diff options
Diffstat (limited to 'auth-options.c')
| -rw-r--r-- | auth-options.c | 649 |
1 files changed, 0 insertions, 649 deletions
diff --git a/auth-options.c b/auth-options.c deleted file mode 100644 index eae45cf2..00000000 --- a/auth-options.c +++ /dev/null @@ -1,649 +0,0 @@ -/* $OpenBSD: auth-options.c,v 1.54 2010/12/24 21:41:48 djm Exp $ */ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - */ - -#include "includes.h" - -#include <sys/types.h> - -#include <netdb.h> -#include <pwd.h> -#include <string.h> -#include <stdio.h> -#include <stdarg.h> - -#include "openbsd-compat/sys-queue.h" -#include "xmalloc.h" -#include "match.h" -#include "log.h" -#include "canohost.h" -#include "buffer.h" -#include "channels.h" -#include "servconf.h" -#include "misc.h" -#include "key.h" -#include "auth-options.h" -#include "hostfile.h" -#include "auth.h" -#ifdef GSSAPI -#include "ssh-gss.h" -#endif -#include "monitor_wrap.h" - -/* Flags set authorized_keys flags */ -int no_port_forwarding_flag = 0; -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; - -/* "environment=" options. */ -struct envstring *custom_environment = NULL; - -/* "tunnel=" option. */ -int forced_tun_device = -1; - -/* "principals=" option. */ -char *authorized_principals = NULL; - -extern ServerOptions options; - -void -auth_clear_options(void) -{ - no_agent_forwarding_flag = 0; - no_port_forwarding_flag = 0; - 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; - xfree(ce->s); - xfree(ce); - } - if (forced_command) { - xfree(forced_command); - forced_command = NULL; - } - if (authorized_principals) { - xfree(authorized_principals); - authorized_principals = NULL; - } - forced_tun_device = -1; - channel_clear_permitted_opens(); -} - -/* - * return 1 if access is granted, 0 if not. - * side effect: sets key option flags - */ -int -auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) -{ - const char *cp; - int i; - - /* reset options */ - auth_clear_options(); - - if (!opts) - 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."); - no_port_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-agent-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Agent forwarding disabled."); - no_agent_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-X11-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("X11 forwarding disabled."); - no_x11_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-pty"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Pty allocation disabled."); - no_pty_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-user-rc"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("User rc file execution disabled."); - no_user_rc = 1; - opts += strlen(cp); - goto next_option; - } - cp = "command=\""; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - opts += strlen(cp); - if (forced_command != NULL) - xfree(forced_command); - forced_command = xmalloc(strlen(opts) + 1); - i = 0; - while (*opts) { - if (*opts == '"') - break; - if (*opts == '\\' && opts[1] == '"') { - opts += 2; - forced_command[i++] = '"'; - continue; - } - forced_command[i++] = *opts++; - } - if (!*opts) { - debug("%.100s, line %lu: missing end quote", - file, linenum); - auth_debug_add("%.100s, line %lu: missing end quote", - file, linenum); - xfree(forced_command); - forced_command = NULL; - goto bad_option; - } - forced_command[i] = '\0'; - auth_debug_add("Forced command."); - opts++; - goto next_option; - } - cp = "principals=\""; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - opts += strlen(cp); - if (authorized_principals != NULL) - xfree(authorized_principals); - authorized_principals = xmalloc(strlen(opts) + 1); - i = 0; - while (*opts) { - if (*opts == '"') - break; - if (*opts == '\\' && opts[1] == '"') { - opts += 2; - authorized_principals[i++] = '"'; - continue; - } - authorized_principals[i++] = *opts++; - } - if (!*opts) { - debug("%.100s, line %lu: missing end quote", - file, linenum); - auth_debug_add("%.100s, line %lu: missing end quote", - file, linenum); - xfree(authorized_principals); - authorized_principals = NULL; - goto bad_option; - } - authorized_principals[i] = '\0'; - auth_debug_add("principals: %.900s", - authorized_principals); - opts++; - goto next_option; - } - cp = "environment=\""; - if (options.permit_user_env && - strncasecmp(opts, cp, strlen(cp)) == 0) { - char *s; - struct envstring *new_envstring; - - opts += strlen(cp); - s = xmalloc(strlen(opts) + 1); - i = 0; - while (*opts) { - if (*opts == '"') - break; - if (*opts == '\\' && opts[1] == '"') { - opts += 2; - s[i++] = '"'; - continue; - } - s[i++] = *opts++; - } - if (!*opts) { - debug("%.100s, line %lu: missing end quote", - file, linenum); - auth_debug_add("%.100s, line %lu: missing end quote", - file, linenum); - xfree(s); - goto bad_option; - } - s[i] = '\0'; - auth_debug_add("Adding to environment: %.900s", s); - debug("Adding to environment: %.900s", s); - opts++; - new_envstring = xmalloc(sizeof(struct envstring)); - new_envstring->s = s; - new_envstring->next = custom_environment; - custom_environment = new_envstring; - goto next_option; - } - cp = "from=\""; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - const char *remote_ip = get_remote_ipaddr(); - const char *remote_host = get_canonical_hostname( - options.use_dns); - char *patterns = xmalloc(strlen(opts) + 1); - - opts += strlen(cp); - i = 0; - while (*opts) { - if (*opts == '"') - break; - if (*opts == '\\' && opts[1] == '"') { - opts += 2; - patterns[i++] = '"'; - continue; - } - patterns[i++] = *opts++; - } - if (!*opts) { - debug("%.100s, line %lu: missing end quote", - file, linenum); - auth_debug_add("%.100s, line %lu: missing end quote", - file, linenum); - xfree(patterns); - goto bad_option; - } - patterns[i] = '\0'; - opts++; - switch (match_host_and_ip(remote_host, remote_ip, - patterns)) { - case 1: - xfree(patterns); - /* Host name matches. */ - goto next_option; - case -1: - debug("%.100s, line %lu: invalid criteria", - file, linenum); - auth_debug_add("%.100s, line %lu: " - "invalid criteria", file, linenum); - /* FALLTHROUGH */ - case 0: - xfree(patterns); - logit("Authentication tried for %.100s with " - "correct key but not from a permitted " - "host (host=%.200s, ip=%.200s).", - pw->pw_name, remote_host, remote_ip); - auth_debug_add("Your host '%.200s' is not " - "permitted to use this key for login.", - remote_host); - break; - } - /* deny access */ - return 0; - } - cp = "permitopen=\""; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - char *host, *p; - int port; - char *patterns = xmalloc(strlen(opts) + 1); - - opts += strlen(cp); - i = 0; - while (*opts) { - if (*opts == '"') - break; - if (*opts == '\\' && opts[1] == '"') { - opts += 2; - patterns[i++] = '"'; - continue; - } - patterns[i++] = *opts++; - } - if (!*opts) { - debug("%.100s, line %lu: missing end quote", - file, linenum); - auth_debug_add("%.100s, line %lu: missing " - "end quote", file, linenum); - xfree(patterns); - goto bad_option; - } - patterns[i] = '\0'; - opts++; - p = patterns; - host = hpdelim(&p); - if (host == NULL || strlen(host) >= NI_MAXHOST) { - debug("%.100s, line %lu: Bad permitopen " - "specification <%.100s>", file, linenum, - patterns); - auth_debug_add("%.100s, line %lu: " - "Bad permitopen specification", file, - linenum); - xfree(patterns); - goto bad_option; - } - host = cleanhostname(host); - if (p == NULL || (port = a2port(p)) <= 0) { - debug("%.100s, line %lu: Bad permitopen port " - "<%.100s>", file, linenum, p ? p : ""); - auth_debug_add("%.100s, line %lu: " - "Bad permitopen port", file, linenum); - xfree(patterns); - goto bad_option; - } - if (options.allow_tcp_forwarding) - channel_add_permitted_opens(host, port); - xfree(patterns); - goto next_option; - } - cp = "tunnel=\""; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - char *tun = NULL; - opts += strlen(cp); - tun = xmalloc(strlen(opts) + 1); - i = 0; - while (*opts) { - if (*opts == '"') - break; - tun[i++] = *opts++; - } - if (!*opts) { - debug("%.100s, line %lu: missing end quote", - file, linenum); - auth_debug_add("%.100s, line %lu: missing end quote", - file, linenum); - xfree(tun); - forced_tun_device = -1; - goto bad_option; - } - tun[i] = '\0'; - forced_tun_device = a2tun(tun, NULL); - xfree(tun); - if (forced_tun_device == SSH_TUNID_ERR) { - debug("%.100s, line %lu: invalid tun device", - file, linenum); - auth_debug_add("%.100s, line %lu: invalid tun device", - file, linenum); - forced_tun_device = -1; - goto bad_option; - } - auth_debug_add("Forced tun device: %d", forced_tun_device); - opts++; - goto next_option; - } -next_option: - /* - * Skip the comma, and move to the next option - * (or break out if there are no more). - */ - if (!*opts) - fatal("Bugs in auth-options.c option processing."); - if (*opts == ' ' || *opts == '\t') - break; /* End of options. */ - if (*opts != ',') - goto bad_option; - opts++; - /* Process the next option. */ - } - - /* grant access */ - return 1; - -bad_option: - logit("Bad options in %.100s file, line %lu: %.50s", - file, linenum, opts); - auth_debug_add("Bad options in %.100s file, line %lu: %.50s", - file, linenum, opts); - - /* deny access */ - return 0; -} - -#define OPTIONS_CRITICAL 1 -#define OPTIONS_EXTENSIONS 2 -static int -parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, - u_int which, int crit, - int *cert_no_port_forwarding_flag, - int *cert_no_agent_forwarding_flag, - int *cert_no_x11_forwarding_flag, - int *cert_no_pty_flag, - int *cert_no_user_rc, - char **cert_forced_command, - int *cert_source_address_done) -{ - char *command, *allowed; - const char *remote_ip; - u_char *name = NULL, *data_blob = NULL; - u_int nlen, dlen, clen; - Buffer c, data; - int ret = -1, found; - - buffer_init(&data); - - /* Make copy to avoid altering original */ - buffer_init(&c); - buffer_append(&c, optblob, optblob_len); - - while (buffer_len(&c) > 0) { - if ((name = buffer_get_cstring_ret(&c, &nlen)) == NULL || - (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) { - error("Certificate options corrupt"); - goto out; - } - buffer_append(&data, data_blob, dlen); - debug3("found certificate option \"%.100s\" len %u", - name, dlen); - if (strlen(name) != nlen) { - error("Certificate constraint name contains \\0"); - goto out; - } - found = 0; - if ((which & OPTIONS_EXTENSIONS) != 0) { - if (strcmp(name, "permit-X11-forwarding") == 0) { - *cert_no_x11_forwarding_flag = 0; - found = 1; - } else if (strcmp(name, - "permit-agent-forwarding") == 0) { - *cert_no_agent_forwarding_flag = 0; - found = 1; - } else if (strcmp(name, - "permit-port-forwarding") == 0) { - *cert_no_port_forwarding_flag = 0; - found = 1; - } else if (strcmp(name, "permit-pty") == 0) { - *cert_no_pty_flag = 0; - found = 1; - } else if (strcmp(name, "permit-user-rc") == 0) { - *cert_no_user_rc = 0; - found = 1; - } - } - if (!found && (which & OPTIONS_CRITICAL) != 0) { - if (strcmp(name, "force-command") == 0) { - if ((command = buffer_get_cstring_ret(&data, - &clen)) == NULL) { - error("Certificate constraint \"%s\" " - "corrupt", name); - goto out; - } - if (strlen(command) != clen) { - error("force-command constraint " - "contains \\0"); - goto out; - } - if (*cert_forced_command != NULL) { - error("Certificate has multiple " - "force-command options"); - xfree(command); - goto out; - } - *cert_forced_command = command; - found = 1; - } - if (strcmp(name, "source-address") == 0) { - if ((allowed = buffer_get_cstring_ret(&data, - &clen)) == NULL) { - error("Certificate constraint " - "\"%s\" corrupt", name); - goto out; - } - if (strlen(allowed) != clen) { - error("source-address constraint " - "contains \\0"); - goto out; - } - if ((*cert_source_address_done)++) { - error("Certificate has multiple " - "source-address options"); - xfree(allowed); - goto out; - } - remote_ip = get_remote_ipaddr(); - 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; - } - found = 1; - } - } - - if (!found) { - if (crit) { - error("Certificate critical option \"%s\" " - "is not supported", name); - goto out; - } else { - logit("Certificate extension \"%s\" " - "is not supported", name); - } - } else if (buffer_len(&data) != 0) { - error("Certificate option \"%s\" corrupt " - "(extra data)", name); - goto out; - } - buffer_clear(&data); - xfree(name); - xfree(data_blob); - name = data_blob = NULL; - } - /* successfully parsed all options */ - ret = 0; - - out: - if (ret != 0 && - cert_forced_command != NULL && - *cert_forced_command != NULL) { - xfree(*cert_forced_command); - *cert_forced_command = NULL; - } - if (name != NULL) - xfree(name); - if (data_blob != NULL) - xfree(data_blob); - buffer_free(&data); - buffer_free(&c); - return ret; -} - -/* - * Set options from critical certificate options. These supersede user key - * options so this must be called after auth_parse_options(). - */ -int -auth_cert_options(Key *k, struct passwd *pw) -{ - 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; - - if (key_cert_is_legacy(k)) { - /* All options are in the one field for v00 certs */ - if (parse_option_list(buffer_ptr(&k->cert->critical), - buffer_len(&k->cert->critical), pw, - OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1, - &cert_no_port_forwarding_flag, - &cert_no_agent_forwarding_flag, - &cert_no_x11_forwarding_flag, - &cert_no_pty_flag, - &cert_no_user_rc, - &cert_forced_command, - &cert_source_address_done) == -1) - return -1; - } else { - /* Separate options and extensions for v01 certs */ - if (parse_option_list(buffer_ptr(&k->cert->critical), - buffer_len(&k->cert->critical), pw, - OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL, - &cert_forced_command, - &cert_source_address_done) == -1) - return -1; - if (parse_option_list(buffer_ptr(&k->cert->extensions), - buffer_len(&k->cert->extensions), pw, - OPTIONS_EXTENSIONS, 1, - &cert_no_port_forwarding_flag, - &cert_no_agent_forwarding_flag, - &cert_no_x11_forwarding_flag, - &cert_no_pty_flag, - &cert_no_user_rc, - NULL, NULL) == -1) - return -1; - } - - 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; - } - return 0; -} - |
