From 93b581bd031b2270deb7f45440e61a1044fe94da Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 6 Mar 2002 20:13:22 +0000 Subject: [PATCH] Ensure our network layer is properly cleaned up before PuTTY exits. Specifically, we explicitly closesocket() all open sockets, which appears to be necessary since otherwise Windows sends RST rather than FIN. I'm _sure_ that's a Windows bug, but there we go. git-svn-id: svn://svn.tartarus.org/sgt/putty@1574 cda61777-01e9-0310-a592-d414129be87e --- console.c | 33 +++++++++++++++++++++++++++------ misc.c | 4 ++-- network.h | 1 + noise.c | 6 ++++-- pageant.c | 2 ++ plink.c | 14 +++++++------- psftp.c | 12 ++++++------ putty.h | 3 +++ puttygen.c | 2 ++ scp.c | 8 ++++---- ssh.c | 12 ++++-------- sshrand.c | 2 +- windlg.c | 6 +++--- window.c | 19 ++++++++++++++++--- winnet.c | 12 ++++++++++++ 15 files changed, 94 insertions(+), 42 deletions(-) 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) { -- 2.11.0