2 * Unix PuTTY main program.
14 * FIXME: At least some of these functions should be replaced with
15 * GTK GUI error-box-type things.
17 * In particular, all the termios-type things must go, and
18 * termios.h should disappear from the above #include list.
20 void fatalbox(char *p
, ...)
23 fprintf(stderr
, "FATAL ERROR: ");
25 vfprintf(stderr
, p
, ap
);
30 void connection_fatal(void *frontend
, char *p
, ...)
33 fprintf(stderr
, "FATAL ERROR: ");
35 vfprintf(stderr
, p
, ap
);
40 void cmdline_error(char *p
, ...)
43 fprintf(stderr
, "plink: ");
45 vfprintf(stderr
, p
, ap
);
54 void cleanup_exit(int code
)
64 void verify_ssh_host_key(void *frontend
, char *host
, int port
, char *keytype
,
65 char *keystr
, char *fingerprint
)
69 static const char absentmsg
[] =
70 "The server's host key is not cached. You have no guarantee\n"
71 "that the server is the computer you think it is.\n"
72 "The server's key fingerprint is:\n"
74 "If you trust this host, enter \"y\" to add the key to\n"
75 "PuTTY's cache and carry on connecting.\n"
76 "If you want to carry on connecting just once, without\n"
77 "adding the key to the cache, enter \"n\".\n"
78 "If you do not trust this host, press Return to abandon the\n"
80 "Store key in cache? (y/n) ";
82 static const char wrongmsg
[] =
83 "WARNING - POTENTIAL SECURITY BREACH!\n"
84 "The server's host key does not match the one PuTTY has\n"
85 "cached. This means that either the server administrator\n"
86 "has changed the host key, or you have actually connected\n"
87 "to another computer pretending to be the server.\n"
88 "The new key fingerprint is:\n"
90 "If you were expecting this change and trust the new key,\n"
91 "enter \"y\" to update PuTTY's cache and continue connecting.\n"
92 "If you want to carry on connecting but without updating\n"
93 "the cache, enter \"n\".\n"
94 "If you want to abandon the connection completely, press\n"
95 "Return to cancel. Pressing Return is the ONLY guaranteed\n"
97 "Update cached key? (y/n, Return cancels connection) ";
99 static const char abandoned
[] = "Connection abandoned.\n";
106 ret
= verify_host_key(host
, port
, keytype
, keystr
);
108 if (ret
== 0) /* success - key matched OK */
111 if (ret
== 2) { /* key was different */
112 fprintf(stderr
, wrongmsg
, fingerprint
);
115 if (ret
== 1) { /* key was absent */
116 fprintf(stderr
, absentmsg
, fingerprint
);
121 struct termios oldmode
, newmode
;
122 tcgetattr(0, &oldmode
);
124 newmode
.c_lflag
|= ECHO
| ISIG
| ICANON
;
125 tcsetattr(0, TCSANOW
, &newmode
);
127 read(0, line
, sizeof(line
) - 1);
128 tcsetattr(0, TCSANOW
, &oldmode
);
131 if (line
[0] != '\0' && line
[0] != '\r' && line
[0] != '\n') {
132 if (line
[0] == 'y' || line
[0] == 'Y')
133 store_host_key(host
, port
, keytype
, keystr
);
135 fprintf(stderr
, abandoned
);
141 * Ask whether the selected cipher is acceptable (since it was
142 * below the configured 'warn' threshold).
143 * cs: 0 = both ways, 1 = client->server, 2 = server->client
145 void askcipher(void *frontend
, char *ciphername
, int cs
)
147 static const char msg
[] =
148 "The first %scipher supported by the server is\n"
149 "%s, which is below the configured warning threshold.\n"
150 "Continue with connection? (y/n) ";
151 static const char abandoned
[] = "Connection abandoned.\n";
157 (cs
== 1) ?
"client-to-server " : "server-to-client ",
162 struct termios oldmode
, newmode
;
163 tcgetattr(0, &oldmode
);
165 newmode
.c_lflag
|= ECHO
| ISIG
| ICANON
;
166 tcsetattr(0, TCSANOW
, &newmode
);
168 read(0, line
, sizeof(line
) - 1);
169 tcsetattr(0, TCSANOW
, &oldmode
);
172 if (line
[0] == 'y' || line
[0] == 'Y') {
175 fprintf(stderr
, abandoned
);
180 void old_keyfile_warning(void)
182 static const char message
[] =
183 "You are loading an SSH 2 private key which has an\n"
184 "old version of the file format. This means your key\n"
185 "file is not fully tamperproof. Future versions of\n"
186 "PuTTY may stop supporting this private key format,\n"
187 "so we recommend you convert your key to the new\n"
190 "Once the key is loaded into PuTTYgen, you can perform\n"
191 "this conversion simply by saving it again.\n";
193 fputs(message
, stderr
);
197 * Another bunch of temporary stub functions. These ones will want
198 * removing by means of implementing them properly: libcharset
199 * should invent its own sensible format for codepage names and a
200 * means of enumerating them, and printer_enum needs to be dealt
201 * with somehow or other too.
204 char *cp_name(int codepage
)
208 char *cp_enumerate(int index
)
212 int decode_codepage(char *cp_name
)
217 printer_enum
*printer_start_enum(int *nprinters_ptr
) {
221 char *printer_get_name(printer_enum
*pe
, int i
) { return NULL
;
223 void printer_finish_enum(printer_enum
*pe
) { }
225 Backend
*select_backend(Config
*cfg
)
228 Backend
*back
= NULL
;
229 for (i
= 0; backends
[i
].backend
!= NULL
; i
++)
230 if (backends
[i
].protocol
== cfg
->protocol
) {
231 back
= backends
[i
].backend
;
234 assert(back
!= NULL
);
238 int cfgbox(Config
*cfg
)
240 extern int do_config_box(const char *title
, Config
*cfg
);
241 return do_config_box("PuTTY Configuration", cfg
);
244 int main(int argc
, char **argv
)
246 extern int pt_main(int argc
, char **argv
);
248 flags
= FLAG_VERBOSE
| FLAG_INTERACTIVE
;
249 default_protocol
= be_default_protocol
;
250 /* Find the appropriate default port. */
253 default_port
= 0; /* illegal */
254 for (i
= 0; backends
[i
].backend
!= NULL
; i
++)
255 if (backends
[i
].protocol
== default_protocol
) {
256 default_port
= backends
[i
].backend
->default_port
;
260 return pt_main(argc
, argv
);