diff options
Diffstat (limited to 'usr.bin/ssh/auth-options.c')
-rw-r--r-- | usr.bin/ssh/auth-options.c | 150 |
1 files changed, 149 insertions, 1 deletions
diff --git a/usr.bin/ssh/auth-options.c b/usr.bin/ssh/auth-options.c index 941c6be9f01..e765b5ad684 100644 --- a/usr.bin/ssh/auth-options.c +++ b/usr.bin/ssh/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.45 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -42,6 +42,7 @@ int no_agent_forwarding_flag = 0; int no_x11_forwarding_flag = 0; int no_pty_flag = 0; int no_user_rc = 0; +int key_is_cert_authority = 0; /* "command=" option. */ char *forced_command = NULL; @@ -62,6 +63,7 @@ auth_clear_options(void) no_pty_flag = 0; no_x11_forwarding_flag = 0; no_user_rc = 0; + key_is_cert_authority = 0; while (custom_environment) { struct envstring *ce = custom_environment; custom_environment = ce->next; @@ -94,6 +96,12 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) return 1; while (*opts && *opts != ' ' && *opts != '\t') { + cp = "cert-authority"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + key_is_cert_authority = 1; + opts += strlen(cp); + goto next_option; + } cp = "no-port-forwarding"; if (strncasecmp(opts, cp, strlen(cp)) == 0) { auth_debug_add("Port forwarding disabled."); @@ -372,3 +380,143 @@ bad_option: /* deny access */ return 0; } + +/* + * Set options from certificate constraints. These supersede user key options + * so this must be called after auth_parse_options(). + */ +int +auth_cert_constraints(Buffer *c_orig, struct passwd *pw) +{ + u_char *name = NULL, *data_blob = NULL; + u_int len; + Buffer c, data; + int ret = -1; + + int cert_no_port_forwarding_flag = 1; + int cert_no_agent_forwarding_flag = 1; + int cert_no_x11_forwarding_flag = 1; + int cert_no_pty_flag = 1; + int cert_no_user_rc = 1; + char *cert_forced_command = NULL; + int cert_source_address_done = 0; + + buffer_init(&data); + + /* Make copy to avoid altering original */ + buffer_init(&c); + buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig)); + + while (buffer_len(&c) > 0) { + if ((name = buffer_get_string_ret(&c, NULL)) == NULL || + (data_blob = buffer_get_string_ret(&c, &len)) == NULL) { + error("Certificate constraints corrupt"); + goto out; + } + buffer_append(&data, data_blob, len); + debug3("found certificate constraint \"%.100s\" len %u", + name, len); + if (strcmp(name, "permit-X11-forwarding") == 0) + cert_no_x11_forwarding_flag = 0; + else if (strcmp(name, "permit-agent-forwarding") == 0) + cert_no_agent_forwarding_flag = 0; + else if (strcmp(name, "permit-port-forwarding") == 0) + cert_no_port_forwarding_flag = 0; + else if (strcmp(name, "permit-pty") == 0) + cert_no_pty_flag = 0; + else if (strcmp(name, "permit-user-rc") == 0) + cert_no_user_rc = 0; + else if (strcmp(name, "force-command") == 0) { + char *command = buffer_get_string_ret(&data, NULL); + + if (command == NULL) { + error("Certificate constraint \"%s\" corrupt", + name); + goto out; + } + if (cert_forced_command != NULL) { + error("Certificate has multiple " + "forced-command constraints"); + xfree(command); + goto out; + } + cert_forced_command = command; + } else if (strcmp(name, "source-address") == 0) { + char *allowed = buffer_get_string_ret(&data, NULL); + const char *remote_ip = get_remote_ipaddr(); + + if (allowed == NULL) { + error("Certificate constraint \"%s\" corrupt", + name); + goto out; + } + if (cert_source_address_done++) { + error("Certificate has multiple " + "source-address constraints"); + xfree(allowed); + goto out; + } + switch (addr_match_cidr_list(remote_ip, allowed)) { + case 1: + /* accepted */ + xfree(allowed); + break; + case 0: + /* no match */ + logit("Authentication tried for %.100s with " + "valid certificate but not from a " + "permitted host (ip=%.200s).", + pw->pw_name, remote_ip); + auth_debug_add("Your address '%.200s' is not " + "permitted to use this certificate for " + "login.", remote_ip); + xfree(allowed); + goto out; + case -1: + error("Certificate source-address contents " + "invalid"); + xfree(allowed); + goto out; + } + } else { + error("Certificate constraint \"%s\" is not supported", + name); + goto out; + } + + if (buffer_len(&data) != 0) { + error("Certificate constraint \"%s\" corrupt " + "(extra data)", name); + goto out; + } + buffer_clear(&data); + xfree(name); + xfree(data_blob); + name = data_blob = NULL; + } + + /* successfully parsed all constraints */ + ret = 0; + + no_port_forwarding_flag |= cert_no_port_forwarding_flag; + no_agent_forwarding_flag |= cert_no_agent_forwarding_flag; + no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; + no_pty_flag |= cert_no_pty_flag; + no_user_rc |= cert_no_user_rc; + /* CA-specified forced command supersedes key option */ + if (cert_forced_command != NULL) { + if (forced_command != NULL) + xfree(forced_command); + forced_command = cert_forced_command; + } + + out: + if (name != NULL) + xfree(name); + if (data_blob != NULL) + xfree(data_blob); + buffer_free(&data); + buffer_free(&c); + return ret; +} + |