diff options
Diffstat (limited to 'auth-options.c')
-rw-r--r-- | auth-options.c | 150 |
1 files changed, 149 insertions, 1 deletions
diff --git a/auth-options.c b/auth-options.c index ab085c233..396bda62f 100644 --- a/auth-options.c +++ b/auth-options.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */ | 1 | /* $OpenBSD: auth-options.c,v 1.45 2010/02/26 20:29:54 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 |
@@ -44,6 +44,7 @@ int no_agent_forwarding_flag = 0; | |||
44 | int no_x11_forwarding_flag = 0; | 44 | int no_x11_forwarding_flag = 0; |
45 | int no_pty_flag = 0; | 45 | int no_pty_flag = 0; |
46 | int no_user_rc = 0; | 46 | int no_user_rc = 0; |
47 | int key_is_cert_authority = 0; | ||
47 | 48 | ||
48 | /* "command=" option. */ | 49 | /* "command=" option. */ |
49 | char *forced_command = NULL; | 50 | char *forced_command = NULL; |
@@ -64,6 +65,7 @@ auth_clear_options(void) | |||
64 | no_pty_flag = 0; | 65 | no_pty_flag = 0; |
65 | no_x11_forwarding_flag = 0; | 66 | no_x11_forwarding_flag = 0; |
66 | no_user_rc = 0; | 67 | no_user_rc = 0; |
68 | key_is_cert_authority = 0; | ||
67 | while (custom_environment) { | 69 | while (custom_environment) { |
68 | struct envstring *ce = custom_environment; | 70 | struct envstring *ce = custom_environment; |
69 | custom_environment = ce->next; | 71 | custom_environment = ce->next; |
@@ -96,6 +98,12 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) | |||
96 | return 1; | 98 | return 1; |
97 | 99 | ||
98 | while (*opts && *opts != ' ' && *opts != '\t') { | 100 | while (*opts && *opts != ' ' && *opts != '\t') { |
101 | cp = "cert-authority"; | ||
102 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { | ||
103 | key_is_cert_authority = 1; | ||
104 | opts += strlen(cp); | ||
105 | goto next_option; | ||
106 | } | ||
99 | cp = "no-port-forwarding"; | 107 | cp = "no-port-forwarding"; |
100 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { | 108 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { |
101 | auth_debug_add("Port forwarding disabled."); | 109 | auth_debug_add("Port forwarding disabled."); |
@@ -374,3 +382,143 @@ bad_option: | |||
374 | /* deny access */ | 382 | /* deny access */ |
375 | return 0; | 383 | return 0; |
376 | } | 384 | } |
385 | |||
386 | /* | ||
387 | * Set options from certificate constraints. These supersede user key options | ||
388 | * so this must be called after auth_parse_options(). | ||
389 | */ | ||
390 | int | ||
391 | auth_cert_constraints(Buffer *c_orig, struct passwd *pw) | ||
392 | { | ||
393 | u_char *name = NULL, *data_blob = NULL; | ||
394 | u_int len; | ||
395 | Buffer c, data; | ||
396 | int ret = -1; | ||
397 | |||
398 | int cert_no_port_forwarding_flag = 1; | ||
399 | int cert_no_agent_forwarding_flag = 1; | ||
400 | int cert_no_x11_forwarding_flag = 1; | ||
401 | int cert_no_pty_flag = 1; | ||
402 | int cert_no_user_rc = 1; | ||
403 | char *cert_forced_command = NULL; | ||
404 | int cert_source_address_done = 0; | ||
405 | |||
406 | buffer_init(&data); | ||
407 | |||
408 | /* Make copy to avoid altering original */ | ||
409 | buffer_init(&c); | ||
410 | buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig)); | ||
411 | |||
412 | while (buffer_len(&c) > 0) { | ||
413 | if ((name = buffer_get_string_ret(&c, NULL)) == NULL || | ||
414 | (data_blob = buffer_get_string_ret(&c, &len)) == NULL) { | ||
415 | error("Certificate constraints corrupt"); | ||
416 | goto out; | ||
417 | } | ||
418 | buffer_append(&data, data_blob, len); | ||
419 | debug3("found certificate constraint \"%.100s\" len %u", | ||
420 | name, len); | ||
421 | if (strcmp(name, "permit-X11-forwarding") == 0) | ||
422 | cert_no_x11_forwarding_flag = 0; | ||
423 | else if (strcmp(name, "permit-agent-forwarding") == 0) | ||
424 | cert_no_agent_forwarding_flag = 0; | ||
425 | else if (strcmp(name, "permit-port-forwarding") == 0) | ||
426 | cert_no_port_forwarding_flag = 0; | ||
427 | else if (strcmp(name, "permit-pty") == 0) | ||
428 | cert_no_pty_flag = 0; | ||
429 | else if (strcmp(name, "permit-user-rc") == 0) | ||
430 | cert_no_user_rc = 0; | ||
431 | else if (strcmp(name, "force-command") == 0) { | ||
432 | char *command = buffer_get_string_ret(&data, NULL); | ||
433 | |||
434 | if (command == NULL) { | ||
435 | error("Certificate constraint \"%s\" corrupt", | ||
436 | name); | ||
437 | goto out; | ||
438 | } | ||
439 | if (cert_forced_command != NULL) { | ||
440 | error("Certificate has multiple " | ||
441 | "forced-command constraints"); | ||
442 | xfree(command); | ||
443 | goto out; | ||
444 | } | ||
445 | cert_forced_command = command; | ||
446 | } else if (strcmp(name, "source-address") == 0) { | ||
447 | char *allowed = buffer_get_string_ret(&data, NULL); | ||
448 | const char *remote_ip = get_remote_ipaddr(); | ||
449 | |||
450 | if (allowed == NULL) { | ||
451 | error("Certificate constraint \"%s\" corrupt", | ||
452 | name); | ||
453 | goto out; | ||
454 | } | ||
455 | if (cert_source_address_done++) { | ||
456 | error("Certificate has multiple " | ||
457 | "source-address constraints"); | ||
458 | xfree(allowed); | ||
459 | goto out; | ||
460 | } | ||
461 | switch (addr_match_cidr_list(remote_ip, allowed)) { | ||
462 | case 1: | ||
463 | /* accepted */ | ||
464 | xfree(allowed); | ||
465 | break; | ||
466 | case 0: | ||
467 | /* no match */ | ||
468 | logit("Authentication tried for %.100s with " | ||
469 | "valid certificate but not from a " | ||
470 | "permitted host (ip=%.200s).", | ||
471 | pw->pw_name, remote_ip); | ||
472 | auth_debug_add("Your address '%.200s' is not " | ||
473 | "permitted to use this certificate for " | ||
474 | "login.", remote_ip); | ||
475 | xfree(allowed); | ||
476 | goto out; | ||
477 | case -1: | ||
478 | error("Certificate source-address contents " | ||
479 | "invalid"); | ||
480 | xfree(allowed); | ||
481 | goto out; | ||
482 | } | ||
483 | } else { | ||
484 | error("Certificate constraint \"%s\" is not supported", | ||
485 | name); | ||
486 | goto out; | ||
487 | } | ||
488 | |||
489 | if (buffer_len(&data) != 0) { | ||
490 | error("Certificate constraint \"%s\" corrupt " | ||
491 | "(extra data)", name); | ||
492 | goto out; | ||
493 | } | ||
494 | buffer_clear(&data); | ||
495 | xfree(name); | ||
496 | xfree(data_blob); | ||
497 | name = data_blob = NULL; | ||
498 | } | ||
499 | |||
500 | /* successfully parsed all constraints */ | ||
501 | ret = 0; | ||
502 | |||
503 | no_port_forwarding_flag |= cert_no_port_forwarding_flag; | ||
504 | no_agent_forwarding_flag |= cert_no_agent_forwarding_flag; | ||
505 | no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; | ||
506 | no_pty_flag |= cert_no_pty_flag; | ||
507 | no_user_rc |= cert_no_user_rc; | ||
508 | /* CA-specified forced command supersedes key option */ | ||
509 | if (cert_forced_command != NULL) { | ||
510 | if (forced_command != NULL) | ||
511 | xfree(forced_command); | ||
512 | forced_command = cert_forced_command; | ||
513 | } | ||
514 | |||
515 | out: | ||
516 | if (name != NULL) | ||
517 | xfree(name); | ||
518 | if (data_blob != NULL) | ||
519 | xfree(data_blob); | ||
520 | buffer_free(&data); | ||
521 | buffer_free(&c); | ||
522 | return ret; | ||
523 | } | ||
524 | |||