Ticket #1528: 1528.2.patch

File 1528.2.patch, 4.7 kB (added by glen, 4 months ago)

test2

  • src/mod_extforward.c

    old new  
    259259*/ 
    260260static int is_proxy_trusted(const char *ipstr, plugin_data *p) 
    261261{ 
    262         data_string* allds = (data_string *) array_get_element(p->conf.forwarder,"all"); 
     262        data_string* allds = (data_string *) array_get_element(p->conf.forwarder, "all"); 
     263 
    263264        if (allds) { 
    264                 if (strcasecmp(allds->value->ptr,"trust") == 0) 
     265                if (strcasecmp(allds->value->ptr, "trust") == 0) 
    265266                        return IP_TRUSTED; 
    266267                else 
    267268                        return IP_UNTRUSTED; 
    268269        } 
    269         return (data_string *)array_get_element(p->conf.forwarder,ipstr) ? IP_TRUSTED : IP_UNTRUSTED ; 
     270 
     271        return (data_string *)array_get_element(p->conf.forwarder,ipstr) ? IP_TRUSTED : IP_UNTRUSTED; 
    270272} 
    271273 
     274/* 
     275 * Return char *ip of last address of proxy that is not trusted. 
     276 */ 
     277static const char *last_not_in_array(array *a, plugin_data *p) 
     278{ 
     279        for (int i = a->used - 1; i >= 0; i--) { 
     280                data_string *ds = (data_string *)a->data[i]; 
     281                const char *ip = ds->value->ptr; 
     282 
     283                if (IP_UNTRUSTED == is_proxy_trusted(ip, p)) { 
     284                        return ip; 
     285                } 
     286        } 
     287        return NULL; 
     288} 
     289 
    272290struct addrinfo *ipstr_to_sockaddr(const char *host) 
    273291{ 
    274292   struct addrinfo hints, *res0; 
     
    316334        struct addrinfo *addrlist = NULL; 
    317335#endif 
    318336        const char *dst_addr_str = NULL; 
    319         int i; 
    320337        array *forward_array = NULL; 
    321         char *real_remote_addr = NULL; 
     338        const char *real_remote_addr = NULL; 
    322339#ifdef HAVE_IPV6 
    323340#endif 
    324341 
     
    342359                return HANDLER_GO_ON; 
    343360        } 
    344361 
    345         /* if the remote ip itself is not trusted , then do nothing */ 
    346362#ifdef HAVE_IPV6 
    347363        dst_addr_str = inet_ntop(con->dst_addr.plain.sa_family, 
    348364                      con->dst_addr.plain.sa_family == AF_INET6 ? 
     
    353369#else 
    354370        dst_addr_str = inet_ntoa(con->dst_addr.ipv4.sin_addr); 
    355371#endif 
    356         if (IP_UNTRUSTED == is_proxy_trusted (dst_addr_str, p) ) { 
     372 
     373        /* if the remote ip itself is not trusted, then do nothing */ 
     374        if (IP_UNTRUSTED == is_proxy_trusted(dst_addr_str, p)) { 
    357375                if (con->conf.log_request_handling) { 
    358376                        log_error_write(srv, __FILE__, __LINE__, "s", 
    359377                                        "remote address is NOT a trusted proxy, skipping"); 
     
    362380                return HANDLER_GO_ON; 
    363381        } 
    364382 
     383        /* build forward_array from forwarded data_string */ 
    365384        forward_array = extract_forward_array(forwarded->value); 
     385        real_remote_addr = last_not_in_array(forward_array, p); 
    366386 
    367         /* Testing shows that multiple headers and multiple values in one header 
    368            come in _reverse_ order. So the first one we get is the last one in the request. */ 
    369         for (i = forward_array->used - 1; i >= 0; i--) { 
    370                 data_string *ds = (data_string *) forward_array->data[i]; 
    371                 if (ds) { 
    372                         real_remote_addr = ds->value->ptr; 
    373                         break; 
    374                 } else { 
    375                         /* bug ?  bailing out here */ 
    376                         break; 
    377                 } 
    378         } 
    379387 
    380388        if (real_remote_addr != NULL) { /* parsed */ 
    381389                sock_addr sock; 
  • tests/mod-extforward.conf

    old new  
    11debug.log-request-handling   = "enable" 
    2 debug.log-response-header   = "enable" 
    3 debug.log-request-header   = "enable" 
     2debug.log-response-header   = "disable" 
     3debug.log-request-header   = "disable" 
    44 
    55server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" 
    66server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" 
     
    2727 
    2828extforward.forwarder = ( 
    2929        "127.0.0.1" => "trust", 
     30        "127.0.30.1" => "trust", 
    3031) 
  • tests/mod-extforward.t

    old new  
    88 
    99use strict; 
    1010use IO::Socket; 
    11 use Test::More tests => 2
     11use Test::More tests => 5
    1212use LightyTest; 
    1313 
    1414my $tf = LightyTest->new(); 
     
    2727EOF 
    2828); 
    2929$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.10.1' } ]; 
    30 ok($tf->handle_http($t) == 0, 'expect 127.0.10.1'); 
     30ok($tf->handle_http($t) == 0, 'expect 127.0.10.1, from single ip'); 
    3131 
    3232$t->{REQUEST} = ( <<EOF 
    3333GET /ip.pl HTTP/1.0 
     
    3636EOF 
    3737); 
    3838$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.20.1' } ]; 
    39 ok($tf->handle_http($t) == 0, 'expect 127.0.20.1'); 
     39ok($tf->handle_http($t) == 0, 'expect 127.0.20.1, from two ips'); 
    4040 
     41$t->{REQUEST} = ( <<EOF 
     42GET /ip.pl HTTP/1.0 
     43Host: www.example.org 
     44X-Forwarded-For: 127.0.10.1, 127.0.20.1, 127.0.30.1 
     45EOF 
     46); 
     47$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.20.1' } ]; 
     48ok($tf->handle_http($t) == 0, 'expect 127.0.20.1, from chained proxies'); 
     49 
    4150ok($tf->stop_proc == 0, "Stopping lighttpd");