diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2001-02-03 10:08:38 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2001-02-03 10:08:38 +0000 |
commit | 72babd8db302c1859dcee23b3e03d634615ae277 (patch) | |
tree | c6fc4a7a7d0667f4169b1bdb963394da57282657 | |
parent | 494de73e55e016caf742fa1eff4d6cac78206137 (diff) |
make ReverseMappingCheck optional in sshd_config; ok djm@,dugsong@
-rw-r--r-- | usr.bin/ssh/auth-options.c | 122 | ||||
-rw-r--r-- | usr.bin/ssh/auth-rh-rsa.c | 5 | ||||
-rw-r--r-- | usr.bin/ssh/auth-rhosts.c | 4 | ||||
-rw-r--r-- | usr.bin/ssh/auth.c | 4 | ||||
-rw-r--r-- | usr.bin/ssh/canohost.c | 199 | ||||
-rw-r--r-- | usr.bin/ssh/canohost.h | 11 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.c | 12 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.h | 3 | ||||
-rw-r--r-- | usr.bin/ssh/session.c | 4 | ||||
-rw-r--r-- | usr.bin/ssh/sshconnect1.c | 8 | ||||
-rw-r--r-- | usr.bin/ssh/sshd.8 | 10 | ||||
-rw-r--r-- | usr.bin/ssh/sshd_config | 3 |
12 files changed, 209 insertions, 176 deletions
diff --git a/usr.bin/ssh/auth-options.c b/usr.bin/ssh/auth-options.c index 5457d9b149c..04d2f085f62 100644 --- a/usr.bin/ssh/auth-options.c +++ b/usr.bin/ssh/auth-options.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-options.c,v 1.11 2001/01/21 19:05:41 markus Exp $"); +RCSID("$OpenBSD: auth-options.c,v 1.12 2001/02/03 10:08:36 markus Exp $"); #include "packet.h" #include "xmalloc.h" @@ -18,6 +18,7 @@ RCSID("$OpenBSD: auth-options.c,v 1.11 2001/01/21 19:05:41 markus Exp $"); #include "log.h" #include "canohost.h" #include "auth-options.h" +#include "servconf.h" /* Flags set authorized_keys flags */ int no_port_forwarding_flag = 0; @@ -31,6 +32,8 @@ char *forced_command = NULL; /* "environment=" options. */ struct envstring *custom_environment = NULL; +extern ServerOptions options; + void auth_clear_options(void) { @@ -55,61 +58,61 @@ auth_clear_options(void) * side effect: sets key option flags */ int -auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum) +auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) { const char *cp; - if (!options) + if (!opts) return 1; /* reset options */ auth_clear_options(); - while (*options && *options != ' ' && *options != '\t') { + while (*opts && *opts != ' ' && *opts != '\t') { cp = "no-port-forwarding"; - if (strncasecmp(options, cp, strlen(cp)) == 0) { + if (strncasecmp(opts, cp, strlen(cp)) == 0) { packet_send_debug("Port forwarding disabled."); no_port_forwarding_flag = 1; - options += strlen(cp); + opts += strlen(cp); goto next_option; } cp = "no-agent-forwarding"; - if (strncasecmp(options, cp, strlen(cp)) == 0) { + if (strncasecmp(opts, cp, strlen(cp)) == 0) { packet_send_debug("Agent forwarding disabled."); no_agent_forwarding_flag = 1; - options += strlen(cp); + opts += strlen(cp); goto next_option; } cp = "no-X11-forwarding"; - if (strncasecmp(options, cp, strlen(cp)) == 0) { + if (strncasecmp(opts, cp, strlen(cp)) == 0) { packet_send_debug("X11 forwarding disabled."); no_x11_forwarding_flag = 1; - options += strlen(cp); + opts += strlen(cp); goto next_option; } cp = "no-pty"; - if (strncasecmp(options, cp, strlen(cp)) == 0) { + if (strncasecmp(opts, cp, strlen(cp)) == 0) { packet_send_debug("Pty allocation disabled."); no_pty_flag = 1; - options += strlen(cp); + opts += strlen(cp); goto next_option; } cp = "command=\""; - if (strncasecmp(options, cp, strlen(cp)) == 0) { + if (strncasecmp(opts, cp, strlen(cp)) == 0) { int i; - options += strlen(cp); - forced_command = xmalloc(strlen(options) + 1); + opts += strlen(cp); + forced_command = xmalloc(strlen(opts) + 1); i = 0; - while (*options) { - if (*options == '"') + while (*opts) { + if (*opts == '"') break; - if (*options == '\\' && options[1] == '"') { - options += 2; + if (*opts == '\\' && opts[1] == '"') { + opts += 2; forced_command[i++] = '"'; continue; } - forced_command[i++] = *options++; + forced_command[i++] = *opts++; } - if (!*options) { + if (!*opts) { debug("%.100s, line %lu: missing end quote", file, linenum); packet_send_debug("%.100s, line %lu: missing end quote", @@ -118,28 +121,28 @@ auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum) } forced_command[i] = 0; packet_send_debug("Forced command: %.900s", forced_command); - options++; + opts++; goto next_option; } cp = "environment=\""; - if (strncasecmp(options, cp, strlen(cp)) == 0) { + if (strncasecmp(opts, cp, strlen(cp)) == 0) { int i; char *s; struct envstring *new_envstring; - options += strlen(cp); - s = xmalloc(strlen(options) + 1); + opts += strlen(cp); + s = xmalloc(strlen(opts) + 1); i = 0; - while (*options) { - if (*options == '"') + while (*opts) { + if (*opts == '"') break; - if (*options == '\\' && options[1] == '"') { - options += 2; + if (*opts == '\\' && opts[1] == '"') { + opts += 2; s[i++] = '"'; continue; } - s[i++] = *options++; + s[i++] = *opts++; } - if (!*options) { + if (!*opts) { debug("%.100s, line %lu: missing end quote", file, linenum); packet_send_debug("%.100s, line %lu: missing end quote", @@ -149,7 +152,7 @@ auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum) s[i] = 0; packet_send_debug("Adding to environment: %.900s", s); debug("Adding to environment: %.900s", s); - options++; + opts++; new_envstring = xmalloc(sizeof(struct envstring)); new_envstring->s = s; new_envstring->next = custom_environment; @@ -157,23 +160,26 @@ auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum) goto next_option; } cp = "from=\""; - if (strncasecmp(options, cp, strlen(cp)) == 0) { + if (strncasecmp(opts, cp, strlen(cp)) == 0) { int mname, mip; - char *patterns = xmalloc(strlen(options) + 1); + const char *remote_ip = get_remote_ipaddr(); + const char *remote_host = get_canonical_hostname( + options.reverse_mapping_check); + char *patterns = xmalloc(strlen(opts) + 1); int i; - options += strlen(cp); + opts += strlen(cp); i = 0; - while (*options) { - if (*options == '"') + while (*opts) { + if (*opts == '"') break; - if (*options == '\\' && options[1] == '"') { - options += 2; + if (*opts == '\\' && opts[1] == '"') { + opts += 2; patterns[i++] = '"'; continue; } - patterns[i++] = *options++; + patterns[i++] = *opts++; } - if (!*options) { + if (!*opts) { debug("%.100s, line %lu: missing end quote", file, linenum); packet_send_debug("%.100s, line %lu: missing end quote", @@ -181,24 +187,26 @@ auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum) continue; } patterns[i] = 0; - options++; + opts++; /* * Deny access if we get a negative * match for the hostname or the ip * or if we get not match at all */ - mname = match_hostname(get_canonical_hostname(), - patterns, strlen(patterns)); - mip = match_hostname(get_remote_ipaddr(), - patterns, strlen(patterns)); + mname = match_hostname(remote_host, patterns, + strlen(patterns)); + mip = match_hostname(remote_ip, patterns, + strlen(patterns)); xfree(patterns); if (mname == -1 || mip == -1 || (mname != 1 && mip != 1)) { - log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).", - pw->pw_name, get_canonical_hostname(), - get_remote_ipaddr()); - packet_send_debug("Your host '%.200s' is not permitted to use this key for login.", - get_canonical_hostname()); + log("Authentication tried for %.100s with " + "correct key but not from a permitted " + "host (host=%.200s, ip=%.200s).", + pw->pw_name, remote_host, remote_ip); + packet_send_debug("Your host '%.200s' is not " + "permitted to use this key for login.", + remote_host); /* deny access */ return 0; } @@ -210,13 +218,13 @@ next_option: * Skip the comma, and move to the next option * (or break out if there are no more). */ - if (!*options) + if (!*opts) fatal("Bugs in auth-options.c option processing."); - if (*options == ' ' || *options == '\t') + if (*opts == ' ' || *opts == '\t') break; /* End of options. */ - if (*options != ',') + if (*opts != ',') goto bad_option; - options++; + opts++; /* Process the next option. */ } /* grant access */ @@ -224,9 +232,9 @@ next_option: bad_option: log("Bad options in %.100s file, line %lu: %.50s", - file, linenum, options); + file, linenum, opts); packet_send_debug("Bad options in %.100s file, line %lu: %.50s", - file, linenum, options); + file, linenum, opts); /* deny access */ return 0; } diff --git a/usr.bin/ssh/auth-rh-rsa.c b/usr.bin/ssh/auth-rh-rsa.c index 87d51549d20..0edbdb5f377 100644 --- a/usr.bin/ssh/auth-rh-rsa.c +++ b/usr.bin/ssh/auth-rh-rsa.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rh-rsa.c,v 1.21 2001/01/21 19:05:42 markus Exp $"); +RCSID("$OpenBSD: auth-rh-rsa.c,v 1.22 2001/02/03 10:08:36 markus Exp $"); #include "packet.h" #include "xmalloc.h" @@ -49,7 +49,8 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key if (!auth_rhosts(pw, client_user)) return 0; - canonical_hostname = get_canonical_hostname(); + canonical_hostname = get_canonical_hostname( + options.reverse_mapping_check); debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname); diff --git a/usr.bin/ssh/auth-rhosts.c b/usr.bin/ssh/auth-rhosts.c index 4f9ea886d47..d8d10ffc9dd 100644 --- a/usr.bin/ssh/auth-rhosts.c +++ b/usr.bin/ssh/auth-rhosts.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rhosts.c,v 1.19 2001/01/21 19:05:42 markus Exp $"); +RCSID("$OpenBSD: auth-rhosts.c,v 1.20 2001/02/03 10:08:36 markus Exp $"); #include "packet.h" #include "xmalloc.h" @@ -183,7 +183,7 @@ auth_rhosts(struct passwd *pw, const char *client_user) stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0) return 0; - hostname = get_canonical_hostname(); + hostname = get_canonical_hostname(options.reverse_mapping_check); ipaddr = get_remote_ipaddr(); /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */ diff --git a/usr.bin/ssh/auth.c b/usr.bin/ssh/auth.c index 450250e28d4..8455107aca6 100644 --- a/usr.bin/ssh/auth.c +++ b/usr.bin/ssh/auth.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.14 2001/01/21 19:05:43 markus Exp $"); +RCSID("$OpenBSD: auth.c,v 1.15 2001/02/03 10:08:37 markus Exp $"); #include "xmalloc.h" #include "match.h" @@ -176,7 +176,7 @@ auth_root_allowed(void) log("Root login accepted for forced command."); return 1; } else { - log("ROOT LOGIN REFUSED FROM %.200s", get_canonical_hostname()); + log("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); return 0; } } diff --git a/usr.bin/ssh/canohost.c b/usr.bin/ssh/canohost.c index 8d5a50d5648..b61a2059e26 100644 --- a/usr.bin/ssh/canohost.c +++ b/usr.bin/ssh/canohost.c @@ -12,154 +12,165 @@ */ #include "includes.h" -RCSID("$OpenBSD: canohost.c,v 1.19 2001/01/29 19:42:33 markus Exp $"); +RCSID("$OpenBSD: canohost.c,v 1.20 2001/02/03 10:08:37 markus Exp $"); #include "packet.h" #include "xmalloc.h" #include "log.h" +void check_ip_options(int socket, char *ipaddr); + /* * Return the canonical name of the host at the other end of the socket. The * caller should free the returned string with xfree. */ char * -get_remote_hostname(int socket) +get_remote_hostname(int socket, int reverse_mapping_check) { struct sockaddr_storage from; int i; socklen_t fromlen; struct addrinfo hints, *ai, *aitop; - char name[MAXHOSTNAMELEN]; - char ntop[NI_MAXHOST], ntop2[NI_MAXHOST]; + char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST]; /* Get IP address of client. */ fromlen = sizeof(from); memset(&from, 0, sizeof(from)); - if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) { + if (getpeername(socket, (struct sockaddr *) &from, &fromlen) < 0) { debug("getpeername failed: %.100s", strerror(errno)); fatal_cleanup(); } + if (from.ss_family == AF_INET) + check_ip_options(socket, ntop); + if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0) fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); /* Map the IP address to a host name. */ if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), - NULL, 0, NI_NAMEREQD) == 0) { - /* Got host name. */ - name[sizeof(name) - 1] = '\0'; - /* - * Convert it to all lowercase (which is expected by the rest - * of this software). - */ - for (i = 0; name[i]; i++) - if (isupper(name[i])) - name[i] = tolower(name[i]); - - /* - * Map it back to an IP address and check that the given - * address actually is an address of this host. This is - * necessary because anyone with access to a name server can - * define arbitrary names for an IP address. Mapping from - * name to IP address can be trusted better (but can still be - * fooled if the intruder has access to the name server of - * the domain). - */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = from.ss_family; - hints.ai_socktype = SOCK_STREAM; - if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { - log("reverse mapping checking getaddrinfo for %.700s failed - POSSIBLE BREAKIN ATTEMPT!", name); - strlcpy(name, ntop, sizeof name); - goto check_ip_options; - } - /* Look for the address from the list of addresses. */ - for (ai = aitop; ai; ai = ai->ai_next) { - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, - sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && - (strcmp(ntop, ntop2) == 0)) - break; - } - freeaddrinfo(aitop); - /* If we reached the end of the list, the address was not there. */ - if (!ai) { - /* Address not found for the host name. */ - log("Address %.100s maps to %.600s, but this does not map back to the address - POSSIBLE BREAKIN ATTEMPT!", - ntop, name); - strlcpy(name, ntop, sizeof name); - goto check_ip_options; - } - /* Address was found for the host name. We accept the host name. */ - } else { - /* Host name not found. Use ascii representation of the address. */ - strlcpy(name, ntop, sizeof name); - log("Could not reverse map address %.100s.", name); + NULL, 0, NI_NAMEREQD) != 0) { + /* Host name not found. Use ip address. */ + log("Could not reverse map address %.100s.", ntop); + return xstrdup(ntop); } -check_ip_options: + /* Got host name. */ + name[sizeof(name) - 1] = '\0'; + /* + * Convert it to all lowercase (which is expected by the rest + * of this software). + */ + for (i = 0; name[i]; i++) + if (isupper(name[i])) + name[i] = tolower(name[i]); + if (!reverse_mapping_check) + return xstrdup(name); /* - * If IP options are supported, make sure there are none (log and - * disconnect them if any are found). Basically we are worried about - * source routing; it can be used to pretend you are somebody - * (ip-address) you are not. That itself may be "almost acceptable" - * under certain circumstances, but rhosts autentication is useless - * if source routing is accepted. Notice also that if we just dropped - * source routing here, the other side could use IP spoofing to do - * rest of the interaction and could still bypass security. So we - * exit here if we detect any IP options. + * Map it back to an IP address and check that the given + * address actually is an address of this host. This is + * necessary because anyone with access to a name server can + * define arbitrary names for an IP address. Mapping from + * name to IP address can be trusted better (but can still be + * fooled if the intruder has access to the name server of + * the domain). */ - /* IP options -- IPv4 only */ - if (from.ss_family == AF_INET) { - u_char options[200], *ucp; - char text[1024], *cp; - socklen_t option_size; - int ipproto; - struct protoent *ip; - - if ((ip = getprotobyname("ip")) != NULL) - ipproto = ip->p_proto; - else - ipproto = IPPROTO_IP; - option_size = sizeof(options); - if (getsockopt(socket, ipproto, IP_OPTIONS, (char *) options, - &option_size) >= 0 && option_size != 0) { - cp = text; - /* Note: "text" buffer must be at least 3x as big as options. */ - for (ucp = options; option_size > 0; ucp++, option_size--, cp += 3) - sprintf(cp, " %2.2x", *ucp); - log("Connection from %.100s with IP options:%.800s", - ntop, text); - packet_disconnect("Connection from %.100s with IP options:%.800s", - ntop, text); - } + memset(&hints, 0, sizeof(hints)); + hints.ai_family = from.ss_family; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { + log("reverse mapping checking getaddrinfo for %.700s " + "failed - POSSIBLE BREAKIN ATTEMPT!", name); + return xstrdup(ntop); + } + /* Look for the address from the list of addresses. */ + for (ai = aitop; ai; ai = ai->ai_next) { + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, + sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && + (strcmp(ntop, ntop2) == 0)) + break; + } + freeaddrinfo(aitop); + /* If we reached the end of the list, the address was not there. */ + if (!ai) { + /* Address not found for the host name. */ + log("Address %.100s maps to %.600s, but this does not " + "map back to the address - POSSIBLE BREAKIN ATTEMPT!", + ntop, name); + return xstrdup(ntop); } - return xstrdup(name); } /* + * If IP options are supported, make sure there are none (log and + * disconnect them if any are found). Basically we are worried about + * source routing; it can be used to pretend you are somebody + * (ip-address) you are not. That itself may be "almost acceptable" + * under certain circumstances, but rhosts autentication is useless + * if source routing is accepted. Notice also that if we just dropped + * source routing here, the other side could use IP spoofing to do + * rest of the interaction and could still bypass security. So we + * exit here if we detect any IP options. + */ +/* IPv4 only */ +void +check_ip_options(int socket, char *ipaddr) +{ + u_char options[200], *ucp; + char text[1024], *cp; + socklen_t option_size; + int ipproto; + struct protoent *ip; + + if ((ip = getprotobyname("ip")) != NULL) + ipproto = ip->p_proto; + else + ipproto = IPPROTO_IP; + option_size = sizeof(options); + if (getsockopt(socket, ipproto, IP_OPTIONS, (void *)options, + &option_size) >= 0 && option_size != 0) { + cp = text; + /* Note: "text" buffer must be at least 3x as big as options. */ + for (ucp = options; option_size > 0; ucp++, option_size--, cp += 3) + sprintf(cp, " %2.2x", *ucp); + log("Connection from %.100s with IP options:%.800s", + ipaddr, text); + packet_disconnect("Connection from %.100s with IP options:%.800s", + ipaddr, text); + } +} + +/* * Return the canonical name of the host in the other side of the current * connection. The host name is cached, so it is efficient to call this * several times. */ const char * -get_canonical_hostname() +get_canonical_hostname(int reverse_mapping_check) { static char *canonical_host_name = NULL; + static int reverse_mapping_checked = 0; - /* Check if we have previously retrieved this same name. */ - if (canonical_host_name != NULL) - return canonical_host_name; + /* Check if we have previously retrieved name with same option. */ + if (canonical_host_name != NULL) { + if (reverse_mapping_checked != reverse_mapping_check) + xfree(canonical_host_name); + else + return canonical_host_name; + } /* Get the real hostname if socket; otherwise return UNKNOWN. */ if (packet_connection_is_on_socket()) - canonical_host_name = get_remote_hostname(packet_get_connection_in()); + canonical_host_name = get_remote_hostname( + packet_get_connection_in(), reverse_mapping_check); else canonical_host_name = xstrdup("UNKNOWN"); + reverse_mapping_checked = reverse_mapping_check; return canonical_host_name; } diff --git a/usr.bin/ssh/canohost.h b/usr.bin/ssh/canohost.h index 982ec594965..da60b3af9f0 100644 --- a/usr.bin/ssh/canohost.h +++ b/usr.bin/ssh/canohost.h @@ -1,4 +1,4 @@ -/* $OpenBSD: canohost.h,v 1.3 2001/01/29 19:42:35 markus Exp $ */ +/* $OpenBSD: canohost.h,v 1.4 2001/02/03 10:08:37 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -11,22 +11,17 @@ * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". */ -/* - * Returns the name of the machine at the other end of the socket. The - * returned string should be freed by the caller. - */ -char *get_remote_hostname(int socket); /* * Return the canonical name of the host in the other side of the current * connection (as returned by packet_get_connection). The host name is * cached, so it is efficient to call this several times. */ -const char *get_canonical_hostname(void); +const char *get_canonical_hostname(int reverse_mapping_check); /* * Returns the IP-address of the remote host as a string. The returned - * string must not be freed. + * string is cached and must not be freed. */ const char *get_remote_ipaddr(void); diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c index 9f292b6a549..5fa41e028e9 100644 --- a/usr.bin/ssh/servconf.c +++ b/usr.bin/ssh/servconf.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.63 2001/01/22 23:06:39 markus Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.64 2001/02/03 10:08:37 markus Exp $"); #ifdef KRB4 #include <krb.h> @@ -92,6 +92,7 @@ initialize_server_options(ServerOptions *options) options->max_startups_rate = -1; options->max_startups = -1; options->banner = NULL; + options->reverse_mapping_check = -1; } void @@ -186,6 +187,8 @@ fill_default_server_options(ServerOptions *options) options->max_startups_rate = 100; /* 100% */ if (options->max_startups_begin == -1) options->max_startups_begin = options->max_startups; + if (options->reverse_mapping_check == -1) + options->reverse_mapping_check = 0; } /* Keyword tokens. */ @@ -208,7 +211,7 @@ typedef enum { sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, - sBanner + sBanner, sReverseMappingCheck } ServerOpCodes; /* Textual representation of the tokens. */ @@ -268,6 +271,7 @@ static struct { { "subsystem", sSubsystem }, { "maxstartups", sMaxStartups }, { "banner", sBanner }, + { "reversemappingcheck", sReverseMappingCheck }, { NULL, 0 } }; @@ -577,6 +581,10 @@ parse_flag: intptr = &options->gateway_ports; goto parse_flag; + case sReverseMappingCheck: + intptr = &options->reverse_mapping_check; + goto parse_flag; + case sLogFacility: intptr = (int *) &options->log_facility; arg = strdelim(&cp); diff --git a/usr.bin/ssh/servconf.h b/usr.bin/ssh/servconf.h index e31636701fb..e7abb94d8ea 100644 --- a/usr.bin/ssh/servconf.h +++ b/usr.bin/ssh/servconf.h @@ -11,7 +11,7 @@ * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$OpenBSD: servconf.h,v 1.35 2001/01/22 23:06:40 markus Exp $"); */ +/* RCSID("$OpenBSD: servconf.h,v 1.36 2001/02/03 10:08:37 markus Exp $"); */ #ifndef SERVCONF_H #define SERVCONF_H @@ -102,6 +102,7 @@ typedef struct { int max_startups_rate; int max_startups; char *banner; /* SSH-2 banner message */ + int reverse_mapping_check; /* cross-check ip and dns */ } ServerOptions; /* diff --git a/usr.bin/ssh/session.c b/usr.bin/ssh/session.c index 7a5e867b965..a32b151a1ba 100644 --- a/usr.bin/ssh/session.c +++ b/usr.bin/ssh/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.51 2001/01/21 19:05:56 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.52 2001/02/03 10:08:37 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -621,7 +621,7 @@ get_remote_name_or_ip(void) { static const char *remote = ""; if (utmp_len > 0) - remote = get_canonical_hostname(); + remote = get_canonical_hostname(options.reverse_mapping_check); if (utmp_len == 0 || strlen(remote) > utmp_len) remote = get_remote_ipaddr(); return remote; diff --git a/usr.bin/ssh/sshconnect1.c b/usr.bin/ssh/sshconnect1.c index e732806f3ff..80b769b47de 100644 --- a/usr.bin/ssh/sshconnect1.c +++ b/usr.bin/ssh/sshconnect1.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.21 2001/01/29 19:47:31 markus Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.22 2001/02/03 10:08:37 markus Exp $"); #include <openssl/bn.h> #include <openssl/evp.h> @@ -399,11 +399,11 @@ try_kerberos_authentication() if (stat(tkt_string(), &st) < 0) return 0; - strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ); + strncpy(inst, (char *) krb_get_phost(get_canonical_hostname(1)), INST_SZ); - realm = (char *) krb_realmofhost(get_canonical_hostname()); + realm = (char *) krb_realmofhost(get_canonical_hostname(1)); if (!realm) { - debug("Kerberos V4: no realm for %s", get_canonical_hostname()); + debug("Kerberos V4: no realm for %s", get_canonical_hostname(1)); return 0; } /* This can really be anything. */ diff --git a/usr.bin/ssh/sshd.8 b/usr.bin/ssh/sshd.8 index 1aad0fc8868..8fca24042d9 100644 --- a/usr.bin/ssh/sshd.8 +++ b/usr.bin/ssh/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.86 2001/01/28 20:43:25 stevesk Exp $ +.\" $OpenBSD: sshd.8,v 1.87 2001/02/03 10:08:37 markus Exp $ .Dd September 25, 1999 .Dt SSHD 8 .Os @@ -593,6 +593,14 @@ The default is .It Cm RandomSeed Obsolete. Random number generation uses other techniques. +.It Cm ReverseMappingCheck +Specifies whether +.Nm +should try to verify the remote host name and check that +the resolved host name for the remote IP address maps back to the +very same IP address. +The default is +.Dq no . .It Cm RhostsAuthentication Specifies whether authentication using rhosts or /etc/hosts.equiv files is sufficient. diff --git a/usr.bin/ssh/sshd_config b/usr.bin/ssh/sshd_config index c4eec67d76c..80e3ce3d86b 100644 --- a/usr.bin/ssh/sshd_config +++ b/usr.bin/ssh/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.28 2001/02/02 12:57:52 deraadt Exp $ +# $OpenBSD: sshd_config,v 1.29 2001/02/03 10:08:37 markus Exp $ # This is the sshd server system-wide configuration file. See sshd(8) # for more information. @@ -60,3 +60,4 @@ PermitEmptyPasswords no #Subsystem sftp /usr/libexec/sftp-server #MaxStartups 10:30:60 #Banner /etc/issue.net +#ReverseMappingCheck yes |