- }
- if (optind < ac)
- {
- printf("Too many arguments.\n");
- usage();
- }
- if (change_passphrase && change_comment)
- {
- printf("Can only have one of -p and -c.\n");
- usage();
- }
-
- if (print_fingerprint)
- do_fingerprint(pw);
-
- /* If the user requested to change the passphrase, do it now. This
- function never returns. */
- if (change_passphrase)
- do_change_passphrase(pw);
-
- /* If the user requested to change the comment, do it now. This function
- never returns. */
- if (change_comment)
- do_change_comment(pw);
-
- arc4random_stir();
-
- if (quiet)
- rsa_set_verbose(0);
-
- /* Generate the rsa key pair. */
- private_key = RSA_new();
- public_key = RSA_new();
- rsa_generate_key(private_key, public_key, bits);
-
- if (!have_identity)
- ask_filename(pw, "Enter file in which to save the key");
-
- /* If the file aready exists, ask the user to confirm. */
- if (stat(identity_file, &st) >= 0)
- {
- printf("%s already exists.\n", identity_file);
- printf("Overwrite (y/n)? ");
- fflush(stdout);
- if (fgets(buf2, sizeof(buf2), stdin) == NULL)
- exit(1);
- if (buf2[0] != 'y' && buf2[0] != 'Y')
- exit(1);
- }
-
- /* Ask for a passphrase (twice). */
- if (identity_passphrase)
- passphrase1 = xstrdup(identity_passphrase);
- else
- if (identity_new_passphrase)
- passphrase1 = xstrdup(identity_new_passphrase);
- else
- {
- passphrase_again:
- passphrase1 =
- read_passphrase("Enter passphrase (empty for no passphrase): ", 1);
- passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
- if (strcmp(passphrase1, passphrase2) != 0)
- {
- /* The passphrases do not match. Clear them and retry. */
- memset(passphrase1, 0, strlen(passphrase1));
- memset(passphrase2, 0, strlen(passphrase2));
- xfree(passphrase1);
- xfree(passphrase2);
- printf("Passphrases do not match. Try again.\n");
- goto passphrase_again;
- }
- /* Clear the other copy of the passphrase. */
- memset(passphrase2, 0, strlen(passphrase2));
- xfree(passphrase2);
- }
-
- /* Create default commend field for the passphrase. The user can later
- edit this field. */
- if (identity_comment)
- {
- strlcpy(buf2, identity_comment, sizeof(buf2));
- }
- else
- {
- if (gethostname(hostname, sizeof(hostname)) < 0)
- {
- perror("gethostname");
- exit(1);
+ /* we need this for the home * directory. */
+ pw = getpwuid(getuid());
+ if (!pw) {
+ printf("You don't exist, go away!\n");
+ exit(1);
+ }
+
+ while ((opt = getopt(ac, av, "qpclb:f:P:N:C:")) != EOF) {
+ switch (opt) {
+ case 'b':
+ bits = atoi(optarg);
+ if (bits < 512 || bits > 32768) {
+ printf("Bits has bad value.\n");
+ exit(1);
+ }
+ break;
+
+ case 'l':
+ print_fingerprint = 1;
+ break;
+
+ case 'p':
+ change_passphrase = 1;
+ break;
+
+ case 'c':
+ change_comment = 1;
+ break;
+
+ case 'f':
+ strlcpy(identity_file, optarg, sizeof(identity_file));
+ have_identity = 1;
+ break;
+
+ case 'P':
+ identity_passphrase = optarg;
+ break;
+
+ case 'N':
+ identity_new_passphrase = optarg;
+ break;
+
+ case 'C':
+ identity_comment = optarg;
+ break;
+
+ case 'q':
+ quiet = 1;
+ break;
+
+ case '?':
+ default:
+ usage();
+ }
+ }
+ if (optind < ac) {
+ printf("Too many arguments.\n");
+ usage();
+ }
+ if (change_passphrase && change_comment) {
+ printf("Can only have one of -p and -c.\n");
+ usage();
+ }
+ if (print_fingerprint)
+ do_fingerprint(pw);
+ if (change_passphrase)
+ do_change_passphrase(pw);
+ if (change_comment)
+ do_change_comment(pw);
+
+ arc4random_stir();
+
+ if (quiet)
+ rsa_set_verbose(0);
+
+ /* Generate the rsa key pair. */
+ private_key = RSA_new();
+ public_key = RSA_new();
+ rsa_generate_key(private_key, public_key, bits);
+
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which to save the key");
+
+ /* Create ~/.ssh directory if it doesn\'t already exist. */
+ snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, SSH_USER_DIR);
+ if (strstr(identity_file, dotsshdir) != NULL &&
+ stat(dotsshdir, &st) < 0) {
+ if (mkdir(dotsshdir, 0755) < 0)
+ error("Could not create directory '%s'.", dotsshdir);
+ else if (!quiet)
+ printf("Created directory '%s'.\n", dotsshdir);
+ }
+ /* If the file already exists, ask the user to confirm. */
+ if (stat(identity_file, &st) >= 0) {
+ char yesno[3];
+ printf("%s already exists.\n", identity_file);
+ printf("Overwrite (y/n)? ");
+ fflush(stdout);
+ if (fgets(yesno, sizeof(yesno), stdin) == NULL)
+ exit(1);
+ if (yesno[0] != 'y' && yesno[0] != 'Y')
+ exit(1);
+ }
+ /* Ask for a passphrase (twice). */
+ if (identity_passphrase)
+ passphrase1 = xstrdup(identity_passphrase);
+ else if (identity_new_passphrase)
+ passphrase1 = xstrdup(identity_new_passphrase);
+ else {
+passphrase_again:
+ passphrase1 =
+ read_passphrase("Enter passphrase (empty for no passphrase): ", 1);
+ passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
+ if (strcmp(passphrase1, passphrase2) != 0) {
+ /* The passphrases do not match. Clear them and retry. */
+ memset(passphrase1, 0, strlen(passphrase1));
+ memset(passphrase2, 0, strlen(passphrase2));
+ xfree(passphrase1);
+ xfree(passphrase2);
+ printf("Passphrases do not match. Try again.\n");
+ goto passphrase_again;
+ }
+ /* Clear the other copy of the passphrase. */
+ memset(passphrase2, 0, strlen(passphrase2));
+ xfree(passphrase2);
+ }
+
+ if (identity_comment) {
+ strlcpy(comment, identity_comment, sizeof(comment));
+ } else {
+ /* Create default commend field for the passphrase. */
+ if (gethostname(hostname, sizeof(hostname)) < 0) {
+ perror("gethostname");
+ exit(1);
+ }
+ snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
+ }
+
+ /* Save the key with the given passphrase and comment. */
+ if (!save_private_key(identity_file, passphrase1, private_key, comment)) {
+ printf("Saving the key failed: %s: %s.\n",
+ identity_file, strerror(errno));
+ memset(passphrase1, 0, strlen(passphrase1));
+ xfree(passphrase1);
+ exit(1);
+ }
+ /* Clear the passphrase. */
+ memset(passphrase1, 0, strlen(passphrase1));
+ xfree(passphrase1);
+
+ /* Clear the private key and the random number generator. */
+ RSA_free(private_key);
+ arc4random_stir();
+
+ if (!quiet)
+ printf("Your identification has been saved in %s.\n", identity_file);
+
+ strlcat(identity_file, ".pub", sizeof(identity_file));
+ f = fopen(identity_file, "w");
+ if (!f) {
+ printf("Could not save your public key in %s\n", identity_file);
+ exit(1);
+ }
+ fprintf(f, "%d ", BN_num_bits(public_key->n));
+ tmpbuf = BN_bn2dec(public_key->e);
+ fprintf(f, "%s ", tmpbuf);
+ free(tmpbuf);
+ tmpbuf = BN_bn2dec(public_key->n);
+ fprintf(f, "%s %s\n", tmpbuf, comment);
+ free(tmpbuf);
+ fclose(f);
+
+ if (!quiet) {
+ printf("Your public key has been saved in %s.\n", identity_file);
+ printf("The key fingerprint is:\n");
+ printf("%d %s %s\n", BN_num_bits(public_key->n),
+ fingerprint(public_key->e, public_key->n),
+ comment);