summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
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 /ssh-keygen.c
parente5c0d52ceb575c3db8c313e0b1aa3845943d7ba8 (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
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c70
1 files changed, 44 insertions, 26 deletions
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
989static void 989static void
990printhost(FILE *f, const char *name, Key *public, int ca, int hash) 990printhost(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);