diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-13 09:53:06 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-13 09:53:06 +0000 |
| commit | 0eb406caa85d6203b9d80da89e197f0b3e9fcc1d (patch) | |
| tree | 42e44146c7413930ff2c5e49af421b1a3de67812 | |
| parent | bd8390a872ae42751ff441180017b2d3c76dbe03 (diff) | |
| download | busybox-w32-0eb406caa85d6203b9d80da89e197f0b3e9fcc1d.tar.gz busybox-w32-0eb406caa85d6203b9d80da89e197f0b3e9fcc1d.tar.bz2 busybox-w32-0eb406caa85d6203b9d80da89e197f0b3e9fcc1d.zip | |
htppd: lots of variable/function renaming in config file parsing.
fixed a bug where we trashed config file's name;
otherwise, should not have any real behavioral changes.
function old new delta
check_user_passwd - 338 +338
handle_incoming_and_exit 2661 2649 -12
parse_conf 1650 1536 -114
checkPerm 338 - -338
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 0/2 up/down: 338/-464) Total: -126 bytes
| -rw-r--r-- | networking/httpd.c | 225 |
1 files changed, 102 insertions, 123 deletions
diff --git a/networking/httpd.c b/networking/httpd.c index 352a97d3c..e3c1a4e11 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | * Doc: | 27 | * Doc: |
| 28 | * "CGI Environment Variables": http://hoohoo.ncsa.uiuc.edu/cgi/env.html | 28 | * "CGI Environment Variables": http://hoohoo.ncsa.uiuc.edu/cgi/env.html |
| 29 | * | 29 | * |
| 30 | * The server can also be invoked as a url arg decoder and html text encoder | 30 | * The applet can also be invoked as a url arg decoder and html text encoder |
| 31 | * as follows: | 31 | * as follows: |
| 32 | * foo=`httpd -d $foo` # decode "Hello%20World" as "Hello World" | 32 | * foo=`httpd -d $foo` # decode "Hello%20World" as "Hello World" |
| 33 | * bar=`httpd -e "<Hello World>"` # encode as "<Hello World>" | 33 | * bar=`httpd -e "<Hello World>"` # encode as "<Hello World>" |
| @@ -55,19 +55,11 @@ | |||
| 55 | * .au:audio/basic # additional mime type for audio.au files | 55 | * .au:audio/basic # additional mime type for audio.au files |
| 56 | * *.php:/path/php # running cgi.php scripts through an interpreter | 56 | * *.php:/path/php # running cgi.php scripts through an interpreter |
| 57 | * | 57 | * |
| 58 | * A/D may be as a/d or allow/deny - first char case insensitive | 58 | * A/D may be as a/d or allow/deny - only first char matters. |
| 59 | * Deny IP rules take precedence over allow rules. | 59 | * Deny/Allow IP logic: |
| 60 | * | 60 | * - Default is to allow all (Allow all (A:*) is a no-op). |
| 61 | * | ||
| 62 | * The Deny/Allow IP logic: | ||
| 63 | * | ||
| 64 | * - Default is to allow all. No addresses are denied unless | ||
| 65 | * denied with a D: rule. | ||
| 66 | * - Order of Deny/Allow rules is significant | ||
| 67 | * - Deny rules take precedence over allow rules. | 61 | * - Deny rules take precedence over allow rules. |
| 68 | * - If a deny all rule (D:*) is used it acts as a catch-all for unmatched | 62 | * - "Deny all" rule (D:*) is applied last. |
| 69 | * addresses. | ||
| 70 | * - Specification of Allow all (A:*) is a no-op | ||
| 71 | * | 63 | * |
| 72 | * Example: | 64 | * Example: |
| 73 | * 1. Allow only specified addresses | 65 | * 1. Allow only specified addresses |
| @@ -494,10 +486,10 @@ static void parse_conf(const char *path, int flag) | |||
| 494 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 486 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
| 495 | Htaccess *cur; | 487 | Htaccess *cur; |
| 496 | #endif | 488 | #endif |
| 497 | const char *cf = configFile; | 489 | const char *filename = configFile; |
| 498 | char buf[160]; | 490 | char buf[160]; |
| 499 | char *p0; | 491 | char *p, *p0; |
| 500 | char *c, *p; | 492 | char *after_colon; |
| 501 | Htaccess_IP *pip; | 493 | Htaccess_IP *pip; |
| 502 | 494 | ||
| 503 | /* discard old rules */ | 495 | /* discard old rules */ |
| @@ -520,20 +512,20 @@ static void parse_conf(const char *path, int flag) | |||
| 520 | } | 512 | } |
| 521 | #endif | 513 | #endif |
| 522 | 514 | ||
| 523 | if (flag == SUBDIR_PARSE || cf == NULL) { | 515 | if (flag == SUBDIR_PARSE || filename == NULL) { |
| 524 | cf = alloca(strlen(path) + sizeof(httpd_conf) + 2); | 516 | filename = alloca(strlen(path) + sizeof(httpd_conf) + 2); |
| 525 | sprintf((char *)cf, "%s/%s", path, httpd_conf); | 517 | sprintf((char *)filename, "%s/%s", path, httpd_conf); |
| 526 | } | 518 | } |
| 527 | 519 | ||
| 528 | while ((f = fopen(cf, "r")) == NULL) { | 520 | while ((f = fopen(filename, "r")) == NULL) { |
| 529 | if (flag == SUBDIR_PARSE || flag == FIND_FROM_HTTPD_ROOT) { | 521 | if (flag == SUBDIR_PARSE || flag == FIND_FROM_HTTPD_ROOT) { |
| 530 | /* config file not found, no changes to config */ | 522 | /* config file not found, no changes to config */ |
| 531 | return; | 523 | return; |
| 532 | } | 524 | } |
| 533 | if (configFile && flag == FIRST_PARSE) /* if -c option given */ | 525 | if (configFile && flag == FIRST_PARSE) /* if -c option given */ |
| 534 | bb_simple_perror_msg_and_die(cf); | 526 | bb_simple_perror_msg_and_die(filename); |
| 535 | flag = FIND_FROM_HTTPD_ROOT; | 527 | flag = FIND_FROM_HTTPD_ROOT; |
| 536 | cf = httpd_conf; | 528 | filename = httpd_conf; |
| 537 | } | 529 | } |
| 538 | 530 | ||
| 539 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 531 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
| @@ -541,58 +533,53 @@ static void parse_conf(const char *path, int flag) | |||
| 541 | #endif | 533 | #endif |
| 542 | /* This could stand some work */ | 534 | /* This could stand some work */ |
| 543 | while ((p0 = fgets(buf, sizeof(buf), f)) != NULL) { | 535 | while ((p0 = fgets(buf, sizeof(buf), f)) != NULL) { |
| 544 | c = NULL; | 536 | after_colon = NULL; |
| 545 | for (p = p0; *p0 != '\0' && *p0 != '#'; p0++) { | 537 | for (p = p0; *p0 != '\0' && *p0 != '#'; p0++) { |
| 546 | if (!isspace(*p0)) { | 538 | if (!isspace(*p0)) { |
| 547 | *p++ = *p0; | 539 | *p++ = *p0; |
| 548 | if (*p0 == ':' && c == NULL) | 540 | if (*p0 == ':' && after_colon == NULL) |
| 549 | c = p; | 541 | after_colon = p; |
| 550 | } | 542 | } |
| 551 | } | 543 | } |
| 552 | *p = '\0'; | 544 | *p = '\0'; |
| 553 | 545 | ||
| 554 | /* test for empty or strange line */ | 546 | /* test for empty or strange line */ |
| 555 | if (c == NULL || *c == '\0') | 547 | if (after_colon == NULL || *after_colon == '\0') |
| 556 | continue; | 548 | continue; |
| 557 | p0 = buf; | 549 | p0 = buf; |
| 558 | if (*p0 == 'd') | 550 | if (*p0 == 'd' || *p0 == 'a') |
| 559 | *p0 = 'D'; | 551 | *p0 -= 0x20; /* a/d -> A/D */ |
| 560 | if (*c == '*') { | 552 | if (*after_colon == '*') { |
| 561 | if (*p0 == 'D') { | 553 | if (*p0 == 'D') { |
| 562 | /* memorize deny all */ | 554 | /* memorize "deny all" */ |
| 563 | flg_deny_all = 1; | 555 | flg_deny_all = 1; |
| 564 | } | 556 | } |
| 565 | /* skip default other "word:*" config lines */ | 557 | /* skip assumed "A:*", it is a default anyway */ |
| 566 | continue; | 558 | continue; |
| 567 | } | 559 | } |
| 568 | 560 | ||
| 569 | if (*p0 == 'a') | ||
| 570 | *p0 = 'A'; | ||
| 571 | if (*p0 == 'A' || *p0 == 'D') { | 561 | if (*p0 == 'A' || *p0 == 'D') { |
| 572 | /* storing current config IP line */ | 562 | /* storing current config IP line */ |
| 573 | pip = xzalloc(sizeof(Htaccess_IP)); | 563 | pip = xzalloc(sizeof(Htaccess_IP)); |
| 574 | if (pip) { | 564 | if (scan_ip_mask(after_colon, &(pip->ip), &(pip->mask))) { |
| 575 | if (scan_ip_mask(c, &(pip->ip), &(pip->mask))) { | 565 | /* IP{/mask} syntax error detected, protect all */ |
| 576 | /* syntax IP{/mask} error detected, protect all */ | 566 | *p0 = 'D'; |
| 577 | *p0 = 'D'; | 567 | pip->mask = 0; |
| 578 | pip->mask = 0; | 568 | } |
| 579 | } | 569 | pip->allow_deny = *p0; |
| 580 | pip->allow_deny = *p0; | 570 | if (*p0 == 'D') { |
| 581 | if (*p0 == 'D') { | 571 | /* Deny:from_IP - prepend */ |
| 582 | /* Deny:from_IP move top */ | 572 | pip->next = ip_a_d; |
| 583 | pip->next = ip_a_d; | 573 | ip_a_d = pip; |
| 574 | } else { | ||
| 575 | /* A:from_IP - append (thus D precedes A) */ | ||
| 576 | Htaccess_IP *prev_IP = ip_a_d; | ||
| 577 | if (prev_IP == NULL) { | ||
| 584 | ip_a_d = pip; | 578 | ip_a_d = pip; |
| 585 | } else { | 579 | } else { |
| 586 | /* add to bottom A:form_IP config line */ | 580 | while (prev_IP->next) |
| 587 | Htaccess_IP *prev_IP = ip_a_d; | 581 | prev_IP = prev_IP->next; |
| 588 | 582 | prev_IP->next = pip; | |
| 589 | if (prev_IP == NULL) { | ||
| 590 | ip_a_d = pip; | ||
| 591 | } else { | ||
| 592 | while (prev_IP->next) | ||
| 593 | prev_IP = prev_IP->next; | ||
| 594 | prev_IP->next = pip; | ||
| 595 | } | ||
| 596 | } | 583 | } |
| 597 | } | 584 | } |
| 598 | continue; | 585 | continue; |
| @@ -601,24 +588,18 @@ static void parse_conf(const char *path, int flag) | |||
| 601 | #if ENABLE_FEATURE_HTTPD_ERROR_PAGES | 588 | #if ENABLE_FEATURE_HTTPD_ERROR_PAGES |
| 602 | if (flag == FIRST_PARSE && *p0 == 'E') { | 589 | if (flag == FIRST_PARSE && *p0 == 'E') { |
| 603 | unsigned i; | 590 | unsigned i; |
| 604 | /* error status code */ | 591 | int status = atoi(++p0); /* error status code */ |
| 605 | int status = atoi(++p0); | ||
| 606 | /* c already points at the character following ':' in parse loop */ | ||
| 607 | /* c = strchr(p0, ':'); c++; */ | ||
| 608 | if (status < HTTP_CONTINUE) { | 592 | if (status < HTTP_CONTINUE) { |
| 609 | bb_error_msg("config error '%s' in '%s'", buf, cf); | 593 | bb_error_msg("config error '%s' in '%s'", buf, filename); |
| 610 | continue; | 594 | continue; |
| 611 | } | 595 | } |
| 612 | |||
| 613 | /* then error page; find matching status */ | 596 | /* then error page; find matching status */ |
| 614 | for (i = 0; i < ARRAY_SIZE(http_response_type); i++) { | 597 | for (i = 0; i < ARRAY_SIZE(http_response_type); i++) { |
| 615 | if (http_response_type[i] == status) { | 598 | if (http_response_type[i] == status) { |
| 616 | // We chdir to home_httpd, thus no need to | 599 | /* We chdir to home_httpd, thus no need to |
| 617 | // concat_path_file(home_httpd, c) | 600 | * concat_path_file(home_httpd, after_colon) |
| 618 | //if (c[0] == '/' || home_httpd[0] != '/') | 601 | * here */ |
| 619 | http_error_page[i] = xstrdup(c); | 602 | http_error_page[i] = xstrdup(after_colon); |
| 620 | //else | ||
| 621 | // http_error_page[i] = concat_path_file(home_httpd, c); | ||
| 622 | break; | 603 | break; |
| 623 | } | 604 | } |
| 624 | } | 605 | } |
| @@ -632,22 +613,22 @@ static void parse_conf(const char *path, int flag) | |||
| 632 | char *url_from, *host_port, *url_to; | 613 | char *url_from, *host_port, *url_to; |
| 633 | Htaccess_Proxy *proxy_entry; | 614 | Htaccess_Proxy *proxy_entry; |
| 634 | 615 | ||
| 635 | url_from = c; | 616 | url_from = after_colon; |
| 636 | host_port = strchr(c, ':'); | 617 | host_port = strchr(after_colon, ':'); |
| 637 | if (host_port == NULL) { | 618 | if (host_port == NULL) { |
| 638 | bb_error_msg("config error '%s' in '%s'", buf, cf); | 619 | bb_error_msg("config error '%s' in '%s'", buf, filename); |
| 639 | continue; | 620 | continue; |
| 640 | } | 621 | } |
| 641 | *host_port++ = '\0'; | 622 | *host_port++ = '\0'; |
| 642 | if (strncmp(host_port, "http://", 7) == 0) | 623 | if (strncmp(host_port, "http://", 7) == 0) |
| 643 | host_port += 7; | 624 | host_port += 7; |
| 644 | if (*host_port == '\0') { | 625 | if (*host_port == '\0') { |
| 645 | bb_error_msg("config error '%s' in '%s'", buf, cf); | 626 | bb_error_msg("config error '%s' in '%s'", buf, filename); |
| 646 | continue; | 627 | continue; |
| 647 | } | 628 | } |
| 648 | url_to = strchr(host_port, '/'); | 629 | url_to = strchr(host_port, '/'); |
| 649 | if (url_to == NULL) { | 630 | if (url_to == NULL) { |
| 650 | bb_error_msg("config error '%s' in '%s'", buf, cf); | 631 | bb_error_msg("config error '%s' in '%s'", buf, filename); |
| 651 | continue; | 632 | continue; |
| 652 | } | 633 | } |
| 653 | *url_to = '\0'; | 634 | *url_to = '\0'; |
| @@ -665,45 +646,44 @@ static void parse_conf(const char *path, int flag) | |||
| 665 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 646 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
| 666 | if (*p0 == '/') { | 647 | if (*p0 == '/') { |
| 667 | /* make full path from httpd root / current_path / config_line_path */ | 648 | /* make full path from httpd root / current_path / config_line_path */ |
| 668 | cf = (flag == SUBDIR_PARSE ? path : ""); | 649 | const char *tp = (flag == SUBDIR_PARSE ? path : ""); |
| 669 | p0 = xmalloc(strlen(cf) + (c - buf) + 2 + strlen(c)); | 650 | p0 = xmalloc(strlen(tp) + (after_colon - buf) + 2 + strlen(after_colon)); |
| 670 | c[-1] = '\0'; | 651 | after_colon[-1] = '\0'; |
| 671 | sprintf(p0, "/%s%s", cf, buf); | 652 | sprintf(p0, "/%s%s", tp, buf); |
| 672 | |||
| 673 | /* another call bb_simplify_path */ | ||
| 674 | cf = p = p0; | ||
| 675 | 653 | ||
| 654 | /* looks like bb_simplify_path... */ | ||
| 655 | tp = p = p0; | ||
| 676 | do { | 656 | do { |
| 677 | if (*p == '/') { | 657 | if (*p == '/') { |
| 678 | if (*cf == '/') { /* skip duplicate (or initial) slash */ | 658 | if (*tp == '/') { /* skip duplicate (or initial) slash */ |
| 679 | continue; | 659 | continue; |
| 680 | } | 660 | } |
| 681 | if (*cf == '.') { | 661 | if (*tp == '.') { |
| 682 | if (cf[1] == '/' || cf[1] == '\0') { /* remove extra '.' */ | 662 | if (tp[1] == '/' || tp[1] == '\0') { /* remove extra '.' */ |
| 683 | continue; | 663 | continue; |
| 684 | } | 664 | } |
| 685 | if ((cf[1] == '.') && (cf[2] == '/' || cf[2] == '\0')) { | 665 | if ((tp[1] == '.') && (tp[2] == '/' || tp[2] == '\0')) { |
| 686 | ++cf; | 666 | ++tp; |
| 687 | if (p > p0) { | 667 | if (p > p0) { |
| 688 | while (*--p != '/') /* omit previous dir */; | 668 | while (*--p != '/') /* omit previous dir */ |
| 669 | continue; | ||
| 689 | } | 670 | } |
| 690 | continue; | 671 | continue; |
| 691 | } | 672 | } |
| 692 | } | 673 | } |
| 693 | } | 674 | } |
| 694 | *++p = *cf; | 675 | *++p = *tp; |
| 695 | } while (*++cf); | 676 | } while (*++tp); |
| 696 | 677 | ||
| 697 | if ((p == p0) || (*p != '/')) { /* not a trailing slash */ | 678 | if ((p == p0) || (*p != '/')) { /* not a trailing slash */ |
| 698 | ++p; /* so keep last character */ | 679 | ++p; /* so keep last character */ |
| 699 | } | 680 | } |
| 700 | *p = ':'; | 681 | *p = ':'; |
| 701 | strcpy(p + 1, c); | 682 | strcpy(p + 1, after_colon); |
| 702 | } | 683 | } |
| 703 | #endif | 684 | #endif |
| 704 | |||
| 705 | if (*p0 == 'I') { | 685 | if (*p0 == 'I') { |
| 706 | index_page = xstrdup(c); | 686 | index_page = xstrdup(after_colon); |
| 707 | continue; | 687 | continue; |
| 708 | } | 688 | } |
| 709 | 689 | ||
| @@ -712,38 +692,39 @@ static void parse_conf(const char *path, int flag) | |||
| 712 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 692 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
| 713 | /* storing current config line */ | 693 | /* storing current config line */ |
| 714 | cur = xzalloc(sizeof(Htaccess) + strlen(p0)); | 694 | cur = xzalloc(sizeof(Htaccess) + strlen(p0)); |
| 715 | cf = strcpy(cur->before_colon, p0); | 695 | strcpy(cur->before_colon, p0); |
| 716 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 696 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
| 717 | if (*p0 == '/') | 697 | if (*p0 == '/') /* was malloced - see above */ |
| 718 | free(p0); | 698 | free(p0); |
| 719 | #endif | 699 | #endif |
| 720 | c = strchr(cf, ':'); | 700 | cur->after_colon = strchr(cur->before_colon, ':'); |
| 721 | *c++ = '\0'; | 701 | *cur->after_colon++ = '\0'; |
| 722 | cur->after_colon = c; | ||
| 723 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES | 702 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES |
| 724 | if (*cf == '.') { | 703 | if (cur->before_colon[0] == '.') { |
| 725 | /* config .mime line move top for overwrite previous */ | 704 | /* .mime line: prepend to mime_a list */ |
| 726 | cur->next = mime_a; | 705 | cur->next = mime_a; |
| 727 | mime_a = cur; | 706 | mime_a = cur; |
| 728 | continue; | 707 | continue; |
| 729 | } | 708 | } |
| 730 | #endif | 709 | #endif |
| 731 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 710 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
| 732 | if (*cf == '*' && cf[1] == '.') { | 711 | if (cur->before_colon[0] == '*' && cur->before_colon[1] == '.') { |
| 733 | /* config script interpreter line move top for overwrite previous */ | 712 | /* script interpreter line: prepend to script_i list */ |
| 734 | cur->next = script_i; | 713 | cur->next = script_i; |
| 735 | script_i = cur; | 714 | script_i = cur; |
| 736 | continue; | 715 | continue; |
| 737 | } | 716 | } |
| 738 | #endif | 717 | #endif |
| 739 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 718 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
| 719 | //TODO: we do not test for leading "/"?? | ||
| 720 | //also, do we leak cur if BASIC_AUTH is off? | ||
| 740 | if (prev == NULL) { | 721 | if (prev == NULL) { |
| 741 | /* first line */ | 722 | /* first line */ |
| 742 | g_auth = prev = cur; | 723 | g_auth = prev = cur; |
| 743 | } else { | 724 | } else { |
| 744 | /* sort path, if current length eq or bigger then move up */ | 725 | /* sort path, if current length eq or bigger then move up */ |
| 745 | Htaccess *prev_hti = g_auth; | 726 | Htaccess *prev_hti = g_auth; |
| 746 | size_t l = strlen(cf); | 727 | size_t l = strlen(cur->before_colon); |
| 747 | Htaccess *hti; | 728 | Htaccess *hti; |
| 748 | 729 | ||
| 749 | for (hti = prev_hti; hti; hti = hti->next) { | 730 | for (hti = prev_hti; hti; hti = hti->next) { |
| @@ -1651,7 +1632,6 @@ static int checkPermIP(void) | |||
| 1651 | { | 1632 | { |
| 1652 | Htaccess_IP *cur; | 1633 | Htaccess_IP *cur; |
| 1653 | 1634 | ||
| 1654 | /* This could stand some work */ | ||
| 1655 | for (cur = ip_a_d; cur; cur = cur->next) { | 1635 | for (cur = ip_a_d; cur; cur = cur->next) { |
| 1656 | #if DEBUG | 1636 | #if DEBUG |
| 1657 | fprintf(stderr, | 1637 | fprintf(stderr, |
| @@ -1668,26 +1648,23 @@ static int checkPermIP(void) | |||
| 1668 | ); | 1648 | ); |
| 1669 | #endif | 1649 | #endif |
| 1670 | if ((rmt_ip & cur->mask) == cur->ip) | 1650 | if ((rmt_ip & cur->mask) == cur->ip) |
| 1671 | return cur->allow_deny == 'A'; /* Allow/Deny */ | 1651 | return (cur->allow_deny == 'A'); /* A -> 1 */ |
| 1672 | } | 1652 | } |
| 1673 | 1653 | ||
| 1674 | /* if unconfigured, return 1 - access from all */ | 1654 | return !flg_deny_all; /* depends on whether we saw "D:*" */ |
| 1675 | return !flg_deny_all; | ||
| 1676 | } | 1655 | } |
| 1677 | 1656 | ||
| 1678 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 1657 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
| 1679 | /* | 1658 | /* |
| 1680 | * Check the permission file for access password protected. | 1659 | * Config file entries are of the form "/<path>:<user>:<passwd>". |
| 1681 | * | 1660 | * If config file has no prefix match for path, access is allowed. |
| 1682 | * If config file isn't present, everything is allowed. | ||
| 1683 | * Entries are of the form you can see example from header source | ||
| 1684 | * | 1661 | * |
| 1685 | * path The file path. | 1662 | * path The file path |
| 1686 | * request User information to validate. | 1663 | * user_and_passwd "user:passwd" to validate |
| 1687 | * | 1664 | * |
| 1688 | * Returns 1 if request is OK. | 1665 | * Returns 1 if user_and_passwd is OK. |
| 1689 | */ | 1666 | */ |
| 1690 | static int checkPerm(const char *path, const char *request) | 1667 | static int check_user_passwd(const char *path, const char *request) |
| 1691 | { | 1668 | { |
| 1692 | Htaccess *cur; | 1669 | Htaccess *cur; |
| 1693 | const char *p; | 1670 | const char *p; |
| @@ -1786,7 +1763,6 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
| 1786 | char *urlcopy; | 1763 | char *urlcopy; |
| 1787 | char *urlp; | 1764 | char *urlp; |
| 1788 | char *tptr; | 1765 | char *tptr; |
| 1789 | int ip_allowed; | ||
| 1790 | #if ENABLE_FEATURE_HTTPD_CGI | 1766 | #if ENABLE_FEATURE_HTTPD_CGI |
| 1791 | static const char request_HEAD[] ALIGN1 = "HEAD"; | 1767 | static const char request_HEAD[] ALIGN1 = "HEAD"; |
| 1792 | const char *prequest; | 1768 | const char *prequest; |
| @@ -1797,6 +1773,10 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
| 1797 | #define prequest request_GET | 1773 | #define prequest request_GET |
| 1798 | unsigned long length = 0; | 1774 | unsigned long length = 0; |
| 1799 | #endif | 1775 | #endif |
| 1776 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | ||
| 1777 | smallint authorized = -1; | ||
| 1778 | #endif | ||
| 1779 | smallint ip_allowed; | ||
| 1800 | char http_major_version; | 1780 | char http_major_version; |
| 1801 | #if ENABLE_FEATURE_HTTPD_PROXY | 1781 | #if ENABLE_FEATURE_HTTPD_PROXY |
| 1802 | char http_minor_version; | 1782 | char http_minor_version; |
| @@ -1804,9 +1784,6 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
| 1804 | char *header_ptr = header_ptr; | 1784 | char *header_ptr = header_ptr; |
| 1805 | Htaccess_Proxy *proxy_entry; | 1785 | Htaccess_Proxy *proxy_entry; |
| 1806 | #endif | 1786 | #endif |
| 1807 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | ||
| 1808 | int credentials = -1; /* if not required this is Ok */ | ||
| 1809 | #endif | ||
| 1810 | 1787 | ||
| 1811 | /* Allocation of iobuf is postponed until now | 1788 | /* Allocation of iobuf is postponed until now |
| 1812 | * (IOW, server process doesn't need to waste 8k) */ | 1789 | * (IOW, server process doesn't need to waste 8k) */ |
| @@ -1946,7 +1923,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
| 1946 | /* have path1/path2 */ | 1923 | /* have path1/path2 */ |
| 1947 | *tptr = '\0'; | 1924 | *tptr = '\0'; |
| 1948 | if (is_directory(urlcopy + 1, 1, &sb)) { | 1925 | if (is_directory(urlcopy + 1, 1, &sb)) { |
| 1949 | /* may be having subdir config */ | 1926 | /* may have subdir config */ |
| 1950 | parse_conf(urlcopy + 1, SUBDIR_PARSE); | 1927 | parse_conf(urlcopy + 1, SUBDIR_PARSE); |
| 1951 | ip_allowed = checkPermIP(); | 1928 | ip_allowed = checkPermIP(); |
| 1952 | } | 1929 | } |
| @@ -2019,8 +1996,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
| 2019 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 1996 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
| 2020 | if (STRNCASECMP(iobuf, "Authorization:") == 0) { | 1997 | if (STRNCASECMP(iobuf, "Authorization:") == 0) { |
| 2021 | /* We only allow Basic credentials. | 1998 | /* We only allow Basic credentials. |
| 2022 | * It shows up as "Authorization: Basic <userid:password>" where | 1999 | * It shows up as "Authorization: Basic <user>:<passwd>" where |
| 2023 | * the userid:password is base64 encoded. | 2000 | * "<user>:<passwd>" is base64 encoded. |
| 2024 | */ | 2001 | */ |
| 2025 | tptr = skip_whitespace(iobuf + sizeof("Authorization:")-1); | 2002 | tptr = skip_whitespace(iobuf + sizeof("Authorization:")-1); |
| 2026 | if (STRNCASECMP(tptr, "Basic") != 0) | 2003 | if (STRNCASECMP(tptr, "Basic") != 0) |
| @@ -2028,9 +2005,9 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
| 2028 | tptr += sizeof("Basic")-1; | 2005 | tptr += sizeof("Basic")-1; |
| 2029 | /* decodeBase64() skips whitespace itself */ | 2006 | /* decodeBase64() skips whitespace itself */ |
| 2030 | decodeBase64(tptr); | 2007 | decodeBase64(tptr); |
| 2031 | credentials = checkPerm(urlcopy, tptr); | 2008 | authorized = check_user_passwd(urlcopy, tptr); |
| 2032 | } | 2009 | } |
| 2033 | #endif /* FEATURE_HTTPD_BASIC_AUTH */ | 2010 | #endif |
| 2034 | #if ENABLE_FEATURE_HTTPD_RANGES | 2011 | #if ENABLE_FEATURE_HTTPD_RANGES |
| 2035 | if (STRNCASECMP(iobuf, "Range:") == 0) { | 2012 | if (STRNCASECMP(iobuf, "Range:") == 0) { |
| 2036 | /* We know only bytes=NNN-[MMM] */ | 2013 | /* We know only bytes=NNN-[MMM] */ |
| @@ -2054,13 +2031,15 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
| 2054 | /* We are done reading headers, disable peer timeout */ | 2031 | /* We are done reading headers, disable peer timeout */ |
| 2055 | alarm(0); | 2032 | alarm(0); |
| 2056 | 2033 | ||
| 2057 | if (strcmp(bb_basename(urlcopy), httpd_conf) == 0 || ip_allowed == 0) { | 2034 | if (strcmp(bb_basename(urlcopy), httpd_conf) == 0 || !ip_allowed) { |
| 2058 | /* protect listing [/path]/httpd_conf or IP deny */ | 2035 | /* protect listing [/path]/httpd_conf or IP deny */ |
| 2059 | send_headers_and_exit(HTTP_FORBIDDEN); | 2036 | send_headers_and_exit(HTTP_FORBIDDEN); |
| 2060 | } | 2037 | } |
| 2061 | 2038 | ||
| 2062 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 2039 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
| 2063 | if (credentials <= 0 && checkPerm(urlcopy, ":") == 0) { | 2040 | /* Case: no "Authorization:" was seen, but page does require passwd. |
| 2041 | * Check that with dummy user:pass */ | ||
| 2042 | if ((authorized <= 0) && check_user_passwd(urlcopy, ":") == 0) { | ||
| 2064 | send_headers_and_exit(HTTP_UNAUTHORIZED); | 2043 | send_headers_and_exit(HTTP_UNAUTHORIZED); |
| 2065 | } | 2044 | } |
| 2066 | #endif | 2045 | #endif |
