diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | auth.c | 5 | ||||
-rw-r--r-- | servconf.c | 356 | ||||
-rw-r--r-- | servconf.h | 11 | ||||
-rw-r--r-- | sshd.c | 17 | ||||
-rw-r--r-- | sshd_config.5 | 23 |
6 files changed, 314 insertions, 112 deletions
@@ -43,6 +43,18 @@ - stevesk@cvs.openbsd.org 2006/07/11 20:27:56 [authfile.c ssh.c] need <errno.h> here also (it's also included in <openssl/err.h>) + - dtucker@cvs.openbsd.org 2006/07/12 11:34:58 + [sshd.c servconf.h servconf.c sshd_config.5 auth.c] + Add support for conditional directives to sshd_config via a "Match" + keyword, which works similarly to the "Host" directive in ssh_config. + Lines after a Match line override the default set in the main section + if the condition on the Match line is true, eg + AllowTcpForwarding yes + Match User anoncvs + AllowTcpForwarding no + will allow port forwarding by all users except "anoncvs". + Currently only a very small subset of directives are supported. + ok djm@ 20060711 - (dtucker) [configure.ac ssh-keygen.c openbsd-compat/bsd-openpty.c @@ -4892,4 +4904,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4399 2006/07/12 12:24:22 dtucker Exp $ +$Id: ChangeLog,v 1.4400 2006/07/12 12:34:17 dtucker Exp $ @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.70 2006/07/11 20:07:25 stevesk Exp $ */ +/* $OpenBSD: auth.c,v 1.71 2006/07/12 11:34:58 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -467,6 +467,9 @@ getpwnamallow(const char *user) #endif struct passwd *pw; + parse_server_match_config(&options, user, + get_canonical_hostname(options.use_dns), get_remote_ipaddr()); + pw = getpwnam(user); if (pw == NULL) { logit("Invalid user %.100s from %.100s", @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.152 2006/07/08 21:47:12 stevesk Exp $ */ +/* $OpenBSD: servconf.c,v 1.153 2006/07/12 11:34:58 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved @@ -25,12 +25,14 @@ #include "cipher.h" #include "kex.h" #include "mac.h" +#include "match.h" static void add_listen_addr(ServerOptions *, char *, u_short); static void add_one_listen_addr(ServerOptions *, char *, u_short); /* Use of privilege separation or not */ extern int use_privsep; +extern Buffer cfg; /* Initializes the server options to their default values. */ @@ -105,9 +107,6 @@ initialize_server_options(ServerOptions *options) options->authorized_keys_file2 = NULL; options->num_accept_env = 0; options->permit_tun = -1; - - /* Needs to be accessable in many places */ - use_privsep = -1; } void @@ -277,110 +276,116 @@ typedef enum { sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, + sMatch, sUsePrivilegeSeparation, sDeprecated, sUnsupported } ServerOpCodes; +#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ +#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ +#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) + /* Textual representation of the tokens. */ static struct { const char *name; ServerOpCodes opcode; + u_int flags; } keywords[] = { /* Portable-specific options */ #ifdef USE_PAM - { "usepam", sUsePAM }, + { "usepam", sUsePAM, SSHCFG_GLOBAL }, #else - { "usepam", sUnsupported }, + { "usepam", sUnsupported, SSHCFG_GLOBAL }, #endif - { "pamauthenticationviakbdint", sDeprecated }, + { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ - { "port", sPort }, - { "hostkey", sHostKeyFile }, - { "hostdsakey", sHostKeyFile }, /* alias */ - { "pidfile", sPidFile }, - { "serverkeybits", sServerKeyBits }, - { "logingracetime", sLoginGraceTime }, - { "keyregenerationinterval", sKeyRegenerationTime }, - { "permitrootlogin", sPermitRootLogin }, - { "syslogfacility", sLogFacility }, - { "loglevel", sLogLevel }, - { "rhostsauthentication", sDeprecated }, - { "rhostsrsaauthentication", sRhostsRSAAuthentication }, - { "hostbasedauthentication", sHostbasedAuthentication }, - { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly }, - { "rsaauthentication", sRSAAuthentication }, - { "pubkeyauthentication", sPubkeyAuthentication }, - { "dsaauthentication", sPubkeyAuthentication }, /* alias */ + { "port", sPort, SSHCFG_GLOBAL }, + { "hostkey", sHostKeyFile, SSHCFG_GLOBAL }, + { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */ + { "pidfile", sPidFile, SSHCFG_GLOBAL }, + { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, + { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, + { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, + { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL }, + { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, + { "loglevel", sLogLevel, SSHCFG_GLOBAL }, + { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, + { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL }, + { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL }, + { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL }, + { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL }, + { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, + { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ #ifdef KRB5 - { "kerberosauthentication", sKerberosAuthentication }, - { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, - { "kerberosticketcleanup", sKerberosTicketCleanup }, + { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL }, + { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL }, + { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL }, #ifdef USE_AFS - { "kerberosgetafstoken", sKerberosGetAFSToken }, + { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL }, #else - { "kerberosgetafstoken", sUnsupported }, + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif #else - { "kerberosauthentication", sUnsupported }, - { "kerberosorlocalpasswd", sUnsupported }, - { "kerberosticketcleanup", sUnsupported }, - { "kerberosgetafstoken", sUnsupported }, + { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif - { "kerberostgtpassing", sUnsupported }, - { "afstokenpassing", sUnsupported }, + { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, + { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI - { "gssapiauthentication", sGssAuthentication }, - { "gssapicleanupcredentials", sGssCleanupCreds }, + { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL }, + { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, #else - { "gssapiauthentication", sUnsupported }, - { "gssapicleanupcredentials", sUnsupported }, + { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL }, + { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, #endif - { "passwordauthentication", sPasswordAuthentication }, - { "kbdinteractiveauthentication", sKbdInteractiveAuthentication }, - { "challengeresponseauthentication", sChallengeResponseAuthentication }, - { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */ - { "checkmail", sDeprecated }, - { "listenaddress", sListenAddress }, - { "addressfamily", sAddressFamily }, - { "printmotd", sPrintMotd }, - { "printlastlog", sPrintLastLog }, - { "ignorerhosts", sIgnoreRhosts }, - { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, - { "x11forwarding", sX11Forwarding }, - { "x11displayoffset", sX11DisplayOffset }, - { "x11uselocalhost", sX11UseLocalhost }, - { "xauthlocation", sXAuthLocation }, - { "strictmodes", sStrictModes }, - { "permitemptypasswords", sEmptyPasswd }, - { "permituserenvironment", sPermitUserEnvironment }, - { "uselogin", sUseLogin }, - { "compression", sCompression }, - { "tcpkeepalive", sTCPKeepAlive }, - { "keepalive", sTCPKeepAlive }, /* obsolete alias */ - { "allowtcpforwarding", sAllowTcpForwarding }, - { "allowusers", sAllowUsers }, - { "denyusers", sDenyUsers }, - { "allowgroups", sAllowGroups }, - { "denygroups", sDenyGroups }, - { "ciphers", sCiphers }, - { "macs", sMacs }, - { "protocol", sProtocol }, - { "gatewayports", sGatewayPorts }, - { "subsystem", sSubsystem }, - { "maxstartups", sMaxStartups }, - { "maxauthtries", sMaxAuthTries }, - { "banner", sBanner }, - { "usedns", sUseDNS }, - { "verifyreversemapping", sDeprecated }, - { "reversemappingcheck", sDeprecated }, - { "clientaliveinterval", sClientAliveInterval }, - { "clientalivecountmax", sClientAliveCountMax }, - { "authorizedkeysfile", sAuthorizedKeysFile }, - { "authorizedkeysfile2", sAuthorizedKeysFile2 }, - { "useprivilegeseparation", sUsePrivilegeSeparation}, - { "acceptenv", sAcceptEnv }, - { "permittunnel", sPermitTunnel }, - { NULL, sBadOption } + { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL }, + { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL }, + { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, + { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ + { "checkmail", sDeprecated, SSHCFG_GLOBAL }, + { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, + { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, + { "printmotd", sPrintMotd, SSHCFG_GLOBAL }, + { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL }, + { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL }, + { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, + { "x11forwarding", sX11Forwarding, SSHCFG_GLOBAL }, + { "x11displayoffset", sX11DisplayOffset, SSHCFG_GLOBAL }, + { "x11uselocalhost", sX11UseLocalhost, SSHCFG_GLOBAL }, + { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, + { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, + { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL }, + { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, + { "uselogin", sUseLogin, SSHCFG_GLOBAL }, + { "compression", sCompression, SSHCFG_GLOBAL }, + { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, + { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ + { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, + { "allowusers", sAllowUsers, SSHCFG_GLOBAL }, + { "denyusers", sDenyUsers, SSHCFG_GLOBAL }, + { "allowgroups", sAllowGroups, SSHCFG_GLOBAL }, + { "denygroups", sDenyGroups, SSHCFG_GLOBAL }, + { "ciphers", sCiphers, SSHCFG_GLOBAL }, + { "macs", sMacs, SSHCFG_GLOBAL }, + { "protocol", sProtocol, SSHCFG_GLOBAL }, + { "gatewayports", sGatewayPorts, SSHCFG_ALL }, + { "subsystem", sSubsystem, SSHCFG_GLOBAL }, + { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, + { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL }, + { "banner", sBanner, SSHCFG_GLOBAL }, + { "usedns", sUseDNS, SSHCFG_GLOBAL }, + { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, + { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, + { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL }, + { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL }, + { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL }, + { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL }, + { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL }, + { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL }, + { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL }, + { NULL, sBadOption, 0 } }; /* @@ -389,13 +394,15 @@ static struct { static ServerOpCodes parse_token(const char *cp, const char *filename, - int linenum) + int linenum, u_int *flags) { u_int i; for (i = 0; keywords[i].name; i++) - if (strcasecmp(cp, keywords[i].name) == 0) + if (strcasecmp(cp, keywords[i].name) == 0) { + *flags = keywords[i].flags; return keywords[i].opcode; + } error("%s: line %d: Bad configuration option: %s", filename, linenum, cp); @@ -440,15 +447,112 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port) options->listen_addrs = aitop; } +/* + * The strategy for the Match blocks is that the config file is parsed twice. + * + * The first time is at startup. activep is initialized to 1 and the + * directives in the global context are processed and acted on. Hitting a + * Match directive unsets activep and the directives inside the block are + * checked for syntax only. + * + * The second time is after a connection has been established but before + * authentication. activep is initialized to 2 and global config directives + * are ignored since they have already been processed. If the criteria in a + * Match block is met, activep is set and the subsequent directives + * processed and actioned until EOF or another Match block unsets it. Any + * options set are copied into the main server config. + * + * Potential additions/improvements: + * - Add Match support for pre-kex directives, eg Protocol, Ciphers. + * + * - Add a Tag directive (idea from David Leonard) ala pf, eg: + * Match Address 192.168.0.* + * Tag trusted + * Match Group wheel + * Tag trusted + * Match Tag trusted + * AllowTcpForwarding yes + * GatewayPorts clientspecified + * [...] + * + * - Add a PermittedChannelRequests directive + * Match Group shell + * PermittedChannelRequests session,forwarded-tcpip + */ + +static int +match_cfg_line(char **condition, int line, const char *user, const char *host, + const char *address) +{ + int result = 1; + char *arg, *attrib, *cp = *condition; + size_t len; + + if (user == NULL) + debug3("checking syntax for 'Match %s'", cp); + else + debug3("checking match for '%s' user %s host %s addr %s", cp, + user ? user : "(null)", host ? host : "(null)", + address ? address : "(null)"); + + while ((attrib = strdelim(&cp)) && *attrib != '\0') { + if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { + error("Missing Match criteria for %s", attrib); + return -1; + } + len = strlen(arg); + if (strcasecmp(attrib, "user") == 0) { + if (!user) { + result = 0; + continue; + } + if (match_pattern_list(user, arg, len, 0) != 1) + result = 0; + else + debug("user %.100s matched 'User %.100s' at " + "line %d", user, arg, line); + } else if (strcasecmp(attrib, "host") == 0) { + if (!host) { + result = 0; + continue; + } + if (match_hostname(host, arg, len) != 1) + result = 0; + else + debug("connection from %.100s matched 'Host " + "%.100s' at line %d", host, arg, line); + } else if (strcasecmp(attrib, "address") == 0) { + debug("address '%s' arg '%s'", address, arg); + if (!address) { + result = 0; + continue; + } + if (match_hostname(address, arg, len) != 1) + result = 0; + else + debug("connection from %.100s matched 'Address " + "%.100s' at line %d", address, arg, line); + } else { + error("Unsupported Match attribute %s", attrib); + return -1; + } + } + if (user != NULL) + debug3("match %sfound", result ? "" : "not "); + *condition = cp; + return result; +} + int process_server_config_line(ServerOptions *options, char *line, - const char *filename, int linenum) + const char *filename, int linenum, int *activep, const char *user, + const char *host, const char *address) { char *cp, **charptr, *arg, *p; - int *intptr, value, n; + int cmdline = 0, *intptr, value, n; ServerOpCodes opcode; u_short port; - u_int i; + u_int i, flags = 0; size_t len; cp = line; @@ -461,7 +565,25 @@ process_server_config_line(ServerOptions *options, char *line, return 0; intptr = NULL; charptr = NULL; - opcode = parse_token(arg, filename, linenum); + opcode = parse_token(arg, filename, linenum, &flags); + + if (activep == NULL) { /* We are processing a command line directive */ + cmdline = 1; + activep = &cmdline; + } + if (*activep && opcode != sMatch) + debug3("%s:%d setting %s %s", filename, linenum, arg, cp); + if (*activep == 0 && !(flags & SSHCFG_MATCH)) { + if (user == NULL) { + fatal("%s line %d: Directive '%s' is not allowed " + "within a Match block", filename, linenum, arg); + } else { /* this is a directive we have already processed */ + while (arg) + arg = strdelim(&cp); + return 0; + } + } + switch (opcode) { /* Portable-specific options */ case sUsePAM: @@ -499,7 +621,7 @@ parse_int: fatal("%s line %d: missing integer value.", filename, linenum); value = atoi(arg); - if (*intptr == -1) + if (*activep && *intptr == -1) *intptr = value; break; @@ -579,7 +701,7 @@ parse_filename: if (!arg || *arg == '\0') fatal("%s line %d: missing file name.", filename, linenum); - if (*charptr == NULL) { + if (*activep && *charptr == NULL) { *charptr = tilde_expand_filename(arg, getuid()); /* increase optional counter */ if (intptr != NULL) @@ -630,7 +752,7 @@ parse_flag: else fatal("%s line %d: Bad yes/no argument: %s", filename, linenum, arg); - if (*intptr == -1) + if (*activep && *intptr == -1) *intptr = value; break; @@ -895,6 +1017,10 @@ parse_flag: if (!arg || *arg == '\0') fatal("%s line %d: Missing subsystem name.", filename, linenum); + if (!*activep) { + arg = strdelim(&cp); + break; + } for (i = 0; i < options->num_subsystems; i++) if (strcmp(arg, options->subsystem_name[i]) == 0) fatal("%s line %d: Subsystem '%s' already defined.", @@ -977,6 +1103,8 @@ parse_flag: if (options->num_accept_env >= MAX_ACCEPT_ENV) fatal("%s line %d: too many allow env.", filename, linenum); + if (!*activep) + break; options->accept_env[options->num_accept_env++] = xstrdup(arg); } @@ -1004,6 +1132,17 @@ parse_flag: *intptr = value; break; + case sMatch: + if (cmdline) + fatal("Match directive not supported as a command-line " + "option"); + value = match_cfg_line(&cp, linenum, user, host, address); + if (value < 0) + fatal("%s line %d: Bad Match condition", filename, + linenum); + *activep = value; + break; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); @@ -1060,18 +1199,41 @@ load_server_config(const char *filename, Buffer *conf) } void -parse_server_config(ServerOptions *options, const char *filename, Buffer *conf) +parse_server_match_config(ServerOptions *options, const char *user, + const char *host, const char *address) +{ + ServerOptions mo; + + initialize_server_options(&mo); + parse_server_config(&mo, "reprocess config", &cfg, user, host, address); + copy_set_server_options(options, &mo); +} + +/* Copy any (supported) values that are set */ +void +copy_set_server_options(ServerOptions *dst, ServerOptions *src) +{ + if (src->allow_tcp_forwarding != -1) + dst->allow_tcp_forwarding = src->allow_tcp_forwarding; + if (src->gateway_ports != -1) + dst->gateway_ports = src->gateway_ports; +} + +void +parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, + const char *user, const char *host, const char *address) { - int linenum, bad_options = 0; + int active, linenum, bad_options = 0; char *cp, *obuf, *cbuf; debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); obuf = cbuf = xstrdup(buffer_ptr(conf)); + active = user ? 0 : 1; linenum = 1; while ((cp = strsep(&cbuf, "\n")) != NULL) { if (process_server_config_line(options, cp, filename, - linenum++) != 0) + linenum++, &active, user, host, address) != 0) bad_options++; } xfree(obuf); @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.74 2006/07/06 10:47:05 djm Exp $ */ +/* $OpenBSD: servconf.h,v 1.75 2006/07/12 11:34:58 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -142,8 +142,13 @@ typedef struct { void initialize_server_options(ServerOptions *); void fill_default_server_options(ServerOptions *); -int process_server_config_line(ServerOptions *, char *, const char *, int); +int process_server_config_line(ServerOptions *, char *, const char *, int, + int *, const char *, const char *, const char *); void load_server_config(const char *, Buffer *); -void parse_server_config(ServerOptions *, const char *, Buffer *); +void parse_server_config(ServerOptions *, const char *, Buffer *, + const char *, const char *, const char *); +void parse_server_match_config(ServerOptions *, const char *, const char *, + const char *); +void copy_set_server_options(ServerOptions *, ServerOptions *); #endif /* SERVCONF_H */ @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.336 2006/07/11 20:07:25 stevesk Exp $ */ +/* $OpenBSD: sshd.c,v 1.337 2006/07/12 11:34:58 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -219,12 +219,15 @@ int *startup_pipes = NULL; int startup_pipe; /* in child */ /* variables used for privilege separation */ -int use_privsep; +int use_privsep = -1; struct monitor *pmonitor = NULL; /* global authentication context */ Authctxt *the_authctxt = NULL; +/* sshd_config buffer */ +Buffer cfg; + /* message to be displayed after login */ Buffer loginmsg; @@ -916,7 +919,6 @@ main(int ac, char **av) Key *key; Authctxt *authctxt; int ret, key_used = 0; - Buffer cfg; #ifdef HAVE_SECUREWARE (void)set_auth_parameters(ac, av); @@ -1036,7 +1038,7 @@ main(int ac, char **av) case 'o': line = xstrdup(optarg); if (process_server_config_line(&options, line, - "command-line", 0) != 0) + "command-line", 0, NULL, NULL, NULL, NULL) != 0) exit(1); xfree(line); break; @@ -1094,11 +1096,8 @@ main(int ac, char **av) else load_server_config(config_file_name, &cfg); - parse_server_config(&options, - rexeced_flag ? "rexec" : config_file_name, &cfg); - - if (!rexec_flag) - buffer_free(&cfg); + parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, + &cfg, NULL, NULL, NULL); seed_rng(); diff --git a/sshd_config.5 b/sshd_config.5 index 3b639b17..0b264602 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.59 2006/07/06 10:47:05 djm Exp $ +.\" $OpenBSD: sshd_config.5,v 1.60 2006/07/12 11:34:58 dtucker Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -463,6 +463,27 @@ for data integrity protection. Multiple algorithms must be comma-separated. The default is: .Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 . +.It Cm Match +Introduces a conditional block. Keywords on lines following a +.Cm Match +block are only applied if all of the criteria on the +.Cm Match +are satisfied. +The the arguments to +.Cm Match +block are one or more criteria-pattern pairs. +The available criteria are +.Cm User , +.Cm Host , +and +.Cm Address . +Only a subset of keywords may be used on the lines following a +.Cm Match +keyword. +Available keywords are +.Cm AllowTcpForwarding , +and +.Cm GatewayPorts . .It Cm MaxAuthTries Specifies the maximum number of authentication attempts permitted per connection. |