X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=d29b51173f5edbb1a5e2fb5a25d8550b9f2e15aa;hp=f76b2f7dc88cdd03abf496b7c7a7247df7432362;hb=8ff919206b9740c46e7fe93e01d62f594d14262e;hpb=ed984858390ff37867ce56ec14b5eb3802a79be2 diff --git a/jcc.c b/jcc.c index f76b2f7d..d29b5117 100644 --- a/jcc.c +++ b/jcc.c @@ -485,8 +485,9 @@ static int client_protocol_is_unsupported(struct client_state *csp, char *req) #ifdef FEATURE_HTTPS_INSPECTION if (client_use_ssl(csp)) { - ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)response, strlen(response)); + ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)response, strlen(response), + get_write_delay(csp)); } else #endif @@ -586,10 +587,8 @@ static jb_err get_request_destination_elsewhere(struct client_state *csp, struct } else if (JB_ERR_OK == get_destination_from_headers(headers, csp->http)) { -#ifndef FEATURE_EXTENDED_HOST_PATTERNS /* Split the domain we just got for pattern matching */ init_domain_components(csp->http); -#endif return JB_ERR_OK; } @@ -868,10 +867,12 @@ static void send_crunch_response(struct client_state *csp, struct http_response #ifdef FEATURE_HTTPS_INSPECTION if (client_use_ssl(csp)) { - if ((ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)rsp->head, rsp->head_length) < 0) - || (ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)rsp->body, rsp->content_length) < 0)) + if ((ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)rsp->head, rsp->head_length, + get_write_delay(csp)) < 0) + || (ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)rsp->body, rsp->content_length, + get_write_delay(csp)) < 0)) { /* There is nothing we can do about it. */ log_error(LOG_LEVEL_CONNECT, "Couldn't deliver the error message " @@ -1619,7 +1620,7 @@ extern int fuzz_client_request(struct client_state *csp, char *fuzz_input_file) if (strcmp(fuzz_input_file, "-") != 0) { log_error(LOG_LEVEL_FATAL, - "Fuzzed client requests can currenty only be read from stdin (-)."); + "Fuzzed client requests can currently only be read from stdin (-)."); } err = receive_client_request(csp); if (err != JB_ERR_OK) @@ -2049,7 +2050,7 @@ static int send_http_request(struct client_state *csp) * Returns : 0 on success, anything else is an error. * *********************************************************************/ -static jb_err receive_and_send_encrypted_post_data(struct client_state *csp) +static int receive_and_send_encrypted_post_data(struct client_state *csp) { int content_length_known = csp->expected_client_content_length != 0; @@ -2093,13 +2094,13 @@ static jb_err receive_and_send_encrypted_post_data(struct client_state *csp) } if (csp->expected_client_content_length == 0) { - log_error(LOG_LEVEL_HEADER, "Forwarded the last %d bytes", len); + log_error(LOG_LEVEL_CONNECT, "Forwarded the last %d bytes", len); break; } } } - log_error(LOG_LEVEL_HEADER, "Done forwarding encrypted POST data"); + log_error(LOG_LEVEL_CONNECT, "Done forwarding encrypted POST data"); return 0; @@ -2217,7 +2218,8 @@ static jb_err receive_encrypted_request(struct client_state *csp) do { log_error(LOG_LEVEL_HEADER, "Reading encrypted headers"); - if (!data_is_available(csp->cfd, (int)csp->config->keep_alive_timeout)) + if (!is_ssl_pending(&(csp->mbedtls_client_attr.ssl)) && + !data_is_available(csp->cfd, csp->config->socket_timeout)) { log_error(LOG_LEVEL_CONNECT, "Socket %d timed out while waiting for client headers", csp->cfd); @@ -2270,8 +2272,8 @@ static jb_err process_encrypted_request(struct client_state *csp) /* XXX: Also used for JB_ERR_MEMORY */ log_error(LOG_LEVEL_ERROR, "Failed to receive encrypted request: %s", jb_err_to_string(err)); - ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)CHEADER, strlen(CHEADER)); + ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp)); return err; } @@ -2280,8 +2282,8 @@ static jb_err process_encrypted_request(struct client_state *csp) if (request_line == NULL) { log_error(LOG_LEVEL_ERROR, "Failed to get the encrypted request line"); - ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)CHEADER, strlen(CHEADER)); + ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp)); return JB_ERR_PARSE; } assert(*request_line != '\0'); @@ -2313,8 +2315,8 @@ static jb_err process_encrypted_request(struct client_state *csp) freez(request_line); if (JB_ERR_OK != err) { - ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)CHEADER, strlen(CHEADER)); + ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp)); /* XXX: Use correct size */ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0", csp->ip_addr_str); log_error(LOG_LEVEL_ERROR, @@ -2348,15 +2350,13 @@ static jb_err process_encrypted_request(struct client_state *csp) */ log_error(LOG_LEVEL_ERROR, "Failed to get the encrypted request destination"); - ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)CHEADER, strlen(CHEADER)); + ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp)); return JB_ERR_PARSE; } -#ifndef FEATURE_EXTENDED_HOST_PATTERNS /* Split the domain we just got for pattern matching */ init_domain_components(csp->http); -#endif #ifdef FEATURE_TOGGLE if ((csp->flags & CSP_FLAG_TOGGLED_ON) != 0) @@ -2386,8 +2386,8 @@ static jb_err process_encrypted_request(struct client_state *csp) err = sed_https(csp); if (JB_ERR_OK != err) { - ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)CHEADER, strlen(CHEADER)); + ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp)); log_error(LOG_LEVEL_ERROR, "Failed to parse client request from %s.", csp->ip_addr_str); log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", @@ -2397,12 +2397,39 @@ static jb_err process_encrypted_request(struct client_state *csp) log_error(LOG_LEVEL_HEADER, "Encrypted request processed"); log_applied_actions(csp->action); - log_error(LOG_LEVEL_GPC, "https://%s%s", csp->http->hostport, + log_error(LOG_LEVEL_REQUEST, "https://%s%s", csp->http->hostport, csp->http->path); return err; } + +/********************************************************************* + * + * Function : cgi_page_requested + * + * Description : Checks if a request is for an internal CGI page. + * + * Parameters : + * 1 : host = The host requested by the client. + * + * Returns : 1 if a CGI page has been requested, 0 otherwise + * + *********************************************************************/ +static int cgi_page_requested(const char *host) +{ + if ((0 == strcmpic(host, CGI_SITE_1_HOST)) + || (0 == strcmpic(host, CGI_SITE_1_HOST ".")) + || (0 == strcmpic(host, CGI_SITE_2_HOST)) + || (0 == strcmpic(host, CGI_SITE_2_HOST "."))) + { + return 1; + } + + return 0; + +} + #endif @@ -2934,11 +2961,12 @@ static void handle_established_connection(struct client_state *csp) */ if (client_use_ssl(csp)) { - if ((ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)hdr, strlen(hdr)) < 0) - || (ssl_send_data(&(csp->mbedtls_client_attr.ssl), + if ((ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)hdr, strlen(hdr), + get_write_delay(csp)) < 0) + || (ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), (const unsigned char *) ((p != NULL) ? p : csp->iob->cur), - csp->content_length) < 0)) + csp->content_length, get_write_delay(csp)) < 0)) { log_error(LOG_LEVEL_ERROR, "write modified content to " "client over TLS/SSL failed"); @@ -3036,12 +3064,13 @@ static void handle_established_connection(struct client_state *csp) */ if (client_use_ssl(csp)) { - if ((ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)hdr, hdrlen) < 0) + if ((ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)hdr, hdrlen, get_write_delay(csp)) < 0) || ((flushed = ssl_flush_socket(&(csp->mbedtls_client_attr.ssl), csp->iob)) < 0) - || (ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)csp->receive_buffer, (size_t)len) < 0)) + || (ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)csp->receive_buffer, (size_t)len, + get_write_delay(csp)) < 0)) { log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed"); @@ -3086,8 +3115,9 @@ static void handle_established_connection(struct client_state *csp) */ if (client_use_ssl(csp)) { - ret = ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)csp->receive_buffer, (size_t)len); + ret = ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)csp->receive_buffer, (size_t)len, + get_write_delay(csp)); if (ret < 0) { log_error(LOG_LEVEL_ERROR, @@ -3151,9 +3181,9 @@ static void handle_established_connection(struct client_state *csp) */ if (client_use_ssl(csp)) { - ssl_send_data(&(csp->mbedtls_client_attr.ssl), + ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE, - strlen(INVALID_SERVER_HEADERS_RESPONSE)); + strlen(INVALID_SERVER_HEADERS_RESPONSE), get_write_delay(csp)); } else #endif /* def FEATURE_HTTPS_INSPECTION */ @@ -3245,9 +3275,10 @@ static void handle_established_connection(struct client_state *csp) */ if (client_use_ssl(csp)) { - ssl_send_data(&(csp->mbedtls_client_attr.ssl), + ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE, - strlen(INVALID_SERVER_HEADERS_RESPONSE)); + strlen(INVALID_SERVER_HEADERS_RESPONSE), + get_write_delay(csp)); } else #endif /* def FEATURE_HTTPS_INSPECTION */ @@ -3277,9 +3308,10 @@ static void handle_established_connection(struct client_state *csp) */ if (client_use_ssl(csp)) { - ssl_send_data(&(csp->mbedtls_client_attr.ssl), + ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE, - strlen(INVALID_SERVER_HEADERS_RESPONSE)); + strlen(INVALID_SERVER_HEADERS_RESPONSE), + get_write_delay(csp)); } else #endif @@ -3346,8 +3378,9 @@ static void handle_established_connection(struct client_state *csp) #ifdef FEATURE_HTTPS_INSPECTION if (client_use_ssl(csp)) { - if ((ssl_send_data(&(csp->mbedtls_client_attr.ssl), - (const unsigned char *)hdr, strlen(hdr)) < 0) + if ((ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), + (const unsigned char *)hdr, strlen(hdr), + get_write_delay(csp)) < 0) || (len = ssl_flush_socket(&(csp->mbedtls_client_attr.ssl), csp->iob) < 0)) { @@ -3407,9 +3440,10 @@ static void handle_established_connection(struct client_state *csp) */ if (client_use_ssl(csp)) { - ssl_send_data(&(csp->mbedtls_client_attr.ssl), + ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl), (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE, - strlen(INVALID_SERVER_HEADERS_RESPONSE)); + strlen(INVALID_SERVER_HEADERS_RESPONSE), + get_write_delay(csp)); } else #endif /* def FEATURE_HTTPS_INSPECTION */ @@ -3529,9 +3563,10 @@ static void chat(struct client_state *csp) #ifdef FEATURE_HTTPS_INSPECTION /* * Setting flags to use old solution with SSL tunnel and to disable - * certificates verification. + * certificate verification. */ - if (csp->http->ssl && !(csp->action->flags & ACTION_HTTPS_INSPECTION)) + if (csp->http->ssl && !(csp->action->flags & ACTION_HTTPS_INSPECTION) + && !cgi_page_requested(csp->http->host)) { use_ssl_tunnel = 1; } @@ -3599,6 +3634,18 @@ static void chat(struct client_state *csp) } #endif +#ifdef FEATURE_HTTPS_INSPECTION + /* + * Log the request unless we're https inspecting + * in which case we don't have the path yet and + * will log the request later. + */ + if (!client_use_ssl(csp)) +#endif + { + log_error(LOG_LEVEL_REQUEST, "%s%s", http->hostport, http->path); + } + if (http->ssl && connect_port_is_forbidden(csp)) { const char *acceptable_connect_ports = @@ -3638,17 +3685,6 @@ static void chat(struct client_state *csp) } log_applied_actions(csp->action); -#ifdef FEATURE_HTTPS_INSPECTION - /* - * Log the request unless we're https inspecting - * in which case we don't have the path yet and - * will log the request later. - */ - if (!client_use_ssl(csp)) -#endif - { - log_error(LOG_LEVEL_GPC, "%s%s", http->hostport, http->path); - } if (fwd->forward_host) { log_error(LOG_LEVEL_CONNECT, "via [%s]:%d to: %s", @@ -3697,32 +3733,25 @@ static void chat(struct client_state *csp) { int ret; /* - * Creating an SSL proxy. If forwarding is disabled, we must send - * CSUCCEED mesage to client. Then TLS/SSL connection with client - * is created. + * Creating a SSL proxy. + * + * By sending the CSUCCEED message we're lying to the client as + * the connection hasn't actually been established yet. We don't + * establish the connection until we have seen and parsed the + * encrypted client headers. */ - - if (fwd->forward_host == NULL) + if (write_socket_delayed(csp->cfd, CSUCCEED, + strlen(CSUCCEED), get_write_delay(csp)) != 0) { - /* - * We're lying to the client as the connection hasn't actually - * been established yet. We don't establish the connection until - * we have seen and parsed the encrypted client headers. - */ - if (write_socket_delayed(csp->cfd, CSUCCEED, - strlen(CSUCCEED), get_write_delay(csp)) != 0) - { - log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed"); - return; - } + log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed"); + return; } ret = create_client_ssl_connection(csp); if (ret != 0) { log_error(LOG_LEVEL_ERROR, - "Can't open secure connection with client"); - close_client_ssl_connection(csp); /* XXX: Is this needed? */ + "Failed to open a secure connection with the client"); return; } if (JB_ERR_OK != process_encrypted_request(csp)) @@ -3853,94 +3882,57 @@ static void chat(struct client_state *csp) } /* - * Test if connection with destination server was established - * successfully by parent proxy. Then we can send response to - * the client and continue or stop. + * Test if the connection to the destination server was + * established successfully by the parent proxy. */ if (!tunnel_established_successfully(server_response, (unsigned int)len)) { - log_error(LOG_LEVEL_ERROR, "Forwarder hasn't established " - "connection with destination server."); - - write_socket(csp->cfd, server_response, (size_t)len); - mark_server_socket_tainted(csp); - close_client_ssl_connection(csp); - return; - } - - /* - * Parent proxy has established connection with destination server. - * Now we must create TLS/SSL connection with parent proxy. - */ - 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 the 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)) - { + log_error(LOG_LEVEL_ERROR, + "The forwarder %s failed to establish a connection with %s", + fwd->forward_host, http->host); rsp = error_response(csp, "connect-failed"); if (rsp) { send_crunch_response(csp, rsp); } + mark_server_socket_tainted(csp); + close_client_ssl_connection(csp); return; } + } /* -END- if (fwd->forward_host != NULL) */ - /* - * TLS/SSL connection with parent proxy is established, we can - * inform client about success. - */ - ret = write_socket(csp->cfd, server_response, (size_t)len); - if (ret != 0) + /* + * We can now create the TLS/SSL connection with the destination server. + */ + int ret = create_server_ssl_connection(csp); + if (ret != 0) + { + if (csp->server_cert_verification_result != SSL_CERT_VALID && + csp->server_cert_verification_result != SSL_CERT_NOT_VERIFIED) { - log_error(LOG_LEVEL_ERROR, - "Sending parent proxy response to client failed"); - mark_server_socket_tainted(csp); - close_client_ssl_connection(csp); + /* + * 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; } - }/* -END- if (fwd->forward_host != NULL) */ - else - { - /* - * Parent proxy is not used, we can just create TLS/SSL connection - * with destination server - */ - int ret = create_server_ssl_connection(csp); - if (ret != 0) + if (csp->server_cert_verification_result == SSL_CERT_NOT_VERIFIED + || csp->server_cert_verification_result == SSL_CERT_VALID) { - if (csp->server_cert_verification_result != SSL_CERT_VALID && - csp->server_cert_verification_result != SSL_CERT_NOT_VERIFIED) - { - /* - * 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) { - /* - * 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); - } - close_client_and_server_ssl_connections(csp); - return; + send_crunch_response(csp, rsp); } + close_client_and_server_ssl_connections(csp); + return; } } }/* -END- if (http->ssl) */ @@ -4246,7 +4238,7 @@ static void serve(struct client_state *csp) { log_error(LOG_LEVEL_CONNECT, "Closing server socket %d connected to %s. " - "Keep-alive %u. Tainted: %u. Socket alive %u. Timeout: %u.", + "Keep-alive: %u. Tainted: %u. Socket alive: %u. Timeout: %u.", csp->server_connection.sfd, csp->server_connection.host, 0 != (csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE), 0 != (csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED),