Skip to content

Commit

Permalink
upstream commit
Browse files Browse the repository at this point in the history
refactor canohost.c: move functions that cache results closer
 to the places that use them (authn and session code). After this, no state is
 cached in canohost.c

feedback and ok markus@

Upstream-ID: 5f2e4df88d4803fc8ec59ec53629105e23ce625e
  • Loading branch information
djmdjm committed Mar 7, 2016
1 parent af0bb38 commit 9576726
Show file tree
Hide file tree
Showing 21 changed files with 372 additions and 373 deletions.
13 changes: 8 additions & 5 deletions auth-options.c
@@ -1,4 +1,4 @@
/* $OpenBSD: auth-options.c,v 1.70 2015/12/10 17:08:40 mmcc Exp $ */
/* $OpenBSD: auth-options.c,v 1.71 2016/03/07 19:02:43 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
Expand Down Expand Up @@ -29,6 +29,7 @@
#include "ssherr.h"
#include "log.h"
#include "canohost.h"
#include "packet.h"
#include "sshbuf.h"
#include "misc.h"
#include "channels.h"
Expand Down Expand Up @@ -120,6 +121,7 @@ match_flag(const char *opt, int allow_negate, char **optsp, const char *msg)
int
auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
{
struct ssh *ssh = active_state; /* XXX */
const char *cp;
int i, r;

Expand Down Expand Up @@ -273,9 +275,9 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
}
cp = "from=\"";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
const char *remote_ip = get_remote_ipaddr();
const char *remote_host = get_canonical_hostname(
options.use_dns);
const char *remote_ip = ssh_remote_ipaddr(ssh);
const char *remote_host = auth_get_canonical_hostname(
ssh, options.use_dns);
char *patterns = xmalloc(strlen(opts) + 1);

opts += strlen(cp);
Expand Down Expand Up @@ -457,6 +459,7 @@ parse_option_list(struct sshbuf *oblob, struct passwd *pw,
char **cert_forced_command,
int *cert_source_address_done)
{
struct ssh *ssh = active_state; /* XXX */
char *command, *allowed;
const char *remote_ip;
char *name = NULL;
Expand Down Expand Up @@ -530,7 +533,7 @@ parse_option_list(struct sshbuf *oblob, struct passwd *pw,
free(allowed);
goto out;
}
remote_ip = get_remote_ipaddr();
remote_ip = ssh_remote_ipaddr(ssh);
result = addr_match_cidr_list(remote_ip,
allowed);
free(allowed);
Expand Down
11 changes: 6 additions & 5 deletions auth-rh-rsa.c
@@ -1,4 +1,4 @@
/* $OpenBSD: auth-rh-rsa.c,v 1.44 2014/07/15 15:54:14 millert Exp $ */
/* $OpenBSD: auth-rh-rsa.c,v 1.45 2016/03/07 19:02:43 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
Expand Down Expand Up @@ -42,8 +42,8 @@
extern ServerOptions options;

int
auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
Key *client_host_key)
auth_rhosts_rsa_key_allowed(struct passwd *pw, const char *cuser,
const char *chost, Key *client_host_key)
{
HostStatus host_status;

Expand All @@ -68,7 +68,8 @@ auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
int
auth_rhosts_rsa(Authctxt *authctxt, char *cuser, Key *client_host_key)
{
char *chost;
struct ssh *ssh = active_state; /* XXX */
const char *chost;
struct passwd *pw = authctxt->pw;

debug("Trying rhosts with RSA host authentication for client user %.100s",
Expand All @@ -78,7 +79,7 @@ auth_rhosts_rsa(Authctxt *authctxt, char *cuser, Key *client_host_key)
client_host_key->rsa == NULL)
return 0;

chost = (char *)get_canonical_hostname(options.use_dns);
chost = auth_get_canonical_hostname(ssh, options.use_dns);
debug("Rhosts RSA authentication: canonical host %.900s", chost);

if (!PRIVSEP(auth_rhosts_rsa_key_allowed(pw, cuser, chost, client_host_key))) {
Expand Down
12 changes: 7 additions & 5 deletions auth-rhosts.c
@@ -1,4 +1,4 @@
/* $OpenBSD: auth-rhosts.c,v 1.46 2014/12/23 22:42:48 djm Exp $ */
/* $OpenBSD: auth-rhosts.c,v 1.47 2016/03/07 19:02:43 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
Expand Down Expand Up @@ -30,14 +30,15 @@
#include <unistd.h>

#include "packet.h"
#include "buffer.h"
#include "uidswap.h"
#include "pathnames.h"
#include "log.h"
#include "misc.h"
#include "buffer.h" /* XXX */
#include "key.h" /* XXX */
#include "servconf.h"
#include "canohost.h"
#include "key.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"

Expand Down Expand Up @@ -189,10 +190,11 @@ check_rhosts_file(const char *filename, const char *hostname,
int
auth_rhosts(struct passwd *pw, const char *client_user)
{
struct ssh *ssh = active_state; /* XXX */
const char *hostname, *ipaddr;

hostname = get_canonical_hostname(options.use_dns);
ipaddr = get_remote_ipaddr();
hostname = auth_get_canonical_hostname(ssh, options.use_dns);
ipaddr = ssh_remote_ipaddr(ssh);
return auth_rhosts2(pw, client_user, hostname, ipaddr);
}

Expand Down
145 changes: 135 additions & 10 deletions auth.c
@@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.113 2015/08/21 03:42:19 djm Exp $ */
/* $OpenBSD: auth.c,v 1.114 2016/03/07 19:02:43 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
Expand Down Expand Up @@ -27,6 +27,7 @@

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>

#include <netinet/in.h>

Expand All @@ -50,6 +51,7 @@
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <netdb.h>

#include "xmalloc.h"
#include "match.h"
Expand Down Expand Up @@ -97,6 +99,7 @@ int auth_debug_init;
int
allowed_user(struct passwd * pw)
{
struct ssh *ssh = active_state; /* XXX */
struct stat st;
const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
u_int i;
Expand Down Expand Up @@ -182,8 +185,8 @@ allowed_user(struct passwd * pw)

if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
options.num_deny_groups > 0 || options.num_allow_groups > 0) {
hostname = get_canonical_hostname(options.use_dns);
ipaddr = get_remote_ipaddr();
hostname = auth_get_canonical_hostname(ssh, options.use_dns);
ipaddr = ssh_remote_ipaddr(ssh);
}

/* Return false if user is listed in DenyUsers */
Expand Down Expand Up @@ -274,6 +277,7 @@ void
auth_log(Authctxt *authctxt, int authenticated, int partial,
const char *method, const char *submethod)
{
struct ssh *ssh = active_state; /* XXX */
void (*authlog) (const char *fmt,...) = verbose;
char *authmsg;

Expand All @@ -300,8 +304,8 @@ auth_log(Authctxt *authctxt, int authenticated, int partial,
submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
authctxt->valid ? "" : "invalid user ",
authctxt->user,
get_remote_ipaddr(),
get_remote_port(),
ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh),
compat20 ? "ssh2" : "ssh1",
authctxt->info != NULL ? ": " : "",
authctxt->info != NULL ? authctxt->info : "");
Expand Down Expand Up @@ -331,12 +335,14 @@ auth_log(Authctxt *authctxt, int authenticated, int partial,
void
auth_maxtries_exceeded(Authctxt *authctxt)
{
struct ssh *ssh = active_state; /* XXX */

error("maximum authentication attempts exceeded for "
"%s%.100s from %.200s port %d %s",
authctxt->valid ? "" : "invalid user ",
authctxt->user,
get_remote_ipaddr(),
get_remote_port(),
ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh),
compat20 ? "ssh2" : "ssh1");
packet_disconnect("Too many authentication failures");
/* NOTREACHED */
Expand All @@ -348,6 +354,8 @@ auth_maxtries_exceeded(Authctxt *authctxt)
int
auth_root_allowed(const char *method)
{
struct ssh *ssh = active_state; /* XXX */

switch (options.permit_root_login) {
case PERMIT_YES:
return 1;
Expand All @@ -364,7 +372,8 @@ auth_root_allowed(const char *method)
}
break;
}
logit("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr());
logit("ROOT LOGIN REFUSED FROM %.200s port %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
return 0;
}

Expand Down Expand Up @@ -604,6 +613,7 @@ auth_openprincipals(const char *file, struct passwd *pw, int strict_modes)
struct passwd *
getpwnamallow(const char *user)
{
struct ssh *ssh = active_state; /* XXX */
#ifdef HAVE_LOGIN_CAP
extern login_cap_t *lc;
#ifdef BSD_AUTH
Expand Down Expand Up @@ -639,8 +649,8 @@ getpwnamallow(const char *user)
}
#endif
if (pw == NULL) {
logit("Invalid user %.100s from %.100s",
user, get_remote_ipaddr());
logit("Invalid user %.100s from %.100s port %d",
user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
#ifdef CUSTOM_FAILED_LOGIN
record_failed_login(user,
get_canonical_hostname(options.use_dns), "ssh");
Expand Down Expand Up @@ -773,3 +783,118 @@ fakepw(void)

return (&fake);
}

/*
* Returns the remote DNS hostname as a string. The returned string must not
* be freed. NB. this will usually trigger a DNS query the first time it is
* called.
* This function does additional checks on the hostname to mitigate some
* attacks on legacy rhosts-style authentication.
* XXX is RhostsRSAAuthentication vulnerable to these?
* XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?)
*/

static char *
remote_hostname(struct ssh *ssh)
{
struct sockaddr_storage from;
socklen_t fromlen;
struct addrinfo hints, *ai, *aitop;
char name[NI_MAXHOST], ntop2[NI_MAXHOST];
const char *ntop = ssh_remote_ipaddr(ssh);

/* Get IP address of client. */
fromlen = sizeof(from);
memset(&from, 0, sizeof(from));
if (getpeername(ssh_packet_get_connection_in(ssh),
(struct sockaddr *)&from, &fromlen) < 0) {
debug("getpeername failed: %.100s", strerror(errno));
return strdup(ntop);
}

ipv64_normalise_mapped(&from, &fromlen);
if (from.ss_family == AF_INET6)
fromlen = sizeof(struct sockaddr_in6);

debug3("Trying to reverse map address %.100s.", ntop);
/* Map the IP address to a host name. */
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
NULL, 0, NI_NAMEREQD) != 0) {
/* Host name not found. Use ip address. */
return strdup(ntop);
}

/*
* if reverse lookup result looks like a numeric hostname,
* someone is trying to trick us by PTR record like following:
* 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
*/
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
name, ntop);
freeaddrinfo(ai);
return strdup(ntop);
}

/* Names are stored in lowercase. */
lowercase(name);

/*
* 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) {
logit("reverse mapping checking getaddrinfo for %.700s "
"[%s] failed - POSSIBLE BREAK-IN ATTEMPT!", name, ntop);
return strdup(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 == NULL) {
/* Address not found for the host name. */
logit("Address %.100s maps to %.600s, but this does not "
"map back to the address - POSSIBLE BREAK-IN ATTEMPT!",
ntop, name);
return strdup(ntop);
}
return strdup(name);
}

/*
* 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 *
auth_get_canonical_hostname(struct ssh *ssh, int use_dns)
{
static char *dnsname;

if (!use_dns)
return ssh_remote_ipaddr(ssh);
else if (dnsname != NULL)
return dnsname;
else {
dnsname = remote_hostname(ssh);
return dnsname;
}
}
4 changes: 3 additions & 1 deletion auth.h
@@ -1,4 +1,4 @@
/* $OpenBSD: auth.h,v 1.86 2015/12/04 16:41:28 markus Exp $ */
/* $OpenBSD: auth.h,v 1.87 2016/03/07 19:02:43 djm Exp $ */

/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
Expand Down Expand Up @@ -197,6 +197,8 @@ FILE *auth_openkeyfile(const char *, struct passwd *, int);
FILE *auth_openprincipals(const char *, struct passwd *, int);
int auth_key_is_revoked(Key *);

const char *auth_get_canonical_hostname(struct ssh *, int);

HostStatus
check_key_in_hostfiles(struct passwd *, Key *, const char *,
const char *, const char *);
Expand Down
7 changes: 4 additions & 3 deletions auth2-hostbased.c
@@ -1,4 +1,4 @@
/* $OpenBSD: auth2-hostbased.c,v 1.25 2015/05/04 06:10:48 djm Exp $ */
/* $OpenBSD: auth2-hostbased.c,v 1.26 2016/03/07 19:02:43 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
Expand Down Expand Up @@ -160,6 +160,7 @@ int
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
Key *key)
{
struct ssh *ssh = active_state; /* XXX */
const char *resolvedname, *ipaddr, *lookup, *reason;
HostStatus host_status;
int len;
Expand All @@ -168,8 +169,8 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
if (auth_key_is_revoked(key))
return 0;

resolvedname = get_canonical_hostname(options.use_dns);
ipaddr = get_remote_ipaddr();
resolvedname = auth_get_canonical_hostname(ssh, options.use_dns);
ipaddr = ssh_remote_ipaddr(ssh);

debug2("%s: chost %s resolvedname %s ipaddr %s", __func__,
chost, resolvedname, ipaddr);
Expand Down

0 comments on commit 9576726

Please sign in to comment.