diff --git a/include/libbb.h b/include/libbb.h index bc1453e12..69f76cbb3 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -962,7 +962,7 @@ static inline tls_state_t *new_tls_state(void) tls_state_t *tls = xzalloc(sizeof(*tls)); return tls; } -void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; +//void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; #define TLSLOOP_EXIT_ON_LOCAL_EOF (1 << 0) void tls_run_copy_loop(tls_state_t *tls, unsigned flags) FAST_FUNC; diff --git a/networking/ssl_client.c b/networking/ssl_client.c index 757745896..653b6f48e 100644 --- a/networking/ssl_client.c +++ b/networking/ssl_client.c @@ -24,6 +24,7 @@ //usage:#define ssl_client_full_usage "" #include "libbb.h" +#include int ssl_client_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int ssl_client_main(int argc UNUSED_PARAM, char **argv) @@ -69,7 +70,7 @@ int ssl_client_main(int argc UNUSED_PARAM, char **argv) } #endif - tls_handshake(tls, sni); + //tls_handshake(tls, sni); BUILD_BUG_ON(TLSLOOP_EXIT_ON_LOCAL_EOF != 1); tls_run_copy_loop(tls, /*flags*/ opt & 1); diff --git a/networking/ssl_helper-wolfssl/ssl_helper.c b/networking/ssl_helper-wolfssl/ssl_helper.c index 38b7b56c6..834912a68 100644 --- a/networking/ssl_helper-wolfssl/ssl_helper.c +++ b/networking/ssl_helper-wolfssl/ssl_helper.c @@ -160,10 +160,10 @@ WOLFSSL *prepare(int sockfd) method = wolfTLSv1_1_client_method(); if (method == NULL) - err_sys("out of memory"); + err_sys("out of memory 3"); ctx = wolfSSL_CTX_new(method); if (ctx == NULL) - err_sys("out of memory"); + err_sys("out of memory 2"); // if (cipherList) // if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS) // err_sys("client can't set cipher list 1"); @@ -279,7 +279,7 @@ WOLFSSL *prepare(int sockfd) ssl = wolfSSL_new(ctx); if (ssl == NULL) - err_sys("out of memory"); + err_sys("out of memory 1"); //#ifdef HAVE_SESSION_TICKET // wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session"); diff --git a/networking/tls.c b/networking/tls.c index 9f1dd67ec..7e8da6df2 100644 --- a/networking/tls.c +++ b/networking/tls.c @@ -2221,6 +2221,7 @@ static void send_client_finished(tls_state_t *tls) xwrite_encrypted(tls, sizeof(*record), RECORD_TYPE_HANDSHAKE); } +/* void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) { // Client RFC 5246 Server @@ -2291,8 +2292,8 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) // defined in Section 7.4.2." // (i.e. the same format as server certs) - /*send_empty_client_cert(tls); - WRONG (breaks handshake hash calc) */ - /* need to hash _all_ server replies first, up to ServerHelloDone */ + //send_empty_client_cert(tls); - WRONG (breaks handshake hash calc) + //need to hash _all_ server replies first, up to ServerHelloDone len = tls_xread_handshake_block(tls, 4); } @@ -2308,13 +2309,13 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) send_client_key_exchange(tls); send_change_cipher_spec(tls); - /* from now on we should send encrypted */ - /* tls->write_seq64_be = 0; - already is */ + // from now on we should send encrypted + // tls->write_seq64_be = 0; - already is tls->flags |= ENCRYPT_ON_WRITE; send_client_finished(tls); - /* Get CHANGE_CIPHER_SPEC */ + // Get CHANGE_CIPHER_SPEC len = tls_xread_record(tls, "switch to encrypted traffic"); if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) bad_record_die(tls, "switch to encrypted traffic", len); @@ -2327,29 +2328,29 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) } else if (!(tls->flags & ENCRYPTION_AESGCM)) { unsigned mac_blocks = (unsigned)(TLS_MAC_SIZE(tls) + AES_BLOCK_SIZE-1) / AES_BLOCK_SIZE; - /* all incoming packets now should be encrypted and have - * at least IV + (MAC padded to blocksize): - */ + // all incoming packets now should be encrypted and have + // at least IV + (MAC padded to blocksize): tls->min_encrypted_len_on_read = AES_BLOCK_SIZE + (mac_blocks * AES_BLOCK_SIZE); } else { tls->min_encrypted_len_on_read = 8 + AES_BLOCK_SIZE; } dbg("min_encrypted_len_on_read: %u\n", tls->min_encrypted_len_on_read); - /* Get (encrypted) FINISHED from the server */ + // Get (encrypted) FINISHED from the server len = tls_xread_record(tls, "'server finished'"); if (len < 4 || tls->inbuf[RECHDR_LEN] != HANDSHAKE_FINISHED) bad_record_die(tls, "'server finished'", len); dbg("<< FINISHED\n"); - /* application data can be sent/received */ + // application data can be sent/received - /* free handshake data */ + // free handshake data psRsaKey_clear(&tls->hsd->server_rsa_pub_key); // if (PARANOIA) // memset(tls->hsd, 0, tls->hsd->hsd_size); free(tls->hsd); tls->hsd = NULL; } +*/ static void tls_xwrite(tls_state_t *tls, int len) { diff --git a/networking/wget.c b/networking/wget.c index 6a64836fb..13474abe4 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -169,7 +169,11 @@ //usage: "\n -Y on/off Use proxy" #include "libbb.h" - +#include +#include +#include +#include +#include #if 0 # define log_io(...) bb_error_msg(__VA_ARGS__) # define SENDFMT(fp, fmt, ...) \ @@ -354,6 +358,39 @@ static ALWAYS_INLINE void progress_meter(int flag UNUSED_PARAM) {} #endif +#if ENABLE_PLATFORM_MINGW32 +/* Use windows installed certificates for wget */ +#include +#include +#include +void gather_certificates(struct tls_config *cfg) +{ + printf("Gathering certificates\n"); + HCERTSTORE dstore; + dstore = CertOpenSystemStore(0,"CA"); + size_t numcerts; + if(!dstore) + bb_error_msg_and_die("Error opening 'CA' cert store"); + X509_STORE *store = X509_STORE_new(); + PCCERT_CONTEXT ctx = NULL; + for(;;) + { + ctx = CertEnumCertificatesInStore(dstore,ctx); + if(!ctx) + break; + char *dcert = ctx->pbCertEncoded; + size_t dcert_len = ctx->cbCertEncoded; + X509 *x509cert; + x509cert = d2i_X509(NULL,dcert,dcert_len); + if(x509cert == NULL) + bb_error_msg_and_die("Failed to convert cert"); + X509_STORE_add_cert(store,x509cert); + X509_free(x509cert); + } + CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG); +} + +#endif /* IPv6 knows scoped address types i.e. link and site local addresses. Link * local addresses can have a scope identifier to specify the * interface/link an address is valid on (e.g. fe80::1%eth0). This scope @@ -488,26 +525,35 @@ static char fgets_trim_sanitize(FILE *fp, const char *fmt) char c; char *buf_ptr; + printf("wget fgets_trim_sanitize 1\n"); set_alarm(); - if (fgets(G.wget_buf, sizeof(G.wget_buf), fp) == NULL) - bb_simple_perror_msg_and_die("error getting response"); + printf("wget fgets_trim_sanitize 2\n"); + if (fgets(G.wget_buf, sizeof(G.wget_buf), fp) == NULL){ + bb_error_msg_and_die("error getting response: %s",strerror(errno)); + } clear_alarm(); + printf("wget fgets_trim_sanitize 3\n"); buf_ptr = strchrnul(G.wget_buf, '\n'); + printf("wget fgets_trim_sanitize 4\n"); c = *buf_ptr; #if 1 /* Disallow any control chars: trim at first char < 0x20 */ + printf("wget fgets_trim_sanitize 5\n"); sanitize_string(G.wget_buf); + printf("wget fgets_trim_sanitize 6\n"); #else *buf_ptr = '\0'; buf_ptr = strchrnul(G.wget_buf, '\r'); *buf_ptr = '\0'; #endif + printf("wget fgets_trim_sanitize 7\n"); log_io("< %s", G.wget_buf); if (fmt && (option_mask32 & WGET_OPT_SERVER_RESPONSE)) fprintf(stderr, fmt, G.wget_buf); + printf("wget fgets_trim_sanitize 8\n"); return c; } @@ -689,6 +735,7 @@ static void reset_beg_range_to_zero(void) } #if ENABLE_FEATURE_WGET_OPENSSL +# if !ENABLE_PLATFORM_MINGW32 static int spawn_https_helper_openssl(const char *host, unsigned port) { char *allocated = NULL; @@ -777,6 +824,38 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) # endif return sp[0]; } +# else +#include +#include +static int spawn_https_helper_openssl(const char *host, unsigned port) +{ + char* allocated = NULL; + char *servername, *cmd; + int sp[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) + bb_simple_perror_msg_and_die("socketpair"); + + if(!strchr(host,":")) + host = allocated = xasprintf("%s:%u",host,port); + servername = xstrdup(host); + fflush_all(); + + struct tls *ctx = tls_client(); + if(ctx == NULL) + bb_error_msg_and_die("Out of memory 1"); + struct tls_config *config = tls_config_new(); + if(config == NULL) + bb_error_msg_and_die("Out of memory 2"); + if(tls_configure(ctx,config) != 0) + bb_error_msg_and_die("Failed to configure client"); + tls_connect_fds(ctx, sp[0], sp[1], servername); + tls_config_free(config); + free(allocated); + free(servername); + printf("Connected sp %s\n"); + return sp[0]; +} +# endif #endif #if ENABLE_FEATURE_WGET_HTTPS @@ -1151,6 +1230,7 @@ static void download_one_url(const char *url) server.user = NULL; target.user = NULL; + printf("wget download_one_url 1\n"); parse_url(url, &target); /* Use the proxy if necessary */ @@ -1172,6 +1252,7 @@ static void download_one_url(const char *url) server.host = target.host; } } + printf("wget download_one_url 2\n"); if (ENABLE_FEATURE_IPV6) strip_ipv6_scope_id(target.host); @@ -1191,6 +1272,7 @@ static void download_one_url(const char *url) G.fname_out = fname_out_alloc = xstrdup(G.fname_out); } } + printf("wget download_one_url 3\n"); #if ENABLE_FEATURE_WGET_STATUSBAR G.curfile = bb_get_last_path_component_nostrip(G.fname_out); #endif @@ -1206,15 +1288,19 @@ static void download_one_url(const char *url) * We are not sure it exists on remote side */ } + printf("wget download_one_url 4\n"); redir_limit = 16; resolve_lsa: + printf("wget download_one_url 5\n"); lsa = xhost2sockaddr(server.host, server.port); if (!(option_mask32 & WGET_OPT_QUIET)) { char *s = xmalloc_sockaddr2dotted(&lsa->u.sa); fprintf(stderr, "Connecting to %s (%s)\n", server.host, s); free(s); } + printf("wget download_one_url 6\n"); establish_session: + printf("wget download_one_url 7\n"); /*G.content_len = 0; - redundant, got_clen = 0 is enough */ G.got_clen = 0; G.chunked = 0; @@ -1229,37 +1315,61 @@ static void download_one_url(const char *url) /* Open socket to http(s) server */ #if ENABLE_FEATURE_WGET_OPENSSL + printf("wget download_one_url 8\n"); /* openssl (and maybe internal TLS) support is configured */ + struct tls *ctx; if (server.protocol == P_HTTPS) { /* openssl-based helper * Inconvenient API since we can't give it an open fd */ - int fd = spawn_https_helper_openssl(server.host, server.port); -# if ENABLE_FEATURE_WGET_HTTPS - if (fd < 0) { /* no openssl? try internal */ - sfp = open_socket(lsa); - spawn_ssl_client(server.host, fileno(sfp), /*flags*/ 0); - goto socket_opened; + printf("wget download_one_url 9\n"); + //int fd = spawn_https_helper_openssl(server.host, server.port); + char *allocated, *servername, *p, *host; + if(!strchr(server.host, ":")) + host = allocated = xasprintf("%s:%u", server.host, server.port); + servername = xstrdup(host); + ctx = tls_client(); + if(ctx == NULL) + bb_error_msg_and_die("Out of memory 1"); + struct tls_config *config; + config = tls_config_new(); + if(config == NULL) + bb_error_msg_and_die("Out of memory 2"); + if(tls_config_set_ca_path(config, "certs") != 0) + bb_error_msg_and_die("Failed to set ca file"); + if(tls_configure(ctx,config) != 0) + bb_error_msg_and_die("Failed to configure client"); + sfp = tmpfile(); + dfp = tmpfile(); + if(tls_connect_fds(ctx, dfp, sfp, servername) != 0) + bb_error_msg_and_die("Failed to connect: %s", tls_error(ctx)); + tls_config_free(config); + free(allocated); + free(servername); + printf("wget download_one_url 10\n"); + printf("wget download_one_url 13\n"); + //sfp = fdopen(fd, "r+"); + if (!sfp){ + bb_error_msg_and_die("Error opening fd: %s",strerror(errno)); } -# else - /* We don't check for exec("openssl") failure in this case */ -# endif - sfp = fdopen(fd, "r+"); - if (!sfp) - bb_die_memory_exhausted(); + printf("wget download_one_url 14\n"); goto socket_opened; } - sfp = open_socket(lsa); + printf("wget download_one_url 15\n"); + //sfp = open_socket(lsa); socket_opened: #elif ENABLE_FEATURE_WGET_HTTPS /* Only internal TLS support is configured */ + printf("wget download_one_url 16\n"); sfp = open_socket(lsa); if (server.protocol == P_HTTPS) spawn_ssl_client(server.host, fileno(sfp), /*flags*/ 0); #else + printf("wget download_one_url 17\n"); /* ssl (https) support is not configured */ sfp = open_socket(lsa); #endif + printf("wget download_one_url 18\n"); /* Send HTTP request */ if (use_proxy) { SENDFMT(sfp, "GET %s://%s/%s HTTP/1.1\r\n", @@ -1270,6 +1380,7 @@ static void download_one_url(const char *url) (option_mask32 & WGET_OPT_POST) ? "POST" : "GET", target.path); } + printf("wget download_one_url 19\n"); if (!USR_HEADER_HOST) SENDFMT(sfp, "Host: %s\r\n", target.host); if (!USR_HEADER_USER_AGENT) @@ -1280,6 +1391,7 @@ static void download_one_url(const char *url) */ SENDFMT(sfp, "Connection: close\r\n"); + printf("wget download_one_url 20\n"); #if ENABLE_FEATURE_WGET_AUTHENTICATION if (target.user && !USR_HEADER_AUTH) { SENDFMT(sfp, "Proxy-Authorization: Basic %s\r\n"+6, @@ -1291,6 +1403,7 @@ static void download_one_url(const char *url) } #endif + printf("wget download_one_url 21\n"); if (G.beg_range != 0 && !USR_HEADER_RANGE) SENDFMT(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range); @@ -1300,6 +1413,7 @@ static void download_one_url(const char *url) fputs(G.extra_headers, sfp); } + printf("wget download_one_url 22\n"); if (option_mask32 & WGET_OPT_POST_FILE) { int fd = xopen_stdin(G.post_file); G.post_data = xmalloc_read(fd, NULL); @@ -1314,15 +1428,18 @@ static void download_one_url(const char *url) ); } # if ENABLE_PLATFORM_MINGW32 + printf("wget download_one_url 23\n"); if (!USR_HEADER_CONTENT_LENGTH) SENDFMT(sfp, "Content-Length: %u\r\n", (int)strlen(G.post_data) ); + printf("wget download_one_url 24\n"); SENDFMT(sfp, "\r\n" "%s", G.post_data ); + printf("wget download_one_url 25\n"); } else # else SENDFMT(sfp, @@ -1338,6 +1455,7 @@ static void download_one_url(const char *url) SENDFMT(sfp, "\r\n"); } + printf("wget download_one_url 26\n"); fflush(sfp); /* Tried doing this unconditionally. @@ -1345,27 +1463,38 @@ static void download_one_url(const char *url) */ #if SSL_SUPPORTED if (target.protocol == P_HTTPS) { + printf("wget download_one_url 26-2\n"); /* If we use SSL helper, keeping our end of the socket open for writing * makes our end (i.e. the same fd!) readable (EAGAIN instead of EOF) * even after child closes its copy of the fd. * This helps: */ shutdown(fileno(sfp), SHUT_WR); + printf("wget download_one_url 26-3\n"); } #endif + rewind(dfp); + sfp = dfp; /* * Retrieve HTTP response line and check for "200" status code. */ read_response: + printf("wget download_one_url 27\n"); fgets_trim_sanitize(sfp, " %s\n"); + printf("wget download_one_url 27-1\n"); str = G.wget_buf; + printf("wget download_one_url 27-2\n"); str = skip_non_whitespace(str); + printf("wget download_one_url 27-3\n"); str = skip_whitespace(str); + printf("wget download_one_url 27-4\n"); // FIXME: no error check // xatou wouldn't work: "200 OK" + printf("wget download_one_url 27-5\n"); status = atoi(str); + printf("wget download_one_url 27-6\n"); switch (status) { case 0: case 100: @@ -1441,6 +1570,7 @@ However, in real world it was observed that some web servers /* * Retrieve HTTP headers. */ + printf("wget download_one_url 28\n"); while ((str = get_sanitized_hdr(sfp)) != NULL) { static const char keywords[] ALIGN1 = "content-length\0""transfer-encoding\0""location\0"; @@ -1497,6 +1627,7 @@ However, in real world it was observed that some web servers goto establish_session; } } + printf("wget download_one_url 29\n"); // if (status >= 300) // bb_error_msg_and_die("bad redirection (no Location: header from server)"); @@ -1514,6 +1645,7 @@ However, in real world it was observed that some web servers free(lsa); + printf("wget download_one_url 30\n"); if (!(option_mask32 & WGET_OPT_SPIDER)) { if (G.output_fd < 0) G.output_fd = xopen(G.fname_out, G.o_flags); @@ -1536,6 +1668,7 @@ However, in real world it was observed that some web servers /* ftpcmd("QUIT", NULL, sfp); - why bother? */ } #endif + printf("wget download_one_url 31\n"); fclose(sfp); free(server.allocated); @@ -1544,11 +1677,13 @@ However, in real world it was observed that some web servers free(target.user); free(fname_out_alloc); free(redirected_path); + printf("wget download_one_url 32\n"); } int wget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int wget_main(int argc UNUSED_PARAM, char **argv) { + printf("wget main 1\n"); #if ENABLE_FEATURE_WGET_LONG_OPTIONS static const char wget_longopts[] ALIGN1 = /* name, has_arg, val */ @@ -1590,6 +1725,7 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") #endif INIT_G(); + printf("wget main 2\n"); #if ENABLE_FEATURE_WGET_TIMEOUT G.timeout_seconds = 900; @@ -1626,6 +1762,8 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_file) ); + + printf("wget main 3\n"); #if 0 /* option bits debug */ if (option_mask32 & WGET_OPT_RETRIES) bb_error_msg("-t NUM"); if (option_mask32 & WGET_OPT_nsomething) bb_error_msg("-nsomething"); @@ -1670,6 +1808,7 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") } #endif + printf("wget main 4\n"); G.output_fd = -1; G.o_flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL; if (G.fname_out) { /* -O FILE ? */ @@ -1691,8 +1830,11 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") } } - while (*argv) + printf("wget main 5\n"); + while (*argv) { + printf("wget main 5-%s\n",argv); download_one_url(*argv++); + } if (G.output_fd >= 0) xclose(G.output_fd); diff --git a/scripts/trylink b/scripts/trylink index 2456252a3..6186284f1 100755 --- a/scripts/trylink +++ b/scripts/trylink @@ -84,7 +84,8 @@ A_FILES="$6" # a real utmp library in LDLIBS, dropping it "works" but resulting binary # does not work properly). LDLIBS="$7" -CONFIG_EXTRA_LDLIBS="$8" +shift 7 +CONFIG_EXTRA_LDLIBS="$@" # The --sort-section option is not supported by older versions of ld SORT_SECTION="-Wl,--sort-section,alignment" diff --git a/win32/mingw.c b/win32/mingw.c index 87e7ca602..7bad3e4fa 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -1214,11 +1214,13 @@ elevation_state(void) return elevated | (enabled << 1); } +/* int getuid(void) { return elevation_state() == (ELEVATED_PRIVILEGE | ADMIN_ENABLED) ? 0 : DEFAULT_UID; } +*/ struct passwd *getpwnam(const char *name) {