diff options
author | Ron Yorston <rmy@pobox.com> | 2015-10-13 14:45:51 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2015-10-13 14:45:51 +0100 |
commit | 8e509f11bceeec419abc718300bef7422d1fee4c (patch) | |
tree | fdfbc752ad94102e3613a5d7254f14a93eaf7f56 /networking/wget.c | |
parent | 420f5edfe7676fe6e7cddbbf15c04649d096e422 (diff) | |
parent | 4d0c1ea4784c9844f8468d97ca5c26d3c70f9921 (diff) | |
download | busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.tar.gz busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.tar.bz2 busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'networking/wget.c')
-rw-r--r-- | networking/wget.c | 159 |
1 files changed, 136 insertions, 23 deletions
diff --git a/networking/wget.c b/networking/wget.c index e09bd2368..0082ced39 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -9,6 +9,94 @@ | |||
9 | * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2. | 9 | * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | //config:config WGET | ||
13 | //config: bool "wget" | ||
14 | //config: default y | ||
15 | //config: help | ||
16 | //config: wget is a utility for non-interactive download of files from HTTP | ||
17 | //config: and FTP servers. | ||
18 | //config: | ||
19 | //config:config FEATURE_WGET_STATUSBAR | ||
20 | //config: bool "Enable a nifty process meter (+2k)" | ||
21 | //config: default y | ||
22 | //config: depends on WGET | ||
23 | //config: help | ||
24 | //config: Enable the transfer progress bar for wget transfers. | ||
25 | //config: | ||
26 | //config:config FEATURE_WGET_AUTHENTICATION | ||
27 | //config: bool "Enable HTTP authentication" | ||
28 | //config: default y | ||
29 | //config: depends on WGET | ||
30 | //config: help | ||
31 | //config: Support authenticated HTTP transfers. | ||
32 | //config: | ||
33 | //config:config FEATURE_WGET_LONG_OPTIONS | ||
34 | //config: bool "Enable long options" | ||
35 | //config: default y | ||
36 | //config: depends on WGET && LONG_OPTS | ||
37 | //config: help | ||
38 | //config: Support long options for the wget applet. | ||
39 | //config: | ||
40 | //config:config FEATURE_WGET_TIMEOUT | ||
41 | //config: bool "Enable timeout option -T SEC" | ||
42 | //config: default y | ||
43 | //config: depends on WGET | ||
44 | //config: help | ||
45 | //config: Supports network read and connect timeouts for wget, | ||
46 | //config: so that wget will give up and timeout, through the -T | ||
47 | //config: command line option. | ||
48 | //config: | ||
49 | //config: Currently only connect and network data read timeout are | ||
50 | //config: supported (i.e., timeout is not applied to the DNS query). When | ||
51 | //config: FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option | ||
52 | //config: will work in addition to -T. | ||
53 | //config: | ||
54 | //config:config FEATURE_WGET_OPENSSL | ||
55 | //config: bool "Try to connect to HTTPS using openssl" | ||
56 | //config: default y | ||
57 | //config: depends on WGET | ||
58 | //config: help | ||
59 | //config: Choose how wget establishes SSL connection for https:// URLs. | ||
60 | //config: | ||
61 | //config: Busybox itself contains no SSL code. wget will spawn | ||
62 | //config: a helper program to talk over HTTPS. | ||
63 | //config: | ||
64 | //config: OpenSSL has a simple SSL client for debug purposes. | ||
65 | //config: If you select "openssl" helper, wget will effectively call | ||
66 | //config: "openssl s_client -quiet -connect IP:443 2>/dev/null" | ||
67 | //config: and pipe its data through it. | ||
68 | //config: Note inconvenient API: host resolution is done twice, | ||
69 | //config: and there is no guarantee openssl's idea of IPv6 address | ||
70 | //config: format is the same as ours. | ||
71 | //config: Another problem is that s_client prints debug information | ||
72 | //config: to stderr, and it needs to be suppressed. This means | ||
73 | //config: all error messages get suppressed too. | ||
74 | //config: openssl is also a big binary, often dynamically linked | ||
75 | //config: against ~15 libraries. | ||
76 | //config: | ||
77 | //config:config FEATURE_WGET_SSL_HELPER | ||
78 | //config: bool "Try to connect to HTTPS using ssl_helper" | ||
79 | //config: default y | ||
80 | //config: depends on WGET | ||
81 | //config: help | ||
82 | //config: Choose how wget establishes SSL connection for https:// URLs. | ||
83 | //config: | ||
84 | //config: Busybox itself contains no SSL code. wget will spawn | ||
85 | //config: a helper program to talk over HTTPS. | ||
86 | //config: | ||
87 | //config: ssl_helper is a tool which can be built statically | ||
88 | //config: from busybox sources against a small embedded SSL library. | ||
89 | //config: Please see networking/ssl_helper/README. | ||
90 | //config: It does not require double host resolution and emits | ||
91 | //config: error messages to stderr. | ||
92 | //config: | ||
93 | //config: Precompiled static binary may be available at | ||
94 | //config: http://busybox.net/downloads/binaries/ | ||
95 | |||
96 | //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
97 | |||
98 | //kbuild:lib-$(CONFIG_WGET) += wget.o | ||
99 | |||
12 | //usage:#define wget_trivial_usage | 100 | //usage:#define wget_trivial_usage |
13 | //usage: IF_FEATURE_WGET_LONG_OPTIONS( | 101 | //usage: IF_FEATURE_WGET_LONG_OPTIONS( |
14 | //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" | 102 | //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" |
@@ -59,7 +147,9 @@ struct host_info { | |||
59 | }; | 147 | }; |
60 | static const char P_FTP[] = "ftp"; | 148 | static const char P_FTP[] = "ftp"; |
61 | static const char P_HTTP[] = "http"; | 149 | static const char P_HTTP[] = "http"; |
150 | #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER | ||
62 | static const char P_HTTPS[] = "https"; | 151 | static const char P_HTTPS[] = "https"; |
152 | #endif | ||
63 | 153 | ||
64 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS | 154 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS |
65 | /* User-specified headers prevent using our corresponding built-in headers. */ | 155 | /* User-specified headers prevent using our corresponding built-in headers. */ |
@@ -328,7 +418,7 @@ static void parse_url(const char *src_url, struct host_info *h) | |||
328 | if (strcmp(url, P_FTP) == 0) { | 418 | if (strcmp(url, P_FTP) == 0) { |
329 | h->port = bb_lookup_port(P_FTP, "tcp", 21); | 419 | h->port = bb_lookup_port(P_FTP, "tcp", 21); |
330 | } else | 420 | } else |
331 | #if !ENABLE_PLATFORM_MINGW32 | 421 | #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER |
332 | if (strcmp(url, P_HTTPS) == 0) { | 422 | if (strcmp(url, P_HTTPS) == 0) { |
333 | h->port = bb_lookup_port(P_HTTPS, "tcp", 443); | 423 | h->port = bb_lookup_port(P_HTTPS, "tcp", 443); |
334 | h->protocol = P_HTTPS; | 424 | h->protocol = P_HTTPS; |
@@ -528,12 +618,13 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ | |||
528 | return sfp; | 618 | return sfp; |
529 | } | 619 | } |
530 | 620 | ||
531 | #if !ENABLE_PLATFORM_MINGW32 | 621 | #if ENABLE_FEATURE_WGET_OPENSSL |
532 | static int spawn_https_helper(const char *host, unsigned port) | 622 | static int spawn_https_helper_openssl(const char *host, unsigned port) |
533 | { | 623 | { |
534 | char *allocated = NULL; | 624 | char *allocated = NULL; |
535 | int sp[2]; | 625 | int sp[2]; |
536 | int pid; | 626 | int pid; |
627 | IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) | ||
537 | 628 | ||
538 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) | 629 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) |
539 | /* Kernel can have AF_UNIX support disabled */ | 630 | /* Kernel can have AF_UNIX support disabled */ |
@@ -542,7 +633,8 @@ static int spawn_https_helper(const char *host, unsigned port) | |||
542 | if (!strchr(host, ':')) | 633 | if (!strchr(host, ':')) |
543 | host = allocated = xasprintf("%s:%u", host, port); | 634 | host = allocated = xasprintf("%s:%u", host, port); |
544 | 635 | ||
545 | pid = BB_MMU ? xfork() : xvfork(); | 636 | fflush_all(); |
637 | pid = xvfork(); | ||
546 | if (pid == 0) { | 638 | if (pid == 0) { |
547 | /* Child */ | 639 | /* Child */ |
548 | char *argv[6]; | 640 | char *argv[6]; |
@@ -551,10 +643,6 @@ static int spawn_https_helper(const char *host, unsigned port) | |||
551 | xmove_fd(sp[1], 0); | 643 | xmove_fd(sp[1], 0); |
552 | xdup2(0, 1); | 644 | xdup2(0, 1); |
553 | /* | 645 | /* |
554 | * TODO: develop a tiny ssl/tls helper (using matrixssl?), | ||
555 | * try to exec it here before falling back to big fat openssl. | ||
556 | */ | ||
557 | /* | ||
558 | * openssl s_client -quiet -connect www.kernel.org:443 2>/dev/null | 646 | * openssl s_client -quiet -connect www.kernel.org:443 2>/dev/null |
559 | * It prints some debug stuff on stderr, don't know how to suppress it. | 647 | * It prints some debug stuff on stderr, don't know how to suppress it. |
560 | * Work around by dev-nulling stderr. We lose all error messages :( | 648 | * Work around by dev-nulling stderr. We lose all error messages :( |
@@ -569,22 +657,31 @@ static int spawn_https_helper(const char *host, unsigned port) | |||
569 | argv[5] = NULL; | 657 | argv[5] = NULL; |
570 | BB_EXECVP(argv[0], argv); | 658 | BB_EXECVP(argv[0], argv); |
571 | xmove_fd(3, 2); | 659 | xmove_fd(3, 2); |
660 | # if ENABLE_FEATURE_WGET_SSL_HELPER | ||
661 | child_failed = 1; | ||
662 | xfunc_die(); | ||
663 | # else | ||
572 | bb_perror_msg_and_die("can't execute '%s'", argv[0]); | 664 | bb_perror_msg_and_die("can't execute '%s'", argv[0]); |
665 | # endif | ||
573 | /* notreached */ | 666 | /* notreached */ |
574 | } | 667 | } |
575 | 668 | ||
576 | /* Parent */ | 669 | /* Parent */ |
577 | free(allocated); | 670 | free(allocated); |
578 | close(sp[1]); | 671 | close(sp[1]); |
672 | # if ENABLE_FEATURE_WGET_SSL_HELPER | ||
673 | if (child_failed) { | ||
674 | close(sp[0]); | ||
675 | return -1; | ||
676 | } | ||
677 | # endif | ||
579 | return sp[0]; | 678 | return sp[0]; |
580 | } | 679 | } |
581 | #endif | 680 | #endif |
582 | 681 | ||
583 | /* See networking/ssl_helper/README */ | 682 | /* See networking/ssl_helper/README how to build one */ |
584 | #define SSL_HELPER 0 | 683 | #if ENABLE_FEATURE_WGET_SSL_HELPER |
585 | 684 | static void spawn_https_helper_small(int network_fd) | |
586 | #if SSL_HELPER | ||
587 | static void spawn_https_helper1(int network_fd) | ||
588 | { | 685 | { |
589 | int sp[2]; | 686 | int sp[2]; |
590 | int pid; | 687 | int pid; |
@@ -861,21 +958,37 @@ static void download_one_url(const char *url) | |||
861 | int status; | 958 | int status; |
862 | 959 | ||
863 | /* Open socket to http(s) server */ | 960 | /* Open socket to http(s) server */ |
864 | #if !ENABLE_PLATFORM_MINGW32 | 961 | #if ENABLE_FEATURE_WGET_OPENSSL |
962 | /* openssl (and maybe ssl_helper) support is configured */ | ||
865 | if (target.protocol == P_HTTPS) { | 963 | if (target.protocol == P_HTTPS) { |
866 | /* openssl-based helper | 964 | /* openssl-based helper |
867 | * Inconvenient API since we can't give it an open fd | 965 | * Inconvenient API since we can't give it an open fd |
868 | */ | 966 | */ |
869 | int fd = spawn_https_helper(server.host, server.port); | 967 | int fd = spawn_https_helper_openssl(server.host, server.port); |
968 | # if ENABLE_FEATURE_WGET_SSL_HELPER | ||
969 | if (fd < 0) { /* no openssl? try ssl_helper */ | ||
970 | sfp = open_socket(lsa); | ||
971 | spawn_https_helper_small(fileno(sfp)); | ||
972 | goto socket_opened; | ||
973 | } | ||
974 | # else | ||
975 | /* We don't check for exec("openssl") failure in this case */ | ||
976 | # endif | ||
870 | sfp = fdopen(fd, "r+"); | 977 | sfp = fdopen(fd, "r+"); |
871 | if (!sfp) | 978 | if (!sfp) |
872 | bb_perror_msg_and_die(bb_msg_memory_exhausted); | 979 | bb_perror_msg_and_die(bb_msg_memory_exhausted); |
873 | } else | 980 | goto socket_opened; |
874 | #endif | 981 | } |
875 | sfp = open_socket(lsa); | 982 | sfp = open_socket(lsa); |
876 | #if SSL_HELPER | 983 | socket_opened: |
984 | #elif ENABLE_FEATURE_WGET_SSL_HELPER | ||
985 | /* Only ssl_helper support is configured */ | ||
986 | sfp = open_socket(lsa); | ||
877 | if (target.protocol == P_HTTPS) | 987 | if (target.protocol == P_HTTPS) |
878 | spawn_https_helper1(fileno(sfp)); | 988 | spawn_https_helper_small(fileno(sfp)); |
989 | #else | ||
990 | /* ssl (https) support is not configured */ | ||
991 | sfp = open_socket(lsa); | ||
879 | #endif | 992 | #endif |
880 | /* Send HTTP request */ | 993 | /* Send HTTP request */ |
881 | if (use_proxy) { | 994 | if (use_proxy) { |