summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2014-07-03 21:24:40 +1000
committerDamien Miller <djm@mindrot.org>2014-07-03 21:24:40 +1000
commit4a1d3d50f02d0a8a4ef95ea4749293cbfb89f919 (patch)
tree279ed314ac7003657ef180c2ca3f7296830f3a20
parente5c0d52ceb575c3db8c313e0b1aa3845943d7ba8 (diff)
downloadopenssh-git-4a1d3d50f02d0a8a4ef95ea4749293cbfb89f919.tar.gz
- djm@cvs.openbsd.org 2014/07/03 03:47:27
[ssh-keygen.c] When hashing or removing hosts using ssh-keygen, don't choke on @revoked markers and don't remove @cert-authority markers; bz#2241, reported by mlindgren AT runelind.net
-rw-r--r--ChangeLog5
-rw-r--r--ssh-keygen.c70
2 files changed, 49 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index 1b12c37a..0f9f1ed5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -29,6 +29,11 @@
[gss-serv.c session.c ssh-keygen.c]
standardise on NI_MAXHOST for gethostname() string lengths; about
1/2 the cases were using it already. Fixes bz#2239 en passant
+ - djm@cvs.openbsd.org 2014/07/03 03:47:27
+ [ssh-keygen.c]
+ When hashing or removing hosts using ssh-keygen, don't choke on
+ @revoked markers and don't remove @cert-authority markers;
+ bz#2241, reported by mlindgren AT runelind.net
20140702
- OpenBSD CVS Sync
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 0ec615fd..23058ee9 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.248 2014/07/03 03:34:09 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.249 2014/07/03 03:47:27 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -987,7 +987,7 @@ do_gen_all_hostkeys(struct passwd *pw)
}
static void
-printhost(FILE *f, const char *name, Key *public, int ca, int hash)
+printhost(FILE *f, const char *name, Key *public, int ca, int revoked, int hash)
{
if (print_fingerprint) {
enum fp_rep rep;
@@ -1007,7 +1007,8 @@ printhost(FILE *f, const char *name, Key *public, int ca, int hash)
} else {
if (hash && (name = host_hash(name, NULL, 0)) == NULL)
fatal("hash_host failed");
- fprintf(f, "%s%s%s ", ca ? CA_MARKER : "", ca ? " " : "", name);
+ fprintf(f, "%s%s%s ", ca ? CA_MARKER " " : "",
+ revoked ? REVOKE_MARKER " " : "" , name);
if (!key_write(public, f))
fatal("key_write failed");
fprintf(f, "\n");
@@ -1022,7 +1023,7 @@ do_known_hosts(struct passwd *pw, const char *name)
char *cp, *cp2, *kp, *kp2;
char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
- int ca;
+ int ca, revoked;
int found_key = 0;
if (!have_identity) {
@@ -1036,6 +1037,7 @@ do_known_hosts(struct passwd *pw, const char *name)
if ((in = fopen(identity_file, "r")) == NULL)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
+ /* XXX this code is a mess; refactor -djm */
/*
* Find hosts goes to stdout, hash and deletions happen in-place
* A corner case is ssh-keygen -HF foo, which should go to stdout
@@ -1079,7 +1081,7 @@ do_known_hosts(struct passwd *pw, const char *name)
fprintf(out, "%s\n", cp);
continue;
}
- /* Check whether this is a CA key */
+ /* Check whether this is a CA key or revocation marker */
if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 &&
(cp[sizeof(CA_MARKER) - 1] == ' ' ||
cp[sizeof(CA_MARKER) - 1] == '\t')) {
@@ -1087,6 +1089,14 @@ do_known_hosts(struct passwd *pw, const char *name)
cp += sizeof(CA_MARKER);
} else
ca = 0;
+ if (strncasecmp(cp, REVOKE_MARKER,
+ sizeof(REVOKE_MARKER) - 1) == 0 &&
+ (cp[sizeof(REVOKE_MARKER) - 1] == ' ' ||
+ cp[sizeof(REVOKE_MARKER) - 1] == '\t')) {
+ revoked = 1;
+ cp += sizeof(REVOKE_MARKER);
+ } else
+ revoked = 0;
/* Find the end of the host name portion. */
for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++)
@@ -1130,20 +1140,23 @@ do_known_hosts(struct passwd *pw, const char *name)
printf("# Host %s found: "
"line %d type %s%s\n", name,
num, key_type(pub),
- ca ? " (CA key)" : "");
- printhost(out, cp, pub, ca, 0);
+ ca ? " (CA key)" :
+ revoked? " (revoked)" : "");
+ printhost(out, cp, pub, ca, revoked, 0);
found_key = 1;
}
if (delete_host) {
- if (!c && !ca)
- printhost(out, cp, pub, ca, 0);
- else
+ if (!c || ca || revoked) {
+ printhost(out, cp, pub,
+ ca, revoked, 0);
+ } else {
printf("# Host %s found: "
"line %d type %s\n", name,
num, key_type(pub));
+ }
}
} else if (hash_hosts)
- printhost(out, cp, pub, ca, 0);
+ printhost(out, cp, pub, ca, revoked, 0);
} else {
if (find_host || delete_host) {
c = (match_hostname(name, cp,
@@ -1154,38 +1167,43 @@ do_known_hosts(struct passwd *pw, const char *name)
"line %d type %s%s\n", name,
num, key_type(pub),
ca ? " (CA key)" : "");
- printhost(out, name, pub,
- ca, hash_hosts && !ca);
+ printhost(out, name, pub, ca, revoked,
+ hash_hosts && !(ca || revoked));
found_key = 1;
}
if (delete_host) {
- if (!c && !ca)
- printhost(out, cp, pub, ca, 0);
- else
+ if (!c || ca || revoked) {
+ printhost(out, cp, pub,
+ ca, revoked, 0);
+ } else {
printf("# Host %s found: "
"line %d type %s\n", name,
num, key_type(pub));
+ }
}
+ } else if (hash_hosts && (ca || revoked)) {
+ /* Don't hash CA and revoked keys' hostnames */
+ printhost(out, cp, pub, ca, revoked, 0);
+ has_unhashed = 1;
} else if (hash_hosts) {
+ /* Hash each hostname separately */
for (cp2 = strsep(&cp, ",");
cp2 != NULL && *cp2 != '\0';
cp2 = strsep(&cp, ",")) {
- if (ca) {
- fprintf(stderr, "Warning: "
- "ignoring CA key for host: "
- "%.64s\n", cp2);
- printhost(out, cp2, pub, ca, 0);
- } else if (strcspn(cp2, "*?!") !=
+ if (strcspn(cp2, "*?!") !=
strlen(cp2)) {
fprintf(stderr, "Warning: "
"ignoring host name with "
"metacharacters: %.64s\n",
cp2);
- printhost(out, cp2, pub, ca, 0);
- } else
- printhost(out, cp2, pub, ca, 1);
+ printhost(out, cp2, pub, ca,
+ revoked, 0);
+ has_unhashed = 1;
+ } else {
+ printhost(out, cp2, pub, ca,
+ revoked, 1);
+ }
}
- has_unhashed = 1;
}
}
key_free(pub);