X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=0ca5b5d45fc81d6cdaca4621a42af0dec9e12307;hp=1cafb1c76c490b725e5bf5ee6b1fca696248bf5a;hb=836a87456a11821a642b28563de27c2d202fb60b;hpb=1cca8d974c645ef98cf343cb4dbf1ce42d5e88bd diff --git a/jcc.c b/jcc.c index 1cafb1c7..0ca5b5d4 100644 --- a/jcc.c +++ b/jcc.c @@ -5,8 +5,8 @@ * Purpose : Main file. Contains main() method, main loop, and * the main connection-handling function. * - * Copyright : Written by and Copyright (C) 2001-2019 the - * Privoxy team. http://www.privoxy.org/ + * Copyright : Written by and Copyright (C) 2001-2020 the + * Privoxy team. https://www.privoxy.org/ * * Based on the Internet Junkbuster originally written * by and Copyright (C) 1997 Anonymous Coders and @@ -2015,6 +2015,59 @@ static int send_http_request(struct client_state *csp) #ifdef FEATURE_HTTPS_FILTERING +/********************************************************************* + * + * Function : receive_and_send_encrypted_post_data + * + * Description : Reads remaining POST data from the client and sends + * it to the server. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * + * Returns : 0 on success, anything else is an error. + * + *********************************************************************/ +static jb_err receive_and_send_encrypted_post_data(struct client_state *csp) +{ + unsigned char buf[BUFFER_SIZE]; + int len; + + while (is_ssl_pending(&(csp->mbedtls_client_attr.ssl))) + { + len = ssl_recv_data(&(csp->mbedtls_client_attr.ssl), buf, sizeof(buf)); + if (len == -1) + { + return 1; + } + if (len == 0) + { + /* XXX: Does this actually happen? */ + break; + } + log_error(LOG_LEVEL_HEADER, "Forwarding %d bytes of encrypted POST data", + len); + len = ssl_send_data(&(csp->mbedtls_server_attr.ssl), buf, (size_t)len); + if (len == -1) + { + return 1; + } + if (csp->expected_client_content_length != 0) + { + if (csp->expected_client_content_length >= len) + { + csp->expected_client_content_length -= (unsigned)len; + } + } + } + + log_error(LOG_LEVEL_HEADER, "Done forwarding encrypted POST data"); + + return 0; + +} + + /********************************************************************* * * Function : send_https_request @@ -2085,6 +2138,10 @@ static int send_https_request(struct client_state *csp) "Flushed %d bytes of request body while expecting %llu", flushed, csp->expected_client_content_length); csp->expected_client_content_length -= (unsigned)flushed; + if (receive_and_send_encrypted_post_data(csp)) + { + return 1; + } } } else @@ -3611,9 +3668,16 @@ static void chat(struct client_state *csp) build_request_line(csp, fwd, &csp->headers->first->str); /* - * We have a request. Check if one of the crunchers wants it. + * We have a request. Check if one of the crunchers wants it + * unless the client wants to use TLS/SSL in which case we + * haven't setup the TLS context yet and will send the crunch + * response later. */ - if (crunch_response_triggered(csp, crunchers_all)) + if ( +#ifdef FEATURE_HTTPS_FILTERING + !client_use_ssl(csp) && +#endif + crunch_response_triggered(csp, crunchers_all)) { /* * Yes. The client got the crunch response and we're done here. @@ -3848,7 +3912,7 @@ static void chat(struct client_state *csp) /* * If TLS/SSL connection wasn't created and invalid certificate - * wasn't detected, we can interrupt this fuction. Otherwise, we + * wasn't detected, we can interrupt this function. Otherwise, we * must inform the client about invalid server certificate. */ if (ret != 0 @@ -3884,21 +3948,34 @@ static void chat(struct client_state *csp) * with destination server */ int ret = create_server_ssl_connection(csp); - /* - * If TLS/SSL connection wasn't created and invalid certificate - * wasn't detected, we can interrupt this function. Otherwise, we - * must inform client about invalid server certificate. - */ - if (ret != 0 - && (csp->server_cert_verification_result == SSL_CERT_NOT_VERIFIED - || csp->server_cert_verification_result == SSL_CERT_VALID)) + if (ret != 0) { - rsp = error_response(csp, "connect-failed"); - if (rsp) + if (csp->server_cert_verification_result != SSL_CERT_VALID && + csp->server_cert_verification_result != SSL_CERT_NOT_VERIFIED) { - send_crunch_response(csp, rsp); + /* + * If the server certificate is invalid, we must inform + * the client and then close connection to the client. + */ + ssl_send_certificate_error(csp); + close_client_and_server_ssl_connections(csp); + return; + } + if (csp->server_cert_verification_result == SSL_CERT_NOT_VERIFIED + || csp->server_cert_verification_result == SSL_CERT_VALID) + { + /* + * The TLS/SSL connection wasn't created but an invalid + * certificate wasn't detected. Report it as connection + * failure. + */ + rsp = error_response(csp, "connect-failed"); + if (rsp) + { + send_crunch_response(csp, rsp); + } + return; } - return; } } }/* -END- if (http->ssl) */ @@ -3974,7 +4051,7 @@ static void chat(struct client_state *csp) rsp = error_response(csp, "connect-failed"); if (rsp) { - send_crunch_response(csp, rsp); /* XXX: use ssl*/ + send_crunch_response(csp, rsp); } close_client_and_server_ssl_connections(csp); return;