X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=23679b53139329b8574a246ebd194c9d7d95bb72;hp=16b71da2c2a8255c68baa1213470343f997e8d86;hb=657f2453b5be61cd11f2900c429c732664659151;hpb=ea957b7ee480999e18005665b5f5b5c32922d8b9 diff --git a/jcc.c b/jcc.c index 16b71da2..23679b53 100644 --- a/jcc.c +++ b/jcc.c @@ -5,7 +5,7 @@ * Purpose : Main file. Contains main() method, main loop, and * the main connection-handling function. * - * Copyright : Written by and Copyright (C) 2001-2021 the + * Copyright : Written by and Copyright (C) 2001-2022 the * Privoxy team. https://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -127,6 +127,10 @@ struct file_list files[1]; #ifdef FEATURE_STATISTICS int urls_read = 0; /* total nr of urls read inc rejected */ int urls_rejected = 0; /* total nr of urls rejected */ +#ifdef MUTEX_LOCKS_AVAILABLE +unsigned long long number_of_requests_received = 0; +unsigned long long number_of_requests_blocked = 0; +#endif #endif /* def FEATURE_STATISTICS */ #ifdef FEATURE_GRACEFUL_TERMINATION @@ -191,9 +195,12 @@ privoxy_mutex_t external_filter_mutex; #ifdef FEATURE_CLIENT_TAGS privoxy_mutex_t client_tags_mutex; #endif +#ifdef FEATURE_STATISTICS +privoxy_mutex_t block_statistics_mutex; +#endif #ifdef FEATURE_EXTENDED_STATISTICS privoxy_mutex_t filter_statistics_mutex; -privoxy_mutex_t block_statistics_mutex; +privoxy_mutex_t block_reason_statistics_mutex; #endif #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) @@ -945,6 +952,11 @@ static int crunch_response_triggered(struct client_state *csp, const struct crun #ifdef FEATURE_STATISTICS if (c->flags & CF_COUNT_AS_REJECT) { +#ifdef MUTEX_LOCKS_AVAILABLE + privoxy_mutex_lock(&block_statistics_mutex); + number_of_requests_blocked++; + privoxy_mutex_unlock(&block_statistics_mutex); +#endif csp->flags |= CSP_FLAG_REJECTED; } #endif /* def FEATURE_STATISTICS */ @@ -1813,6 +1825,19 @@ static jb_err receive_client_request(struct client_state *csp) free_http_request(http); return JB_ERR_PARSE; } + if (http->ssl && strcmpic(http->gpc, "CONNECT")) + { + write_socket_delayed(csp->cfd, 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, "Client %s tried to send a https " + "URL without sending a CONNECT request first", + csp->ip_addr_str); + free_http_request(http); + return JB_ERR_PARSE; + } /* grab the rest of the client's headers */ init_list(headers); @@ -1835,7 +1860,8 @@ static jb_err receive_client_request(struct client_state *csp) if (!data_is_available(csp->cfd, csp->config->socket_timeout)) { log_error(LOG_LEVEL_ERROR, - "Stopped grabbing the client headers."); + "Client headers did not arrive in time. Timeout: %d", + csp->config->socket_timeout); destroy_list(headers); return JB_ERR_PARSE; } @@ -2080,12 +2106,13 @@ static int read_http_request_body(struct client_state *csp) if (to_read != 0) { - log_error(LOG_LEVEL_CONNECT, "Not enough request body has been read: expected %llu more bytes", - csp->expected_client_content_length); + log_error(LOG_LEVEL_CONNECT, + "Not enough request body has been read: expected %lu more bytes", + to_read); return 1; } - log_error(LOG_LEVEL_CONNECT, "The last %llu bytes of the request body have been read", - csp->expected_client_content_length); + log_error(LOG_LEVEL_CONNECT, + "The last %d bytes of the request body have been read", len); return 0; } @@ -2158,7 +2185,7 @@ static int can_filter_request_body(const struct client_state *csp) { log_error(LOG_LEVEL_INFO, "Not filtering request body from %s: buffer limit %lu will be exceeded " - "(content length %lluu)", csp->ip_addr_str, csp->config->buffer_limit, + "(content length %llu)", csp->ip_addr_str, csp->config->buffer_limit, csp->expected_client_content_length); return FALSE; } @@ -2205,6 +2232,7 @@ static int send_http_request(struct client_state *csp) update_client_headers(csp, to_send_len)) { log_error(LOG_LEVEL_HEADER, "Error updating client headers"); + freez(to_send); return 1; } csp->expected_client_content_length = 0; @@ -2229,6 +2257,10 @@ static int send_http_request(struct client_state *csp) { log_error(LOG_LEVEL_CONNECT, "Failed sending request headers to: %s: %E", csp->http->hostport); + if (filter_client_body) + { + freez(to_send); + } return 1; } @@ -2520,9 +2552,10 @@ static int send_https_request(struct client_state *csp) /********************************************************************* * - * Function : receive_encrypted_request + * Function : receive_encrypted_request_headers * - * Description : Receives an encrypted request. + * Description : Receives the encrypted request headers when + * https-inspecting. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) @@ -2531,7 +2564,7 @@ static int send_https_request(struct client_state *csp) * JB_ERR_PARSE or JB_ERR_MEMORY otherwise * *********************************************************************/ -static jb_err receive_encrypted_request(struct client_state *csp) +static jb_err receive_encrypted_request_headers(struct client_state *csp) { char buf[BUFFER_SIZE]; int len; @@ -2675,9 +2708,10 @@ static jb_err change_encrypted_request_destination(struct client_state *csp) /********************************************************************* * - * Function : process_encrypted_request + * Function : process_encrypted_request_headers * - * Description : Receives and parses an encrypted request. + * Description : Receives and parses the encrypted headers send + * by the client when https-inspecting. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) @@ -2686,7 +2720,7 @@ static jb_err change_encrypted_request_destination(struct client_state *csp) * JB_ERR_PARSE or JB_ERR_MEMORY otherwise * *********************************************************************/ -static jb_err process_encrypted_request(struct client_state *csp) +static jb_err process_encrypted_request_headers(struct client_state *csp) { char *p; char *request_line; @@ -2703,7 +2737,7 @@ static jb_err process_encrypted_request(struct client_state *csp) csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE; } #endif - err = receive_encrypted_request(csp); + err = receive_encrypted_request_headers(csp); if (err != JB_ERR_OK) { if (csp->client_iob->cur == NULL || @@ -2798,6 +2832,8 @@ static jb_err process_encrypted_request(struct client_state *csp) "Failed to get the encrypted request destination"); ssl_send_data_delayed(&(csp->ssl_client_attr), (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp)); + destroy_list(headers); + return JB_ERR_PARSE; } @@ -2870,7 +2906,7 @@ static jb_err process_encrypted_request(struct client_state *csp) return JB_ERR_PARSE; } - log_error(LOG_LEVEL_HEADER, "Encrypted request processed"); + log_error(LOG_LEVEL_HEADER, "Encrypted request headers processed"); log_error(LOG_LEVEL_REQUEST, "https://%s%s", csp->http->hostport, csp->http->path); @@ -2936,12 +2972,18 @@ static void continue_https_chat(struct client_state *csp) { const struct forward_spec *fwd; - if (JB_ERR_OK != process_encrypted_request(csp)) + if (JB_ERR_OK != process_encrypted_request_headers(csp)) { csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE; return; } +#if defined(FEATURE_STATISTICS) && defined(MUTEX_LOCKS_AVAILABLE) + privoxy_mutex_lock(&block_statistics_mutex); + number_of_requests_received++; + privoxy_mutex_unlock(&block_statistics_mutex); +#endif + csp->requests_received_total++; /* @@ -3098,6 +3140,16 @@ static void handle_established_connection(struct client_state *csp) */ goto server_wants_to_talk; } + if (watch_client_socket && client_use_ssl(csp) && + is_ssl_pending(&(csp->ssl_client_attr))) + { + /* + * The TLS libray may also consume all of the remaining data + * from the client when we're shuffling the data from an + * unbuffered request body to the server. + */ + goto client_wants_to_talk; + } #endif #ifndef HAVE_POLL FD_ZERO(&rfds); @@ -3239,7 +3291,13 @@ static void handle_established_connection(struct client_state *csp) if (FD_ISSET(csp->cfd, &rfds)) #endif /* def HAVE_POLL*/ { - int max_bytes_to_read = (int)csp->receive_buffer_size; + int max_bytes_to_read; + +#ifdef FEATURE_HTTPS_INSPECTION + client_wants_to_talk: +#endif + + max_bytes_to_read = (int)csp->receive_buffer_size; #ifdef FEATURE_CONNECTION_KEEP_ALIVE if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ)) @@ -4167,6 +4225,13 @@ static void chat(struct client_state *csp) { return; } + +#if defined(FEATURE_STATISTICS) && defined(MUTEX_LOCKS_AVAILABLE) + privoxy_mutex_lock(&block_statistics_mutex); + number_of_requests_received++; + privoxy_mutex_unlock(&block_statistics_mutex); +#endif + if (parse_client_request(csp) != JB_ERR_OK) { return; @@ -4318,7 +4383,7 @@ static void chat(struct client_state *csp) "Failed to open a secure connection with the client"); return; } - if (JB_ERR_OK != process_encrypted_request(csp)) + if (JB_ERR_OK != process_encrypted_request_headers(csp)) { close_client_ssl_connection(csp); return; @@ -4338,13 +4403,14 @@ static void chat(struct client_state *csp) } #endif + log_applied_actions(csp->action); + /* decide how to route the HTTP request */ fwd = forward_url(csp, http); freez(csp->headers->first->str); build_request_line(csp, fwd, &csp->headers->first->str); - log_applied_actions(csp->action); if (fwd->forward_host) { log_error(LOG_LEVEL_CONNECT, "via [%s]:%d to: %s", @@ -5240,9 +5306,12 @@ static void initialize_mutexes(void) #ifdef FEATURE_CLIENT_TAGS privoxy_mutex_init(&client_tags_mutex); #endif +#ifdef FEATURE_STATISTICS + privoxy_mutex_init(&block_statistics_mutex); +#endif #ifdef FEATURE_EXTENDED_STATISTICS privoxy_mutex_init(&filter_statistics_mutex); - privoxy_mutex_init(&block_statistics_mutex); + privoxy_mutex_init(&block_reason_statistics_mutex); #endif /* @@ -6272,6 +6341,8 @@ static void listen_loop(void) log_error(LOG_LEVEL_INFO, "Graceful termination requested."); + close_ports_helper(bfds); + unload_current_config_file(); unload_current_actions_file(); unload_current_re_filterfile();