X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/32874aeac8dacbca26663777b39a79efc5d8dc4b..2184a5d91ffbcf2de2f730c83dda2d9443035f50:/pageant.c diff --git a/pageant.c b/pageant.c index 0605b4b3..01148047 100644 --- a/pageant.c +++ b/pageant.c @@ -65,7 +65,7 @@ int agent_exists(void); * pads its data with random bytes. Since we only use rsadecrypt() * and the signing functions, which are deterministic, this should * never be called. - * + * * If it _is_ called, there is a _serious_ problem, because it * won't generate true random numbers. So we must scream, panic, * and exit immediately if that should happen. @@ -74,6 +74,8 @@ int random_byte(void) { MessageBox(hwnd, "Internal Error", APPNAME, MB_OK | MB_ICONERROR); exit(0); + /* this line can't be reached but it placates MSVC's warnings :-) */ + return 0; } /* @@ -168,6 +170,8 @@ static int CALLBACK AboutProc(HWND hwnd, UINT msg, return 0; } +static HWND passphrase_box; + /* * Dialog-box function for the passphrase box. */ @@ -179,6 +183,7 @@ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg, switch (msg) { case WM_INITDIALOG: + passphrase_box = hwnd; /* * Centre the window. */ @@ -232,6 +237,26 @@ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg, } /* + * Warn about the obsolescent key file format. + */ +void old_keyfile_warning(void) +{ + static const char mbtitle[] = "PuTTY Key File Warning"; + static const char message[] = + "You are loading an SSH 2 private key which has an\n" + "old version of the file format. This means your key\n" + "file is not fully tamperproof. Future versions of\n" + "PuTTY may stop supporting this private key format,\n" + "so we recommend you convert your key to the new\n" + "format.\n" + "\n" + "You can perform this conversion by loading the key\n" + "into PuTTYgen and then saving it again."; + + MessageBox(NULL, message, mbtitle, MB_OK); +} + +/* * Update the visible key list. */ static void keylist_update(void) @@ -294,8 +319,8 @@ static void keylist_update(void) static void add_keyfile(char *filename) { char passphrase[PASSPHRASE_MAXLEN]; - struct RSAKey *rkey; - struct ssh2_userkey *skey; + struct RSAKey *rkey = NULL; + struct ssh2_userkey *skey = NULL; int needs_pass; int ret; int attempts; @@ -324,6 +349,7 @@ static void add_keyfile(char *filename) int dlgret; dlgret = DialogBoxParam(instance, MAKEINTRESOURCE(210), NULL, PassphraseProc, (LPARAM) & pps); + passphrase_box = NULL; if (!dlgret) { if (comment) sfree(comment); @@ -358,6 +384,7 @@ static void add_keyfile(char *filename) if (ver == 1) { if (already_running) { unsigned char *request, *response; + void *vresponse; int reqlen, clen, resplen; clen = strlen(rkey->comment); @@ -391,7 +418,8 @@ static void add_keyfile(char *filename) reqlen += 4 + clen; PUT_32BIT(request, reqlen - 4); - agent_query(request, reqlen, &response, &resplen); + agent_query(request, reqlen, &vresponse, &resplen); + response = vresponse; if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) MessageBox(NULL, "The already running Pageant " "refused to add the key.", APPNAME, @@ -403,6 +431,7 @@ static void add_keyfile(char *filename) } else { if (already_running) { unsigned char *request, *response; + void *vresponse; int reqlen, alglen, clen, keybloblen, resplen; alglen = strlen(skey->alg->name); clen = strlen(skey->comment); @@ -431,7 +460,8 @@ static void add_keyfile(char *filename) PUT_32BIT(request, reqlen - 4); reqlen += clen + 4; - agent_query(request, reqlen, &response, &resplen); + agent_query(request, reqlen, &vresponse, &resplen); + response = vresponse; if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) MessageBox(NULL, "The already running Pageant" "refused to add the key.", APPNAME, @@ -603,7 +633,7 @@ static void answer_msg(void *msg) break; case SSH2_AGENTC_SIGN_REQUEST: /* - * Reply with either SSH2_AGENT_RSA_RESPONSE or + * Reply with either SSH2_AGENT_SIGN_RESPONSE or * SSH_AGENT_FAILURE, depending on whether we have that key * or not. */ @@ -640,16 +670,19 @@ static void answer_msg(void *msg) { struct RSAKey *key; char *comment; + int commentlen; key = smalloc(sizeof(struct RSAKey)); - memset(key, 0, sizeof(key)); + memset(key, 0, sizeof(struct RSAKey)); p += makekey(p, key, NULL, 1); p += makeprivate(p, key); - p += ssh1_read_bignum(p, key->iqmp); /* p^-1 mod q */ - p += ssh1_read_bignum(p, key->p); /* p */ - p += ssh1_read_bignum(p, key->q); /* q */ - comment = smalloc(GET_32BIT(p)); + p += ssh1_read_bignum(p, &key->iqmp); /* p^-1 mod q */ + p += ssh1_read_bignum(p, &key->p); /* p */ + p += ssh1_read_bignum(p, &key->q); /* q */ + commentlen = GET_32BIT(p); + comment = smalloc(commentlen+1); if (comment) { - memcpy(comment, p + 4, GET_32BIT(p)); + memcpy(comment, p + 4, commentlen); + comment[commentlen] = '\0'; key->comment = comment; } PUT_32BIT(ret, 1); @@ -683,6 +716,8 @@ static void answer_msg(void *msg) /* Add further algorithm names here. */ if (alglen == 7 && !memcmp(alg, "ssh-rsa", 7)) key->alg = &ssh_rsa; + else if (alglen == 7 && !memcmp(alg, "ssh-dss", 7)) + key->alg = &ssh_dss; else { sfree(key); goto failure; @@ -938,11 +973,6 @@ static int cmpkeys_ssh2_asymm(void *av, void *bv) return c; } -static void error(char *s) -{ - MessageBox(hwnd, s, APPNAME, MB_OK | MB_ICONERROR); -} - /* * Prompt for a key file to add, and add it. */ @@ -1018,6 +1048,11 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg, case 101: /* add key */ if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) { + if (passphrase_box) { + MessageBeep(MB_ICONERROR); + SetForegroundWindow(passphrase_box); + break; + } prompt_add_keyfile(); } return 0; @@ -1060,13 +1095,54 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg, return 0; } +/* Set up a system tray icon */ +static BOOL AddTrayIcon(HWND hwnd) +{ + BOOL res; + NOTIFYICONDATA tnid; + HICON hicon; + +#ifdef NIM_SETVERSION + tnid.uVersion = 0; + res = Shell_NotifyIcon(NIM_SETVERSION, &tnid); +#endif + + tnid.cbSize = sizeof(NOTIFYICONDATA); + tnid.hWnd = hwnd; + tnid.uID = 1; /* unique within this systray use */ + tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + tnid.uCallbackMessage = WM_SYSTRAY; + tnid.hIcon = hicon = LoadIcon(instance, MAKEINTRESOURCE(201)); + strcpy(tnid.szTip, "Pageant (PuTTY authentication agent)"); + + res = Shell_NotifyIcon(NIM_ADD, &tnid); + + if (hicon) DestroyIcon(hicon); + + return res; +} + static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { int ret; static int menuinprogress; + static UINT msgTaskbarCreated = 0; switch (message) { + case WM_CREATE: + msgTaskbarCreated = RegisterWindowMessage(_T("TaskbarCreated")); + break; + default: + if (message==msgTaskbarCreated) { + /* + * Explorer has been restarted, so the tray icon will + * have been lost. + */ + AddTrayIcon(hwnd); + } + break; + case WM_SYSTRAY: if (lParam == WM_RBUTTONUP) { POINT cursorpos; @@ -1092,6 +1168,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, case WM_SYSCOMMAND: switch (wParam & ~0xF) { /* low 4 bits reserved to Windows */ case IDM_CLOSE: + if (passphrase_box) + SendMessage(passphrase_box, WM_CLOSE, 0, 0); SendMessage(hwnd, WM_CLOSE, 0, 0); break; case IDM_VIEWKEYS: @@ -1109,6 +1187,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, } break; case IDM_ADDKEY: + if (passphrase_box) { + MessageBeep(MB_ICONERROR); + SetForegroundWindow(passphrase_box); + break; + } prompt_add_keyfile(); break; case IDM_ABOUT: @@ -1135,9 +1218,12 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, COPYDATASTRUCT *cds; char *mapname; void *p; - HANDLE filemap, proc; + HANDLE filemap; +#ifndef NO_SECURITY + HANDLE proc; PSID mapowner, procowner; PSECURITY_DESCRIPTOR psd1 = NULL, psd2 = NULL; +#endif int ret = 0; cds = (COPYDATASTRUCT *) lParam; @@ -1154,8 +1240,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, debug(("filemap is %p\n", filemap)); #endif if (filemap != NULL && filemap != INVALID_HANDLE_VALUE) { - int rc; #ifndef NO_SECURITY + int rc; if (has_security) { if ((proc = OpenProcess(MAXIMUM_ALLOWED, FALSE, GetCurrentProcessId())) == @@ -1234,7 +1320,7 @@ void spawn_cmd(char *cmdline, int show) NULL, NULL, show) <= (HINSTANCE) 32) { TCHAR sMsg[140]; sprintf(sMsg, _T("Failed to run \"%.100s\", Error: %d"), cmdline, - GetLastError()); + (int)GetLastError()); MessageBox(NULL, sMsg, APPNAME, MB_OK | MB_ICONEXCLAMATION); } } @@ -1317,37 +1403,15 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) 100, 100, NULL, NULL, inst, NULL); /* Set up a system tray icon */ - { - BOOL res; - NOTIFYICONDATA tnid; - HICON hicon; + AddTrayIcon(hwnd); -#ifdef NIM_SETVERSION - tnid.uVersion = 0; - res = Shell_NotifyIcon(NIM_SETVERSION, &tnid); -#endif - - tnid.cbSize = sizeof(NOTIFYICONDATA); - tnid.hWnd = hwnd; - tnid.uID = 1; /* unique within this systray use */ - tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; - tnid.uCallbackMessage = WM_SYSTRAY; - tnid.hIcon = hicon = LoadIcon(instance, MAKEINTRESOURCE(201)); - strcpy(tnid.szTip, "Pageant (PuTTY authentication agent)"); - - res = Shell_NotifyIcon(NIM_ADD, &tnid); - - if (hicon) - DestroyIcon(hicon); - - systray_menu = CreatePopupMenu(); - /* accelerators used: vkxa */ - AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS, - "&View Keys"); - AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key"); - AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About"); - AppendMenu(systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit"); - } + systray_menu = CreatePopupMenu(); + /* accelerators used: vkxa */ + AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS, + "&View Keys"); + AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key"); + AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About"); + AppendMenu(systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit"); ShowWindow(hwnd, SW_HIDE); @@ -1367,7 +1431,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { char *p; int inquotes = 0; - int ignorearg = 0; p = cmdline; while (*p) { while (*p && isspace(*p))