X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=puttygen.c;h=e045c33563425b3ae36e2a234845cada1cc5605e;hb=9a8c58a64bd9effebee2199d3757a0bcedac83e1;hp=8a5c3c99babdce0d9ca09018fd5332d18c64cb58;hpb=d8fa043b22d291c2ec8879e6829320d72ba0a671;p=PuTTY.git diff --git a/puttygen.c b/puttygen.c index 8a5c3c99..e045c335 100644 --- a/puttygen.c +++ b/puttygen.c @@ -18,6 +18,8 @@ #define DEFAULT_KEYSIZE 1024 +static int requested_help; + /* ---------------------------------------------------------------------- * Progress report code. This is really horrible :-) */ @@ -44,6 +46,9 @@ static void progress_update(void *param, int action, int phase, int iprogress) if (action < PROGFN_READY && p->nphases < phase) p->nphases = phase; switch (action) { + case PROGFN_INITIALISE: + p->nphases = 0; + break; case PROGFN_LIN_PHASE: p->phases[phase-1].exponential = 0; p->phases[phase-1].mult = p->phases[phase].total / progress; @@ -302,6 +307,8 @@ static DWORD WINAPI generate_rsa_key_thread(void *param) struct progress prog; prog.progbar = params->progressbar; + progress_update(&prog, PROGFN_INITIALISE, 0, 0); + if (params->is_dsa) dsa_generate(params->dsskey, params->keysize, progress_update, &prog); else @@ -401,6 +408,26 @@ static int save_ssh1_pubkey(char *filename, struct RSAKey *key) return 1; } +/* + * Warn about the obsolescent key file format. + */ +void old_keyfile_warning(void) +{ + static const char mbtitle[] = "PuTTY Key File Warning"; + static const char message[] = + "You are loading an SSH 2 private key which has an\n" + "old version of the file format. This means your key\n" + "file is not fully tamperproof. Future versions of\n" + "PuTTY may stop supporting this private key format,\n" + "so we recommend you convert your key to the new\n" + "format.\n" + "\n" + "Once the key is loaded into PuTTYgen, you can perform\n" + "this conversion simply by saving it again."; + + MessageBox(NULL, message, mbtitle, MB_OK); +} + static int save_ssh2_pubkey(char *filename, struct ssh2_userkey *key) { unsigned char *pub_blob; @@ -474,6 +501,8 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, IDC_TYPESTATIC, IDC_KEYSSH1, IDC_KEYSSH2RSA, IDC_KEYSSH2DSA, IDC_BITSSTATIC, IDC_BITS, IDC_ABOUT, + IDC_GIVEHELP, + IDC_IMPORT, IDC_EXPORT_OPENSSH, IDC_EXPORT_SSHCOM }; static const int nokey_ids[] = { IDC_NOKEY, 0 }; static const int generating_ids[] = @@ -493,6 +522,55 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, switch (msg) { case WM_INITDIALOG: + if (help_path) + SetWindowLong(hwnd, GWL_EXSTYLE, + GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP); + else { + /* + * If we add a Help button, this is where we destroy it + * if the help file isn't present. + */ + } + requested_help = FALSE; + + { + HMENU menu, menu1; + + menu = CreateMenu(); + + menu1 = CreateMenu(); + AppendMenu(menu1, MF_ENABLED, IDC_GENERATE, "&Generate key pair"); + AppendMenu(menu1, MF_ENABLED, IDC_LOAD, "&Load private key"); + AppendMenu(menu1, MF_ENABLED, IDC_SAVEPUB, "Save p&ublic key"); + AppendMenu(menu1, MF_ENABLED, IDC_SAVE, "&Save private key"); + + AppendMenu(menu, MF_POPUP | MF_ENABLED, (UINT) menu1, "&File"); + +#if 0 + /* + * Exporting not yet supported, but when we do it we + * should just put this lot back in. + */ + menu1 = CreateMenu(); + AppendMenu(menu1, MF_ENABLED, IDC_EXPORT_OPENSSH, + "Export &OpenSSH key"); + AppendMenu(menu1, MF_ENABLED, IDC_EXPORT_SSHCOM, + "Export &ssh.com key"); + + AppendMenu(menu, MF_POPUP | MF_ENABLED, (UINT) menu1, + "&Export"); +#endif + + menu1 = CreateMenu(); + AppendMenu(menu1, MF_ENABLED, IDC_ABOUT, "&About"); + if (help_path) + AppendMenu(menu1, MF_ENABLED, IDC_GIVEHELP, "&Help"); + + AppendMenu(menu, MF_POPUP | MF_ENABLED, (UINT) menu1, "&Help"); + + SetMenu(hwnd, menu); + } + /* * Centre the window. */ @@ -519,9 +597,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, /* Accelerators used: acglops1rbd */ - ctlposinit(&cp, hwnd, 10, 10, 10); - bartitle(&cp, "Public and private key generation for PuTTY", - IDC_TITLE); + ctlposinit(&cp, hwnd, 4, 4, 4); beginbox(&cp, "Key", IDC_BOX_KEY); cp2 = cp; statictext(&cp2, "No key.", 1, IDC_NOKEY); @@ -530,7 +606,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, progressbar(&cp2, IDC_PROGRESS); bigeditctrl(&cp, "&Public key for pasting into authorized_keys file:", - IDC_PKSTATIC, IDC_KEYDISPLAY, 7); + IDC_PKSTATIC, IDC_KEYDISPLAY, 5); SendDlgItemMessage(hwnd, IDC_KEYDISPLAY, EM_SETREADONLY, 1, 0); staticedit(&cp, "Key fingerprint:", IDC_FPSTATIC, IDC_FINGERPRINT, 75); @@ -651,6 +727,16 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, EnableWindow(hwnd, 1); SetActiveWindow(hwnd); return 0; + case IDC_GIVEHELP: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) { + if (help_path) { + WinHelp(hwnd, help_path, HELP_COMMAND, + (DWORD)"JI(`',`puttygen.general')"); + requested_help = TRUE; + } + } + return 0; case IDC_GENERATE: state = (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA); @@ -808,26 +894,40 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, if (prompt_keyfile(hwnd, "Load private key:", filename, 0)) { char passphrase[PASSPHRASE_MAXLEN]; int needs_pass; - int ver; + int type, realtype; int ret; char *comment; struct PassphraseProcStruct pps; struct RSAKey newkey1; struct ssh2_userkey *newkey2 = NULL; - ver = keyfile_version(filename); - if (ver == 0) { - MessageBox(NULL, "Couldn't load private key.", + type = realtype = key_type(filename); + if (type != SSH_KEYTYPE_SSH1 && + type != SSH_KEYTYPE_SSH2 && + !import_possible(type)) { + char msg[256]; + sprintf(msg, "Couldn't load private key (%s)", + key_type_to_str(type)); + MessageBox(NULL, msg, "PuTTYgen Error", MB_OK | MB_ICONERROR); break; } + if (type != SSH_KEYTYPE_SSH1 && + type != SSH_KEYTYPE_SSH2) { + realtype = type; + type = import_target_type(type); + } + comment = NULL; - if (ver == 1) + if (realtype == SSH_KEYTYPE_SSH1) needs_pass = rsakey_encrypted(filename, &comment); - else + else if (realtype == SSH_KEYTYPE_SSH2) needs_pass = ssh2_userkey_encrypted(filename, &comment); + else + needs_pass = import_encrypted(filename, realtype, + &comment); pps.passphrase = passphrase; pps.comment = comment; do { @@ -843,12 +943,20 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, } } else *passphrase = '\0'; - if (ver == 1) - ret = - loadrsakey(filename, &newkey1, passphrase); - else { - newkey2 = - ssh2_load_userkey(filename, passphrase); + if (type == SSH_KEYTYPE_SSH1) { + if (realtype == type) + ret = loadrsakey(filename, &newkey1, + passphrase); + else + ret = import_ssh1(filename, realtype, + &newkey1, passphrase); + } else { + if (realtype == type) + newkey2 = ssh2_load_userkey(filename, + passphrase); + else + newkey2 = import_ssh2(filename, realtype, + passphrase); if (newkey2 == SSH2_WRONG_PASSPHRASE) ret = -1; else if (!newkey2) @@ -880,7 +988,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, passphrase); SetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT, passphrase); - if (ver == 1) { + if (type == SSH_KEYTYPE_SSH1) { char buf[128]; char *savecomment; @@ -1042,19 +1150,95 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, hidemany(hwnd, generating_ids, TRUE); hidemany(hwnd, gotkey_ids, FALSE); break; + case WM_HELP: + if (help_path) { + int id = ((LPHELPINFO)lParam)->iCtrlId; + char *cmd = NULL; + switch (id) { + case IDC_GENERATING: + case IDC_PROGRESS: + case IDC_GENSTATIC: + case IDC_GENERATE: + cmd = "JI(`',`puttygen.generate')"; break; + case IDC_PKSTATIC: + case IDC_KEYDISPLAY: + cmd = "JI(`',`puttygen.pastekey')"; break; + case IDC_FPSTATIC: + case IDC_FINGERPRINT: + cmd = "JI(`',`puttygen.fingerprint')"; break; + case IDC_COMMENTSTATIC: + case IDC_COMMENTEDIT: + cmd = "JI(`',`puttygen.comment')"; break; + case IDC_PASSPHRASE1STATIC: + case IDC_PASSPHRASE1EDIT: + case IDC_PASSPHRASE2STATIC: + case IDC_PASSPHRASE2EDIT: + cmd = "JI(`',`puttygen.passphrase')"; break; + case IDC_LOADSTATIC: + case IDC_LOAD: + cmd = "JI(`',`puttygen.load')"; break; + case IDC_SAVESTATIC: + case IDC_SAVE: + cmd = "JI(`',`puttygen.savepriv')"; break; + case IDC_SAVEPUB: + cmd = "JI(`',`puttygen.savepub')"; break; + case IDC_TYPESTATIC: + case IDC_KEYSSH1: + case IDC_KEYSSH2RSA: + case IDC_KEYSSH2DSA: + cmd = "JI(`',`puttygen.keytype')"; break; + case IDC_BITSSTATIC: + case IDC_BITS: + cmd = "JI(`',`puttygen.bits')"; break; + } + if (cmd) { + WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd); + requested_help = TRUE; + } else { + MessageBeep(0); + } + } + break; case WM_CLOSE: state = (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA); sfree(state); + if (requested_help) { + WinHelp(hwnd, help_path, HELP_QUIT, 0); + requested_help = FALSE; + } EndDialog(hwnd, 1); return 0; } return 0; } +void cleanup_exit(int code) { exit(code); } + int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { InitCommonControls(); hinst = inst; + + /* + * See if we can find our Help file. + */ + { + char b[2048], *p, *q, *r; + FILE *fp; + GetModuleFileName(NULL, b, sizeof(b) - 1); + r = b; + p = strrchr(b, '\\'); + if (p && p >= r) r = p+1; + q = strrchr(b, ':'); + if (q && q >= r) r = q+1; + strcpy(r, "putty.hlp"); + if ( (fp = fopen(b, "r")) != NULL) { + help_path = dupstr(b); + fclose(fp); + } else + help_path = NULL; + } + random_init(); return DialogBox(hinst, MAKEINTRESOURCE(201), NULL, MainDlgProc) != IDOK;