- RSA *key;
- RSA *public_key;
- char *saved_comment, *comment;
- int success;
-
- key = RSA_new();
- public_key = RSA_new();
- if (!load_public_key(filename, public_key, &saved_comment))
- {
- printf("Bad key file %s: %s\n", filename, strerror(errno));
- return;
- }
- RSA_free(public_key);
-
- /* At first, try empty passphrase */
- success = load_private_key(filename, "", key, &comment);
- if (!success) {
- printf("Need passphrase for %s (%s).\n", filename, saved_comment);
- if (!isatty(STDIN_FILENO)) {
-#ifdef USE_EXTERNAL_ASKPASS
- int prompts = 3;
-
- while (prompts && !success)
- {
- success = askpass(filename, key, saved_comment, &comment);
- prompts--;
+ Key *private;
+ char *comment = NULL;
+ char msg[1024];
+ int fd, perms_ok, ret = -1;
+
+ if ((fd = open(filename, O_RDONLY)) < 0) {
+ perror(filename);
+ return -1;
+ }
+
+ /*
+ * Since we'll try to load a keyfile multiple times, permission errors
+ * will occur multiple times, so check perms first and bail if wrong.
+ */
+ perms_ok = key_perm_ok(fd, filename);
+ close(fd);
+ if (!perms_ok)
+ return -1;
+
+ /* At first, try empty passphrase */
+ private = key_load_private(filename, "", &comment);
+ if (comment == NULL)
+ comment = xstrdup(filename);
+ /* try last */
+ if (private == NULL && pass != NULL)
+ private = key_load_private(filename, pass, NULL);
+ if (private == NULL) {
+ /* clear passphrase since it did not work */
+ clear_pass();
+ snprintf(msg, sizeof msg, "Enter passphrase for %.200s: ",
+ comment);
+ for (;;) {
+ pass = read_passphrase(msg, RP_ALLOW_STDIN);
+ if (strcmp(pass, "") == 0) {
+ clear_pass();
+ xfree(comment);
+ return -1;
+ }
+ private = key_load_private(filename, pass, &comment);
+ if (private != NULL)
+ break;
+ clear_pass();
+ snprintf(msg, sizeof msg,
+ "Bad passphrase, try again for %.200s: ", comment);
+ }
+ }
+
+ if (ssh_add_identity_constrained(ac, private, comment, lifetime,
+ confirm)) {
+ fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
+ ret = 0;
+ if (lifetime != 0)
+ fprintf(stderr,
+ "Lifetime set to %d seconds\n", lifetime);
+ if (confirm != 0)
+ fprintf(stderr,
+ "The user has to confirm each use of the key\n");
+ } else {
+ fprintf(stderr, "Could not add identity: %s\n", filename);
+ }
+
+ xfree(comment);
+ key_free(private);
+
+ return ret;
+}
+
+static int
+update_card(AuthenticationConnection *ac, int add, const char *id)
+{
+ char *pin;
+ int ret = -1;
+
+ pin = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
+ if (pin == NULL)
+ return -1;
+
+ if (ssh_update_card(ac, add, id, pin, lifetime, confirm)) {
+ fprintf(stderr, "Card %s: %s\n",
+ add ? "added" : "removed", id);
+ ret = 0;
+ } else {
+ fprintf(stderr, "Could not %s card: %s\n",
+ add ? "add" : "remove", id);
+ ret = -1;
+ }
+ xfree(pin);
+ return ret;
+}
+
+static int
+list_identities(AuthenticationConnection *ac, int do_fp)
+{
+ Key *key;
+ char *comment, *fp;
+ int had_identities = 0;
+ int version;
+
+ for (version = 1; version <= 2; version++) {
+ for (key = ssh_get_first_identity(ac, &comment, version);
+ key != NULL;
+ key = ssh_get_next_identity(ac, &comment, version)) {
+ had_identities = 1;
+ if (do_fp) {
+ fp = key_fingerprint(key, SSH_FP_MD5,
+ SSH_FP_HEX);
+ printf("%d %s %s (%s)\n",
+ key_size(key), fp, comment, key_type(key));
+ xfree(fp);
+ } else {
+ if (!key_write(key, stdout))
+ fprintf(stderr, "key_write failed");
+ fprintf(stdout, " %s\n", comment);
+ }
+ key_free(key);
+ xfree(comment);