diff options
author | Damien Miller <djm@mindrot.org> | 2014-07-03 21:24:40 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2014-07-03 21:24:40 +1000 |
commit | 4a1d3d50f02d0a8a4ef95ea4749293cbfb89f919 (patch) | |
tree | 279ed314ac7003657ef180c2ca3f7296830f3a20 | |
parent | e5c0d52ceb575c3db8c313e0b1aa3845943d7ba8 (diff) |
- 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-- | ChangeLog | 5 | ||||
-rw-r--r-- | ssh-keygen.c | 70 |
2 files changed, 49 insertions, 26 deletions
@@ -29,6 +29,11 @@ | |||
29 | [gss-serv.c session.c ssh-keygen.c] | 29 | [gss-serv.c session.c ssh-keygen.c] |
30 | standardise on NI_MAXHOST for gethostname() string lengths; about | 30 | standardise on NI_MAXHOST for gethostname() string lengths; about |
31 | 1/2 the cases were using it already. Fixes bz#2239 en passant | 31 | 1/2 the cases were using it already. Fixes bz#2239 en passant |
32 | - djm@cvs.openbsd.org 2014/07/03 03:47:27 | ||
33 | [ssh-keygen.c] | ||
34 | When hashing or removing hosts using ssh-keygen, don't choke on | ||
35 | @revoked markers and don't remove @cert-authority markers; | ||
36 | bz#2241, reported by mlindgren AT runelind.net | ||
32 | 37 | ||
33 | 20140702 | 38 | 20140702 |
34 | - OpenBSD CVS Sync | 39 | - OpenBSD CVS Sync |
diff --git a/ssh-keygen.c b/ssh-keygen.c index 0ec615fd6..23058ee99 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.248 2014/07/03 03:34:09 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.249 2014/07/03 03:47:27 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -987,7 +987,7 @@ do_gen_all_hostkeys(struct passwd *pw) | |||
987 | } | 987 | } |
988 | 988 | ||
989 | static void | 989 | static void |
990 | printhost(FILE *f, const char *name, Key *public, int ca, int hash) | 990 | printhost(FILE *f, const char *name, Key *public, int ca, int revoked, int hash) |
991 | { | 991 | { |
992 | if (print_fingerprint) { | 992 | if (print_fingerprint) { |
993 | enum fp_rep rep; | 993 | enum fp_rep rep; |
@@ -1007,7 +1007,8 @@ printhost(FILE *f, const char *name, Key *public, int ca, int hash) | |||
1007 | } else { | 1007 | } else { |
1008 | if (hash && (name = host_hash(name, NULL, 0)) == NULL) | 1008 | if (hash && (name = host_hash(name, NULL, 0)) == NULL) |
1009 | fatal("hash_host failed"); | 1009 | fatal("hash_host failed"); |
1010 | fprintf(f, "%s%s%s ", ca ? CA_MARKER : "", ca ? " " : "", name); | 1010 | fprintf(f, "%s%s%s ", ca ? CA_MARKER " " : "", |
1011 | revoked ? REVOKE_MARKER " " : "" , name); | ||
1011 | if (!key_write(public, f)) | 1012 | if (!key_write(public, f)) |
1012 | fatal("key_write failed"); | 1013 | fatal("key_write failed"); |
1013 | fprintf(f, "\n"); | 1014 | fprintf(f, "\n"); |
@@ -1022,7 +1023,7 @@ do_known_hosts(struct passwd *pw, const char *name) | |||
1022 | char *cp, *cp2, *kp, *kp2; | 1023 | char *cp, *cp2, *kp, *kp2; |
1023 | char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; | 1024 | char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; |
1024 | int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; | 1025 | int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; |
1025 | int ca; | 1026 | int ca, revoked; |
1026 | int found_key = 0; | 1027 | int found_key = 0; |
1027 | 1028 | ||
1028 | if (!have_identity) { | 1029 | if (!have_identity) { |
@@ -1036,6 +1037,7 @@ do_known_hosts(struct passwd *pw, const char *name) | |||
1036 | if ((in = fopen(identity_file, "r")) == NULL) | 1037 | if ((in = fopen(identity_file, "r")) == NULL) |
1037 | fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); | 1038 | fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); |
1038 | 1039 | ||
1040 | /* XXX this code is a mess; refactor -djm */ | ||
1039 | /* | 1041 | /* |
1040 | * Find hosts goes to stdout, hash and deletions happen in-place | 1042 | * Find hosts goes to stdout, hash and deletions happen in-place |
1041 | * A corner case is ssh-keygen -HF foo, which should go to stdout | 1043 | * 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) | |||
1079 | fprintf(out, "%s\n", cp); | 1081 | fprintf(out, "%s\n", cp); |
1080 | continue; | 1082 | continue; |
1081 | } | 1083 | } |
1082 | /* Check whether this is a CA key */ | 1084 | /* Check whether this is a CA key or revocation marker */ |
1083 | if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 && | 1085 | if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 && |
1084 | (cp[sizeof(CA_MARKER) - 1] == ' ' || | 1086 | (cp[sizeof(CA_MARKER) - 1] == ' ' || |
1085 | cp[sizeof(CA_MARKER) - 1] == '\t')) { | 1087 | cp[sizeof(CA_MARKER) - 1] == '\t')) { |
@@ -1087,6 +1089,14 @@ do_known_hosts(struct passwd *pw, const char *name) | |||
1087 | cp += sizeof(CA_MARKER); | 1089 | cp += sizeof(CA_MARKER); |
1088 | } else | 1090 | } else |
1089 | ca = 0; | 1091 | ca = 0; |
1092 | if (strncasecmp(cp, REVOKE_MARKER, | ||
1093 | sizeof(REVOKE_MARKER) - 1) == 0 && | ||
1094 | (cp[sizeof(REVOKE_MARKER) - 1] == ' ' || | ||
1095 | cp[sizeof(REVOKE_MARKER) - 1] == '\t')) { | ||
1096 | revoked = 1; | ||
1097 | cp += sizeof(REVOKE_MARKER); | ||
1098 | } else | ||
1099 | revoked = 0; | ||
1090 | 1100 | ||
1091 | /* Find the end of the host name portion. */ | 1101 | /* Find the end of the host name portion. */ |
1092 | for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) | 1102 | for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) |
@@ -1130,20 +1140,23 @@ do_known_hosts(struct passwd *pw, const char *name) | |||
1130 | printf("# Host %s found: " | 1140 | printf("# Host %s found: " |
1131 | "line %d type %s%s\n", name, | 1141 | "line %d type %s%s\n", name, |
1132 | num, key_type(pub), | 1142 | num, key_type(pub), |
1133 | ca ? " (CA key)" : ""); | 1143 | ca ? " (CA key)" : |
1134 | printhost(out, cp, pub, ca, 0); | 1144 | revoked? " (revoked)" : ""); |
1145 | printhost(out, cp, pub, ca, revoked, 0); | ||
1135 | found_key = 1; | 1146 | found_key = 1; |
1136 | } | 1147 | } |
1137 | if (delete_host) { | 1148 | if (delete_host) { |
1138 | if (!c && !ca) | 1149 | if (!c || ca || revoked) { |
1139 | printhost(out, cp, pub, ca, 0); | 1150 | printhost(out, cp, pub, |
1140 | else | 1151 | ca, revoked, 0); |
1152 | } else { | ||
1141 | printf("# Host %s found: " | 1153 | printf("# Host %s found: " |
1142 | "line %d type %s\n", name, | 1154 | "line %d type %s\n", name, |
1143 | num, key_type(pub)); | 1155 | num, key_type(pub)); |
1156 | } | ||
1144 | } | 1157 | } |
1145 | } else if (hash_hosts) | 1158 | } else if (hash_hosts) |
1146 | printhost(out, cp, pub, ca, 0); | 1159 | printhost(out, cp, pub, ca, revoked, 0); |
1147 | } else { | 1160 | } else { |
1148 | if (find_host || delete_host) { | 1161 | if (find_host || delete_host) { |
1149 | c = (match_hostname(name, cp, | 1162 | c = (match_hostname(name, cp, |
@@ -1154,38 +1167,43 @@ do_known_hosts(struct passwd *pw, const char *name) | |||
1154 | "line %d type %s%s\n", name, | 1167 | "line %d type %s%s\n", name, |
1155 | num, key_type(pub), | 1168 | num, key_type(pub), |
1156 | ca ? " (CA key)" : ""); | 1169 | ca ? " (CA key)" : ""); |
1157 | printhost(out, name, pub, | 1170 | printhost(out, name, pub, ca, revoked, |
1158 | ca, hash_hosts && !ca); | 1171 | hash_hosts && !(ca || revoked)); |
1159 | found_key = 1; | 1172 | found_key = 1; |
1160 | } | 1173 | } |
1161 | if (delete_host) { | 1174 | if (delete_host) { |
1162 | if (!c && !ca) | 1175 | if (!c || ca || revoked) { |
1163 | printhost(out, cp, pub, ca, 0); | 1176 | printhost(out, cp, pub, |
1164 | else | 1177 | ca, revoked, 0); |
1178 | } else { | ||
1165 | printf("# Host %s found: " | 1179 | printf("# Host %s found: " |
1166 | "line %d type %s\n", name, | 1180 | "line %d type %s\n", name, |
1167 | num, key_type(pub)); | 1181 | num, key_type(pub)); |
1182 | } | ||
1168 | } | 1183 | } |
1184 | } else if (hash_hosts && (ca || revoked)) { | ||
1185 | /* Don't hash CA and revoked keys' hostnames */ | ||
1186 | printhost(out, cp, pub, ca, revoked, 0); | ||
1187 | has_unhashed = 1; | ||
1169 | } else if (hash_hosts) { | 1188 | } else if (hash_hosts) { |
1189 | /* Hash each hostname separately */ | ||
1170 | for (cp2 = strsep(&cp, ","); | 1190 | for (cp2 = strsep(&cp, ","); |
1171 | cp2 != NULL && *cp2 != '\0'; | 1191 | cp2 != NULL && *cp2 != '\0'; |
1172 | cp2 = strsep(&cp, ",")) { | 1192 | cp2 = strsep(&cp, ",")) { |
1173 | if (ca) { | 1193 | if (strcspn(cp2, "*?!") != |
1174 | fprintf(stderr, "Warning: " | ||
1175 | "ignoring CA key for host: " | ||
1176 | "%.64s\n", cp2); | ||
1177 | printhost(out, cp2, pub, ca, 0); | ||
1178 | } else if (strcspn(cp2, "*?!") != | ||
1179 | strlen(cp2)) { | 1194 | strlen(cp2)) { |
1180 | fprintf(stderr, "Warning: " | 1195 | fprintf(stderr, "Warning: " |
1181 | "ignoring host name with " | 1196 | "ignoring host name with " |
1182 | "metacharacters: %.64s\n", | 1197 | "metacharacters: %.64s\n", |
1183 | cp2); | 1198 | cp2); |
1184 | printhost(out, cp2, pub, ca, 0); | 1199 | printhost(out, cp2, pub, ca, |
1185 | } else | 1200 | revoked, 0); |
1186 | printhost(out, cp2, pub, ca, 1); | 1201 | has_unhashed = 1; |
1202 | } else { | ||
1203 | printhost(out, cp2, pub, ca, | ||
1204 | revoked, 1); | ||
1205 | } | ||
1187 | } | 1206 | } |
1188 | has_unhashed = 1; | ||
1189 | } | 1207 | } |
1190 | } | 1208 | } |
1191 | key_free(pub); | 1209 | key_free(pub); |