]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: allow "ssh-add -d -" to read keys to be deleted from
authordjm@openbsd.org <djm@openbsd.org>
Fri, 26 Jun 2020 05:04:07 +0000 (05:04 +0000)
committerDamien Miller <djm@mindrot.org>
Fri, 26 Jun 2020 05:24:28 +0000 (15:24 +1000)
stdin bz#3180; ok dtucker@

OpenBSD-Commit-ID: 15c7f10289511eb19fce7905c9cae8954e3857ff

ssh-add.1
ssh-add.c

index 58d42138ed1fab8af53f4928f906ce3d89c7d6d1..f3db1956e1b816f2c045886a595ff9df371cafc1 100644 (file)
--- a/ssh-add.1
+++ b/ssh-add.1
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ssh-add.1,v 1.79 2020/02/07 03:57:31 djm Exp $
+.\"    $OpenBSD: ssh-add.1,v 1.80 2020/06/26 05:04:07 djm Exp $
 .\"
 .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
 .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,7 +35,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: February 7 2020 $
+.Dd $Mdocdate: June 26 2020 $
 .Dt SSH-ADD 1
 .Os
 .Sh NAME
@@ -113,6 +113,11 @@ If no public key is found at a given path,
 will append
 .Pa .pub
 and retry.
+If the argument list consists of
+.Dq -
+then
+.Nm
+will read public keys to be removed from standard input.
 .It Fl E Ar fingerprint_hash
 Specifies the hash algorithm used when displaying key fingerprints.
 Valid options are:
index a40198ab588774d209d4eda253139c29ff1f2864..931197474a08d2463c6c0494ab560db8fb4acb3b 100644 (file)
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-add.c,v 1.155 2020/03/16 02:17:02 dtucker Exp $ */
+/* $OpenBSD: ssh-add.c,v 1.156 2020/06/26 05:04:07 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -110,6 +110,54 @@ clear_pass(void)
        }
 }
 
+static int
+delete_one(int agent_fd, const struct sshkey *key, const char *comment,
+    const char *path, int qflag)
+{
+       int r;
+
+       if ((r = ssh_remove_identity(agent_fd, key)) != 0) {
+               fprintf(stderr, "Could not remove identity \"%s\": %s\n",
+                   path, ssh_err(r));
+               return r;
+       }
+       if (!qflag) {
+               fprintf(stderr, "Identity removed: %s %s (%s)\n", path,
+                   sshkey_type(key), comment);
+       }
+       return 0;
+}
+
+static int
+delete_stdin(int agent_fd, int qflag)
+{
+       char *line = NULL, *cp;
+       size_t linesize = 0;
+       struct sshkey *key = NULL;
+       int lnum = 0, r, ret = -1;
+
+       while (getline(&line, &linesize, stdin) != -1) {
+               lnum++;
+               sshkey_free(key);
+               key = NULL;
+               line[strcspn(line, "\n")] = '\0';
+               cp = line + strspn(line, " \t");
+               if (*cp == '#' || *cp == '\0')
+                       continue;
+               if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
+                       fatal("%s: sshkey_new", __func__);
+               if ((r = sshkey_read(key, &cp)) != 0) {
+                       error("(stdin):%d: invalid key: %s", lnum, ssh_err(r));
+                       continue;
+               }
+               if (delete_one(agent_fd, key, cp, "(stdin)", qflag) == 0)
+                       ret = 0;
+       }
+       sshkey_free(key);
+       free(line);
+       return ret;
+}
+
 static int
 delete_file(int agent_fd, const char *filename, int key_only, int qflag)
 {
@@ -117,19 +165,15 @@ delete_file(int agent_fd, const char *filename, int key_only, int qflag)
        char *certpath = NULL, *comment = NULL;
        int r, ret = -1;
 
+       if (strcmp(filename, "-") == 0)
+               return delete_stdin(agent_fd, qflag);
+
        if ((r = sshkey_load_public(filename, &public,  &comment)) != 0) {
                printf("Bad key file %s: %s\n", filename, ssh_err(r));
                return -1;
        }
-       if ((r = ssh_remove_identity(agent_fd, public)) == 0) {
-               if (!qflag) {
-                       fprintf(stderr, "Identity removed: %s (%s)\n",
-                           filename, comment);
-               }
+       if (delete_one(agent_fd, public, comment, filename, qflag) == 0)
                ret = 0;
-       } else
-               fprintf(stderr, "Could not remove identity \"%s\": %s\n",
-                   filename, ssh_err(r));
 
        if (key_only)
                goto out;
@@ -149,15 +193,8 @@ delete_file(int agent_fd, const char *filename, int key_only, int qflag)
                fatal("Certificate %s does not match private key %s",
                    certpath, filename);
 
-       if ((r = ssh_remove_identity(agent_fd, cert)) == 0) {
-               if (!qflag) {
-                       fprintf(stderr, "Identity removed: %s (%s)\n",
-                           certpath, comment);
-               }
+       if (delete_one(agent_fd, cert, comment, certpath, qflag) == 0)
                ret = 0;
-       } else
-               fprintf(stderr, "Could not remove identity \"%s\": %s\n",
-                   certpath, ssh_err(r));
 
  out:
        sshkey_free(cert);