]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - cmdgen.c
Unix buildinfo: stop saying 'GTK' in pure CLI utilities.
[PuTTY.git] / cmdgen.c
index 4722a8ad7af73b271012d967f810bc0fd224463b..9d9d011ab7727fafeba728dbe05aafd64b795be4 100644 (file)
--- a/cmdgen.c
+++ b/cmdgen.c
@@ -19,7 +19,7 @@
 #ifdef TEST_CMDGEN
 /*
  * This section overrides some definitions below for test purposes.
- * When compiled with -DTEST_CMDGEN:
+ * When compiled with -DTEST_CMDGEN (as cgtest.c will do):
  * 
  *  - Calls to get_random_data() are replaced with the diagnostic
  *    function below (I #define the name so that I can still link
@@ -37,7 +37,7 @@
  *    run tests.
  */
 #define get_random_data get_random_data_diagnostic
-char *get_random_data(int len)
+char *get_random_data(int len, const char *device)
 {
     char *buf = snewn(len, char);
     memset(buf, 'x', len);
@@ -52,8 +52,7 @@ int console_get_userpass_input(prompts_t *p, unsigned char *in, int inlen)
     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++]);
+           p->prompts[i]->result = dupstr(prompts[promptsgot++]);
        } else {
            promptsgot++;           /* track number of requests anyway */
            ret = 0;
@@ -130,12 +129,14 @@ void sk_cleanup(void)
 
 void showversion(void)
 {
-    printf("puttygen: %s\n", ver);
+    char *buildinfo_text = buildinfo("\n");
+    printf("puttygen: %s\n%s\n", ver, buildinfo_text);
+    sfree(buildinfo_text);
 }
 
 void usage(int standalone)
 {
-    fprintf(stderr,
+    fprintf(standalone ? stderr : stdout,
            "Usage: puttygen ( keyfile | -t type [ -b bits ] )\n"
            "                [ -C comment ] [ -P ] [ -q ]\n"
            "                [ -o output-keyfile ] [ -O type | -l | -L"
@@ -151,33 +152,35 @@ void help(void)
      * Help message is an extended version of the usage message. So
      * start with that, plus a version heading.
      */
-    showversion();
+    printf("PuTTYgen: key generator and converter for the PuTTY tools\n"
+          "%s\n", ver);
     usage(FALSE);
-    fprintf(stderr,
-           "  -t    specify key type when generating (ed25519, ecdsa, rsa, "
+    printf("  -t    specify key type when generating (ed25519, ecdsa, 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"
-           "           private-openssh-new export OpenSSH private key "
-                                             "(force new file format)\n"
-           "           private-sshcom      export ssh.com private key\n"
-           "           public              RFC 4716 / ssh.com public key\n"
-           "           public-openssh      OpenSSH public key\n"
-           "           fingerprint         output the key fingerprint\n"
-           "  -o    specify output file\n"
-           "  -l    equivalent to `-O fingerprint'\n"
-           "  -L    equivalent to `-O public-openssh'\n"
-           "  -p    equivalent to `-O public'\n"
-           "  --old-passphrase file\n"
-           "        specify file containing old key passphrase\n"
-           "  --new-passphrase file\n"
-           "        specify file containing new key passphrase\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"
+          "           private-openssh-new export OpenSSH private key "
+                                             "(force new format)\n"
+          "           private-sshcom      export ssh.com private key\n"
+          "           public              RFC 4716 / ssh.com public key\n"
+          "           public-openssh      OpenSSH public key\n"
+          "           fingerprint         output the key fingerprint\n"
+          "  -o    specify output file\n"
+          "  -l    equivalent to `-O fingerprint'\n"
+          "  -L    equivalent to `-O public-openssh'\n"
+          "  -p    equivalent to `-O public'\n"
+          "  --old-passphrase file\n"
+          "        specify file containing old key passphrase\n"
+          "  --new-passphrase file\n"
+          "        specify file containing new key passphrase\n"
+          "  --random-device device\n"
+          "        specify device to read entropy from (e.g. /dev/urandom)\n"
+          );
 }
 
 static int move(char *from, char *to)
@@ -222,6 +225,11 @@ static char *readpassphrase(const char *filename)
     return line;
 }
 
+#define DEFAULT_RSADSA_BITS 2048
+
+/* For Unix in particular, but harmless if this main() is reused elsewhere */
+const int buildinfo_gtk_relevant = FALSE;
+
 int main(int argc, char **argv)
 {
     char *infile = NULL;
@@ -245,6 +253,7 @@ int main(int argc, char **argv)
     char *old_passphrase = NULL, *new_passphrase = NULL;
     int load_encrypted;
     progfn_t progressfn = is_interactive() ? progress_update : no_progress;
+    const char *random_device = NULL;
 
     /* ------------------------------------------------------------------
      * Parse the command line to figure out what we've been asked to do.
@@ -338,6 +347,16 @@ int main(int argc, char **argv)
                                if (!new_passphrase)
                                    errs = TRUE;
                            }
+                       } else if (!strcmp(opt, "-random-device")) {
+                           if (!val && argc > 1)
+                               --argc, val = *++argv;
+                           if (!val) {
+                               errs = TRUE;
+                               fprintf(stderr, "puttygen: option `-%s'"
+                                       " expects an argument\n", opt);
+                           } else {
+                                random_device = val;
+                           }
                        } else {
                            errs = TRUE;
                            fprintf(stderr,
@@ -488,7 +507,7 @@ int main(int argc, char **argv)
             bits = 256;
             break;
           default:
-            bits = 2048;
+            bits = DEFAULT_RSADSA_BITS;
             break;
         }
     }
@@ -503,6 +522,19 @@ int main(int argc, char **argv)
         errs = TRUE;
     }
 
+    if (keytype == RSA2 || keytype == RSA1 || keytype == DSA) {
+        if (bits < 256) {
+            fprintf(stderr, "puttygen: cannot generate %s keys shorter than"
+                    " 256 bits\n", (keytype == DSA ? "DSA" : "RSA"));
+            errs = TRUE;
+        } else if (bits < DEFAULT_RSADSA_BITS) {
+            fprintf(stderr, "puttygen: warning: %s keys shorter than"
+                    " %d bits are probably not secure\n",
+                    (keytype == DSA ? "DSA" : "RSA"), DEFAULT_RSADSA_BITS);
+            /* but this is just a warning, so proceed anyway */
+        }
+    }
+
     if (errs)
        return 1;
 
@@ -677,7 +709,7 @@ int main(int argc, char **argv)
            strftime(default_comment, 30, "rsa-key-%Y%m%d", &tm);
 
        random_ref();
-       entropy = get_random_data(bits / 8);
+       entropy = get_random_data(bits / 8, random_device);
        if (!entropy) {
            fprintf(stderr, "puttygen: failed to collect entropy, "
                    "could not generate key\n");
@@ -1133,6 +1165,8 @@ void test(int retval, ...)
     } else {
        passes++;
     }
+
+    sfree(argv);
 }
 
 void filecmp(char *file1, char *file2, char *fmt, ...)
@@ -1180,7 +1214,7 @@ char *cleanup_fp(char *s)
     s += strspn(s, " \n\t");
     s += strcspn(s, " \n\t");
 
-    return dupprintf("%.*s", s - p, p);
+    return dupprintf("%.*s", (int)(s - p), p);
 }
 
 char *get_fp(char *filename)