X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/5d17ccfcfb6aaa0fe7b3fb1d90ffde20a1013cc1..edd0cb8aef57080ae884e06731a7892ca8cdba44:/cmdgen.c diff --git a/cmdgen.c b/cmdgen.c index 42772aa3..36da55ee 100644 --- a/cmdgen.c +++ b/cmdgen.c @@ -25,9 +25,10 @@ * order to avoid depleting the test system's /dev/random * unnecessarily. * - * - Calls to console_get_line() are replaced with the diagnostic - * function below, so that I can run tests in an automated - * manner and provide their interactive passphrase inputs. + * - Calls to console_get_userpass_input() are replaced with the + * diagnostic function below, so that I can run tests in an + * automated manner and provide their interactive passphrase + * inputs. * * - main() is renamed to cmdgen_main(); at the bottom of the file * I define another main() which calls the former repeatedly to @@ -40,19 +41,23 @@ char *get_random_data(int len) memset(buf, 'x', len); return buf; } -#define console_get_line console_get_line_diagnostic +#define console_get_userpass_input console_get_userpass_input_diagnostic int nprompts, promptsgot; const char *prompts[3]; -int console_get_line(const char *prompt, char *str, int maxlen, int is_pw) +int console_get_userpass_input(prompts_t *p, unsigned char *in, int inlen) { - if (promptsgot < nprompts) { - assert(strlen(prompts[promptsgot]) < maxlen); - strcpy(str, prompts[promptsgot++]); - return TRUE; - } else { - promptsgot++; /* track number of requests anyway */ - return FALSE; + size_t i; + int ret = 1; + for (i = 0; i < p->n_prompts; i++) { + if (promptsgot < nprompts) { + assert(strlen(prompts[promptsgot]) < p->prompts[i]->result_len); + strcpy(p->prompts[i]->result, prompts[promptsgot++]); + } else { + promptsgot++; /* track number of requests anyway */ + ret = 0; + } } + return ret; } #define main cmdgen_main #endif @@ -313,7 +318,11 @@ int main(int argc, char **argv) } else if (!strcmp(opt, "-version")) { showversion(); nogo = TRUE; - } + } else if (!strcmp(opt, "-pgpfp")) { + /* support "-pgpfp" for consistency with others */ + pgp_fingerprints(); + nogo = TRUE; + } /* * A sample option requiring an argument: * @@ -523,7 +532,7 @@ int main(int argc, char **argv) case SSH_KEYTYPE_SSH1: if (sshver == 2) { - fprintf(stderr, "puttygen: conversion from SSH1 to SSH2 keys" + fprintf(stderr, "puttygen: conversion from SSH-1 to SSH-2 keys" " not supported\n"); return 1; } @@ -534,7 +543,7 @@ int main(int argc, char **argv) case SSH_KEYTYPE_OPENSSH: case SSH_KEYTYPE_SSHCOM: if (sshver == 1) { - fprintf(stderr, "puttygen: conversion from SSH2 to SSH1 keys" + fprintf(stderr, "puttygen: conversion from SSH-2 to SSH-1 keys" " not supported\n"); return 1; } @@ -602,19 +611,17 @@ int main(int argc, char **argv) if (keytype != NOKEYGEN) { char *entropy; char default_comment[80]; - time_t t; - struct tm *tm; + struct tm tm; struct progress prog; prog.phase = -1; prog.current = -1; - time(&t); - tm = localtime(&t); + tm = ltime(); if (keytype == DSA) - strftime(default_comment, 30, "dsa-key-%Y%m%d", tm); + strftime(default_comment, 30, "dsa-key-%Y%m%d", &tm); else - strftime(default_comment, 30, "rsa-key-%Y%m%d", tm); + strftime(default_comment, 30, "rsa-key-%Y%m%d", &tm); random_ref(); entropy = get_random_data(bits / 8); @@ -668,11 +675,20 @@ int main(int argc, char **argv) * If so, ask for a passphrase. */ if (encrypted && load_encrypted) { - passphrase = snewn(512, char); - if (!console_get_line("Enter passphrase to load key: ", - passphrase, 512, TRUE)) { + prompts_t *p = new_prompts(NULL); + int ret; + p->to_server = FALSE; + p->name = dupstr("SSH key passphrase"); + add_prompt(p, dupstr("Enter passphrase to load key: "), FALSE, 512); + ret = console_get_userpass_input(p, NULL, 0); + assert(ret >= 0); + if (!ret) { + free_prompts(p); perror("puttygen: unable to read passphrase"); return 1; + } else { + passphrase = dupstr(p->prompts[0]->result); + free_prompts(p); } } else { passphrase = NULL; @@ -688,7 +704,8 @@ int main(int argc, char **argv) char *blob; int n, l, bloblen; - ret = rsakey_pubblob(&infilename, &vblob, &bloblen, &error); + ret = rsakey_pubblob(&infilename, &vblob, &bloblen, + &origcomment, &error); blob = (char *)vblob; n = 4; /* skip modulus bits */ @@ -696,17 +713,17 @@ int main(int argc, char **argv) l = ssh1_read_bignum(blob + n, bloblen - n, &ssh1key->exponent); if (l < 0) { - error = "SSH1 public key blob was too short"; + error = "SSH-1 public key blob was too short"; } else { n += l; l = ssh1_read_bignum(blob + n, bloblen - n, &ssh1key->modulus); if (l < 0) { - error = "SSH1 public key blob was too short"; + error = "SSH-1 public key blob was too short"; } else n += l; } - ssh1key->comment = NULL; + ssh1key->comment = dupstr(origcomment); ssh1key->private_exponent = NULL; } else { ret = loadrsakey(&infilename, ssh1key, passphrase, &error); @@ -720,7 +737,7 @@ int main(int argc, char **argv) case SSH_KEYTYPE_SSH2: if (!load_encrypted) { ssh2blob = ssh2_userkey_loadpub(&infilename, &ssh2alg, - &ssh2bloblen, &error); + &ssh2bloblen, NULL, &error); ssh2algf = find_pubkey_alg(ssh2alg); if (ssh2algf) bits = ssh2algf->pubkey_bits(ssh2blob, ssh2bloblen); @@ -741,15 +758,14 @@ int main(int argc, char **argv) case SSH_KEYTYPE_OPENSSH: case SSH_KEYTYPE_SSHCOM: - ssh2key = import_ssh2(&infilename, intype, passphrase); - if (ssh2key && ssh2key != SSH2_WRONG_PASSPHRASE) - error = NULL; - else if (!error) { - if (ssh2key == SSH2_WRONG_PASSPHRASE) - error = "wrong passphrase"; + ssh2key = import_ssh2(&infilename, intype, passphrase, &error); + if (ssh2key) { + if (ssh2key != SSH2_WRONG_PASSPHRASE) + error = NULL; else - error = "unknown error"; - } + error = "wrong passphrase"; + } else if (!error) + error = "unknown error"; break; default: @@ -783,31 +799,35 @@ int main(int argc, char **argv) * we have just generated a key. */ if (change_passphrase || keytype != NOKEYGEN) { - char *passphrase2; - - if (passphrase) { - memset(passphrase, 0, strlen(passphrase)); - sfree(passphrase); - } + prompts_t *p = new_prompts(NULL); + int ret; - passphrase = snewn(512, char); - passphrase2 = snewn(512, char); - if (!console_get_line("Enter passphrase to save key: ", - passphrase, 512, TRUE) || - !console_get_line("Re-enter passphrase to verify: ", - passphrase2, 512, TRUE)) { + p->to_server = FALSE; + p->name = dupstr("New SSH key passphrase"); + add_prompt(p, dupstr("Enter passphrase to save key: "), FALSE, 512); + add_prompt(p, dupstr("Re-enter passphrase to verify: "), FALSE, 512); + ret = console_get_userpass_input(p, NULL, 0); + assert(ret >= 0); + if (!ret) { + free_prompts(p); perror("puttygen: unable to read new passphrase"); return 1; - } - if (strcmp(passphrase, passphrase2)) { - fprintf(stderr, "puttygen: passphrases do not match\n"); - return 1; - } - memset(passphrase2, 0, strlen(passphrase2)); - sfree(passphrase2); - if (!*passphrase) { - sfree(passphrase); - passphrase = NULL; + } else { + if (strcmp(p->prompts[0]->result, p->prompts[1]->result)) { + free_prompts(p); + fprintf(stderr, "puttygen: passphrases do not match\n"); + return 1; + } + if (passphrase) { + memset(passphrase, 0, strlen(passphrase)); + sfree(passphrase); + } + passphrase = dupstr(p->prompts[0]->result); + free_prompts(p); + if (!*passphrase) { + sfree(passphrase); + passphrase = NULL; + } } } @@ -832,14 +852,14 @@ int main(int argc, char **argv) assert(ssh1key); ret = saversakey(&outfilename, ssh1key, passphrase); if (!ret) { - fprintf(stderr, "puttygen: unable to save SSH1 private key\n"); + fprintf(stderr, "puttygen: unable to save SSH-1 private key\n"); return 1; } } else { assert(ssh2key); ret = ssh2_save_userkey(&outfilename, ssh2key, passphrase); if (!ret) { - fprintf(stderr, "puttygen: unable to save SSH2 private key\n"); + fprintf(stderr, "puttygen: unable to save SSH-2 private key\n"); return 1; } } @@ -1218,10 +1238,10 @@ int main(int argc, char **argv) * Change the comment of the key; this _does_ require a * passphrase owing to the tamperproofing. * - * NOTE: In SSH1, this only requires a passphrase because + * NOTE: In SSH-1, this only requires a passphrase because * of inadequacies of the loading and saving mechanisms. In * _principle_, it should be perfectly possible to modify - * the comment on an SSH1 key without requiring a + * the comment on an SSH-1 key without requiring a * passphrase; the only reason I can't do it is because my * loading and saving mechanisms don't include a method of * loading all the key data without also trying to decrypt @@ -1229,7 +1249,7 @@ int main(int argc, char **argv) * * I don't consider this to be a problem worth solving, * because (a) to fix it would probably end up bloating - * PuTTY proper, and (b) SSH1 is on the way out anyway so + * PuTTY proper, and (b) SSH-1 is on the way out anyway so * it shouldn't be highly significant. If it seriously * bothers anyone then perhaps I _might_ be persuadable. */