📄 puttygen.c
字号:
state->collecting_entropy = FALSE;
SetDlgItemText(hwnd, IDC_GENERATING, generating_msg);
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE, 0,
MAKELPARAM(0, PROGRESSRANGE));
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, 0, 0);
params = snew(struct rsa_key_thread_params);
params->progressbar = GetDlgItem(hwnd, IDC_PROGRESS);
params->dialog = hwnd;
params->keysize = state->keysize;
params->is_dsa = state->is_dsa;
params->key = &state->key;
params->dsskey = &state->dsskey;
if (!CreateThread(NULL, 0, generate_rsa_key_thread,
params, 0, &threadid)) {
MessageBox(hwnd, "Out of thread resources",
"Key generation error",
MB_OK | MB_ICONERROR);
sfree(params);
} else {
state->generation_thread_exists = TRUE;
}
}
}
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_KEYSSH1:
case IDC_KEYSSH2RSA:
case IDC_KEYSSH2DSA:
{
state = (struct MainDlgState *)
GetWindowLong(hwnd, GWL_USERDATA);
if (!IsDlgButtonChecked(hwnd, LOWORD(wParam)))
CheckRadioButton(hwnd, IDC_KEYSSH1, IDC_KEYSSH2DSA,
LOWORD(wParam));
CheckMenuRadioItem(state->keymenu, IDC_KEYSSH1, IDC_KEYSSH2DSA,
LOWORD(wParam), MF_BYCOMMAND);
}
break;
case IDC_QUIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
case IDC_COMMENTEDIT:
if (HIWORD(wParam) == EN_CHANGE) {
state = (struct MainDlgState *)
GetWindowLong(hwnd, GWL_USERDATA);
if (state->key_exists) {
HWND editctl = GetDlgItem(hwnd, IDC_COMMENTEDIT);
int len = GetWindowTextLength(editctl);
if (*state->commentptr)
sfree(*state->commentptr);
*state->commentptr = snewn(len + 1, char);
GetWindowText(editctl, *state->commentptr, len + 1);
if (state->ssh2) {
setupbigedit2(hwnd, IDC_KEYDISPLAY, IDC_PKSTATIC,
&state->ssh2key);
} else {
setupbigedit1(hwnd, IDC_KEYDISPLAY, IDC_PKSTATIC,
&state->key);
}
}
}
break;
case IDC_ABOUT:
EnableWindow(hwnd, 0);
DialogBox(hinst, MAKEINTRESOURCE(213), hwnd, AboutProc);
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:
if (HIWORD(wParam) != BN_CLICKED &&
HIWORD(wParam) != BN_DOUBLECLICKED)
break;
state =
(struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
if (!state->generation_thread_exists) {
BOOL ok;
state->keysize = GetDlgItemInt(hwnd, IDC_BITS, &ok, FALSE);
if (!ok)
state->keysize = DEFAULT_KEYSIZE;
/* If we ever introduce a new key type, check it here! */
state->ssh2 = !IsDlgButtonChecked(hwnd, IDC_KEYSSH1);
state->is_dsa = IsDlgButtonChecked(hwnd, IDC_KEYSSH2DSA);
if (state->keysize < 256) {
int ret = MessageBox(hwnd,
"PuTTYgen will not generate a key"
" smaller than 256 bits.\n"
"Key length reset to 256. Continue?",
"PuTTYgen Warning",
MB_ICONWARNING | MB_OKCANCEL);
if (ret != IDOK)
break;
state->keysize = 256;
SetDlgItemInt(hwnd, IDC_BITS, 256, FALSE);
}
ui_set_state(hwnd, state, 1);
SetDlgItemText(hwnd, IDC_GENERATING, entropy_msg);
state->key_exists = FALSE;
state->collecting_entropy = TRUE;
/*
* My brief statistical tests on mouse movements
* suggest that there are about 2.5 bits of
* randomness in the x position, 2.5 in the y
* position, and 1.7 in the message time, making
* 5.7 bits of unpredictability per mouse movement.
* However, other people have told me it's far less
* than that, so I'm going to be stupidly cautious
* and knock that down to a nice round 2. With this
* method, we require two words per mouse movement,
* so with 2 bits per mouse movement we expect 2
* bits every 2 words.
*/
state->entropy_required = (state->keysize / 2) * 2;
state->entropy_got = 0;
state->entropy_size = (state->entropy_required *
sizeof(unsigned));
state->entropy = snewn(state->entropy_required, unsigned);
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE, 0,
MAKELPARAM(0, state->entropy_required));
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, 0, 0);
}
break;
case IDC_SAVE:
case IDC_EXPORT_OPENSSH:
case IDC_EXPORT_SSHCOM:
if (HIWORD(wParam) != BN_CLICKED)
break;
state =
(struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
if (state->key_exists) {
char filename[FILENAME_MAX];
char passphrase[PASSPHRASE_MAXLEN];
char passphrase2[PASSPHRASE_MAXLEN];
int type, realtype;
if (state->ssh2)
realtype = SSH_KEYTYPE_SSH2;
else
realtype = SSH_KEYTYPE_SSH1;
if (LOWORD(wParam) == IDC_EXPORT_OPENSSH)
type = SSH_KEYTYPE_OPENSSH;
else if (LOWORD(wParam) == IDC_EXPORT_SSHCOM)
type = SSH_KEYTYPE_SSHCOM;
else
type = realtype;
if (type != realtype &&
import_target_type(type) != realtype) {
char msg[256];
sprintf(msg, "Cannot export an SSH%d key in an SSH%d"
" format", (state->ssh2 ? 2 : 1),
(state->ssh2 ? 1 : 2));
MessageBox(hwnd, msg,
"PuTTYgen Error", MB_OK | MB_ICONERROR);
break;
}
GetDlgItemText(hwnd, IDC_PASSPHRASE1EDIT,
passphrase, sizeof(passphrase));
GetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT,
passphrase2, sizeof(passphrase2));
if (strcmp(passphrase, passphrase2)) {
MessageBox(hwnd,
"The two passphrases given do not match.",
"PuTTYgen Error", MB_OK | MB_ICONERROR);
break;
}
if (!*passphrase) {
int ret;
ret = MessageBox(hwnd,
"Are you sure you want to save this key\n"
"without a passphrase to protect it?",
"PuTTYgen Warning",
MB_YESNO | MB_ICONWARNING);
if (ret != IDYES)
break;
}
if (prompt_keyfile(hwnd, "Save private key as:",
filename, 1, (type == realtype))) {
int ret;
FILE *fp = fopen(filename, "r");
if (fp) {
char *buffer;
fclose(fp);
buffer = dupprintf("Overwrite existing file\n%s?",
filename);
ret = MessageBox(hwnd, buffer, "PuTTYgen Warning",
MB_YESNO | MB_ICONWARNING);
sfree(buffer);
if (ret != IDYES)
break;
}
if (state->ssh2) {
Filename fn = filename_from_str(filename);
if (type != realtype)
ret = export_ssh2(&fn, type, &state->ssh2key,
*passphrase ? passphrase : NULL);
else
ret = ssh2_save_userkey(&fn, &state->ssh2key,
*passphrase ? passphrase :
NULL);
} else {
Filename fn = filename_from_str(filename);
if (type != realtype)
ret = export_ssh1(&fn, type, &state->key,
*passphrase ? passphrase : NULL);
else
ret = saversakey(&fn, &state->key,
*passphrase ? passphrase : NULL);
}
if (ret <= 0) {
MessageBox(hwnd, "Unable to save key file",
"PuTTYgen Error", MB_OK | MB_ICONERROR);
}
}
}
break;
case IDC_SAVEPUB:
if (HIWORD(wParam) != BN_CLICKED)
break;
state =
(struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
if (state->key_exists) {
char filename[FILENAME_MAX];
if (prompt_keyfile(hwnd, "Save public key as:",
filename, 1, 0)) {
int ret;
FILE *fp = fopen(filename, "r");
if (fp) {
char *buffer;
fclose(fp);
buffer = dupprintf("Overwrite existing file\n%s?",
filename);
ret = MessageBox(hwnd, buffer, "PuTTYgen Warning",
MB_YESNO | MB_ICONWARNING);
sfree(buffer);
if (ret != IDYES)
break;
}
if (state->ssh2) {
ret = save_ssh2_pubkey(filename, &state->ssh2key);
} else {
ret = save_ssh1_pubkey(filename, &state->key);
}
if (ret <= 0) {
MessageBox(hwnd, "Unable to save key file",
"PuTTYgen Error", MB_OK | MB_ICONERROR);
}
}
}
break;
case IDC_LOAD:
case IDC_IMPORT:
if (HIWORD(wParam) != BN_CLICKED)
break;
state =
(struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
if (!state->generation_thread_exists) {
char filename[FILENAME_MAX];
if (prompt_keyfile(hwnd, "Load private key:",
filename, 0, LOWORD(wParam)==IDC_LOAD))
load_key_file(hwnd, state, filename_from_str(filename),
LOWORD(wParam) != IDC_LOAD);
}
break;
}
return 0;
case WM_DONEKEY:
state = (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
state->generation_thread_exists = FALSE;
state->key_exists = TRUE;
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE, 0,
MAKELPARAM(0, PROGRESSRANGE));
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, PROGRESSRANGE, 0);
if (state->ssh2) {
if (state->is_dsa) {
state->ssh2key.data = &state->dsskey;
state->ssh2key.alg = &ssh_dss;
} else {
state->ssh2key.data = &state->key;
state->ssh2key.alg = &ssh_rsa;
}
state->commentptr = &state->ssh2key.comment;
} else {
state->commentptr = &state->key.comment;
}
/*
* Invent a comment for the key. We'll do this by including
* the date in it. This will be so horrifyingly ugly that
* the user will immediately want to change it, which is
* what we want :-)
*/
*state->commentptr = snewn(30, char);
{
time_t t;
struct tm *tm;
time(&t);
tm = localtime(&t);
if (state->is_dsa)
strftime(*state->commentptr, 30, "dsa-key-%Y%m%d", tm);
else
strftime(*state->commentptr, 30, "rsa-key-%Y%m%d", tm);
}
/*
* Now update the key controls with all the key data.
*/
{
char *savecomment;
/*
* Blank passphrase, initially. This isn't dangerous,
* because we will warn (Are You Sure?) before allowing
* the user to save an unprotected private key.
*/
SetDlgItemText(hwnd, IDC_PASSPHRASE1EDIT, "");
SetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT, "");
/*
* Set the comment.
*/
SetDlgItemText(hwnd, IDC_COMMENTEDIT, *state->commentptr);
/*
* Set the key fingerprint.
*/
savecomment = *state->commentptr;
*state->commentptr = NULL;
if (state->ssh2) {
char *fp;
fp = state->ssh2key.alg->fingerprint(state->ssh2key.data);
SetDlgItemText(hwnd, IDC_FINGERPRINT, fp);
sfree(fp);
} else {
char buf[128];
rsa_fingerprint(buf, sizeof(buf), &state->key);
SetDlgItemText(hwnd, IDC_FINGERPRINT, buf);
}
*state->commentptr = savecomment;
/*
* Construct a decimal representation of the key, for
* pasting into .ssh/authorized_keys or
* .ssh/authorized_keys2 on a Unix box.
*/
if (state->ssh2) {
setupbigedit2(hwnd, IDC_KEYDISPLAY,
IDC_PKSTATIC, &state->ssh2key);
} else {
setupbigedit1(hwnd, IDC_KEYDISPLAY,
IDC_PKSTATIC, &state->key);
}
}
/*
* Finally, hide the progress bar and show the key data.
*/
ui_set_state(hwnd, state, 2);
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;
case IDC_IMPORT:
case IDC_EXPORT_OPENSSH:
case IDC_EXPORT_SSHCOM:
cmd = "JI(`',`puttygen.conversions')"; 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)
{
int argc;
char **argv;
split_into_argv(cmdline, &argc, &argv, NULL);
if (argc > 0) {
/*
* Assume the first argument to be a private key file, and
* attempt to load it.
*/
cmdline_keyfile = argv[0];
}
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -