X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/1c2a93c4834e2cc84f29c997b16a28e2c9c4fb4d..ded53fce5af6818acc2da88653b56c5c94377b8e:/pageant.c diff --git a/pageant.c b/pageant.c index a9af585c..888dd430 100644 --- a/pageant.c +++ b/pageant.c @@ -3,9 +3,12 @@ */ #include +#ifndef NO_SECURITY #include -#include /* FIXME */ -#include "putty.h" /* FIXME */ +#endif +#include +#include +#include #include "ssh.h" #include "tree234.h" @@ -25,6 +28,8 @@ #define IDM_CLOSE 0x0010 #define IDM_VIEWKEYS 0x0020 +#define IDM_ADDKEY 0x0030 +#define IDM_ABOUT 0x0040 #define APPNAME "Pageant" @@ -37,19 +42,24 @@ #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[]; + +static HINSTANCE instance; +static HWND hwnd; +static HWND keylist; +static HWND aboutbox; +static HMENU systray_menu; -tree234 *rsakeys; +static tree234 *rsakeys; -int has_security; +static int has_security; +#ifndef NO_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; +#endif /* * We need this to link with the RSA code, because rsaencrypt() @@ -92,6 +102,59 @@ struct PassphraseProcStruct { }; /* + * 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, @@ -101,6 +164,9 @@ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg, switch (msg) { case WM_INITDIALOG: + SetForegroundWindow(hwnd); + SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); p = (struct PassphraseProcStruct *)lParam; passphrase = p->passphrase; if (p->comment) @@ -136,7 +202,7 @@ 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; @@ -161,7 +227,7 @@ 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; @@ -172,7 +238,7 @@ void add_keyfile(char *filename) { needs_pass = rsakey_encrypted(filename, &comment); attempts = 0; - key = malloc(sizeof(*key)); + key = smalloc(sizeof(*key)); pps.passphrase = passphrase; pps.comment = comment; do { @@ -182,30 +248,30 @@ void add_keyfile(char *filename) { NULL, PassphraseProc, (LPARAM)&pps); if (!dlgret) { - if (comment) free(comment); - free(key); + if (comment) sfree(comment); + sfree(key); return; /* operation cancelled */ } } else *passphrase = '\0'; - ret = loadrsakey(filename, key, passphrase); + ret = loadrsakey(filename, key, NULL, passphrase); attempts++; } while (ret == -1); - if (comment) free(comment); + if (comment) sfree(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); + sfree(key); return; } if (add234(rsakeys, key) != key) - free(key); /* already present, don't waste RAM */ + sfree(key); /* already present, don't waste RAM */ } /* * 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; @@ -316,14 +382,14 @@ void answer_msg(void *msg) { { struct RSAKey *key; char *comment; - key = malloc(sizeof(struct RSAKey)); + key = smalloc(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)); + comment = smalloc(GET_32BIT(p)); if (comment) { memcpy(comment, p+4, GET_32BIT(p)); key->comment = comment; @@ -335,7 +401,7 @@ void answer_msg(void *msg) { ret[4] = SSH_AGENT_SUCCESS; } else { freersakey(key); - free(key); + sfree(key); } } break; @@ -376,7 +442,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; @@ -411,14 +477,40 @@ static void error(char *s) { } /* + * Prompt for a key file to add, and add it. + */ +static void prompt_add_keyfile(void) { + OPENFILENAME of; + char filename[FILENAME_MAX]; + memset(&of, 0, sizeof(of)); +#ifdef OPENFILENAME_SIZE_VERSION_400 + of.lStructSize = OPENFILENAME_SIZE_VERSION_400; +#else + of.lStructSize = sizeof(of); +#endif + of.hwndOwner = hwnd; + of.lpstrFilter = "All Files\0*\0\0\0"; + of.lpstrCustomFilter = NULL; + of.nFilterIndex = 1; + of.lpstrFile = filename; *filename = '\0'; + of.nMaxFile = sizeof(filename); + of.lpstrFileTitle = NULL; + of.lpstrInitialDir = NULL; + of.lpstrTitle = "Select Private Key File"; + of.Flags = 0; + if (GetOpenFileName(&of)) { + add_keyfile(filename); + keylist_update(); + } +} + +/* * Dialog-box function for the key list box. */ static int CALLBACK KeyListProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { enum234 e; struct RSAKey *key; - OPENFILENAME of; - char filename[FILENAME_MAX]; switch (msg) { case WM_INITDIALOG: @@ -440,33 +532,14 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg, case 101: /* add key */ if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) { - memset(&of, 0, sizeof(of)); -#ifdef OPENFILENAME_SIZE_VERSION_400 - of.lStructSize = OPENFILENAME_SIZE_VERSION_400; -#else - of.lStructSize = sizeof(of); -#endif - of.hwndOwner = hwnd; - of.lpstrFilter = "All Files\0*\0\0\0"; - of.lpstrCustomFilter = NULL; - of.nFilterIndex = 1; - of.lpstrFile = filename; *filename = '\0'; - of.nMaxFile = sizeof(filename); - of.lpstrFileTitle = NULL; - of.lpstrInitialDir = NULL; - of.lpstrTitle = "Select Public Key File"; - of.Flags = 0; - if (GetOpenFileName(&of)) { - add_keyfile(filename); - keylist_update(); - } + prompt_add_keyfile(); } 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; } @@ -535,6 +608,23 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); } break; + case IDM_ADDKEY: + prompt_add_keyfile(); + 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: @@ -565,6 +655,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, #endif if (filemap != NULL && filemap != INVALID_HANDLE_VALUE) { int rc; +#ifndef NO_SECURITY if (has_security) { if ((proc = OpenProcess(MAXIMUM_ALLOWED, FALSE, GetCurrentProcessId())) == NULL) { @@ -608,6 +699,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, debug(("security APIs not present\r\n")); #endif } +#endif p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0); #ifdef DEBUG_IPC debug(("p is %p\r\n", p)); @@ -643,6 +735,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { has_security = FALSE; if (has_security) { +#ifndef NO_SECURITY /* * Attempt to ge the security API we need. */ @@ -655,6 +748,13 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { "Pageant Fatal Error", MB_ICONERROR | MB_OK); return 1; } +#else + MessageBox(NULL, + "This program has been compiled for Win9X and will\n" + "not run on NT, in case it causes a security breach.", + "Pageant Fatal Error", MB_ICONERROR | MB_OK); + return 1; +#endif } else advapi = NULL; @@ -718,7 +818,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { 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"); }