7087284 proftpd using GSS fails for IPv6
authorTomas Klacko <tomas.klacko@oracle.com>
Mon, 02 Jul 2012 11:16:01 -0700
changeset 902 908943bbfdb9
parent 901 19b502ccabc8
child 903 ebe1b43bc331
7087284 proftpd using GSS fails for IPv6
components/proftpd/Makefile
components/proftpd/mod_gss-patches/ip4-mapped-gss-channel-bindings.patch
components/proftpd/patches/getipnodebyname.patch
--- a/components/proftpd/Makefile	Sat Jun 30 06:30:16 2012 -0700
+++ b/components/proftpd/Makefile	Mon Jul 02 11:16:01 2012 -0700
@@ -81,6 +81,7 @@
 	cd $(BUILD_DIR) ; \
 	$(UNPACK) $(UNPACK_ARGS) ../$(COMPONENT_ARCHIVE_1) ; \
 	cd $(COMPONENT_SRC_1) ; \
+	$(GPATCH) -p1 < ../../mod_gss-patches/*; \
 	./configure CC="$(CC)" CFLAGS="-I/usr/include/kerberosv5" ; \
 	$(CP) mod_gss.c mod_auth_gss.c $(SOURCE_DIR)/contrib ; \
 	$(CP) mod_gss.h $(SOURCE_DIR)/include ; \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/proftpd/mod_gss-patches/ip4-mapped-gss-channel-bindings.patch	Mon Jul 02 11:16:01 2012 -0700
@@ -0,0 +1,128 @@
+--- a/mod_gss.c.in
++++ b/mod_gss.c.in
+@@ -1412,6 +1412,87 @@ MODRET gss_auth(cmd_rec *cmd) {
+     return HANDLED(cmd);
+ }
+ 
++#ifdef USE_IPV6 /* { */
++#define IPV6_STR_SIZE   128
++
++static int ip6_to_str(struct in6_addr* addr, char* buf, int size) {
++
++    const char *err;
++
++    if(size<IPV6_STR_SIZE)
++        return 0;
++
++    memset(buf, 0, size);
++    err=inet_ntop(AF_INET6, addr, buf, size-1);
++    if(err!=buf)
++        return 0;
++
++    return 1;
++}
++
++static int ip6_to_ip4(struct in6_addr *ip6, struct in_addr *ip4) {
++
++    char buf[IPV6_STR_SIZE];
++
++    if (!ip6_to_str(ip6, buf, IPV6_STR_SIZE))
++        return 0;
++
++    const char *ip4_str=strrchr(buf, ':');
++    if (ip4_str == 0)
++        return 0;
++
++    ip4_str++;
++    if (!inet_aton(ip4_str, ip4))
++        return 0;
++
++    return 1;
++}
++
++static int set_chan_v4mapped(
++    gss_channel_bindings_t chan, struct in_addr *ia, struct in_addr *aa) {
++
++    if (!ip6_to_ip4(&(session.c->remote_addr->na_addr.v6.sin6_addr), ia))
++        return 0;
++
++    if (!ip6_to_ip4(&(session.c->local_addr->na_addr.v6.sin6_addr), aa))
++        return 0;
++
++    chan->initiator_addrtype = GSS_C_AF_INET;
++    chan->initiator_address.length = sizeof(struct in_addr);
++    chan->initiator_address.value = ia;
++
++    chan->acceptor_addrtype = GSS_C_AF_INET;
++    chan->acceptor_address.length = sizeof(struct in_addr);
++    chan->acceptor_address.value = aa;
++
++    chan->application_data.length = 0;
++    chan->application_data.value = 0;
++
++    return 1;
++}
++
++static int try_v4mapped() {
++
++    struct in6_addr* addr;
++
++    if (pr_netaddr_get_family(session.c->remote_addr) != AF_INET6)
++        return 0;
++
++    if (pr_netaddr_get_family(session.c->local_addr) != AF_INET6)
++        return 0;
++
++    addr = (struct in6_addr*)pr_netaddr_get_inaddr(session.c->remote_addr);
++    if (!IN6_IS_ADDR_V4MAPPED(addr))
++        return 0;
++
++    addr = (struct in6_addr*)pr_netaddr_get_inaddr(session.c->local_addr);
++    if (!IN6_IS_ADDR_V4MAPPED(addr))
++        return 0;
++
++    return 1;
++}
++#endif /* } */
++
+ /*
+    AUTHENTICATION/SECURITY DATA (ADAT)
+ 
+@@ -1527,6 +1608,12 @@ MODRET gss_adat(cmd_rec *cmd) {
+     char *gbuf ;
+   
+     gss_channel_bindings_t chan=GSS_C_NO_CHANNEL_BINDINGS;
++    gss_channel_bindings_t chan_sl=GSS_C_NO_CHANNEL_BINDINGS;
++#ifdef USE_IPV6
++    gss_channel_bindings_t chan_v4m=GSS_C_NO_CHANNEL_BINDINGS;
++    struct in_addr ia;
++    struct in_addr aa;
++#endif
+ 
+     if (!gss_engine)
+         return DECLINED(cmd);
+@@ -1631,13 +1718,22 @@ MODRET gss_adat(cmd_rec *cmd) {
+ 	    continue;
+ 	}
+ 
++        chan_sl = chan;
++#ifdef USE_IPV6
++        if (try_v4mapped()) {
++            chan_v4m = pcalloc(cmd->tmp_pool,sizeof(*chan_v4m));
++            if (set_chan_v4mapped(chan_v4m, &ia, &aa))
++                chan_sl = chan_v4m;
++        }
++#endif
++
+ 	found++;
+ 	gcontext = GSS_C_NO_CONTEXT;
+ 	accept_maj = gss_accept_sec_context(&accept_min,
+ 	   				    &gcontext, /* context_handle */
+ 					    server_creds, /* verifier_cred_handle */
+ 					    &tok, /* input_token */
+-					    chan, /* channel bindings */
++					    chan_sl, /* channel bindings */
+ 					    &client, /* src_name */
+ 					    &mechid, /* mech_type */
+ 					    &out_tok, /* output_token */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/proftpd/patches/getipnodebyname.patch	Mon Jul 02 11:16:01 2012 -0700
@@ -0,0 +1,32 @@
+--- a/src/netaddr.c
++++ b/src/netaddr.c
+@@ -1295,12 +1295,19 @@ const char *pr_netaddr_get_dnsstr(pr_netaddr_t *na) {
+     buf[sizeof(buf)-1] = '\0';
+ 
+     if (res == 0) {
++      int err_num;
++      int flags;
+       char **checkaddr;
+       struct hostent *hent = NULL;
+       unsigned char ok = FALSE;
+       int family = pr_netaddr_get_family(na);
+       void *inaddr = pr_netaddr_get_inaddr(na);
+-    
++
++//#ifdef HAVE_GETIPNODEBYNAME
++#if 1
++      flags=AI_V4MAPPED;
++      hent=getipnodebyname(buf, family, flags, &err_num);
++#else
+ #ifdef HAVE_GETHOSTBYNAME2
+       if (pr_netaddr_is_v4mappedv6(na) == TRUE) {
+         family = AF_INET;
+@@ -1311,6 +1318,7 @@ const char *pr_netaddr_get_dnsstr(pr_netaddr_t *na) {
+ #else
+       hent = gethostbyname(buf);
+ #endif /* HAVE_GETHOSTBYNAME2 */
++#endif /* HAVE_GETIPNODEBYNAME */
+ 
+       if (hent != NULL) {
+ 
+