- avsm@cvs.openbsd.org 2005/05/23 22:44:01
     [moduli.c ssh-keygen.c]
     - removes signed/unsigned comparisons in moduli generation
     - use strtonum instead of atoi where its easier
     - check some strlcpy overflow and fatal instead of truncate
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 6f0713d..bee4312 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keygen.c,v 1.123 2005/04/05 13:45:31 otto Exp $");
+RCSID("$OpenBSD: ssh-keygen.c,v 1.124 2005/05/23 22:44:01 avsm Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/pem.h>
@@ -36,7 +36,7 @@
 #include "dns.h"
 
 /* Number of bits in the RSA/DSA key.  This value can be changed on the command line. */
-int bits = 1024;
+u_int32_t bits = 1024;
 
 /*
  * Flag indicating that we just want to change the passphrase.  This can be
@@ -90,7 +90,7 @@
 char hostname[MAXHOSTNAMELEN];
 
 /* moduli.c */
-int gen_candidates(FILE *, int, int, BIGNUM *);
+int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
 int prime_test(FILE *, FILE *, u_int32_t, u_int32_t);
 
 static void
@@ -1007,8 +1007,8 @@
 	Key *private, *public;
 	struct passwd *pw;
 	struct stat st;
-	int opt, type, fd, download = 0, memory = 0;
-	int generator_wanted = 0, trials = 100;
+	int opt, type, fd, download = 0;
+        uint32_t memory = 0, generator_wanted = 0, trials = 100;
 	int do_gen_candidates = 0, do_screen_candidates = 0;
 	int log_level = SYSLOG_LEVEL_INFO;
 	BIGNUM *start = NULL;
@@ -1016,6 +1016,7 @@
 
 	extern int optind;
 	extern char *optarg;
+	const char *errstr;
 
 	__progname = ssh_get_progname(av[0]);
 
@@ -1040,9 +1041,9 @@
 	    "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {
 		switch (opt) {
 		case 'b':
-			bits = atoi(optarg);
-			if (bits < 512 || bits > 32768) {
-				printf("Bits has bad value.\n");
+			bits = strtonum(optarg, 512, 32768, &errstr);
+			if (errstr) {
+				printf("Bits has bad value %s (%s)\n", optarg, errstr);
 				exit(1);
 			}
 			break;
@@ -1070,7 +1071,9 @@
 			change_comment = 1;
 			break;
 		case 'f':
-			strlcpy(identity_file, optarg, sizeof(identity_file));
+			if (strlcpy(identity_file, optarg, sizeof(identity_file)) >=
+			    sizeof(identity_file))
+				fatal("Identity filename too long");
 			have_identity = 1;
 			break;
 		case 'g':
@@ -1125,23 +1128,34 @@
 			rr_hostname = optarg;
 			break;
 		case 'W':
-			generator_wanted = atoi(optarg);
-			if (generator_wanted < 1)
-				fatal("Desired generator has bad value.");
+			generator_wanted = strtonum(optarg, 1, UINT_MAX, &errstr);
+			if (errstr)
+				fatal("Desired generator has bad value: %s (%s)",
+					optarg, errstr);
 			break;
 		case 'a':
-			trials = atoi(optarg);
+			trials = strtonum(optarg, 1, UINT_MAX, &errstr);
+			if (errstr)
+				fatal("Invalid number of trials: %s (%s)",
+					optarg, errstr);
 			break;
 		case 'M':
-			memory = atoi(optarg);
+			memory = strtonum(optarg, 1, UINT_MAX, &errstr);
+			if (errstr) {
+				fatal("Memory limit is %s: %s", errstr, optarg);
+			}
 			break;
 		case 'G':
 			do_gen_candidates = 1;
-			strlcpy(out_file, optarg, sizeof(out_file));
+			if (strlcpy(out_file, optarg, sizeof(out_file)) >=
+			    sizeof(out_file))
+				fatal("Output filename too long");
 			break;
 		case 'T':
 			do_screen_candidates = 1;
-			strlcpy(out_file, optarg, sizeof(out_file));
+			if (strlcpy(out_file, optarg, sizeof(out_file)) >=
+			    sizeof(out_file))
+				fatal("Output filename too long");
 			break;
 		case 'S':
 			/* XXX - also compare length against bits */