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..38163440f 100644 --- a/networking/ssl_client.c +++ b/networking/ssl_client.c @@ -69,7 +69,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/tls.c b/networking/tls.c index 9f1dd67ec..60e1afe99 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,30 @@ 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..4a5b4c9f0 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -1,4 +1,3 @@ -/* vi: set sw=4 ts=4: */ /* * wget - retrieve a file using HTTP or FTP * @@ -460,6 +459,49 @@ static FILE *open_socket(len_and_sockaddr *lsa) return fp; } +#if ENABLE_PLATFORM_MINGW32 +/* Use windows installed certificates for wget */ +#include +#include +#include +char* gather_certificates(struct tls_config *cfg) +{ + FILE *pemfile; + pemfile = tmpfile(); + HCERTSTORE dstore; + dstore = CertOpenSystemStore(0,"ROOT"); + size_t numcerts; + if(!dstore) + bb_error_msg_and_die("Error opening 'CA' cert store"); + PCCERT_CONTEXT ctx = NULL; + size_t certs_len; + 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"); + if(!PEM_write_X509(pemfile, x509cert)) + bb_error_msg_and_die("Failed to write cert"); + X509_free(x509cert); + } + CertCloseStore(dstore, CERT_CLOSE_STORE_CHECK_FLAG); + size_t pemsize = ftell(pemfile); + char *pemmem = (char*)malloc(pemsize); + if(pemmem == NULL) + bb_error_msg_and_die("out of memory"); + rewind(pemfile); + if(fread(pemmem, sizeof(char), pemsize, pemfile) != pemsize) + bb_error_msg_and_die("Failed to read temp ca pem file"); + tls_config_set_ca_mem(cfg, pemmem, pemsize); +} +#endif + /* We balk at any control chars in other side's messages. * This prevents nasty surprises (e.g. ESC sequences) in "Location:" URLs * and error messages. @@ -689,6 +731,9 @@ static void reset_beg_range_to_zero(void) } #if ENABLE_FEATURE_WGET_OPENSSL +#include +#include +/* static int spawn_https_helper_openssl(const char *host, unsigned port) { char *allocated = NULL; @@ -698,7 +743,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) IF_FEATURE_WGET_HTTPS(volatile int child_failed = 0;) if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) - /* Kernel can have AF_UNIX support disabled */ + // Kernel can have AF_UNIX support disabled / bb_simple_perror_msg_and_die("socketpair"); if (!strchr(host, ':')) @@ -709,18 +754,18 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) fflush_all(); pid = xvfork(); if (pid == 0) { - /* Child */ + // Child / char *argv[13]; char **argp; close(sp[0]); xmove_fd(sp[1], 0); xdup2(0, 1); - /* - * openssl s_client -quiet -connect www.kernel.org:443 2>/dev/null - * It prints some debug stuff on stderr, don't know how to suppress it. - * Work around by dev-nulling stderr. We lose all error messages :( - */ + // + // openssl s_client -quiet -connect www.kernel.org:443 2>/dev/null + // It prints some debug stuff on stderr, don't know how to suppress it. + // Work around by dev-nulling stderr. We lose all error messages :( + // xmove_fd(2, 3); xopen("/dev/null", O_RDWR); memset(&argv, 0, sizeof(argv)); @@ -729,18 +774,18 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) argv[2] = (char*)"-quiet"; argv[3] = (char*)"-connect"; argv[4] = (char*)host; - /* - * Per RFC 6066 Section 3, the only permitted values in the - * TLS server_name (SNI) field are FQDNs (DNS hostnames). - * IPv4 and IPv6 addresses, port numbers are not allowed. - */ + // + // Per RFC 6066 Section 3, the only permitted values in the + // TLS server_name (SNI) field are FQDNs (DNS hostnames). + // IPv4 and IPv6 addresses, port numbers are not allowed. + // argp = &argv[5]; if (!is_ip_address(servername)) { *argp++ = (char*)"-servername"; //[5] *argp++ = (char*)servername; //[6] } if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT)) { - /* Abort on bad server certificate */ + // Abort on bad server certificate / *argp++ = (char*)"-verify"; //[7] *argp++ = (char*)"100"; //[8] *argp++ = (char*)"-verify_return_error"; //[9] @@ -762,10 +807,10 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) # else bb_perror_msg_and_die("can't execute '%s'", argv[0]); # endif - /* notreached */ + // notreached / } - /* Parent */ + // Parent / free(servername); free(allocated); close(sp[1]); @@ -777,6 +822,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) # endif return sp[0]; } +*/ #endif #if ENABLE_FEATURE_WGET_HTTPS @@ -1230,26 +1276,51 @@ static void download_one_url(const char *url) /* Open socket to http(s) server */ #if ENABLE_FEATURE_WGET_OPENSSL /* 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); + //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; - } + char *allocated, *servername, *host, *pemmem; + struct tls_config *config; + 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"); + 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 path"); + if(tls_config_set_ca_file(config, "cert.pem") != 0) + bb_error_msg_and_die("Failed to set ca file"); + gather_certificates(config); + if(tls_configure(ctx,config) != 0) + bb_error_msg_and_die("Failed to configure client"); + sfp = tmpfile(); + dfp = tmpfile(); + if(tls_connect(ctx, servername, NULL) != 0) + bb_error_msg_and_die("Failed to connect: %s", tls_error(ctx)); + free(pemmem); + tls_config_free(config); + free(allocated); + free(servername); + //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(); + //sfp = fdopen(fd, "r+"); + //if (!sfp) + // bb_die_memory_exhausted(); goto socket_opened; } - sfp = open_socket(lsa); + //sfp = open_socket(lsa); socket_opened: #elif ENABLE_FEATURE_WGET_HTTPS /* Only internal TLS support is configured */ @@ -1353,7 +1424,35 @@ static void download_one_url(const char *url) shutdown(fileno(sfp), SHUT_WR); } #endif - + //How much data did we actually get? + size_t wlen, bufsize; + wlen = ftell(sfp); + bufsize = 4096; + char buf[bufsize]; + char *outbuf; + outbuf = (char*)malloc(sizeof(char) * wlen); + rewind(sfp); + rewind(dfp); + if(fread(outbuf, sizeof(char), wlen, sfp) < wlen) + bb_error_msg_and_die("Failed to read tmpfile: %s", strerror(errno)); + if(tls_write(ctx, outbuf, wlen) < wlen) + bb_error_msg_and_die("Failed to write:%s",tls_error(ctx)); + ssize_t len; + len = TLS_WANT_POLLIN; + while(len == TLS_WANT_POLLIN || len > 0){ + len = tls_read(ctx, buf, bufsize); + if(len == -1) + bb_error_msg_and_die("Failed tls read: %s", tls_error(ctx)); + if (len != TLS_WANT_POLLIN){ + wlen = fwrite(buf, sizeof(char), len, dfp); + if(wlen != len) + bb_error_msg_and_die("Failed to write to tempfile: (%zu) (%zd) %s", wlen, len, strerror(errno)); + } + } + if(len == -1) + bb_error_msg_and_die("tls read error: %s", tls_error(ctx)); + rewind(dfp); + sfp = dfp; /* * Retrieve HTTP response line and check for "200" status code. */ 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) {