#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
}
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;
}
/* Log that the request was crunched and why. */
log_applied_actions(csp->action);
- log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url);
- log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u",
- csp->ip_addr_str, http->ocmd, status_code, rsp->content_length);
-
+#ifdef FEATURE_HTTPS_INSPECTION
+ if (client_use_ssl(csp))
+ {
+ log_error(LOG_LEVEL_CRUNCH, "%s: https://%s%s", crunch_reason(rsp),
+ http->hostport, http->path);
+ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s https://%s%s %s\" %s %llu",
+ csp->ip_addr_str, http->gpc, http->hostport, http->path,
+ http->version, status_code, rsp->content_length);
+ }
+ else
+#endif
+ {
+ log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url);
+ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u",
+ csp->ip_addr_str, http->ocmd, status_code, rsp->content_length);
+ }
/* Write the answer to the client */
#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 "
* if +downgrade action applies.
*/
if ((csp->action->flags & ACTION_DOWNGRADE)
- && (!strcmpic(http->ver, "HTTP/1.1")))
+ && (!strcmpic(http->version, "HTTP/1.1")))
{
- freez(http->ver);
- http->ver = strdup_or_die("HTTP/1.0");
+ freez(http->version);
+ http->version = strdup_or_die("HTTP/1.0");
}
/*
string_append(request_line, http->path);
}
string_append(request_line, " ");
- string_append(request_line, http->ver);
+ string_append(request_line, http->version);
if (*request_line == NULL)
{
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)
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
- && (!strcmpic(csp->http->ver, "HTTP/1.1"))
+ && (!strcmpic(csp->http->version, "HTTP/1.1"))
&& (csp->http->ssl == 0))
{
/* Assume persistence until further notice */
* 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;
- while (is_ssl_pending(&(csp->mbedtls_client_attr.ssl)))
+ while (is_ssl_pending(&(csp->mbedtls_client_attr.ssl))
+ || (content_length_known && csp->expected_client_content_length != 0))
{
unsigned char buf[BUFFER_SIZE];
int len;
/* XXX: Does this actually happen? */
break;
}
- log_error(LOG_LEVEL_HEADER, "Forwarding %d bytes of encrypted POST data",
+ log_error(LOG_LEVEL_CONNECT, "Forwarding %d bytes of encrypted POST data",
len);
len = ssl_send_data(&(csp->mbedtls_server_attr.ssl), buf, (size_t)len);
if (len == -1)
}
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;
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);
/* 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;
}
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');
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,
*/
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)
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",
log_error(LOG_LEVEL_HEADER, "Encrypted request processed");
log_applied_actions(csp->action);
+ 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
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
#ifdef FEATURE_HTTPS_INSPECTION
- /*
- * Reading data from standard or secured connection (HTTP/HTTPS)
- */
if (client_use_ssl(csp))
{
- /*
- * Receiving HTTP request from client over TLS/SSL and sending
- * it to server over TLS/SSL.
- */
- len = ssl_recv_data(&(csp->mbedtls_client_attr.ssl),
- (unsigned char *)csp->receive_buffer, (size_t)max_bytes_to_read);
-
- if (len <= 0)
- {
- mark_server_socket_tainted(csp);
- break;
- }
-
- ret = ssl_send_data(&(csp->mbedtls_server_attr.ssl),
- (const unsigned char *)csp->receive_buffer, (size_t)len);
-
- if (ret < 0)
- {
- log_error(LOG_LEVEL_ERROR,
- "Send request over TLS/SSL to: %s failed", http->host);
- mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
- return;
- }
+ log_error(LOG_LEVEL_CONNECT, "Breaking with TLS/SSL.");
+ break;
}
else
#endif /* def FEATURE_HTTPS_INSPECTION */
*/
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");
*/
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");
*/
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,
*/
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 */
*/
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 */
*/
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
#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))
{
*/
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 */
}
#endif
- log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %llu",
- csp->ip_addr_str, http->ocmd, csp->content_length);
-
+#ifdef FEATURE_HTTPS_INSPECTION
+ if (client_use_ssl(csp))
+ {
+ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s https://%s%s %s\" 200 %llu",
+ csp->ip_addr_str, http->gpc, http->hostport, http->path,
+ http->version, csp->content_length);
+ }
+ else
+#endif
+ {
+ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %llu",
+ csp->ip_addr_str, http->ocmd, csp->content_length);
+ }
csp->server_connection.timestamp = time(NULL);
}
#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;
}
}
#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 =
}
log_applied_actions(csp->action);
- 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",
{
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))
}
/*
- * 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) */
{
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),