Move old canohost.h API to shared place, so it can be used by audit and gssapi (states)

This commit is contained in:
Jakub Jelen 2016-07-26 10:54:13 +02:00
parent 5878ebb50e
commit b487a6d746
4 changed files with 490 additions and 228 deletions

View File

@ -12,7 +12,7 @@ diff -up openssh-6.1p1/sshconnect2.c.canohost openssh-6.1p1/sshconnect2.c
gss_host = options.gss_server_identity;
- else if (options.gss_trust_dns)
+ else if (options.gss_trust_dns) {
gss_host = get_canonical_hostname(1);
gss_host = get_canonical_hostname(active_state, 1);
+ if ( strcmp( gss_host, "UNKNOWN" ) == 0 )
+ gss_host = authctxt->host;
+ }

File diff suppressed because it is too large Load Diff

View File

@ -495,7 +495,7 @@ diff -up openssh-7.2p1/sshconnect2.c.fips openssh-7.2p1/sshconnect2.c
- orig = options.kex_algorithms;
-
- if (options.gss_trust_dns)
- gss_host = (char *)get_canonical_hostname(1);
- gss_host = (char *)get_canonical_hostname(active_state, 1);
- else
- gss_host = host;
-
@ -514,7 +514,7 @@ diff -up openssh-7.2p1/sshconnect2.c.fips openssh-7.2p1/sshconnect2.c
+ orig = options.kex_algorithms;
+
+ if (options.gss_trust_dns)
+ gss_host = (char *)get_canonical_hostname(1);
+ gss_host = (char *)get_canonical_hostname(active_state, 1);
+ else
+ gss_host = host;
+

View File

@ -1251,7 +1251,7 @@ diff -up openssh-7.2p1/kexgssc.c.gsskex openssh-7.2p1/kexgssc.c
+ switch (ssh->kex->kex_type) {
+ case KEX_GSS_GRP1_SHA1:
+ case KEX_GSS_GRP14_SHA1:
+ kex_dh_hash( ssh->kex->client_version_string,
+ kex_dh_hash(ssh->kex->hash_alg, ssh->kex->client_version_string,
+ ssh->kex->server_version_string,
+ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my),
+ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer),
@ -1320,7 +1320,7 @@ diff -up openssh-7.2p1/kexgssc.c.gsskex openssh-7.2p1/kexgssc.c
diff -up openssh-7.2p1/kexgsss.c.gsskex openssh-7.2p1/kexgsss.c
--- openssh-7.2p1/kexgsss.c.gsskex 2016-02-19 10:01:04.868969323 +0100
+++ openssh-7.2p1/kexgsss.c 2016-02-19 10:01:04.868969323 +0100
@@ -0,0 +1,295 @@
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
+ *
@ -1543,7 +1543,7 @@ diff -up openssh-7.2p1/kexgsss.c.gsskex openssh-7.2p1/kexgsss.c
+ switch (ssh->kex->kex_type) {
+ case KEX_GSS_GRP1_SHA1:
+ case KEX_GSS_GRP14_SHA1:
+ kex_dh_hash(
+ kex_dh_hash(ssh->kex->hash_alg,
+ ssh->kex->client_version_string, ssh->kex->server_version_string,
+ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer),
+ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my),
@ -2306,7 +2306,7 @@ diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c
+ orig = options.kex_algorithms;
+
+ if (options.gss_trust_dns)
+ gss_host = (char *)get_canonical_hostname(1);
+ gss_host = (char *)get_canonical_hostname(active_state, 1);
+ else
+ gss_host = host;
+
@ -2401,7 +2401,7 @@ diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c
+ if (options.gss_server_identity)
+ gss_host = options.gss_server_identity;
+ else if (options.gss_trust_dns)
+ gss_host = get_canonical_hostname(1);
+ gss_host = get_canonical_hostname(active_state, 1);
+ else
+ gss_host = authctxt->host;
@ -2741,3 +2741,264 @@ diff -up openssh-7.2p1/sshkey.h.gsskex openssh-7.2p1/sshkey.h
KEY_UNSPEC
};
diff --git a/auth.c b/auth.c
index e0f7639..a5a346e 100644
--- a/auth.c
+++ b/auth.c
@@ -784,99 +784,6 @@ fakepw(void)
}
/*
- * 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.", 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.", 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.
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index 80729b3..93a1b04 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -32,6 +32,8 @@
#include "log.h"
#include "xmalloc.h"
#include "port-linux.h"
+#include "canohost.h"
+#include "misc.h"
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
@@ -286,4 +288,121 @@ oom_adjust_restore(void)
return;
}
#endif /* LINUX_OOM_ADJUST */
+
+/**************** XXX moved from auth.c ****************/
+
+/*
+ * 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?)
+ */
+
+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 *
+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;
+ }
+}
#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index e2ca8a1..6c5ac3f 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -18,6 +18,7 @@
#ifndef _PORT_LINUX_H
#define _PORT_LINUX_H
+#include "packet.h"
#ifdef WITH_SELINUX
int ssh_selinux_enabled(void);
@@ -39,4 +40,8 @@ void oom_adjust_setup(void);
void linux_seed(void);
+const char *get_canonical_hostname(struct ssh *, int);
+char *remote_hostname(struct ssh *);
+
+
#endif /* ! _PORT_LINUX_H */