This is a port of a patch I contributed to ssh 1.2.23 in May 1998. I have missed the functionality after moving to OpenSSH so I have updated the patch and hope OpenSSH might accept it. The patch allows sshd_config to have lines like: AllowUsers root at localhost AllowUsers tridge@* AllowUsers guest at 192.168.2.* DenyUsers badguy@* etc. I found this useful for restricting users to only login from hostnames that they pre-arranged with me. Patch is against current cvs. Cheers, Tridge Index: auth.c ==================================================================RCS file: /cvs/openssh_cvs/auth.c,v retrieving revision 1.28 diff -u -r1.28 auth.c --- auth.c 2001/03/19 22:15:57 1.28 +++ auth.c 2001/06/04 15:20:52 @@ -45,6 +45,56 @@ extern ServerOptions options; /* + match a hostname or an IP to a pattern. If the pattern only contains digits and '.' + then match as a IP, otherwise match as a hostname + */ +static int match_host(const char *host, const char *ip, const char *pattern) +{ + const char *p; + for (p=pattern; *p; p++) { + if (!strchr("0123456789*?.", *p)) { + /* treat as a hostname */ + return match_pattern(host, pattern); + } + } + return match_pattern(ip, pattern); +} + + +/* this combines the effect of match_pattern on a username, hostname + and IP address. If the pattern contains a @ then the part preceding + the @ is checked against the username. The part after the @ is + checked against the hostname and IP address. If no @ is found then + a normal match_pattern is done against the username + + This is more useful than just a match_pattern as it allows you to + specify exactly what users are alowed to login from what hosts + (tridge, May 1998) +*/ +static int match_user(const char *user, const char *host, const char *ip, + const char *pattern) +{ + int ret; + char *p2; + char *p; + + p = strchr(pattern,'@'); + + if (!p) return match_pattern(user, pattern); + + p2 = xstrdup(pattern); + p = strchr(p2, '@'); + + *p = 0; + + ret = match_pattern(user,p2) && match_host(host, ip, p + 1); + + xfree(p2); + return ret; +} + + +/* * Check if the user is allowed to log in via ssh. If user is listed * in DenyUsers or one of user's groups is listed in DenyGroups, false * will be returned. If AllowUsers isn't empty and user isn't listed @@ -103,14 +153,18 @@ /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { + const char *hostname = get_canonical_hostname(options.reverse_mapping_check); + const char *ipaddr = get_remote_ipaddr(); for (i = 0; i < options.num_deny_users; i++) - if (match_pattern(pw->pw_name, options.deny_users[i])) + if (match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i])) return 0; } /* Return false if AllowUsers isn't empty and user isn't listed there */ if (options.num_allow_users > 0) { + const char *hostname = get_canonical_hostname(options.reverse_mapping_check); + const char *ipaddr = get_remote_ipaddr(); for (i = 0; i < options.num_allow_users; i++) - if (match_pattern(pw->pw_name, options.allow_users[i])) + if (match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i])) break; /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) Index: sshd.8 ==================================================================RCS file: /cvs/openssh_cvs/sshd.8,v retrieving revision 1.78 diff -u -r1.78 sshd.8 --- sshd.8 2001/05/04 22:38:43 1.78 +++ sshd.8 2001/06/04 15:20:54 @@ -330,6 +330,9 @@ wildcards in the patterns. Only user names are valid; a numerical user ID isn't recognized. By default login is allowed regardless of the user name. +If the pattern takes the form USER at HOST then USER and HOST +are separately checked, allowing you to restrict logins to particular +users from particular hosts. .Pp .It Cm Banner In some jurisdictions, sending a warning message before authentication