Ticket #1528: 1528.2.patch
| File 1528.2.patch, 4.7 kB (added by glen, 4 months ago) |
|---|
-
src/mod_extforward.c
old new 259 259 */ 260 260 static int is_proxy_trusted(const char *ipstr, plugin_data *p) 261 261 { 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 263 264 if (allds) { 264 if (strcasecmp(allds->value->ptr, "trust") == 0)265 if (strcasecmp(allds->value->ptr, "trust") == 0) 265 266 return IP_TRUSTED; 266 267 else 267 268 return IP_UNTRUSTED; 268 269 } 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; 270 272 } 271 273 274 /* 275 * Return char *ip of last address of proxy that is not trusted. 276 */ 277 static 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 272 290 struct addrinfo *ipstr_to_sockaddr(const char *host) 273 291 { 274 292 struct addrinfo hints, *res0; … … 316 334 struct addrinfo *addrlist = NULL; 317 335 #endif 318 336 const char *dst_addr_str = NULL; 319 int i;320 337 array *forward_array = NULL; 321 c har *real_remote_addr = NULL;338 const char *real_remote_addr = NULL; 322 339 #ifdef HAVE_IPV6 323 340 #endif 324 341 … … 342 359 return HANDLER_GO_ON; 343 360 } 344 361 345 /* if the remote ip itself is not trusted , then do nothing */346 362 #ifdef HAVE_IPV6 347 363 dst_addr_str = inet_ntop(con->dst_addr.plain.sa_family, 348 364 con->dst_addr.plain.sa_family == AF_INET6 ? … … 353 369 #else 354 370 dst_addr_str = inet_ntoa(con->dst_addr.ipv4.sin_addr); 355 371 #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)) { 357 375 if (con->conf.log_request_handling) { 358 376 log_error_write(srv, __FILE__, __LINE__, "s", 359 377 "remote address is NOT a trusted proxy, skipping"); … … 362 380 return HANDLER_GO_ON; 363 381 } 364 382 383 /* build forward_array from forwarded data_string */ 365 384 forward_array = extract_forward_array(forwarded->value); 385 real_remote_addr = last_not_in_array(forward_array, p); 366 386 367 /* Testing shows that multiple headers and multiple values in one header368 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 }379 387 380 388 if (real_remote_addr != NULL) { /* parsed */ 381 389 sock_addr sock; -
tests/mod-extforward.conf
old new 1 1 debug.log-request-handling = "enable" 2 debug.log-response-header = " enable"3 debug.log-request-header = " enable"2 debug.log-response-header = "disable" 3 debug.log-request-header = "disable" 4 4 5 5 server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" 6 6 server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" … … 27 27 28 28 extforward.forwarder = ( 29 29 "127.0.0.1" => "trust", 30 "127.0.30.1" => "trust", 30 31 ) -
tests/mod-extforward.t
old new 8 8 9 9 use strict; 10 10 use IO::Socket; 11 use Test::More tests => 2;11 use Test::More tests => 5; 12 12 use LightyTest; 13 13 14 14 my $tf = LightyTest->new(); … … 27 27 EOF 28 28 ); 29 29 $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 ');30 ok($tf->handle_http($t) == 0, 'expect 127.0.10.1, from single ip'); 31 31 32 32 $t->{REQUEST} = ( <<EOF 33 33 GET /ip.pl HTTP/1.0 … … 36 36 EOF 37 37 ); 38 38 $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 ');39 ok($tf->handle_http($t) == 0, 'expect 127.0.20.1, from two ips'); 40 40 41 $t->{REQUEST} = ( <<EOF 42 GET /ip.pl HTTP/1.0 43 Host: www.example.org 44 X-Forwarded-For: 127.0.10.1, 127.0.20.1, 127.0.30.1 45 EOF 46 ); 47 $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.20.1' } ]; 48 ok($tf->handle_http($t) == 0, 'expect 127.0.20.1, from chained proxies'); 49 41 50 ok($tf->stop_proc == 0, "Stopping lighttpd");

