X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/231ee168f3732ad79bdc8772ab91393f109b8f53..0016d70b76e2706064b54c9dd24d45a45646b0de:/pageant.c diff --git a/pageant.c b/pageant.c index df24a7df..2ebf3ab1 100644 --- a/pageant.c +++ b/pageant.c @@ -2,20 +2,23 @@ * Pageant: the PuTTY Authentication Agent. */ -#include -#ifndef NO_SECURITY -#include -#endif #include #include #include #include #include +#include "putty.h" #include "ssh.h" #include "misc.h" #include "tree234.h" +#include + +#ifndef NO_SECURITY +#include +#endif + #define IDI_MAINICON 200 #define IDI_TRAYICON 201 @@ -48,7 +51,7 @@ static HMENU systray_menu, session_menu; static int already_running; static int requested_help; -static char *help_path; +char *help_path; static char *putty_path; #define IDM_PUTTY 0x0060 @@ -58,6 +61,23 @@ static char *putty_path; #define PUTTY_DEFAULT "Default%20Settings" static int initial_menuitems_count; +/* + * Print a modal (Really Bad) message box and perform a fatal exit. + */ +void modalfatalbox(char *fmt, ...) +{ + va_list ap; + char *buf; + + va_start(ap, fmt); + buf = dupvprintf(fmt, ap); + va_end(ap); + MessageBox(main_hwnd, buf, "Pageant Fatal Error", + MB_SYSTEMMODAL | MB_ICONERROR | MB_OK); + sfree(buf); + exit(1); +} + /* Un-munge session names out of the registry. */ static void unmungestr(char *in, char *out, int outlen) { @@ -95,18 +115,12 @@ static gsi_fn_t getsecurityinfo; #endif /* - * Exports from pageantc.c - */ -void agent_query(void *in, int inlen, void **out, int *outlen); -int agent_exists(void); - -/* * Forward references */ static void *make_keylist1(int *length); static void *make_keylist2(int *length); -static void *get_keylist1(void); -static void *get_keylist2(void); +static void *get_keylist1(int *length); +static void *get_keylist2(int *length); /* * We need this to link with the RSA code, because rsaencrypt() @@ -136,14 +150,6 @@ struct blob { }; static int cmpkeys_ssh2_asymm(void *av, void *bv); -/* - * This function is needed to link with the DES code. We need not - * have it do anything at all. - */ -void logevent(char *msg) -{ -} - #define GET_32BIT(cp) \ (((unsigned long)(unsigned char)(cp)[0] << 24) | \ ((unsigned long)(unsigned char)(cp)[1] << 16) | \ @@ -220,7 +226,7 @@ static int CALLBACK AboutProc(HWND hwnd, UINT msg, return 0; case 101: EnableWindow(hwnd, 0); - DialogBox(instance, MAKEINTRESOURCE(214), NULL, LicenceProc); + DialogBox(instance, MAKEINTRESOURCE(214), hwnd, LicenceProc); EnableWindow(hwnd, 1); SetActiveWindow(hwnd); return 0; @@ -380,7 +386,7 @@ static void keylist_update(void) /* * This function loads a key from a file and adds it. */ -static void add_keyfile(char *filename) +static void add_keyfile(Filename filename) { char passphrase[PASSPHRASE_MAXLEN]; struct RSAKey *rkey = NULL; @@ -393,7 +399,7 @@ static void add_keyfile(char *filename) int type; int original_pass; - type = key_type(filename); + type = key_type(&filename); if (type != SSH_KEYTYPE_SSH1 && type != SSH_KEYTYPE_SSH2) { char msg[256]; sprintf(msg, "Couldn't load this key (%s)", key_type_to_str(type)); @@ -408,35 +414,41 @@ static void add_keyfile(char *filename) { void *blob; unsigned char *keylist, *p; - int i, nkeys, bloblen; + int i, nkeys, bloblen, keylistlen; if (type == SSH_KEYTYPE_SSH1) { - if (!rsakey_pubblob(filename, &blob, &bloblen)) { + if (!rsakey_pubblob(&filename, &blob, &bloblen, NULL)) { MessageBox(NULL, "Couldn't load private key.", APPNAME, MB_OK | MB_ICONERROR); return; } - keylist = get_keylist1(); + keylist = get_keylist1(&keylistlen); } else { unsigned char *blob2; - blob = ssh2_userkey_loadpub(filename, NULL, &bloblen); + blob = ssh2_userkey_loadpub(&filename, NULL, &bloblen, NULL); if (!blob) { MessageBox(NULL, "Couldn't load private key.", APPNAME, MB_OK | MB_ICONERROR); return; } /* For our purposes we want the blob prefixed with its length */ - blob2 = smalloc(bloblen+4); + blob2 = snewn(bloblen+4, unsigned char); PUT_32BIT(blob2, bloblen); memcpy(blob2 + 4, blob, bloblen); sfree(blob); blob = blob2; - keylist = get_keylist2(); + keylist = get_keylist2(&keylistlen); } if (keylist) { + if (keylistlen < 4) { + MessageBox(NULL, "Received broken key list?!", APPNAME, + MB_OK | MB_ICONERROR); + return; + } nkeys = GET_32BIT(keylist); p = keylist + 4; + keylistlen -= 4; for (i = 0; i < nkeys; i++) { if (!memcmp(blob, p, bloblen)) { @@ -446,12 +458,48 @@ static void add_keyfile(char *filename) return; } /* Now skip over public blob */ - if (type == SSH_KEYTYPE_SSH1) - p += rsa_public_blob_len(p); - else - p += 4 + GET_32BIT(p); + if (type == SSH_KEYTYPE_SSH1) { + int n = rsa_public_blob_len(p, keylistlen); + if (n < 0) { + MessageBox(NULL, "Received broken key list?!", APPNAME, + MB_OK | MB_ICONERROR); + return; + } + p += n; + keylistlen -= n; + } else { + int n; + if (keylistlen < 4) { + MessageBox(NULL, "Received broken key list?!", APPNAME, + MB_OK | MB_ICONERROR); + return; + } + n = 4 + GET_32BIT(p); + if (keylistlen < n) { + MessageBox(NULL, "Received broken key list?!", APPNAME, + MB_OK | MB_ICONERROR); + return; + } + p += n; + keylistlen -= n; + } /* Now skip over comment field */ - p += 4 + GET_32BIT(p); + { + int n; + if (keylistlen < 4) { + MessageBox(NULL, "Received broken key list?!", APPNAME, + MB_OK | MB_ICONERROR); + return; + } + n = 4 + GET_32BIT(p); + if (keylistlen < n) { + MessageBox(NULL, "Received broken key list?!", APPNAME, + MB_OK | MB_ICONERROR); + return; + } + p += n; + keylistlen -= n; + } } sfree(keylist); @@ -461,12 +509,12 @@ static void add_keyfile(char *filename) } if (type == SSH_KEYTYPE_SSH1) - needs_pass = rsakey_encrypted(filename, &comment); + needs_pass = rsakey_encrypted(&filename, &comment); else - needs_pass = ssh2_userkey_encrypted(filename, &comment); + needs_pass = ssh2_userkey_encrypted(&filename, &comment); attempts = 0; if (type == SSH_KEYTYPE_SSH1) - rkey = smalloc(sizeof(*rkey)); + rkey = snew(struct RSAKey); pps.passphrase = passphrase; pps.comment = comment; original_pass = 0; @@ -493,9 +541,9 @@ static void add_keyfile(char *filename) } else *passphrase = '\0'; if (type == SSH_KEYTYPE_SSH1) - ret = loadrsakey(filename, rkey, passphrase); + ret = loadrsakey(&filename, rkey, passphrase, NULL); else { - skey = ssh2_load_userkey(filename, passphrase); + skey = ssh2_load_userkey(&filename, passphrase, NULL); if (skey == SSH2_WRONG_PASSPHRASE) ret = -1; else if (!skey) @@ -525,7 +573,7 @@ static void add_keyfile(char *filename) if (already_running) { unsigned char *request, *response; void *vresponse; - int reqlen, clen, resplen; + int reqlen, clen, resplen, ret; clen = strlen(rkey->comment); @@ -539,7 +587,7 @@ static void add_keyfile(char *filename) ssh1_bignum_length(rkey->q) + 4 + clen /* comment */ ; - request = smalloc(reqlen); + request = snewn(reqlen, unsigned char); request[4] = SSH1_AGENTC_ADD_RSA_IDENTITY; reqlen = 5; @@ -558,7 +606,9 @@ static void add_keyfile(char *filename) reqlen += 4 + clen; PUT_32BIT(request, reqlen - 4); - agent_query(request, reqlen, &vresponse, &resplen); + ret = agent_query(request, reqlen, &vresponse, &resplen, + NULL, NULL); + assert(ret == 1); response = vresponse; if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) MessageBox(NULL, "The already running Pageant " @@ -575,7 +625,7 @@ static void add_keyfile(char *filename) if (already_running) { unsigned char *request, *response; void *vresponse; - int reqlen, alglen, clen, keybloblen, resplen; + int reqlen, alglen, clen, keybloblen, resplen, ret; alglen = strlen(skey->alg->name); clen = strlen(skey->comment); @@ -587,7 +637,7 @@ static void add_keyfile(char *filename) 4 + clen /* comment */ ; - request = smalloc(reqlen); + request = snewn(reqlen, unsigned char); request[4] = SSH2_AGENTC_ADD_IDENTITY; reqlen = 5; @@ -600,13 +650,15 @@ static void add_keyfile(char *filename) keybloblen); PUT_32BIT(request + reqlen, clen); memcpy(request + reqlen + 4, skey->comment, clen); - PUT_32BIT(request, reqlen - 4); reqlen += clen + 4; + PUT_32BIT(request, reqlen - 4); - agent_query(request, reqlen, &vresponse, &resplen); + ret = agent_query(request, reqlen, &vresponse, &resplen, + NULL, NULL); + assert(ret == 1); response = vresponse; if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) - MessageBox(NULL, "The already running Pageant" + MessageBox(NULL, "The already running Pageant " "refused to add the key.", APPNAME, MB_OK | MB_ICONERROR); @@ -646,7 +698,7 @@ static void *make_keylist1(int *length) } /* Allocate the buffer. */ - p = ret = smalloc(len); + p = ret = snewn(len, unsigned char); if (length) *length = len; PUT_32BIT(p, nkeys); @@ -691,7 +743,7 @@ static void *make_keylist2(int *length) } /* Allocate the buffer. */ - p = ret = smalloc(len); + p = ret = snewn(len, unsigned char); if (length) *length = len; /* @@ -721,27 +773,31 @@ static void *make_keylist2(int *length) * calling make_keylist1 (if that's us) or sending a message to the * primary Pageant (if it's not). */ -static void *get_keylist1(void) +static void *get_keylist1(int *length) { void *ret; if (already_running) { unsigned char request[5], *response; void *vresponse; - int resplen; + int resplen, retval; request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES; PUT_32BIT(request, 4); - agent_query(request, 5, &vresponse, &resplen); + retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL); + assert(retval == 1); response = vresponse; if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER) return NULL; - ret = smalloc(resplen-5); + ret = snewn(resplen-5, unsigned char); memcpy(ret, response+5, resplen-5); sfree(response); + + if (length) + *length = resplen-5; } else { - ret = make_keylist1(NULL); + ret = make_keylist1(length); } return ret; } @@ -751,28 +807,32 @@ static void *get_keylist1(void) * calling make_keylist2 (if that's us) or sending a message to the * primary Pageant (if it's not). */ -static void *get_keylist2(void) +static void *get_keylist2(int *length) { void *ret; if (already_running) { unsigned char request[5], *response; void *vresponse; - int resplen; + int resplen, retval; request[4] = SSH2_AGENTC_REQUEST_IDENTITIES; PUT_32BIT(request, 4); - agent_query(request, 5, &vresponse, &resplen); + retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL); + assert(retval == 1); response = vresponse; if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER) return NULL; - ret = smalloc(resplen-5); + ret = snewn(resplen-5, unsigned char); memcpy(ret, response+5, resplen-5); sfree(response); + + if (length) + *length = resplen-5; } else { - ret = make_keylist2(NULL); + ret = make_keylist2(length); } return ret; } @@ -784,11 +844,19 @@ static void answer_msg(void *msg) { unsigned char *p = msg; unsigned char *ret = msg; + unsigned char *msgend; int type; /* + * Get the message length. + */ + msgend = p + 4 + GET_32BIT(p); + + /* * Get the message type. */ + if (msgend < p+5) + goto failure; type = p[4]; p += 5; @@ -845,12 +913,28 @@ static void answer_msg(void *msg) int i, len; p += 4; - p += ssh1_read_bignum(p, &reqkey.exponent); - p += ssh1_read_bignum(p, &reqkey.modulus); - p += ssh1_read_bignum(p, &challenge); + i = ssh1_read_bignum(p, msgend - p, &reqkey.exponent); + if (i < 0) + goto failure; + p += i; + i = ssh1_read_bignum(p, msgend - p, &reqkey.modulus); + if (i < 0) + goto failure; + p += i; + i = ssh1_read_bignum(p, msgend - p, &challenge); + if (i < 0) + goto failure; + p += i; + if (msgend < p+16) { + freebn(reqkey.exponent); + freebn(reqkey.modulus); + freebn(challenge); + goto failure; + } memcpy(response_source + 32, p, 16); p += 16; - if (GET_32BIT(p) != 1 || + if (msgend < p+4 || + GET_32BIT(p) != 1 || (key = find234(rsakeys, &reqkey, NULL)) == NULL) { freebn(reqkey.exponent); freebn(reqkey.modulus); @@ -892,12 +976,20 @@ static void answer_msg(void *msg) unsigned char *data, *signature; int datalen, siglen, len; + if (msgend < p+4) + goto failure; b.len = GET_32BIT(p); p += 4; + if (msgend < p+b.len) + goto failure; b.blob = p; p += b.len; + if (msgend < p+4) + goto failure; datalen = GET_32BIT(p); p += 4; + if (msgend < p+datalen) + goto failure; data = p; key = find234(ssh2keys, &b, cmpkeys_ssh2_asymm); if (!key) @@ -919,16 +1011,65 @@ static void answer_msg(void *msg) { struct RSAKey *key; char *comment; - int commentlen; - key = smalloc(sizeof(struct RSAKey)); + int n, commentlen; + + key = snew(struct RSAKey); 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 */ + + n = makekey(p, msgend - p, key, NULL, 1); + if (n < 0) { + freersakey(key); + sfree(key); + goto failure; + } + p += n; + + n = makeprivate(p, msgend - p, key); + if (n < 0) { + freersakey(key); + sfree(key); + goto failure; + } + p += n; + + n = ssh1_read_bignum(p, msgend - p, &key->iqmp); /* p^-1 mod q */ + if (n < 0) { + freersakey(key); + sfree(key); + goto failure; + } + p += n; + + n = ssh1_read_bignum(p, msgend - p, &key->p); /* p */ + if (n < 0) { + freersakey(key); + sfree(key); + goto failure; + } + p += n; + + n = ssh1_read_bignum(p, msgend - p, &key->q); /* q */ + if (n < 0) { + freersakey(key); + sfree(key); + goto failure; + } + p += n; + + if (msgend < p+4) { + freersakey(key); + sfree(key); + goto failure; + } commentlen = GET_32BIT(p); - comment = smalloc(commentlen+1); + + if (msgend < p+commentlen) { + freersakey(key); + sfree(key); + goto failure; + } + + comment = snewn(commentlen+1, char); if (comment) { memcpy(comment, p + 4, commentlen); comment[commentlen] = '\0'; @@ -956,12 +1097,17 @@ static void answer_msg(void *msg) int alglen, commlen; int bloblen; - key = smalloc(sizeof(struct ssh2_userkey)); + if (msgend < p+4) + goto failure; alglen = GET_32BIT(p); p += 4; + if (msgend < p+alglen) + goto failure; alg = p; p += alglen; + + key = snew(struct ssh2_userkey); /* Add further algorithm names here. */ if (alglen == 7 && !memcmp(alg, "ssh-rsa", 7)) key->alg = &ssh_rsa; @@ -972,19 +1118,33 @@ static void answer_msg(void *msg) goto failure; } - bloblen = - GET_32BIT((unsigned char *) msg) - (p - - (unsigned char *) msg - - 4); + bloblen = msgend - p; key->data = key->alg->openssh_createkey(&p, &bloblen); if (!key->data) { sfree(key); goto failure; } + + /* + * p has been advanced by openssh_createkey, but + * certainly not _beyond_ the end of the buffer. + */ + assert(p <= msgend); + + if (msgend < p+4) { + key->alg->freekey(key->data); + sfree(key); + goto failure; + } commlen = GET_32BIT(p); p += 4; - comment = smalloc(commlen + 1); + if (msgend < p+commlen) { + key->alg->freekey(key->data); + sfree(key); + goto failure; + } + comment = snewn(commlen + 1, char); if (comment) { memcpy(comment, p, commlen); comment[commlen] = '\0'; @@ -1011,8 +1171,12 @@ static void answer_msg(void *msg) */ { struct RSAKey reqkey, *key; + int n; + + n = makekey(p, msgend - p, &reqkey, NULL, 0); + if (n < 0) + goto failure; - p += makekey(p, &reqkey, NULL, 0); key = find234(rsakeys, &reqkey, NULL); freebn(reqkey.exponent); freebn(reqkey.modulus); @@ -1037,10 +1201,16 @@ static void answer_msg(void *msg) struct ssh2_userkey *key; struct blob b; + if (msgend < p+4) + goto failure; b.len = GET_32BIT(p); p += 4; + + if (msgend < p+b.len) + goto failure; b.blob = p; p += b.len; + key = find234(ssh2keys, &b, cmpkeys_ssh2_asymm); if (!key) goto failure; @@ -1229,7 +1399,7 @@ static void prompt_add_keyfile(void) { OPENFILENAME of; char filename[FILENAME_MAX]; - char *filelist = smalloc(8192); + char *filelist = snewn(8192, char); char *filewalker; int n, dirlen; @@ -1240,7 +1410,8 @@ static void prompt_add_keyfile(void) of.lStructSize = sizeof(of); #endif of.hwndOwner = main_hwnd; - of.lpstrFilter = "All Files\0*\0\0\0"; + of.lpstrFilter = "PuTTY Private Key Files (*.ppk)\0*.ppk\0" + "All Files (*.*)\0*\0\0\0"; of.lpstrCustomFilter = NULL; of.nFilterIndex = 1; of.lpstrFile = filelist; @@ -1253,7 +1424,7 @@ static void prompt_add_keyfile(void) if (GetOpenFileName(&of)) { if(strlen(filelist) > of.nFileOffset) /* Only one filename returned? */ - add_keyfile(filelist); + add_keyfile(filename_from_str(filelist)); else { /* we are returned a bunch of strings, end to * end. first string is the directory, the @@ -1281,7 +1452,7 @@ static void prompt_add_keyfile(void) memcpy(filename + dirlen, filewalker, n); filewalker += n; - add_keyfile(filename); + add_keyfile(filename_from_str(filename)); } } @@ -1375,7 +1546,7 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg, } /* get item indices in an array */ - selectedArray = smalloc(numSelected * sizeof(int)); + selectedArray = snewn(numSelected, int); SendDlgItemMessage(hwnd, 100, LB_GETSELITEMS, numSelected, (WPARAM)selectedArray); @@ -1595,14 +1766,17 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, keylist = CreateDialog(instance, MAKEINTRESOURCE(211), NULL, KeyListProc); ShowWindow(keylist, SW_SHOWNORMAL); - /* - * Sometimes the window comes up minimised / hidden - * for no obvious reason. Prevent this. - */ - SetForegroundWindow(keylist); - SetWindowPos(keylist, HWND_TOP, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); } + /* + * Sometimes the window comes up minimised / hidden for + * no obvious reason. Prevent this. This also brings it + * to the front if it's already present (the user + * selected View Keys because they wanted to _see_ the + * thing). + */ + SetForegroundWindow(keylist); + SetWindowPos(keylist, HWND_TOP, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); break; case IDM_ADDKEY: if (passphrase_box) { @@ -1769,31 +1943,47 @@ void spawn_cmd(char *cmdline, char * args, int show) { if (ShellExecute(NULL, _T("open"), cmdline, args, NULL, show) <= (HINSTANCE) 32) { - TCHAR sMsg[140]; - sprintf(sMsg, _T("Failed to run \"%.100s\", Error: %d"), cmdline, - (int)GetLastError()); - MessageBox(NULL, sMsg, APPNAME, MB_OK | MB_ICONEXCLAMATION); + char *msg; + msg = dupprintf("Failed to run \"%.100s\", Error: %d", cmdline, + (int)GetLastError()); + MessageBox(NULL, msg, APPNAME, MB_OK | MB_ICONEXCLAMATION); + sfree(msg); } } +/* + * This is a can't-happen stub, since Pageant never makes + * asynchronous agent requests. + */ +void agent_schedule_callback(void (*callback)(void *, void *, int), + void *callback_ctx, void *data, int len) +{ + assert(!"We shouldn't get here"); +} + void cleanup_exit(int code) { exit(code); } +int flags = FLAG_SYNCAGENT; + int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { WNDCLASS wndclass; MSG msg; - OSVERSIONINFO osi; HMODULE advapi; char *command = NULL; int added_keys = 0; + int argc, i; + char **argv, **argstart; /* * Determine whether we're an NT system (should have security * APIs) or a non-NT system (don't do security). */ - memset(&osi, 0, sizeof(OSVERSIONINFO)); - osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (GetVersionEx(&osi) && osi.dwPlatformId == VER_PLATFORM_WIN32_NT) { + if (!init_winver()) + { + modalfatalbox("Windows refuses to report a version"); + } + if (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) { has_security = TRUE; } else has_security = FALSE; @@ -1936,46 +2126,23 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) /* * Process the command line and add keys as listed on it. - * If we already determined that we need to spawn a program from above we - * need to ignore the first two arguments. [DBW] */ - { - char *p; - int inquotes = 0; - p = cmdline; - while (*p) { - while (*p && isspace(*p)) - p++; - if (*p && !isspace(*p)) { - char *q = p, *pp = p; - while (*p && (inquotes || !isspace(*p))) { - if (*p == '"') { - inquotes = !inquotes; - p++; - continue; - } - *pp++ = *p++; - } - if (*pp) { - if (*p) - p++; - *pp++ = '\0'; - } - if (!strcmp(q, "-c")) { - /* - * If we see `-c', then the rest of the - * command line should be treated as a - * command to be spawned. - */ - while (*p && isspace(*p)) - p++; - command = p; - break; - } else { - add_keyfile(q); - added_keys = TRUE; - } - } + split_into_argv(cmdline, &argc, &argv, &argstart); + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-c")) { + /* + * If we see `-c', then the rest of the + * command line should be treated as a + * command to be spawned. + */ + if (i < argc-1) + command = argstart[i+1]; + else + command = ""; + break; + } else { + add_keyfile(filename_from_str(argv[i])); + added_keys = TRUE; } } @@ -2017,8 +2184,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) * Main message loop. */ while (GetMessage(&msg, NULL, 0, 0) == 1) { - TranslateMessage(&msg); - DispatchMessage(&msg); + if (!(IsWindow(keylist) && IsDialogMessage(keylist, &msg)) && + !(IsWindow(aboutbox) && IsDialogMessage(aboutbox, &msg))) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } /* Clean up the system tray icon */