Patch to sshd match
Alain Williams
addw at phcomp.co.uk
Mon Nov 12 04:41:02 EST 2007
Please find attached a patch against openssh-4.7p1
It extends the Match in sshd_config. The point is that it is sometimes
easier (and more secure) to match on NOT something.
A criterium may be preceded by ! which inverts the condition, thus:
Match !Group sysadmins
ForceCommand /usr/bin/sftp
forces use of sftp on any user who is not a system administrator.
A !! has the same effect as no ! - but I didn't document that.
I am looking at sftp, extend it:
* read a config file - optionally
* commands to restrict a user to their $HOME.
--
Alain Williams
Linux Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
Chairman of UKUUG: http://www.ukuug.org/
#include <std_disclaimer.h>
-------------- next part --------------
--- servconf.c.orig 2007-05-20 06:03:16.000000000 +0100
+++ servconf.c 2007-11-11 17:21:38.000000000 +0000
@@ -498,13 +498,21 @@
* PermittedChannelRequests session,forwarded-tcpip
*/
+/* Check if user is in the comma separated group list grps. Invert condition if not.
+ * line is the config file line.
+ * Return:
+ * 1 match
+ * 0 not match
+ * -1 error
+ */
static int
-match_cfg_line_group(const char *grps, int line, const char *user)
+match_cfg_line_group(const char *grps, int line, const char *user, int not)
{
int result = 0;
u_int ngrps = 0;
char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
struct passwd *pw;
+ char* notstr = not ? "!" : "";
/*
* Even if we do not have a user yet, we still need to check for
@@ -529,12 +537,12 @@
} 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(grplist, ngrps) == not) {
+ debug("user %.100s does not match %sgroup %.100s at line %d",
+ user, notstr, arg, line);
} else {
- debug("user %.100s matched group %.100s at line %d", user,
- arg, line);
+ debug("user %.100s matched %sgroup %.100s at line %d", user,
+ notstr, arg, line);
result = 1;
}
out:
@@ -550,6 +558,8 @@
int result = 1;
char *arg, *attrib, *cp = *condition;
size_t len;
+ int not = 0;
+ char* notstr;
if (user == NULL)
debug3("checking syntax for 'Match %s'", cp);
@@ -559,6 +569,13 @@
address ? address : "(null)");
while ((attrib = strdelim(&cp)) && *attrib != '\0') {
+ while(*attrib == '!') { /* Parse a '!' to mean invert the condition */
+ not ^= 1;
+ attrib++;
+ }
+ if(*attrib == '\0') /* Maybe a ! was followed by white space */
+ continue;
+ notstr = not ? "!" : ""; /* For debug */
if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
error("Missing Match criteria for %s", attrib);
return -1;
@@ -567,15 +584,16 @@
if (strcasecmp(attrib, "user") == 0) {
if (!user) {
result = 0;
+ not = 0;
continue;
}
- if (match_pattern_list(user, arg, len, 0) != 1)
+ if (match_pattern_list(user, arg, len, 0) == not)
result = 0;
else
- debug("user %.100s matched 'User %.100s' at "
- "line %d", user, arg, line);
+ debug("user %.100s matched '%sUser %.100s' at "
+ "line %d", user, notstr, arg, line);
} else if (strcasecmp(attrib, "group") == 0) {
- switch (match_cfg_line_group(arg, line, user)) {
+ switch (match_cfg_line_group(arg, line, user, not)) {
case -1:
return -1;
case 0:
@@ -584,27 +602,30 @@
} else if (strcasecmp(attrib, "host") == 0) {
if (!host) {
result = 0;
+ not = 0;
continue;
}
- if (match_hostname(host, arg, len) != 1)
+ if (match_hostname(host, arg, len) == not)
result = 0;
else
- debug("connection from %.100s matched 'Host "
- "%.100s' at line %d", host, arg, line);
+ debug("connection from %.100s matched '%sHost "
+ "%.100s' at line %d", host, notstr, arg, line);
} else if (strcasecmp(attrib, "address") == 0) {
if (!address) {
result = 0;
+ not = 0;
continue;
}
- if (match_hostname(address, arg, len) != 1)
+ if (match_hostname(address, arg, len) == not)
result = 0;
else
- debug("connection from %.100s matched 'Address "
- "%.100s' at line %d", address, arg, line);
+ debug("connection from %.100s matched '%sAddress "
+ "%.100s' at line %d", address, notstr, arg, line);
} else {
error("Unsupported Match attribute %s", attrib);
return -1;
}
+ not = 0; /* Reset for next condition */
}
if (user != NULL)
debug3("match %sfound", result ? "" : "not ");
--- sshd_config.5.orig 2007-06-11 05:07:13.000000000 +0100
+++ sshd_config.5 2007-11-11 17:17:16.000000000 +0000
@@ -529,6 +529,16 @@
.Cm X11Forwarding ,
and
.Cm X11UseLocalHost .
+.Pp
+A criterium may be preceded by
+.Cm !
+which inverts the condition, thus:
+.pP
+.Bl -tag -width Ds -compact -offset indent
+.It Match !Group sysadmins
+.It ForceCommand /usr/bin/sftp
+.El
+forces use of sftp on any user who is not a system administrator.
.It Cm MaxAuthTries
Specifies the maximum number of authentication attempts permitted per
connection.
More information about the openssh-unix-dev
mailing list