summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 58d42138e..f3db1956e 100644
--- a/ssh-add.1
+++ b/ssh-add.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-add.1,v 1.79 2020/02/07 03:57:31 djm Exp $ 1.\" $OpenBSD: ssh-add.1,v 1.80 2020/06/26 05:04:07 djm Exp $
2.\" 2.\"
3.\" Author: Tatu Ylonen <ylo@cs.hut.fi> 3.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,7 +35,7 @@
35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37.\" 37.\"
38.Dd $Mdocdate: February 7 2020 $ 38.Dd $Mdocdate: June 26 2020 $
39.Dt SSH-ADD 1 39.Dt SSH-ADD 1
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -113,6 +113,11 @@ If no public key is found at a given path,
113will append 113will append
114.Pa .pub 114.Pa .pub
115and retry. 115and retry.
116If the argument list consists of
117.Dq -
118then
119.Nm
120will read public keys to be removed from standard input.
116.It Fl E Ar fingerprint_hash 121.It Fl E Ar fingerprint_hash
117Specifies the hash algorithm used when displaying key fingerprints. 122Specifies the hash algorithm used when displaying key fingerprints.
118Valid options are: 123Valid options are:
diff --git a/ssh-add.c b/ssh-add.c
index a40198ab5..931197474 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.155 2020/03/16 02:17:02 dtucker Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.156 2020/06/26 05:04:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -111,25 +111,69 @@ clear_pass(void)
111} 111}
112 112
113static int 113static int
114delete_one(int agent_fd, const struct sshkey *key, const char *comment,
115 const char *path, int qflag)
116{
117 int r;
118
119 if ((r = ssh_remove_identity(agent_fd, key)) != 0) {
120 fprintf(stderr, "Could not remove identity \"%s\": %s\n",
121 path, ssh_err(r));
122 return r;
123 }
124 if (!qflag) {
125 fprintf(stderr, "Identity removed: %s %s (%s)\n", path,
126 sshkey_type(key), comment);
127 }
128 return 0;
129}
130
131static int
132delete_stdin(int agent_fd, int qflag)
133{
134 char *line = NULL, *cp;
135 size_t linesize = 0;
136 struct sshkey *key = NULL;
137 int lnum = 0, r, ret = -1;
138
139 while (getline(&line, &linesize, stdin) != -1) {
140 lnum++;
141 sshkey_free(key);
142 key = NULL;
143 line[strcspn(line, "\n")] = '\0';
144 cp = line + strspn(line, " \t");
145 if (*cp == '#' || *cp == '\0')
146 continue;
147 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
148 fatal("%s: sshkey_new", __func__);
149 if ((r = sshkey_read(key, &cp)) != 0) {
150 error("(stdin):%d: invalid key: %s", lnum, ssh_err(r));
151 continue;
152 }
153 if (delete_one(agent_fd, key, cp, "(stdin)", qflag) == 0)
154 ret = 0;
155 }
156 sshkey_free(key);
157 free(line);
158 return ret;
159}
160
161static int
114delete_file(int agent_fd, const char *filename, int key_only, int qflag) 162delete_file(int agent_fd, const char *filename, int key_only, int qflag)
115{ 163{
116 struct sshkey *public, *cert = NULL; 164 struct sshkey *public, *cert = NULL;
117 char *certpath = NULL, *comment = NULL; 165 char *certpath = NULL, *comment = NULL;
118 int r, ret = -1; 166 int r, ret = -1;
119 167
168 if (strcmp(filename, "-") == 0)
169 return delete_stdin(agent_fd, qflag);
170
120 if ((r = sshkey_load_public(filename, &public, &comment)) != 0) { 171 if ((r = sshkey_load_public(filename, &public, &comment)) != 0) {
121 printf("Bad key file %s: %s\n", filename, ssh_err(r)); 172 printf("Bad key file %s: %s\n", filename, ssh_err(r));
122 return -1; 173 return -1;
123 } 174 }
124 if ((r = ssh_remove_identity(agent_fd, public)) == 0) { 175 if (delete_one(agent_fd, public, comment, filename, qflag) == 0)
125 if (!qflag) {
126 fprintf(stderr, "Identity removed: %s (%s)\n",
127 filename, comment);
128 }
129 ret = 0; 176 ret = 0;
130 } else
131 fprintf(stderr, "Could not remove identity \"%s\": %s\n",
132 filename, ssh_err(r));
133 177
134 if (key_only) 178 if (key_only)
135 goto out; 179 goto out;
@@ -149,15 +193,8 @@ delete_file(int agent_fd, const char *filename, int key_only, int qflag)
149 fatal("Certificate %s does not match private key %s", 193 fatal("Certificate %s does not match private key %s",
150 certpath, filename); 194 certpath, filename);
151 195
152 if ((r = ssh_remove_identity(agent_fd, cert)) == 0) { 196 if (delete_one(agent_fd, cert, comment, certpath, qflag) == 0)
153 if (!qflag) {
154 fprintf(stderr, "Identity removed: %s (%s)\n",
155 certpath, comment);
156 }
157 ret = 0; 197 ret = 0;
158 } else
159 fprintf(stderr, "Could not remove identity \"%s\": %s\n",
160 certpath, ssh_err(r));
161 198
162 out: 199 out:
163 sshkey_free(cert); 200 sshkey_free(cert);