diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2018-05-30 09:52:20 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2018-05-30 10:44:48 +0000 |
commit | 1d0560a9b6b5597b191e5aff69a31c2fe0aba273 (patch) | |
tree | 23e808e7b123643b55e2eb07101b8467b429b975 /main/busybox | |
parent | 782065ccea8a1415f01f568f5bce411898f4d7fb (diff) | |
download | aports-1d0560a9b6b5597b191e5aff69a31c2fe0aba273.tar.bz2 aports-1d0560a9b6b5597b191e5aff69a31c2fe0aba273.tar.xz |
main/busybox: properly fix wget https support
fix busybox wget https support by using an external ssl_client helper
for https.
Disable the use of external openssl. This was fixed to check
certificates as a temporary solution. openssl can not produce any useful
error messages on certificate errors. It is big. So we simply disable
its use.
For dynamic busybox we disable the internal ssl_client and the internal
(broken) tls code, and build our own ssl_client which properly verifies
the certificates.
For the static busybox we enable the internal ssl_client and tls code,
but we only allow its use with --no-check-certificates. This is so we
still can fetch things from https in an emergency situation.
We auto-install ssl_client if both libssl and busybox are installed. This
is to keep backwards compatibility.
Diffstat (limited to 'main/busybox')
-rw-r--r-- | main/busybox/0001-wget-emit-a-message-that-certificate-verification-is.patch | 67 | ||||
-rw-r--r-- | main/busybox/0001-wget-print-warning-when-internal-tls-is-used.patch | 87 | ||||
-rw-r--r-- | main/busybox/0002-wget-verify-certificate-when-openssl-helper-is-used.patch | 71 | ||||
-rw-r--r-- | main/busybox/APKBUILD | 36 | ||||
-rw-r--r-- | main/busybox/busyboxconfig | 6 | ||||
-rw-r--r-- | main/busybox/external_ssl_client.patch | 52 | ||||
-rw-r--r-- | main/busybox/ssl_client.c | 158 |
7 files changed, 307 insertions, 170 deletions
diff --git a/main/busybox/0001-wget-emit-a-message-that-certificate-verification-is.patch b/main/busybox/0001-wget-emit-a-message-that-certificate-verification-is.patch new file mode 100644 index 0000000000..3780b039e2 --- /dev/null +++ b/main/busybox/0001-wget-emit-a-message-that-certificate-verification-is.patch @@ -0,0 +1,67 @@ +From 948090c675f8b60b74c7357fcafb1cc8c179e0a6 Mon Sep 17 00:00:00 2001 +From: Denys Vlasenko <vda.linux@googlemail.com> +Date: Mon, 28 May 2018 14:36:26 +0200 +Subject: [PATCH] wget: emit a message that certificate verification is not + implemented + +function old new delta +spawn_ssl_client 185 209 +24 + +Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> +--- + networking/wget.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/networking/wget.c b/networking/wget.c +index d1d85230c..cd92b3a28 100644 +--- a/networking/wget.c ++++ b/networking/wget.c +@@ -136,6 +136,7 @@ + //usage: "Retrieve files via HTTP or FTP\n" + //usage: IF_FEATURE_WGET_LONG_OPTIONS( + //usage: "\n --spider Only check URL existence: $? is 0 if exists" ++///////: "\n --no-check-certificate Don't validate the server's certificate" + //usage: ) + //usage: "\n -c Continue retrieval of aborted transfer" + //usage: "\n -q Quiet" +@@ -267,6 +268,7 @@ enum { + WGET_OPT_HEADER = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS, + WGET_OPT_POST_DATA = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS, + WGET_OPT_SPIDER = (1 << 12) * ENABLE_FEATURE_WGET_LONG_OPTIONS, ++ WGET_OPT_NO_CHECK_CERT = (1 << 13) * ENABLE_FEATURE_WGET_LONG_OPTIONS, + }; + + enum { +@@ -765,6 +767,9 @@ static void spawn_ssl_client(const char *host, int network_fd) + int pid; + char *servername, *p; + ++ if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT)) ++ bb_error_msg("note: TLS certificate validation not implemented"); ++ + servername = xstrdup(host); + p = strrchr(servername, ':'); + if (p) *p = '\0'; +@@ -1353,10 +1358,9 @@ IF_DESKTOP( "tries\0" Required_argument "t") + "header\0" Required_argument "\xff" + "post-data\0" Required_argument "\xfe" + "spider\0" No_argument "\xfd" ++ "no-check-certificate\0" No_argument "\xfc" + /* Ignored (we always use PASV): */ + IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") +- /* Ignored (we don't do ssl) */ +-IF_DESKTOP( "no-check-certificate\0" No_argument "\xf0") + /* Ignored (we don't support caching) */ + IF_DESKTOP( "no-cache\0" No_argument "\xf0") + IF_DESKTOP( "no-verbose\0" No_argument "\xf0") +@@ -1416,6 +1420,7 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") + if (option_mask32 & WGET_OPT_HEADER) bb_error_msg("--header"); + if (option_mask32 & WGET_OPT_POST_DATA) bb_error_msg("--post-data"); + if (option_mask32 & WGET_OPT_SPIDER) bb_error_msg("--spider"); ++ if (option_mask32 & WGET_OPT_NO_CHECK_CERT) bb_error_msg("--no-check-certificate"); + exit(0); + #endif + argv += optind; +-- +2.17.0 + diff --git a/main/busybox/0001-wget-print-warning-when-internal-tls-is-used.patch b/main/busybox/0001-wget-print-warning-when-internal-tls-is-used.patch deleted file mode 100644 index 5a027c1bf5..0000000000 --- a/main/busybox/0001-wget-print-warning-when-internal-tls-is-used.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 76026fa8c9a62423e359b992b16b6e0bbdd4e5a1 Mon Sep 17 00:00:00 2001 -From: Jakub Jirutka <jakub@jirutka.cz> -Date: Thu, 24 May 2018 02:19:23 +0200 -Subject: [PATCH] wget: print warning when internal TLS is used - -Internal TLS code (FEATURE_WGET_HTTPS) does not implement verification -of the server's certificate. It is documented in the code, but not -even mentioned in the --help message, so users typically don't know -about this behaviour. That's a crime against security! - -This patch changes this behaviour for the case when both -FEATURE_WGET_LONG_OPTIONS and FEATURE_WGET_HTTPS are enabled - -before initializing a TLS connection using the internal TLS code (i.e. -without certificate validation) warning message is printed, unless the -user specified option "--no-check-certificate". - -See-Also: http://lists.busybox.net/pipermail/busybox/2018-May/086444.html ---- - networking/wget.c | 30 +++++++++++++++++++----------- - 1 file changed, 19 insertions(+), 11 deletions(-) - -diff --git a/networking/wget.c b/networking/wget.c ---- a/networking/wget.c -+++ b/networking/wget.c -@@ -135,18 +135,21 @@ - //usage:#define wget_full_usage "\n\n" - //usage: "Retrieve files via HTTP or FTP\n" - //usage: IF_FEATURE_WGET_LONG_OPTIONS( --//usage: "\n --spider Only check URL existence: $? is 0 if exists" -+//usage: "\n --spider Only check URL existence: $? is 0 if exists" -+//usage: IF_FEATURE_WGET_HTTPS( -+//usage: "\n --no-check-certificate Don't validate the server's certificate" -+//usage: ) - //usage: ) --//usage: "\n -c Continue retrieval of aborted transfer" --//usage: "\n -q Quiet" --//usage: "\n -P DIR Save to DIR (default .)" --//usage: "\n -S Show server response" -+//usage: "\n -c Continue retrieval of aborted transfer" -+//usage: "\n -q Quiet" -+//usage: "\n -P DIR Save to DIR (default .)" -+//usage: "\n -S Show server response" - //usage: IF_FEATURE_WGET_TIMEOUT( --//usage: "\n -T SEC Network read timeout is SEC seconds" -+//usage: "\n -T SEC Network read timeout is SEC seconds" - //usage: ) --//usage: "\n -O FILE Save to FILE ('-' for stdout)" --//usage: "\n -U STR Use STR for User-Agent header" --//usage: "\n -Y on/off Use proxy" -+//usage: "\n -O FILE Save to FILE ('-' for stdout)" -+//usage: "\n -U STR Use STR for User-Agent header" -+//usage: "\n -Y on/off Use proxy" - - #include "libbb.h" - -@@ -267,6 +270,7 @@ - WGET_OPT_HEADER = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS, - WGET_OPT_POST_DATA = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS, - WGET_OPT_SPIDER = (1 << 12) * ENABLE_FEATURE_WGET_LONG_OPTIONS, -+ WGET_OPT_NO_CHECK_CERT = (1 << 13) * ENABLE_FEATURE_WGET_LONG_OPTIONS, - }; - - enum { -@@ -765,6 +769,11 @@ - int pid; - char *servername, *p; - -+#if ENABLE_FEATURE_WGET_LONG_OPTIONS -+ if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT)) -+ bb_error_msg("WARNING: SSL/TLS certificate is not being validated!"); -+#endif -+ - servername = xstrdup(host); - p = strrchr(servername, ':'); - if (p) *p = '\0'; -@@ -1353,10 +1362,9 @@ - "header\0" Required_argument "\xff" - "post-data\0" Required_argument "\xfe" - "spider\0" No_argument "\xfd" -+ "no-check-certificate\0" No_argument "\xfc" - /* Ignored (we always use PASV): */ - IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") -- /* Ignored (we don't do ssl) */ --IF_DESKTOP( "no-check-certificate\0" No_argument "\xf0") - /* Ignored (we don't support caching) */ - IF_DESKTOP( "no-cache\0" No_argument "\xf0") - IF_DESKTOP( "no-verbose\0" No_argument "\xf0") diff --git a/main/busybox/0002-wget-verify-certificate-when-openssl-helper-is-used.patch b/main/busybox/0002-wget-verify-certificate-when-openssl-helper-is-used.patch deleted file mode 100644 index ca00a61f1b..0000000000 --- a/main/busybox/0002-wget-verify-certificate-when-openssl-helper-is-used.patch +++ /dev/null @@ -1,71 +0,0 @@ -From: Jakub Jirutka <jakub@jirutka.cz> -Date: Mon, 28 May 2018 00:04:00 +0200 -Subject: [PATCH] wget: verify certificate when openssl helper is used - -This patch is based on -http://lists.busybox.net/pipermail/busybox/2018-May/086458.html. - -When TLS verification fails, e.g. due to invalid certificate, wget will print: - - Connecting to example.org (...:443) - wget: error getting response: Connection reset by peer - -wget executes openssl s_client as an external command and communicates -with it using stdin/stdout. Since s_client prints debug output to stderr -even when -quiet option is used, wget throws it to /dev/null. s_client -also does not disquish various error states using different exit codes, -so if openssl s_client exits prematurely, it cannot know why. - ---- a/networking/wget.c -+++ b/networking/wget.c -@@ -709,7 +709,12 @@ - pid = xvfork(); - if (pid == 0) { - /* Child */ -+#if ENABLE_FEATURE_WGET_LONG_OPTIONS -+ char *argv[13]; -+ int argc; -+#else - char *argv[8]; -+#endif - - close(sp[0]); - xmove_fd(sp[1], 0); -@@ -735,7 +740,26 @@ - if (!is_ip_address(servername)) { - argv[5] = (char*)"-servername"; - argv[6] = (char*)servername; -+#if ENABLE_FEATURE_WGET_LONG_OPTIONS -+ argc = 7; -+ } else -+ argc = 5; -+ -+ if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT)) { -+ argv[argc++] = (char*)"-verify"; -+ argv[argc++] = (char*)"16"; -+ argv[argc++] = (char*)"-verify_return_error"; -+ -+ if (is_ip_address(servername)) -+ argv[argc++] = (char*)"-verify_ip"; -+ else -+ argv[argc++] = (char*)"-verify_hostname"; -+ -+ argv[argc++] = (char*)servername; - } -+#else -+ } -+#endif - - BB_EXECVP(argv[0], argv); - xmove_fd(3, 2); -@@ -1068,6 +1092,10 @@ - int fd = spawn_https_helper_openssl(server.host, server.port); - # if ENABLE_FEATURE_WGET_HTTPS - if (fd < 0) { /* no openssl? try internal */ -+# if ENABLE_FEATURE_WGET_LONG_OPTIONS -+ if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT)) -+ bb_error_msg_and_die("unable to validate the server's certificate"); -+# endif - sfp = open_socket(lsa); - spawn_ssl_client(server.host, fileno(sfp)); - goto socket_opened; diff --git a/main/busybox/APKBUILD b/main/busybox/APKBUILD index f656f86d57..de1a1fcbf0 100644 --- a/main/busybox/APKBUILD +++ b/main/busybox/APKBUILD @@ -3,19 +3,19 @@ # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=busybox pkgver=1.28.3 -pkgrel=1 +pkgrel=2 pkgdesc="Size optimized toolbox of many common UNIX utilities" url=http://busybox.net arch="all" license="GPL-2.0" -makedepends_build="" +makedepends_build="libressl-dev" makedepends_host="linux-headers" makedepends="$makedepends_build $makedepends_host" checkdepends="zip" provides="/bin/sh" install="$pkgname.post-install $pkgname.post-upgrade $pkgname-extras.post-install $pkgname-extras.pre-deinstall" -subpackages="$pkgname-static $pkgname-suid $pkgname-extras" +subpackages="$pkgname-static $pkgname-suid $pkgname-extras ssl_client" options="suid !check" triggers="busybox.trigger=/bin:/usr/bin:/sbin:/usr/sbin:/lib/modules/*" source="http://busybox.net/downloads/$pkgname-$pkgver.tar.bz2 @@ -42,8 +42,8 @@ source="http://busybox.net/downloads/$pkgname-$pkgver.tar.bz2 0001-nsenter-Rename-network-option-to-net.patch 0002-nsenter-fix-parsing-of-t-S-and-G-options.patch - 0001-wget-print-warning-when-internal-tls-is-used.patch - 0002-wget-verify-certificate-when-openssl-helper-is-used.patch + 0001-wget-emit-a-message-that-certificate-verification-is.patch + external_ssl_client.patch acpid.logrotate busyboxconfig @@ -51,6 +51,7 @@ source="http://busybox.net/downloads/$pkgname-$pkgver.tar.bz2 bbsuid.c dad.if-up nologin.c + ssl_client.c " # secfixes: @@ -81,6 +82,10 @@ build() { ${CC:-${CROSS_COMPILE}gcc} ${CPPFLAGS} ${CFLAGS} \ ${LDFLAGS} "$srcdir"/bbsuid.c -o "$_dyndir"/bbsuid + msg "Building ssl_client" + ${CC:-${CROSS_COMPILE}gcc} ${CPPFLAGS} ${CFLAGS} $(pkg-config --cflags libtls) \ + "$srcdir"/ssl_client.c -o "$_dyndir"/ssl_client ${LDFLAGS} $(pkg-config --libs libtls) + # build dynamic cd "$_dyndir" msg "Building dynamic busybox" @@ -104,8 +109,10 @@ build() { # build static cd "$_staticdir" msg "Building static busybox" + # enable internal ssl_client for static build sed -e "s/.*CONFIG_PIE.*/\# CONFIG_PIE is not set/" \ -e "s/.*CONFIG_STATIC.*/CONFIG_STATIC=y/" \ + -e "s/.*CONFIG_SSL_CLIENT.*/CONFIG_SSL_CLIENT=y/" \ "$_config" > .config # musl does not support GNU regex [ "$CLIBC" = musl ] && sed -i \ @@ -187,6 +194,16 @@ static() { "$subpkgdir"/bin/busybox.static } +ssl_client() { + pkgdesc="EXternal ssl_client for busybox wget" + local _sslver=$(pkg-config --modversion libssl) + # automatically pull in if both busybox and libssl is installed + install_if="$pkgname=$pkgver-r$pkgrel libressl${_sslver%.*}-libssl" + mkdir -p "$subpkgdir"/usr/bin + install -m755 "$_dyndir"/ssl_client \ + "$subpkgdir"/usr/bin/ssl_client +} + sha512sums="0e87019d9d1179bc072a5ef9752d7342747e311db13c0b0dfa9f380a1e3ad1c265cca118d41f86829629ec5c8eb3e83985421c6f3ea6c8a9991b92ed301a4982 busybox-1.28.3.tar.bz2 51d4d58baff825a51d476bd4594cb8980ec2aa4d0c864a0eec39ccbbadd1ae9f1cd1b20f492a735ffcdf7c925573594f3c4363b0561c8aa7b91ef534bfc7b2e0 0001-ash-add-support-for-command_not_found_handle-hook-fu.patch 5d2fd3e521ee29d970f377363e3a3144eaf9f7714bc57494d743ded9e39c1ad93ea8759b2febd9c3786968b41e61b8d01ce2361aa997df177b644d63718470ba 0002-fsck-resolve-LABEL-.-UUID-.-spec-to-device.patch @@ -208,11 +225,12 @@ d90d6b3406760fe3df6dbed46a0f4d1c02a69d5184ebc86d8c1692bc4576532127283ba3ff9a81e6 0dbe3ee424c0a6e4aba4f551f6b6b9ee087655a03747a40906961b141d40b1cbb2345438f17887a1b78d880cb3a7ad0116936dd7c05e95160febfd299423e83b 0001-cat-fix-cat-e-and-cat-v-erroneously-numbering-1st-li.patch d2364e20b12c5215c4baecc3c6faf903e6e1e2bee95d697af047d680e9d57e7aeea54c8584d062d92daa0ea64898b502fbae010b22ab236ec4018966b74deeec 0001-nsenter-Rename-network-option-to-net.patch 0dbffae82b62317fc4144a01940ebc601e58b0e14eb8338bc42db79407d0b74dbe9f0f44758b9a5baa399eb90f8e8ee8f9c344bebd1b03bdd2ce520cb2b28d5e 0002-nsenter-fix-parsing-of-t-S-and-G-options.patch -38973e70fc77450ba1bf4d2aa7db5425d57f18eab9ae5676d457294ade12ae6b44300ae41f100f452e2efa1d027612fa501c9ac0f95ce340519e1dce497e4971 0001-wget-print-warning-when-internal-tls-is-used.patch -2af27d1f6f1a0b028464a0f5abed79311d39d27f2ba99abe91fb15e24ed93d0df69edd8cfbf5c6444d10af1eb8b343ec8d5053010f385fe77a6cc71abb3cdcbd 0002-wget-verify-certificate-when-openssl-helper-is-used.patch +90f9e95f6f953df2cf579f701b3135bad910f514e94b3e23b953acec12b10f33aa9200169dc7b454c6a04fbd992a370e6ca835406f9b5495951e0a8416137000 0001-wget-emit-a-message-that-certificate-verification-is.patch +27bd37af65f48b52fe6329f5ddf86ce9afdd1c156f94c6e868d35434298ec96c3b436097ced57f403940a29a9721b56e09bee66da3ee2cfc49c0d90d2e7a2d3d external_ssl_client.patch a9b1403c844c51934637215307dd9e2adb9458921047acff0d86dcf229b6e0027f4b2c6cdaa25a58407aad9d098fb5685d58eb5ff8d2aa3de4912cdea21fe54c acpid.logrotate -035f2a28719971d9ff805d208d70bc1144fd3701235dc46ef581a559e696ef92265f28f7debf0248a2cee004a773dcd07828bcc088716f5aff944ccdce15d30f busyboxconfig +d65dc165488a179ab19482ad74e350df9dfdccf2363b26424d2d145e27ab0819cd0cfdfb79b4a2bd0bd7c6eda3b95ea61f3c264357986e78c4675df94d487aec busyboxconfig 0efbe22e2fd56993d92b6542d4ccffb2b42d50495be085c98f417a71f503b4071e2f092afcec77f78064d33ffb0922c28daa3cb9958e6d7fb26d5a660abd90f4 busyboxconfig-extras 0becc2186d6c32fb0c401cf7bc0e46268b38ce8892db33be1daf40273024c1c02d518283f44086a313a2ccef34230a1d945ec148cc173f26e6aa9d88a7426e54 bbsuid.c a1127c8a384294135e11500fde7ead33b73d24b11c21911b08447a4c4ef71d7a9965d6466f60f2da64e3b877213b0a3e924a5add3c5333ee3ecde8c2a91c5e02 dad.if-up -061f7417c1cbf0424a5fab77e2f5912aa1593f39b33ea294af4c03518ca712d793a77ea82ff1f36e9cb98751d9faacb9d0240cdf0894efd8f26c13c28a692404 nologin.c" +061f7417c1cbf0424a5fab77e2f5912aa1593f39b33ea294af4c03518ca712d793a77ea82ff1f36e9cb98751d9faacb9d0240cdf0894efd8f26c13c28a692404 nologin.c +d7e1409a7beba30bb8f30a04d2ef1aad6461c19d5ab3a09514e3698fe86c247c4cc10d4d94b85c1608e6401374964b705fa6982b3f7a2b2acc2d6f14ba91806d ssl_client.c" diff --git a/main/busybox/busyboxconfig b/main/busybox/busyboxconfig index 3e658be600..d2ea6fd759 100644 --- a/main/busybox/busyboxconfig +++ b/main/busybox/busyboxconfig @@ -910,7 +910,7 @@ CONFIG_FEATURE_FANCY_PING=y CONFIG_PSCAN=y CONFIG_ROUTE=y CONFIG_SLATTACH=y -CONFIG_SSL_CLIENT=y +# CONFIG_SSL_CLIENT is not set # CONFIG_TCPSVD is not set # CONFIG_UDPSVD is not set # CONFIG_TELNET is not set @@ -927,7 +927,7 @@ CONFIG_SSL_CLIENT=y # CONFIG_FEATURE_TFTP_PUT is not set # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set # CONFIG_TFTP_DEBUG is not set -CONFIG_TLS=y +# CONFIG_TLS is not set CONFIG_TRACEROUTE=y CONFIG_TRACEROUTE6=y CONFIG_FEATURE_TRACEROUTE_VERBOSE=y @@ -941,7 +941,7 @@ CONFIG_FEATURE_WGET_STATUSBAR=y CONFIG_FEATURE_WGET_AUTHENTICATION=y CONFIG_FEATURE_WGET_TIMEOUT=y CONFIG_FEATURE_WGET_HTTPS=y -CONFIG_FEATURE_WGET_OPENSSL=y +# CONFIG_FEATURE_WGET_OPENSSL is not set CONFIG_WHOIS=y # CONFIG_ZCIP is not set # CONFIG_UDHCPD is not set diff --git a/main/busybox/external_ssl_client.patch b/main/busybox/external_ssl_client.patch new file mode 100644 index 0000000000..8adb7b41be --- /dev/null +++ b/main/busybox/external_ssl_client.patch @@ -0,0 +1,52 @@ +diff --git a/networking/wget.c b/networking/wget.c +index cd92b3a28..a12c921cd 100644 +--- a/networking/wget.c ++++ b/networking/wget.c +@@ -50,7 +50,6 @@ + //config: bool "Support HTTPS using internal TLS code" + //config: default y + //config: depends on WGET +-//config: select TLS + //config: help + //config: wget will use internal TLS code to connect to https:// URLs. + //config: Note: +@@ -767,8 +766,8 @@ static void spawn_ssl_client(const char *host, int network_fd) + int pid; + char *servername, *p; + +- if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT)) +- bb_error_msg("note: TLS certificate validation not implemented"); ++ if (ENABLE_SSL_CLIENT && !(option_mask32 & WGET_OPT_NO_CHECK_CERT)) ++ bb_error_msg_and_die("note: TLS certificate validation not implemented"); + + servername = xstrdup(host); + p = strrchr(servername, ':'); +@@ -785,21 +784,25 @@ static void spawn_ssl_client(const char *host, int network_fd) + close(sp[0]); + xmove_fd(sp[1], 0); + xdup2(0, 1); +- if (BB_MMU) { ++ if (BB_MMU && ENABLE_TLS && (option_mask32 & WGET_OPT_NO_CHECK_CERT)) { + tls_state_t *tls = new_tls_state(); + tls->ifd = tls->ofd = network_fd; + tls_handshake(tls, servername); + tls_run_copy_loop(tls); + exit(0); + } else { +- char *argv[5]; ++ char *argv[6]; + xmove_fd(network_fd, 3); + argv[0] = (char*)"ssl_client"; + argv[1] = (char*)"-s3"; + //TODO: if (!is_ip_address(servername))... + argv[2] = (char*)"-n"; + argv[3] = servername; +- argv[4] = NULL; ++ if (!ENABLE_SSL_CLIENT &&(option_mask32 & WGET_OPT_NO_CHECK_CERT)) { ++ argv[4] = (char*)"-I"; ++ argv[5] = NULL; ++ } else ++ argv[4] = NULL; + BB_EXECVP(argv[0], argv); + bb_perror_msg_and_die("can't execute '%s'", argv[0]); + } diff --git a/main/busybox/ssl_client.c b/main/busybox/ssl_client.c new file mode 100644 index 0000000000..8aa558e70f --- /dev/null +++ b/main/busybox/ssl_client.c @@ -0,0 +1,158 @@ +#include <err.h> +#include <errno.h> +#include <poll.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <tls.h> + +#define BUFSIZE 16384 + +#define TLS_DEBUG 0 + +#if TLS_DEBUG +# define dbg(...) fprintf(stderr, __VA_ARGS__) +#else +# define dbg(...) ((void)0) +#endif + +static void copy_from_stdin_to_tls(struct tls *ctx, int *fd) +{ + static size_t buf[BUFSIZE]; + ssize_t n; + int i = 0; + dbg("DEBUG: data from STDIN\n"); + do { + n = read(STDIN_FILENO, buf, sizeof(buf)); + dbg("read %zu\n", n); + } while (n < 0 && errno == EINTR); + + if (n < 1) { + *fd = -1; + return; + } + + while (n > 0) { + ssize_t r = tls_write(ctx, &buf[i], n); + if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT) + continue; + if (r < 0) + err(1, "tls_write: %s", tls_error(ctx)); + i += r; + n -= r; + } +} + +static int copy_from_tls_to_stdout(struct tls *ctx) +{ + static size_t buf[BUFSIZE]; + ssize_t n,r; + int i = 0; + + dbg("DEBUG: data from TLS\n"); + do { + n = tls_read(ctx, buf, sizeof(buf)); + } while (n == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT); + if (n < 0) + err(1, "tls read: %s", tls_error(ctx)); + + if (n == 0) + return 1; + + while (n) { + r = write(STDOUT_FILENO, &buf[i], n); + if (r < 0) + err(1, "write"); + i += r; + n -= r; + } + return 0; +} + +int do_poll(struct pollfd *fds, int nfds) +{ + int r; + while ((r = poll(fds, nfds, -1)) < 0) { + if (errno != EINTR && errno != ENOMEM) + err(1, "poll"); + } + return r; +} + +static void copy_loop(struct tls *ctx, int sfd) +{ + struct pollfd fds[2] = { + { .fd = STDIN_FILENO, .events = POLLIN }, + { .fd = sfd, .events = POLLIN }, + }; + + while (1) { + int r = do_poll(fds, 2); + if (fds[0].revents) + copy_from_stdin_to_tls(ctx, &fds[0].fd); + + if (fds[1].revents && copy_from_tls_to_stdout(ctx)) + break; + } +} + +void usage(const char *prog, int ret) { + printf("usage: %s [-s FD] [-I] -n SNI\n", prog); + exit(ret); +} + +int main(int argc, char *argv[]) +{ + int c, sfd = 1;; + const char *sni = NULL; + struct tls_config *tc; + struct tls *ctx; + int insecure = 0; + + while ((c = getopt(argc, argv, "hs:n:I")) != -1) { + switch (c) { + case 'h': + usage(argv[0], 0); + break; + case 's': + sfd = atoi(optarg); + break; + case 'n': + sni = optarg; + break; + case 'I': + insecure = 1; + break; + case '?': + usage(argv[0], 1); + } + } + + if (tls_init() == -1) + errx(1, "tls_init() failed"); + + if ((ctx = tls_client()) == NULL) + errx(1, "tls_client() failed"); + + if (insecure) { + if ((tc = tls_config_new()) == NULL) + errx(1, "tls_config_new() failed"); + tls_config_insecure_noverifycert(tc); + tls_config_insecure_noverifyname(tc); + tls_config_insecure_noverifytime(tc); + if (tls_configure(ctx, tc) == -1) + err(1, "tls_configure: %s", tls_error(ctx)); + tls_config_free(tc); + } + + if (tls_connect_fds(ctx, sfd, sfd, sni) == -1) + errx(1, "%s: TLS connect failed", sni); + + if (tls_handshake(ctx) == -1) + errx(1, "%s: %s", sni, tls_error(ctx)); + + copy_loop(ctx, sfd); + tls_close(ctx); + return 0; +} |