X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/e4cb16ddcd754840281ae01b3e554ada4672bdbd..7374c7790ee32f36855e4257eb15d2fe43e277ea:/cmdgen.c diff --git a/cmdgen.c b/cmdgen.c index 20c0d117..763d05e3 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 @@ -119,13 +124,16 @@ void showversion(void) sfree(verstr); } -void usage(void) +void usage(int standalone) { fprintf(stderr, "Usage: puttygen ( keyfile | -t type [ -b bits ] )\n" - " [ -C comment ] [ -P ]\n" + " [ -C comment ] [ -P ] [ -q ]\n" " [ -o output-keyfile ] [ -O type | -l | -L" " | -p ]\n"); + if (standalone) + fprintf(stderr, + "Use \"puttygen --help\" for more detail.\n"); } void help(void) @@ -135,12 +143,13 @@ void help(void) * start with that, plus a version heading. */ showversion(); - usage(); + usage(FALSE); fprintf(stderr, " -t specify key type when generating (rsa, dsa, rsa1)\n" " -b specify number of bits when generating key\n" " -C change or specify key comment\n" " -P change key passphrase\n" + " -q quiet: do not display progress bar\n" " -O specify output type:\n" " private output PuTTY private key format\n" " private-openssh export OpenSSH private key\n" @@ -277,7 +286,7 @@ int main(int argc, char **argv) * return success. */ if (argc <= 1) { - usage(); + usage(TRUE); return 0; } @@ -331,7 +340,7 @@ int main(int argc, char **argv) else { errs = TRUE; fprintf(stderr, - "puttygen: no such option `--%s'\n", opt); + "puttygen: no such option `-%s'\n", opt); } } p = NULL; @@ -470,7 +479,7 @@ int main(int argc, char **argv) * ones, print the usage message and return failure. */ if (!infile && keytype == NOKEYGEN) { - usage(); + usage(TRUE); return 1; } @@ -482,11 +491,21 @@ int main(int argc, char **argv) * Bomb out if we've been asked to both load and generate a * key. */ - if (keytype != NOKEYGEN && intype) { + if (keytype != NOKEYGEN && infile) { fprintf(stderr, "puttygen: cannot both load and generate a key\n"); return 1; } + /* + * We must save the private part when generating a new key. + */ + if (keytype != NOKEYGEN && + (outtype != PRIVATE && outtype != OPENSSH && outtype != SSHCOM)) { + fprintf(stderr, "puttygen: this would generate a new key but " + "discard the private part\n"); + return 1; + } + /* * Analyse the type of the input file, in case this affects our * course of action. @@ -670,11 +689,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; @@ -785,31 +813,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; + } } }