components/proftpd/mod_gss-patches/ip4-mapped-gss-channel-bindings.patch
changeset 902 908943bbfdb9
equal deleted inserted replaced
901:19b502ccabc8 902:908943bbfdb9
       
     1 --- a/mod_gss.c.in
       
     2 +++ b/mod_gss.c.in
       
     3 @@ -1412,6 +1412,87 @@ MODRET gss_auth(cmd_rec *cmd) {
       
     4      return HANDLED(cmd);
       
     5  }
       
     6  
       
     7 +#ifdef USE_IPV6 /* { */
       
     8 +#define IPV6_STR_SIZE   128
       
     9 +
       
    10 +static int ip6_to_str(struct in6_addr* addr, char* buf, int size) {
       
    11 +
       
    12 +    const char *err;
       
    13 +
       
    14 +    if(size<IPV6_STR_SIZE)
       
    15 +        return 0;
       
    16 +
       
    17 +    memset(buf, 0, size);
       
    18 +    err=inet_ntop(AF_INET6, addr, buf, size-1);
       
    19 +    if(err!=buf)
       
    20 +        return 0;
       
    21 +
       
    22 +    return 1;
       
    23 +}
       
    24 +
       
    25 +static int ip6_to_ip4(struct in6_addr *ip6, struct in_addr *ip4) {
       
    26 +
       
    27 +    char buf[IPV6_STR_SIZE];
       
    28 +
       
    29 +    if (!ip6_to_str(ip6, buf, IPV6_STR_SIZE))
       
    30 +        return 0;
       
    31 +
       
    32 +    const char *ip4_str=strrchr(buf, ':');
       
    33 +    if (ip4_str == 0)
       
    34 +        return 0;
       
    35 +
       
    36 +    ip4_str++;
       
    37 +    if (!inet_aton(ip4_str, ip4))
       
    38 +        return 0;
       
    39 +
       
    40 +    return 1;
       
    41 +}
       
    42 +
       
    43 +static int set_chan_v4mapped(
       
    44 +    gss_channel_bindings_t chan, struct in_addr *ia, struct in_addr *aa) {
       
    45 +
       
    46 +    if (!ip6_to_ip4(&(session.c->remote_addr->na_addr.v6.sin6_addr), ia))
       
    47 +        return 0;
       
    48 +
       
    49 +    if (!ip6_to_ip4(&(session.c->local_addr->na_addr.v6.sin6_addr), aa))
       
    50 +        return 0;
       
    51 +
       
    52 +    chan->initiator_addrtype = GSS_C_AF_INET;
       
    53 +    chan->initiator_address.length = sizeof(struct in_addr);
       
    54 +    chan->initiator_address.value = ia;
       
    55 +
       
    56 +    chan->acceptor_addrtype = GSS_C_AF_INET;
       
    57 +    chan->acceptor_address.length = sizeof(struct in_addr);
       
    58 +    chan->acceptor_address.value = aa;
       
    59 +
       
    60 +    chan->application_data.length = 0;
       
    61 +    chan->application_data.value = 0;
       
    62 +
       
    63 +    return 1;
       
    64 +}
       
    65 +
       
    66 +static int try_v4mapped() {
       
    67 +
       
    68 +    struct in6_addr* addr;
       
    69 +
       
    70 +    if (pr_netaddr_get_family(session.c->remote_addr) != AF_INET6)
       
    71 +        return 0;
       
    72 +
       
    73 +    if (pr_netaddr_get_family(session.c->local_addr) != AF_INET6)
       
    74 +        return 0;
       
    75 +
       
    76 +    addr = (struct in6_addr*)pr_netaddr_get_inaddr(session.c->remote_addr);
       
    77 +    if (!IN6_IS_ADDR_V4MAPPED(addr))
       
    78 +        return 0;
       
    79 +
       
    80 +    addr = (struct in6_addr*)pr_netaddr_get_inaddr(session.c->local_addr);
       
    81 +    if (!IN6_IS_ADDR_V4MAPPED(addr))
       
    82 +        return 0;
       
    83 +
       
    84 +    return 1;
       
    85 +}
       
    86 +#endif /* } */
       
    87 +
       
    88  /*
       
    89     AUTHENTICATION/SECURITY DATA (ADAT)
       
    90  
       
    91 @@ -1527,6 +1608,12 @@ MODRET gss_adat(cmd_rec *cmd) {
       
    92      char *gbuf ;
       
    93    
       
    94      gss_channel_bindings_t chan=GSS_C_NO_CHANNEL_BINDINGS;
       
    95 +    gss_channel_bindings_t chan_sl=GSS_C_NO_CHANNEL_BINDINGS;
       
    96 +#ifdef USE_IPV6
       
    97 +    gss_channel_bindings_t chan_v4m=GSS_C_NO_CHANNEL_BINDINGS;
       
    98 +    struct in_addr ia;
       
    99 +    struct in_addr aa;
       
   100 +#endif
       
   101  
       
   102      if (!gss_engine)
       
   103          return DECLINED(cmd);
       
   104 @@ -1631,13 +1718,22 @@ MODRET gss_adat(cmd_rec *cmd) {
       
   105  	    continue;
       
   106  	}
       
   107  
       
   108 +        chan_sl = chan;
       
   109 +#ifdef USE_IPV6
       
   110 +        if (try_v4mapped()) {
       
   111 +            chan_v4m = pcalloc(cmd->tmp_pool,sizeof(*chan_v4m));
       
   112 +            if (set_chan_v4mapped(chan_v4m, &ia, &aa))
       
   113 +                chan_sl = chan_v4m;
       
   114 +        }
       
   115 +#endif
       
   116 +
       
   117  	found++;
       
   118  	gcontext = GSS_C_NO_CONTEXT;
       
   119  	accept_maj = gss_accept_sec_context(&accept_min,
       
   120  	   				    &gcontext, /* context_handle */
       
   121  					    server_creds, /* verifier_cred_handle */
       
   122  					    &tok, /* input_token */
       
   123 -					    chan, /* channel bindings */
       
   124 +					    chan_sl, /* channel bindings */
       
   125  					    &client, /* src_name */
       
   126  					    &mechid, /* mech_type */
       
   127  					    &out_tok, /* output_token */
       
   128