aboutsummaryrefslogtreecommitdiff
path: root/networking/wget.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2015-10-13 14:45:51 +0100
committerRon Yorston <rmy@pobox.com>2015-10-13 14:45:51 +0100
commit8e509f11bceeec419abc718300bef7422d1fee4c (patch)
treefdfbc752ad94102e3613a5d7254f14a93eaf7f56 /networking/wget.c
parent420f5edfe7676fe6e7cddbbf15c04649d096e422 (diff)
parent4d0c1ea4784c9844f8468d97ca5c26d3c70f9921 (diff)
downloadbusybox-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.c159
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};
60static const char P_FTP[] = "ftp"; 148static const char P_FTP[] = "ftp";
61static const char P_HTTP[] = "http"; 149static const char P_HTTP[] = "http";
150#if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER
62static const char P_HTTPS[] = "https"; 151static 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
532static int spawn_https_helper(const char *host, unsigned port) 622static 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 684static void spawn_https_helper_small(int network_fd)
586#if SSL_HELPER
587static 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) {