aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-02-06 15:15:08 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-02-06 15:15:08 +0100
commit403f2999f94937ba3f37db6d093832f636815bb9 (patch)
tree8a9167e639458e9aee5cdc4fa6685b179c02239d
parente999657f6da95b8a40e51978461d964b56189e92 (diff)
downloadbusybox-w32-403f2999f94937ba3f37db6d093832f636815bb9.tar.gz
busybox-w32-403f2999f94937ba3f37db6d093832f636815bb9.tar.bz2
busybox-w32-403f2999f94937ba3f37db6d093832f636815bb9.zip
wget: initial support for ftps://
function old new delta spawn_ssl_client - 185 +185 parse_url 409 461 +52 packed_usage 32259 32278 +19 tls_run_copy_loop 293 306 +13 ssl_client_main 128 138 +10 showmode 330 338 +8 P_FTPS - 5 +5 filter_datapoints 177 179 +2 deflate 907 905 -2 decode_one_format 723 716 -7 wget_main 2591 2440 -151 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 6/3 up/down: 294/-160) Total: 134 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--include/libbb.h3
-rw-r--r--networking/ssl_client.c14
-rw-r--r--networking/tls.c4
-rw-r--r--networking/wget.c37
4 files changed, 42 insertions, 16 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 2bb364366..a4eb6ee67 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -772,7 +772,8 @@ static inline tls_state_t *new_tls_state(void)
772 return tls; 772 return tls;
773} 773}
774void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; 774void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC;
775void tls_run_copy_loop(tls_state_t *tls) FAST_FUNC; 775#define TLSLOOP_EXIT_ON_LOCAL_EOF (1 << 0)
776void tls_run_copy_loop(tls_state_t *tls, unsigned flags) FAST_FUNC;
776 777
777 778
778void socket_want_pktinfo(int fd) FAST_FUNC; 779void socket_want_pktinfo(int fd) FAST_FUNC;
diff --git a/networking/ssl_client.c b/networking/ssl_client.c
index d479846d7..eb84e7726 100644
--- a/networking/ssl_client.c
+++ b/networking/ssl_client.c
@@ -15,7 +15,7 @@
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: "-s FD [-r FD] [-n SNI]" 18//usage: "[-e] -s FD [-r FD] [-n SNI]"
19//usage:#define ssl_client_full_usage "" 19//usage:#define ssl_client_full_usage ""
20 20
21#include "libbb.h" 21#include "libbb.h"
@@ -30,26 +30,28 @@ int ssl_client_main(int argc UNUSED_PARAM, char **argv)
30 // INIT_G(); 30 // INIT_G();
31 31
32 tls = new_tls_state(); 32 tls = new_tls_state();
33 opt = getopt32(argv, "s:#r:#n:", &tls->ofd, &tls->ifd, &sni); 33 opt = getopt32(argv, "es:#r:#n:", &tls->ofd, &tls->ifd, &sni);
34 if (!(opt & 2)) { 34 if (!(opt & (1<<2))) {
35 /* -r N defaults to -s N */ 35 /* -r N defaults to -s N */
36 tls->ifd = tls->ofd; 36 tls->ifd = tls->ofd;
37 } 37 }
38 38
39 if (!(opt & 3)) { 39 if (!(opt & (3<<1))) {
40 if (!argv[1]) 40 if (!argv[1])
41 bb_show_usage(); 41 bb_show_usage();
42 /* Undocumented debug feature: without -s and -r, takes HOST arg and connects to it */ 42 /* Undocumented debug feature: without -s and -r, takes HOST arg and connects to it */
43 // 43 //
44 // Talk to kernel.org: 44 // Talk to kernel.org:
45 // printf "GET / HTTP/1.1\r\nHost: kernel.org\r\n\r\n" | ./busybox ssl_client kernel.org 45 // printf "GET / HTTP/1.1\r\nHost: kernel.org\r\n\r\n" | busybox ssl_client kernel.org
46 if (!sni) 46 if (!sni)
47 sni = argv[1]; 47 sni = argv[1];
48 tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443); 48 tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443);
49 } 49 }
50 50
51 tls_handshake(tls, sni); 51 tls_handshake(tls, sni);
52 tls_run_copy_loop(tls); 52
53 BUILD_BUG_ON(TLSLOOP_EXIT_ON_LOCAL_EOF != 1);
54 tls_run_copy_loop(tls, /*flags*/ opt & 1);
53 55
54 return EXIT_SUCCESS; 56 return EXIT_SUCCESS;
55} 57}
diff --git a/networking/tls.c b/networking/tls.c
index 7936afca2..da7b6058f 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -1727,7 +1727,7 @@ static void tls_xwrite(tls_state_t *tls, int len)
1727// openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL 1727// openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL
1728// openssl s_client -connect 127.0.0.1:4433 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL-SHA256 1728// openssl s_client -connect 127.0.0.1:4433 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL-SHA256
1729 1729
1730void FAST_FUNC tls_run_copy_loop(tls_state_t *tls) 1730void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags)
1731{ 1731{
1732 int inbuf_size; 1732 int inbuf_size;
1733 const int INBUF_STEP = 4 * 1024; 1733 const int INBUF_STEP = 4 * 1024;
@@ -1762,6 +1762,8 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls)
1762 */ 1762 */
1763 pfds[0].fd = -1; 1763 pfds[0].fd = -1;
1764 tls_free_outbuf(tls); /* mem usage optimization */ 1764 tls_free_outbuf(tls); /* mem usage optimization */
1765 if (flags & TLSLOOP_EXIT_ON_LOCAL_EOF)
1766 break;
1765 } else { 1767 } else {
1766 if (nread == inbuf_size) { 1768 if (nread == inbuf_size) {
1767 /* TLS has per record overhead, if input comes fast, 1769 /* TLS has per record overhead, if input comes fast,
diff --git a/networking/wget.c b/networking/wget.c
index 9300fa30b..daa728a9d 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -48,6 +48,7 @@
48//config: 48//config:
49//config:config FEATURE_WGET_HTTPS 49//config:config FEATURE_WGET_HTTPS
50//config: bool "Support HTTPS using internal TLS code" 50//config: bool "Support HTTPS using internal TLS code"
51//it also enables FTPS support, but it's not well tested yet
51//config: default y 52//config: default y
52//config: depends on WGET 53//config: depends on WGET
53//config: select TLS 54//config: select TLS
@@ -176,6 +177,9 @@ struct host_info {
176static const char P_FTP[] ALIGN1 = "ftp"; 177static const char P_FTP[] ALIGN1 = "ftp";
177static const char P_HTTP[] ALIGN1 = "http"; 178static const char P_HTTP[] ALIGN1 = "http";
178#if SSL_SUPPORTED 179#if SSL_SUPPORTED
180# if ENABLE_FEATURE_WGET_HTTPS
181static const char P_FTPS[] ALIGN1 = "ftps";
182# endif
179static const char P_HTTPS[] ALIGN1 = "https"; 183static const char P_HTTPS[] ALIGN1 = "https";
180#endif 184#endif
181 185
@@ -484,6 +488,12 @@ static void parse_url(const char *src_url, struct host_info *h)
484 h->port = bb_lookup_port(P_FTP, "tcp", 21); 488 h->port = bb_lookup_port(P_FTP, "tcp", 21);
485 } else 489 } else
486#if SSL_SUPPORTED 490#if SSL_SUPPORTED
491# if ENABLE_FEATURE_WGET_HTTPS
492 if (strcmp(url, P_FTPS) == 0) {
493 h->port = bb_lookup_port(P_FTPS, "tcp", 990);
494 h->protocol = P_FTPS;
495 } else
496# endif
487 if (strcmp(url, P_HTTPS) == 0) { 497 if (strcmp(url, P_HTTPS) == 0) {
488 h->port = bb_lookup_port(P_HTTPS, "tcp", 443); 498 h->port = bb_lookup_port(P_HTTPS, "tcp", 443);
489 h->protocol = P_HTTPS; 499 h->protocol = P_HTTPS;
@@ -678,7 +688,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
678#endif 688#endif
679 689
680#if ENABLE_FEATURE_WGET_HTTPS 690#if ENABLE_FEATURE_WGET_HTTPS
681static void spawn_ssl_client(const char *host, int network_fd) 691static void spawn_ssl_client(const char *host, int network_fd, int flags)
682{ 692{
683 int sp[2]; 693 int sp[2];
684 int pid; 694 int pid;
@@ -703,17 +713,19 @@ static void spawn_ssl_client(const char *host, int network_fd)
703 tls_state_t *tls = new_tls_state(); 713 tls_state_t *tls = new_tls_state();
704 tls->ifd = tls->ofd = network_fd; 714 tls->ifd = tls->ofd = network_fd;
705 tls_handshake(tls, servername); 715 tls_handshake(tls, servername);
706 tls_run_copy_loop(tls); 716 tls_run_copy_loop(tls, flags);
707 exit(0); 717 exit(0);
708 } else { 718 } else {
709 char *argv[5]; 719 char *argv[6];
720
710 xmove_fd(network_fd, 3); 721 xmove_fd(network_fd, 3);
711 argv[0] = (char*)"ssl_client"; 722 argv[0] = (char*)"ssl_client";
712 argv[1] = (char*)"-s3"; 723 argv[1] = (char*)"-s3";
713 //TODO: if (!is_ip_address(servername))... 724 //TODO: if (!is_ip_address(servername))...
714 argv[2] = (char*)"-n"; 725 argv[2] = (char*)"-n";
715 argv[3] = servername; 726 argv[3] = servername;
716 argv[4] = NULL; 727 argv[4] = (flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? (char*)"-e" : NULL);
728 argv[5] = NULL;
717 BB_EXECVP(argv[0], argv); 729 BB_EXECVP(argv[0], argv);
718 bb_perror_msg_and_die("can't execute '%s'", argv[0]); 730 bb_perror_msg_and_die("can't execute '%s'", argv[0]);
719 } 731 }
@@ -737,6 +749,11 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
737 target->user = xstrdup("anonymous:busybox@"); 749 target->user = xstrdup("anonymous:busybox@");
738 750
739 sfp = open_socket(lsa); 751 sfp = open_socket(lsa);
752#if ENABLE_FEATURE_WGET_HTTPS
753 if (target->protocol == P_FTPS)
754 spawn_ssl_client(target->host, fileno(sfp), TLSLOOP_EXIT_ON_LOCAL_EOF);
755#endif
756
740 if (ftpcmd(NULL, NULL, sfp) != 220) 757 if (ftpcmd(NULL, NULL, sfp) != 220)
741 bb_error_msg_and_die("%s", sanitize_string(G.wget_buf + 4)); 758 bb_error_msg_and_die("%s", sanitize_string(G.wget_buf + 4));
742 759
@@ -794,6 +811,10 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
794 811
795 *dfpp = open_socket(lsa); 812 *dfpp = open_socket(lsa);
796 813
814 //For encrypted data, need to send "PROT P" and get "200 PROT now Private" response first
815 //Without it (or with "PROT C"), data is sent unencrypted
816 //spawn_ssl_client(target->host, fileno(*dfpp), /*flags*/ 0);
817
797 if (G.beg_range != 0) { 818 if (G.beg_range != 0) {
798 sprintf(G.wget_buf, "REST %"OFF_FMT"u", G.beg_range); 819 sprintf(G.wget_buf, "REST %"OFF_FMT"u", G.beg_range);
799 if (ftpcmd(G.wget_buf, NULL, sfp) == 350) 820 if (ftpcmd(G.wget_buf, NULL, sfp) == 350)
@@ -981,7 +1002,7 @@ static void download_one_url(const char *url)
981 /* Use the proxy if necessary */ 1002 /* Use the proxy if necessary */
982 use_proxy = (strcmp(G.proxy_flag, "off") != 0); 1003 use_proxy = (strcmp(G.proxy_flag, "off") != 0);
983 if (use_proxy) { 1004 if (use_proxy) {
984 proxy = getenv(target.protocol == P_FTP ? "ftp_proxy" : "http_proxy"); 1005 proxy = getenv(target.protocol[0] == 'f' ? "ftp_proxy" : "http_proxy");
985//FIXME: what if protocol is https? Ok to use http_proxy? 1006//FIXME: what if protocol is https? Ok to use http_proxy?
986 use_proxy = (proxy && proxy[0]); 1007 use_proxy = (proxy && proxy[0]);
987 if (use_proxy) 1008 if (use_proxy)
@@ -1042,7 +1063,7 @@ static void download_one_url(const char *url)
1042 /*G.content_len = 0; - redundant, got_clen = 0 is enough */ 1063 /*G.content_len = 0; - redundant, got_clen = 0 is enough */
1043 G.got_clen = 0; 1064 G.got_clen = 0;
1044 G.chunked = 0; 1065 G.chunked = 0;
1045 if (use_proxy || target.protocol != P_FTP) { 1066 if (use_proxy || target.protocol[0] != 'f' /*not ftp[s]*/) {
1046 /* 1067 /*
1047 * HTTP session 1068 * HTTP session
1048 */ 1069 */
@@ -1060,7 +1081,7 @@ static void download_one_url(const char *url)
1060# if ENABLE_FEATURE_WGET_HTTPS 1081# if ENABLE_FEATURE_WGET_HTTPS
1061 if (fd < 0) { /* no openssl? try internal */ 1082 if (fd < 0) { /* no openssl? try internal */
1062 sfp = open_socket(lsa); 1083 sfp = open_socket(lsa);
1063 spawn_ssl_client(server.host, fileno(sfp)); 1084 spawn_ssl_client(server.host, fileno(sfp), /*flags*/ 0);
1064 goto socket_opened; 1085 goto socket_opened;
1065 } 1086 }
1066# else 1087# else
@@ -1077,7 +1098,7 @@ static void download_one_url(const char *url)
1077 /* Only internal TLS support is configured */ 1098 /* Only internal TLS support is configured */
1078 sfp = open_socket(lsa); 1099 sfp = open_socket(lsa);
1079 if (target.protocol == P_HTTPS) 1100 if (target.protocol == P_HTTPS)
1080 spawn_ssl_client(server.host, fileno(sfp)); 1101 spawn_ssl_client(server.host, fileno(sfp), /*flags*/ 0);
1081#else 1102#else
1082 /* ssl (https) support is not configured */ 1103 /* ssl (https) support is not configured */
1083 sfp = open_socket(lsa); 1104 sfp = open_socket(lsa);