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>2018-08-24 17:49:04 +0100
commite6c7c11ac2576ac62334616bd4408bf64140bba7 (patch)
tree0625a34b2eafa6425602cb8c7185fbddc2d05fd7 /auth.c
parente6547182a54f0f268ee36e7c99319eeddffbaff2 (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. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 Last-Updated: 2018-08-24 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 9a3bc96f1..80eb78c48 100644
--- a/auth.c
+++ b/auth.c
@@ -395,7 +395,8 @@ auth_root_allowed(struct ssh *ssh, const char *method)
395 case PERMIT_NO_PASSWD: 395 case PERMIT_NO_PASSWD:
396 if (strcmp(method, "publickey") == 0 || 396 if (strcmp(method, "publickey") == 0 ||
397 strcmp(method, "hostbased") == 0 || 397 strcmp(method, "hostbased") == 0 ||
398 strcmp(method, "gssapi-with-mic") == 0) 398 strcmp(method, "gssapi-with-mic") == 0 ||
399 strcmp(method, "gssapi-keyex") == 0)
399 return 1; 400 return 1;
400 break; 401 break;
401 case PERMIT_FORCED_ONLY: 402 case PERMIT_FORCED_ONLY:
@@ -734,99 +735,6 @@ fakepw(void)
734} 735}
735 736
736/* 737/*
737 * Returns the remote DNS hostname as a string. The returned string must not
738 * be freed. NB. this will usually trigger a DNS query the first time it is
739 * called.
740 * This function does additional checks on the hostname to mitigate some
741 * attacks on legacy rhosts-style authentication.
742 * XXX is RhostsRSAAuthentication vulnerable to these?
743 * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?)
744 */
745
746static char *
747remote_hostname(struct ssh *ssh)
748{
749 struct sockaddr_storage from;
750 socklen_t fromlen;
751 struct addrinfo hints, *ai, *aitop;
752 char name[NI_MAXHOST], ntop2[NI_MAXHOST];
753 const char *ntop = ssh_remote_ipaddr(ssh);
754
755 /* Get IP address of client. */
756 fromlen = sizeof(from);
757 memset(&from, 0, sizeof(from));
758 if (getpeername(ssh_packet_get_connection_in(ssh),
759 (struct sockaddr *)&from, &fromlen) < 0) {
760 debug("getpeername failed: %.100s", strerror(errno));
761 return strdup(ntop);
762 }
763
764 ipv64_normalise_mapped(&from, &fromlen);
765 if (from.ss_family == AF_INET6)
766 fromlen = sizeof(struct sockaddr_in6);
767
768 debug3("Trying to reverse map address %.100s.", ntop);
769 /* Map the IP address to a host name. */
770 if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
771 NULL, 0, NI_NAMEREQD) != 0) {
772 /* Host name not found. Use ip address. */
773 return strdup(ntop);
774 }
775
776 /*
777 * if reverse lookup result looks like a numeric hostname,
778 * someone is trying to trick us by PTR record like following:
779 * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
780 */
781 memset(&hints, 0, sizeof(hints));
782 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
783 hints.ai_flags = AI_NUMERICHOST;
784 if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
785 logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
786 name, ntop);
787 freeaddrinfo(ai);
788 return strdup(ntop);
789 }
790
791 /* Names are stored in lowercase. */
792 lowercase(name);
793
794 /*
795 * Map it back to an IP address and check that the given
796 * address actually is an address of this host. This is
797 * necessary because anyone with access to a name server can
798 * define arbitrary names for an IP address. Mapping from
799 * name to IP address can be trusted better (but can still be
800 * fooled if the intruder has access to the name server of
801 * the domain).
802 */
803 memset(&hints, 0, sizeof(hints));
804 hints.ai_family = from.ss_family;
805 hints.ai_socktype = SOCK_STREAM;
806 if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
807 logit("reverse mapping checking getaddrinfo for %.700s "
808 "[%s] failed.", name, ntop);
809 return strdup(ntop);
810 }
811 /* Look for the address from the list of addresses. */
812 for (ai = aitop; ai; ai = ai->ai_next) {
813 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
814 sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
815 (strcmp(ntop, ntop2) == 0))
816 break;
817 }
818 freeaddrinfo(aitop);
819 /* If we reached the end of the list, the address was not there. */
820 if (ai == NULL) {
821 /* Address not found for the host name. */
822 logit("Address %.100s maps to %.600s, but this does not "
823 "map back to the address.", ntop, name);
824 return strdup(ntop);
825 }
826 return strdup(name);
827}
828
829/*
830 * Return the canonical name of the host in the other side of the current 738 * Return the canonical name of the host in the other side of the current
831 * connection. The host name is cached, so it is efficient to call this 739 * connection. The host name is cached, so it is efficient to call this
832 * several times. 740 * several times.