X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/602aedb153244f33c78a7b37a173fb7a09a01475..5156b1a1fca465f5acd9a09f208d610a64ec2ab3:/openssh/servconf.c diff --git a/openssh/servconf.c b/openssh/servconf.c index f906e10..3194f85 100644 --- a/openssh/servconf.c +++ b/openssh/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.177 2008/02/10 10:54:28 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.186 2008/07/04 03:44:59 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -23,7 +23,9 @@ #include #include #include +#include +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "log.h" @@ -108,6 +110,7 @@ initialize_server_options(ServerOptions *options) options->use_login = -1; options->compression = -1; options->allow_tcp_forwarding = -1; + options->allow_agent_forwarding = -1; options->num_allow_users = 0; options->num_deny_users = 0; options->num_allow_groups = 0; @@ -121,6 +124,7 @@ initialize_server_options(ServerOptions *options) options->max_startups_rate = -1; options->max_startups = -1; options->max_authtries = -1; + options->max_sessions = -1; options->banner = NULL; options->use_dns = -1; options->client_alive_interval = -1; @@ -171,7 +175,7 @@ fill_default_server_options(ServerOptions *options) if (options->pid_file == NULL) options->pid_file = _PATH_SSH_DAEMON_PID_FILE; if (options->server_key_bits == -1) - options->server_key_bits = 768; + options->server_key_bits = 1024; if (options->login_grace_time == -1) options->login_grace_time = 120; if (options->key_regeneration_time == -1) @@ -248,6 +252,8 @@ fill_default_server_options(ServerOptions *options) options->compression = COMP_DELAYED; if (options->allow_tcp_forwarding == -1) options->allow_tcp_forwarding = 1; + if (options->allow_agent_forwarding == -1) + options->allow_agent_forwarding = 1; if (options->gateway_ports == -1) options->gateway_ports = 0; if (options->max_startups == -1) @@ -258,6 +264,8 @@ fill_default_server_options(ServerOptions *options) options->max_startups_begin = options->max_startups; if (options->max_authtries == -1) options->max_authtries = DEFAULT_AUTH_FAIL_MAX; + if (options->max_sessions == -1) + options->max_sessions = DEFAULT_SESSIONS_MAX; if (options->use_dns == -1) options->use_dns = 1; if (options->client_alive_interval == -1) @@ -351,7 +359,7 @@ typedef enum { sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, - sMaxStartups, sMaxAuthTries, + sMaxStartups, sMaxAuthTries, sMaxSessions, sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, @@ -363,8 +371,9 @@ typedef enum { sGsiAllowLimitedProxy, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, - sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll, + sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize, + sUsePrivilegeSeparation, sAllowAgentForwarding, sDeprecated, sUnsupported } ServerOpCodes; @@ -469,6 +478,7 @@ static struct { { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, + { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL }, { "allowusers", sAllowUsers, SSHCFG_GLOBAL }, { "denyusers", sDenyUsers, SSHCFG_GLOBAL }, { "allowgroups", sAllowGroups, SSHCFG_GLOBAL }, @@ -479,7 +489,8 @@ static struct { { "gatewayports", sGatewayPorts, SSHCFG_ALL }, { "subsystem", sSubsystem, SSHCFG_GLOBAL }, { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, - { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL }, + { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, + { "maxsessions", sMaxSessions, SSHCFG_ALL }, { "banner", sBanner, SSHCFG_ALL }, { "usedns", sUseDNS, SSHCFG_GLOBAL }, { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, @@ -502,6 +513,17 @@ static struct { { NULL, sBadOption, 0 } }; +static struct { + int val; + char *text; +} tunmode_desc[] = { + { SSH_TUNMODE_NO, "no" }, + { SSH_TUNMODE_POINTOPOINT, "point-to-point" }, + { SSH_TUNMODE_ETHERNET, "ethernet" }, + { SSH_TUNMODE_YES, "yes" }, + { -1, NULL } +}; + /* * Returns the number of the token pointed to by cp or sBadOption. */ @@ -599,24 +621,8 @@ static int match_cfg_line_group(const char *grps, int line, const char *user) { int result = 0; - u_int ngrps = 0; - char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS]; struct passwd *pw; - /* - * Even if we do not have a user yet, we still need to check for - * valid syntax. - */ - arg = cp = xstrdup(grps); - while ((p = strsep(&cp, ",")) != NULL && *p != '\0') { - if (ngrps >= MAX_MATCH_GROUPS) { - error("line %d: too many groups in Match Group", line); - result = -1; - goto out; - } - grplist[ngrps++] = p; - } - if (user == NULL) goto out; @@ -626,17 +632,16 @@ match_cfg_line_group(const char *grps, int line, const char *user) } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { debug("Can't Match group because user %.100s not in any group " "at line %d", user, line); - } else if (ga_match(grplist, ngrps) != 1) { - debug("user %.100s does not match group %.100s at line %d", - user, arg, line); + } else if (ga_match_pattern_list(grps) != 1) { + debug("user %.100s does not match group list %.100s at line %d", + user, grps, line); } else { - debug("user %.100s matched group %.100s at line %d", user, - arg, line); + debug("user %.100s matched group list %.100s at line %d", user, + grps, line); result = 1; } out: ga_free(); - xfree(arg); return result; } @@ -689,15 +694,18 @@ match_cfg_line(char **condition, int line, const char *user, const char *host, debug("connection from %.100s matched 'Host " "%.100s' at line %d", host, arg, line); } else if (strcasecmp(attrib, "address") == 0) { - if (!address) { - result = 0; - continue; - } - if (match_hostname(address, arg, len) != 1) - result = 0; - else + switch (addr_match_list(address, arg)) { + case 1: debug("connection from %.100s matched 'Address " "%.100s' at line %d", address, arg, line); + break; + case 0: + case -1: + result = 0; + break; + case -2: + return -1; + } } else { error("Unsupported Match attribute %s", attrib); return -1; @@ -785,7 +793,7 @@ process_server_config_line(ServerOptions *options, char *line, case sServerKeyBits: intptr = &options->server_key_bits; -parse_int: + parse_int: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing integer value.", @@ -797,7 +805,7 @@ parse_int: case sLoginGraceTime: intptr = &options->login_grace_time; -parse_time: + parse_time: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing time value.", @@ -866,7 +874,7 @@ parse_time: fatal("%s line %d: too many host keys specified (max %d).", filename, linenum, MAX_HOSTKEYS); charptr = &options->host_key_files[*intptr]; -parse_filename: + parse_filename: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing file name.", @@ -909,7 +917,7 @@ parse_filename: case sIgnoreRhosts: intptr = &options->ignore_rhosts; -parse_flag: + parse_flag: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing yes/no argument.", @@ -1153,6 +1161,10 @@ parse_flag: intptr = &options->allow_tcp_forwarding; goto parse_flag; + case sAllowAgentForwarding: + intptr = &options->allow_agent_forwarding; + goto parse_flag; + case sUsePrivilegeSeparation: intptr = &use_privsep; goto parse_flag; @@ -1294,6 +1306,10 @@ parse_flag: intptr = &options->max_authtries; goto parse_int; + case sMaxSessions: + intptr = &options->max_sessions; + goto parse_int; + case sBanner: charptr = &options->banner; goto parse_filename; @@ -1340,16 +1356,13 @@ parse_flag: if (!arg || *arg == '\0') fatal("%s line %d: Missing yes/point-to-point/" "ethernet/no argument.", filename, linenum); - value = 0; /* silence compiler */ - if (strcasecmp(arg, "ethernet") == 0) - value = SSH_TUNMODE_ETHERNET; - else if (strcasecmp(arg, "point-to-point") == 0) - value = SSH_TUNMODE_POINTOPOINT; - else if (strcasecmp(arg, "yes") == 0) - value = SSH_TUNMODE_YES; - else if (strcasecmp(arg, "no") == 0) - value = SSH_TUNMODE_NO; - else + value = -1; + for (i = 0; tunmode_desc[i].val != -1; i++) + if (strcmp(tunmode_desc[i].text, arg) == 0) { + value = tunmode_desc[i].val; + break; + } + if (value == -1) fatal("%s line %d: Bad yes/point-to-point/ethernet/" "no argument: %s", filename, linenum, arg); if (*intptr == -1) @@ -1517,10 +1530,13 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(permit_root_login); M_CP_INTOPT(allow_tcp_forwarding); + M_CP_INTOPT(allow_agent_forwarding); M_CP_INTOPT(gateway_ports); M_CP_INTOPT(x11_display_offset); M_CP_INTOPT(x11_forwarding); M_CP_INTOPT(x11_use_localhost); + M_CP_INTOPT(max_sessions); + M_CP_INTOPT(max_authtries); M_CP_STROPT(banner); if (preauth) @@ -1554,3 +1570,213 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, fatal("%s: terminating, %d bad configuration options", filename, bad_options); } + +static const char * +fmt_intarg(ServerOpCodes code, int val) +{ + if (code == sAddressFamily) { + switch (val) { + case AF_INET: + return "inet"; + case AF_INET6: + return "inet6"; + case AF_UNSPEC: + return "any"; + default: + return "UNKNOWN"; + } + } + if (code == sPermitRootLogin) { + switch (val) { + case PERMIT_NO_PASSWD: + return "without-passord"; + case PERMIT_FORCED_ONLY: + return "forced-commands-only"; + case PERMIT_YES: + return "yes"; + } + } + if (code == sProtocol) { + switch (val) { + case SSH_PROTO_1: + return "1"; + case SSH_PROTO_2: + return "2"; + case (SSH_PROTO_1|SSH_PROTO_2): + return "2,1"; + default: + return "UNKNOWN"; + } + } + if (code == sGatewayPorts && val == 2) + return "clientspecified"; + if (code == sCompression && val == COMP_DELAYED) + return "delayed"; + switch (val) { + case -1: + return "unset"; + case 0: + return "no"; + case 1: + return "yes"; + } + return "UNKNOWN"; +} + +static const char * +lookup_opcode_name(ServerOpCodes code) +{ + u_int i; + + for (i = 0; keywords[i].name != NULL; i++) + if (keywords[i].opcode == code) + return(keywords[i].name); + return "UNKNOWN"; +} + +static void +dump_cfg_int(ServerOpCodes code, int val) +{ + printf("%s %d\n", lookup_opcode_name(code), val); +} + +static void +dump_cfg_fmtint(ServerOpCodes code, int val) +{ + printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); +} + +static void +dump_cfg_string(ServerOpCodes code, const char *val) +{ + if (val == NULL) + return; + printf("%s %s\n", lookup_opcode_name(code), val); +} + +static void +dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) +{ + u_int i; + + for (i = 0; i < count; i++) + printf("%s %s\n", lookup_opcode_name(code), vals[i]); +} + +void +dump_config(ServerOptions *o) +{ + u_int i; + int ret; + struct addrinfo *ai; + char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; + + /* these are usually at the top of the config */ + for (i = 0; i < o->num_ports; i++) + printf("port %d\n", o->ports[i]); + dump_cfg_fmtint(sProtocol, o->protocol); + dump_cfg_fmtint(sAddressFamily, o->address_family); + + /* ListenAddress must be after Port */ + for (ai = o->listen_addrs; ai; ai = ai->ai_next) { + if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, + sizeof(addr), port, sizeof(port), + NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { + error("getnameinfo failed: %.100s", + (ret != EAI_SYSTEM) ? gai_strerror(ret) : + strerror(errno)); + } else { + if (ai->ai_family == AF_INET6) + printf("listenaddress [%s]:%s\n", addr, port); + else + printf("listenaddress %s:%s\n", addr, port); + } + } + + /* integer arguments */ + dump_cfg_int(sServerKeyBits, o->server_key_bits); + dump_cfg_int(sLoginGraceTime, o->login_grace_time); + dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time); + dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); + dump_cfg_int(sMaxAuthTries, o->max_authtries); + dump_cfg_int(sClientAliveInterval, o->client_alive_interval); + dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); + + /* formatted integer arguments */ + dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); + dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts); + dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts); + dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication); + dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication); + dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, + o->hostbased_uses_name_from_packet_only); + dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication); + dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); + dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); + dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); + dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); + dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); + dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); + dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); + dump_cfg_fmtint(sKbdInteractiveAuthentication, + o->kbd_interactive_authentication); + dump_cfg_fmtint(sChallengeResponseAuthentication, + o->challenge_response_authentication); + dump_cfg_fmtint(sPrintMotd, o->print_motd); + dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); + dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); + dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); + dump_cfg_fmtint(sStrictModes, o->strict_modes); + dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); + dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); + dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); + dump_cfg_fmtint(sUseLogin, o->use_login); + dump_cfg_fmtint(sCompression, o->compression); + dump_cfg_fmtint(sGatewayPorts, o->gateway_ports); + dump_cfg_fmtint(sUseDNS, o->use_dns); + dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); + dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); + + /* string arguments */ + dump_cfg_string(sPidFile, o->pid_file); + dump_cfg_string(sXAuthLocation, o->xauth_location); + dump_cfg_string(sCiphers, o->ciphers); + dump_cfg_string(sMacs, o->macs); + dump_cfg_string(sBanner, o->banner); + dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file); + dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2); + dump_cfg_string(sForceCommand, o->adm_forced_command); + + /* string arguments requiring a lookup */ + dump_cfg_string(sLogLevel, log_level_name(o->log_level)); + dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); + + /* string array arguments */ + dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, + o->host_key_files); + dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); + dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); + dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); + dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); + dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); + + /* other arguments */ + for (i = 0; i < o->num_subsystems; i++) + printf("subsystem %s %s\n", o->subsystem_name[i], + o->subsystem_args[i]); + + printf("maxstartups %d:%d:%d\n", o->max_startups_begin, + o->max_startups_rate, o->max_startups); + + for (i = 0; tunmode_desc[i].val != -1; i++) + if (tunmode_desc[i].val == o->permit_tun) { + s = tunmode_desc[i].text; + break; + } + dump_cfg_string(sPermitTunnel, s); + + printf("permitopen"); + channel_print_adm_permitted_opens(); + printf("\n"); +}