summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-06-26 05:04:07 +0000
committerDamien Miller <djm@mindrot.org>2020-06-26 15:24:28 +1000
commitfe2ec0b9c19adeab0cd9f04b8152dc17f31c31e5 (patch)
tree5c4b7c655ce1be9b45ba6c6147ed1d861d6fad35
parenta3e0c376ffc11862fa3568b28188bd12965973e1 (diff)
downloadopenssh-git-fe2ec0b9c19adeab0cd9f04b8152dc17f31c31e5.tar.gz
upstream: allow "ssh-add -d -" to read keys to be deleted from
stdin bz#3180; ok dtucker@ OpenBSD-Commit-ID: 15c7f10289511eb19fce7905c9cae8954e3857ff
-rw-r--r--ssh-add.19
-rw-r--r--ssh-add.c71
2 files changed, 61 insertions, 19 deletions
diff --git a/ssh-add.1 b/ssh-add.1
index 58d42138..f3db1956 100644
--- 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:
diff --git a/ssh-add.c b/ssh-add.c
index a40198ab..93119747 100644
--- 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
@@ -111,25 +111,69 @@ 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)
{
struct sshkey *public, *cert = NULL;
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);