mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-21 22:28:37 -05:00
PuTTYgen will now start by loading a private key file if one is
provided on its command line. [originally from svn r1810]
This commit is contained in:
parent
452adcc952
commit
5e49e3fe1c
5
Recipe
5
Recipe
@ -124,8 +124,9 @@ pscp : [C] scp console SSH be_none SFTP wildcard MISC scp.res LIBS1
|
|||||||
psftp : [C] psftp console SSH be_none SFTP MISC scp.res LIBS1
|
psftp : [C] psftp console SSH be_none SFTP MISC scp.res LIBS1
|
||||||
|
|
||||||
pageant : [G] pageant sshrsa sshpubk sshdes sshbn sshmd5 version tree234
|
pageant : [G] pageant sshrsa sshpubk sshdes sshbn sshmd5 version tree234
|
||||||
+ misc sshaes sshsha pageantc sshdss sshsh512 pageant.res LIBS
|
+ misc sshaes sshsha pageantc sshdss sshsh512 winutils
|
||||||
|
+ pageant.res LIBS
|
||||||
|
|
||||||
puttygen : [G] puttygen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version
|
puttygen : [G] puttygen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version
|
||||||
+ sshrand noise sshsha winstore misc winctrls sshrsa sshdss
|
+ sshrand noise sshsha winstore misc winctrls sshrsa sshdss
|
||||||
+ sshpubk sshaes sshsh512 import puttygen.res LIBS
|
+ sshpubk sshaes sshsh512 import winutils puttygen.res LIBS
|
||||||
|
359
puttygen.c
359
puttygen.c
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
static int requested_help;
|
static int requested_help;
|
||||||
|
|
||||||
|
static char *cmdline_keyfile = NULL;
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* Progress report code. This is really horrible :-)
|
* Progress report code. This is really horrible :-)
|
||||||
*/
|
*/
|
||||||
@ -610,6 +612,175 @@ void ui_set_state(HWND hwnd, struct MainDlgState *state, int status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void load_key_file(HWND hwnd, struct MainDlgState *state,
|
||||||
|
char *filename, int was_import_cmd)
|
||||||
|
{
|
||||||
|
char passphrase[PASSPHRASE_MAXLEN];
|
||||||
|
int needs_pass;
|
||||||
|
int type, realtype;
|
||||||
|
int ret;
|
||||||
|
char *comment;
|
||||||
|
struct PassphraseProcStruct pps;
|
||||||
|
struct RSAKey newkey1;
|
||||||
|
struct ssh2_userkey *newkey2 = NULL;
|
||||||
|
|
||||||
|
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);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != SSH_KEYTYPE_SSH1 &&
|
||||||
|
type != SSH_KEYTYPE_SSH2) {
|
||||||
|
realtype = type;
|
||||||
|
type = import_target_type(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
comment = NULL;
|
||||||
|
if (realtype == SSH_KEYTYPE_SSH1)
|
||||||
|
needs_pass = rsakey_encrypted(filename, &comment);
|
||||||
|
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 {
|
||||||
|
if (needs_pass) {
|
||||||
|
int dlgret;
|
||||||
|
dlgret = DialogBoxParam(hinst,
|
||||||
|
MAKEINTRESOURCE(210),
|
||||||
|
NULL, PassphraseProc,
|
||||||
|
(LPARAM) & pps);
|
||||||
|
if (!dlgret) {
|
||||||
|
ret = -2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
*passphrase = '\0';
|
||||||
|
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)
|
||||||
|
ret = 0;
|
||||||
|
else
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
} while (ret == -1);
|
||||||
|
if (comment)
|
||||||
|
sfree(comment);
|
||||||
|
if (ret == 0) {
|
||||||
|
MessageBox(NULL, "Couldn't load private key.",
|
||||||
|
"PuTTYgen Error", MB_OK | MB_ICONERROR);
|
||||||
|
} else if (ret == 1) {
|
||||||
|
/*
|
||||||
|
* Now update the key controls with all the
|
||||||
|
* key data.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
SetDlgItemText(hwnd, IDC_PASSPHRASE1EDIT,
|
||||||
|
passphrase);
|
||||||
|
SetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT,
|
||||||
|
passphrase);
|
||||||
|
if (type == SSH_KEYTYPE_SSH1) {
|
||||||
|
char buf[128];
|
||||||
|
char *savecomment;
|
||||||
|
|
||||||
|
state->ssh2 = FALSE;
|
||||||
|
state->commentptr = &state->key.comment;
|
||||||
|
state->key = newkey1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the key fingerprint.
|
||||||
|
*/
|
||||||
|
savecomment = state->key.comment;
|
||||||
|
state->key.comment = NULL;
|
||||||
|
rsa_fingerprint(buf, sizeof(buf),
|
||||||
|
&state->key);
|
||||||
|
state->key.comment = savecomment;
|
||||||
|
|
||||||
|
SetDlgItemText(hwnd, IDC_FINGERPRINT, buf);
|
||||||
|
/*
|
||||||
|
* Construct a decimal representation
|
||||||
|
* of the key, for pasting into
|
||||||
|
* .ssh/authorized_keys on a Unix box.
|
||||||
|
*/
|
||||||
|
setupbigedit1(hwnd, IDC_KEYDISPLAY,
|
||||||
|
IDC_PKSTATIC, &state->key);
|
||||||
|
} else {
|
||||||
|
char *fp;
|
||||||
|
char *savecomment;
|
||||||
|
|
||||||
|
state->ssh2 = TRUE;
|
||||||
|
state->commentptr =
|
||||||
|
&state->ssh2key.comment;
|
||||||
|
state->ssh2key = *newkey2; /* structure copy */
|
||||||
|
sfree(newkey2);
|
||||||
|
|
||||||
|
savecomment = state->ssh2key.comment;
|
||||||
|
state->ssh2key.comment = NULL;
|
||||||
|
fp =
|
||||||
|
state->ssh2key.alg->
|
||||||
|
fingerprint(state->ssh2key.data);
|
||||||
|
state->ssh2key.comment = savecomment;
|
||||||
|
|
||||||
|
SetDlgItemText(hwnd, IDC_FINGERPRINT, fp);
|
||||||
|
sfree(fp);
|
||||||
|
|
||||||
|
setupbigedit2(hwnd, IDC_KEYDISPLAY,
|
||||||
|
IDC_PKSTATIC, &state->ssh2key);
|
||||||
|
}
|
||||||
|
SetDlgItemText(hwnd, IDC_COMMENTEDIT,
|
||||||
|
*state->commentptr);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Finally, hide the progress bar and show
|
||||||
|
* the key data.
|
||||||
|
*/
|
||||||
|
ui_set_state(hwnd, state, 2);
|
||||||
|
state->key_exists = TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the user has imported a foreign key
|
||||||
|
* using the Load command, let them know.
|
||||||
|
* If they've used the Import command, be
|
||||||
|
* silent.
|
||||||
|
*/
|
||||||
|
if (realtype != type && !was_import_cmd) {
|
||||||
|
char msg[512];
|
||||||
|
sprintf(msg, "Successfully imported foreign key\n"
|
||||||
|
"(%s).\n"
|
||||||
|
"To use this key with PuTTY, you need to\n"
|
||||||
|
"use the \"Save private key\" command to\n"
|
||||||
|
"save it in PuTTY's own format.",
|
||||||
|
key_type_to_str(realtype));
|
||||||
|
MessageBox(NULL, msg, "PuTTYgen Notice",
|
||||||
|
MB_OK | MB_ICONINFORMATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dialog-box function for the main PuTTYgen dialog box.
|
* Dialog-box function for the main PuTTYgen dialog box.
|
||||||
*/
|
*/
|
||||||
@ -757,6 +928,12 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
|||||||
*/
|
*/
|
||||||
ui_set_state(hwnd, state, 0);
|
ui_set_state(hwnd, state, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load a key file if one was provided on the command line.
|
||||||
|
*/
|
||||||
|
if (cmdline_keyfile)
|
||||||
|
load_key_file(hwnd, state, cmdline_keyfile, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
state = (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
|
state = (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
|
||||||
@ -1040,172 +1217,9 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
|||||||
if (!state->generation_thread_exists) {
|
if (!state->generation_thread_exists) {
|
||||||
char filename[FILENAME_MAX];
|
char filename[FILENAME_MAX];
|
||||||
if (prompt_keyfile(hwnd, "Load private key:",
|
if (prompt_keyfile(hwnd, "Load private key:",
|
||||||
filename, 0, LOWORD(wParam)==IDC_LOAD)) {
|
filename, 0, LOWORD(wParam)==IDC_LOAD))
|
||||||
char passphrase[PASSPHRASE_MAXLEN];
|
load_key_file(hwnd, state, filename,
|
||||||
int needs_pass;
|
LOWORD(wParam) != IDC_LOAD);
|
||||||
int type, realtype;
|
|
||||||
int ret;
|
|
||||||
char *comment;
|
|
||||||
struct PassphraseProcStruct pps;
|
|
||||||
struct RSAKey newkey1;
|
|
||||||
struct ssh2_userkey *newkey2 = NULL;
|
|
||||||
|
|
||||||
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 (realtype == SSH_KEYTYPE_SSH1)
|
|
||||||
needs_pass = rsakey_encrypted(filename, &comment);
|
|
||||||
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 {
|
|
||||||
if (needs_pass) {
|
|
||||||
int dlgret;
|
|
||||||
dlgret = DialogBoxParam(hinst,
|
|
||||||
MAKEINTRESOURCE(210),
|
|
||||||
NULL, PassphraseProc,
|
|
||||||
(LPARAM) & pps);
|
|
||||||
if (!dlgret) {
|
|
||||||
ret = -2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
*passphrase = '\0';
|
|
||||||
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)
|
|
||||||
ret = 0;
|
|
||||||
else
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
} while (ret == -1);
|
|
||||||
if (comment)
|
|
||||||
sfree(comment);
|
|
||||||
if (ret == 0) {
|
|
||||||
MessageBox(NULL, "Couldn't load private key.",
|
|
||||||
"PuTTYgen Error", MB_OK | MB_ICONERROR);
|
|
||||||
} else if (ret == 1) {
|
|
||||||
/*
|
|
||||||
* Now update the key controls with all the
|
|
||||||
* key data.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
SetDlgItemText(hwnd, IDC_PASSPHRASE1EDIT,
|
|
||||||
passphrase);
|
|
||||||
SetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT,
|
|
||||||
passphrase);
|
|
||||||
if (type == SSH_KEYTYPE_SSH1) {
|
|
||||||
char buf[128];
|
|
||||||
char *savecomment;
|
|
||||||
|
|
||||||
state->ssh2 = FALSE;
|
|
||||||
state->commentptr = &state->key.comment;
|
|
||||||
state->key = newkey1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the key fingerprint.
|
|
||||||
*/
|
|
||||||
savecomment = state->key.comment;
|
|
||||||
state->key.comment = NULL;
|
|
||||||
rsa_fingerprint(buf, sizeof(buf),
|
|
||||||
&state->key);
|
|
||||||
state->key.comment = savecomment;
|
|
||||||
|
|
||||||
SetDlgItemText(hwnd, IDC_FINGERPRINT, buf);
|
|
||||||
/*
|
|
||||||
* Construct a decimal representation
|
|
||||||
* of the key, for pasting into
|
|
||||||
* .ssh/authorized_keys on a Unix box.
|
|
||||||
*/
|
|
||||||
setupbigedit1(hwnd, IDC_KEYDISPLAY,
|
|
||||||
IDC_PKSTATIC, &state->key);
|
|
||||||
} else {
|
|
||||||
char *fp;
|
|
||||||
char *savecomment;
|
|
||||||
|
|
||||||
state->ssh2 = TRUE;
|
|
||||||
state->commentptr =
|
|
||||||
&state->ssh2key.comment;
|
|
||||||
state->ssh2key = *newkey2; /* structure copy */
|
|
||||||
sfree(newkey2);
|
|
||||||
|
|
||||||
savecomment = state->ssh2key.comment;
|
|
||||||
state->ssh2key.comment = NULL;
|
|
||||||
fp =
|
|
||||||
state->ssh2key.alg->
|
|
||||||
fingerprint(state->ssh2key.data);
|
|
||||||
state->ssh2key.comment = savecomment;
|
|
||||||
|
|
||||||
SetDlgItemText(hwnd, IDC_FINGERPRINT, fp);
|
|
||||||
sfree(fp);
|
|
||||||
|
|
||||||
setupbigedit2(hwnd, IDC_KEYDISPLAY,
|
|
||||||
IDC_PKSTATIC, &state->ssh2key);
|
|
||||||
}
|
|
||||||
SetDlgItemText(hwnd, IDC_COMMENTEDIT,
|
|
||||||
*state->commentptr);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Finally, hide the progress bar and show
|
|
||||||
* the key data.
|
|
||||||
*/
|
|
||||||
ui_set_state(hwnd, state, 2);
|
|
||||||
state->key_exists = TRUE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the user has imported a foreign key
|
|
||||||
* using the Load command, let them know.
|
|
||||||
* If they've used the Import command, be
|
|
||||||
* silent.
|
|
||||||
*/
|
|
||||||
if (realtype != type && LOWORD(wParam) == IDC_LOAD) {
|
|
||||||
char msg[512];
|
|
||||||
sprintf(msg, "Successfully imported foreign key\n"
|
|
||||||
"(%s).\n"
|
|
||||||
"To use this key with PuTTY, you need to\n"
|
|
||||||
"use the \"Save private key\" command to\n"
|
|
||||||
"save it in PuTTY's own format.",
|
|
||||||
key_type_to_str(realtype));
|
|
||||||
MessageBox(NULL, msg, "PuTTYgen Notice",
|
|
||||||
MB_OK | MB_ICONINFORMATION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1367,6 +1381,19 @@ void cleanup_exit(int code) { exit(code); }
|
|||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||||
{
|
{
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
|
||||||
|
split_into_argv(cmdline, &argc, &argv);
|
||||||
|
|
||||||
|
if (argc > 0) {
|
||||||
|
/*
|
||||||
|
* Assume the first argument to be a private key file, and
|
||||||
|
* attempt to load it.
|
||||||
|
*/
|
||||||
|
cmdline_keyfile = argv[0];
|
||||||
|
}
|
||||||
|
|
||||||
InitCommonControls();
|
InitCommonControls();
|
||||||
hinst = inst;
|
hinst = inst;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user