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>
This commit is contained in:
parent
e999657f6d
commit
403f2999f9
@ -772,7 +772,8 @@ static inline tls_state_t *new_tls_state(void)
|
||||
return tls;
|
||||
}
|
||||
void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC;
|
||||
void tls_run_copy_loop(tls_state_t *tls) FAST_FUNC;
|
||||
#define TLSLOOP_EXIT_ON_LOCAL_EOF (1 << 0)
|
||||
void tls_run_copy_loop(tls_state_t *tls, unsigned flags) FAST_FUNC;
|
||||
|
||||
|
||||
void socket_want_pktinfo(int fd) FAST_FUNC;
|
||||
|
@ -15,7 +15,7 @@
|
||||
//kbuild:lib-$(CONFIG_SSL_CLIENT) += ssl_client.o
|
||||
|
||||
//usage:#define ssl_client_trivial_usage
|
||||
//usage: "-s FD [-r FD] [-n SNI]"
|
||||
//usage: "[-e] -s FD [-r FD] [-n SNI]"
|
||||
//usage:#define ssl_client_full_usage ""
|
||||
|
||||
#include "libbb.h"
|
||||
@ -30,26 +30,28 @@ int ssl_client_main(int argc UNUSED_PARAM, char **argv)
|
||||
// INIT_G();
|
||||
|
||||
tls = new_tls_state();
|
||||
opt = getopt32(argv, "s:#r:#n:", &tls->ofd, &tls->ifd, &sni);
|
||||
if (!(opt & 2)) {
|
||||
opt = getopt32(argv, "es:#r:#n:", &tls->ofd, &tls->ifd, &sni);
|
||||
if (!(opt & (1<<2))) {
|
||||
/* -r N defaults to -s N */
|
||||
tls->ifd = tls->ofd;
|
||||
}
|
||||
|
||||
if (!(opt & 3)) {
|
||||
if (!(opt & (3<<1))) {
|
||||
if (!argv[1])
|
||||
bb_show_usage();
|
||||
/* Undocumented debug feature: without -s and -r, takes HOST arg and connects to it */
|
||||
//
|
||||
// Talk to kernel.org:
|
||||
// printf "GET / HTTP/1.1\r\nHost: kernel.org\r\n\r\n" | ./busybox ssl_client kernel.org
|
||||
// printf "GET / HTTP/1.1\r\nHost: kernel.org\r\n\r\n" | busybox ssl_client kernel.org
|
||||
if (!sni)
|
||||
sni = argv[1];
|
||||
tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443);
|
||||
}
|
||||
|
||||
tls_handshake(tls, sni);
|
||||
tls_run_copy_loop(tls);
|
||||
|
||||
BUILD_BUG_ON(TLSLOOP_EXIT_ON_LOCAL_EOF != 1);
|
||||
tls_run_copy_loop(tls, /*flags*/ opt & 1);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -1727,7 +1727,7 @@ static void tls_xwrite(tls_state_t *tls, int len)
|
||||
// openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL
|
||||
// openssl s_client -connect 127.0.0.1:4433 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL-SHA256
|
||||
|
||||
void FAST_FUNC tls_run_copy_loop(tls_state_t *tls)
|
||||
void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags)
|
||||
{
|
||||
int inbuf_size;
|
||||
const int INBUF_STEP = 4 * 1024;
|
||||
@ -1762,6 +1762,8 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls)
|
||||
*/
|
||||
pfds[0].fd = -1;
|
||||
tls_free_outbuf(tls); /* mem usage optimization */
|
||||
if (flags & TLSLOOP_EXIT_ON_LOCAL_EOF)
|
||||
break;
|
||||
} else {
|
||||
if (nread == inbuf_size) {
|
||||
/* TLS has per record overhead, if input comes fast,
|
||||
|
@ -48,6 +48,7 @@
|
||||
//config:
|
||||
//config:config FEATURE_WGET_HTTPS
|
||||
//config: bool "Support HTTPS using internal TLS code"
|
||||
//it also enables FTPS support, but it's not well tested yet
|
||||
//config: default y
|
||||
//config: depends on WGET
|
||||
//config: select TLS
|
||||
@ -176,6 +177,9 @@ struct host_info {
|
||||
static const char P_FTP[] ALIGN1 = "ftp";
|
||||
static const char P_HTTP[] ALIGN1 = "http";
|
||||
#if SSL_SUPPORTED
|
||||
# if ENABLE_FEATURE_WGET_HTTPS
|
||||
static const char P_FTPS[] ALIGN1 = "ftps";
|
||||
# endif
|
||||
static const char P_HTTPS[] ALIGN1 = "https";
|
||||
#endif
|
||||
|
||||
@ -484,6 +488,12 @@ static void parse_url(const char *src_url, struct host_info *h)
|
||||
h->port = bb_lookup_port(P_FTP, "tcp", 21);
|
||||
} else
|
||||
#if SSL_SUPPORTED
|
||||
# if ENABLE_FEATURE_WGET_HTTPS
|
||||
if (strcmp(url, P_FTPS) == 0) {
|
||||
h->port = bb_lookup_port(P_FTPS, "tcp", 990);
|
||||
h->protocol = P_FTPS;
|
||||
} else
|
||||
# endif
|
||||
if (strcmp(url, P_HTTPS) == 0) {
|
||||
h->port = bb_lookup_port(P_HTTPS, "tcp", 443);
|
||||
h->protocol = P_HTTPS;
|
||||
@ -678,7 +688,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
|
||||
#endif
|
||||
|
||||
#if ENABLE_FEATURE_WGET_HTTPS
|
||||
static void spawn_ssl_client(const char *host, int network_fd)
|
||||
static void spawn_ssl_client(const char *host, int network_fd, int flags)
|
||||
{
|
||||
int sp[2];
|
||||
int pid;
|
||||
@ -703,17 +713,19 @@ static void spawn_ssl_client(const char *host, int network_fd)
|
||||
tls_state_t *tls = new_tls_state();
|
||||
tls->ifd = tls->ofd = network_fd;
|
||||
tls_handshake(tls, servername);
|
||||
tls_run_copy_loop(tls);
|
||||
tls_run_copy_loop(tls, flags);
|
||||
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;
|
||||
argv[4] = (flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? (char*)"-e" : NULL);
|
||||
argv[5] = NULL;
|
||||
BB_EXECVP(argv[0], argv);
|
||||
bb_perror_msg_and_die("can't execute '%s'", argv[0]);
|
||||
}
|
||||
@ -737,6 +749,11 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
|
||||
target->user = xstrdup("anonymous:busybox@");
|
||||
|
||||
sfp = open_socket(lsa);
|
||||
#if ENABLE_FEATURE_WGET_HTTPS
|
||||
if (target->protocol == P_FTPS)
|
||||
spawn_ssl_client(target->host, fileno(sfp), TLSLOOP_EXIT_ON_LOCAL_EOF);
|
||||
#endif
|
||||
|
||||
if (ftpcmd(NULL, NULL, sfp) != 220)
|
||||
bb_error_msg_and_die("%s", sanitize_string(G.wget_buf + 4));
|
||||
|
||||
@ -794,6 +811,10 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
|
||||
|
||||
*dfpp = open_socket(lsa);
|
||||
|
||||
//For encrypted data, need to send "PROT P" and get "200 PROT now Private" response first
|
||||
//Without it (or with "PROT C"), data is sent unencrypted
|
||||
//spawn_ssl_client(target->host, fileno(*dfpp), /*flags*/ 0);
|
||||
|
||||
if (G.beg_range != 0) {
|
||||
sprintf(G.wget_buf, "REST %"OFF_FMT"u", G.beg_range);
|
||||
if (ftpcmd(G.wget_buf, NULL, sfp) == 350)
|
||||
@ -981,7 +1002,7 @@ static void download_one_url(const char *url)
|
||||
/* Use the proxy if necessary */
|
||||
use_proxy = (strcmp(G.proxy_flag, "off") != 0);
|
||||
if (use_proxy) {
|
||||
proxy = getenv(target.protocol == P_FTP ? "ftp_proxy" : "http_proxy");
|
||||
proxy = getenv(target.protocol[0] == 'f' ? "ftp_proxy" : "http_proxy");
|
||||
//FIXME: what if protocol is https? Ok to use http_proxy?
|
||||
use_proxy = (proxy && proxy[0]);
|
||||
if (use_proxy)
|
||||
@ -1042,7 +1063,7 @@ static void download_one_url(const char *url)
|
||||
/*G.content_len = 0; - redundant, got_clen = 0 is enough */
|
||||
G.got_clen = 0;
|
||||
G.chunked = 0;
|
||||
if (use_proxy || target.protocol != P_FTP) {
|
||||
if (use_proxy || target.protocol[0] != 'f' /*not ftp[s]*/) {
|
||||
/*
|
||||
* HTTP session
|
||||
*/
|
||||
@ -1060,7 +1081,7 @@ static void download_one_url(const char *url)
|
||||
# if ENABLE_FEATURE_WGET_HTTPS
|
||||
if (fd < 0) { /* no openssl? try internal */
|
||||
sfp = open_socket(lsa);
|
||||
spawn_ssl_client(server.host, fileno(sfp));
|
||||
spawn_ssl_client(server.host, fileno(sfp), /*flags*/ 0);
|
||||
goto socket_opened;
|
||||
}
|
||||
# else
|
||||
@ -1077,7 +1098,7 @@ static void download_one_url(const char *url)
|
||||
/* Only internal TLS support is configured */
|
||||
sfp = open_socket(lsa);
|
||||
if (target.protocol == P_HTTPS)
|
||||
spawn_ssl_client(server.host, fileno(sfp));
|
||||
spawn_ssl_client(server.host, fileno(sfp), /*flags*/ 0);
|
||||
#else
|
||||
/* ssl (https) support is not configured */
|
||||
sfp = open_socket(lsa);
|
||||
|
Loading…
Reference in New Issue
Block a user