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>
.\" 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:

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>
* 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);