diff --git a/console.c b/console.c index 2a7efdcb..557c1447 100644 --- a/console.c +++ b/console.c @@ -15,6 +15,27 @@ int console_batch_mode = FALSE; +/* + * Clean up and exit. + */ +void cleanup_exit(int code) +{ + /* + * Clean up. + */ + sk_cleanup(); + WSACleanup(); + + if (cfg.protocol == PROT_SSH) { + random_save_seed(); +#ifdef MSCRYPTOAPI + crypto_wrapup(); +#endif + } + + exit(code); +} + void verify_ssh_host_key(char *host, int port, char *keytype, char *keystr, char *fingerprint) { @@ -86,7 +107,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype, if (ret == 2) { /* key was different */ if (console_batch_mode) { fprintf(stderr, wrongmsg_batch, fingerprint); - exit(1); + cleanup_exit(1); } fprintf(stderr, wrongmsg, fingerprint); fflush(stderr); @@ -94,7 +115,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype, if (ret == 1) { /* key was absent */ if (console_batch_mode) { fprintf(stderr, absentmsg_batch, fingerprint); - exit(1); + cleanup_exit(1); } fprintf(stderr, absentmsg, fingerprint); fflush(stderr); @@ -112,7 +133,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype, store_host_key(host, port, keytype, keystr); } else { fprintf(stderr, abandoned); - exit(0); + cleanup_exit(0); } } @@ -143,7 +164,7 @@ void askcipher(char *ciphername, int cs) (cs == 0) ? "" : (cs == 1) ? "client-to-server " : "server-to-client ", ciphername); - exit(1); + cleanup_exit(1); } fprintf(stderr, msg, @@ -163,7 +184,7 @@ void askcipher(char *ciphername, int cs) return; } else { fprintf(stderr, abandoned); - exit(0); + cleanup_exit(0); } } @@ -266,7 +287,7 @@ int console_get_line(const char *prompt, char *str, hout = GetStdHandle(STD_OUTPUT_HANDLE); if (hin == INVALID_HANDLE_VALUE || hout == INVALID_HANDLE_VALUE) { fprintf(stderr, "Cannot get standard input/output handles\n"); - exit(1); + cleanup_exit(1); } GetConsoleMode(hin, &savemode); diff --git a/misc.c b/misc.c index a2d741e5..ee1abf7b 100644 --- a/misc.c +++ b/misc.c @@ -415,7 +415,7 @@ void *safemalloc(size_t size) #endif MessageBox(NULL, str, "PuTTY Fatal Error", MB_SYSTEMMODAL | MB_ICONERROR | MB_OK); - exit(1); + cleanup_exit(1); } #ifdef MALLOC_LOG if (fp) @@ -452,7 +452,7 @@ void *saferealloc(void *ptr, size_t size) #endif MessageBox(NULL, str, "PuTTY Fatal Error", MB_SYSTEMMODAL | MB_ICONERROR | MB_OK); - exit(1); + cleanup_exit(1); } #ifdef MALLOC_LOG if (fp) diff --git a/network.h b/network.h index 3ec9eb78..2cab4388 100644 --- a/network.h +++ b/network.h @@ -62,6 +62,7 @@ struct plug_function_table { void sk_init(void); /* called once at program startup */ +void sk_cleanup(void); /* called just before program exit */ SockAddr sk_namelookup(char *host, char **canonicalname); void sk_getaddr(SockAddr addr, char *buf, int buflen); diff --git a/noise.c b/noise.c index 856974bc..a094d25e 100644 --- a/noise.c +++ b/noise.c @@ -53,8 +53,10 @@ void random_save_seed(void) int len; void *data; - random_get_savedata(&data, &len); - write_random_seed(data, len); + if (random_active) { + random_get_savedata(&data, &len); + write_random_seed(data, len); + } } /* diff --git a/pageant.c b/pageant.c index 12e03a8a..c4eef554 100644 --- a/pageant.c +++ b/pageant.c @@ -1658,6 +1658,8 @@ void spawn_cmd(char *cmdline, char * args, int show) } } +void cleanup_exit(int code) { exit(code); } + int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { WNDCLASS wndclass; diff --git a/plink.c b/plink.c index b2c07acc..a76570ee 100644 --- a/plink.c +++ b/plink.c @@ -27,7 +27,7 @@ void fatalbox(char *p, ...) va_end(ap); fputc('\n', stderr); WSACleanup(); - exit(1); + cleanup_exit(1); } void connection_fatal(char *p, ...) { @@ -38,7 +38,7 @@ void connection_fatal(char *p, ...) va_end(ap); fputc('\n', stderr); WSACleanup(); - exit(1); + cleanup_exit(1); } static char *password = NULL; @@ -607,7 +607,7 @@ int main(int argc, char **argv) if (!CreateThread(NULL, 0, stdout_write_thread, &odata, 0, &out_threadid)) { fprintf(stderr, "Unable to create output thread\n"); - exit(1); + cleanup_exit(1); } edata.event = stderrevent; edata.eventback = CreateEvent(NULL, FALSE, FALSE, NULL); @@ -616,7 +616,7 @@ int main(int argc, char **argv) if (!CreateThread(NULL, 0, stdout_write_thread, &edata, 0, &err_threadid)) { fprintf(stderr, "Unable to create error output thread\n"); - exit(1); + cleanup_exit(1); } while (1) { @@ -644,7 +644,7 @@ int main(int argc, char **argv) if (!CreateThread(NULL, 0, stdin_read_thread, &idata, 0, &in_threadid)) { fprintf(stderr, "Unable to create input thread\n"); - exit(1); + cleanup_exit(1); } sending = TRUE; } @@ -725,7 +725,7 @@ int main(int argc, char **argv) odata.busy = 0; if (!odata.writeret) { fprintf(stderr, "Unable to write to standard output\n"); - exit(0); + cleanup_exit(0); } bufchain_consume(&stdout_data, odata.lenwritten); if (bufchain_size(&stdout_data) > 0) @@ -738,7 +738,7 @@ int main(int argc, char **argv) edata.busy = 0; if (!edata.writeret) { fprintf(stderr, "Unable to write to standard output\n"); - exit(0); + cleanup_exit(0); } bufchain_consume(&stderr_data, edata.lenwritten); if (bufchain_size(&stderr_data) > 0) diff --git a/psftp.c b/psftp.c index 094e68b0..6dae40ac 100644 --- a/psftp.c +++ b/psftp.c @@ -1453,7 +1453,7 @@ void fatalbox(char *fmt, ...) strcat(str, "\n"); fputs(str, stderr); - exit(1); + cleanup_exit(1); } void connection_fatal(char *fmt, ...) { @@ -1466,7 +1466,7 @@ void connection_fatal(char *fmt, ...) strcat(str, "\n"); fputs(str, stderr); - exit(1); + cleanup_exit(1); } void ldisc_send(char *buf, int len, int interactive) @@ -1627,11 +1627,11 @@ static void init_winsock(void) winsock_ver = MAKEWORD(1, 1); if (WSAStartup(winsock_ver, &wsadata)) { fprintf(stderr, "Unable to initialise WinSock"); - exit(1); + cleanup_exit(1); } if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1) { fprintf(stderr, "WinSock version is incompatible with 1.1"); - exit(1); + cleanup_exit(1); } } @@ -1650,7 +1650,7 @@ static void usage(void) printf(" -v show verbose messages\n"); printf(" -P port connect to specified port\n"); printf(" -pw passw login with specified password\n"); - exit(1); + cleanup_exit(1); } /* @@ -1720,7 +1720,7 @@ static int psftp_connect(char *userhost, char *user, int portnumber) printf("login as: "); if (!fgets(cfg.username, sizeof(cfg.username), stdin)) { fprintf(stderr, "psftp: aborting\n"); - exit(1); + cleanup_exit(1); } else { int len = strlen(cfg.username); if (cfg.username[len - 1] == '\n') diff --git a/putty.h b/putty.h index baa55ff6..04804c27 100644 --- a/putty.h +++ b/putty.h @@ -427,6 +427,8 @@ void get_window_pos(int *x, int *y); void get_window_pixels(int *x, int *y); char *get_window_title(int icon); +void cleanup_exit(int); + /* * Exports from noise.c. */ @@ -536,6 +538,7 @@ void random_add_noise(void *noise, int length); void random_init(void); int random_byte(void); void random_get_savedata(void **data, int *len); +extern int random_active; /* * Exports from misc.c. diff --git a/puttygen.c b/puttygen.c index 330176c6..6116e0f1 100644 --- a/puttygen.c +++ b/puttygen.c @@ -1142,6 +1142,8 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, return 0; } +void cleanup_exit(int code) { exit(code); } + int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { InitCommonControls(); diff --git a/scp.c b/scp.c index 34f6ffb5..bde4cdad 100644 --- a/scp.c +++ b/scp.c @@ -210,7 +210,7 @@ void fatalbox(char *fmt, ...) 0 /*lParam */ ))SleepEx(1000, TRUE); } - exit(1); + cleanup_exit(1); } void connection_fatal(char *fmt, ...) { @@ -233,7 +233,7 @@ void connection_fatal(char *fmt, ...) 0 /*lParam */ ))SleepEx(1000, TRUE); } - exit(1); + cleanup_exit(1); } /* @@ -404,7 +404,7 @@ static void bump(char *fmt, ...) 0 /*lParam */ ))SleepEx(1000, TRUE); } - exit(1); + cleanup_exit(1); } /* @@ -2055,7 +2055,7 @@ static void usage(void) printf (" -gui hWnd GUI mode with the windows handle for receiving messages\n"); #endif - exit(1); + cleanup_exit(1); } /* diff --git a/ssh.c b/ssh.c index 4fb0822a..d03de083 100644 --- a/ssh.c +++ b/ssh.c @@ -2168,8 +2168,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt) break; case 3: case 4: - random_save_seed(); - exit(0); + cleanup_exit(0); break; default: if (((c >= ' ' && c <= '~') || @@ -2474,8 +2473,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt) break; case 3: case 4: - random_save_seed(); - exit(0); + cleanup_exit(0); break; default: if (pos < sizeof(password)-1) @@ -3973,8 +3971,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) break; case 3: case 4: - random_save_seed(); - exit(0); + cleanup_exit(0); break; default: if (((c >= ' ' && c <= '~') || @@ -4452,8 +4449,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) break; case 3: case 4: - random_save_seed(); - exit(0); + cleanup_exit(0); break; default: if (pos < sizeof(password)-1) diff --git a/sshrand.c b/sshrand.c index 3014da4f..7c401af4 100644 --- a/sshrand.c +++ b/sshrand.c @@ -39,7 +39,7 @@ struct RandPool { }; static struct RandPool pool; -static int random_active = 0; +int random_active = 0; void random_stir(void) { diff --git a/windlg.c b/windlg.c index 7ee5c97a..20d7fc27 100644 --- a/windlg.c +++ b/windlg.c @@ -3365,7 +3365,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype, if (mbret == IDYES) store_host_key(host, port, keytype, keystr); if (mbret == IDCANCEL) - exit(0); + cleanup_exit(0); } if (ret == 1) { /* key was absent */ int mbret; @@ -3375,7 +3375,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype, if (mbret == IDYES) store_host_key(host, port, keytype, keystr); if (mbret == IDCANCEL) - exit(0); + cleanup_exit(0); } } @@ -3406,7 +3406,7 @@ void askcipher(char *ciphername, int cs) if (mbret == IDYES) return; else - exit(0); + cleanup_exit(0); } /* diff --git a/window.c b/window.c index 4bcc2697..a779dbc7 100644 --- a/window.c +++ b/window.c @@ -159,6 +159,8 @@ static char *window_name, *icon_name; static int compose_state = 0; +static int wsa_started = 0; + static OSVERSIONINFO osVersion; static UINT wm_mousewheel = WM_MOUSEWHEEL; @@ -192,6 +194,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) WSACleanup(); return 1; } + wsa_started = 1; /* WISHLIST: maybe allow config tweaking even if winsock not present? */ sk_init(); @@ -753,6 +756,14 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) } } + cleanup_exit(msg.wParam); +} + +/* + * Clean up and exit. + */ +void cleanup_exit(int code) +{ /* * Clean up. */ @@ -760,7 +771,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) sfree(logpal); if (pal) DeleteObject(pal); - WSACleanup(); + sk_cleanup(); + if (wsa_started) + WSACleanup(); if (cfg.protocol == PROT_SSH) { random_save_seed(); @@ -769,7 +782,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) #endif } - return msg.wParam; + exit(code); } /* @@ -4123,7 +4136,7 @@ void fatalbox(char *fmt, ...) vsprintf(stuff, fmt, ap); va_end(ap); MessageBox(hwnd, stuff, "PuTTY Fatal Error", MB_ICONERROR | MB_OK); - exit(1); + cleanup_exit(1); } /* diff --git a/winnet.c b/winnet.c index 1663148f..0dac18e2 100644 --- a/winnet.c +++ b/winnet.c @@ -124,6 +124,18 @@ void sk_init(void) sktree = newtree234(cmpfortree); } +void sk_cleanup(void) +{ + Actual_Socket s; + int i; + + if (sktree) { + for (i = 0; (s = index234(sktree, i)) != NULL; i++) { + closesocket(s->s); + } + } +} + char *winsock_error_string(int error) { switch (error) {