X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/3c0b3d061d49c188caf3ba24c6f9845a30eabaac..6d2d5e8dcea13c2c01cf583eeebfd72bc6bea6e0:/pageant.c diff --git a/pageant.c b/pageant.c index dc8914e0..7f05e1b3 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,19 +37,22 @@ #define SSH_AGENTC_ADD_RSA_IDENTITY 7 #define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 -HINSTANCE instance; -HWND hwnd; -HWND keylist; -HMENU systray_menu; +extern char ver[]; -tree234 *rsakeys; +static HINSTANCE instance; +static HWND hwnd; +static HWND keylist; +static HWND aboutbox; +static HMENU systray_menu; -int has_security; +static tree234 *rsakeys; + +static int has_security; typedef DWORD (WINAPI *gsi_fn_t) (HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, PSID *, PSID *, PACL *, PACL *, PSECURITY_DESCRIPTOR *); -gsi_fn_t getsecurityinfo; +static gsi_fn_t getsecurityinfo; /* * We need this to link with the RSA code, because rsaencrypt() @@ -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: @@ -127,15 +192,23 @@ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg, /* * Update the visible key list. */ -void keylist_update(void) { +static 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) key->comment); + 0, (LPARAM)listentry); } SendDlgItemMessage (keylist, 100, LB_SETCURSEL, (WPARAM) -1, 0); } @@ -144,24 +217,28 @@ void keylist_update(void) { /* * This function loads a key from a file and adds it. */ -void add_keyfile(char *filename) { +static void add_keyfile(char *filename) { char passphrase[PASSPHRASE_MAXLEN]; struct RSAKey *key; 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 */ } @@ -170,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; @@ -183,7 +261,7 @@ void add_keyfile(char *filename) { /* * This is the main agent function that answers messages. */ -void answer_msg(void *msg) { +static void answer_msg(void *msg) { unsigned char *p = msg; unsigned char *ret = msg; int type; @@ -313,6 +391,7 @@ void answer_msg(void *msg) { ret[4] = SSH_AGENT_SUCCESS; } else { freersakey(key); + free(key); } } break; @@ -334,6 +413,7 @@ void answer_msg(void *msg) { if (key) { del234(rsakeys, key); keylist_update(); + freersakey(key); ret[4] = SSH_AGENT_SUCCESS; } } @@ -352,7 +432,7 @@ void answer_msg(void *msg) { /* * Key comparison function for the 2-3-4 tree of RSA keys. */ -int cmpkeys(void *av, void *bv) { +static int cmpkeys(void *av, void *bv) { struct RSAKey *a = (struct RSAKey *)av; struct RSAKey *b = (struct RSAKey *)bv; Bignum am, bm; @@ -398,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)) { @@ -427,7 +510,7 @@ 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); @@ -439,7 +522,7 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg, 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; } @@ -448,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; } @@ -513,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: @@ -696,7 +788,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { DestroyIcon(hicon); systray_menu = CreatePopupMenu(); + /* 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"); }