upstream: allow "ssh-add -d -" to read keys to be deleted from

stdin bz#3180; ok dtucker@

OpenBSD-Commit-ID: 15c7f10289511eb19fce7905c9cae8954e3857ff
This commit is contained in:
djm@openbsd.org 2020-06-26 05:04:07 +00:00 committed by Damien Miller
parent a3e0c376ff
commit fe2ec0b9c1
2 changed files with 61 additions and 19 deletions

View File

@ -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> .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" 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 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" 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 .Dt SSH-ADD 1
.Os .Os
.Sh NAME .Sh NAME
@ -113,6 +113,11 @@ If no public key is found at a given path,
will append will append
.Pa .pub .Pa .pub
and retry. 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 .It Fl E Ar fingerprint_hash
Specifies the hash algorithm used when displaying key fingerprints. Specifies the hash algorithm used when displaying key fingerprints.
Valid options are: Valid options are:

View File

@ -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> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * 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 static int
delete_file(int agent_fd, const char *filename, int key_only, int qflag) 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; char *certpath = NULL, *comment = NULL;
int r, ret = -1; int r, ret = -1;
if (strcmp(filename, "-") == 0)
return delete_stdin(agent_fd, qflag);
if ((r = sshkey_load_public(filename, &public, &comment)) != 0) { if ((r = sshkey_load_public(filename, &public, &comment)) != 0) {
printf("Bad key file %s: %s\n", filename, ssh_err(r)); printf("Bad key file %s: %s\n", filename, ssh_err(r));
return -1; return -1;
} }
if ((r = ssh_remove_identity(agent_fd, public)) == 0) { if (delete_one(agent_fd, public, comment, filename, qflag) == 0)
if (!qflag) {
fprintf(stderr, "Identity removed: %s (%s)\n",
filename, comment);
}
ret = 0; ret = 0;
} else
fprintf(stderr, "Could not remove identity \"%s\": %s\n",
filename, ssh_err(r));
if (key_only) if (key_only)
goto out; 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", fatal("Certificate %s does not match private key %s",
certpath, filename); certpath, filename);
if ((r = ssh_remove_identity(agent_fd, cert)) == 0) { if (delete_one(agent_fd, cert, comment, certpath, qflag) == 0)
if (!qflag) {
fprintf(stderr, "Identity removed: %s (%s)\n",
certpath, comment);
}
ret = 0; ret = 0;
} else
fprintf(stderr, "Could not remove identity \"%s\": %s\n",
certpath, ssh_err(r));
out: out:
sshkey_free(cert); sshkey_free(cert);