Bugzilla – Attachment 1127 Details for
Bug 1180
Add finer-grained controls to sshd_config
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Updated Match patch, against portable current.
openssh-match5.patch (text/plain), 35.04 KB, created by
Darren Tucker
on 2006-05-01 16:12:33 AEST
(
hide
)
Description:
Updated Match patch, against portable current.
Filename:
MIME Type:
Creator:
Darren Tucker
Created:
2006-05-01 16:12:33 AEST
Size:
35.04 KB
patch
obsolete
>Index: Makefile.in >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/Makefile.in,v >retrieving revision 1.278 >diff -u -p -r1.278 Makefile.in >--- Makefile.in 23 Apr 2006 02:15:08 -0000 1.278 >+++ Makefile.in 1 May 2006 03:51:22 -0000 >@@ -82,7 +82,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw > auth.o auth1.o auth2.o auth-options.o session.o \ > auth-chall.o auth2-chall.o groupaccess.o \ > auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ >- auth2-none.o auth2-passwd.o auth2-pubkey.o \ >+ auth2-none.o auth2-passwd.o auth2-pubkey.o cfgmatch.o \ > monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \ > auth-krb5.o \ > auth2-gss.o gss-serv.o gss-serv-krb5.o \ >Index: auth.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth.c,v >retrieving revision 1.109 >diff -u -p -r1.109 auth.c >--- auth.c 31 Mar 2006 12:14:24 -0000 1.109 >+++ auth.c 1 May 2006 03:51:22 -0000 >@@ -499,6 +499,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", >Index: cfgmatch.c >=================================================================== >RCS file: cfgmatch.c >diff -N cfgmatch.c >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ cfgmatch.c 1 May 2006 05:11:42 -0000 >@@ -0,0 +1,140 @@ >+/* >+ * Copyright (c) 2006 Darren Tucker. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR >+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES >+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. >+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, >+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT >+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF >+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "includes.h" >+ >+#include "match.h" >+#include "log.h" >+#include "misc.h" >+#include "canohost.h" >+#include "servconf.h" >+#include "groupaccess.h" >+#include "xmalloc.h" >+ >+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; >+ >+ 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; >+ >+ if ((pw = getpwnam(user)) == NULL) { >+ debug("Can't match group at line %d because " >+ "user %.100s does not exist", line, 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 { >+ debug("user %.100s matched group %.100s at " >+ "line %d", user, arg, line); >+ result = 1; >+ } >+out: >+ xfree(arg); >+ return result; >+} >+ >+ >+int >+match_cfg_line(char **condition, int line, const char *user, const char *host, >+ const char *address) >+{ >+ int r, 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'", cp); >+ >+ 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) >+ /* XXX what about negative match? */ >+ result = 0; >+ else >+ debug("user %.100s matched 'User %.100s' at " >+ "line %d", user, arg, line); >+ } else if (strcasecmp(attrib, "group") == 0) { >+ if ((r = match_cfg_line_group(arg, line, user)) < 0) >+ return -1; >+ if (r == 0) >+ result = 0; >+ } 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) { >+ 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; >+} >Index: groupaccess.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/groupaccess.c,v >retrieving revision 1.10 >diff -u -p -r1.10 groupaccess.c >--- groupaccess.c 26 Mar 2006 03:24:49 -0000 1.10 >+++ groupaccess.c 1 May 2006 04:39:43 -0000 >@@ -32,6 +32,8 @@ > > static int ngroups; > static char **groups_byname; >+static char *saved_user; >+static gid_t saved_gid; > > /* > * Initialize group access list for user with primary (base) and >@@ -44,14 +46,23 @@ ga_init(const char *user, gid_t base) > int i, j; > struct group *gr; > >- if (ngroups > 0) >+ if (saved_user != NULL && strcmp(saved_user, user) == 0 && >+ saved_gid == base) >+ return ngroups; >+ >+ if (ngroups > 0) { > ga_free(); >+ xfree(saved_user); >+ saved_user = NULL; >+ } > > ngroups = NGROUPS_MAX; > #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX) > ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX)); > #endif > >+ saved_user = xstrdup(user); >+ saved_gid = base; > groups_bygid = xmalloc(ngroups * sizeof(*groups_bygid)); > groups_byname = xmalloc(ngroups * sizeof(*groups_byname)); > >Index: match.h >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/match.h,v >retrieving revision 1.12 >diff -u -p -r1.12 match.h >--- match.h 26 Mar 2006 03:30:02 -0000 1.12 >+++ match.h 1 May 2006 03:51:22 -0000 >@@ -20,5 +20,6 @@ int match_hostname(const char *, const > int match_host_and_ip(const char *, const char *, const char *); > int match_user(const char *, const char *, const char *, const char *); > char *match_list(const char *, const char *, u_int *); >+int match_cfg_line(char **, int, const char *, const char *, const char *); > > #endif >Index: monitor.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/monitor.c,v >retrieving revision 1.102 >diff -u -p -r1.102 monitor.c >--- monitor.c 31 Mar 2006 12:14:24 -0000 1.102 >+++ monitor.c 1 May 2006 04:30:22 -0000 >@@ -628,6 +628,12 @@ mm_answer_pwnamallow(int sock, Buffer *m > #endif > buffer_put_cstring(m, pwent->pw_dir); > buffer_put_cstring(m, pwent->pw_shell); >+ buffer_put_string(m, &options, sizeof(options)); >+ if (options.banner != NULL) { >+ buffer_put_int(m, 1); >+ buffer_put_cstring(m, options.banner); >+ } else >+ buffer_put_int(m, 0); > > out: > debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); >Index: monitor_wrap.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/monitor_wrap.c,v >retrieving revision 1.59 >diff -u -p -r1.59 monitor_wrap.c >--- monitor_wrap.c 31 Mar 2006 12:13:02 -0000 1.59 >+++ monitor_wrap.c 1 May 2006 05:49:21 -0000 >@@ -196,7 +196,9 @@ mm_getpwnamallow(const char *username) > { > Buffer m; > struct passwd *pw; >- u_int pwlen; >+ u_int len; >+ void *p; >+ ServerOptions newopts; > > debug3("%s entering", __func__); > >@@ -212,8 +214,8 @@ mm_getpwnamallow(const char *username) > buffer_free(&m); > return (NULL); > } >- pw = buffer_get_string(&m, &pwlen); >- if (pwlen != sizeof(struct passwd)) >+ pw = buffer_get_string(&m, &len); >+ if (len != sizeof(struct passwd)) > fatal("%s: struct passwd size mismatch", __func__); > pw->pw_name = buffer_get_string(&m, NULL); > pw->pw_passwd = buffer_get_string(&m, NULL); >@@ -223,6 +225,32 @@ mm_getpwnamallow(const char *username) > #endif > pw->pw_dir = buffer_get_string(&m, NULL); > pw->pw_shell = buffer_get_string(&m, NULL); >+ >+ /* copy options block as a Match directive may have changed some */ >+ p = buffer_get_string(&m, &len); >+ if (len != sizeof(newopts)) >+ fatal("%s: option block size mismatch", __func__); >+ memcpy(&newopts, p, sizeof(newopts)); >+ newopts.banner = NULL; >+ if (buffer_get_int(&m) == 1) >+ newopts.banner = buffer_get_string(&m, NULL); >+ /* unset the string/array options not used in the slave */ >+ newopts.num_ports = 0; >+ newopts.ports_from_cmdline = 0; >+ newopts.pid_file = NULL; >+ newopts.xauth_location = NULL; >+ newopts.ciphers = NULL; >+ newopts.num_allow_users = 0; >+ newopts.num_deny_users = 0; >+ newopts.num_allow_groups = 0; >+ newopts.num_deny_groups = 0; >+ newopts.macs = NULL; >+ newopts.num_subsystems = 0; >+ newopts.authorized_keys_file = NULL; >+ newopts.authorized_keys_file2 = NULL; >+ newopts.num_accept_env = 0; >+ copy_set_server_options(&options, &newopts); >+ > buffer_free(&m); > > return (pw); >Index: servconf.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/servconf.c,v >retrieving revision 1.140 >diff -u -p -r1.140 servconf.c >--- servconf.c 26 Mar 2006 03:24:50 -0000 1.140 >+++ servconf.c 1 May 2006 06:06:34 -0000 >@@ -22,12 +22,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. */ > >@@ -102,9 +104,6 @@ initialize_server_options(ServerOptions > 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 >@@ -274,110 +273,117 @@ typedef enum { > sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, > sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, > sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, >+ sMatch, > sUsePrivilegeSeparation, > sDeprecated, sUnsupported > } ServerOpCodes; > >+#define SSHCFG_GLOBAL 0x01 >+#define SSHCFG_MATCH 0x02 >+#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_ALL }, > #else >- { "usepam", sUnsupported }, >+ { "usepam", sUnsupported, SSHCFG_ALL }, > #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_ALL }, >+ { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, >+ { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, >+ { "syslogfacility", sLogFacility, SSHCFG_ALL }, >+ { "loglevel", sLogLevel, SSHCFG_ALL }, >+ { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, >+ { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL }, >+ { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, >+ { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL }, >+ { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL }, >+ { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, >+ { "dsaauthentication", sPubkeyAuthentication, SSHCFG_ALL }, /* alias */ > #ifdef KRB5 >- { "kerberosauthentication", sKerberosAuthentication }, >- { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, >- { "kerberosticketcleanup", sKerberosTicketCleanup }, >+ { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, >+ { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_ALL }, >+ { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_ALL }, > #ifdef USE_AFS >- { "kerberosgetafstoken", sKerberosGetAFSToken }, >+ { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_ALL }, > #else >- { "kerberosgetafstoken", sUnsupported }, >+ { "kerberosgetafstoken", sUnsupported, SSHCFG_ALL }, > #endif > #else >- { "kerberosauthentication", sUnsupported }, >- { "kerberosorlocalpasswd", sUnsupported }, >- { "kerberosticketcleanup", sUnsupported }, >- { "kerberosgetafstoken", sUnsupported }, >+ { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, >+ { "kerberosorlocalpasswd", sUnsupported, SSHCFG_ALL }, >+ { "kerberosticketcleanup", sUnsupported, SSHCFG_ALL }, >+ { "kerberosgetafstoken", sUnsupported, SSHCFG_ALL }, > #endif >- { "kerberostgtpassing", sUnsupported }, >- { "afstokenpassing", sUnsupported }, >+ { "kerberostgtpassing", sUnsupported, SSHCFG_ALL }, >+ { "afstokenpassing", sUnsupported, SSHCFG_ALL }, > #ifdef GSSAPI >- { "gssapiauthentication", sGssAuthentication }, >- { "gssapicleanupcredentials", sGssCleanupCreds }, >+ { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, >+ { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_ALL }, > #else >- { "gssapiauthentication", sUnsupported }, >- { "gssapicleanupcredentials", sUnsupported }, >+ { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, >+ { "gssapicleanupcredentials", sUnsupported, SSHCFG_ALL }, > #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_ALL }, >+ { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, >+ { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_ALL }, >+ { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_ALL }, /* alias */ >+ { "checkmail", sDeprecated, SSHCFG_GLOBAL }, >+ { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, >+ { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, >+ { "printmotd", sPrintMotd, SSHCFG_ALL }, >+ { "printlastlog", sPrintLastLog, SSHCFG_ALL }, >+ { "ignorerhosts", sIgnoreRhosts, SSHCFG_ALL }, >+ { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_ALL }, >+ { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, >+ { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, >+ { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, >+ { "xauthlocation", sXAuthLocation, SSHCFG_ALL }, >+ { "strictmodes", sStrictModes, SSHCFG_ALL }, >+ { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL }, >+ { "permituserenvironment", sPermitUserEnvironment, SSHCFG_ALL }, >+ { "uselogin", sUseLogin, SSHCFG_ALL }, >+ { "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_ALL }, >+ { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, >+ { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, >+ { "banner", sBanner, SSHCFG_ALL }, >+ { "usedns", sUseDNS, SSHCFG_GLOBAL }, >+ { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, >+ { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, >+ { "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL }, >+ { "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL }, >+ { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL }, >+ { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_ALL }, >+ { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL}, >+ { "acceptenv", sAcceptEnv, SSHCFG_ALL }, >+ { "permittunnel", sPermitTunnel, SSHCFG_ALL }, >+ { "match", sMatch, SSHCFG_ALL }, >+ { NULL, sBadOption, 0 } > }; > > /* >@@ -386,13 +392,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); >@@ -437,15 +445,49 @@ add_one_listen_addr(ServerOptions *optio > 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 >+ */ >+ > 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; > > cp = line; > if ((arg = strdelim(&cp)) == NULL) >@@ -457,7 +499,25 @@ process_server_config_line(ServerOptions > 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: >@@ -495,7 +555,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; > >@@ -575,7 +635,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) >@@ -626,7 +686,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; > >@@ -891,6 +951,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.", >@@ -962,6 +1026,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); > } >@@ -989,6 +1055,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); >@@ -1045,18 +1122,146 @@ load_server_config(const char *filename, > } > > 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) >+{ >+ u_int i; >+ >+ if (src->use_pam != -1) >+ dst->use_pam = src->use_pam; >+ if (src->num_accept_env > 0) { >+ for (i = 0; i < dst->num_accept_env; i++) >+ xfree(dst->accept_env[i]); >+ dst->num_accept_env = 0; >+ for (i = 0; i < src->num_accept_env; i++) { >+ if (dst->num_accept_env >= MAX_ACCEPT_ENV) >+ fatal("Too many allow env in Match block."); >+ dst->accept_env[dst->num_accept_env++] = >+ src->accept_env[i]; >+ } >+ } >+ if (src->allow_tcp_forwarding != -1) >+ dst->allow_tcp_forwarding = src->allow_tcp_forwarding; >+ if (src->authorized_keys_file != NULL) { >+ if (dst->authorized_keys_file != NULL) >+ xfree(dst->authorized_keys_file); >+ dst->authorized_keys_file = src->authorized_keys_file; >+ } >+ if (src->authorized_keys_file2 != NULL) { >+ if (dst->authorized_keys_file2 != NULL) >+ xfree(dst->authorized_keys_file2); >+ dst->authorized_keys_file2 = src->authorized_keys_file2; >+ } >+ if (src->banner != NULL) { >+ if (dst->banner != NULL) >+ xfree(dst->banner); >+ dst->banner = src->banner; >+ } >+ if (src->password_authentication != -1) >+ dst->password_authentication = src->password_authentication; >+ if (src->challenge_response_authentication != -1) >+ dst->challenge_response_authentication = >+ src->challenge_response_authentication; >+ if (src->client_alive_count_max != -1) >+ dst->client_alive_count_max = src->client_alive_count_max; >+ if (src->client_alive_interval != -1) >+ dst->client_alive_interval = src->client_alive_interval; >+ if (src->gateway_ports != -1) >+ dst->gateway_ports = src->gateway_ports; >+ if (src->gss_authentication != -1) >+ dst->gss_authentication = src->gss_authentication; >+ if (src->hostbased_authentication != -1) >+ dst->hostbased_authentication = src->hostbased_authentication; >+ if (src->hostbased_uses_name_from_packet_only != -1) >+ dst->hostbased_uses_name_from_packet_only = >+ src->hostbased_uses_name_from_packet_only; >+ if (src->kerberos_authentication != -1) >+ dst->kerberos_authentication = src->kerberos_authentication; >+ if (src->kerberos_or_local_passwd != -1) >+ dst->kerberos_or_local_passwd = src->kerberos_or_local_passwd; >+ if (src->kerberos_ticket_cleanup != -1) >+ dst->kerberos_ticket_cleanup = src->kerberos_ticket_cleanup; >+ if (src->kerberos_get_afs_token != -1) >+ dst->kerberos_get_afs_token = src->kerberos_get_afs_token; >+ if (src->login_grace_time != -1) >+ dst->login_grace_time = src->login_grace_time; >+ if (src->log_facility != -1) >+ dst->log_facility = src->log_facility; >+ if (src->log_level != -1) >+ dst->log_level = src->log_level; >+ if (src->permit_root_login != -1) >+ dst->permit_root_login = src->permit_root_login; >+ if (src->max_authtries != -1) >+ dst->max_authtries = src->max_authtries; >+ if (src->permit_empty_passwd != -1) >+ dst->permit_empty_passwd = src->permit_empty_passwd; >+ if (src->permit_tun != -1) >+ dst->permit_tun = src->permit_tun; >+ if (src->permit_user_env != -1) >+ dst->permit_user_env = src->permit_user_env; >+ if (src->print_motd != -1) >+ dst->print_motd = src->print_motd; >+ if (src->pubkey_authentication != -1) >+ dst->pubkey_authentication = src->pubkey_authentication; >+ if (src->rsa_authentication != -1) >+ dst->rsa_authentication = src->rsa_authentication; >+ if (src->strict_modes != -1) >+ dst->strict_modes = src->strict_modes; >+ if (src->num_subsystems != 0) { /* Not currently used */ >+ for (i = 0; i < dst->num_subsystems; i++) { >+ xfree(dst->subsystem_name[i]); >+ xfree(dst->subsystem_command[i]); >+ } >+ dst->num_subsystems = 0; >+ for (i = 0; i < src->num_subsystems; i++) { >+ dst->subsystem_name[dst->num_subsystems] = >+ src->subsystem_name[i]; >+ dst->subsystem_command[dst->num_subsystems] = >+ src->subsystem_command[i]; >+ dst->num_subsystems++; >+ } >+ } >+ if (src->use_login != -1) >+ dst->use_login = src->use_login; >+ if (src->xauth_location != NULL) { >+ if (dst->xauth_location != NULL) >+ xfree(dst->xauth_location); >+ dst->xauth_location = src->xauth_location; >+ } >+ if (src->x11_display_offset != -1) >+ dst->x11_display_offset = src->x11_display_offset; >+ if (src->x11_forwarding != -1) >+ dst->x11_forwarding = src->x11_forwarding; >+ if (src->x11_use_localhost != -1) >+ dst->x11_use_localhost = src->x11_use_localhost; >+} >+ >+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); >Index: servconf.h >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/servconf.h,v >retrieving revision 1.65 >diff -u -p -r1.65 servconf.h >--- servconf.h 26 Mar 2006 03:30:02 -0000 1.65 >+++ servconf.h 1 May 2006 05:39:16 -0000 >@@ -27,6 +27,7 @@ > #define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ > #define MAX_HOSTKEYS 256 /* Max # hostkeys. */ > #define MAX_ACCEPT_ENV 256 /* Max # of env vars. */ >+#define MAX_MATCH_GROUPS 256 /* Max # of groups for Match Group */ > > /* permit_root_login */ > #define PERMIT_NOT_SET -1 >@@ -141,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 */ >Index: sshd.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/sshd.c,v >retrieving revision 1.333 >diff -u -p -r1.333 sshd.c >--- sshd.c 26 Mar 2006 03:24:50 -0000 1.333 >+++ sshd.c 1 May 2006 03:51:22 -0000 >@@ -213,12 +213,15 @@ int *startup_pipes = NULL; > int startup_pipe; /* in child */ > > /* variables used for privilege separation */ >-int use_privsep; >+int use_privsep = -1; /* Needs to be accessable in many places */ > struct monitor *pmonitor = NULL; > > /* global authentication context */ > Authctxt *the_authctxt = NULL; > >+/* sshd_config buffer */ >+Buffer cfg; >+ > /* message to be displayed after login */ > Buffer loginmsg; > >@@ -910,7 +913,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); >@@ -1030,7 +1032,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; >@@ -1088,11 +1090,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(); > >Index: sshd_config.5 >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/sshd_config.5,v >retrieving revision 1.63 >diff -u -p -r1.63 sshd_config.5 >--- sshd_config.5 15 Mar 2006 01:07:07 -0000 1.63 >+++ sshd_config.5 1 May 2006 03:51:22 -0000 >@@ -463,6 +463,70 @@ 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 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 Group , >+.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 AcceptEnv , >+.Cm AllowTcpForwarding , >+.Cm AuthorizedKeysFile , >+.Cm AuthorizedKeysFile2 , >+.Cm Banner , >+.Cm ChallengeResponseAuthentication , >+.Cm ChallengeResponseAuthentication , >+.Cm ClientAliveCountMax , >+.Cm ClientAliveInterval , >+.Cm GatewayPorts , >+.Cm GssAuthentication , >+.Cm GssCleanupCreds , >+.Cm HostbasedAuthentication , >+.Cm HostbasedUsesNameFromPacketOnly , >+.Cm IgnoreRhosts , >+.Cm IgnoreUserKnownHosts , >+.Cm KbdInteractiveAuthentication , >+.Cm KerberosAuthentication , >+.Cm KerberosGetAFSToken , >+.Cm KerberosOrLocalPasswd , >+.Cm KerberosTicketCleanup , >+.Cm LogFacility , >+.Cm LogLevel , >+.Cm LoginGraceTime , >+.Cm MaxAuthTries , >+.Cm PasswordAuthentication , >+.Cm PermitEmptyPasswd , >+.Cm PermitRootLogin , >+.Cm PermitTunnel , >+.Cm PermitUserEnvironment , >+.Cm PrintLastLog , >+.Cm PrintMotd , >+.Cm PubkeyAuthentication , >+.Cm PubkeyAuthentication , >+.Cm RSAAuthentication , >+.Cm RhostsRSAAuthentication , >+.Cm StrictModes , >+.Cm Subsystem , >+.Cm UseLogin , >+.Cm UsePAM , >+.Cm X11DisplayOffset , >+.Cm X11Forwarding , >+.Cm X11UseLocalhost , >+and >+.Cm XAuthLocation . > .It Cm MaxAuthTries > Specifies the maximum number of authentication attempts permitted per > connection. >@@ -855,6 +919,17 @@ Contains configuration data for > This file should be writable by root only, but it is recommended > (though not necessary) that it be world-readable. > .El >+.Sh EXAMPLES >+To allow >+.Cm PasswordAuthentication >+only from the local private network: >+.Bd -literal -offset indent >+PasswordAuthentication no >+Match Address 192.168.0.* >+ PasswordAuthentication yes >+.Ed >+.Bl -tag -width Ds >+.Bl -tag -width Ds > .Sh SEE ALSO > .Xr sshd 8 > .Sh AUTHORS
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1180
:
1118
| 1127 |
1184
|
1185
|
1240