* Purpose : Main file. Contains main() method, main loop, and
* the main connection-handling function.
*
- * Copyright : Written by and Copyright (C) 2001-2019 the
+ * Copyright : Written by and Copyright (C) 2001-2020 the
* Privoxy team. https://www.privoxy.org/
*
* Based on the Internet Junkbuster originally written
#include "project.h"
#include "list.h"
#include "jcc.h"
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
#include "ssl.h"
#endif
#include "filters.h"
#if !defined(_WIN32) && !defined(__OS2__)
static void sig_handler(int the_signal);
#endif
-static int client_protocol_is_unsupported(const struct client_state *csp, char *req);
+static int client_protocol_is_unsupported(struct client_state *csp, char *req);
static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers);
static jb_err get_server_headers(struct client_state *csp);
static const char *crunch_reason(const struct http_response *rsp);
privoxy_mutex_t log_init_mutex;
privoxy_mutex_t connection_reuse_mutex;
-#ifdef LIMIT_MUTEX_NUMBER
-privoxy_mutex_t certificates_mutexes[32];
-#else
-privoxy_mutex_t certificates_mutexes[65536];
-#endif /* LIMIT_MUTEX_NUMBER */
+#ifdef FEATURE_HTTPS_INSPECTION
+privoxy_mutex_t certificate_mutex;
privoxy_mutex_t rng_mutex;
+#endif
#ifdef FEATURE_EXTERNAL_FILTERS
privoxy_mutex_t external_filter_mutex;
* FALSE if the request doesn't look invalid.
*
*********************************************************************/
-static int client_protocol_is_unsupported(const struct client_state *csp, char *req)
+static int client_protocol_is_unsupported(struct client_state *csp, char *req)
{
/*
* If it's a FTP or gopher request, we don't support it.
log_error(LOG_LEVEL_CLF,
"%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req);
freez(req);
- write_socket_delayed(csp->cfd, response, strlen(response),
- get_write_delay(csp));
+
+#ifdef FEATURE_HTTPS_INSPECTION
+ if (client_use_ssl(csp))
+ {
+ ssl_send_data(&(csp->mbedtls_client_attr.ssl),
+ (const unsigned char *)response, strlen(response));
+ }
+ else
+#endif
+ {
+ write_socket_delayed(csp->cfd, response, strlen(response),
+ get_write_delay(csp));
+ }
return TRUE;
}
csp->ip_addr_str, http->ocmd, status_code, rsp->content_length);
/* Write the answer to the client */
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
if (client_use_ssl(csp))
{
if ((ssl_send_data(&(csp->mbedtls_client_attr.ssl),
}
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
+/*********************************************************************
+ *
+ * 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)
+{
+ int content_length_known = csp->expected_client_content_length != 0;
+
+ while (is_ssl_pending(&(csp->mbedtls_client_attr.ssl)))
+ {
+ unsigned char buf[BUFFER_SIZE];
+ int len;
+ int max_bytes_to_read = sizeof(buf);
+
+ if (content_length_known && csp->expected_client_content_length < sizeof(buf))
+ {
+ max_bytes_to_read = (int)csp->expected_client_content_length;
+ }
+ log_error(LOG_LEVEL_CONNECT,
+ "Waiting for up to %d bytes of POST data from the client.",
+ max_bytes_to_read);
+ len = ssl_recv_data(&(csp->mbedtls_client_attr.ssl), buf,
+ (unsigned)max_bytes_to_read);
+ 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;
+ }
+ if (csp->expected_client_content_length == 0)
+ {
+ log_error(LOG_LEVEL_HEADER, "Forwarded the last %d bytes", len);
+ break;
+ }
+ }
+ }
+
+ log_error(LOG_LEVEL_HEADER, "Done forwarding encrypted POST data");
+
+ return 0;
+
+}
+
+
/*********************************************************************
*
* Function : send_https_request
"Failed sending encrypted request headers to: %s: %E",
csp->http->hostport);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return 1;
}
"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
if (err != JB_ERR_OK)
{
/* 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));
return err;
request_line = get_header(csp->client_iob);
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));
return JB_ERR_PARSE;
if (client_protocol_is_unsupported(csp, request_line))
{
- ssl_send_data(&(csp->mbedtls_client_attr.ssl),
- (const unsigned char *)CHEADER, strlen(CHEADER));
+ /*
+ * If the protocol is unsupported we're done here.
+ * client_protocol_is_unsupported() took care of sending
+ * the error response and logging the error message.
+ */
return JB_ERR_PARSE;
}
* Our attempts to get the request destination
* elsewhere failed.
*/
+ 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));
return JB_ERR_PARSE;
init_domain_components(csp->http);
#endif
- /*
- * Determine the actions for this URL
- */
#ifdef FEATURE_TOGGLE
- if (!(csp->flags & CSP_FLAG_TOGGLED_ON))
- {
- /* Most compatible set of actions (i.e. none) */
- init_current_action(csp->action);
- }
- else
-#endif /* ndef FEATURE_TOGGLE */
+ if ((csp->flags & CSP_FLAG_TOGGLED_ON) != 0)
+#endif
{
+ /* Determine the actions for this URL */
get_url_actions(csp, csp->http);
}
}
log_error(LOG_LEVEL_HEADER, "Encrypted request processed");
+ log_applied_actions(csp->action);
return err;
long len = 0; /* for buffer sizes (and negative error codes) */
int buffer_and_filter_content = 0;
unsigned int write_delay;
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
int ret = 0;
int use_ssl_tunnel = 0;
csp->dont_verify_certificate = 0;
- /*
- * Preset flags informing if SSL connections with server or client
- * are opened or closed
- */
- csp->ssl_with_server_is_opened = 0;
- csp->ssl_with_client_is_opened = 0;
-
- if (csp->http->ssl && !(csp->action->flags & ACTION_ENABLE_HTTPS_FILTER))
+ if (csp->http->ssl && !(csp->action->flags & ACTION_HTTPS_INSPECTION))
{
/* Pass encrypted content without filtering. */
use_ssl_tunnel = 1;
}
#endif /* FEATURE_CONNECTION_KEEP_ALIVE */
-#ifdef FEATURE_HTTPS_FILTERING
- /*
- * Test if some data from client or destination server are pending
- * on TLS/SSL. We must work with them preferably. TLS/SSL data can
- * be pending because of maximal fragment size.
- */
- int read_ssl_server = 0;
- int read_ssl_client = 0;
-
- if (client_use_ssl(csp))
- {
- read_ssl_client = is_ssl_pending(&(csp->mbedtls_client_attr.ssl)) != 0;
- }
-
- if (server_use_ssl(csp))
+#ifdef HAVE_POLL
+ poll_fds[0].fd = csp->cfd;
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ if (!watch_client_socket)
{
- read_ssl_server = is_ssl_pending(&(csp->mbedtls_server_attr.ssl)) != 0;
+ /*
+ * Ignore incoming data, but still watch out
+ * for disconnects etc. These flags are always
+ * implied anyway but explicitly setting them
+ * doesn't hurt.
+ */
+ poll_fds[0].events = POLLERR|POLLHUP;
}
-
- if (!read_ssl_server && !read_ssl_client)
+ else
#endif
{
-#ifdef HAVE_POLL
- poll_fds[0].fd = csp->cfd;
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
- if (!watch_client_socket)
- {
- /*
- * Ignore incoming data, but still watch out
- * for disconnects etc. These flags are always
- * implied anyway but explicitly setting them
- * doesn't hurt.
- */
- poll_fds[0].events = POLLERR|POLLHUP;
- }
- else
-#endif
- {
- poll_fds[0].events = POLLIN;
- }
- poll_fds[1].fd = csp->server_connection.sfd;
- poll_fds[1].events = POLLIN;
- n = poll(poll_fds, 2, csp->config->socket_timeout * 1000);
+ poll_fds[0].events = POLLIN;
+ }
+ poll_fds[1].fd = csp->server_connection.sfd;
+ poll_fds[1].events = POLLIN;
+ n = poll(poll_fds, 2, csp->config->socket_timeout * 1000);
#else
- timeout.tv_sec = csp->config->socket_timeout;
- timeout.tv_usec = 0;
- n = select((int)maxfd + 1, &rfds, NULL, NULL, &timeout);
+ timeout.tv_sec = csp->config->socket_timeout;
+ timeout.tv_usec = 0;
+ n = select((int)maxfd + 1, &rfds, NULL, NULL, &timeout);
#endif /* def HAVE_POLL */
- /*server or client not responding in timeout */
- if (n == 0)
+ /*server or client not responding in timeout */
+ if (n == 0)
+ {
+ log_error(LOG_LEVEL_CONNECT, "Socket timeout %d reached: %s",
+ csp->config->socket_timeout, http->url);
+ if ((byte_count == 0) && (http->ssl == 0))
{
- log_error(LOG_LEVEL_CONNECT, "Socket timeout %d reached: %s",
- csp->config->socket_timeout, http->url);
- if ((byte_count == 0) && (http->ssl == 0))
- {
- send_crunch_response(csp, error_response(csp, "connection-timeout"));
- }
- mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
- close_client_and_server_ssl_connections(csp);
-#endif
- return;
+ send_crunch_response(csp, error_response(csp, "connection-timeout"));
}
- else if (n < 0)
- {
-#ifdef HAVE_POLL
- log_error(LOG_LEVEL_ERROR, "poll() failed!: %E");
-#else
- log_error(LOG_LEVEL_ERROR, "select() failed!: %E");
-#endif
- mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
- close_client_and_server_ssl_connections(csp);
+ mark_server_socket_tainted(csp);
+#ifdef FEATURE_HTTPS_INSPECTION
+ close_client_and_server_ssl_connections(csp);
#endif
- return;
- }
+ return;
}
-#ifdef FEATURE_HTTPS_FILTERING
- else
+ else if (n < 0)
{
- /* set FD if some data are pending on TLS/SSL connections */
-#ifndef HAVE_POLL
- FD_ZERO(&rfds);
-#endif
- if (read_ssl_client)
- {
#ifdef HAVE_POLL
- poll_fds[0].fd = csp->cfd;
- poll_fds[0].events = POLLIN;
+ log_error(LOG_LEVEL_ERROR, "poll() failed!: %E");
#else
- FD_SET(csp->cfd, &rfds);
+ log_error(LOG_LEVEL_ERROR, "select() failed!: %E");
#endif
- n++;
- }
-
- if (read_ssl_server)
- {
-#ifdef HAVE_POLL
- poll_fds[1].fd = csp->server_connection.sfd;
- poll_fds[1].events = POLLIN;
-#else
- FD_SET(csp->server_connection.sfd, &rfds);
+ mark_server_socket_tainted(csp);
+#ifdef FEATURE_HTTPS_INSPECTION
+ close_client_and_server_ssl_connections(csp);
#endif
- n++;
- }
+ return;
}
-#endif
+
/*
* This is the body of the browser's request,
* just read and write it.
assert(max_bytes_to_read <= csp->receive_buffer_size);
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Reading data from standard or secured connection (HTTP/HTTPS)
*/
}
}
else
-#endif /* def FEATURE_HTTPS_FILTERING */
+#endif /* def FEATURE_HTTPS_INSPECTION */
{
len = read_socket(csp->cfd, csp->receive_buffer, max_bytes_to_read);
{
log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
- close_client_and_server_ssl_connections(csp);
-#endif
return;
}
}
log_error(LOG_LEVEL_CONNECT,
"The server still wants to talk, but the client hung up on us.");
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
}
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Reading data from standard or secured connection (HTTP/HTTPS)
*/
log_error(LOG_LEVEL_ERROR, "read from: %s failed: %E", http->host);
if ((http->ssl && (csp->fwd == NULL))
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
&& use_ssl_tunnel
#endif
)
log_error(LOG_LEVEL_ERROR, "Already forwarded the original headers. "
"Unable to tell the client about the problem.");
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
{
if (server_body || (http->ssl
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
&& use_ssl_tunnel
#endif
))
log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
}
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
}
}
else
-#endif /* def FEATURE_HTTPS_FILTERING */
+#endif /* def FEATURE_HTTPS_INSPECTION */
{
if (write_socket_delayed(csp->cfd, hdr, strlen(hdr), write_delay)
|| write_socket_delayed(csp->cfd, ((p != NULL) ? p : csp->iob->cur),
freez(hdr);
freez(p);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
- close_client_and_server_ssl_connections(csp);
-#endif
return;
}
}
* content-filtering.
*/
if (server_body || (http->ssl
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
&& use_ssl_tunnel
#endif
))
rsp = cgi_error_memory();
send_crunch_response(csp, rsp);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
}
hdrlen = strlen(hdr);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
}
}
else
-#endif /* def FEATURE_HTTPS_FILTERING */
+#endif /* def FEATURE_HTTPS_INSPECTION */
{
if (write_socket_delayed(csp->cfd, hdr, hdrlen, write_delay)
|| ((flushed = flush_iob(csp->cfd, csp->iob, write_delay)) < 0)
"Flush header and buffers to client failed: %E");
freez(hdr);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
- close_client_and_server_ssl_connections(csp);
-#endif
return;
}
}
}
else
{
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
}
}
else
-#endif /* def FEATURE_HTTPS_FILTERING */
+#endif /* def FEATURE_HTTPS_INSPECTION */
{
if (write_socket_delayed(csp->cfd, csp->receive_buffer,
(size_t)len, write_delay))
{
log_error(LOG_LEVEL_ERROR, "write to client failed: %E");
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
- close_client_and_server_ssl_connections(csp);
-#endif
return;
}
}
rsp = cgi_error_memory();
send_crunch_response(csp, rsp);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
"Applying the MS IIS5 hack didn't help.");
log_error(LOG_LEVEL_CLF,
"%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
strlen(INVALID_SERVER_HEADERS_RESPONSE));
}
else
-#endif /* def FEATURE_HTTPS_FILTERING */
+#endif /* def FEATURE_HTTPS_INSPECTION */
{
write_socket_delayed(csp->cfd,
INVALID_SERVER_HEADERS_RESPONSE,
strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
}
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
}
free_http_request(http);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
csp->headers->first->str);
log_error(LOG_LEVEL_CLF,
"%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
strlen(INVALID_SERVER_HEADERS_RESPONSE));
}
else
-#endif /* def FEATURE_HTTPS_FILTERING */
+#endif /* def FEATURE_HTTPS_INSPECTION */
{
write_socket_delayed(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
}
free_http_request(http);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
{
log_error(LOG_LEVEL_CLF,
"%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
}
free_http_request(http);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
*/
freez(hdr);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
* may be in the buffer). Use standard or secured
* connection.
*/
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
if (client_use_ssl(csp))
{
if ((ssl_send_data(&(csp->mbedtls_client_attr.ssl),
*/
freez(hdr);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
}
}
else
-#endif /* def FEATURE_HTTPS_FILTERING */
+#endif /* def FEATURE_HTTPS_INSPECTION */
{
if (write_socket_delayed(csp->cfd, hdr, strlen(hdr), write_delay)
|| ((len = flush_iob(csp->cfd, csp->iob, write_delay)) < 0))
*/
freez(hdr);
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
- close_client_and_server_ssl_connections(csp);
-#endif
return;
}
}
"Applying the MS IIS5 hack didn't help.");
log_error(LOG_LEVEL_CLF,
"%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
strlen(INVALID_SERVER_HEADERS_RESPONSE));
}
else
-#endif /* def FEATURE_HTTPS_FILTERING */
+#endif /* def FEATURE_HTTPS_INSPECTION */
{
write_socket_delayed(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
}
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return;
continue;
}
mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
return; /* huh? we should never get here */
}
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
#endif
if (csp->content_length == 0)
struct http_request *http;
/* Skeleton for HTTP response, if we should intercept the request */
struct http_response *rsp;
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
int use_ssl_tunnel = 0;
#endif
return;
}
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Setting flags to use old solution with SSL tunnel and to disable
* certificates verification.
*/
- if (csp->http->ssl && !(csp->action->flags & ACTION_ENABLE_HTTPS_FILTER))
+ if (csp->http->ssl && !(csp->action->flags & ACTION_HTTPS_INSPECTION))
{
use_ssl_tunnel = 1;
}
*
*/
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Presetting SSL client and server flags
*/
csp->ip_addr_str, acceptable_connect_ports, csp->http->hostport);
csp->action->flags |= ACTION_BLOCK;
http->ssl = 0;
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
http->client_ssl = 0;
http->server_ssl = 0;
#endif
* haven't setup the TLS context yet and will send the crunch
* response later.
*/
- if (!client_use_ssl(csp) && crunch_response_triggered(csp, crunchers_all))
+ if (
+#ifdef FEATURE_HTTPS_INSPECTION
+ !client_use_ssl(csp) &&
+#endif
+ crunch_response_triggered(csp, crunchers_all))
{
/*
* Yes. The client got the crunch response and we're done here.
mark_connection_closed(&csp->server_connection);
}
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
if (http->ssl && !use_ssl_tunnel)
{
int ret;
* client body in the buffer (if there is one) and to
* continue parsing the bytes that follow.
*/
+#ifdef FEATURE_HTTPS_INSPECTION
+ close_client_ssl_connection(csp);
+#endif
drain_and_close_socket(csp->cfd);
csp->cfd = JB_INVALID_SOCKET;
return;
}
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/*
* Creating TLS/SSL connections with destination server or parent
* proxy. If forwarding is enabled, we must send client request to
/*
* 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
* 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);
+ }
+ close_client_and_server_ssl_connections(csp);
+ return;
}
- return;
}
}
}/* -END- if (http->ssl) */
-#endif /* def FEATURE_HTTPS_FILTERING */
+#endif /* def FEATURE_HTTPS_INSPECTION */
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
save_connection_destination(csp->server_connection.sfd,
assert(csp->headers->last == NULL);
}
else if (http->ssl == 0 || (fwd->forward_host
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
&& use_ssl_tunnel
#endif
))
* Using old solution with SSL tunnel or new solution with SSL proxy
*/
list_remove_all(csp->headers);
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
if (use_ssl_tunnel)
#endif
{
return;
}
}
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
else
{
/*
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;
}
}
-#endif /* def FEATURE_HTTPS_FILTERING */
+#endif /* def FEATURE_HTTPS_INSPECTION */
clear_iob(csp->client_iob);
}/* -END- else ... if (http->ssl == 1) */
* Prepare global mutex semaphores
*/
-#ifdef LIMIT_MUTEX_NUMBER
- int i = 0;
- for (i = 0; i < 32; i++)
-#else
- int i = 0;
- for (i = 0; i < 65536; i++)
-#endif /* LIMIT_MUTEX_NUMBER */
- {
- privoxy_mutex_init(&(certificates_mutexes[i]));
- }
+#ifdef FEATURE_HTTPS_INSPECTION
+ privoxy_mutex_init(&certificate_mutex);
privoxy_mutex_init(&rng_mutex);
+#endif
privoxy_mutex_init(&log_mutex);
privoxy_mutex_init(&log_init_mutex);
/* NOTREACHED unless FEATURE_GRACEFUL_TERMINATION is defined */
-#ifdef FEATURE_HTTPS_FILTERING
+#ifdef FEATURE_HTTPS_INSPECTION
/* Clean up. Aim: free all memory (no leaks) */
if (rng_seeded == 1)
{