summaryrefslogtreecommitdiff
path: root/auth.c
diff options
context:
space:
mode:
authorSimon Wilkinson <simon@sxw.org.uk>2014-02-09 16:09:48 +0000
committerColin Watson <cjwatson@debian.org>2019-06-05 07:06:44 +0100
commit7ce79be85036c4b36937f1b1ba85f6094068412c (patch)
treec964917d8395ef5605cff9513aad4458b222beae /auth.c
parent102062f825fb26a74295a1c089c00c4c4c76b68a (diff)
GSSAPI key exchange support
This patch has been rejected upstream: "None of the OpenSSH developers are in favour of adding this, and this situation has not changed for several years. This is not a slight on Simon's patch, which is of fine quality, but just that a) we don't trust GSSAPI implementations that much and b) we don't like adding new KEX since they are pre-auth attack surface. This one is particularly scary, since it requires hooks out to typically root-owned system resources." However, quite a lot of people rely on this in Debian, and it's better to have it merged into the main openssh package rather than having separate -krb5 packages (as we used to have). It seems to have a generally good security history. Origin: other, https://github.com/openssh-gsskex/openssh-gsskex/commits/debian/master Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 Last-Updated: 2019-06-05 Patch-Name: gssapi.patch
Diffstat (limited to 'auth.c')
-rw-r--r--auth.c96
1 files changed, 2 insertions, 94 deletions
diff --git a/auth.c b/auth.c
index 8696f258e..f7a23afba 100644
--- a/auth.c
+++ b/auth.c
@@ -399,7 +399,8 @@ auth_root_allowed(struct ssh *ssh, const char *method)
399 case PERMIT_NO_PASSWD: 399 case PERMIT_NO_PASSWD:
400 if (strcmp(method, "publickey") == 0 || 400 if (strcmp(method, "publickey") == 0 ||
401 strcmp(method, "hostbased") == 0 || 401 strcmp(method, "hostbased") == 0 ||
402 strcmp(method, "gssapi-with-mic") == 0) 402 strcmp(method, "gssapi-with-mic") == 0 ||
403 strcmp(method, "gssapi-keyex") == 0)
403 return 1; 404 return 1;
404 break; 405 break;
405 case PERMIT_FORCED_ONLY: 406 case PERMIT_FORCED_ONLY:
@@ -724,99 +725,6 @@ fakepw(void)
724} 725}
725 726
726/* 727/*
727 * Returns the remote DNS hostname as a string. The returned string must not
728 * be freed. NB. this will usually trigger a DNS query the first time it is
729 * called.
730 * This function does additional checks on the hostname to mitigate some
731 * attacks on legacy rhosts-style authentication.
732 * XXX is RhostsRSAAuthentication vulnerable to these?
733 * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?)
734 */
735
736static char *
737remote_hostname(struct ssh *ssh)
738{
739 struct sockaddr_storage from;
740 socklen_t fromlen;
741 struct addrinfo hints, *ai, *aitop;
742 char name[NI_MAXHOST], ntop2[NI_MAXHOST];
743 const char *ntop = ssh_remote_ipaddr(ssh);
744
745 /* Get IP address of client. */
746 fromlen = sizeof(from);
747 memset(&from, 0, sizeof(from));
748 if (getpeername(ssh_packet_get_connection_in(ssh),
749 (struct sockaddr *)&from, &fromlen) < 0) {
750 debug("getpeername failed: %.100s", strerror(errno));
751 return strdup(ntop);
752 }
753
754 ipv64_normalise_mapped(&from, &fromlen);
755 if (from.ss_family == AF_INET6)
756 fromlen = sizeof(struct sockaddr_in6);
757
758 debug3("Trying to reverse map address %.100s.", ntop);
759 /* Map the IP address to a host name. */
760 if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
761 NULL, 0, NI_NAMEREQD) != 0) {
762 /* Host name not found. Use ip address. */
763 return strdup(ntop);
764 }
765
766 /*
767 * if reverse lookup result looks like a numeric hostname,
768 * someone is trying to trick us by PTR record like following:
769 * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
770 */
771 memset(&hints, 0, sizeof(hints));
772 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
773 hints.ai_flags = AI_NUMERICHOST;
774 if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
775 logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
776 name, ntop);
777 freeaddrinfo(ai);
778 return strdup(ntop);
779 }
780
781 /* Names are stored in lowercase. */
782 lowercase(name);
783
784 /*
785 * Map it back to an IP address and check that the given
786 * address actually is an address of this host. This is
787 * necessary because anyone with access to a name server can
788 * define arbitrary names for an IP address. Mapping from
789 * name to IP address can be trusted better (but can still be
790 * fooled if the intruder has access to the name server of
791 * the domain).
792 */
793 memset(&hints, 0, sizeof(hints));
794 hints.ai_family = from.ss_family;
795 hints.ai_socktype = SOCK_STREAM;
796 if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
797 logit("reverse mapping checking getaddrinfo for %.700s "
798 "[%s] failed.", name, ntop);
799 return strdup(ntop);
800 }
801 /* Look for the address from the list of addresses. */
802 for (ai = aitop; ai; ai = ai->ai_next) {
803 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
804 sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
805 (strcmp(ntop, ntop2) == 0))
806 break;
807 }
808 freeaddrinfo(aitop);
809 /* If we reached the end of the list, the address was not there. */
810 if (ai == NULL) {
811 /* Address not found for the host name. */
812 logit("Address %.100s maps to %.600s, but this does not "
813 "map back to the address.", ntop, name);
814 return strdup(ntop);
815 }
816 return strdup(name);
817}
818
819/*
820 * Return the canonical name of the host in the other side of the current 728 * Return the canonical name of the host in the other side of the current
821 * connection. The host name is cached, so it is efficient to call this 729 * connection. The host name is cached, so it is efficient to call this
822 * several times. 730 * several times.