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