X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/016ef8abc3f237802ce9d1927d79dc1ecc96dca3..d4dcbf569b6ede76fe107268168cf852b9452360:/pageant.c diff --git a/pageant.c b/pageant.c index e00d4e14..62f60db2 100644 --- a/pageant.c +++ b/pageant.c @@ -4,8 +4,7 @@ #include #include -#include /* FIXME */ -#include "putty.h" /* FIXME */ +#include #include "ssh.h" #include "tree234.h" @@ -25,6 +24,7 @@ #define IDM_CLOSE 0x0010 #define IDM_VIEWKEYS 0x0020 +#define IDM_ABOUT 0x0030 #define APPNAME "Pageant" @@ -37,9 +37,12 @@ #define SSH_AGENTC_ADD_RSA_IDENTITY 7 #define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 +extern char ver[]; + HINSTANCE instance; HWND hwnd; HWND keylist; +HWND aboutbox; HMENU systray_menu; tree234 *rsakeys; @@ -86,16 +89,78 @@ void logevent(char *msg) { #define PASSPHRASE_MAXLEN 512 +struct PassphraseProcStruct { + char *passphrase; + char *comment; +}; + +/* + * Dialog-box function for the Licence box. + */ +static int CALLBACK LicenceProc (HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam) { + switch (msg) { + case WM_INITDIALOG: + return 1; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + EndDialog(hwnd, 1); + return 0; + } + return 0; + case WM_CLOSE: + EndDialog(hwnd, 1); + return 0; + } + return 0; +} + +/* + * Dialog-box function for the About box. + */ +static int CALLBACK AboutProc (HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam) { + switch (msg) { + case WM_INITDIALOG: + SetDlgItemText (hwnd, 100, ver); + return 1; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + aboutbox = NULL; + DestroyWindow (hwnd); + return 0; + case 101: + EnableWindow(hwnd, 0); + DialogBox (instance, MAKEINTRESOURCE(214), NULL, LicenceProc); + EnableWindow(hwnd, 1); + SetActiveWindow(hwnd); + return 0; + } + return 0; + case WM_CLOSE: + aboutbox = NULL; + DestroyWindow (hwnd); + return 0; + } + return 0; +} + /* * Dialog-box function for the passphrase box. */ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static char *passphrase; + struct PassphraseProcStruct *p; switch (msg) { case WM_INITDIALOG: - passphrase = (char *)lParam; + p = (struct PassphraseProcStruct *)lParam; + passphrase = p->passphrase; + if (p->comment) + SetDlgItemText(hwnd, 101, p->comment); *passphrase = 0; return 0; case WM_COMMAND: @@ -125,6 +190,31 @@ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg, } /* + * Update the visible key list. + */ +void keylist_update(void) { + struct RSAKey *key; + enum234 e; + + if (keylist) { + SendDlgItemMessage(keylist, 100, LB_RESETCONTENT, 0, 0); + for (key = first234(rsakeys, &e); key; key = next234(&e)) { + char listentry[512], *p; + /* + * Replace two spaces in the fingerprint with tabs, for + * nice alignment in the box. + */ + rsa_fingerprint(listentry, sizeof(listentry), key); + p = strchr(listentry, ' '); if (p) *p = '\t'; + p = strchr(listentry, ' '); if (p) *p = '\t'; + SendDlgItemMessage (keylist, 100, LB_ADDSTRING, + 0, (LPARAM)listentry); + } + SendDlgItemMessage (keylist, 100, LB_SETCURSEL, (WPARAM) -1, 0); + } +} + +/* * This function loads a key from a file and adds it. */ void add_keyfile(char *filename) { @@ -133,18 +223,22 @@ void add_keyfile(char *filename) { int needs_pass; int ret; int attempts; + char *comment; + struct PassphraseProcStruct pps; - /* FIXME: we can acquire comment here and use it in dialog */ - needs_pass = rsakey_encrypted(filename, NULL); + needs_pass = rsakey_encrypted(filename, &comment); attempts = 0; key = malloc(sizeof(*key)); + pps.passphrase = passphrase; + pps.comment = comment; do { if (needs_pass) { int dlgret; dlgret = DialogBoxParam(instance, MAKEINTRESOURCE(210), NULL, PassphraseProc, - (LPARAM)passphrase); + (LPARAM)&pps); if (!dlgret) { + if (comment) free(comment); free(key); return; /* operation cancelled */ } @@ -153,8 +247,9 @@ void add_keyfile(char *filename) { ret = loadrsakey(filename, key, passphrase); attempts++; } while (ret == -1); + if (comment) free(comment); if (ret == 0) { - MessageBox(NULL, "Couldn't load public key.", APPNAME, + MessageBox(NULL, "Couldn't load private key.", APPNAME, MB_OK | MB_ICONERROR); free(key); return; @@ -269,12 +364,36 @@ void answer_msg(void *msg) { memcpy(ret+5, response_md5, 16); } break; -#if 0 /* FIXME: implement these */ case SSH_AGENTC_ADD_RSA_IDENTITY: /* * Add to the list and return SSH_AGENT_SUCCESS, or * SSH_AGENT_FAILURE if the key was malformed. */ + { + struct RSAKey *key; + char *comment; + key = malloc(sizeof(struct RSAKey)); + memset(key, 0, sizeof(key)); + p += makekey(p, key, NULL, 1); + p += makeprivate(p, key); + p += ssh1_read_bignum(p, NULL); /* p^-1 mod q */ + p += ssh1_read_bignum(p, NULL); /* p */ + p += ssh1_read_bignum(p, NULL); /* q */ + comment = malloc(GET_32BIT(p)); + if (comment) { + memcpy(comment, p+4, GET_32BIT(p)); + key->comment = comment; + } + PUT_32BIT(ret, 1); + ret[4] = SSH_AGENT_FAILURE; + if (add234(rsakeys, key) == key) { + keylist_update(); + ret[4] = SSH_AGENT_SUCCESS; + } else { + freersakey(key); + free(key); + } + } break; case SSH_AGENTC_REMOVE_RSA_IDENTITY: /* @@ -282,8 +401,23 @@ void answer_msg(void *msg) { * perhaps SSH_AGENT_FAILURE if it wasn't in the list to * start with. */ + { + struct RSAKey reqkey, *key; + + p += makekey(p, &reqkey, NULL, 0); + key = find234(rsakeys, &reqkey, NULL); + freebn(reqkey.exponent); + freebn(reqkey.modulus); + PUT_32BIT(ret, 1); + ret[4] = SSH_AGENT_FAILURE; + if (key) { + del234(rsakeys, key); + keylist_update(); + freersakey(key); + ret[4] = SSH_AGENT_SUCCESS; + } + } break; -#endif default: failure: /* @@ -344,10 +478,13 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg, switch (msg) { case WM_INITDIALOG: - for (key = first234(rsakeys, &e); key; key = next234(&e)) { - SendDlgItemMessage (hwnd, 100, LB_ADDSTRING, - 0, (LPARAM) key->comment); - } + keylist = hwnd; + { + static int tabs[2] = {25, 175}; + SendDlgItemMessage (hwnd, 100, LB_SETTABSTOPS, 2, + (LPARAM) tabs); + } + keylist_update(); return 0; case WM_COMMAND: switch (LOWORD(wParam)) { @@ -373,24 +510,19 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg, of.nMaxFile = sizeof(filename); of.lpstrFileTitle = NULL; of.lpstrInitialDir = NULL; - of.lpstrTitle = "Select Public Key File"; + of.lpstrTitle = "Select Private Key File"; of.Flags = 0; if (GetOpenFileName(&of)) { add_keyfile(filename); + keylist_update(); } - SendDlgItemMessage(hwnd, 100, LB_RESETCONTENT, 0, 0); - for (key = first234(rsakeys, &e); key; key = next234(&e)) { - SendDlgItemMessage (hwnd, 100, LB_ADDSTRING, - 0, (LPARAM) key->comment); - } - SendDlgItemMessage (hwnd, 100, LB_SETCURSEL, (WPARAM) -1, 0); } return 0; case 102: /* remove key */ if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) { int n = SendDlgItemMessage (hwnd, 100, LB_GETCURSEL, 0, 0); - if (n == LB_ERR || n == 0) { + if (n == LB_ERR) { MessageBeep(0); break; } @@ -399,12 +531,7 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg, break; del234(rsakeys, key); freersakey(key); free(key); - SendDlgItemMessage(hwnd, 100, LB_RESETCONTENT, 0, 0); - for (key = first234(rsakeys, &e); key; key = next234(&e)) { - SendDlgItemMessage (hwnd, 100, LB_ADDSTRING, - 0, (LPARAM) key->comment); - } - SendDlgItemMessage (hwnd, 100, LB_SETCURSEL, (WPARAM) -1, 0); + keylist_update(); } return 0; } @@ -464,6 +591,20 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); } break; + case IDM_ABOUT: + if (!aboutbox) { + aboutbox = CreateDialog (instance, MAKEINTRESOURCE(213), + NULL, AboutProc); + ShowWindow (aboutbox, SW_SHOWNORMAL); + /* + * Sometimes the window comes up minimised / hidden + * for no obvious reason. Prevent this. + */ + SetForegroundWindow(aboutbox); + SetWindowPos (aboutbox, HWND_TOP, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + } + break; } break; case WM_DESTROY: @@ -647,8 +788,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { DestroyIcon(hicon); systray_menu = CreatePopupMenu(); - AppendMenu (systray_menu, MF_ENABLED, IDM_VIEWKEYS, "View Keys"); - AppendMenu (systray_menu, MF_ENABLED, IDM_CLOSE, "Terminate"); + /* accelerators used: vxa */ + AppendMenu (systray_menu, MF_ENABLED, IDM_VIEWKEYS, "&View Keys"); + AppendMenu (systray_menu, MF_ENABLED, IDM_ABOUT, "&About"); + AppendMenu (systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit"); } ShowWindow (hwnd, SW_HIDE);