📄 pageant.c
字号:
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; else if (alglen == 7 && !memcmp(alg, "ssh-dss", 7)) key->alg = &ssh_dss; else { sfree(key); goto failure; } 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; 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'; } key->comment = comment; PUT_32BIT(ret, 1); ret[4] = SSH_AGENT_FAILURE; if (add234(ssh2keys, key) == key) { keylist_update(); ret[4] = SSH_AGENT_SUCCESS; } else { key->alg->freekey(key->data); sfree(key->comment); sfree(key); } } break; case SSH1_AGENTC_REMOVE_RSA_IDENTITY: /* * Remove from the list and return SSH_AGENT_SUCCESS, or * perhaps SSH_AGENT_FAILURE if it wasn't in the list to * start with. */ { struct RSAKey reqkey, *key; int n; n = makekey(p, msgend - p, &reqkey, NULL, 0); if (n < 0) goto failure; 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); sfree(key); ret[4] = SSH_AGENT_SUCCESS; } } break; case SSH2_AGENTC_REMOVE_IDENTITY: /* * Remove from the list and return SSH_AGENT_SUCCESS, or * perhaps SSH_AGENT_FAILURE if it wasn't in the list to * start with. */ { 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; PUT_32BIT(ret, 1); ret[4] = SSH_AGENT_FAILURE; if (key) { del234(ssh2keys, key); keylist_update(); key->alg->freekey(key->data); sfree(key); ret[4] = SSH_AGENT_SUCCESS; } } break; case SSH1_AGENTC_REMOVE_ALL_RSA_IDENTITIES: /* * Remove all SSH1 keys. Always returns success. */ { struct RSAKey *rkey; while ((rkey = index234(rsakeys, 0)) != NULL) { del234(rsakeys, rkey); freersakey(rkey); sfree(rkey); } keylist_update(); PUT_32BIT(ret, 1); ret[4] = SSH_AGENT_SUCCESS; } break; case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: /* * Remove all SSH2 keys. Always returns success. */ { struct ssh2_userkey *skey; while ((skey = index234(ssh2keys, 0)) != NULL) { del234(ssh2keys, skey); skey->alg->freekey(skey->data); sfree(skey); } keylist_update(); PUT_32BIT(ret, 1); ret[4] = SSH_AGENT_SUCCESS; } break; default: failure: /* * Unrecognised message. Return SSH_AGENT_FAILURE. */ PUT_32BIT(ret, 1); ret[4] = SSH_AGENT_FAILURE; break; }}/* * Key comparison function for the 2-3-4 tree of RSA keys. */static int cmpkeys_rsa(void *av, void *bv){ struct RSAKey *a = (struct RSAKey *) av; struct RSAKey *b = (struct RSAKey *) bv; Bignum am, bm; int alen, blen; am = a->modulus; bm = b->modulus; /* * Compare by length of moduli. */ alen = bignum_bitcount(am); blen = bignum_bitcount(bm); if (alen > blen) return +1; else if (alen < blen) return -1; /* * Now compare by moduli themselves. */ alen = (alen + 7) / 8; /* byte count */ while (alen-- > 0) { int abyte, bbyte; abyte = bignum_byte(am, alen); bbyte = bignum_byte(bm, alen); if (abyte > bbyte) return +1; else if (abyte < bbyte) return -1; } /* * Give up. */ return 0;}/* * Key comparison function for the 2-3-4 tree of SSH2 keys. */static int cmpkeys_ssh2(void *av, void *bv){ struct ssh2_userkey *a = (struct ssh2_userkey *) av; struct ssh2_userkey *b = (struct ssh2_userkey *) bv; int i; int alen, blen; unsigned char *ablob, *bblob; int c; /* * Compare purely by public blob. */ ablob = a->alg->public_blob(a->data, &alen); bblob = b->alg->public_blob(b->data, &blen); c = 0; for (i = 0; i < alen && i < blen; i++) { if (ablob[i] < bblob[i]) { c = -1; break; } else if (ablob[i] > bblob[i]) { c = +1; break; } } if (c == 0 && i < alen) c = +1; /* a is longer */ if (c == 0 && i < blen) c = -1; /* a is longer */ sfree(ablob); sfree(bblob); return c;}/* * Key comparison function for looking up a blob in the 2-3-4 tree * of SSH2 keys. */static int cmpkeys_ssh2_asymm(void *av, void *bv){ struct blob *a = (struct blob *) av; struct ssh2_userkey *b = (struct ssh2_userkey *) bv; int i; int alen, blen; unsigned char *ablob, *bblob; int c; /* * Compare purely by public blob. */ ablob = a->blob; alen = a->len; bblob = b->alg->public_blob(b->data, &blen); c = 0; for (i = 0; i < alen && i < blen; i++) { if (ablob[i] < bblob[i]) { c = -1; break; } else if (ablob[i] > bblob[i]) { c = +1; break; } } if (c == 0 && i < alen) c = +1; /* a is longer */ if (c == 0 && i < blen) c = -1; /* a is longer */ sfree(bblob); return c;}/* * Prompt for a key file to add, and add it. */static void prompt_add_keyfile(void){ OPENFILENAME of; char filename[FILENAME_MAX]; char *filelist = snewn(8192, char); char *filewalker; int n, dirlen; memset(&of, 0, sizeof(of));#ifdef OPENFILENAME_SIZE_VERSION_400 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;#else of.lStructSize = sizeof(of);#endif of.hwndOwner = main_hwnd; 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; *filelist = '\0'; of.nMaxFile = FILENAME_MAX; of.lpstrFileTitle = NULL; of.lpstrInitialDir = NULL; of.lpstrTitle = "Select Private Key File"; of.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER; if (GetOpenFileName(&of)) { if(strlen(filelist) > of.nFileOffset) /* Only one filename returned? */ add_keyfile(filename_from_str(filelist)); else { /* we are returned a bunch of strings, end to * end. first string is the directory, the * rest the filenames. terminated with an * empty string. */ filewalker = filelist; dirlen = strlen(filewalker); if(dirlen > FILENAME_MAX - 8) return; memcpy(filename, filewalker, dirlen); filewalker += dirlen + 1; filename[dirlen++] = '\\'; /* then go over names one by one */ for(;;) { n = strlen(filewalker) + 1; /* end of the list */ if(n == 1) break; /* too big, shouldn't happen */ if(n + dirlen > FILENAME_MAX) break; memcpy(filename + dirlen, filewalker, n); filewalker += n; add_keyfile(filename_from_str(filename)); } } keylist_update(); forget_passphrases(); } sfree(filelist);}/* * Dialog-box function for the key list box. */static int CALLBACK KeyListProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ struct RSAKey *rkey; struct ssh2_userkey *skey; switch (msg) { case WM_INITDIALOG: /* * Centre the window. */ { /* centre the window */ RECT rs, rd; HWND hw; hw = GetDesktopWindow(); if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd)) MoveWindow(hwnd, (rs.right + rs.left + rd.left - rd.right) / 2, (rs.bottom + rs.top + rd.top - rd.bottom) / 2, rd.right - rd.left, rd.bottom - rd.top, TRUE); } if (help_path) SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP); else { HWND item = GetDlgItem(hwnd, 103); /* the Help button */ if (item) DestroyWindow(item); } requested_help = FALSE; keylist = hwnd; { static int tabs[] = { 35, 60, 210 }; SendDlgItemMessage(hwnd, 100, LB_SETTABSTOPS, sizeof(tabs) / sizeof(*tabs), (LPARAM) tabs); } keylist_update(); return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: keylist = NULL; DestroyWindow(hwnd); return 0; 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; case 102: /* remove key */ if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) { int i; int rCount, sCount; int *selectedArray; /* our counter within the array of selected items */ int itemNum; /* get the number of items selected in the list */ int numSelected = SendDlgItemMessage(hwnd, 100, LB_GETSELCOUNT, 0, 0); /* none selected? that was silly */ if (numSelected == 0) { MessageBeep(0); break; } /* get item indices in an array */ selectedArray = snewn(numSelected, int); SendDlgItemMessage(hwnd, 100, LB_GETSELITEMS, numSelected, (WPARAM)selectedArray); itemNum = numSelected - 1; rCount = count234(rsakeys); sCount = count234(ssh2keys); /* go through the non-rsakeys until we've covered them all, * and/or we're out of selected items to check. note that * we go *backwards*, to avoid complications from deleting * things hence altering the offset of subsequent items */ for (i = sCount - 1; (itemNum >= 0) && (i >= 0); i--) { skey = index234(ssh2keys, i); if (selectedArray[itemNum] == rCount + i) { del234(ssh2keys, skey); skey->alg->freekey(skey->data); sfree(skey); itemNum--; } } /* do the same for the rsa keys */ for (i = rCount - 1; (itemNum >= 0) && (i >= 0); i--) { rkey = index234(rsakeys, i); if(selectedArray[itemNum] == i) { del234(rsakeys, rkey); freersakey(rkey); sfree(rkey); itemNum--; } } sfree(selectedArray); keylist_update(); } return 0; case 103: /* help */ if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) { if (help_path) { WinHelp(main_hwnd, help_path, HELP_COMMAND, (DWORD)"JI(`',`pageant.general')"); requested_help = TRUE; } } return 0; } return 0; case WM_HELP: if (help_path) { int id = ((LPHELPINFO)lParam)->iCtrlId; char *cmd = NULL; switch (id) { case 100: cmd = "JI(`',`pageant.keylist')"; break; case 101: cmd = "JI(`',`pageant.addkey')"; break; case 102: cmd = "JI(`',`pageant.remkey')"; break; } if (cmd) { WinHelp(main_hwnd, help_path, HELP_COMMAND, (DWORD)cmd); requested_help = TRUE; } else { MessageBeep(0); } } break; case WM_CLOSE: keylist = NULL; DestroyWindow(hwnd); return 0; } 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;}/* Update the saved-sessions menu. */static void update_sessions(void){ int num_entries; HKEY hkey; TCHAR buf[MAX_PATH + 1]; MENUITEMINFO mii;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -