diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-07-25 21:34:57 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-07-25 21:34:57 +0200 |
commit | ed72761843945ff7efc5a8ba3095a0f82e8f3e45 (patch) | |
tree | 32fa40efe67ab5f6f800ae29c8636d42acd52bba | |
parent | 9d20297ba803832d118bd27cd42107371123aa39 (diff) | |
download | busybox-w32-ed72761843945ff7efc5a8ba3095a0f82e8f3e45.tar.gz busybox-w32-ed72761843945ff7efc5a8ba3095a0f82e8f3e45.tar.bz2 busybox-w32-ed72761843945ff7efc5a8ba3095a0f82e8f3e45.zip |
wget: run s_client helper with -servername HOST
This is necessary for multi-hosted TLSed web sites.
function old new delta
spawn_https_helper_openssl 334 441 +107
Based on a patch by Jeremy Chadwick <jdc@koitsu.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/wget.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/networking/wget.c b/networking/wget.c index 37950ed39..653d8076f 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -62,9 +62,10 @@ | |||
62 | //config: a helper program to talk over HTTPS. | 62 | //config: a helper program to talk over HTTPS. |
63 | //config: | 63 | //config: |
64 | //config: OpenSSL has a simple SSL client for debug purposes. | 64 | //config: OpenSSL has a simple SSL client for debug purposes. |
65 | //config: If you select "openssl" helper, wget will effectively call | 65 | //config: If you select "openssl" helper, wget will effectively run: |
66 | //config: "openssl s_client -quiet -connect IP:443 2>/dev/null" | 66 | //config: "openssl s_client -quiet -connect hostname:443 |
67 | //config: and pipe its data through it. | 67 | //config: -servername hostname 2>/dev/null" and pipe its data |
68 | //config: through it. -servername is not used if hostname is numeric. | ||
68 | //config: Note inconvenient API: host resolution is done twice, | 69 | //config: Note inconvenient API: host resolution is done twice, |
69 | //config: and there is no guarantee openssl's idea of IPv6 address | 70 | //config: and there is no guarantee openssl's idea of IPv6 address |
70 | //config: format is the same as ours. | 71 | //config: format is the same as ours. |
@@ -349,6 +350,30 @@ static void set_alarm(void) | |||
349 | # define clear_alarm() ((void)0) | 350 | # define clear_alarm() ((void)0) |
350 | #endif | 351 | #endif |
351 | 352 | ||
353 | #if ENABLE_FEATURE_WGET_OPENSSL | ||
354 | /* | ||
355 | * is_ip_address() attempts to verify whether or not a string | ||
356 | * contains an IPv4 or IPv6 address (vs. an FQDN). The result | ||
357 | * of inet_pton() can be used to determine this. | ||
358 | * | ||
359 | * TODO add proper error checking when inet_pton() returns -1 | ||
360 | * (some form of system error has occurred, and errno is set) | ||
361 | */ | ||
362 | static int is_ip_address(const char *string) | ||
363 | { | ||
364 | struct sockaddr_in sa; | ||
365 | |||
366 | int result = inet_pton(AF_INET, string, &(sa.sin_addr)); | ||
367 | # if ENABLE_FEATURE_IPV6 | ||
368 | if (result == 0) { | ||
369 | struct sockaddr_in6 sa6; | ||
370 | result = inet_pton(AF_INET6, string, &(sa6.sin6_addr)); | ||
371 | } | ||
372 | # endif | ||
373 | return (result == 1); | ||
374 | } | ||
375 | #endif | ||
376 | |||
352 | static FILE *open_socket(len_and_sockaddr *lsa) | 377 | static FILE *open_socket(len_and_sockaddr *lsa) |
353 | { | 378 | { |
354 | int fd; | 379 | int fd; |
@@ -629,6 +654,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ | |||
629 | static int spawn_https_helper_openssl(const char *host, unsigned port) | 654 | static int spawn_https_helper_openssl(const char *host, unsigned port) |
630 | { | 655 | { |
631 | char *allocated = NULL; | 656 | char *allocated = NULL; |
657 | char *servername; | ||
632 | int sp[2]; | 658 | int sp[2]; |
633 | int pid; | 659 | int pid; |
634 | IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) | 660 | IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) |
@@ -639,12 +665,14 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
639 | 665 | ||
640 | if (!strchr(host, ':')) | 666 | if (!strchr(host, ':')) |
641 | host = allocated = xasprintf("%s:%u", host, port); | 667 | host = allocated = xasprintf("%s:%u", host, port); |
668 | servername = xstrdup(host); | ||
669 | strrchr(servername, ':')[0] = '\0'; | ||
642 | 670 | ||
643 | fflush_all(); | 671 | fflush_all(); |
644 | pid = xvfork(); | 672 | pid = xvfork(); |
645 | if (pid == 0) { | 673 | if (pid == 0) { |
646 | /* Child */ | 674 | /* Child */ |
647 | char *argv[6]; | 675 | char *argv[8]; |
648 | 676 | ||
649 | close(sp[0]); | 677 | close(sp[0]); |
650 | xmove_fd(sp[1], 0); | 678 | xmove_fd(sp[1], 0); |
@@ -656,12 +684,22 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
656 | */ | 684 | */ |
657 | xmove_fd(2, 3); | 685 | xmove_fd(2, 3); |
658 | xopen("/dev/null", O_RDWR); | 686 | xopen("/dev/null", O_RDWR); |
687 | memset(&argv, 0, sizeof(argv)); | ||
659 | argv[0] = (char*)"openssl"; | 688 | argv[0] = (char*)"openssl"; |
660 | argv[1] = (char*)"s_client"; | 689 | argv[1] = (char*)"s_client"; |
661 | argv[2] = (char*)"-quiet"; | 690 | argv[2] = (char*)"-quiet"; |
662 | argv[3] = (char*)"-connect"; | 691 | argv[3] = (char*)"-connect"; |
663 | argv[4] = (char*)host; | 692 | argv[4] = (char*)host; |
664 | argv[5] = NULL; | 693 | /* |
694 | * Per RFC 6066 Section 3, the only permitted values in the | ||
695 | * TLS server_name (SNI) field are FQDNs (DNS hostnames). | ||
696 | * IPv4 and IPv6 addresses, port numbers are not allowed. | ||
697 | */ | ||
698 | if (!is_ip_address(servername)) { | ||
699 | argv[5] = (char*)"-servername"; | ||
700 | argv[6] = (char*)servername; | ||
701 | } | ||
702 | |||
665 | BB_EXECVP(argv[0], argv); | 703 | BB_EXECVP(argv[0], argv); |
666 | xmove_fd(3, 2); | 704 | xmove_fd(3, 2); |
667 | # if ENABLE_FEATURE_WGET_SSL_HELPER | 705 | # if ENABLE_FEATURE_WGET_SSL_HELPER |
@@ -674,6 +712,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
674 | } | 712 | } |
675 | 713 | ||
676 | /* Parent */ | 714 | /* Parent */ |
715 | free(servername); | ||
677 | free(allocated); | 716 | free(allocated); |
678 | close(sp[1]); | 717 | close(sp[1]); |
679 | # if ENABLE_FEATURE_WGET_SSL_HELPER | 718 | # if ENABLE_FEATURE_WGET_SSL_HELPER |