summaryrefslogtreecommitdiff
path: root/hostfile.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-03-04 21:53:35 +1100
committerDamien Miller <djm@mindrot.org>2010-03-04 21:53:35 +1100
commit1aed65eb27feec505997c98621bdf158f9ab8b99 (patch)
tree81c2d0b9aff3c2211388ba00cde544e0618750d2 /hostfile.c
parent2befbad9b3c8fc6e4e564c062870229bc722734c (diff)
- djm@cvs.openbsd.org 2010/03/04 10:36:03
[auth-rh-rsa.c auth-rsa.c auth.c auth.h auth2-hostbased.c auth2-pubkey.c] [authfile.c authfile.h hostfile.c hostfile.h servconf.c servconf.h] [ssh-keygen.c ssh.1 sshconnect.c sshd_config.5] Add a TrustedUserCAKeys option to sshd_config to specify CA keys that are trusted to authenticate users (in addition than doing it per-user in authorized_keys). Add a RevokedKeys option to sshd_config and a @revoked marker to known_hosts to allow keys to me revoked and banned for user or host authentication. feedback and ok markus@
Diffstat (limited to 'hostfile.c')
-rw-r--r--hostfile.c102
1 files changed, 81 insertions, 21 deletions
diff --git a/hostfile.c b/hostfile.c
index fc7f84c79..afab6dad1 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: hostfile.c,v 1.47 2010/02/26 20:29:54 djm Exp $ */ 1/* $OpenBSD: hostfile.c,v 1.48 2010/03/04 10:36:03 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -183,6 +183,41 @@ hostfile_check_key(int bits, const Key *key, const char *host, const char *filen
183 return 1; 183 return 1;
184} 184}
185 185
186static enum { MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA }
187check_markers(char **cpp)
188{
189 char marker[32], *sp, *cp = *cpp;
190 int ret = MRK_NONE;
191
192 while (*cp == '@') {
193 /* Only one marker is allowed */
194 if (ret != MRK_NONE)
195 return MRK_ERROR;
196 /* Markers are terminated by whitespace */
197 if ((sp = strchr(cp, ' ')) == NULL &&
198 (sp = strchr(cp, '\t')) == NULL)
199 return MRK_ERROR;
200 /* Extract marker for comparison */
201 if (sp <= cp + 1 || sp >= cp + sizeof(marker))
202 return MRK_ERROR;
203 memcpy(marker, cp, sp - cp);
204 marker[sp - cp] = '\0';
205 if (strcmp(marker, CA_MARKER) == 0)
206 ret = MRK_CA;
207 else if (strcmp(marker, REVOKE_MARKER) == 0)
208 ret = MRK_REVOKE;
209 else
210 return MRK_ERROR;
211
212 /* Skip past marker and any whitespace that follows it */
213 cp = sp;
214 for (; *cp == ' ' || *cp == '\t'; cp++)
215 ;
216 }
217 *cpp = cp;
218 return ret;
219}
220
186/* 221/*
187 * Checks whether the given host (which must be in all lowercase) is already 222 * Checks whether the given host (which must be in all lowercase) is already
188 * in the list of our known hosts. Returns HOST_OK if the host is known and 223 * in the list of our known hosts. Returns HOST_OK if the host is known and
@@ -195,17 +230,21 @@ hostfile_check_key(int bits, const Key *key, const char *host, const char *filen
195 230
196static HostStatus 231static HostStatus
197check_host_in_hostfile_by_key_or_type(const char *filename, 232check_host_in_hostfile_by_key_or_type(const char *filename,
198 const char *host, const Key *key, int keytype, Key *found, int *numret) 233 const char *host, const Key *key, int keytype, Key *found,
234 int want_revocation, int *numret)
199{ 235{
200 FILE *f; 236 FILE *f;
201 char line[8192]; 237 char line[8192];
202 int linenum = 0, want_cert = key_is_cert(key); 238 int want, have, linenum = 0, want_cert = key_is_cert(key);
203 u_int kbits; 239 u_int kbits;
204 char *cp, *cp2, *hashed_host; 240 char *cp, *cp2, *hashed_host;
205 HostStatus end_return; 241 HostStatus end_return;
206 242
207 debug3("check_host_in_hostfile: host %s filename %s", host, filename); 243 debug3("check_host_in_hostfile: host %s filename %s", host, filename);
208 244
245 if (want_revocation && (key == NULL || keytype != 0 || found != NULL))
246 fatal("%s: invalid arguments", __func__);
247
209 /* Open the file containing the list of known hosts. */ 248 /* Open the file containing the list of known hosts. */
210 f = fopen(filename, "r"); 249 f = fopen(filename, "r");
211 if (!f) 250 if (!f)
@@ -229,21 +268,18 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
229 if (!*cp || *cp == '#' || *cp == '\n') 268 if (!*cp || *cp == '#' || *cp == '\n')
230 continue; 269 continue;
231 270
232 /* 271 if (want_revocation)
233 * Ignore CA keys when looking for raw keys. 272 want = MRK_REVOKE;
234 * Ignore raw keys when looking for CA keys. 273 else if (want_cert)
235 */ 274 want = MRK_CA;
236 if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 && 275 else
237 (cp[sizeof(CA_MARKER) - 1] == ' ' || 276 want = MRK_NONE;
238 cp[sizeof(CA_MARKER) - 1] == '\t')) { 277
239 if (want_cert) { 278 if ((have = check_markers(&cp)) == MRK_ERROR) {
240 /* Skip the marker and following whitespace */ 279 verbose("%s: invalid marker at %s:%d",
241 cp += sizeof(CA_MARKER); 280 __func__, filename, linenum);
242 for (; *cp == ' ' || *cp == '\t'; cp++) 281 continue;
243 ; 282 } else if (want != have)
244 } else
245 continue;
246 } else if (want_cert)
247 continue; 283 continue;
248 284
249 /* Find the end of the host name portion. */ 285 /* Find the end of the host name portion. */
@@ -267,6 +303,9 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
267 /* Got a match. Skip host name. */ 303 /* Got a match. Skip host name. */
268 cp = cp2; 304 cp = cp2;
269 305
306 if (want_revocation)
307 found = key_new(KEY_UNSPEC);
308
270 /* 309 /*
271 * Extract the key from the line. This will skip any leading 310 * Extract the key from the line. This will skip any leading
272 * whitespace. Ignore badly formatted lines. 311 * whitespace. Ignore badly formatted lines.
@@ -289,6 +328,24 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
289 if (!hostfile_check_key(kbits, found, host, filename, linenum)) 328 if (!hostfile_check_key(kbits, found, host, filename, linenum))
290 continue; 329 continue;
291 330
331 if (want_revocation) {
332 if (key_is_cert(key) &&
333 key_equal_public(key->cert->signature_key, found)) {
334 verbose("check_host_in_hostfile: revoked CA "
335 "line %d", linenum);
336 key_free(found);
337 return HOST_REVOKED;
338 }
339 if (key_equal_public(key, found)) {
340 verbose("check_host_in_hostfile: revoked key "
341 "line %d", linenum);
342 key_free(found);
343 return HOST_REVOKED;
344 }
345 key_free(found);
346 continue;
347 }
348
292 /* Check if the current key is the same as the given key. */ 349 /* Check if the current key is the same as the given key. */
293 if (want_cert && key_equal(key->cert->signature_key, found)) { 350 if (want_cert && key_equal(key->cert->signature_key, found)) {
294 /* Found CA cert for key */ 351 /* Found CA cert for key */
@@ -325,8 +382,11 @@ check_host_in_hostfile(const char *filename, const char *host, const Key *key,
325{ 382{
326 if (key == NULL) 383 if (key == NULL)
327 fatal("no key to look up"); 384 fatal("no key to look up");
328 return (check_host_in_hostfile_by_key_or_type(filename, host, key, 0, 385 if (check_host_in_hostfile_by_key_or_type(filename, host,
329 found, numret)); 386 key, 0, NULL, 1, NULL) == HOST_REVOKED)
387 return HOST_REVOKED;
388 return check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
389 found, 0, numret);
330} 390}
331 391
332int 392int
@@ -334,7 +394,7 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host,
334 int keytype, Key *found, int *numret) 394 int keytype, Key *found, int *numret)
335{ 395{
336 return (check_host_in_hostfile_by_key_or_type(filename, host, NULL, 396 return (check_host_in_hostfile_by_key_or_type(filename, host, NULL,
337 keytype, found, numret) == HOST_FOUND); 397 keytype, found, 0, numret) == HOST_FOUND);
338} 398}
339 399
340/* 400/*