diff options
| author | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-09-08 10:59:27 +0000 |
|---|---|---|
| committer | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-09-08 10:59:27 +0000 |
| commit | 5e1de01ceaf87fde95e7c3486ab462c2e7f32b06 (patch) | |
| tree | 109d02a7364d37d614ea5e407b0d482191fa1ca0 | |
| parent | c8f4e5025e4045c626129d1de5df43ab0d4bc60a (diff) | |
| download | busybox-w32-5e1de01ceaf87fde95e7c3486ab462c2e7f32b06.tar.gz busybox-w32-5e1de01ceaf87fde95e7c3486ab462c2e7f32b06.tar.bz2 busybox-w32-5e1de01ceaf87fde95e7c3486ab462c2e7f32b06.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.
git-svn-id: svn://busybox.net/trunk/busybox@7423 69ca8d6d-28ef-0310-b511-8ec308f3f277
| -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 | ||
