diff --git a/ChangeLog b/ChangeLog index 9701f255a..48b51a4eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -51,6 +51,10 @@ requests? It could have been attacked with something like SSH'jack: http://www.storm.net.nz/projects/7 feedback & ok markus + - djm@cvs.openbsd.org 2008/06/10 23:06:19 + [auth-options.c match.c servconf.c addrmatch.c sshd.8] + support CIDR address matching in .ssh/authorized_keys from="..." stanzas + ok and extensive testing dtucker@ - (dtucker) [openbsd-compat/fake-rfc2553.h] Add sin6_scope_id to sockaddr_in6 since the new CIDR code in addmatch.c references it. - (dtucker) [Makefile.in configure.ac regress/addrmatch.sh] Skip IPv6 @@ -4143,4 +4147,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4962 2008/06/10 23:34:01 dtucker Exp $ +$Id: ChangeLog,v 1.4963 2008/06/10 23:34:46 dtucker Exp $ diff --git a/addrmatch.c b/addrmatch.c index a0559efa0..2086afe84 100644 --- a/addrmatch.c +++ b/addrmatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: addrmatch.c,v 1.2 2008/06/10 05:22:45 djm Exp $ */ +/* $OpenBSD: addrmatch.c,v 1.3 2008/06/10 23:06:19 djm Exp $ */ /* * Copyright (c) 2004-2008 Damien Miller @@ -366,7 +366,8 @@ addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen) * * Returns 1 on match found (never returned when addr == NULL). * Returns 0 on if no match found, or no errors found when addr == NULL. - * Returns -1 on invalid list entry. + * Returns -1 on negated match found (never returned when addr == NULL). + * Returns -2 on invalid list entry. */ int addr_match_list(const char *addr, const char *_list) @@ -387,7 +388,7 @@ addr_match_list(const char *addr, const char *_list) if (neg) cp++; if (*cp == '\0') { - ret = -1; + ret = -2; break; } /* Prefer CIDR address matching */ @@ -395,14 +396,14 @@ addr_match_list(const char *addr, const char *_list) if (r == -2) { error("Inconsistent mask length for " "network \"%.100s\"", cp); - ret = -1; + ret = -2; break; } else if (r == 0) { if (addr != NULL && addr_netmatch(&try_addr, &match_addr, masklen) == 0) { foundit: if (neg) { - ret = 0; + ret = -1; break; } ret = 1; diff --git a/auth-options.c b/auth-options.c index 3a6c3c0f3..25361455e 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.42 2008/05/08 12:02:23 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.43 2008/06/10 23:06:19 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -226,8 +226,19 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) } patterns[i] = '\0'; opts++; - if (match_host_and_ip(remote_host, remote_ip, - patterns) != 1) { + 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 " @@ -236,12 +247,10 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) auth_debug_add("Your host '%.200s' is not " "permitted to use this key for login.", remote_host); - /* deny access */ - return 0; + break; } - xfree(patterns); - /* Host name matches. */ - goto next_option; + /* deny access */ + return 0; } cp = "permitopen=\""; if (strncasecmp(opts, cp, strlen(cp)) == 0) { diff --git a/match.c b/match.c index e3c993073..238947778 100644 --- a/match.c +++ b/match.c @@ -1,4 +1,4 @@ -/* $OpenBSD: match.c,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: match.c,v 1.27 2008/06/10 23:06:19 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -183,7 +183,8 @@ match_hostname(const char *host, const char *pattern, u_int len) /* * returns 0 if we get a negative match for the hostname or the ip - * or if we get no match at all. returns 1 otherwise. + * or if we get no match at all. returns -1 on error, or 1 on + * successful match. */ int match_host_and_ip(const char *host, const char *ipaddr, @@ -191,9 +192,12 @@ match_host_and_ip(const char *host, const char *ipaddr, { int mhost, mip; - /* negative ipaddr match */ - if ((mip = match_hostname(ipaddr, patterns, strlen(patterns))) == -1) + /* error in ipaddr match */ + if ((mip = addr_match_list(ipaddr, patterns)) == -2) + return -1; + else if (mip == -1) /* negative ip address match */ return 0; + /* negative hostname match */ if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1) return 0; diff --git a/servconf.c b/servconf.c index 63704fb33..8f5ddbd33 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.182 2008/06/10 04:50:25 dtucker Exp $ */ +/* $OpenBSD: servconf.c,v 1.183 2008/06/10 23:06:19 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -621,9 +621,10 @@ match_cfg_line(char **condition, int line, const char *user, const char *host, "%.100s' at line %d", address, arg, line); break; case 0: + case -1: result = 0; break; - case -1: + case -2: return -1; } } else { diff --git a/sshd.8 b/sshd.8 index 1ec135ca9..0ae02ea3e 100644 --- a/sshd.8 +++ b/sshd.8 @@ -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.8,v 1.243 2008/06/10 08:17:40 jmc Exp $ +.\" $OpenBSD: sshd.8,v 1.244 2008/06/10 23:06:19 djm Exp $ .Dd $Mdocdate: June 10 2008 $ .Dt SSHD 8 .Os @@ -531,23 +531,27 @@ This option is automatically disabled if .Cm UseLogin is enabled. .It Cm from="pattern-list" -Specifies that in addition to public key authentication, the canonical name -of the remote host must be present in the comma-separated list of -patterns. -The purpose -of this option is to optionally increase security: public key authentication -by itself does not trust the network or name servers or anything (but -the key); however, if somebody somehow steals the key, the key -permits an intruder to log in from anywhere in the world. -This additional option makes using a stolen key more difficult (name -servers and/or routers would have to be compromised in addition to -just the key). -.Pp +Specifies that in addition to public key authentication, either the canonical +name of the remote host or its IP address must be present in the +comma-separated list of patterns. See .Sx PATTERNS in .Xr ssh_config 5 for more information on patterns. +.Pp +In addition to the wildcard matching that may be applied to hostnames or +addresses, a +.Cm from +stanza may match IP addressess using CIDR address/masklen notation. +.Pp +The purpose of this option is to optionally increase security: public key +authentication by itself does not trust the network or name servers or +anything (but the key); however, if somebody somehow steals the key, the key +permits an intruder to log in from anywhere in the world. +This additional option makes using a stolen key more difficult (name +servers and/or routers would have to be compromised in addition to +just the key). .It Cm no-agent-forwarding Forbids authentication agent forwarding when this key is used for authentication.