summaryrefslogtreecommitdiff
path: root/auth2-pubkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r--auth2-pubkey.c88
1 files changed, 84 insertions, 4 deletions
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 2886f1275..51aa77487 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-pubkey.c,v 1.19 2008/07/03 21:46:58 otto Exp $ */ 1/* $OpenBSD: auth2-pubkey.c,v 1.21 2010/03/04 10:36:03 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -32,6 +32,8 @@
32#include <pwd.h> 32#include <pwd.h>
33#include <stdio.h> 33#include <stdio.h>
34#include <stdarg.h> 34#include <stdarg.h>
35#include <string.h>
36#include <time.h>
35#include <unistd.h> 37#include <unistd.h>
36 38
37#include "xmalloc.h" 39#include "xmalloc.h"
@@ -54,6 +56,7 @@
54#endif 56#endif
55#include "monitor_wrap.h" 57#include "monitor_wrap.h"
56#include "misc.h" 58#include "misc.h"
59#include "authfile.h"
57 60
58/* import */ 61/* import */
59extern ServerOptions options; 62extern ServerOptions options;
@@ -178,6 +181,7 @@ static int
178user_key_allowed2(struct passwd *pw, Key *key, char *file) 181user_key_allowed2(struct passwd *pw, Key *key, char *file)
179{ 182{
180 char line[SSH_MAX_PUBKEY_BYTES]; 183 char line[SSH_MAX_PUBKEY_BYTES];
184 const char *reason;
181 int found_key = 0; 185 int found_key = 0;
182 FILE *f; 186 FILE *f;
183 u_long linenum = 0; 187 u_long linenum = 0;
@@ -196,11 +200,13 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
196 } 200 }
197 201
198 found_key = 0; 202 found_key = 0;
199 found = key_new(key->type); 203 found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
200 204
201 while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { 205 while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
202 char *cp, *key_options = NULL; 206 char *cp, *key_options = NULL;
203 207
208 auth_clear_options();
209
204 /* Skip leading whitespace, empty and comment lines. */ 210 /* Skip leading whitespace, empty and comment lines. */
205 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 211 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
206 ; 212 ;
@@ -227,8 +233,32 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
227 continue; 233 continue;
228 } 234 }
229 } 235 }
230 if (key_equal(found, key) && 236 if (auth_parse_options(pw, key_options, file, linenum) != 1)
231 auth_parse_options(pw, key_options, file, linenum) == 1) { 237 continue;
238 if (key->type == KEY_RSA_CERT || key->type == KEY_DSA_CERT) {
239 if (!key_is_cert_authority)
240 continue;
241 if (!key_equal(found, key->cert->signature_key))
242 continue;
243 debug("matching CA found: file %s, line %lu",
244 file, linenum);
245 fp = key_fingerprint(found, SSH_FP_MD5,
246 SSH_FP_HEX);
247 verbose("Found matching %s CA: %s",
248 key_type(found), fp);
249 xfree(fp);
250 if (key_cert_check_authority(key, 0, 0, pw->pw_name,
251 &reason) != 0) {
252 error("%s", reason);
253 auth_debug_add("%s", reason);
254 continue;
255 }
256 if (auth_cert_constraints(&key->cert->constraints,
257 pw) != 0)
258 continue;
259 found_key = 1;
260 break;
261 } else if (!key_is_cert_authority && key_equal(found, key)) {
232 found_key = 1; 262 found_key = 1;
233 debug("matching key found: file %s, line %lu", 263 debug("matching key found: file %s, line %lu",
234 file, linenum); 264 file, linenum);
@@ -247,6 +277,47 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
247 return found_key; 277 return found_key;
248} 278}
249 279
280/* Authenticate a certificate key against TrustedUserCAKeys */
281static int
282user_cert_trusted_ca(struct passwd *pw, Key *key)
283{
284 char *key_fp, *ca_fp;
285 const char *reason;
286 int ret = 0;
287
288 if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
289 return 0;
290
291 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
292 ca_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
293
294 if (key_in_file(key->cert->signature_key,
295 options.trusted_user_ca_keys, 1) != 1) {
296 debug2("%s: CA %s %s is not listed in %s", __func__,
297 key_type(key->cert->signature_key), ca_fp,
298 options.trusted_user_ca_keys);
299 goto out;
300 }
301 if (key_cert_check_authority(key, 0, 1, pw->pw_name, &reason) != 0) {
302 error("%s", reason);
303 auth_debug_add("%s", reason);
304 goto out;
305 }
306 if (auth_cert_constraints(&key->cert->constraints, pw) != 0)
307 goto out;
308
309 verbose("%s certificate %s allowed by trusted %s key %s",
310 key_type(key), key_fp, key_type(key->cert->signature_key), ca_fp);
311 ret = 1;
312
313 out:
314 if (key_fp != NULL)
315 xfree(key_fp);
316 if (ca_fp != NULL)
317 xfree(ca_fp);
318 return ret;
319}
320
250/* check whether given key is in .ssh/authorized_keys* */ 321/* check whether given key is in .ssh/authorized_keys* */
251int 322int
252user_key_allowed(struct passwd *pw, Key *key) 323user_key_allowed(struct passwd *pw, Key *key)
@@ -254,6 +325,15 @@ user_key_allowed(struct passwd *pw, Key *key)
254 int success; 325 int success;
255 char *file; 326 char *file;
256 327
328 if (auth_key_is_revoked(key))
329 return 0;
330 if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
331 return 0;
332
333 success = user_cert_trusted_ca(pw, key);
334 if (success)
335 return success;
336
257 file = authorized_keys_file(pw); 337 file = authorized_keys_file(pw);
258 success = user_key_allowed2(pw, key, file); 338 success = user_key_allowed2(pw, key, file);
259 xfree(file); 339 xfree(file);