aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-03-15 10:32:23 +0000
committerRon Yorston <rmy@pobox.com>2018-03-15 10:39:20 +0000
commit7cc082e2370da69c8783812c251190d316ce82b3 (patch)
tree8a6224f8dd28fb1ffd3e6ef111efcc8b82f429b8
parentf011d7284d8cabe5d453b43d4df44d0423db22c8 (diff)
downloadbusybox-w32-7cc082e2370da69c8783812c251190d316ce82b3.tar.gz
busybox-w32-7cc082e2370da69c8783812c251190d316ce82b3.tar.bz2
busybox-w32-7cc082e2370da69c8783812c251190d316ce82b3.zip
wget: add support for https
Allow wget to support https URLs. Changes are: - Add mingw_popen2 which uses a named pipe to allow bidirectional communication with a child process; - Modify ssl_client to accept a WIN32 handle instead of a file descriptor as an argument; - Allow tls_get_random to open /dev/urandom; - Using the above changes implement a WIN32 version of spawn_ssl_client in wget. This closes GitHub issue #75. Also, enable authentication in wget.
-rw-r--r--configs/mingw32_defconfig11
-rw-r--r--configs/mingw64_defconfig11
-rw-r--r--include/mingw.h1
-rw-r--r--networking/ssl_client.c23
-rw-r--r--networking/tls.c6
-rw-r--r--networking/wget.c27
-rw-r--r--win32/popen.c103
7 files changed, 171 insertions, 11 deletions
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig
index c143d9f0c..8128764a8 100644
--- a/configs/mingw32_defconfig
+++ b/configs/mingw32_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.29.0.git 3# Busybox version: 1.29.0.git
4# Wed Feb 7 15:11:44 2018 4# Thu Mar 15 10:05:34 2018
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7# CONFIG_PLATFORM_POSIX is not set 7# CONFIG_PLATFORM_POSIX is not set
@@ -478,6 +478,7 @@ CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE=y
478# CONFIG_HALT is not set 478# CONFIG_HALT is not set
479# CONFIG_POWEROFF is not set 479# CONFIG_POWEROFF is not set
480# CONFIG_REBOOT is not set 480# CONFIG_REBOOT is not set
481# CONFIG_FEATURE_WAIT_FOR_INIT is not set
481# CONFIG_FEATURE_CALL_TELINIT is not set 482# CONFIG_FEATURE_CALL_TELINIT is not set
482CONFIG_TELINIT_PATH="" 483CONFIG_TELINIT_PATH=""
483# CONFIG_INIT is not set 484# CONFIG_INIT is not set
@@ -904,7 +905,7 @@ CONFIG_NC_SERVER=y
904# CONFIG_PSCAN is not set 905# CONFIG_PSCAN is not set
905# CONFIG_ROUTE is not set 906# CONFIG_ROUTE is not set
906# CONFIG_SLATTACH is not set 907# CONFIG_SLATTACH is not set
907# CONFIG_SSL_CLIENT is not set 908CONFIG_SSL_CLIENT=y
908# CONFIG_TC is not set 909# CONFIG_TC is not set
909# CONFIG_FEATURE_TC_INGRESS is not set 910# CONFIG_FEATURE_TC_INGRESS is not set
910# CONFIG_TCPSVD is not set 911# CONFIG_TCPSVD is not set
@@ -923,7 +924,7 @@ CONFIG_NC_SERVER=y
923# CONFIG_FEATURE_TFTP_PUT is not set 924# CONFIG_FEATURE_TFTP_PUT is not set
924# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set 925# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
925# CONFIG_TFTP_DEBUG is not set 926# CONFIG_TFTP_DEBUG is not set
926# CONFIG_TLS is not set 927CONFIG_TLS=y
927# CONFIG_TRACEROUTE is not set 928# CONFIG_TRACEROUTE is not set
928# CONFIG_TRACEROUTE6 is not set 929# CONFIG_TRACEROUTE6 is not set
929# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set 930# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
@@ -934,9 +935,9 @@ CONFIG_NC_SERVER=y
934CONFIG_WGET=y 935CONFIG_WGET=y
935CONFIG_FEATURE_WGET_LONG_OPTIONS=y 936CONFIG_FEATURE_WGET_LONG_OPTIONS=y
936# CONFIG_FEATURE_WGET_STATUSBAR is not set 937# CONFIG_FEATURE_WGET_STATUSBAR is not set
937# CONFIG_FEATURE_WGET_AUTHENTICATION is not set 938CONFIG_FEATURE_WGET_AUTHENTICATION=y
938# CONFIG_FEATURE_WGET_TIMEOUT is not set 939# CONFIG_FEATURE_WGET_TIMEOUT is not set
939# CONFIG_FEATURE_WGET_HTTPS is not set 940CONFIG_FEATURE_WGET_HTTPS=y
940# CONFIG_FEATURE_WGET_OPENSSL is not set 941# CONFIG_FEATURE_WGET_OPENSSL is not set
941CONFIG_WHOIS=y 942CONFIG_WHOIS=y
942# CONFIG_ZCIP is not set 943# CONFIG_ZCIP is not set
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig
index 9427f7b5b..d96dc4540 100644
--- a/configs/mingw64_defconfig
+++ b/configs/mingw64_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.29.0.git 3# Busybox version: 1.29.0.git
4# Wed Feb 7 15:18:49 2018 4# Thu Mar 15 10:21:09 2018
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7# CONFIG_PLATFORM_POSIX is not set 7# CONFIG_PLATFORM_POSIX is not set
@@ -478,6 +478,7 @@ CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE=y
478# CONFIG_HALT is not set 478# CONFIG_HALT is not set
479# CONFIG_POWEROFF is not set 479# CONFIG_POWEROFF is not set
480# CONFIG_REBOOT is not set 480# CONFIG_REBOOT is not set
481# CONFIG_FEATURE_WAIT_FOR_INIT is not set
481# CONFIG_FEATURE_CALL_TELINIT is not set 482# CONFIG_FEATURE_CALL_TELINIT is not set
482CONFIG_TELINIT_PATH="" 483CONFIG_TELINIT_PATH=""
483# CONFIG_INIT is not set 484# CONFIG_INIT is not set
@@ -904,7 +905,7 @@ CONFIG_NC_SERVER=y
904# CONFIG_PSCAN is not set 905# CONFIG_PSCAN is not set
905# CONFIG_ROUTE is not set 906# CONFIG_ROUTE is not set
906# CONFIG_SLATTACH is not set 907# CONFIG_SLATTACH is not set
907# CONFIG_SSL_CLIENT is not set 908CONFIG_SSL_CLIENT=y
908# CONFIG_TC is not set 909# CONFIG_TC is not set
909# CONFIG_FEATURE_TC_INGRESS is not set 910# CONFIG_FEATURE_TC_INGRESS is not set
910# CONFIG_TCPSVD is not set 911# CONFIG_TCPSVD is not set
@@ -923,7 +924,7 @@ CONFIG_NC_SERVER=y
923# CONFIG_FEATURE_TFTP_PUT is not set 924# CONFIG_FEATURE_TFTP_PUT is not set
924# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set 925# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
925# CONFIG_TFTP_DEBUG is not set 926# CONFIG_TFTP_DEBUG is not set
926# CONFIG_TLS is not set 927CONFIG_TLS=y
927# CONFIG_TRACEROUTE is not set 928# CONFIG_TRACEROUTE is not set
928# CONFIG_TRACEROUTE6 is not set 929# CONFIG_TRACEROUTE6 is not set
929# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set 930# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
@@ -934,9 +935,9 @@ CONFIG_NC_SERVER=y
934CONFIG_WGET=y 935CONFIG_WGET=y
935CONFIG_FEATURE_WGET_LONG_OPTIONS=y 936CONFIG_FEATURE_WGET_LONG_OPTIONS=y
936# CONFIG_FEATURE_WGET_STATUSBAR is not set 937# CONFIG_FEATURE_WGET_STATUSBAR is not set
937# CONFIG_FEATURE_WGET_AUTHENTICATION is not set 938CONFIG_FEATURE_WGET_AUTHENTICATION=y
938# CONFIG_FEATURE_WGET_TIMEOUT is not set 939# CONFIG_FEATURE_WGET_TIMEOUT is not set
939# CONFIG_FEATURE_WGET_HTTPS is not set 940CONFIG_FEATURE_WGET_HTTPS=y
940# CONFIG_FEATURE_WGET_OPENSSL is not set 941# CONFIG_FEATURE_WGET_OPENSSL is not set
941CONFIG_WHOIS=y 942CONFIG_WHOIS=y
942# CONFIG_ZCIP is not set 943# CONFIG_ZCIP is not set
diff --git a/include/mingw.h b/include/mingw.h
index 386540b37..e56e8f03d 100644
--- a/include/mingw.h
+++ b/include/mingw.h
@@ -111,6 +111,7 @@ int mingw_rename(const char*, const char*);
111 111
112FILE *mingw_popen(const char *cmd, const char *mode); 112FILE *mingw_popen(const char *cmd, const char *mode);
113int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid); 113int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid);
114int mingw_popen2(const char *cmd, pid_t *pid);
114int mingw_pclose(FILE *fd); 115int mingw_pclose(FILE *fd);
115#undef popen 116#undef popen
116#undef pclose 117#undef pclose
diff --git a/networking/ssl_client.c b/networking/ssl_client.c
index eb84e7726..e56d82fc1 100644
--- a/networking/ssl_client.c
+++ b/networking/ssl_client.c
@@ -15,7 +15,12 @@
15//kbuild:lib-$(CONFIG_SSL_CLIENT) += ssl_client.o 15//kbuild:lib-$(CONFIG_SSL_CLIENT) += ssl_client.o
16 16
17//usage:#define ssl_client_trivial_usage 17//usage:#define ssl_client_trivial_usage
18//usage: IF_NOT_PLATFORM_MINGW32(
18//usage: "[-e] -s FD [-r FD] [-n SNI]" 19//usage: "[-e] -s FD [-r FD] [-n SNI]"
20//usage: )
21//usage: IF_PLATFORM_MINGW32(
22//usage: "[-e] -h handle [-n SNI]"
23//usage: )
19//usage:#define ssl_client_full_usage "" 24//usage:#define ssl_client_full_usage ""
20 25
21#include "libbb.h" 26#include "libbb.h"
@@ -26,15 +31,24 @@ int ssl_client_main(int argc UNUSED_PARAM, char **argv)
26 tls_state_t *tls; 31 tls_state_t *tls;
27 const char *sni = NULL; 32 const char *sni = NULL;
28 int opt; 33 int opt;
34#if ENABLE_PLATFORM_MINGW32
35 char *hstr = NULL;
36 HANDLE h;
37#endif
29 38
30 // INIT_G(); 39 // INIT_G();
31 40
32 tls = new_tls_state(); 41 tls = new_tls_state();
33 opt = getopt32(argv, "es:#r:#n:", &tls->ofd, &tls->ifd, &sni); 42#if !ENABLE_PLATFORM_MINGW32
43 opt = getopt32(argv, "es:+r:+n:", &tls->ofd, &tls->ifd, &sni);
44
34 if (!(opt & (1<<2))) { 45 if (!(opt & (1<<2))) {
35 /* -r N defaults to -s N */ 46 /* -r N defaults to -s N */
36 tls->ifd = tls->ofd; 47 tls->ifd = tls->ofd;
37 } 48 }
49#else
50 opt = getopt32(argv, "eh:n:", &hstr, &sni);
51#endif
38 52
39 if (!(opt & (3<<1))) { 53 if (!(opt & (3<<1))) {
40 if (!argv[1]) 54 if (!argv[1])
@@ -47,6 +61,13 @@ int ssl_client_main(int argc UNUSED_PARAM, char **argv)
47 sni = argv[1]; 61 sni = argv[1];
48 tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443); 62 tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443);
49 } 63 }
64#if ENABLE_PLATFORM_MINGW32
65 else {
66 if (!hstr || sscanf(hstr, "%p", &h) != 1)
67 bb_error_msg_and_die("invalid handle");
68 tls->ifd = tls->ofd = _open_osfhandle((intptr_t)h, _O_RDWR|_O_BINARY);
69 }
70#endif
50 71
51 tls_handshake(tls, sni); 72 tls_handshake(tls, sni);
52 73
diff --git a/networking/tls.c b/networking/tls.c
index 99722cfb4..ec5a56d57 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -289,8 +289,14 @@ static void dump_tls_record(const void *vp, int len)
289 289
290void tls_get_random(void *buf, unsigned len) 290void tls_get_random(void *buf, unsigned len)
291{ 291{
292#if !ENABLE_PLATFORM_MINGW32
292 if (len != open_read_close("/dev/urandom", buf, len)) 293 if (len != open_read_close("/dev/urandom", buf, len))
293 xfunc_die(); 294 xfunc_die();
295#else
296 int fd = mingw_open("/dev/urandom", O_RDONLY|O_SPECIAL);
297 if (fd < 0 || len != read_close(fd, buf, len))
298 xfunc_die();
299#endif
294} 300}
295 301
296/* Nondestructively see the current hash value */ 302/* Nondestructively see the current hash value */
diff --git a/networking/wget.c b/networking/wget.c
index 150bc8e12..776894dca 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -714,6 +714,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
714#endif 714#endif
715 715
716#if ENABLE_FEATURE_WGET_HTTPS 716#if ENABLE_FEATURE_WGET_HTTPS
717# if !ENABLE_PLATFORM_MINGW32
717static void spawn_ssl_client(const char *host, int network_fd, int flags) 718static void spawn_ssl_client(const char *host, int network_fd, int flags)
718{ 719{
719 int sp[2]; 720 int sp[2];
@@ -763,6 +764,32 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags)
763 close(sp[1]); 764 close(sp[1]);
764 xmove_fd(sp[0], network_fd); 765 xmove_fd(sp[0], network_fd);
765} 766}
767# else
768static void spawn_ssl_client(const char *host, int network_fd, int flags)
769{
770 int fd1;
771 pid_t pid;
772 char *servername, *p, *cmd;
773
774 servername = xstrdup(host);
775 p = strrchr(servername, ':');
776 if (p) *p = '\0';
777
778 fflush_all();
779
780 cmd = xasprintf("%s ssl_client -h %p -n %s%s", bb_busybox_exec_path,
781 (void *)_get_osfhandle(network_fd), servername,
782 flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? " -e" : "");
783
784 if ( (fd1=mingw_popen2(cmd, &pid)) == -1 ) {
785 bb_perror_msg_and_die("can't execute ssl_client");
786 }
787
788 free(cmd);
789 free(servername);
790 xmove_fd(fd1, network_fd);
791}
792# endif
766#endif 793#endif
767 794
768static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_sockaddr *lsa) 795static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_sockaddr *lsa)
diff --git a/win32/popen.c b/win32/popen.c
index 59f5ca9f0..c075e2144 100644
--- a/win32/popen.c
+++ b/win32/popen.c
@@ -288,6 +288,109 @@ finito:
288 return fd; 288 return fd;
289} 289}
290 290
291/*
292 * Open a bidirectional pipe to a command. The pid of the command is
293 * returned in the variable pid, which can be NULL.
294 */
295int mingw_popen2(const char *cmd, pid_t *pid)
296{
297 pipe_data *p;
298 char *name = NULL;
299 SECURITY_ATTRIBUTES sa;
300 STARTUPINFO siStartInfo;
301 int success;
302 int fd = -1;
303 const int ip = 1; /* index of parent end of pipe */
304 const int ic = 0; /* index of child end of pipe */
305
306 if ( cmd == NULL || *cmd == '\0' ) {
307 return -1;
308 }
309
310 /* find an unused pipe structure */
311 if ( (p=find_pipe()) == NULL ) {
312 return -1;
313 }
314
315 /* Create the pipe */
316 name = xasprintf("\\\\.\\pipe\\bb_pipe.%d.%d", getpid(), (int)(p-pipes));
317
318 sa.nLength = sizeof(sa); /* Length in bytes */
319 sa.bInheritHandle = 1; /* the child must inherit these handles */
320 sa.lpSecurityDescriptor = NULL;
321
322 p->pipe[ip] = CreateNamedPipe(name,
323 PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
324 PIPE_TYPE_BYTE|PIPE_WAIT,
325 1, 4096, 4096, 0, &sa);
326 if (p->pipe[ip] == INVALID_HANDLE_VALUE) {
327 goto finito;
328 }
329
330 /* Connect to the pipe */
331 p->pipe[ic] = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, &sa,
332 OPEN_EXISTING,
333 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
334 NULL);
335 if (p->pipe[ic] == INVALID_HANDLE_VALUE) {
336 goto finito;
337 }
338
339 /* Make the parent end of the pipe non-inheritable */
340 SetHandleInformation(p->pipe[ip], HANDLE_FLAG_INHERIT, 0);
341
342 /* Now create the child process */
343 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
344 siStartInfo.cb = sizeof(STARTUPINFO);
345 siStartInfo.wShowWindow = SW_HIDE;
346 siStartInfo.hStdInput = p->pipe[ic];
347 siStartInfo.hStdOutput = p->pipe[ic];
348 siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
349 siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
350
351 success = CreateProcess(NULL,
352 (LPTSTR)cmd, /* command line */
353 NULL, /* process security attributes */
354 NULL, /* primary thread security attributes */
355 TRUE, /* handles are inherited */
356 0, /* creation flags */
357 NULL, /* use parent's environment */
358 NULL, /* use parent's current directory */
359 &siStartInfo, /* STARTUPINFO pointer */
360 &p->piProcInfo); /* receives PROCESS_INFORMATION */
361
362 if ( !success ) {
363 goto finito;
364 }
365
366 /* close child end of pipe */
367 CloseHandle(p->pipe[ic]);
368 p->pipe[ic] = INVALID_HANDLE_VALUE;
369
370 fd = _open_osfhandle((intptr_t)p->pipe[ip], _O_RDWR|_O_BINARY);
371
372finito:
373 free(name);
374 if ( fd == -1 ) {
375 errno = err_win_to_posix(GetLastError());
376 if ( p->pipe[0] != INVALID_HANDLE_VALUE ) {
377 CloseHandle(p->pipe[0]);
378 }
379 if ( p->pipe[1] != INVALID_HANDLE_VALUE ) {
380 CloseHandle(p->pipe[1]);
381 }
382 }
383 else {
384 p->mode = 'r';
385 p->fd = fd;
386 if ( pid ) {
387 *pid = (pid_t)p->piProcInfo.dwProcessId;
388 }
389 }
390
391 return fd;
392}
393
291int mingw_pclose(FILE *fp) 394int mingw_pclose(FILE *fp)
292{ 395{
293 int i, ip, fd; 396 int i, ip, fd;