--- 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) {
+
+