diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-09-08 10:59:27 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-09-08 10:59:27 +0000 |
commit | b65422cf652c3f04cf6edd4c6050186df25e844c (patch) | |
tree | 109d02a7364d37d614ea5e407b0d482191fa1ca0 | |
parent | 350733abb8157cd8e9e0b6bb10e8699a96c31a20 (diff) | |
download | busybox-w32-b65422cf652c3f04cf6edd4c6050186df25e844c.tar.gz busybox-w32-b65422cf652c3f04cf6edd4c6050186df25e844c.tar.bz2 busybox-w32-b65422cf652c3f04cf6edd4c6050186df25e844c.zip |
last_patch_109 from Vladimir N. Oleynik
Busybox`s httpd have the defect (from born):
ip 1.2.3.1 have true comparing also with
1.2.3.10-1.2.3.19 and 1.2.3.100-1.2.3.199.
Last patch removed this bug and added feature:
allow/deny rule can support network/netmask
example: 1.2.3.0/255.255.255.128
or
network/mask_bits
example: 1.2.3.0/25
now; old format
1
1.2
1.2.3
1.2.3.4
too support and converted to
1/8 1.2/16 1.2.3/24 1.2.3.4/32
automaticaly.
Also, current CVS have small problem: ignores
A:IP, (loses 'A', 'a' only work). Corrected.
-rw-r--r-- | networking/httpd.c | 287 |
1 files changed, 198 insertions, 89 deletions
diff --git a/networking/httpd.c b/networking/httpd.c index 8c87e7e91..eb03f34c0 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -49,9 +49,9 @@ | |||
49 | * | 49 | * |
50 | * httpd.conf has the following format: | 50 | * httpd.conf has the following format: |
51 | * | 51 | * |
52 | * A:172.20. # Allow any address that begins with 172.20 | 52 | * A:172.20. # Allow address from 172.20.0.0/16 |
53 | * A:10.10. # Allow any address that begins with 10.10. | 53 | * A:10.0.0.0/25 # Allow any address from 10.0.0.0-10.0.0.127 |
54 | * A:10.20 # Allow any address that previous set and 10.200-209.X.X | 54 | * A:10.0.0.0/255.255.255.128 # Allow any address that previous set |
55 | * A:127.0.0.1 # Allow local loopback connections | 55 | * A:127.0.0.1 # Allow local loopback connections |
56 | * D:* # Deny from other IP connections | 56 | * D:* # Deny from other IP connections |
57 | * /cgi-bin:foo:bar # Require user foo, pwd bar on urls starting with /cgi-bin/ | 57 | * /cgi-bin:foo:bar # Require user foo, pwd bar on urls starting with /cgi-bin/ |
@@ -75,9 +75,8 @@ | |||
75 | * | 75 | * |
76 | * Example: | 76 | * Example: |
77 | * 1. Allow only specified addresses | 77 | * 1. Allow only specified addresses |
78 | * A:172.20. # Allow any address that begins with 172.20 | 78 | * A:172.20 # Allow any address that begins with 172.20. |
79 | * A:10.10. # Allow any address that begins with 10.10. | 79 | * A:10.10. # Allow any address that begins with 10.10. |
80 | * A:10.10 # Allow any address that previous set and 10.100-109.X.X | ||
81 | * A:127.0.0.1 # Allow local loopback connections | 80 | * A:127.0.0.1 # Allow local loopback connections |
82 | * D:* # Deny from other IP connections | 81 | * D:* # Deny from other IP connections |
83 | * | 82 | * |
@@ -87,8 +86,7 @@ | |||
87 | * A:* # (optional line added for clarity) | 86 | * A:* # (optional line added for clarity) |
88 | * | 87 | * |
89 | * If a sub directory contains a config file it is parsed and merged with | 88 | * If a sub directory contains a config file it is parsed and merged with |
90 | * any existing settings as if it was appended to the original configuration | 89 | * any existing settings as if it was appended to the original configuration. |
91 | * except that all previous IP config rules are discarded. | ||
92 | * | 90 | * |
93 | * subdir paths are relative to the containing subdir and thus cannot | 91 | * subdir paths are relative to the containing subdir and thus cannot |
94 | * affect the parent rules. | 92 | * affect the parent rules. |
@@ -122,7 +120,7 @@ | |||
122 | #include "busybox.h" | 120 | #include "busybox.h" |
123 | 121 | ||
124 | 122 | ||
125 | static const char httpdVersion[] = "busybox httpd/1.28 22-Jun-2003"; | 123 | static const char httpdVersion[] = "busybox httpd/1.30 7-Sep-2003"; |
126 | static const char default_path_httpd_conf[] = "/etc"; | 124 | static const char default_path_httpd_conf[] = "/etc"; |
127 | static const char httpd_conf[] = "httpd.conf"; | 125 | static const char httpd_conf[] = "httpd.conf"; |
128 | static const char home[] = "./"; | 126 | static const char home[] = "./"; |
@@ -221,6 +219,13 @@ typedef struct HT_ACCESS { | |||
221 | char before_colon[1]; /* really bigger, must last */ | 219 | char before_colon[1]; /* really bigger, must last */ |
222 | } Htaccess; | 220 | } Htaccess; |
223 | 221 | ||
222 | typedef struct HT_ACCESS_IP { | ||
223 | unsigned int ip; | ||
224 | unsigned int mask; | ||
225 | int allow_deny; | ||
226 | struct HT_ACCESS_IP *next; | ||
227 | } Htaccess_IP; | ||
228 | |||
224 | typedef struct | 229 | typedef struct |
225 | { | 230 | { |
226 | #ifdef CONFIG_FEATURE_HTTPD_CGI | 231 | #ifdef CONFIG_FEATURE_HTTPD_CGI |
@@ -234,7 +239,10 @@ typedef struct | |||
234 | #endif | 239 | #endif |
235 | const char *configFile; | 240 | const char *configFile; |
236 | 241 | ||
237 | char rmt_ip[16]; /* for set env REMOTE_ADDR */ | 242 | unsigned int rmt_ip; |
243 | #if defined(CONFIG_FEATURE_HTTPD_CGI) || defined(DEBUG) | ||
244 | char rmt_ip_str[16]; /* for set env REMOTE_ADDR */ | ||
245 | #endif | ||
238 | unsigned port; /* server initial port and for | 246 | unsigned port; /* server initial port and for |
239 | set env REMOTE_PORT */ | 247 | set env REMOTE_PORT */ |
240 | 248 | ||
@@ -242,7 +250,7 @@ typedef struct | |||
242 | off_t ContentLength; /* -1 - unknown */ | 250 | off_t ContentLength; /* -1 - unknown */ |
243 | time_t last_mod; | 251 | time_t last_mod; |
244 | 252 | ||
245 | Htaccess *ip_a_d; /* config allow/deny lines */ | 253 | Htaccess_IP *ip_a_d; /* config allow/deny lines */ |
246 | int flg_deny_all; | 254 | int flg_deny_all; |
247 | #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH | 255 | #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH |
248 | Htaccess *auth; /* config user:password lines */ | 256 | Htaccess *auth; /* config user:password lines */ |
@@ -353,7 +361,83 @@ static const char RFC1123FMT[] = "%a, %d %b %Y %H:%M:%S GMT"; | |||
353 | static const char Content_length[] = "Content-length:"; | 361 | static const char Content_length[] = "Content-length:"; |
354 | 362 | ||
355 | 363 | ||
364 | static int | ||
365 | scan_ip (const char **ep, unsigned int *ip, unsigned char endc) | ||
366 | { | ||
367 | const char *p = *ep; | ||
368 | int auto_mask = 8; | ||
369 | int j; | ||
370 | |||
371 | *ip = 0; | ||
372 | for (j = 0; j < 4; j++) { | ||
373 | unsigned int octet; | ||
374 | |||
375 | if ((*p < '0' || *p > '9') && (*p != '/' || j == 0) && *p != 0) | ||
376 | return -auto_mask; | ||
377 | octet = 0; | ||
378 | while (*p >= '0' && *p <= '9') { | ||
379 | octet *= 10; | ||
380 | octet += *p - '0'; | ||
381 | if (octet > 255) | ||
382 | return -auto_mask; | ||
383 | p++; | ||
384 | } | ||
385 | if (*p == '.') | ||
386 | p++; | ||
387 | if (*p != '/' && *p != 0) | ||
388 | auto_mask += 8; | ||
389 | *ip = ((*ip) << 8) | octet; | ||
390 | } | ||
391 | if (*p != 0) { | ||
392 | if (*p != endc) | ||
393 | return -auto_mask; | ||
394 | p++; | ||
395 | if(*p == 0) | ||
396 | return -auto_mask; | ||
397 | } | ||
398 | *ep = p; | ||
399 | return auto_mask; | ||
400 | } | ||
401 | |||
402 | static int | ||
403 | scan_ip_mask (const char *ipm, unsigned int *ip, unsigned int *mask) | ||
404 | { | ||
405 | int i; | ||
406 | unsigned int msk; | ||
407 | |||
408 | i = scan_ip(&ipm, ip, '/'); | ||
409 | if(i < 0) | ||
410 | return i; | ||
411 | if(*ipm) { | ||
412 | const char *p = ipm; | ||
413 | |||
414 | i = 0; | ||
415 | while (*p) { | ||
416 | if (*p < '0' || *p > '9') { | ||
417 | if (*p == '.') { | ||
418 | i = scan_ip (&ipm, mask, 0); | ||
419 | return i != 32; | ||
420 | } | ||
421 | return -1; | ||
422 | } | ||
423 | i *= 10; | ||
424 | i += *p - '0'; | ||
425 | p++; | ||
426 | } | ||
427 | } | ||
428 | if (i > 32 || i < 0) | ||
429 | return -1; | ||
430 | msk = 0x80000000; | ||
431 | *mask = 0; | ||
432 | while (i > 0) { | ||
433 | *mask |= msk; | ||
434 | msk >>= 1; | ||
435 | i--; | ||
436 | } | ||
437 | return 0; | ||
438 | } | ||
356 | 439 | ||
440 | #if defined(CONFIG_FEATURE_HTTPD_BASIC_AUTH) || defined(CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES) | ||
357 | static void free_config_lines(Htaccess **pprev) | 441 | static void free_config_lines(Htaccess **pprev) |
358 | { | 442 | { |
359 | Htaccess *prev = *pprev; | 443 | Htaccess *prev = *pprev; |
@@ -366,6 +450,7 @@ static void free_config_lines(Htaccess **pprev) | |||
366 | } | 450 | } |
367 | *pprev = NULL; | 451 | *pprev = NULL; |
368 | } | 452 | } |
453 | #endif | ||
369 | 454 | ||
370 | /* flag */ | 455 | /* flag */ |
371 | #define FIRST_PARSE 0 | 456 | #define FIRST_PARSE 0 |
@@ -411,18 +496,29 @@ static void parse_conf(const char *path, int flag) | |||
411 | char *c, *p; | 496 | char *c, *p; |
412 | 497 | ||
413 | /* free previous ip setup if present */ | 498 | /* free previous ip setup if present */ |
414 | free_config_lines(&config->ip_a_d); | 499 | Htaccess_IP *pip = config->ip_a_d; |
500 | |||
501 | while( pip ) { | ||
502 | Htaccess_IP *cur_ipl = pip; | ||
503 | |||
504 | pip = cur_ipl->next; | ||
505 | free(cur_ipl); | ||
506 | } | ||
507 | config->ip_a_d = NULL; | ||
508 | |||
415 | config->flg_deny_all = 0; | 509 | config->flg_deny_all = 0; |
510 | |||
511 | #if defined(CONFIG_FEATURE_HTTPD_BASIC_AUTH) || defined(CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES) | ||
416 | /* retain previous auth and mime config only for subdir parse */ | 512 | /* retain previous auth and mime config only for subdir parse */ |
417 | if(flag != SUBDIR_PARSE) { | 513 | if(flag != SUBDIR_PARSE) { |
418 | #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH | 514 | #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH |
419 | free_config_lines(&config->auth) | 515 | free_config_lines(&config->auth); |
420 | #endif | 516 | #endif |
421 | ; /* appease compiler warnings if option is not set */ | ||
422 | #ifdef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES | 517 | #ifdef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES |
423 | free_config_lines(&config->mime_a); | 518 | free_config_lines(&config->mime_a); |
424 | #endif | 519 | #endif |
425 | } | 520 | } |
521 | #endif | ||
426 | 522 | ||
427 | if(flag == SUBDIR_PARSE || cf == NULL) { | 523 | if(flag == SUBDIR_PARSE || cf == NULL) { |
428 | cf = alloca(strlen(path) + sizeof(httpd_conf) + 2); | 524 | cf = alloca(strlen(path) + sizeof(httpd_conf) + 2); |
@@ -477,7 +573,7 @@ static void parse_conf(const char *path, int flag) | |||
477 | 573 | ||
478 | if(*p0 == 'a') | 574 | if(*p0 == 'a') |
479 | *p0 = 'A'; | 575 | *p0 = 'A'; |
480 | else if(*p0 != 'D' | 576 | else if(*p0 != 'D' && *p0 != 'A' |
481 | #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH | 577 | #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH |
482 | && *p0 != '/' | 578 | && *p0 != '/' |
483 | #endif | 579 | #endif |
@@ -486,7 +582,35 @@ static void parse_conf(const char *path, int flag) | |||
486 | #endif | 582 | #endif |
487 | ) | 583 | ) |
488 | continue; | 584 | continue; |
585 | if(*p0 == 'A' || *p0 == 'D') { | ||
586 | /* storing current config IP line */ | ||
587 | pip = calloc(1, sizeof(Htaccess_IP)); | ||
588 | if(pip) { | ||
589 | if(scan_ip_mask (c, &(pip->ip), &(pip->mask))) { | ||
590 | /* syntax IP{/mask} error detected, protect all */ | ||
591 | *p0 = 'D'; | ||
592 | pip->mask = 0; | ||
593 | } | ||
594 | pip->allow_deny = *p0; | ||
595 | if(*p0 == 'D') { | ||
596 | /* Deny:form_IP move top */ | ||
597 | pip->next = config->ip_a_d; | ||
598 | config->ip_a_d = pip; | ||
599 | } else { | ||
600 | /* add to bottom A:form_IP config line */ | ||
601 | Htaccess_IP *prev_IP = config->ip_a_d; | ||
489 | 602 | ||
603 | if(prev_IP == NULL) { | ||
604 | config->ip_a_d = pip; | ||
605 | } else { | ||
606 | while(prev_IP->next) | ||
607 | prev_IP = prev_IP->next; | ||
608 | prev_IP->next = pip; | ||
609 | } | ||
610 | } | ||
611 | } | ||
612 | continue; | ||
613 | } | ||
490 | #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH | 614 | #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH |
491 | if(*p0 == '/') { | 615 | if(*p0 == '/') { |
492 | /* make full path from httpd root / curent_path / config_line_path */ | 616 | /* make full path from httpd root / curent_path / config_line_path */ |
@@ -526,8 +650,9 @@ static void parse_conf(const char *path, int flag) | |||
526 | sprintf(p0, "%s:%s", p0, c); | 650 | sprintf(p0, "%s:%s", p0, c); |
527 | } | 651 | } |
528 | #endif | 652 | #endif |
529 | /* storing current config line */ | ||
530 | 653 | ||
654 | #if defined(CONFIG_FEATURE_HTTPD_BASIC_AUTH) || defined(CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES) | ||
655 | /* storing current config line */ | ||
531 | cur = calloc(1, sizeof(Htaccess) + strlen(p0)); | 656 | cur = calloc(1, sizeof(Htaccess) + strlen(p0)); |
532 | if(cur) { | 657 | if(cur) { |
533 | cf = strcpy(cur->before_colon, p0); | 658 | cf = strcpy(cur->before_colon, p0); |
@@ -538,24 +663,6 @@ static void parse_conf(const char *path, int flag) | |||
538 | if(*cf == '/') | 663 | if(*cf == '/') |
539 | free(p0); | 664 | free(p0); |
540 | #endif | 665 | #endif |
541 | if(*cf == 'A' || *cf == 'D') { | ||
542 | if(*cf == 'D') { | ||
543 | /* Deny:form_IP move top */ | ||
544 | cur->next = config->ip_a_d; | ||
545 | config->ip_a_d = cur; | ||
546 | } else { | ||
547 | /* add to bottom A:form_IP config line */ | ||
548 | Htaccess *prev_IP = config->ip_a_d; | ||
549 | |||
550 | if(prev_IP == NULL) { | ||
551 | config->ip_a_d = cur; | ||
552 | } else { | ||
553 | while(prev_IP->next) | ||
554 | prev_IP = prev_IP->next; | ||
555 | prev_IP->next = cur; | ||
556 | } | ||
557 | } | ||
558 | } | ||
559 | #ifdef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES | 666 | #ifdef CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES |
560 | else if(*cf == '.') { | 667 | else if(*cf == '.') { |
561 | /* config .mime line move top for overwrite previous */ | 668 | /* config .mime line move top for overwrite previous */ |
@@ -595,6 +702,7 @@ static void parse_conf(const char *path, int flag) | |||
595 | } | 702 | } |
596 | } | 703 | } |
597 | #endif | 704 | #endif |
705 | #endif | ||
598 | } | 706 | } |
599 | } | 707 | } |
600 | fclose(f); | 708 | fclose(f); |
@@ -1100,10 +1208,10 @@ static int sendCgi(const char *url, | |||
1100 | addEnv("SERVER", "PROTOCOL", "HTTP/1.0"); | 1208 | addEnv("SERVER", "PROTOCOL", "HTTP/1.0"); |
1101 | addEnv("GATEWAY_INTERFACE", "", "CGI/1.1"); | 1209 | addEnv("GATEWAY_INTERFACE", "", "CGI/1.1"); |
1102 | #ifdef CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV | 1210 | #ifdef CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV |
1103 | addEnv("REMOTE", "ADDR", config->rmt_ip); | 1211 | addEnv("REMOTE", "ADDR", config->rmt_ip_str); |
1104 | addEnvPort("REMOTE"); | 1212 | addEnvPort("REMOTE"); |
1105 | #else | 1213 | #else |
1106 | addEnv("REMOTE_ADDR", "", config->rmt_ip); | 1214 | addEnv("REMOTE_ADDR", "", config->rmt_ip_str); |
1107 | #endif | 1215 | #endif |
1108 | if(bodyLen) { | 1216 | if(bodyLen) { |
1109 | char sbl[32]; | 1217 | char sbl[32]; |
@@ -1288,17 +1396,45 @@ static int sendFile(const char *url, char *buf) | |||
1288 | return 0; | 1396 | return 0; |
1289 | } | 1397 | } |
1290 | 1398 | ||
1399 | static int checkPermIP(void) | ||
1400 | { | ||
1401 | Htaccess_IP * cur; | ||
1402 | |||
1403 | /* This could stand some work */ | ||
1404 | for (cur = config->ip_a_d; cur; cur = cur->next) { | ||
1405 | #ifdef DEBUG | ||
1406 | if (config->debugHttpd) { | ||
1407 | fprintf(stderr, "checkPermIP: '%s' ? ", config->rmt_ip_str); | ||
1408 | fprintf(stderr, "'%u.%u.%u.%u/%u.%u.%u.%u'\n", | ||
1409 | (unsigned char)(cur->ip >> 24), | ||
1410 | (unsigned char)(cur->ip >> 16), | ||
1411 | (unsigned char)(cur->ip >> 8), | ||
1412 | cur->ip & 0xff, | ||
1413 | (unsigned char)(cur->mask >> 24), | ||
1414 | (unsigned char)(cur->mask >> 16), | ||
1415 | (unsigned char)(cur->mask >> 8), | ||
1416 | cur->mask & 0xff); | ||
1417 | } | ||
1418 | #endif | ||
1419 | if((config->rmt_ip & cur->mask) == cur->ip) | ||
1420 | return cur->allow_deny == 'A'; /* Allow/Deny */ | ||
1421 | } | ||
1422 | |||
1423 | /* if uncofigured, return 1 - access from all */ | ||
1424 | return !config->flg_deny_all; | ||
1425 | } | ||
1426 | |||
1291 | /**************************************************************************** | 1427 | /**************************************************************************** |
1292 | * | 1428 | * |
1293 | > $Function: checkPerm() | 1429 | > $Function: checkPerm() |
1294 | * | 1430 | * |
1295 | * $Description: Check the permission file for access. | 1431 | * $Description: Check the permission file for access password protected. |
1296 | * | 1432 | * |
1297 | * If config file isn't present, everything is allowed. | 1433 | * If config file isn't present, everything is allowed. |
1298 | * Entries are of the form you can see example from header source | 1434 | * Entries are of the form you can see example from header source |
1299 | * | 1435 | * |
1300 | * $Parameters: | 1436 | * $Parameters: |
1301 | * (const char *) path . . . . The file path or NULL for ip addresses. | 1437 | * (const char *) path . . . . The file path. |
1302 | * (const char *) request . . . User information to validate. | 1438 | * (const char *) request . . . User information to validate. |
1303 | * | 1439 | * |
1304 | * $Return: (int) . . . . . . . . . 1 if request OK, 0 otherwise. | 1440 | * $Return: (int) . . . . . . . . . 1 if request OK, 0 otherwise. |
@@ -1312,25 +1448,19 @@ static int checkPerm(const char *path, const char *request) | |||
1312 | const char *p; | 1448 | const char *p; |
1313 | const char *p0; | 1449 | const char *p0; |
1314 | 1450 | ||
1315 | int ipaddr = path == NULL; | ||
1316 | const char *prev = NULL; | 1451 | const char *prev = NULL; |
1317 | 1452 | ||
1318 | /* This could stand some work */ | 1453 | /* This could stand some work */ |
1319 | for (cur = ipaddr ? config->ip_a_d : config->auth; cur; cur = cur->next) { | 1454 | for (cur = config->auth; cur; cur = cur->next) { |
1320 | p0 = cur->before_colon; | 1455 | p0 = cur->before_colon; |
1321 | if(prev != NULL && strcmp(prev, p0) != 0) | 1456 | if(prev != NULL && strcmp(prev, p0) != 0) |
1322 | continue; /* find next identical */ | 1457 | continue; /* find next identical */ |
1323 | p = cur->after_colon; | 1458 | p = cur->after_colon; |
1324 | #ifdef DEBUG | 1459 | #ifdef DEBUG |
1325 | if (config->debugHttpd) | 1460 | if (config->debugHttpd) |
1326 | fprintf(stderr,"checkPerm: '%s' ? '%s'\n", | 1461 | fprintf(stderr,"checkPerm: '%s' ? '%s'\n", p0, request); |
1327 | (ipaddr ? (*p ? p : "*") : p0), request); | ||
1328 | #endif | 1462 | #endif |
1329 | if(ipaddr) { | 1463 | { |
1330 | if(strncmp(p, request, strlen(p)) != 0) | ||
1331 | continue; | ||
1332 | return *p0 == 'A'; /* Allow/Deny */ | ||
1333 | } else { | ||
1334 | int l = strlen(p0); | 1464 | int l = strlen(p0); |
1335 | 1465 | ||
1336 | if(strncmp(p0, path, l) == 0 && | 1466 | if(strncmp(p0, path, l) == 0 && |
@@ -1372,33 +1502,9 @@ static int checkPerm(const char *path, const char *request) | |||
1372 | } | 1502 | } |
1373 | } /* for */ | 1503 | } /* for */ |
1374 | 1504 | ||
1375 | if(ipaddr) | ||
1376 | return !config->flg_deny_all; | ||
1377 | return prev == NULL; | 1505 | return prev == NULL; |
1378 | } | 1506 | } |
1379 | 1507 | ||
1380 | #else /* ifndef CONFIG_FEATURE_HTTPD_BASIC_AUTH */ | ||
1381 | static int checkPermIP(const char *request) | ||
1382 | { | ||
1383 | Htaccess * cur; | ||
1384 | const char *p; | ||
1385 | |||
1386 | /* This could stand some work */ | ||
1387 | for (cur = config->ip_a_d; cur; cur = cur->next) { | ||
1388 | p = cur->after_colon; | ||
1389 | #ifdef DEBUG | ||
1390 | if (config->debugHttpd) | ||
1391 | fprintf(stderr, "checkPerm: '%s' ? '%s'\n", | ||
1392 | (*p ? p : "*"), request); | ||
1393 | #endif | ||
1394 | if(strncmp(p, request, strlen(p)) == 0) | ||
1395 | return *cur->before_colon == 'A'; /* Allow/Deny */ | ||
1396 | } | ||
1397 | |||
1398 | /* if uncofigured, return 1 - access from all */ | ||
1399 | return !config->flg_deny_all; | ||
1400 | } | ||
1401 | #define checkPerm(null, request) checkPermIP(request) | ||
1402 | #endif /* CONFIG_FEATURE_HTTPD_BASIC_AUTH */ | 1508 | #endif /* CONFIG_FEATURE_HTTPD_BASIC_AUTH */ |
1403 | 1509 | ||
1404 | 1510 | ||
@@ -1518,14 +1624,14 @@ BAD_REQUEST: | |||
1518 | #endif | 1624 | #endif |
1519 | 1625 | ||
1520 | test = url; | 1626 | test = url; |
1521 | ip_allowed = checkPerm(NULL, config->rmt_ip); | 1627 | ip_allowed = checkPermIP(); |
1522 | while(ip_allowed && (test = strchr( test + 1, '/' )) != NULL) { | 1628 | while(ip_allowed && (test = strchr( test + 1, '/' )) != NULL) { |
1523 | /* have path1/path2 */ | 1629 | /* have path1/path2 */ |
1524 | *test = '\0'; | 1630 | *test = '\0'; |
1525 | if( is_directory(url + 1, 1, &sb) ) { | 1631 | if( is_directory(url + 1, 1, &sb) ) { |
1526 | /* may be having subdir config */ | 1632 | /* may be having subdir config */ |
1527 | parse_conf(url + 1, SUBDIR_PARSE); | 1633 | parse_conf(url + 1, SUBDIR_PARSE); |
1528 | ip_allowed = checkPerm(NULL, config->rmt_ip); | 1634 | ip_allowed = checkPermIP(); |
1529 | } | 1635 | } |
1530 | *test = '/'; | 1636 | *test = '/'; |
1531 | } | 1637 | } |
@@ -1679,7 +1785,6 @@ static int miniHttpd(int server) | |||
1679 | int on; | 1785 | int on; |
1680 | struct sockaddr_in fromAddr; | 1786 | struct sockaddr_in fromAddr; |
1681 | 1787 | ||
1682 | unsigned int addr; | ||
1683 | socklen_t fromAddrLen = sizeof(fromAddr); | 1788 | socklen_t fromAddrLen = sizeof(fromAddr); |
1684 | int s = accept(server, | 1789 | int s = accept(server, |
1685 | (struct sockaddr *)&fromAddr, &fromAddrLen); | 1790 | (struct sockaddr *)&fromAddr, &fromAddrLen); |
@@ -1688,19 +1793,22 @@ static int miniHttpd(int server) | |||
1688 | continue; | 1793 | continue; |
1689 | } | 1794 | } |
1690 | config->accepted_socket = s; | 1795 | config->accepted_socket = s; |
1691 | addr = ntohl(fromAddr.sin_addr.s_addr); | 1796 | config->rmt_ip = ntohl(fromAddr.sin_addr.s_addr); |
1692 | sprintf(config->rmt_ip, "%u.%u.%u.%u", | 1797 | #if defined(CONFIG_FEATURE_HTTPD_CGI) || defined(DEBUG) |
1693 | (unsigned char)(addr >> 24), | 1798 | sprintf(config->rmt_ip_str, "%u.%u.%u.%u", |
1694 | (unsigned char)(addr >> 16), | 1799 | (unsigned char)(config->rmt_ip >> 24), |
1695 | (unsigned char)(addr >> 8), | 1800 | (unsigned char)(config->rmt_ip >> 16), |
1696 | addr & 0xff); | 1801 | (unsigned char)(config->rmt_ip >> 8), |
1802 | config->rmt_ip & 0xff); | ||
1697 | config->port = ntohs(fromAddr.sin_port); | 1803 | config->port = ntohs(fromAddr.sin_port); |
1698 | #ifdef DEBUG | 1804 | #ifdef DEBUG |
1699 | if (config->debugHttpd) { | 1805 | if (config->debugHttpd) { |
1700 | bb_error_msg("connection from IP=%s, port %u\n", | 1806 | bb_error_msg("connection from IP=%s, port %u\n", |
1701 | config->rmt_ip, config->port); | 1807 | config->rmt_ip_str, config->port); |
1702 | } | 1808 | } |
1703 | #endif | 1809 | #endif |
1810 | #endif /* CONFIG_FEATURE_HTTPD_CGI */ | ||
1811 | |||
1704 | /* set the KEEPALIVE option to cull dead connections */ | 1812 | /* set the KEEPALIVE option to cull dead connections */ |
1705 | on = 1; | 1813 | on = 1; |
1706 | setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof (on)); | 1814 | setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof (on)); |
@@ -1729,15 +1837,16 @@ static int miniHttpd(void) | |||
1729 | { | 1837 | { |
1730 | struct sockaddr_in fromAddrLen; | 1838 | struct sockaddr_in fromAddrLen; |
1731 | socklen_t sinlen = sizeof (struct sockaddr_in); | 1839 | socklen_t sinlen = sizeof (struct sockaddr_in); |
1732 | unsigned int addr; | ||
1733 | 1840 | ||
1734 | getpeername (0, (struct sockaddr *)&fromAddrLen, &sinlen); | 1841 | getpeername (0, (struct sockaddr *)&fromAddrLen, &sinlen); |
1735 | addr = ntohl(fromAddrLen.sin_addr.s_addr); | 1842 | config->rmt_ip = ntohl(fromAddrLen.sin_addr.s_addr); |
1736 | sprintf(config->rmt_ip, "%u.%u.%u.%u", | 1843 | #if defined(CONFIG_FEATURE_HTTPD_CGI) || defined(DEBUG) |
1737 | (unsigned char)(addr >> 24), | 1844 | sprintf(config->rmt_ip_str, "%u.%u.%u.%u", |
1738 | (unsigned char)(addr >> 16), | 1845 | (unsigned char)(config->rmt_ip >> 24), |
1739 | (unsigned char)(addr >> 8), | 1846 | (unsigned char)(config->rmt_ip >> 16), |
1740 | addr & 0xff); | 1847 | (unsigned char)(config->rmt_ip >> 8), |
1848 | config->rmt_ip & 0xff); | ||
1849 | #endif | ||
1741 | config->port = ntohs(fromAddrLen.sin_port); | 1850 | config->port = ntohs(fromAddrLen.sin_port); |
1742 | handleIncoming(); | 1851 | handleIncoming(); |
1743 | return 0; | 1852 | return 0; |
@@ -1750,12 +1859,12 @@ static void sighup_handler(int sig) | |||
1750 | /* set and reset */ | 1859 | /* set and reset */ |
1751 | struct sigaction sa; | 1860 | struct sigaction sa; |
1752 | 1861 | ||
1862 | parse_conf(default_path_httpd_conf, | ||
1863 | sig == SIGHUP ? SIGNALED_PARSE : FIRST_PARSE); | ||
1753 | sa.sa_handler = sighup_handler; | 1864 | sa.sa_handler = sighup_handler; |
1754 | sigemptyset(&sa.sa_mask); | 1865 | sigemptyset(&sa.sa_mask); |
1755 | sa.sa_flags = SA_RESTART; | 1866 | sa.sa_flags = SA_RESTART; |
1756 | sigaction(SIGHUP, &sa, NULL); | 1867 | sigaction(SIGHUP, &sa, NULL); |
1757 | parse_conf(default_path_httpd_conf, | ||
1758 | sig == SIGHUP ? SIGNALED_PARSE : FIRST_PARSE); | ||
1759 | } | 1868 | } |
1760 | #endif | 1869 | #endif |
1761 | 1870 | ||