Please "
@@ -1261,7 +1286,8 @@ jb_err cgi_error_unknown(const struct client_state *csp,
"\n"
"\n";
/* Includes room for larger error numbers in the future. */
- const size_t body_size = sizeof(body_prefix) + sizeof(body_suffix) + 5;
+ const size_t body_size = csp->ssl_with_client_is_opened != 0 ? sizeof(body_prefix_ssl) :
+ sizeof(body_prefix) + sizeof(body_suffix) + 5;
assert(csp);
assert(rsp);
@@ -1276,7 +1302,8 @@ jb_err cgi_error_unknown(const struct client_state *csp,
rsp->body = malloc_or_die(body_size);
- snprintf(rsp->body, body_size, "%s%d%s", body_prefix, error_to_report, body_suffix);
+ snprintf(rsp->body, body_size, "%s%d%s", csp->ssl_with_client_is_opened != 0 ?
+ body_prefix_ssl : body_prefix, error_to_report, body_suffix);
rsp->status = strdup(status);
if (rsp->status == NULL)
@@ -1580,7 +1607,7 @@ struct http_response *finish_http_response(struct client_state *csp, struct http
/* Special case - do NOT change this statically allocated response,
* which is ready for output anyway.
*/
- if (rsp == cgi_error_memory_response)
+ if (rsp == &cgi_error_memory_responses[0] || rsp == &cgi_error_memory_responses[1])
{
return rsp;
}
@@ -1748,7 +1775,7 @@ struct http_response *finish_http_response(struct client_state *csp, struct http
if (err || (NULL == (rsp->head = list_to_text(rsp->headers))))
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
rsp->head_length = strlen(rsp->head);
@@ -1791,9 +1818,10 @@ struct http_response *alloc_http_response(void)
void free_http_response(struct http_response *rsp)
{
/*
- * Must special case cgi_error_memory_response, which is never freed.
+ * Must special case cgi_error_memory_responses, which are never freed.
*/
- if (rsp && (rsp != cgi_error_memory_response))
+ if (rsp && rsp != &cgi_error_memory_responses[0]
+ && rsp != &cgi_error_memory_responses[1])
{
freez(rsp->status);
freez(rsp->head);
@@ -2179,8 +2207,10 @@ struct map *default_exports(const struct client_state *csp, const char *caller)
if (!err) err = map(exports, "my-hostname", 1, html_encode(hostname ? hostname : "unknown"), 0);
freez(hostname);
if (!err) err = map(exports, "homepage", 1, html_encode(HOME_PAGE_URL), 0);
- if (!err) err = map(exports, "default-cgi", 1, html_encode(CGI_PREFIX), 0);
- if (!err) err = map(exports, "menu", 1, make_menu(caller, csp->config->feature_flags), 0);
+ if (!err) err = map(exports, "default-cgi", 1, html_encode(csp->ssl_with_client_is_opened != 0 ?
+ CGI_SSL_PREFIX : CGI_PREFIX), 0);
+ if (!err) err = map(exports, "menu", 1, make_menu(caller, csp->config->feature_flags,
+ csp->ssl_with_client_is_opened), 0);
if (!err) err = map(exports, "code-status", 1, CODE_STATUS, 1);
if (!strncmpic(csp->config->usermanual, "file://", 7) ||
!strncmpic(csp->config->usermanual, "http", 4))
@@ -2191,7 +2221,8 @@ struct map *default_exports(const struct client_state *csp, const char *caller)
else
{
/* Manual is delivered by Privoxy. */
- if (!err) err = map(exports, "user-manual", 1, html_encode(CGI_PREFIX"user-manual/"), 0);
+ if (!err) err = map(exports, "user-manual", 1,
+ html_encode(CGI_USER_MANUAL(csp->ssl_with_client_is_opened != 0 ? CGI_SSL_PREFIX : CGI_PREFIX)), 0);
}
if (!err) err = map(exports, "actions-help-prefix", 1, ACTIONS_HELP_PREFIX ,1);
#ifdef FEATURE_TOGGLE
@@ -2371,12 +2402,13 @@ jb_err map_conditional(struct map *exports, const char *name, int choose_first)
* 1 : self = name of CGI to leave out, can be NULL for
* complete listing.
* 2 : feature_flags = feature bitmap from csp->config
+ * 3 : ssl = menu should be created with https links
*
*
* Returns : menu string, or NULL on out-of-memory error.
*
*********************************************************************/
-char *make_menu(const char *self, const unsigned feature_flags)
+char *make_menu(const char *self, const unsigned feature_flags, int ssl)
{
const struct cgi_dispatcher *d;
char *result = strdup("");
@@ -2409,7 +2441,7 @@ char *make_menu(const char *self, const unsigned feature_flags)
* the "blocked" template's JavaScript.
*/
string_append(&result, "
http->ssl != 0 ? CGI_SSL_PREFIX: CGI_PREFIX));
}
@@ -3193,7 +3207,7 @@ jb_err cgi_edit_actions_submit(struct client_state *csp,
return err;
}
- snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%i#l%u",
+ snprintf(target, sizeof(target), CGI_EDIT_AL_FOO_LUIU(csp->http->ssl != 0 ? CGI_SSL_PREFIX : CGI_PREFIX),
(long) time(NULL), file->identifier, sectionid);
edit_free_file(file);
@@ -3314,7 +3328,7 @@ jb_err cgi_edit_actions_url(struct client_state *csp,
return err;
}
- snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%i#l%u",
+ snprintf(target, sizeof(target), CGI_EDIT_AL_FOO_LUIU(csp->http->ssl != 0 ? CGI_SSL_PREFIX : CGI_PREFIX),
(long) time(NULL), file->identifier, section_start_line_number);
edit_free_file(file);
@@ -3437,7 +3451,7 @@ jb_err cgi_edit_actions_add_url(struct client_state *csp,
return err;
}
- snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%i#l%u",
+ snprintf(target, sizeof(target), CGI_EDIT_AL_FOO_LUIU(csp->http->ssl != 0 ? CGI_SSL_PREFIX : CGI_PREFIX),
(long) time(NULL), file->identifier, sectionid);
edit_free_file(file);
@@ -3548,7 +3562,7 @@ jb_err cgi_edit_actions_remove_url(struct client_state *csp,
return err;
}
- snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u#l%u",
+ snprintf(target, sizeof(target), CGI_EDIT_AL_FOO_LUUU(csp->http->ssl != 0 ? CGI_SSL_PREFIX : CGI_PREFIX),
(long) time(NULL), file->identifier, section_start_line_number);
edit_free_file(file);
@@ -3670,7 +3684,7 @@ jb_err cgi_edit_actions_section_remove(struct client_state *csp,
return err;
}
- snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u",
+ snprintf(target, sizeof(target), CGI_EDIT_AL_FOO_LUU(csp->http->ssl != 0 ? CGI_SSL_PREFIX : CGI_PREFIX),
(long) time(NULL), file->identifier);
edit_free_file(file);
@@ -3833,7 +3847,7 @@ jb_err cgi_edit_actions_section_add(struct client_state *csp,
return err;
}
- snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u",
+ snprintf(target, sizeof(target), CGI_EDIT_AL_FOO_LUU(csp->http->ssl != 0 ? CGI_SSL_PREFIX : CGI_PREFIX),
(long) time(NULL), file->identifier);
edit_free_file(file);
@@ -4022,7 +4036,7 @@ jb_err cgi_edit_actions_section_swap(struct client_state *csp,
}
} /* END if (section1 != section2) */
- snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u",
+ snprintf(target, sizeof(target), CGI_EDIT_AL_FOO_LUU(csp->http->ssl != 0 ? CGI_SSL_PREFIX : CGI_PREFIX),
(long) time(NULL), file->identifier);
edit_free_file(file);
diff --git a/cgisimple.c b/cgisimple.c
index 79b811f9..63cd4f95 100644
--- a/cgisimple.c
+++ b/cgisimple.c
@@ -63,6 +63,35 @@
#include "client-tags.h"
#endif
+
+#define CGI_SHUTDOWN_REQUEST(prefix) \
+ "\n" \
+ "\n" \
+ " Privoxy shutdown request received \n" \
+ " \n" \
+ " \n" \
+ "\n" \
+ "\n" \
+ "Privoxy shutdown request received \n" \
+ "Privoxy is going to shut down after the next request.
\n" \
+ "\n" \
+ "\n"
+
+#define CGI_CLIENT_TAG_FORM(prefix) \
+ ""
+
+#define CGI_CLIENT_TAGS(prefix) \
+ prefix "client-tags"
+
+#define CGI_USER_MANUAL(prefix) \
+ prefix "user-manual/"
+
+
static jb_err show_defines(struct map *exports);
static jb_err cgi_show_file(struct client_state *csp,
struct http_response *rsp,
@@ -172,18 +201,8 @@ jb_err cgi_die (struct client_state *csp,
const struct map *parameters)
{
static const char status[] = "200 OK Privoxy shutdown request received";
- static const char body[] =
- "\n"
- "\n"
- " Privoxy shutdown request received \n"
- " \n"
- " \n"
- "\n"
- "\n"
- "Privoxy shutdown request received \n"
- "Privoxy is going to shut down after the next request.
\n"
- "\n"
- "\n";
+ static const char body[] = CGI_SHUTDOWN_REQUEST(CGI_PREFIX)
+ static const char body_ssl[] = CGI_SHUTDOWN_REQUEST(CGI_SSL_PREFIX)
assert(csp);
assert(rsp);
@@ -198,7 +217,7 @@ jb_err cgi_die (struct client_state *csp,
rsp->head_length = 0;
rsp->is_static = 0;
- rsp->body = strdup_or_die(body);
+ rsp->body = strdup_or_die(csp->ssl_with_client_is_opened != 0 ? body_ssl : body);
rsp->status = strdup_or_die(status);
return JB_ERR_OK;
@@ -286,12 +305,13 @@ jb_err cgi_show_request(struct client_state *csp,
* 4 : toggle_state = Desired state after the button pressed 0
* 5 : expires = Whether or not the tag should be enabled.
* Only checked if toggle_state is 1.
+ * 6 : ssl = form should be created with https links
*
* Returns : void
*
*********************************************************************/
static void cgi_create_client_tag_form(char *form, size_t size,
- const char *tag, int toggle_state, int expires)
+ const char *tag, int toggle_state, int expires, int ssl)
{
char *button_name;
@@ -305,13 +325,16 @@ static void cgi_create_client_tag_form(char *form, size_t size,
button_name = "Disable";
}
- snprintf(form, size,
- "", tag, toggle_state, !expires, button_name);
+ if (ssl != 0)
+ {
+ snprintf(form, size, CGI_CLIENT_TAG_FORM(CGI_SSL_PREFIX),
+ tag, toggle_state, !expires, button_name);
+ }
+ else
+ {
+ snprintf(form, size, CGI_CLIENT_TAG_FORM(CGI_PREFIX),
+ tag, toggle_state, !expires, button_name);
+ }
}
/*********************************************************************
@@ -375,11 +398,13 @@ jb_err cgi_show_client_tags(struct client_state *csp,
if (!err) err = string_append(&client_tag_status, " ");
if (!err) err = string_append(&client_tag_status, tag_state == 1 ? "Enabled" : "Disabled");
if (!err) err = string_append(&client_tag_status, " ");
- cgi_create_client_tag_form(buf, sizeof(buf), this_tag->name, !tag_state, 1);
+ cgi_create_client_tag_form(buf, sizeof(buf), this_tag->name, !tag_state, 1,
+ csp->ssl_with_client_is_opened);
if (!err) err = string_append(&client_tag_status, buf);
if (tag_state == 0)
{
- cgi_create_client_tag_form(buf, sizeof(buf), this_tag->name, !tag_state, 0);
+ cgi_create_client_tag_form(buf, sizeof(buf), this_tag->name, !tag_state, 0,
+ csp->ssl_with_client_is_opened);
if (!err) err = string_append(&client_tag_status, buf);
}
if (!err) err = string_append(&client_tag_status, " ");
@@ -496,7 +521,8 @@ jb_err cgi_toggle_client_tag(struct client_state *csp,
}
rsp->status = strdup_or_die("302 Done dealing with toggle request");
if (enlist_unique_header(rsp->headers,
- "Location", CGI_PREFIX "client-tags"))
+ "Location", CGI_CLIENT_TAGS(csp->ssl_with_client_is_opened != 0 ?
+ CGI_SSL_PREFIX : CGI_PREFIX)))
{
return JB_ERR_MEMORY;
}
@@ -533,6 +559,7 @@ jb_err cgi_send_banner(struct client_state *csp,
const struct map *parameters)
{
char imagetype = lookup(parameters, "type")[0];
+ int ssl = csp->ssl_with_client_is_opened;
/*
* If type is auto, then determine the right thing
@@ -550,6 +577,8 @@ jb_err cgi_send_banner(struct client_state *csp,
{
static const char prefix1[] = CGI_PREFIX "send-banner?type=";
static const char prefix2[] = "http://" CGI_SITE_1_HOST "/send-banner?type=";
+ static const char prefix1_ssl[] = CGI_SSL_PREFIX "send-banner?type=";
+ static const char prefix2_ssl[] = "https://" CGI_SITE_1_HOST "/send-banner?type=";
const char *p = csp->action->string[ACTION_STRING_IMAGE_BLOCKER];
if (p == NULL)
@@ -569,13 +598,15 @@ jb_err cgi_send_banner(struct client_state *csp,
* If the action is to call this CGI, determine
* the argument:
*/
- else if (0 == strncmpic(p, prefix1, sizeof(prefix1) - 1))
+ else if (0 == strncmpic(p, ssl != 0 ? prefix1_ssl : prefix1,
+ sizeof(ssl != 0 ? prefix1_ssl : prefix1) - 1))
{
- imagetype = p[sizeof(prefix1) - 1];
+ imagetype = p[sizeof(ssl != 0 ? prefix1_ssl : prefix1) - 1];
}
- else if (0 == strncmpic(p, prefix2, sizeof(prefix2) - 1))
+ else if (0 == strncmpic(p, ssl != 0 ? prefix2_ssl : prefix2,
+ sizeof(ssl != 0 ? prefix2_ssl : prefix2) - 1))
{
- imagetype = p[sizeof(prefix2) - 1];
+ imagetype = p[sizeof(ssl != 0 ? prefix2_ssl : prefix2) - 1];
}
/*
@@ -982,7 +1013,8 @@ jb_err cgi_send_user_manual(struct client_state *csp,
if (!parameters->first)
{
/* requested http://p.p/user-manual (without trailing slash) */
- return cgi_redirect(rsp, CGI_PREFIX "user-manual/");
+ return cgi_redirect(rsp, CGI_USER_MANUAL(csp->ssl_with_client_is_opened != 0 ?
+ CGI_SSL_PREFIX : CGI_PREFIX));
}
get_string_param(parameters, "file", &filename);
diff --git a/filters.c b/filters.c
index a0ddb939..9e09d337 100644
--- a/filters.c
+++ b/filters.c
@@ -554,7 +554,7 @@ struct http_response *block_url(struct client_state *csp)
*/
if (NULL == (rsp = alloc_http_response()))
{
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
/*
@@ -582,14 +582,14 @@ struct http_response *block_url(struct client_state *csp)
if (rsp->body == NULL)
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
rsp->content_length = image_pattern_length;
if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
}
else if (0 == strcmpic(p, "blank"))
@@ -599,14 +599,14 @@ struct http_response *block_url(struct client_state *csp)
if (rsp->body == NULL)
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
rsp->content_length = image_blank_length;
if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
}
else
@@ -616,7 +616,7 @@ struct http_response *block_url(struct client_state *csp)
if (enlist_unique_header(rsp->headers, "Location", p))
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
}
@@ -655,7 +655,7 @@ struct http_response *block_url(struct client_state *csp)
if (enlist_unique_header(rsp->headers, "Content-Type", new_content_type))
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
}
}
@@ -674,7 +674,7 @@ struct http_response *block_url(struct client_state *csp)
if (exports == NULL)
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
#ifdef FEATURE_FORCE_LOAD
@@ -715,14 +715,14 @@ struct http_response *block_url(struct client_state *csp)
{
free_map(exports);
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
err = template_fill_for_cgi(csp, "blocked", exports, rsp);
if (err)
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
}
rsp->crunch_reason = BLOCKED;
@@ -769,7 +769,7 @@ struct http_response *trust_url(struct client_state *csp)
*/
if (NULL == (rsp = alloc_http_response()))
{
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
rsp->status = strdup_or_die("403 Request blocked by Privoxy");
@@ -777,7 +777,7 @@ struct http_response *trust_url(struct client_state *csp)
if (exports == NULL)
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
/*
@@ -800,7 +800,7 @@ struct http_response *trust_url(struct client_state *csp)
{
free_map(exports);
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
/*
@@ -818,7 +818,7 @@ struct http_response *trust_url(struct client_state *csp)
{
free_map(exports);
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
/*
@@ -845,7 +845,7 @@ struct http_response *trust_url(struct client_state *csp)
{
free_map(exports);
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
/*
@@ -873,7 +873,7 @@ struct http_response *trust_url(struct client_state *csp)
{
free_map(exports);
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
/*
@@ -883,7 +883,7 @@ struct http_response *trust_url(struct client_state *csp)
if (err)
{
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
rsp->crunch_reason = UNTRUSTED;
@@ -1266,7 +1266,7 @@ struct http_response *redirect_url(struct client_state *csp)
freez(new_url);
if (encoded_url == NULL)
{
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
new_url = encoded_url;
assert(FALSE == url_requires_percent_encoding(new_url));
@@ -1286,7 +1286,7 @@ struct http_response *redirect_url(struct client_state *csp)
if (NULL == (rsp = alloc_http_response()))
{
freez(new_url);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
rsp->status = strdup_or_die("302 Local Redirect from Privoxy");
@@ -1294,7 +1294,7 @@ struct http_response *redirect_url(struct client_state *csp)
{
freez(new_url);
free_http_response(rsp);
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
rsp->crunch_reason = REDIRECTED;
freez(new_url);
@@ -2590,7 +2590,7 @@ struct http_response *direct_response(struct client_state *csp)
/* Get mem for response or fail*/
if (NULL == (rsp = alloc_http_response()))
{
- return cgi_error_memory();
+ return cgi_error_memory(csp->ssl_with_client_is_opened);
}
rsp->status = strdup_or_die("501 Not Implemented");
diff --git a/jcc.c b/jcc.c
index 6dc6d10f..3cb4a0a2 100644
--- a/jcc.c
+++ b/jcc.c
@@ -1126,7 +1126,7 @@ static void send_crunch_response(const struct client_state *csp, struct http_res
}
/* Clean up and return */
- if (cgi_error_memory() != rsp)
+ if (cgi_error_memory(csp->ssl_with_client_is_opened) != rsp)
{
free_http_response(rsp);
}
@@ -2315,7 +2315,7 @@ static void handle_established_connection(struct client_state *csp)
{
log_error(LOG_LEVEL_ERROR,
"Out of memory. Failed to allocate the receive buffer.");
- rsp = cgi_error_memory();
+ rsp = cgi_error_memory(csp->ssl_with_client_is_opened);
send_crunch_response(csp, rsp);
return;
}
@@ -2921,7 +2921,7 @@ static void handle_established_connection(struct client_state *csp)
* Send our static "Out-of-memory" page.
*/
log_error(LOG_LEVEL_ERROR, "Out of memory while trying to flush.");
- rsp = cgi_error_memory();
+ rsp = cgi_error_memory(csp->ssl_with_client_is_opened);
send_crunch_response(csp, rsp);
mark_server_socket_tainted(csp);
close_client_and_server_ssl_connections(csp);
@@ -3018,7 +3018,7 @@ static void handle_established_connection(struct client_state *csp)
if (add_to_iob(csp->iob, csp->config->buffer_limit, csp->receive_buffer, len))
{
log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers.");
- rsp = cgi_error_memory();
+ rsp = cgi_error_memory(csp->ssl_with_client_is_opened);
send_crunch_response(csp, rsp);
mark_server_socket_tainted(csp);
close_client_and_server_ssl_connections(csp);
diff --git a/project.h b/project.h
index 5d8195ee..50e0960c 100644
--- a/project.h
+++ b/project.h
@@ -1624,6 +1624,7 @@ struct configuration_spec
* INCLUDES the trailing slash.
*/
#define CGI_PREFIX "http://" CGI_SITE_2_HOST CGI_SITE_2_PATH "/"
+#define CGI_SSL_PREFIX "https://" CGI_SITE_2_HOST CGI_SITE_2_PATH "/"
#endif /* ndef PROJECT_H_INCLUDED */
--
2.26.2
From 570b3a8abbda2dea45b5c2486ce30fd2a33d32f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:03:32 +0200
Subject: [PATCH 59/83] When CONNECT request to cgi url is received, connection
with destination server is not created, but SSL connection with client is
created. Then particular client request over SSL is received and cgi response
to this request is created and sent to client. So this solves receiving of
cgi requests over https and responses sending.
---
jcc.c | 227 ++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 143 insertions(+), 84 deletions(-)
diff --git a/jcc.c b/jcc.c
index 3cb4a0a2..041d951e 100644
--- a/jcc.c
+++ b/jcc.c
@@ -956,7 +956,7 @@ static int create_server_connection(struct client_state *csp) {
}
- log_error(LOG_LEVEL_INFO, "SSL CONNECTION WITH SERVER CREATED SUCCESSFULLY");
+ log_error(LOG_LEVEL_CONNECT, "SSL connection with server was created successfully");
}
}
@@ -1136,22 +1136,23 @@ static void send_crunch_response(const struct client_state *csp, struct http_res
/*********************************************************************
*
- * Function : crunch_response_triggered
+ * Function : should_trigger_crunch_response
*
* Description : Checks if the request has to be crunched,
- * and delivers the crunch response if necessary.
+ * and prepares the crunch response if necessary.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
* 2 : crunchers = list of cruncher functions to run
+ * 3 : rsp = pointer where crunch response should be
+ * returned
*
- * Returns : TRUE if the request was answered with a crunch response
- * FALSE otherwise.
+ * Returns : TRUE if the request should be answered with
+ * a crunch response, FALSE otherwise.
*
*********************************************************************/
-static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[])
+static int should_trigger_crunch_response(struct client_state *csp, const struct cruncher crunchers[], int prepare_rsp, struct http_response **rsp)
{
- struct http_response *rsp = NULL;
const struct cruncher *c;
/*
@@ -1160,10 +1161,11 @@ static int crunch_response_triggered(struct client_state *csp, const struct crun
* prevent unintentional blocks or redirects.
*/
if (!(csp->config->feature_flags & RUNTIME_FEATURE_CGI_CRUNCHING)
- && (NULL != (rsp = dispatch_cgi(csp))))
+ && NULL != (*rsp = dispatch_cgi(csp)))
{
- /* Deliver, log and free the interception response. */
- send_crunch_response(csp, rsp);
+ if (!prepare_rsp) {
+ free_http_response(*rsp);
+ }
csp->flags |= CSP_FLAG_CRUNCHED;
return TRUE;
}
@@ -1176,14 +1178,11 @@ static int crunch_response_triggered(struct client_state *csp, const struct crun
* applies to forced requests as well.
*/
if (((csp->flags & CSP_FLAG_TOGGLED_ON) &&
- !(csp->flags & CSP_FLAG_FORCED)) ||
- (c->flags & CF_IGNORE_FORCE))
+ !(csp->flags & CSP_FLAG_FORCED)) ||
+ (c->flags & CF_IGNORE_FORCE))
{
- rsp = c->cruncher(csp);
- if (NULL != rsp)
+ if (NULL != (*rsp = c->cruncher(csp)))
{
- /* Deliver, log and free the interception response. */
- send_crunch_response(csp, rsp);
csp->flags |= CSP_FLAG_CRUNCHED;
#ifdef FEATURE_STATISTICS
if (c->flags & CF_COUNT_AS_REJECT)
@@ -1192,6 +1191,9 @@ static int crunch_response_triggered(struct client_state *csp, const struct crun
}
#endif /* def FEATURE_STATISTICS */
+ if (!prepare_rsp) {
+ free_http_response(*rsp);
+ }
return TRUE;
}
}
@@ -1201,6 +1203,39 @@ static int crunch_response_triggered(struct client_state *csp, const struct crun
}
+/*********************************************************************
+ *
+ * Function : crunch_response_triggered
+ *
+ * Description : Checks if the request has to be crunched,
+ * and delivers the crunch response if necessary.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ * 2 : crunchers = list of cruncher functions to run
+ *
+ * Returns : TRUE if the request was answered with a crunch response
+ * FALSE otherwise.
+ *
+ *********************************************************************/
+static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[])
+{
+ struct http_response *rsp = NULL;
+ int should_be_triggered = FALSE;
+
+ should_be_triggered = should_trigger_crunch_response(csp, crunchers, TRUE, &rsp);
+
+ if (should_be_triggered == TRUE && rsp != NULL)
+ {
+ /* Deliver, log and free the interception response. */
+ send_crunch_response(csp, rsp);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
/*********************************************************************
*
* Function : build_request_line
@@ -1561,6 +1596,7 @@ static void mark_server_socket_tainted(struct client_state *csp)
csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
}
+
/*********************************************************************
*
* Function : get_request_line
@@ -3434,6 +3470,8 @@ static void chat(struct client_state *csp)
struct http_request *http;
/* Skeleton for HTTP response, if we should intercept the request */
struct http_response *rsp;
+ struct http_response *crunch_rsp;
+ int should_send_crunch_rsp = FALSE;
int ret = 0;
http = csp->http;
@@ -3511,8 +3549,10 @@ static void chat(struct client_state *csp)
/*
* We have a request. Check if one of the crunchers wants it.
*/
- if (crunch_response_triggered(csp, crunchers_all))
+ should_send_crunch_rsp = should_trigger_crunch_response(csp, crunchers_all, !http->ssl, &crunch_rsp);
+ if (should_send_crunch_rsp && !http->ssl)
{
+ send_crunch_response(csp, crunch_rsp);
/*
* Yes. The client got the crunch response and we're done here.
*/
@@ -3535,95 +3575,106 @@ static void chat(struct client_state *csp)
/*
* Preparing connection with requested server.
*/
- ret = create_server_connection(csp);
- if (ret != 0)
- {
- return;
- }
- csp->server_connection.requests_sent_total++;
-
- if ((fwd->type == SOCKS_5T) && (NULL == csp->headers->first))
- {
- /* Client headers have been sent optimistically */
- assert(csp->headers->last == NULL);
- }
- else if ((fwd->forward_host && csp->use_ssl_tunnel) || http->ssl == 0)
- {
- if (send_http_request(csp))
+ if (!should_send_crunch_rsp) {
+ ret = create_server_connection(csp);
+ if (ret != 0)
{
- rsp = error_response(csp, "connect-failed");
- if (rsp)
- {
- send_crunch_response(csp, rsp);
- }
return;
}
+ csp->server_connection.requests_sent_total++;
}
- else
+
+ if (!should_send_crunch_rsp)
{
- /*
- * Using old solution with SSL tunnel or new solution with SSL proxy
- */
- list_remove_all(csp->headers);
- if (csp->use_ssl_tunnel)
+ if ((fwd->type == SOCKS_5T) && (NULL == csp->headers->first))
{
- /*
- * We're running an SSL tunnel and we're not forwarding,
- * so just ditch the client headers, send the "connect succeeded"
- * message to the client, flush the rest, and get out of the way.
- */
- if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
+ /* Client headers have been sent optimistically */
+ assert(csp->headers->last == NULL);
+ }
+ else if ((fwd->forward_host && csp->use_ssl_tunnel) || http->ssl == 0)
+ {
+ if (send_http_request(csp))
{
+ rsp = error_response(csp, "connect-failed");
+ if (rsp)
+ {
+ send_crunch_response(csp, rsp);
+ }
return;
}
}
else
{
/*
- * Creating an SSL proxy. If forwarding is disabled, we must send
- * CSUCCEED mesage to client. Then SSL/TLS connection with client
- * is created.
+ * Using old solution with SSL tunnel or new solution with SSL proxy
*/
-
- if (fwd->forward_host == NULL)
+ list_remove_all(csp->headers);
+ if (csp->use_ssl_tunnel)
{
+ /*
+ * We're running an SSL tunnel and we're not forwarding,
+ * so just ditch the client headers, send the "connect succeeded"
+ * message to the client, flush the rest, and get out of the way.
+ */
if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
{
- log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
- close_client_and_server_ssl_connections(csp);
return;
}
}
-
- ret = create_client_ssl_connection(csp);
- if (ret != 0)
+ else
{
- log_error(LOG_LEVEL_ERROR,
- "Can't open secure connection with client");
- close_client_and_server_ssl_connections(csp);
- return;
- }
+ /*
+ * Creating an SSL proxy. If forwarding is disabled, we must send
+ * CSUCCEED mesage to client. Then SSL/TLS connection with client
+ * is created.
+ */
- /*
- * If server certificate is invalid, we must inform client and then
- * close connection with client.
- */
+ if (fwd->forward_host == NULL)
+ {
+ if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
+ {
+ log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
+ close_client_and_server_ssl_connections(csp);
+ return;
+ }
+ }
+
+ ret = create_client_ssl_connection(csp);
+ if (ret != 0)
+ {
+ log_error(LOG_LEVEL_ERROR,
+ "Can't open secure connection with client");
+ close_client_and_server_ssl_connections(csp);
+ return;
+ }
+
+ /*
+ * If server certificate is invalid, we must inform client and then
+ * close connection with client.
+ */
#ifdef FEATURE_MBEDTLS
- if (csp->server_cert_verification_result != SSL_CERT_VALID)
+ if (csp->server_cert_verification_result != SSL_CERT_VALID)
#elif defined(FEATURE_LIBRESSL)
- if (csp->server_cert_verification_result != X509_V_OK)
+ if (csp->server_cert_verification_result != X509_V_OK)
#endif
#if defined(FEATURE_MBEDTLS) || defined(FEATURE_LIBRESSL)
- {
- ssl_send_certificate_error(csp);
- close_client_and_server_ssl_connections(csp);
- return;
- }
+ {
+ ssl_send_certificate_error(csp);
+ close_client_and_server_ssl_connections(csp);
+ return;
+ }
#endif
- log_error(LOG_LEVEL_INFO, "SSL CONNECTION WITH CLIENT CREATED SUCCESSFULLY");
+ log_error(LOG_LEVEL_CONNECT, "SSL connection with client was created successfully");
+ }
+ clear_iob(csp->client_iob);
}
- clear_iob(csp->client_iob);
+ }
+ else
+ {
+ list_remove_all(csp->headers);
+ write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED));
+ ret = create_client_ssl_connection(csp);
}
log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
@@ -3632,7 +3683,7 @@ static void chat(struct client_state *csp)
* We have created SSL connection with client and server, so now we can receive
* client request header over ssl, filter it and send it to the server.
*/
- if (csp->http->ssl && !csp->use_ssl_tunnel)
+ if ((csp->http->ssl && !csp->use_ssl_tunnel) || should_send_crunch_rsp)
{
if (process_client_request(csp))
{
@@ -3648,15 +3699,23 @@ static void chat(struct client_state *csp)
log_applied_actions(csp->action);
- if (send_http_request(csp))
+ if (should_send_crunch_rsp)
+ {
+ crunch_response_triggered(csp, crunchers_all);
+ return;
+ }
+ else
{
- rsp = error_response(csp, "connect-failed");
- if (rsp)
+ if (send_http_request(csp))
{
- send_crunch_response(csp, rsp);
+ rsp = error_response(csp, "connect-failed");
+ if (rsp)
+ {
+ send_crunch_response(csp, rsp);
+ }
+ close_client_and_server_ssl_connections(csp);
+ return;
}
- close_client_and_server_ssl_connections(csp);
- return;
}
}
--
2.26.2
From 51946d40f052d7ff4d58142e8a7bee9b90b76050 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:03:57 +0200
Subject: [PATCH 60/83] Added CONNECT into supported method. No error log will
be loged.
---
cgi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/cgi.c b/cgi.c
index 75228285..5dd5d2ba 100644
--- a/cgi.c
+++ b/cgi.c
@@ -399,7 +399,8 @@ struct http_response *dispatch_cgi(struct client_state *csp)
}
if (strcmpic(csp->http->gpc, "GET")
- && strcmpic(csp->http->gpc, "HEAD"))
+ && strcmpic(csp->http->gpc, "HEAD")
+ && strcmpic(csp->http->gpc, "CONNECT"))
{
log_error(LOG_LEVEL_ERROR,
"CGI request with unsupported method received: %s", csp->http->gpc);
--
2.26.2
From aba5d61f1bc1cd2854c78cf2ea3414415b59eeb6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:14:49 +0200
Subject: [PATCH 61/83] Edited functions to create and close ssl connections to
set all flags and variables needed for keeping ssl session alive. Changed
functions (server|client)_use_ssl() to check, whether ssl connection is
really opened and ready to be used. Added new variables for ssl session reuse
into http_request, client_state and reusable_connection structures.
---
project.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
ssl_libressl.c | 41 +++++++++++++++++++++++++++++++---------
ssl_libressl.h | 3 +++
3 files changed, 86 insertions(+), 9 deletions(-)
diff --git a/project.h b/project.h
index 50e0960c..40b62818 100644
--- a/project.h
+++ b/project.h
@@ -345,6 +345,7 @@ struct http_request
int server_ssl;
unsigned char hash_of_host_hex[(HASH_OF_HOST_BUF_SIZE * 2) + 1]; /**< chars for hash in hex string and one for '\0' */
unsigned char hash_of_host[HASH_OF_HOST_BUF_SIZE + 1]; /**< chars for bytes of hash and one for '\0' */
+ int should_be_crunched; /* TRUE when crunch response should be send */
};
#ifdef FEATURE_MBEDTLS
@@ -771,6 +772,7 @@ struct reusable_connection
{
jb_socket sfd;
int in_use;
+ int ssl; /* connection use ssl */
time_t timestamp; /* XXX: rename? */
time_t request_sent;
@@ -794,6 +796,14 @@ struct reusable_connection
int gateway_port;
char *forward_host;
int forward_port;
+
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ /* Client connect request is kept here to be prepared in case
+ * when we use parent proxy server and we would have to
+ * restore ssl connection with server
+ */
+ struct list connect_headers[1];
+#endif
};
@@ -968,6 +978,44 @@ struct reusable_connection
#define CSP_FLAG_FUZZED_INPUT 0x08000000U
#endif
+/*
+ * Flags for use in csp->flags
+ */
+
+/**
+ * Flag for csp->ssl_flags: Set if ssl connection with server is
+ * being reused.
+ */
+#define CSP_SSL_FLAG_SERVER_CONNECTION_REUSED 0x01U
+
+
+/**
+ * Flag for csp->ssl_flags: Set if ssl connection with client is
+ * being reused.
+ */
+#define CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED 0x02U
+
+/**
+ * Flag for csp->ssl_flags: Set if we can't close ssl connection
+ * because of future reusing.
+ */
+#define CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED 0x04U
+
+
+/**
+ * Flag for csp->ssl_flags: Set if we should close ssl connection
+ * with server, because it can be tainted.
+ */
+#define CSP_SSL_FLAG_SERVER_CONNECTION_TAINTED 0x08U
+
+
+/**
+ * Flag for csp->ssl_flags: Set if we should close ssl connection
+ * with server and no reason is specified.
+ */
+#define CSP_SSL_FLAG_CLOSE_SERVER_CONNECTION 0x10U
+
+
/*
* Flags for use in return codes of child processes
*/
@@ -1019,6 +1067,9 @@ struct client_state
/** Multi-purpose flag container, see CSP_FLAG_* above */
unsigned int flags;
+ /** Multi-purpose flag container, see CSP_SSL_FLAG_* above */
+ unsigned int ssl_flags;
+
/** Client PC's IP address, as reported by the accept() function.
As a string. */
char *ip_addr_str;
diff --git a/ssl_libressl.c b/ssl_libressl.c
index 185ac2e8..7d8bcd79 100644
--- a/ssl_libressl.c
+++ b/ssl_libressl.c
@@ -192,6 +192,11 @@ extern int create_server_ssl_connection(struct client_state *csp)
BIO_set_ssl(csp->ssl_server_attr.ssl_bio, csp->ssl_server_attr.ssl, BIO_CLOSE);
csp->ssl_with_server_is_opened = 1;
+ csp->server_connection.ssl = 1;
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ csp->ssl_flags &= ~CSP_SSL_FLAG_SERVER_CONNECTION_TAINTED;
+ csp->ssl_flags &= ~CSP_SSL_FLAG_SERVER_CONNECTION_REUSED;
+#endif
ret = 0;
exit:
if (ret == -1) {
@@ -236,11 +241,17 @@ static void free_server_ssl_structures(struct client_state *csp)
* Returns : N/A
*
**********************************************************************/
-static void close_server_ssl_connection(struct client_state *csp)
+extern void close_server_ssl_connection(struct client_state *csp)
{
int ret = 0;
-
- if (csp->ssl_with_server_is_opened == 0)
+
+ if (csp->ssl_with_server_is_opened == 0
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ || (csp->ssl_flags & CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED
+ && !(csp->ssl_flags & CSP_SSL_FLAG_SERVER_CONNECTION_TAINTED)
+ && !(csp->ssl_flags & CSP_SSL_FLAG_CLOSE_SERVER_CONNECTION))
+#endif
+ )
{
return;
}
@@ -252,6 +263,11 @@ static void close_server_ssl_connection(struct client_state *csp)
free_server_ssl_structures(csp);
csp->ssl_with_server_is_opened = 0;
+ csp->server_connection.ssl = 0;
+
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ csp->ssl_flags &= ~CSP_SSL_FLAG_CLOSE_SERVER_CONNECTION;
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
}
@@ -289,11 +305,15 @@ static void free_client_ssl_structures(struct client_state *csp)
* Returns : N/A
*
*********************************************************************/
-static void close_client_ssl_connection(struct client_state *csp)
+extern void close_client_ssl_connection(struct client_state *csp)
{
int ret = 0;
-
- if (csp->ssl_with_client_is_opened == 0)
+
+ if (csp->ssl_with_client_is_opened == 0
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ || csp->ssl_flags & CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED
+#endif
+ )
{
return;
}
@@ -465,6 +485,9 @@ extern int create_client_ssl_connection(struct client_state *csp) {
BIO_set_ssl(csp->ssl_client_attr.ssl_bio, csp->ssl_client_attr.ssl, BIO_CLOSE);
csp->ssl_with_client_is_opened = 1;
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ csp->ssl_flags &= ~CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED;
+#endif
ret = 0;
exit:
if (ret != 0) {
@@ -491,7 +514,7 @@ exit:
*********************************************************************/
extern int client_use_ssl(struct client_state *csp)
{
- return csp->http->client_ssl;
+ return csp->ssl_with_client_is_opened;
}
@@ -511,7 +534,7 @@ extern int client_use_ssl(struct client_state *csp)
*********************************************************************/
extern int server_use_ssl(struct client_state *csp)
{
- return csp->http->server_ssl;
+ return csp->ssl_with_server_is_opened;
}
@@ -633,7 +656,7 @@ exit:
*
* Function : is_ssl_pending
*
- * Description : Returns return the number of pending characters in
+ * Description : Returns the number of pending characters in
* the BIO's read and write buffers.
*
* Parameters :
diff --git a/ssl_libressl.h b/ssl_libressl.h
index ada709a1..35601d2a 100644
--- a/ssl_libressl.h
+++ b/ssl_libressl.h
@@ -51,5 +51,8 @@ extern void ssl_send_certificate_error(struct client_state *csp);
extern int create_client_ssl_connection(struct client_state *csp);
extern int create_server_ssl_connection(struct client_state *csp);
extern void close_client_and_server_ssl_connections(struct client_state *csp);
+extern void close_server_ssl_connection(struct client_state *csp);
+extern void close_client_ssl_connection(struct client_state *csp);
+
#endif /* ndef SSL_LIBRESSL_H_INCLUDED */
\ No newline at end of file
--
2.26.2
From bd7ee06f046580dcb087692c77a317ca99263e0a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:16:51 +0200
Subject: [PATCH 62/83] Added function connection_is_still_alive which checks
also state of ssl connection when it's used. SSL variable in
reusable_connection structure in gateway.c is set, cleaned and checked when
reused_connection is stored, closed or compared. Cleaning ssl variable in
urlmatch.c when client request starts with 'http://', because previous client
request could be over ssl.
---
gateway.c | 5 ++++-
jbsockets.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++
jbsockets.h | 1 +
urlmatch.c | 4 +++-
4 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/gateway.c b/gateway.c
index c84e3b28..ccb12ede 100644
--- a/gateway.c
+++ b/gateway.c
@@ -222,6 +222,7 @@ void remember_connection(const struct reusable_connection *connection)
reusable_connection[slot].host = strdup_or_die(connection->host);
reusable_connection[slot].sfd = connection->sfd;
reusable_connection[slot].port = connection->port;
+ reusable_connection[slot].ssl = connection->ssl;
reusable_connection[slot].in_use = 0;
reusable_connection[slot].timestamp = connection->timestamp;
reusable_connection[slot].request_sent = connection->request_sent;
@@ -289,6 +290,7 @@ void mark_connection_closed(struct reusable_connection *closed_connection)
closed_connection->gateway_port = 0;
freez(closed_connection->forward_host);
closed_connection->forward_port = 0;
+ closed_connection->ssl = 0;
}
@@ -359,7 +361,8 @@ int connection_destination_matches(const struct reusable_connection *connection,
if ((connection->forwarder_type != fwd->type)
|| (connection->gateway_port != fwd->gateway_port)
|| (connection->forward_port != fwd->forward_port)
- || (connection->port != http->port))
+ || (connection->port != http->port)
+ || (connection->ssl != http->ssl))
{
return FALSE;
}
diff --git a/jbsockets.c b/jbsockets.c
index b4bed371..5a25fab1 100644
--- a/jbsockets.c
+++ b/jbsockets.c
@@ -1681,6 +1681,66 @@ int socket_is_still_alive(jb_socket sfd)
}
+
+/*********************************************************************
+ *
+ * Function : connection_is_still_alive
+ *
+ * Description : Figures out whether or not a specified connection
+ * is still alive. Including test of ssl connection.
+ * (Whether "close notify" alert was received)
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ * 2 : src = Value from communication_side enum
+ *
+ * Returns : TRUE for yes, otherwise FALSE.
+ *
+ *********************************************************************/
+extern int connection_is_still_alive(const struct client_state *csp, int src)
+{
+#if defined(FEATURE_MBEDTLS) || defined(FEATURE_LIBRESSL)
+ int is_using_ssl = 0;
+ SSL *ssl;
+ char tmp[10];
+
+ if (src == CLIENT)
+ {
+ is_using_ssl = csp->ssl_with_client_is_opened;
+ ssl = csp->ssl_client_attr.ssl;
+ }
+ else if (src == SERVER)
+ {
+ is_using_ssl = csp->ssl_with_server_is_opened;
+ ssl = csp->ssl_server_attr.ssl;
+ }
+
+ /*
+ * We have to call data_is_available_tcp_ssl and SSL_peek, because
+ * it loads SSL shutdown flag, which signals whether "close notify"
+ * alert was received or not.
+ */
+ if (is_using_ssl && data_is_available_tcp_ssl(csp, src, 0)) {
+ SSL_peek(ssl, tmp, 1);
+ if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN)
+ {
+ return FALSE;
+ }
+ }
+#endif
+ if (src == CLIENT)
+ {
+ return socket_is_still_alive(csp->cfd);
+ }
+ else if (src == SERVER)
+ {
+ return socket_is_still_alive(csp->server_connection.sfd);
+ }
+
+ return FALSE;
+}
+
+
#ifdef FEATURE_EXTERNAL_FILTERS
/*********************************************************************
*
@@ -1925,6 +1985,7 @@ extern int flush_socket(const struct client_state *csp, int dest, struct iob *io
*********************************************************************/
extern int data_is_available_tcp_ssl(const struct client_state *csp, int src, int seconds_to_wait) {
int ret = 0;
+
if (src == CLIENT)
{
#if defined FEATURE_LIBRESSL || defined FEATURE_MBEDTLS
diff --git a/jbsockets.h b/jbsockets.h
index 6fdbc429..63b50d7c 100644
--- a/jbsockets.h
+++ b/jbsockets.h
@@ -61,6 +61,7 @@ extern void get_host_information(jb_socket afd, char **ip_address, char **port,
extern unsigned long resolve_hostname_to_ip(const char *host);
extern int socket_is_still_alive(jb_socket sfd);
+extern int connection_is_still_alive(const struct client_state *csp, int src);
#ifdef FEATURE_EXTERNAL_FILTERS
extern void mark_socket_for_close_on_execute(jb_socket fd);
diff --git a/urlmatch.c b/urlmatch.c
index 0a6b7478..65e411e6 100644
--- a/urlmatch.c
+++ b/urlmatch.c
@@ -260,6 +260,7 @@ jb_err parse_http_url(const char *url, struct http_request *http, int require_pr
if (strncmpic(url_noproto, "http://", 7) == 0)
{
url_noproto += 7;
+ http->ssl = 0;
}
else if (strncmpic(url_noproto, "https://", 8) == 0)
{
@@ -279,7 +280,8 @@ jb_err parse_http_url(const char *url, struct http_request *http, int require_pr
* When we are receiving http request over ssl, there is
* no host, but we should have it from CONNECT request.
*/
- if (http->client_ssl == 0) {
+ if (http->client_ssl == 0)
+ {
http->host = NULL;
}
host_available = 0;
--
2.26.2
From 6d227c3dcd14aa3443240c0f2fa9416cdc00eb9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:17:44 +0200
Subject: [PATCH 63/83] Changed client request processing, when request was
received over reused ssl connection. When we have reused ssl connection, we
already know destination and we receive only relative URI in request. We also
have to set all flags when reusing ssl connection, change behaving for ssl
tunnels and do other smaller changes.
---
jcc.c | 57 ++++++++++++++++++++++++++++++++++++-------------------
parsers.c | 27 +++++++++++++++++++++++---
parsers.h | 2 +-
3 files changed, 62 insertions(+), 24 deletions(-)
diff --git a/jcc.c b/jcc.c
index 041d951e..b0ee529d 100644
--- a/jcc.c
+++ b/jcc.c
@@ -571,7 +571,12 @@ static jb_err get_request_destination_elsewhere(struct client_state *csp, struct
{
char *req;
- if (!(csp->config->feature_flags & RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS))
+ if (!(csp->config->feature_flags & RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS)
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ /* When ssl sesions are reused, we get only relative URI */
+ && !(csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED)
+#endif
+ )
{
log_error(LOG_LEVEL_ERROR, "%s's request: \'%s\' is invalid."
" Privoxy isn't configured to accept intercepted requests.",
@@ -586,7 +591,13 @@ static jb_err get_request_destination_elsewhere(struct client_state *csp, struct
return JB_ERR_PARSE;
}
- else if (JB_ERR_OK == get_destination_from_headers(headers, csp->http))
+ else if (JB_ERR_OK == get_destination_from_headers(headers, csp->http,
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ (csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED) != 0
+#else
+ FALSE
+#endif
+ ))
{
#ifndef FEATURE_EXTENDED_HOST_PATTERNS
/* Split the domain we just got for pattern matching */
@@ -1666,7 +1677,10 @@ static char *get_request_line(struct client_state *csp)
}
len = recv_data(csp, CLIENT, (unsigned char*)buf, sizeof(buf) - 1);
- if (len <= 0) return NULL;
+ if (len <= 0)
+ {
+ return NULL;
+ }
/*
* If there is no memory left for buffering the
@@ -2039,6 +2053,7 @@ static jb_err receive_client_request(struct client_state *csp)
/* grab the rest of the client's headers */
init_list(headers);
+
for (;;)
{
p = get_header(csp->client_iob);
@@ -2177,14 +2192,13 @@ static jb_err parse_client_request(struct client_state *csp)
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
- && (!strcmpic(csp->http->ver, "HTTP/1.1"))
- && (csp->http->ssl == 0))
+ && (!strcmpic(csp->http->ver, "HTTP/1.1")))
{
/* Assume persistence until further notice */
csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
}
- if (csp->http->ssl == 0)
+ if (!csp->use_ssl_tunnel)
{
/*
* This whole block belongs to chat() but currently
@@ -2205,6 +2219,10 @@ static jb_err parse_client_request(struct client_state *csp)
}
else
{
+ /*
+ * It's ssl connection with tunnel, so we want to close connection
+ * when session ends.
+ */
csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
}
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
@@ -3376,7 +3394,7 @@ static void handle_established_connection(struct client_state *csp)
*
* Request can be received over tcp or ssl connection.
* Source will depend on the variable
- * csp->http->client_ssl.
+ * csp->ssl_with_client_is_opened.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
@@ -3396,6 +3414,15 @@ static int process_client_request(struct client_state *csp) {
return 1;
}
+ /*
+ * Setting flags to use old solution with SSL tunel and to disable
+ * certificates verification.
+ */
+ if (http->ssl && csp->action->flags & ACTION_DISABLE_HTTPS_FILTER)
+ {
+ csp->use_ssl_tunnel = 1;
+ }
+
if (parse_client_request(csp) != JB_ERR_OK)
{
log_error(LOG_LEVEL_ERROR, "Parsing client request failed");
@@ -3413,24 +3440,16 @@ static int process_client_request(struct client_state *csp) {
return 1;
}
- /*
- * Setting flags to use old solution with SSL tunel and to disable
- * certificates verification.
- */
- if (http->ssl && csp->action->flags & ACTION_DISABLE_HTTPS_FILTER)
- {
- csp->use_ssl_tunnel = 1;
- }
-
if (http->ssl && csp->action->flags & ACTION_IGNORE_CERTIFICATE_ERRORS)
{
csp->dont_verify_certificate = 1;
}
/*
- * Presetting SSL client and server flags
+ * Presetting SSL client and server flags when ssl will be used.
+ * No matter who will create it. (client or proxy)
*/
- if (http->ssl && !csp->use_ssl_tunnel)
+ if (http->ssl)
{
http->client_ssl = 1;
http->server_ssl = 1;
@@ -3475,8 +3494,6 @@ static void chat(struct client_state *csp)
int ret = 0;
http = csp->http;
- http->client_ssl = 0;
- http->server_ssl = 0;
csp->dont_verify_certificate = 0;
ret = process_client_request(csp);
diff --git a/parsers.c b/parsers.c
index f56345fe..a9eb3b09 100644
--- a/parsers.c
+++ b/parsers.c
@@ -4408,7 +4408,8 @@ static jb_err parse_time_header(const char *header, time_t *result)
*
* Description : Parse the "Host:" header to get the request's destination.
* Only needed if the client's request was forcefully
- * redirected into Privoxy.
+ * redirected into Privoxy or when https request was received
+ * from reused client connection.
*
* Code mainly copied from client_host() which is currently
* run too late for this purpose.
@@ -4417,13 +4418,15 @@ static jb_err parse_time_header(const char *header, time_t *result)
* 1 : headers = List of headers (one of them hopefully being
* the "Host:" header)
* 2 : http = storage for the result (host, port and hostport).
+ * 3 : reused_ssl_connection = TRUE when headers were received over
+ * reused ssl connection
*
* Returns : JB_ERR_MEMORY (or terminates) in case of memory problems,
* JB_ERR_PARSE if the host header couldn't be found,
* JB_ERR_OK otherwise.
*
*********************************************************************/
-jb_err get_destination_from_headers(const struct list *headers, struct http_request *http)
+jb_err get_destination_from_headers(const struct list *headers, struct http_request *http, const int reused_ssl_connection)
{
char *q;
char *p;
@@ -4454,7 +4457,25 @@ jb_err get_destination_from_headers(const struct list *headers, struct http_requ
}
else
{
- http->port = 80;
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ if (reused_ssl_connection)
+ {
+ http->port = 443;
+ }
+ else
+#endif
+ {
+ http->port = 80;
+ }
+ }
+
+ /*
+ * When connection is reused, we shouldn't send requests with
+ * absolute URIs, because destination is already known.
+ */
+ if (reused_ssl_connection)
+ {
+ return JB_ERR_OK;
}
/* Rebuild request URL */
diff --git a/parsers.h b/parsers.h
index d4cfc1c1..03243742 100644
--- a/parsers.h
+++ b/parsers.h
@@ -58,7 +58,7 @@ extern char *get_header_value(const struct list *header_list, const char *header
extern jb_err sed(struct client_state *csp, int filter_server_headers);
extern jb_err update_server_headers(struct client_state *csp);
extern void get_http_time(int time_offset, char *buf, size_t buffer_size);
-extern jb_err get_destination_from_headers(const struct list *headers, struct http_request *http);
+extern jb_err get_destination_from_headers(const struct list *headers, struct http_request *http, const int reused_ssl_connection);
extern unsigned long long get_expected_content_length(struct list *headers);
extern jb_err client_transfer_encoding(struct client_state *csp, char **header);
--
2.26.2
From f8228957baa9942273b0ab449178411ba79a51c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:19:47 +0200
Subject: [PATCH 64/83] Changed creating of server connection. Added check,
whether ssl connection is alive when it should be reused. Also changed
behaving when parent proxy server is used and it's connection already
timeouted. Then proxy tries to restore this connection.
---
jcc.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 56 insertions(+), 14 deletions(-)
diff --git a/jcc.c b/jcc.c
index b0ee529d..9a8fe2e8 100644
--- a/jcc.c
+++ b/jcc.c
@@ -747,7 +747,7 @@ static int create_server_connection(struct client_state *csp) {
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
if ((csp->server_connection.sfd != JB_INVALID_SOCKET)
- && socket_is_still_alive(csp->server_connection.sfd)
+ && connection_is_still_alive(csp, SERVER)
&& connection_destination_matches(&csp->server_connection, http, fwd))
{
log_error(LOG_LEVEL_CONNECT,
@@ -767,11 +767,18 @@ static int create_server_connection(struct client_state *csp) {
else
#endif /* def FEATURE_CONNECTION_SHARING */
{
+ /*
+ * Connection with server is not alive anymore. We can close it,
+ * and then we can open new one to the same destination.
+ */
log_error(LOG_LEVEL_CONNECT,
- "Closing server socket %d connected to %s. Total requests: %u.",
+ "Closing server ssl connection and server socket %d "
+ "connected to %s. Total requests: %u.",
csp->server_connection.sfd, csp->server_connection.host,
csp->server_connection.requests_sent_total);
- close_socket(csp->server_connection.sfd);
+ csp->ssl_flags |= CSP_SSL_FLAG_CLOSE_SERVER_CONNECTION;
+ close_server_ssl_connection(csp);
+ drain_and_close_socket(csp->server_connection.sfd);
}
mark_connection_closed(&csp->server_connection);
}
@@ -834,7 +841,34 @@ static int create_server_connection(struct client_state *csp) {
char server_response[BUFFER_SIZE];
int ret = 0;
int len = 0;
- char *hdr = list_to_text(csp->headers);
+ char *hdr = NULL;
+
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ if (csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED)
+ {
+ /*
+ * Connection with parent proxy is going to be restored,
+ * so we have to send CONNECT request first.
+ */
+ hdr = list_to_text(csp->server_connection.connect_headers);
+ log_error(LOG_LEVEL_CONNECT, "Going to restore ssl connection with parent proxy"
+ "- sending original CONNECT request.");
+ }
+ else
+ {
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+ hdr = list_to_text(csp->headers);
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ /*
+ * Creating copy of CONNECT header for ssl connection restoring.
+ */
+ if (csp->ssl_flags & CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED)
+ {
+ list_duplicate(csp->server_connection.connect_headers, csp->headers);
+ }
+ list_remove_all(csp->headers);
+ }
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
memset(server_response, 0, sizeof(server_response));
if (hdr == NULL)
@@ -921,18 +955,27 @@ static int create_server_connection(struct client_state *csp) {
return 1;
}
-
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
/*
- * SSL/TLS connection with parent proxy is established, we can
- * inform client about success.
+ * When ssl connection with client is reused, client has no
+ * idea about server connection restoring so we can't send
+ * information about it to him.
*/
- ret = write_socket(csp->cfd, server_response, len);
- if (ret != 0)
+ if (!(csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED))
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
{
- log_error(LOG_LEVEL_ERROR,
- "Sending parent proxy response to client failed");
- mark_server_socket_tainted(csp);
- return 1;
+ /*
+ * SSL/TLS connection with parent proxy is established, we can
+ * inform client about success.
+ */
+ ret = write_socket(csp->cfd, server_response, len);
+ if (ret != 0)
+ {
+ log_error(LOG_LEVEL_ERROR,
+ "Sending parent proxy response to client failed");
+ mark_server_socket_tainted(csp);
+ return 1;
+ }
}
}
else
@@ -966,7 +1009,6 @@ static int create_server_connection(struct client_state *csp) {
return 1;
}
-
log_error(LOG_LEVEL_CONNECT, "SSL connection with server was created successfully");
}
}
--
2.26.2
From 15f6676481759acec65cf2913e99e41c4a8adedd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:20:55 +0200
Subject: [PATCH 65/83] Setting flags for ssl sessions reusing at the begining
of chat function. Crunch responses over reused ssl connection with client are
send immediatelly. Added check if client ssl connection is already created,
to avoid second connection openning. When connection is reused, we didn't
received CONNECT request so received client requests are sent immediately to
server and then is called function handle_established_connection. Fixed bug -
removed list items freeing, which was redundant.
---
jcc.c | 197 ++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 129 insertions(+), 68 deletions(-)
diff --git a/jcc.c b/jcc.c
index 9a8fe2e8..b2c3b57b 100644
--- a/jcc.c
+++ b/jcc.c
@@ -876,7 +876,6 @@ static int create_server_connection(struct client_state *csp) {
log_error(LOG_LEVEL_FATAL,
"Out of memory parsing client header");
}
- list_remove_all(csp->headers);
/*
* Sending client's CONNECT request to the parent proxy
@@ -3532,14 +3531,33 @@ static void chat(struct client_state *csp)
/* Skeleton for HTTP response, if we should intercept the request */
struct http_response *rsp;
struct http_response *crunch_rsp;
- int should_send_crunch_rsp = FALSE;
+ int should_prepare_crunch_rsp = FALSE;
int ret = 0;
http = csp->http;
csp->dont_verify_certificate = 0;
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ /*
+ * Setting flags when we should reuse ssl connections and we have
+ * already created ssl connection which we are reusing.
+ */
+ if (csp->ssl_flags & CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED)
+ {
+ if (csp->ssl_with_client_is_opened)
+ {
+ csp->ssl_flags |= CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED;
+ }
+ if (csp->ssl_with_server_is_opened)
+ {
+ csp->ssl_flags |= CSP_SSL_FLAG_SERVER_CONNECTION_REUSED;
+ }
+ }
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+
ret = process_client_request(csp);
- if (ret != 0) {
+ if (ret != 0)
+ {
return;
}
fwd = csp->use_fwd;
@@ -3608,8 +3626,13 @@ static void chat(struct client_state *csp)
/*
* We have a request. Check if one of the crunchers wants it.
*/
- should_send_crunch_rsp = should_trigger_crunch_response(csp, crunchers_all, !http->ssl, &crunch_rsp);
- if (should_send_crunch_rsp && !http->ssl)
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ should_prepare_crunch_rsp = csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED || !http->ssl;
+#else
+ should_prepare_crunch_rsp = !http->ssl;
+#endif
+ http->should_be_crunched = should_trigger_crunch_response(csp, crunchers_all, should_prepare_crunch_rsp, &crunch_rsp);
+ if (http->should_be_crunched && should_prepare_crunch_rsp)
{
send_crunch_response(csp, crunch_rsp);
/*
@@ -3634,7 +3657,8 @@ static void chat(struct client_state *csp)
/*
* Preparing connection with requested server.
*/
- if (!should_send_crunch_rsp) {
+ if (!http->should_be_crunched)
+ {
ret = create_server_connection(csp);
if (ret != 0)
{
@@ -3643,100 +3667,137 @@ static void chat(struct client_state *csp)
csp->server_connection.requests_sent_total++;
}
- if (!should_send_crunch_rsp)
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ /*
+ * When we are reusing connection with client, we don't want
+ * to creat new connection again.
+ */
+ if (!(csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED))
{
- if ((fwd->type == SOCKS_5T) && (NULL == csp->headers->first))
- {
- /* Client headers have been sent optimistically */
- assert(csp->headers->last == NULL);
- }
- else if ((fwd->forward_host && csp->use_ssl_tunnel) || http->ssl == 0)
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+ if (!http->should_be_crunched)
{
- if (send_http_request(csp))
+ if ((fwd->type == SOCKS_5T) && (NULL == csp->headers->first))
{
- rsp = error_response(csp, "connect-failed");
- if (rsp)
- {
- send_crunch_response(csp, rsp);
- }
- return;
+ /* Client headers have been sent optimistically */
+ assert(csp->headers->last == NULL);
}
- }
- else
- {
- /*
- * Using old solution with SSL tunnel or new solution with SSL proxy
- */
- list_remove_all(csp->headers);
- if (csp->use_ssl_tunnel)
+ else if ((fwd->forward_host && csp->use_ssl_tunnel) || http->ssl == 0)
{
- /*
- * We're running an SSL tunnel and we're not forwarding,
- * so just ditch the client headers, send the "connect succeeded"
- * message to the client, flush the rest, and get out of the way.
- */
- if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
+ if (send_http_request(csp))
{
+ rsp = error_response(csp, "connect-failed");
+ if (rsp)
+ {
+ send_crunch_response(csp, rsp);
+ }
return;
}
}
else
{
/*
- * Creating an SSL proxy. If forwarding is disabled, we must send
- * CSUCCEED mesage to client. Then SSL/TLS connection with client
- * is created.
+ * Using old solution with SSL tunnel or new solution with SSL proxy
*/
-
- if (fwd->forward_host == NULL)
+ list_remove_all(csp->headers);
+ if (csp->use_ssl_tunnel)
{
+ /*
+ * We're running an SSL tunnel and we're not forwarding,
+ * so just ditch the client headers, send the "connect succeeded"
+ * message to the client, flush the rest, and get out of the way.
+ */
if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
{
- log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
- close_client_and_server_ssl_connections(csp);
return;
}
}
-
- ret = create_client_ssl_connection(csp);
- if (ret != 0)
+ else
{
- log_error(LOG_LEVEL_ERROR,
- "Can't open secure connection with client");
- close_client_and_server_ssl_connections(csp);
- return;
- }
+ /*
+ * Creating an SSL proxy. If forwarding is disabled, we must send
+ * CSUCCEED mesage to client. Then SSL/TLS connection with client
+ * is created.
+ */
- /*
- * If server certificate is invalid, we must inform client and then
- * close connection with client.
- */
+ if (fwd->forward_host == NULL)
+ {
+ if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
+ {
+ log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
+ close_client_and_server_ssl_connections(csp);
+ return;
+ }
+ }
+
+ ret = create_client_ssl_connection(csp);
+ if (ret != 0)
+ {
+ log_error(LOG_LEVEL_ERROR,
+ "Can't open secure connection with client");
+#ifndef FEATURE_CONNECTION_KEEP_ALIVE
+ close_client_and_server_ssl_connections(csp);
+#endif
+ return;
+ }
+
+ /*
+ * If server certificate is invalid, we must inform client and then
+ * close connection with client.
+ */
#ifdef FEATURE_MBEDTLS
- if (csp->server_cert_verification_result != SSL_CERT_VALID)
+ if (csp->server_cert_verification_result != SSL_CERT_VALID)
#elif defined(FEATURE_LIBRESSL)
- if (csp->server_cert_verification_result != X509_V_OK)
+ if (csp->server_cert_verification_result != X509_V_OK)
#endif
#if defined(FEATURE_MBEDTLS) || defined(FEATURE_LIBRESSL)
- {
- ssl_send_certificate_error(csp);
- close_client_and_server_ssl_connections(csp);
- return;
- }
+ {
+ ssl_send_certificate_error(csp);
+ close_client_and_server_ssl_connections(csp);
+ return;
+ }
#endif
- log_error(LOG_LEVEL_CONNECT, "SSL connection with client was created successfully");
+ log_error(LOG_LEVEL_CONNECT, "SSL connection with client was created successfully");
+ }
+ clear_iob(csp->client_iob);
}
- clear_iob(csp->client_iob);
+ log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
}
+ else
+ {
+ list_remove_all(csp->headers);
+ if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
+ {
+ log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
+ close_client_and_server_ssl_connections(csp);
+ return;
+ }
+ ret = create_client_ssl_connection(csp);
+ }
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
}
- else
+ else
{
- list_remove_all(csp->headers);
- write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED));
- ret = create_client_ssl_connection(csp);
+ /*
+ * Sending client's request to server, when SSL connection is reused.
+ */
+ freez(csp->headers->first->str);
+ build_request_line(csp, fwd, &csp->headers->first->str);
+
+ if (send_http_request(csp))
+ {
+ rsp = error_response(csp, "connect-failed");
+ if (rsp)
+ {
+ send_crunch_response(csp, rsp);
+ }
+ mark_server_socket_tainted(csp);
+ close_client_and_server_ssl_connections(csp);
+ return;
+ }
}
-
- log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
/*
* We have created SSL connection with client and server, so now we can receive
--
2.26.2
From 338d38acf171b88c3954353cdddfb62fc9422d70 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:22:34 +0200
Subject: [PATCH 66/83] When ssl connection is reused, second request
processing is turned off, because there isn't any second request part. When
ssl connection is reused and tainted, ssl connections are closed properly.
(function serve) Setting ssl_flags when server socket is marked as tainted
and before serving new client request.
---
jcc.c | 53 +++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 45 insertions(+), 8 deletions(-)
diff --git a/jcc.c b/jcc.c
index b2c3b57b..cfbd8ed5 100644
--- a/jcc.c
+++ b/jcc.c
@@ -1646,6 +1646,12 @@ static void mark_server_socket_tainted(struct client_state *csp)
csp->server_connection.sfd);
}
csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ if (csp->http->server_ssl)
+ {
+ csp->ssl_flags |= CSP_SSL_FLAG_SERVER_CONNECTION_TAINTED;
+ }
+#endif
}
@@ -2586,7 +2592,7 @@ static void handle_established_connection(struct client_state *csp)
{
log_error(LOG_LEVEL_CONNECT, "Socket timeout %d reached: %s",
csp->config->socket_timeout, http->url);
- if ((byte_count == 0) && (http->ssl == 0))
+ if (byte_count == 0)
{
send_crunch_response(csp, error_response(csp, "connection-timeout"));
}
@@ -3801,10 +3807,21 @@ static void chat(struct client_state *csp)
/*
* We have created SSL connection with client and server, so now we can receive
- * client request header over ssl, filter it and send it to the server.
+ * client request header over ssl, filter it and send it to the server. Requests
+ * from reused SSL connections were already received.
*/
- if ((csp->http->ssl && !csp->use_ssl_tunnel) || should_send_crunch_rsp)
+ if (((csp->http->ssl && !csp->use_ssl_tunnel) || http->should_be_crunched)
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ && !(csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED)
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+ )
{
+ /*
+ * Preparing flag for processing HTTPS request, so correct value
+ * will be given into function handle_established_connection.
+ */
+ csp->flags &= ~CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
+
if (process_client_request(csp))
{
close_client_and_server_ssl_connections(csp);
@@ -3819,7 +3836,7 @@ static void chat(struct client_state *csp)
log_applied_actions(csp->action);
- if (should_send_crunch_rsp)
+ if (http->should_be_crunched)
{
crunch_response_triggered(csp, crunchers_all);
return;
@@ -4041,7 +4058,8 @@ static void serve(struct client_state *csp)
&& (csp->cfd != JB_INVALID_SOCKET)
&& (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
&& ((csp->flags & CSP_FLAG_SERVER_CONTENT_LENGTH_SET)
- || (csp->flags & CSP_FLAG_CHUNKED));
+ || (csp->flags & CSP_FLAG_CHUNKED))
+ && !(csp->ssl_flags & CSP_SSL_FLAG_SERVER_CONNECTION_TAINTED);
if (!(csp->flags & CSP_FLAG_CRUNCHED)
&& (csp->server_connection.sfd != JB_INVALID_SOCKET))
@@ -4052,6 +4070,7 @@ static void serve(struct client_state *csp)
}
if (!(csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
|| (csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
+ || (csp->ssl_flags & CSP_SSL_FLAG_SERVER_CONNECTION_TAINTED)
|| !socket_is_still_alive(csp->server_connection.sfd)
|| !(latency < csp->server_connection.keep_alive_timeout))
{
@@ -4069,6 +4088,10 @@ static void serve(struct client_state *csp)
forget_connection(csp->server_connection.sfd);
}
#endif /* def FEATURE_CONNECTION_SHARING */
+
+ /* Setting flag to close ssl connections */
+ csp->ssl_flags |= CSP_SSL_FLAG_CLOSE_SERVER_CONNECTION;
+ close_server_ssl_connection(csp);
close_socket(csp->server_connection.sfd);
mark_connection_closed(&csp->server_connection);
}
@@ -4110,8 +4133,8 @@ static void serve(struct client_state *csp)
}
if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
- && data_is_available(csp->cfd, (int)csp->config->keep_alive_timeout)
- && socket_is_still_alive(csp->cfd))
+ && data_is_available_tcp_ssl(csp, CLIENT, (int)csp->config->keep_alive_timeout)
+ && socket_is_still_alive(csp->cfd))
{
log_error(LOG_LEVEL_CONNECT,
"Client request %u arrived in time on socket %d.",
@@ -4148,6 +4171,7 @@ static void serve(struct client_state *csp)
privoxy_mutex_unlock(&connection_reuse_mutex);
}
#endif /* def FEATURE_CONNECTION_SHARING */
+ csp->ssl_flags &= ~CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED;
break;
}
}
@@ -4170,6 +4194,11 @@ static void serve(struct client_state *csp)
chat(csp);
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+ /*
+ * Closing ssl and then tcp connections, if they were opened.
+ */
+ csp->ssl_flags = 0;
+ close_client_and_server_ssl_connections(csp);
if (csp->server_connection.sfd != JB_INVALID_SOCKET)
{
#ifdef FEATURE_CONNECTION_SHARING
@@ -4199,7 +4228,6 @@ static void serve(struct client_state *csp)
free_csp_resources(csp);
csp->flags &= ~CSP_FLAG_ACTIVE;
-
}
@@ -5241,6 +5269,15 @@ static void listen_loop(void)
}
#endif /* def FEATURE_ACL */
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ /* Setting flag to keep ssl connections opened if possible */
+ csp->ssl_flags = 0;
+ if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
+ {
+ csp->ssl_flags = CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED;
+ }
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+
if ((0 != config->max_client_connections)
&& (active_threads >= config->max_client_connections))
{
--
2.26.2
From da65566591bf4f5f7fbb43eb5ee022d3d297952a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:25:32 +0200
Subject: [PATCH 67/83] Removed ssl connection closing after
mark_server_socket_tainted, because ssl connections are closed at the end of
function serve() when tainted flags are set. Variable ssl_flags and defined
flags for it was surrounded by ifdef FEATURE_CONNECTION_KEEP_ALIVE.
---
jcc.c | 22 ++--------------------
project.h | 4 ++++
2 files changed, 6 insertions(+), 20 deletions(-)
diff --git a/jcc.c b/jcc.c
index cfbd8ed5..a62bd152 100644
--- a/jcc.c
+++ b/jcc.c
@@ -2704,7 +2704,6 @@ static void handle_established_connection(struct client_state *csp)
log_error(LOG_LEVEL_ERROR,
"Send request over SSL/TLS to: %s failed", http->host);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
}
@@ -2775,7 +2774,6 @@ static void handle_established_connection(struct client_state *csp)
log_error(LOG_LEVEL_CONNECT,
"The server still wants to talk, but the client hung up on us.");
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
#endif /* def _WIN32 */
}
@@ -2821,7 +2819,6 @@ static void handle_established_connection(struct client_state *csp)
log_error(LOG_LEVEL_ERROR, "Already forwarded the original headers. "
"Unable to tell the client about the problem.");
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
/*
@@ -2950,7 +2947,6 @@ static void handle_established_connection(struct client_state *csp)
freez(hdr);
freez(p);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
}
@@ -2965,7 +2961,6 @@ static void handle_established_connection(struct client_state *csp)
freez(hdr);
freez(p);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
}
@@ -3025,7 +3020,6 @@ static void handle_established_connection(struct client_state *csp)
rsp = cgi_error_memory(csp->ssl_with_client_is_opened);
send_crunch_response(csp, rsp);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
hdrlen = strlen(hdr);
@@ -3046,7 +3040,6 @@ static void handle_established_connection(struct client_state *csp)
"Flush header and buffers to client failed");
freez(hdr);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
}
@@ -3090,7 +3083,6 @@ static void handle_established_connection(struct client_state *csp)
log_error(LOG_LEVEL_ERROR,
"Sending data to client failed");
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
}
@@ -3101,7 +3093,6 @@ static void handle_established_connection(struct client_state *csp)
{
log_error(LOG_LEVEL_ERROR, "write to client failed: %E");
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
}
@@ -3122,7 +3113,6 @@ static void handle_established_connection(struct client_state *csp)
rsp = cgi_error_memory(csp->ssl_with_client_is_opened);
send_crunch_response(csp, rsp);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
@@ -3157,7 +3147,6 @@ static void handle_established_connection(struct client_state *csp)
strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
}
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
else
@@ -3203,7 +3192,6 @@ static void handle_established_connection(struct client_state *csp)
}
free_http_request(http);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
@@ -3243,7 +3231,6 @@ static void handle_established_connection(struct client_state *csp)
free_http_request(http);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
@@ -3272,7 +3259,6 @@ static void handle_established_connection(struct client_state *csp)
}
free_http_request(http);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
hdr = list_to_text(csp->headers);
@@ -3307,7 +3293,6 @@ static void handle_established_connection(struct client_state *csp)
*/
freez(hdr);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
/* Buffer and pcrs filter this if appropriate. */
@@ -3336,7 +3321,6 @@ static void handle_established_connection(struct client_state *csp)
*/
freez(hdr);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
}
@@ -3353,7 +3337,6 @@ static void handle_established_connection(struct client_state *csp)
*/
freez(hdr);
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
}
@@ -3391,14 +3374,12 @@ static void handle_established_connection(struct client_state *csp)
strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
}
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
}
continue;
}
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return; /* huh? we should never get here */
}
@@ -3799,7 +3780,6 @@ static void chat(struct client_state *csp)
send_crunch_response(csp, rsp);
}
mark_server_socket_tainted(csp);
- close_client_and_server_ssl_connections(csp);
return;
}
}
@@ -4197,7 +4177,9 @@ static void serve(struct client_state *csp)
/*
* Closing ssl and then tcp connections, if they were opened.
*/
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
csp->ssl_flags = 0;
+#endif
close_client_and_server_ssl_connections(csp);
if (csp->server_connection.sfd != JB_INVALID_SOCKET)
{
diff --git a/project.h b/project.h
index 40b62818..ecdd75a0 100644
--- a/project.h
+++ b/project.h
@@ -978,6 +978,7 @@ struct reusable_connection
#define CSP_FLAG_FUZZED_INPUT 0x08000000U
#endif
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
/*
* Flags for use in csp->flags
*/
@@ -1015,6 +1016,7 @@ struct reusable_connection
*/
#define CSP_SSL_FLAG_CLOSE_SERVER_CONNECTION 0x10U
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
/*
* Flags for use in return codes of child processes
@@ -1067,8 +1069,10 @@ struct client_state
/** Multi-purpose flag container, see CSP_FLAG_* above */
unsigned int flags;
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
/** Multi-purpose flag container, see CSP_SSL_FLAG_* above */
unsigned int ssl_flags;
+#endif
/** Client PC's IP address, as reported by the accept() function.
As a string. */
--
2.26.2
From f72d7d5b70dbf2db490fa1c91df17ca5e2014e0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:26:44 +0200
Subject: [PATCH 68/83] Replaced socket_is_still_alive for
connection_is_still_alive when it's appropriate. So we are checking also
whether ssl connection is still alive.
---
jcc.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/jcc.c b/jcc.c
index a62bd152..23b66332 100644
--- a/jcc.c
+++ b/jcc.c
@@ -1705,7 +1705,7 @@ static char *get_request_line(struct client_state *csp)
!data_is_available_tcp_ssl(csp, CLIENT, csp->config->socket_timeout)
)
{
- if (socket_is_still_alive(csp->cfd))
+ if (connection_is_still_alive(csp, CLIENT))
{
log_error(LOG_LEVEL_CONNECT,
"No request line on socket %d received in time. Timeout: %d.",
@@ -2765,7 +2765,7 @@ static void handle_established_connection(struct client_state *csp)
* noticed pretty much right away anyway, so we can reduce the
* overhead by skipping the check.
*/
- if (buffer_and_filter_content && !socket_is_still_alive(csp->cfd))
+ if (buffer_and_filter_content && !connection_is_still_alive(csp, CLIENT))
{
#ifdef _WIN32
log_error(LOG_LEVEL_CONNECT,
@@ -4051,7 +4051,7 @@ static void serve(struct client_state *csp)
if (!(csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
|| (csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
|| (csp->ssl_flags & CSP_SSL_FLAG_SERVER_CONNECTION_TAINTED)
- || !socket_is_still_alive(csp->server_connection.sfd)
+ || !connection_is_still_alive(csp, SERVER)
|| !(latency < csp->server_connection.keep_alive_timeout))
{
log_error(LOG_LEVEL_CONNECT,
@@ -4060,7 +4060,7 @@ static void serve(struct client_state *csp)
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),
- socket_is_still_alive(csp->server_connection.sfd),
+ connection_is_still_alive(csp, SERVER),
csp->server_connection.keep_alive_timeout);
#ifdef FEATURE_CONNECTION_SHARING
if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
@@ -4086,7 +4086,7 @@ static void serve(struct client_state *csp)
if (continue_chatting)
{
if (((csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING) != 0)
- && socket_is_still_alive(csp->cfd))
+ && connection_is_still_alive(csp, CLIENT))
{
log_error(LOG_LEVEL_CONNECT, "Client request %d has been "
"pipelined on socket %d and the socket is still alive.",
@@ -4114,7 +4114,7 @@ static void serve(struct client_state *csp)
if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
&& data_is_available_tcp_ssl(csp, CLIENT, (int)csp->config->keep_alive_timeout)
- && socket_is_still_alive(csp->cfd))
+ && connection_is_still_alive(csp, CLIENT))
{
log_error(LOG_LEVEL_CONNECT,
"Client request %u arrived in time on socket %d.",
@@ -4126,7 +4126,7 @@ static void serve(struct client_state *csp)
#ifdef FEATURE_CONNECTION_SHARING
if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
&& (csp->server_connection.sfd != JB_INVALID_SOCKET)
- && (socket_is_still_alive(csp->server_connection.sfd)))
+ && (connection_is_still_alive(csp, SERVER)))
{
time_t time_open = time(NULL) - csp->server_connection.timestamp;
@@ -4164,7 +4164,7 @@ static void serve(struct client_state *csp)
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),
- socket_is_still_alive(csp->server_connection.sfd),
+ connection_is_still_alive(csp, SERVER),
csp->server_connection.keep_alive_timeout,
config_file_change_detected);
}
--
2.26.2
From 9826554914aaceb76a2966c133fa4c4e09615d6f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:28:37 +0200
Subject: [PATCH 69/83] Function connection_is_still_alive adapted to work with
mbedtls. (To check close notification) Added macro FEATURE_SSL in
configuration, which is set when any ssl library is set. Setting ssl_flags in
mbedtls functions and other changes in mbedtls functions to enable ssl
sessions reusing.
---
acconfig.h | 3 +++
configure.in | 6 +++++
jbsockets.c | 50 ++++++++++++++++++++++++++++++++---------
jbsockets.h | 4 ++--
jcc.c | 13 ++++++-----
ssl.c | 61 +++++++++++++++++++++++++++++++++-----------------
ssl.h | 16 +++++++------
ssl_libressl.c | 12 +++++-----
8 files changed, 113 insertions(+), 52 deletions(-)
diff --git a/acconfig.h b/acconfig.h
index 5cdd1290..08eba4ae 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -134,6 +134,9 @@
/* Allow Privoxy to use mbedtls for SSL comunication and filtering. */
#undef FEATURE_MBEDTLS
+/* Some SSL library is allowed to be used. */
+#undef FEATURE_SSL
+
/*
* Allow filtering with scripts and programs.
*/
diff --git a/configure.in b/configure.in
index da4a264e..2908a8ba 100644
--- a/configure.in
+++ b/configure.in
@@ -1096,22 +1096,28 @@ AC_ARG_ENABLE(mbedtls,
[enablembedtls=$enableval],
[enablembedtls=no])
+USAGE_SSL=
if test $enablembedtls = yes; then
echo Enabling mbedtls.
AC_DEFINE(FEATURE_MBEDTLS)
+ AC_DEFINE(FEATURE_SSL)
USAGE_MBEDTLS=
USAGE_LIBRESSL=#
else
if test $disablelibressl = no; then
echo Enabling libressl.
AC_DEFINE(FEATURE_LIBRESSL)
+ AC_DEFINE(FEATURE_SSL)
USAGE_MBEDTLS=#
USAGE_LIBRESSL=
+ else
+ USAGE_SSL=#
fi
fi
AC_SUBST(USAGE_MBEDTLS)
AC_SUBST(USAGE_LIBRESSL)
+AC_SUBST(USAGE_SSL)
dnl =================================================================
dnl END of SSL libraries
diff --git a/jbsockets.c b/jbsockets.c
index 5a25fab1..9391cef6 100644
--- a/jbsockets.c
+++ b/jbsockets.c
@@ -1697,37 +1697,65 @@ int socket_is_still_alive(jb_socket sfd)
* Returns : TRUE for yes, otherwise FALSE.
*
*********************************************************************/
-extern int connection_is_still_alive(const struct client_state *csp, int src)
+extern int connection_is_still_alive(struct client_state *csp, int src)
{
-#if defined(FEATURE_MBEDTLS) || defined(FEATURE_LIBRESSL)
- int is_using_ssl = 0;
+#ifdef FEATURE_SSL
+#ifdef FEATURE_LIBRESSL
SSL *ssl;
- char tmp[10];
+#endif
+#ifdef FEATURE_MBEDTLS
+ mbedtls_ssl_context *ssl;
+#endif
+ int is_using_ssl = 0;
+ unsigned char tmp[10];
if (src == CLIENT)
{
is_using_ssl = csp->ssl_with_client_is_opened;
+#ifdef FEATURE_LIBRESSL
ssl = csp->ssl_client_attr.ssl;
+#endif
+#ifdef FEATURE_MBEDTLS
+ ssl = &csp->ssl_client_attr.ssl;
+#endif
}
else if (src == SERVER)
{
is_using_ssl = csp->ssl_with_server_is_opened;
+#ifdef FEATURE_LIBRESSL
ssl = csp->ssl_server_attr.ssl;
+#endif
+#ifdef FEATURE_MBEDTLS
+ ssl = &csp->ssl_server_attr.ssl;
+#endif
}
- /*
- * We have to call data_is_available_tcp_ssl and SSL_peek, because
- * it loads SSL shutdown flag, which signals whether "close notify"
- * alert was received or not.
- */
if (is_using_ssl && data_is_available_tcp_ssl(csp, src, 0)) {
+#ifdef FEATURE_MBEDTLS
+ /*
+ * mbedtls_ssl_read reads available data and checks connection state.
+ * When connection was closed by peer, closure notifice is returned.
+ * Otherway, no chars are set to given buffer and stay pending.
+ */
+ if (mbedtls_ssl_read(ssl, tmp, 0) == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+ return FALSE;
+ }
+#endif /* def FEATURE_MBEDTLS */
+#ifdef FEATURE_LIBRESSL
+ /*
+ * We have to call data_is_available_tcp_ssl and SSL_peek, because
+ * it loads SSL shutdown flag, which signals whether "close notify"
+ * alert was received or not.
+ */
SSL_peek(ssl, tmp, 1);
if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN)
{
return FALSE;
}
+#endif /* def FEATURE_LIBRESSL */
}
-#endif
+#endif /* def FEATURE_SSL */
+
if (src == CLIENT)
{
return socket_is_still_alive(csp->cfd);
@@ -1806,7 +1834,7 @@ void mark_socket_for_close_on_execute(jb_socket fd)
* value on error.
*
*********************************************************************/
-extern int recv_data(const struct client_state *csp, int src, unsigned char *buf, int maxLen) {
+extern int recv_data(struct client_state *csp, int src, unsigned char *buf, int maxLen) {
if (src == CLIENT)
{
#if defined FEATURE_LIBRESSL || defined FEATURE_MBEDTLS
diff --git a/jbsockets.h b/jbsockets.h
index 63b50d7c..a2934ee2 100644
--- a/jbsockets.h
+++ b/jbsockets.h
@@ -61,14 +61,14 @@ extern void get_host_information(jb_socket afd, char **ip_address, char **port,
extern unsigned long resolve_hostname_to_ip(const char *host);
extern int socket_is_still_alive(jb_socket sfd);
-extern int connection_is_still_alive(const struct client_state *csp, int src);
+extern int connection_is_still_alive(struct client_state *csp, int src);
#ifdef FEATURE_EXTERNAL_FILTERS
extern void mark_socket_for_close_on_execute(jb_socket fd);
#endif
extern int send_data_delayed(const struct client_state *csp, int destination, const char *buf, int len, int delay);
-extern int recv_data(const struct client_state *csp, int source, unsigned char *buf, int maxLen);
+extern int recv_data(struct client_state *csp, int source, unsigned char *buf, int maxLen);
extern int send_data(const struct client_state *csp, int destination, const char *buf, int len);
extern int flush_socket(const struct client_state *csp, int destination, struct iob *iob, unsigned int delay);
extern int data_is_available_tcp_ssl(const struct client_state *csp, int source, int seconds_to_wait);
diff --git a/jcc.c b/jcc.c
index 23b66332..17d253d7 100644
--- a/jcc.c
+++ b/jcc.c
@@ -941,7 +941,8 @@ static int create_server_connection(struct client_state *csp) {
#ifdef FEATURE_MBEDTLS
&& (csp->server_cert_verification_result == SSL_CERT_NOT_VERIFIED
|| csp->server_cert_verification_result == SSL_CERT_VALID)
-#elif defined(FEATURE_LIBRESSL)
+#endif
+#ifdef FEATURE_LIBRESSL
&& (csp->server_cert_verification_result == X509_V_OK)
#endif
)
@@ -995,7 +996,8 @@ static int create_server_connection(struct client_state *csp) {
#ifdef FEATURE_MBEDTLS
&& (csp->server_cert_verification_result == SSL_CERT_NOT_VERIFIED
|| csp->server_cert_verification_result == SSL_CERT_VALID)
-#elif defined(FEATURE_LIBRESSL)
+#endif
+#ifdef FEATURE_LIBRESSL
&& (csp->server_cert_verification_result == X509_V_OK)
#endif
)
@@ -3728,22 +3730,23 @@ static void chat(struct client_state *csp)
return;
}
+#ifdef FEATURE_SSL
/*
* If server certificate is invalid, we must inform client and then
* close connection with client.
*/
#ifdef FEATURE_MBEDTLS
if (csp->server_cert_verification_result != SSL_CERT_VALID)
-#elif defined(FEATURE_LIBRESSL)
+#endif
+#ifdef FEATURE_LIBRESSL
if (csp->server_cert_verification_result != X509_V_OK)
#endif
-#if defined(FEATURE_MBEDTLS) || defined(FEATURE_LIBRESSL)
{
ssl_send_certificate_error(csp);
close_client_and_server_ssl_connections(csp);
return;
}
-#endif
+#endif /* def FEATURE_SSL */
log_error(LOG_LEVEL_CONNECT, "SSL connection with client was created successfully");
}
diff --git a/ssl.c b/ssl.c
index bb9fcf1b..3f4b7580 100644
--- a/ssl.c
+++ b/ssl.c
@@ -88,19 +88,18 @@ static int seed_rng(struct client_state *csp);
*
* Function : client_use_ssl
*
- * Description : Tests if client in current client state structure should use
- * SSL connection or standard connection.
+ * Description : Tests if ssl connection with client is opened.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
*
- * Returns : If client should use SSL/TLS connection, 1 is returned.
+ * Returns : If client uses SSL/TLS connection, 1 is returned.
* Otherwise 0 is returned.
*
*********************************************************************/
extern int client_use_ssl(struct client_state *csp)
{
- return csp->http->client_ssl;
+ return csp->ssl_with_client_is_opened;
}
@@ -108,19 +107,18 @@ extern int client_use_ssl(struct client_state *csp)
*
* Function : server_use_ssl
*
- * Description : Tests if server in current client state structure should use
- * SSL connection or standard connection.
+ * Description : Tests if ssl connection with server is opened.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
*
- * Returns : If server should use SSL/TLS connection, 1 is returned.
- * Otherwise 0 is returned.
+ * Returns : If server uses SSL/TLS connection, 1 is returned.
+ * Otherwise 0 is returned
*
*********************************************************************/
extern int server_use_ssl(struct client_state *csp)
{
- return csp->http->server_ssl;
+ return csp->ssl_with_server_is_opened;
}
@@ -137,7 +135,7 @@ extern int server_use_ssl(struct client_state *csp)
* >0 => Pending data length
*
*********************************************************************/
-extern size_t is_ssl_pending(ssl_connection_attr * connection)
+extern size_t is_ssl_pending(const ssl_connection_attr * connection)
{
if (&(connection->ssl) == NULL)
{
@@ -163,7 +161,7 @@ extern size_t is_ssl_pending(ssl_connection_attr * connection)
* Returns : Length of sent data or negative value on error.
*
*********************************************************************/
-extern int ssl_send_data(ssl_connection_attr * connection, const unsigned char * buf, int len)
+extern int ssl_send_data(const ssl_connection_attr * connection, const unsigned char * buf, int len)
{
int ret = 0;
char err_buf[ERROR_BUF_SIZE];
@@ -199,7 +197,7 @@ extern int ssl_send_data(ssl_connection_attr * connection, const unsigned char *
/*
* Sending one part of the buffer
*/
- while ((ret = mbedtls_ssl_write(&connection->ssl,
+ while ((ret = mbedtls_ssl_write((mbedtls_ssl_context*)&connection->ssl,
(const unsigned char *)(buf + pos),
send_len)) < 0)
{
@@ -237,7 +235,7 @@ extern int ssl_send_data(ssl_connection_attr * connection, const unsigned char *
* nonzero on error.
*
*********************************************************************/
-extern int ssl_send_data_delayed(ssl_connection_attr *connection, const unsigned char *buf, size_t len, unsigned int delay) {
+extern int ssl_send_data_delayed(const ssl_connection_attr *connection, const unsigned char *buf, size_t len, unsigned int delay) {
size_t i = 0;
if (delay == 0)
@@ -329,7 +327,7 @@ extern int ssl_recv_data(ssl_connection_attr *connection, unsigned char * buf, i
* indicates nothing was sent). On error, -1 is returned.
*
*********************************************************************/
-extern long ssl_flush_socket(ssl_connection_attr * connection, struct iob *iob)
+extern long ssl_flush_socket(const ssl_connection_attr * connection, struct iob *iob)
{
/* Computing length of buffer part to send*/
long len = iob->eod - iob->cur;
@@ -585,7 +583,10 @@ extern int create_client_ssl_connection(struct client_state *csp)
log_error(LOG_LEVEL_CONNECT, "Client successfully connected over SSL/TLS");
csp->ssl_with_client_is_opened = 1;
-
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ csp->ssl_flags &= ~CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED;
+#endif
+ ret = 0;
exit:
/*
* Freeing allocated paths to files
@@ -621,11 +622,15 @@ exit:
* Returns : N/A
*
*********************************************************************/
-static void close_client_ssl_connection(struct client_state *csp)
+extern void close_client_ssl_connection(struct client_state *csp)
{
int ret = 0;
- if (csp->ssl_with_client_is_opened == 0)
+ if (csp->ssl_with_client_is_opened == 0
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ || csp->ssl_flags & CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED
+#endif
+ )
{
return;
}
@@ -852,8 +857,13 @@ extern int create_server_ssl_connection(struct client_state *csp)
free_certificate_chain(csp);
csp->ssl_with_server_is_opened = 1;
+ csp->server_connection.ssl = 1;
csp->server_cert_verification_result = mbedtls_ssl_get_verify_result(&(csp->ssl_server_attr.ssl));
-
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ csp->ssl_flags &= ~CSP_SSL_FLAG_SERVER_CONNECTION_TAINTED;
+ csp->ssl_flags &= ~CSP_SSL_FLAG_SERVER_CONNECTION_REUSED;
+#endif
+ ret = 0;
exit:
/* Freeing structures if connection wasn't created successfully */
if (ret < 0)
@@ -878,11 +888,17 @@ exit:
* Returns : N/A
*
**********************************************************************/
-static void close_server_ssl_connection(struct client_state *csp)
+extern void close_server_ssl_connection(struct client_state *csp)
{
int ret = 0;
- if (csp->ssl_with_server_is_opened == 0)
+ if (csp->ssl_with_server_is_opened == 0
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ || (csp->ssl_flags & CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED
+ && !(csp->ssl_flags & CSP_SSL_FLAG_SERVER_CONNECTION_TAINTED)
+ && !(csp->ssl_flags & CSP_SSL_FLAG_CLOSE_SERVER_CONNECTION))
+#endif
+ )
{
return;
}
@@ -896,6 +912,11 @@ static void close_server_ssl_connection(struct client_state *csp)
free_server_ssl_structures(csp);
csp->ssl_with_server_is_opened = 0;
+ csp->server_connection.ssl = 0;
+
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ csp->ssl_flags &= ~CSP_SSL_FLAG_CLOSE_SERVER_CONNECTION;
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
}
diff --git a/ssl.h b/ssl.h
index 1638fa54..d4170cc6 100644
--- a/ssl.h
+++ b/ssl.h
@@ -43,26 +43,28 @@
#define SSL_CERT_NOT_VERIFIED 0xFFFFFFFF
/* Variables for one common RNG for all SSL use */
-static mbedtls_ctr_drbg_context ctr_drbg;
-static mbedtls_entropy_context entropy;
-static int rng_seeded;
+mbedtls_ctr_drbg_context ctr_drbg;
+mbedtls_entropy_context entropy;
+int rng_seeded;
/* Boolean functions to get informations about SSL/TLS connections */
extern int client_use_ssl(struct client_state *csp);
extern int server_use_ssl(struct client_state *csp);
-extern size_t is_ssl_pending(ssl_connection_attr *connection);
+extern size_t is_ssl_pending(const ssl_connection_attr *connection);
extern int tunnel_established_successfully(const char * response, unsigned int response_len);
/* Functions for sending and receiving data over SSL/TLS connections */
-extern int ssl_send_data(ssl_connection_attr * connection, const unsigned char * buf, int len);
-extern int ssl_send_data_delayed(ssl_connection_attr *connection, const unsigned char *buf, size_t len, unsigned int delay);
+extern int ssl_send_data(const ssl_connection_attr * connection, const unsigned char * buf, int len);
+extern int ssl_send_data_delayed(const ssl_connection_attr *connection, const unsigned char *buf, size_t len, unsigned int delay);
extern int ssl_recv_data(ssl_connection_attr * connection, unsigned char * buf, int maxLen);
-extern long ssl_flush_socket(ssl_connection_attr * connection, struct iob *iob);
+extern long ssl_flush_socket(const ssl_connection_attr * connection, struct iob *iob);
extern void ssl_send_certificate_error(struct client_state *csp);
/* Functions for opening and closing SSL/TLS connections */
extern int create_client_ssl_connection(struct client_state *csp);
extern int create_server_ssl_connection(struct client_state *csp);
extern void close_client_and_server_ssl_connections(struct client_state *csp);
+extern void close_server_ssl_connection(struct client_state *csp);
+extern void close_client_ssl_connection(struct client_state *csp);
#endif /* ndef SSL_H_INCLUDED */
diff --git a/ssl_libressl.c b/ssl_libressl.c
index 7d8bcd79..fc3a5f34 100644
--- a/ssl_libressl.c
+++ b/ssl_libressl.c
@@ -502,13 +502,12 @@ exit:
*
* Function : client_use_ssl
*
- * Description : Tests if client in current client state structure should use
- * SSL connection or standard connection.
+ * Description : Tests if ssl connection with client is opened.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
*
- * Returns : If client should use SSL/TLS connection, 1 is returned.
+ * Returns : If client uses SSL/TLS connection, 1 is returned.
* Otherwise 0 is returned.
*
*********************************************************************/
@@ -522,14 +521,13 @@ extern int client_use_ssl(struct client_state *csp)
*
* Function : server_use_ssl
*
- * Description : Tests if server in current client state structure should use
- * SSL connection or standard connection.
+ * Description : Tests if ssl connection with server is opened.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
*
- * Returns : If server should use SSL/TLS connection, 1 is returned.
- * Otherwise 0 is returned.
+ * Returns : If server uses SSL/TLS connection, 1 is returned.
+ * Otherwise 0 is returned
*
*********************************************************************/
extern int server_use_ssl(struct client_state *csp)
--
2.26.2
From 841734db3720e8d7c2963a00598148f000861958 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:33:15 +0200
Subject: [PATCH 70/83] Replaced if...else for sending and receiving data over
tcp/ssl in handle_established_connection with functions, which decide
according to given parameters. Removed redundant ssl connections closing.
---
jcc.c | 284 ++++++++++++++--------------------------------------------
1 file changed, 66 insertions(+), 218 deletions(-)
diff --git a/jcc.c b/jcc.c
index 17d253d7..01c77040 100644
--- a/jcc.c
+++ b/jcc.c
@@ -2404,7 +2404,6 @@ static void handle_established_connection(struct client_state *csp)
int buffer_and_filter_content = 0;
unsigned int write_delay;
const struct forward_spec *fwd = csp->use_fwd;
- int ret = 0;
/* Skeleton for HTTP response, if we should intercept the request */
struct http_response *rsp;
@@ -2683,67 +2682,37 @@ static void handle_established_connection(struct client_state *csp)
/*
* Reading data from standard or secured connection (HTTP/HTTPS)
*/
- if (client_use_ssl(csp))
+ len = recv_data(csp, CLIENT, (unsigned char*)csp->receive_buffer, max_bytes_to_read);
+ if (len <= 0)
{
- /*
- * Receiving HTTP request from client over SSL/TLS and sending
- * it to server over SSL/TLS.
- */
- len = ssl_recv_data(&(csp->ssl_client_attr),
- (unsigned char *) csp->receive_buffer, max_bytes_to_read);
-
- if (len <= 0)
- {
- mark_server_socket_tainted(csp);
- break;
- }
-
- ret = ssl_send_data(&(csp->ssl_server_attr),
- (unsigned char *) csp->receive_buffer, len);
-
- if (ret < 0)
- {
- log_error(LOG_LEVEL_ERROR,
- "Send request over SSL/TLS to: %s failed", http->host);
- mark_server_socket_tainted(csp);
- return;
- }
+ mark_server_socket_tainted(csp);
+ break; /* "game over, man" */
}
- else
- {
- len = read_socket(csp->cfd, csp->receive_buffer, max_bytes_to_read);
-
- if (len <= 0)
- {
- /* XXX: not sure if this is necessary. */
- mark_server_socket_tainted(csp);
- break; /* "game over, man" */
- }
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
- if (csp->expected_client_content_length != 0)
+ if (csp->expected_client_content_length != 0)
+ {
+ assert(len <= max_bytes_to_read);
+ csp->expected_client_content_length -= (unsigned)len;
+ log_error(LOG_LEVEL_CONNECT,
+ "Expected client content length set to %llu "
+ "after reading %d bytes.",
+ csp->expected_client_content_length, len);
+ if (csp->expected_client_content_length == 0)
{
- assert(len <= max_bytes_to_read);
- csp->expected_client_content_length -= (unsigned)len;
log_error(LOG_LEVEL_CONNECT,
- "Expected client content length set to %llu "
- "after reading %d bytes.",
- csp->expected_client_content_length, len);
- if (csp->expected_client_content_length == 0)
- {
- log_error(LOG_LEVEL_CONNECT,
- "Done reading from the client.");
- csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
- }
+ "Done reading from the client.");
+ log_error(LOG_LEVEL_ERROR, "CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ SET4");
+ csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
}
+ }
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
- if (write_socket(csp->server_connection.sfd, csp->receive_buffer, (size_t)len))
- {
- log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
- mark_server_socket_tainted(csp);
- return;
- }
+ if (send_data(csp, SERVER, csp->receive_buffer, (size_t)len))
+ {
+ log_error(LOG_LEVEL_ERROR, "send data to: %s failed: %E", http->host);
+ mark_server_socket_tainted(csp);
+ return;
}
continue;
}
@@ -2784,19 +2753,10 @@ static void handle_established_connection(struct client_state *csp)
/*
* Reading data from standard or secured connection (HTTP/HTTPS)
*/
- if (server_use_ssl(csp))
- {
- len = ssl_recv_data(&(csp->ssl_server_attr),
- (unsigned char *)csp->receive_buffer, (int)csp->receive_buffer_size);
- }
- else
- {
- len = read_socket(csp->server_connection.sfd, csp->receive_buffer, (int)csp->receive_buffer_size);
- }
-
+ len = recv_data(csp, SERVER, (unsigned char *)csp->receive_buffer, (int)csp->receive_buffer_size);
if (len < 0)
{
- log_error(LOG_LEVEL_ERROR, "read from: %s failed: %E", http->host);
+ log_error(LOG_LEVEL_ERROR, "receive data from: %s failed: %E", http->host);
if ((http->ssl && (fwd->forward_host == NULL)) && csp->use_ssl_tunnel)
{
@@ -2936,35 +2896,16 @@ static void handle_established_connection(struct client_state *csp)
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
- if (client_use_ssl(csp))
- {
- if ((ssl_send_data(&(csp->ssl_client_attr),
- (const unsigned char *)hdr, strlen(hdr)) < 0)
- || (ssl_send_data(&(csp->ssl_client_attr),
- (const unsigned char *)((p != NULL) ? p : csp->iob->cur),
- (size_t)csp->content_length) < 0))
- {
- log_error(LOG_LEVEL_ERROR, "write modified content to "
- "client over SSL/TLS failed");
- freez(hdr);
- freez(p);
- mark_server_socket_tainted(csp);
- return;
- }
- }
- else
+ if (send_data_delayed(csp, CLIENT, hdr, strlen(hdr), write_delay)
+ || send_data_delayed(csp, CLIENT,
+ ((p != NULL) ? p : csp->iob->cur),
+ (size_t)csp->content_length, write_delay))
{
- if (write_socket_delayed(csp->cfd, hdr, strlen(hdr), write_delay)
- || write_socket_delayed(csp->cfd,
- ((p != NULL) ? p : csp->iob->cur),
- (size_t)csp->content_length, write_delay))
- {
- log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E");
- freez(hdr);
- freez(p);
- mark_server_socket_tainted(csp);
- return;
- }
+ log_error(LOG_LEVEL_ERROR, "send modified content to client failed: %E");
+ freez(hdr);
+ freez(p);
+ mark_server_socket_tainted(csp);
+ return;
}
freez(hdr);
@@ -3029,35 +2970,16 @@ static void handle_established_connection(struct client_state *csp)
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
- if (client_use_ssl(csp))
- {
- if ((ssl_send_data(&(csp->ssl_client_attr),
- (const unsigned char *)hdr, hdrlen) < 0)
- || ((flushed = ssl_flush_socket(&(csp->ssl_client_attr),
- csp->iob)) < 0)
- || (ssl_send_data(&(csp->ssl_client_attr),
- (const unsigned char *)csp->receive_buffer, (size_t)len) < 0))
- {
- log_error(LOG_LEVEL_CONNECT,
- "Flush header and buffers to client failed");
- freez(hdr);
- mark_server_socket_tainted(csp);
- return;
- }
- }
- else
+ if (send_data_delayed(csp, CLIENT, hdr, hdrlen, write_delay)
+ || ((flushed = flush_socket(csp, CLIENT, csp->iob, write_delay)) < 0)
+ || send_data_delayed(csp, CLIENT, csp->receive_buffer,
+ (size_t)len, write_delay))
{
- if (write_socket_delayed(csp->cfd, hdr, hdrlen, write_delay)
- || ((flushed = flush_iob(csp->cfd, csp->iob, write_delay)) < 0)
- || write_socket_delayed(csp->cfd, csp->receive_buffer,
- (size_t)len, write_delay))
- {
- log_error(LOG_LEVEL_CONNECT,
- "Flush header and buffers to client failed: %E");
- freez(hdr);
- mark_server_socket_tainted(csp);
- return;
- }
+ log_error(LOG_LEVEL_CONNECT,
+ "Flush header and buffers to client failed: %E");
+ freez(hdr);
+ mark_server_socket_tainted(csp);
+ return;
}
/*
@@ -3076,27 +2998,12 @@ static void handle_established_connection(struct client_state *csp)
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
- if (client_use_ssl(csp))
- {
- ret = ssl_send_data(&(csp->ssl_client_attr),
- (const unsigned char *)csp->receive_buffer, len);
- if (ret < 0)
- {
- log_error(LOG_LEVEL_ERROR,
- "Sending data to client failed");
- mark_server_socket_tainted(csp);
- return;
- }
- }
- else
+ if (send_data_delayed(csp, CLIENT, csp->receive_buffer,
+ (size_t)len, write_delay))
{
- 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);
- return;
- }
+ log_error(LOG_LEVEL_ERROR, "send data to client failed: %E");
+ mark_server_socket_tainted(csp);
+ return;
}
}
byte_count += (unsigned long long)len;
@@ -3136,18 +3043,9 @@ static void handle_established_connection(struct client_state *csp)
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
- if (client_use_ssl(csp))
- {
- ssl_send_data(&(csp->ssl_client_attr),
- (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE,
- strlen(INVALID_SERVER_HEADERS_RESPONSE));
- }
- else
- {
- write_socket_delayed(csp->cfd,
- INVALID_SERVER_HEADERS_RESPONSE,
- strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
- }
+ send_data_delayed(csp, CLIENT,
+ INVALID_SERVER_HEADERS_RESPONSE,
+ strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
mark_server_socket_tainted(csp);
return;
}
@@ -3219,17 +3117,8 @@ static void handle_established_connection(struct client_state *csp)
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
- if(client_use_ssl(csp))
- {
- ssl_send_data(&(csp->ssl_client_attr),
- (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE,
- strlen(INVALID_SERVER_HEADERS_RESPONSE));
- }
- else
- {
- write_socket_delayed(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
- strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
- }
+ send_data_delayed(csp, CLIENT, INVALID_SERVER_HEADERS_RESPONSE,
+ strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
free_http_request(http);
mark_server_socket_tainted(csp);
@@ -3248,17 +3137,8 @@ static void handle_established_connection(struct client_state *csp)
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
- if (client_use_ssl(csp))
- {
- ssl_send_data(&(csp->ssl_client_attr),
- (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE,
- strlen(INVALID_SERVER_HEADERS_RESPONSE));
- }
- else
- {
- write_socket_delayed(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
- strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
- }
+ send_data_delayed(csp, CLIENT, INVALID_SERVER_HEADERS_RESPONSE,
+ strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
free_http_request(http);
mark_server_socket_tainted(csp);
return;
@@ -3308,39 +3188,18 @@ static void handle_established_connection(struct client_state *csp)
* may be in the buffer) Use standard or secured
* connection.
*/
- if (client_use_ssl(csp))
- {
- if ((ssl_send_data(&(csp->ssl_client_attr),
- (const unsigned char *)hdr, strlen(hdr)) < 0)
- || (len = ssl_flush_socket(&(csp->ssl_client_attr),
- csp->iob) < 0))
- {
- log_error(LOG_LEVEL_CONNECT, "Write header to client failed");
-
- /*
- * The write failed, so don't bother mentioning it
- * to the client... it probably can't hear us anyway.
- */
- freez(hdr);
- mark_server_socket_tainted(csp);
- return;
- }
- }
- else
+ if (send_data_delayed(csp, CLIENT, hdr, strlen(hdr), write_delay)
+ || ((len = flush_socket(csp, CLIENT, csp->iob, write_delay)) < 0))
{
- if (write_socket_delayed(csp->cfd, hdr, strlen(hdr), write_delay)
- || ((len = flush_iob(csp->cfd, csp->iob, write_delay)) < 0))
- {
- log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E");
+ log_error(LOG_LEVEL_CONNECT, "send header to client failed: %E");
- /*
- * The write failed, so don't bother mentioning it
- * to the client... it probably can't hear us anyway.
- */
- freez(hdr);
- mark_server_socket_tainted(csp);
- return;
- }
+ /*
+ * The write failed, so don't bother mentioning it
+ * to the client... it probably can't hear us anyway.
+ */
+ freez(hdr);
+ mark_server_socket_tainted(csp);
+ return;
}
}
@@ -3364,17 +3223,8 @@ static void handle_established_connection(struct client_state *csp)
/*
* Sending data with standard or secured connection (HTTP/HTTPS)
*/
- if (client_use_ssl(csp))
- {
- ssl_send_data(&(csp->ssl_client_attr),
- (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE,
- strlen(INVALID_SERVER_HEADERS_RESPONSE));
- }
- else
- {
- write_socket_delayed(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
- strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
- }
+ send_data_delayed(csp, CLIENT, INVALID_SERVER_HEADERS_RESPONSE,
+ strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay);
mark_server_socket_tainted(csp);
return;
}
@@ -3385,8 +3235,6 @@ static void handle_established_connection(struct client_state *csp)
return; /* huh? we should never get here */
}
- close_client_and_server_ssl_connections(csp);
-
if (csp->content_length == 0)
{
/*
--
2.26.2
From df1172a452341924f2735864cecf09487b2ab8a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:36:37 +0200
Subject: [PATCH 71/83] Added possibility to compile Privoxy without any ssl
library. But without ssl library won't be any ssl feature available.
---
cgi.c | 5 +-
configure.in | 2 +
jbsockets.c | 17 ++---
jcc.c | 178 ++++++++++++++++++++++++++++++++-------------------
urlmatch.c | 12 +++-
5 files changed, 138 insertions(+), 76 deletions(-)
diff --git a/cgi.c b/cgi.c
index 5dd5d2ba..4271f01e 100644
--- a/cgi.c
+++ b/cgi.c
@@ -400,7 +400,10 @@ struct http_response *dispatch_cgi(struct client_state *csp)
if (strcmpic(csp->http->gpc, "GET")
&& strcmpic(csp->http->gpc, "HEAD")
- && strcmpic(csp->http->gpc, "CONNECT"))
+#ifdef FEATURE_SSL
+ && strcmpic(csp->http->gpc, "CONNECT")
+#endif /* def FEATURE_SSL */
+ )
{
log_error(LOG_LEVEL_ERROR,
"CGI request with unsupported method received: %s", csp->http->gpc);
diff --git a/configure.in b/configure.in
index 2908a8ba..5cb94456 100644
--- a/configure.in
+++ b/configure.in
@@ -1112,6 +1112,8 @@ else
USAGE_LIBRESSL=
else
USAGE_SSL=#
+ USAGE_MBEDTLS=#
+ USAGE_LIBRESSL=#
fi
fi
diff --git a/jbsockets.c b/jbsockets.c
index 9391cef6..3f37d9ab 100644
--- a/jbsockets.c
+++ b/jbsockets.c
@@ -1837,7 +1837,7 @@ void mark_socket_for_close_on_execute(jb_socket fd)
extern int recv_data(struct client_state *csp, int src, unsigned char *buf, int maxLen) {
if (src == CLIENT)
{
-#if defined FEATURE_LIBRESSL || defined FEATURE_MBEDTLS
+#ifdef FEATURE_SSL
if (csp->ssl_with_client_is_opened == 1)
{
return ssl_recv_data(&(csp->ssl_client_attr), buf, maxLen);
@@ -1850,7 +1850,7 @@ extern int recv_data(struct client_state *csp, int src, unsigned char *buf, int
}
else if (src == SERVER)
{
-#if defined FEATURE_LIBRESSL || defined FEATURE_MBEDTLS
+#ifdef FEATURE_SSL
if (csp->ssl_with_server_is_opened == 1)
{
return ssl_recv_data(&(csp->ssl_server_attr), buf, maxLen);
@@ -1890,7 +1890,7 @@ extern int recv_data(struct client_state *csp, int src, unsigned char *buf, int
extern int send_data_delayed(const struct client_state *csp, int dest, const char *buf, int len, int delay) {
if (dest == CLIENT)
{
-#if defined FEATURE_LIBRESSL || defined FEATURE_MBEDTLS
+#ifdef FEATURE_SSL
if (csp->ssl_with_client_is_opened == 1)
{
return 0 > ssl_send_data_delayed(&(csp->ssl_client_attr), (const unsigned char*)buf, len, delay);
@@ -1903,8 +1903,9 @@ extern int send_data_delayed(const struct client_state *csp, int dest, const cha
}
else if (dest == SERVER)
{
-#if defined FEATURE_LIBRESSL || defined FEATURE_MBEDTLS
+#ifdef FEATURE_SSL
if (csp->ssl_with_server_is_opened == 1) {
+ log_error(LOG_LEVEL_ERROR, "POSILANI DAT NA SERVER PRES SSL");
return 0 > ssl_send_data_delayed(&(csp->ssl_server_attr), (const unsigned char*)buf, len, delay);
}
else
@@ -1964,7 +1965,7 @@ extern int send_data(const struct client_state *csp, int dest, const char *buf,
extern int flush_socket(const struct client_state *csp, int dest, struct iob *iob, unsigned int delay) {
if (dest == CLIENT)
{
-#if defined FEATURE_LIBRESSL || defined FEATURE_MBEDTLS
+#ifdef FEATURE_SSL
if (csp->ssl_with_client_is_opened == 1)
{
return ssl_flush_socket(&(csp->ssl_client_attr), iob);
@@ -1978,7 +1979,7 @@ extern int flush_socket(const struct client_state *csp, int dest, struct iob *io
}
else if (dest == SERVER)
{
-#if defined FEATURE_LIBRESSL || defined FEATURE_MBEDTLS
+#ifdef FEATURE_SSL
if (csp->ssl_with_server_is_opened == 1) {
return ssl_flush_socket(&(csp->ssl_server_attr), iob);
}
@@ -2016,7 +2017,7 @@ extern int data_is_available_tcp_ssl(const struct client_state *csp, int src, in
if (src == CLIENT)
{
-#if defined FEATURE_LIBRESSL || defined FEATURE_MBEDTLS
+#ifdef FEATURE_SSL
if (csp->ssl_with_client_is_opened == 1)
{
ret = is_ssl_pending(&(csp->ssl_client_attr));
@@ -2030,7 +2031,7 @@ extern int data_is_available_tcp_ssl(const struct client_state *csp, int src, in
}
else if (src == SERVER)
{
-#if defined FEATURE_LIBRESSL || defined FEATURE_MBEDTLS
+#ifdef FEATURE_SSL
if (csp->ssl_with_server_is_opened == 1)
{
ret = is_ssl_pending(&(csp->ssl_server_attr));
diff --git a/jcc.c b/jcc.c
index 01c77040..ed166c6f 100644
--- a/jcc.c
+++ b/jcc.c
@@ -135,6 +135,11 @@
#include "ssl_libressl.h"
#endif
+#ifdef FEATURE_SSL
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+#define FEATURE_SSL_CONNECTION_KEEP_ALIVE
+#endif
+#endif
int daemon_mode = 1;
struct client_states clients[1];
@@ -572,7 +577,7 @@ static jb_err get_request_destination_elsewhere(struct client_state *csp, struct
char *req;
if (!(csp->config->feature_flags & RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS)
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+#ifdef FEATURE_SSL_CONNECTION_KEEP_ALIVE
/* When ssl sesions are reused, we get only relative URI */
&& !(csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED)
#endif
@@ -592,11 +597,11 @@ static jb_err get_request_destination_elsewhere(struct client_state *csp, struct
return JB_ERR_PARSE;
}
else if (JB_ERR_OK == get_destination_from_headers(headers, csp->http,
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+#ifdef FEATURE_SSL_CONNECTION_KEEP_ALIVE
(csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED) != 0
#else
FALSE
-#endif
+#endif /* def FEATURE_SSL_CONNECTION_KEEP_ALIVE */
))
{
#ifndef FEATURE_EXTENDED_HOST_PATTERNS
@@ -737,7 +742,6 @@ static jb_err get_server_headers(struct client_state *csp)
*
**********************************************************************/
static int create_server_connection(struct client_state *csp) {
- int ret = 0;
struct http_request *http;
const struct forward_spec *fwd;
struct http_response *rsp;
@@ -776,8 +780,10 @@ static int create_server_connection(struct client_state *csp) {
"connected to %s. Total requests: %u.",
csp->server_connection.sfd, csp->server_connection.host,
csp->server_connection.requests_sent_total);
+#ifdef FEATURE_SSL
csp->ssl_flags |= CSP_SSL_FLAG_CLOSE_SERVER_CONNECTION;
close_server_ssl_connection(csp);
+#endif
drain_and_close_socket(csp->server_connection.sfd);
}
mark_connection_closed(&csp->server_connection);
@@ -829,6 +835,7 @@ static int create_server_connection(struct client_state *csp) {
return 1;
}
+#ifdef FEATURE_SSL
/*
* Creating SSL/TLS connections with destinantion server or parent
* proxy. If forwarding is enabled, we must send client request to
@@ -836,10 +843,11 @@ static int create_server_connection(struct client_state *csp) {
*/
if (http->ssl && !csp->use_ssl_tunnel)
{
+ int ret = 0;
+
if (fwd->forward_host != NULL)
{
char server_response[BUFFER_SIZE];
- int ret = 0;
int len = 0;
char *hdr = NULL;
@@ -1013,6 +1021,7 @@ static int create_server_connection(struct client_state *csp) {
log_error(LOG_LEVEL_CONNECT, "SSL connection with server was created successfully");
}
}
+#endif /* def FEATURE_SSL */
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
save_connection_destination(csp->server_connection.sfd,
@@ -1648,7 +1657,7 @@ static void mark_server_socket_tainted(struct client_state *csp)
csp->server_connection.sfd);
}
csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+#ifdef FEATURE_SSL_CONNECTION_KEEP_ALIVE
if (csp->http->server_ssl)
{
csp->ssl_flags |= CSP_SSL_FLAG_SERVER_CONNECTION_TAINTED;
@@ -2241,7 +2250,11 @@ static jb_err parse_client_request(struct client_state *csp)
#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->ver, "HTTP/1.1"))
+#ifndef FEATURE_SSL
+ && (csp->http->ssl == 0)
+#endif /* def FEATURE_SSL */
+ )
{
/* Assume persistence until further notice */
csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
@@ -2509,6 +2522,7 @@ static void handle_established_connection(struct client_state *csp)
}
#endif /* FEATURE_CONNECTION_KEEP_ALIVE */
+#ifdef FEATURE_SSL
/*
* Test if some data from client or destination server are pending
* on SSL/TLS. We must work with them preferably. SSL/TLS data can
@@ -2527,36 +2541,7 @@ static void handle_established_connection(struct client_state *csp)
read_ssl_server = is_ssl_pending(&(csp->ssl_server_attr));
}
- if (!read_ssl_server && !read_ssl_client)
- {
-#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);
-#else
- timeout.tv_sec = csp->config->socket_timeout;
- timeout.tv_usec = 0;
- n = select((int)maxfd + 1, &rfds, NULL, NULL, &timeout);
-#endif /* def HAVE_POLL */
- }
- else
+ if (read_ssl_server || read_ssl_client)
{
#ifdef HAVE_POLL
if (read_ssl_client)
@@ -2588,12 +2573,46 @@ static void handle_established_connection(struct client_state *csp)
}
#endif /* def HAVE_POLL */
}
+ else
+#endif /* def FEATURE_SSL*/
+ {
+#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);
+#else
+ timeout.tv_sec = csp->config->socket_timeout;
+ timeout.tv_usec = 0;
+ n = select((int)maxfd + 1, &rfds, NULL, NULL, &timeout);
+#endif /* def HAVE_POLL */
+ }
if (n == 0)
{
log_error(LOG_LEVEL_CONNECT, "Socket timeout %d reached: %s",
csp->config->socket_timeout, http->url);
- if (byte_count == 0)
+ if (byte_count == 0
+#ifndef FEATURE_SSL
+ && http->ssl == 0
+#endif
+ )
{
send_crunch_response(csp, error_response(csp, "connection-timeout"));
}
@@ -2758,7 +2777,7 @@ static void handle_established_connection(struct client_state *csp)
{
log_error(LOG_LEVEL_ERROR, "receive data from: %s failed: %E", http->host);
- if ((http->ssl && (fwd->forward_host == NULL)) && csp->use_ssl_tunnel)
+ if (http->ssl && (fwd->forward_host == NULL) && csp->use_ssl_tunnel)
{
/*
* Just hang up. We already confirmed the client's CONNECT
@@ -3294,9 +3313,14 @@ static int process_client_request(struct client_state *csp) {
/*
* Setting flags to use old solution with SSL tunel and to disable
- * certificates verification.
+ * certificates verification. We are also setting this flag, when
+ * no ssl library is used, because ssl tunneling will be used.
*/
- if (http->ssl && csp->action->flags & ACTION_DISABLE_HTTPS_FILTER)
+ if (http->ssl
+#ifdef FEATURE_SSL
+ && csp->action->flags & ACTION_DISABLE_HTTPS_FILTER
+#endif
+ )
{
csp->use_ssl_tunnel = 1;
}
@@ -3366,7 +3390,9 @@ static void chat(struct client_state *csp)
const struct forward_spec *fwd;
struct http_request *http;
/* Skeleton for HTTP response, if we should intercept the request */
+#ifdef FEATURE_SSL
struct http_response *rsp;
+#endif
struct http_response *crunch_rsp;
int should_prepare_crunch_rsp = FALSE;
int ret = 0;
@@ -3374,7 +3400,7 @@ static void chat(struct client_state *csp)
http = csp->http;
csp->dont_verify_certificate = 0;
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+#ifdef FEATURE_SSL_CONNECTION_KEEP_ALIVE
/*
* Setting flags when we should reuse ssl connections and we have
* already created ssl connection which we are reusing.
@@ -3390,7 +3416,7 @@ static void chat(struct client_state *csp)
csp->ssl_flags |= CSP_SSL_FLAG_SERVER_CONNECTION_REUSED;
}
}
-#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+#endif /* def FEATURE_SSL_CONNECTION_KEEP_ALIVE */
ret = process_client_request(csp);
if (ret != 0)
@@ -3463,11 +3489,11 @@ static void chat(struct client_state *csp)
/*
* We have a request. Check if one of the crunchers wants it.
*/
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+#ifdef FEATURE_SSL_CONNECTION_KEEP_ALIVE
should_prepare_crunch_rsp = csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED || !http->ssl;
#else
should_prepare_crunch_rsp = !http->ssl;
-#endif
+#endif /* def FEATURE_SSL_CONNECTION_KEEP_ALIVE */
http->should_be_crunched = should_trigger_crunch_response(csp, crunchers_all, should_prepare_crunch_rsp, &crunch_rsp);
if (http->should_be_crunched && should_prepare_crunch_rsp)
{
@@ -3477,6 +3503,18 @@ static void chat(struct client_state *csp)
*/
return;
}
+#ifndef FEATURE_SSL
+ /*
+ * Request should be crunched over ssl, but we are not able to
+ * create ssl connection.
+ */
+ else if (http->should_be_crunched && http->ssl)
+ {
+ send_data_delayed(csp, CLIENT, CHEADER, strlen(CHEADER),
+ get_write_delay(csp));
+ return;
+ }
+#endif /* ndef FEATURE_SSL */
log_applied_actions(csp->action);
log_error(LOG_LEVEL_GPC, "%s%s", http->hostport, http->path);
@@ -3504,14 +3542,14 @@ static void chat(struct client_state *csp)
csp->server_connection.requests_sent_total++;
}
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+#ifdef FEATURE_SSL_CONNECTION_KEEP_ALIVE
/*
* When we are reusing connection with client, we don't want
* to creat new connection again.
*/
if (!(csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED))
{
-#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+#endif /* def FEATURE_SSL_CONNECTION_KEEP_ALIVE */
if (!http->should_be_crunched)
{
if ((fwd->type == SOCKS_5T) && (NULL == csp->headers->first))
@@ -3533,23 +3571,12 @@ static void chat(struct client_state *csp)
}
else
{
+ list_remove_all(csp->headers);
+#ifdef FEATURE_SSL
/*
* Using old solution with SSL tunnel or new solution with SSL proxy
*/
- list_remove_all(csp->headers);
- if (csp->use_ssl_tunnel)
- {
- /*
- * We're running an SSL tunnel and we're not forwarding,
- * so just ditch the client headers, send the "connect succeeded"
- * message to the client, flush the rest, and get out of the way.
- */
- if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
- {
- return;
- }
- }
- else
+ if (!csp->use_ssl_tunnel)
{
/*
* Creating an SSL proxy. If forwarding is disabled, we must send
@@ -3578,7 +3605,6 @@ static void chat(struct client_state *csp)
return;
}
-#ifdef FEATURE_SSL
/*
* If server certificate is invalid, we must inform client and then
* close connection with client.
@@ -3594,14 +3620,28 @@ static void chat(struct client_state *csp)
close_client_and_server_ssl_connections(csp);
return;
}
-#endif /* def FEATURE_SSL */
log_error(LOG_LEVEL_CONNECT, "SSL connection with client was created successfully");
}
+ else
+#endif /* def FEATURE_SSL */
+ {
+ /*
+ * We're running an SSL tunnel and we're not forwarding,
+ * so just ditch the client headers, send the "connect succeeded"
+ * message to the client, flush the rest, and get out of the way.
+ */
+ if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
+ {
+ return;
+ }
+ }
+
clear_iob(csp->client_iob);
}
log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
}
+#ifdef FEATURE_SSL
else
{
list_remove_all(csp->headers);
@@ -3686,6 +3726,7 @@ static void chat(struct client_state *csp)
}
}
}
+#endif /* def FEATURE_SSL */
/* XXX: should the time start earlier for optimistically sent data? */
csp->server_connection.request_sent = time(NULL);
@@ -3920,9 +3961,11 @@ static void serve(struct client_state *csp)
}
#endif /* def FEATURE_CONNECTION_SHARING */
+#ifdef FEATURE_SSL
/* Setting flag to close ssl connections */
csp->ssl_flags |= CSP_SSL_FLAG_CLOSE_SERVER_CONNECTION;
close_server_ssl_connection(csp);
+#endif /* def FEATURE_SSL */
close_socket(csp->server_connection.sfd);
mark_connection_closed(&csp->server_connection);
}
@@ -4002,7 +4045,9 @@ static void serve(struct client_state *csp)
privoxy_mutex_unlock(&connection_reuse_mutex);
}
#endif /* def FEATURE_CONNECTION_SHARING */
+#ifdef FEATURE_SSL
csp->ssl_flags &= ~CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED;
+#endif
break;
}
}
@@ -4025,6 +4070,7 @@ static void serve(struct client_state *csp)
chat(csp);
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+#ifdef FEATURE_SSL
/*
* Closing ssl and then tcp connections, if they were opened.
*/
@@ -4032,6 +4078,8 @@ static void serve(struct client_state *csp)
csp->ssl_flags = 0;
#endif
close_client_and_server_ssl_connections(csp);
+#endif /* def FEATURE_SSL */
+
if (csp->server_connection.sfd != JB_INVALID_SOCKET)
{
#ifdef FEATURE_CONNECTION_SHARING
@@ -5102,9 +5150,9 @@ static void listen_loop(void)
}
#endif /* def FEATURE_ACL */
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
- /* Setting flag to keep ssl connections opened if possible */
csp->ssl_flags = 0;
+#ifdef FEATURE_SSL_CONNECTION_KEEP_ALIVE
+ /* Setting flag to keep ssl connections opened if possible */
if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
{
csp->ssl_flags = CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED;
diff --git a/urlmatch.c b/urlmatch.c
index 65e411e6..ec101ea7 100644
--- a/urlmatch.c
+++ b/urlmatch.c
@@ -280,7 +280,9 @@ jb_err parse_http_url(const char *url, struct http_request *http, int require_pr
* When we are receiving http request over ssl, there is
* no host, but we should have it from CONNECT request.
*/
+#ifdef FEATURE_SSL
if (http->client_ssl == 0)
+#endif
{
http->host = NULL;
}
@@ -547,11 +549,14 @@ jb_err parse_http_request(const char *req, struct http_request *http)
int n;
jb_err err;
+#ifdef FEATURE_SSL
/*
* We are not reading client's request over ssl, so we didn't
* receive any information before over tcp and we can clean struct.
*/
- if (http->client_ssl == 0) {
+ if (http->client_ssl == 0)
+#endif /* def FEATURE_SSL */
+ {
memset(http, '\0', sizeof(*http));
}
buf = strdup_or_die(req);
@@ -585,7 +590,10 @@ jb_err parse_http_request(const char *req, struct http_request *http)
return JB_ERR_PARSE;
}
- if (http->ssl != 1) {
+#ifdef FEATURE_SSL
+ if (!http->ssl)
+#endif
+ {
http->ssl = !strcmpic(v[0], "CONNECT");
}
--
2.26.2
From b8ec3b69150b96975d5676f315ebcb542bd47c05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:40:21 +0200
Subject: [PATCH 72/83] Part which is preparing connection with client
(creating ssl connection, forwarding requests, sending succeed, ...) was
excluded from function chat to separated function.
---
jcc.c | 304 +++++++++++++++++++++++++++++++++-------------------------
1 file changed, 172 insertions(+), 132 deletions(-)
diff --git a/jcc.c b/jcc.c
index ed166c6f..15e5e375 100644
--- a/jcc.c
+++ b/jcc.c
@@ -162,6 +162,7 @@ static jb_err get_request_destination_elsewhere(struct client_state *csp, struct
static jb_err get_server_headers(struct client_state *csp);
static const char *crunch_reason(const struct http_response *rsp);
static void send_crunch_response(const struct client_state *csp, struct http_response *rsp);
+static int send_http_request(struct client_state *csp);
static char *get_request_line(struct client_state *csp);
static jb_err receive_client_request(struct client_state *csp);
static jb_err parse_client_request(struct client_state *csp);
@@ -1035,6 +1036,173 @@ static int create_server_connection(struct client_state *csp) {
}
+/**********************************************************************
+ *
+ * Function : prepare_client_connection
+ *
+ * Description : Takes existing tcp connection with client and prepares
+ * it for data transmission. So ssl connection can be
+ * created, "Connection established" message can be send
+ * and client request can be forwarded to server.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns : 0 on success, other values when connection wasn't
+ * prepared well.
+ *
+ **********************************************************************/
+static int prepare_client_connection(struct client_state *csp)
+{
+ const struct forward_spec *fwd;
+ struct http_request *http;
+ /* Skeleton for HTTP response, if we should intercept the request */
+ struct http_response *rsp;
+#ifdef FEATURE_SSL
+ int ret = 0;
+#endif
+
+ http = csp->http;
+ fwd = csp->use_fwd;
+
+#ifdef FEATURE_SSL_CONNECTION_KEEP_ALIVE
+ /*
+ * When we are reusing connection with client, we don't want
+ * to creat new connection again.
+ */
+ if (!(csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED))
+ {
+#endif /* def FEATURE_SSL_CONNECTION_KEEP_ALIVE */
+ if (!http->should_be_crunched)
+ {
+ if ((fwd->type == SOCKS_5T) && (NULL == csp->headers->first))
+ {
+ /* Client headers have been sent optimistically */
+ assert(csp->headers->last == NULL);
+ }
+ else if ((fwd->forward_host && csp->use_ssl_tunnel) || http->ssl == 0)
+ {
+ if (send_http_request(csp))
+ {
+ rsp = error_response(csp, "connect-failed");
+ if (rsp)
+ {
+ send_crunch_response(csp, rsp);
+ }
+ return 1;
+ }
+ }
+ else
+ {
+ list_remove_all(csp->headers);
+#ifdef FEATURE_SSL
+ /*
+ * Using old solution with SSL tunnel or new solution with SSL proxy
+ */
+ if (!csp->use_ssl_tunnel)
+ {
+ /*
+ * Creating an SSL proxy. If forwarding is disabled, we must send
+ * CSUCCEED mesage to client. Then SSL/TLS connection with client
+ * is created.
+ */
+
+ if (fwd->forward_host == NULL)
+ {
+ if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
+ {
+ log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
+ close_client_and_server_ssl_connections(csp);
+ return 1;
+ }
+ }
+
+ ret = create_client_ssl_connection(csp);
+ if (ret != 0)
+ {
+ log_error(LOG_LEVEL_ERROR,
+ "Can't open secure connection with client");
+#ifndef FEATURE_CONNECTION_KEEP_ALIVE
+ close_client_and_server_ssl_connections(csp);
+#endif
+ return 1;
+ }
+
+ /*
+ * If server certificate is invalid, we must inform client and then
+ * close connection with client.
+ */
+#ifdef FEATURE_MBEDTLS
+ if (csp->server_cert_verification_result != SSL_CERT_VALID)
+#endif
+#ifdef FEATURE_LIBRESSL
+ if (csp->server_cert_verification_result != X509_V_OK)
+#endif
+ {
+ ssl_send_certificate_error(csp);
+ close_client_and_server_ssl_connections(csp);
+ return 1;
+ }
+
+ log_error(LOG_LEVEL_CONNECT, "SSL connection with client was created successfully");
+ }
+ else
+#endif /* def FEATURE_SSL */
+ {
+ /*
+ * We're running an SSL tunnel and we're not forwarding,
+ * so just ditch the client headers, send the "connect succeeded"
+ * message to the client, flush the rest, and get out of the way.
+ */
+ if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
+ {
+ return 1;
+ }
+ }
+
+ clear_iob(csp->client_iob);
+ }
+ log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
+ }
+#ifdef FEATURE_SSL
+ else
+ {
+ list_remove_all(csp->headers);
+ if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
+ {
+ log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
+ close_client_and_server_ssl_connections(csp);
+ return 1;
+ }
+ ret = create_client_ssl_connection(csp);
+ }
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ }
+ else
+ {
+ /*
+ * Sending client's request to server, when SSL connection is reused.
+ */
+ freez(csp->headers->first->str);
+ build_request_line(csp, fwd, &csp->headers->first->str);
+
+ if (send_http_request(csp))
+ {
+ rsp = error_response(csp, "connect-failed");
+ if (rsp)
+ {
+ send_crunch_response(csp, rsp);
+ }
+ mark_server_socket_tainted(csp);
+ return 1;
+ }
+ }
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+#endif /* def FEATURE_SSL */
+ return 0;
+}
+
+
/*********************************************************************
*
* Function : crunch_reason
@@ -3542,140 +3710,12 @@ static void chat(struct client_state *csp)
csp->server_connection.requests_sent_total++;
}
-#ifdef FEATURE_SSL_CONNECTION_KEEP_ALIVE
- /*
- * When we are reusing connection with client, we don't want
- * to creat new connection again.
- */
- if (!(csp->ssl_flags & CSP_SSL_FLAG_CLIENT_CONNECTION_REUSED))
- {
-#endif /* def FEATURE_SSL_CONNECTION_KEEP_ALIVE */
- if (!http->should_be_crunched)
- {
- if ((fwd->type == SOCKS_5T) && (NULL == csp->headers->first))
- {
- /* Client headers have been sent optimistically */
- assert(csp->headers->last == NULL);
- }
- else if ((fwd->forward_host && csp->use_ssl_tunnel) || http->ssl == 0)
- {
- if (send_http_request(csp))
- {
- rsp = error_response(csp, "connect-failed");
- if (rsp)
- {
- send_crunch_response(csp, rsp);
- }
- return;
- }
- }
- else
- {
- list_remove_all(csp->headers);
-#ifdef FEATURE_SSL
- /*
- * Using old solution with SSL tunnel or new solution with SSL proxy
- */
- if (!csp->use_ssl_tunnel)
- {
- /*
- * Creating an SSL proxy. If forwarding is disabled, we must send
- * CSUCCEED mesage to client. Then SSL/TLS connection with client
- * is created.
- */
-
- if (fwd->forward_host == NULL)
- {
- if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
- {
- log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
- close_client_and_server_ssl_connections(csp);
- return;
- }
- }
-
- ret = create_client_ssl_connection(csp);
- if (ret != 0)
- {
- log_error(LOG_LEVEL_ERROR,
- "Can't open secure connection with client");
-#ifndef FEATURE_CONNECTION_KEEP_ALIVE
- close_client_and_server_ssl_connections(csp);
-#endif
- return;
- }
-
- /*
- * If server certificate is invalid, we must inform client and then
- * close connection with client.
- */
-#ifdef FEATURE_MBEDTLS
- if (csp->server_cert_verification_result != SSL_CERT_VALID)
-#endif
-#ifdef FEATURE_LIBRESSL
- if (csp->server_cert_verification_result != X509_V_OK)
-#endif
- {
- ssl_send_certificate_error(csp);
- close_client_and_server_ssl_connections(csp);
- return;
- }
-
- log_error(LOG_LEVEL_CONNECT, "SSL connection with client was created successfully");
- }
- else
-#endif /* def FEATURE_SSL */
- {
- /*
- * We're running an SSL tunnel and we're not forwarding,
- * so just ditch the client headers, send the "connect succeeded"
- * message to the client, flush the rest, and get out of the way.
- */
- if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
- {
- return;
- }
- }
-
- clear_iob(csp->client_iob);
- }
- log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
- }
-#ifdef FEATURE_SSL
- else
- {
- list_remove_all(csp->headers);
- if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
- {
- log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
- close_client_and_server_ssl_connections(csp);
- return;
- }
- ret = create_client_ssl_connection(csp);
- }
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
- }
- else
- {
- /*
- * Sending client's request to server, when SSL connection is reused.
- */
- freez(csp->headers->first->str);
- build_request_line(csp, fwd, &csp->headers->first->str);
-
- if (send_http_request(csp))
- {
- rsp = error_response(csp, "connect-failed");
- if (rsp)
- {
- send_crunch_response(csp, rsp);
- }
- mark_server_socket_tainted(csp);
- return;
- }
+ ret = prepare_client_connection(csp);
+ if (ret != 0) {
+ return;
}
-#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+#ifdef FEATURE_SSL
/*
* We have created SSL connection with client and server, so now we can receive
* client request header over ssl, filter it and send it to the server. Requests
--
2.26.2
From 725badc94ffad383e837f9bc835e8688c18a1cb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:45:37 +0200
Subject: [PATCH 73/83] Added functions data_is_available_to_tcp_ssl_ssl_attr
and connection_is_still_alive_ssl_attr. These functions will be able to work
with given ssl_connection_attr, they don't need whole csp. These functions
also replace parts of similar functions.
---
jbsockets.c | 139 ++++++++++++++++++++++++++++++----------------------
jbsockets.h | 1 +
2 files changed, 81 insertions(+), 59 deletions(-)
diff --git a/jbsockets.c b/jbsockets.c
index 3f37d9ab..fa89ad15 100644
--- a/jbsockets.c
+++ b/jbsockets.c
@@ -127,6 +127,8 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client
static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct client_state *csp);
#endif
+static int data_is_available_tcp_ssl_ssl_attr(const ssl_connection_attr *connection, int is_using_ssl, int seconds_to_wait);
+
/*********************************************************************
*
* Function : set_no_delay_flag
@@ -1470,6 +1472,8 @@ int accept_connection(struct client_state * csp, jb_socket fds[])
set_no_delay_flag(afd);
csp->cfd = afd;
+ csp->ssl_client_attr.socket_fd = csp->cfd;
+
#ifdef HAVE_RFC2553
csp->ip_addr_str = malloc_or_die(NI_MAXHOST);
retval = getnameinfo((struct sockaddr *) &client, c_length,
@@ -1699,45 +1703,60 @@ int socket_is_still_alive(jb_socket sfd)
*********************************************************************/
extern int connection_is_still_alive(struct client_state *csp, int src)
{
-#ifdef FEATURE_SSL
-#ifdef FEATURE_LIBRESSL
- SSL *ssl;
-#endif
-#ifdef FEATURE_MBEDTLS
- mbedtls_ssl_context *ssl;
-#endif
+ ssl_connection_attr * ssl_connection_attr;
int is_using_ssl = 0;
- unsigned char tmp[10];
if (src == CLIENT)
{
is_using_ssl = csp->ssl_with_client_is_opened;
-#ifdef FEATURE_LIBRESSL
- ssl = csp->ssl_client_attr.ssl;
-#endif
-#ifdef FEATURE_MBEDTLS
- ssl = &csp->ssl_client_attr.ssl;
-#endif
+ ssl_connection_attr = &csp->ssl_client_attr;
}
else if (src == SERVER)
{
is_using_ssl = csp->ssl_with_server_is_opened;
-#ifdef FEATURE_LIBRESSL
- ssl = csp->ssl_server_attr.ssl;
-#endif
-#ifdef FEATURE_MBEDTLS
- ssl = &csp->ssl_server_attr.ssl;
-#endif
+ ssl_connection_attr = &csp->ssl_server_attr;
}
+ else
+ {
+ return FALSE;
+ }
+
+ return connection_is_still_alive_ssl_attr(ssl_connection_attr, is_using_ssl);
+}
+
- if (is_using_ssl && data_is_available_tcp_ssl(csp, src, 0)) {
+/*********************************************************************
+ *
+ * Function : connection_is_still_alive_ssl_attr
+ *
+ * Description : Figures out whether or not a given connection
+ * is still alive. (Whether "close notify" alert
+ * was received) Caller must give paremeter if
+ * connection uses ssl.
+ *
+ * Parameters :
+ * 1 : connection_attr = Attributes of ssl connection
+ * 2 : is_using_ssl = TRUE when given connection uses ssl
+ *
+ * Returns : TRUE for yes, otherwise FALSE.
+ *
+ *********************************************************************/
+extern int connection_is_still_alive_ssl_attr(ssl_connection_attr *connection_attr, int is_using_ssl)
+{
+#ifdef FEATURE_SSL
+ unsigned char tmp[10];
+#endif
+
+ if (is_using_ssl && data_is_available_tcp_ssl_ssl_attr(connection_attr, 0, 0))
+ {
#ifdef FEATURE_MBEDTLS
/*
* mbedtls_ssl_read reads available data and checks connection state.
* When connection was closed by peer, closure notifice is returned.
* Otherway, no chars are set to given buffer and stay pending.
*/
- if (mbedtls_ssl_read(ssl, tmp, 0) == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+ if (mbedtls_ssl_read(&connection_attr->ssl, tmp, 0) == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
+ {
return FALSE;
}
#endif /* def FEATURE_MBEDTLS */
@@ -1747,25 +1766,15 @@ extern int connection_is_still_alive(struct client_state *csp, int src)
* it loads SSL shutdown flag, which signals whether "close notify"
* alert was received or not.
*/
- SSL_peek(ssl, tmp, 1);
- if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN)
+ SSL_peek(connection_attr->ssl, tmp, 1);
+ if (SSL_get_shutdown(connection_attr->ssl) & SSL_RECEIVED_SHUTDOWN)
{
return FALSE;
}
#endif /* def FEATURE_LIBRESSL */
}
-#endif /* def FEATURE_SSL */
- if (src == CLIENT)
- {
- return socket_is_still_alive(csp->cfd);
- }
- else if (src == SERVER)
- {
- return socket_is_still_alive(csp->server_connection.sfd);
- }
-
- return FALSE;
+ return socket_is_still_alive(connection_attr->socket_fd);
}
@@ -2013,35 +2022,47 @@ extern int flush_socket(const struct client_state *csp, int dest, struct iob *io
*
*********************************************************************/
extern int data_is_available_tcp_ssl(const struct client_state *csp, int src, int seconds_to_wait) {
- int ret = 0;
-
if (src == CLIENT)
{
-#ifdef FEATURE_SSL
- if (csp->ssl_with_client_is_opened == 1)
- {
- ret = is_ssl_pending(&(csp->ssl_client_attr));
- }
- if (ret == 0)
-#endif
- {
- ret = data_is_available(csp->cfd, seconds_to_wait);
- }
- return ret;
+ return data_is_available_tcp_ssl_ssl_attr(&csp->ssl_client_attr, csp->ssl_with_client_is_opened, seconds_to_wait);
}
else if (src == SERVER)
{
-#ifdef FEATURE_SSL
- if (csp->ssl_with_server_is_opened == 1)
- {
- ret = is_ssl_pending(&(csp->ssl_server_attr));
- }
- if (ret == 0)
-#endif
- {
- ret = data_is_available(csp->server_connection.sfd, seconds_to_wait);
- }
- return ret;
+ return data_is_available_tcp_ssl_ssl_attr(&csp->ssl_server_attr, csp->ssl_with_server_is_opened, seconds_to_wait);
}
return 0;
}
+
+
+/*********************************************************************
+ *
+ * Function : data_is_available_tcp_ssl_ssl_attr
+ *
+ * Description : Checks whether some data are available from given
+ * connection.
+ *
+ * Parameters :
+ * 1 : connection_attr = Attributes of ssl connection
+ * 2 : is_using_ssl = TRUE when given connection uses ssl
+ * 3 : seconds_to_wait = number of seconds after which
+ * we give up. (only for tcp connection)
+ *
+ * Returns : TRUE for yes, otherwise FALSE.
+ *
+ *********************************************************************/
+static int data_is_available_tcp_ssl_ssl_attr(const ssl_connection_attr *connection_attr, int is_using_ssl, int seconds_to_wait)
+{
+ int ret = 0;
+
+#ifdef FEATURE_SSL
+ if (is_using_ssl == 1)
+ {
+ ret = is_ssl_pending(connection_attr);
+ }
+ if (ret == 0)
+#endif
+ {
+ ret = data_is_available(connection_attr->socket_fd, seconds_to_wait);
+ }
+ return ret;
+}
\ No newline at end of file
diff --git a/jbsockets.h b/jbsockets.h
index a2934ee2..24b4f1fc 100644
--- a/jbsockets.h
+++ b/jbsockets.h
@@ -62,6 +62,7 @@ extern unsigned long resolve_hostname_to_ip(const char *host);
extern int socket_is_still_alive(jb_socket sfd);
extern int connection_is_still_alive(struct client_state *csp, int src);
+extern int connection_is_still_alive_ssl_attr(ssl_connection_attr *connection, int is_using_ssl);
#ifdef FEATURE_EXTERNAL_FILTERS
extern void mark_socket_for_close_on_execute(jb_socket fd);
--
2.26.2
From 5a3ba3b3c09d9f831749825524c9302fc0cd06f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:47:10 +0200
Subject: [PATCH 74/83] Added functions free_ssl_structures and
close_ssl_connection, which are able to work with given ssl_connection_attr.
---
ssl_libressl.c | 78 ++++++++++++++++++++++++++++----------------------
ssl_libressl.h | 2 ++
2 files changed, 45 insertions(+), 35 deletions(-)
diff --git a/ssl_libressl.c b/ssl_libressl.c
index fc3a5f34..bd6350c4 100644
--- a/ssl_libressl.c
+++ b/ssl_libressl.c
@@ -58,7 +58,6 @@
extern int client_use_ssl(struct client_state *csp);
extern int server_use_ssl(struct client_state *csp);
-static void free_server_ssl_structures(struct client_state *csp);
extern int generate_key(RSA **key_rsa, struct client_state *csp);
extern int generate_webpage_certificate(struct client_state * csp);
static int file_exists(const char * path);
@@ -200,31 +199,60 @@ extern int create_server_ssl_connection(struct client_state *csp)
ret = 0;
exit:
if (ret == -1) {
- free_server_ssl_structures(csp);
+ free_ssl_structures(&csp->ssl_server_attr);
}
return ret;
}
-/*********************************************************************
+/**********************************************************************
*
- * Function : free_server_ssl_structures
+ * Function : free_ssl_structures
*
- * Description : Frees structures used for SSL communication with server
+ * Description : Frees given structures used for SSL communication.
*
* Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
+ * 1 : connection_attr = Attributes of ssl connection
*
* Returns : N/A
*
*********************************************************************/
-static void free_server_ssl_structures(struct client_state *csp)
+extern void free_ssl_structures(ssl_connection_attr *connection_attr)
{
- SSL_free(csp->ssl_server_attr.ssl);
- SSL_CTX_free(csp->ssl_server_attr.ctx);
+ SSL_free(connection_attr->ssl);
+ SSL_CTX_free(connection_attr->ctx);
+ connection_attr->socket_fd = JB_INVALID_SOCKET;
+}
+
+
+/**********************************************************************
+ *
+ * Function : close_ssl_connection
+ *
+ * Description : Closes SSL/TLS connection with given ssl attributes.
+ * This function doesn't check if attributes are not
+ * initialized. It must be done by caller.
+ *
+ * Parameters :
+ * 1 : connection_attr = Attributes of ssl connection
+ *
+ * Returns : N/A
+ *
+ **********************************************************************/
+extern void close_ssl_connection(ssl_connection_attr *connection_attr)
+{
+ /*
+ * Notifying the peer that the connection is being closed.
+ */
+ int ret = SSL_shutdown(connection_attr->ssl);
+ if (ret < 0)
+ {
+ log_error(LOG_LEVEL_ERROR, "SSL_shutdown of ssl connection failed");
+ }
- csp->ssl_server_attr.socket_fd = -1;
+ free_ssl_structures(connection_attr);
+ connection_attr->ssl = NULL;
}
@@ -261,7 +289,7 @@ extern void close_server_ssl_connection(struct client_state *csp)
log_error(LOG_LEVEL_ERROR, "SSL_shutdown with server failed");
}
- free_server_ssl_structures(csp);
+ free_ssl_structures(&csp->ssl_server_attr);
csp->ssl_with_server_is_opened = 0;
csp->server_connection.ssl = 0;
@@ -271,27 +299,6 @@ extern void close_server_ssl_connection(struct client_state *csp)
}
-/**********************************************************************
- *
- * Function : free_client_ssl_structures
- *
- * Description : Frees structures used for SSL communication with client
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : N/A
- *
- *********************************************************************/
-static void free_client_ssl_structures(struct client_state *csp)
-{
- SSL_free(csp->ssl_client_attr.ssl);
- SSL_CTX_free(csp->ssl_client_attr.ctx);
-
- csp->ssl_client_attr.socket_fd = -1;
-}
-
-
/*********************************************************************
*
* Function : close_client_ssl_connection
@@ -322,11 +329,12 @@ extern void close_client_ssl_connection(struct client_state *csp)
* Notifying the peer that the connection is being closed.
*/
ret = SSL_shutdown(csp->ssl_client_attr.ssl);
- if (ret < 0) {
+ if (ret < 0)
+ {
log_error(LOG_LEVEL_ERROR, "SSL_shutdown with client failed");
}
- free_client_ssl_structures(csp);
+ free_ssl_structures(&csp->ssl_client_attr);
csp->ssl_with_client_is_opened = 0;
}
@@ -491,7 +499,7 @@ extern int create_client_ssl_connection(struct client_state *csp) {
ret = 0;
exit:
if (ret != 0) {
- free_client_ssl_structures(csp);
+ free_ssl_structures(&csp->ssl_client_attr);
}
return ret;
diff --git a/ssl_libressl.h b/ssl_libressl.h
index 35601d2a..66c3c615 100644
--- a/ssl_libressl.h
+++ b/ssl_libressl.h
@@ -53,6 +53,8 @@ extern int create_server_ssl_connection(struct client_state *csp);
extern void close_client_and_server_ssl_connections(struct client_state *csp);
extern void close_server_ssl_connection(struct client_state *csp);
extern void close_client_ssl_connection(struct client_state *csp);
+extern void free_ssl_structures(ssl_connection_attr *connection);
+extern void close_ssl_connection(ssl_connection_attr *connection);
#endif /* ndef SSL_LIBRESSL_H_INCLUDED */
\ No newline at end of file
--
2.26.2
From 889645c6cb975a155927726ba2d63adc2cf03ce3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:48:03 +0200
Subject: [PATCH 75/83] Edited function to remember shared connection. There
was added storing of ssl connection attributes. Edited function
forwarded_connect. It has two new output parameters. First to return ssl
connection attributes when ssl connection was taken from shared connections.
Second to determine, whether connection was found between shared connection
or created. Other small changes to work properly with shared ssl connections.
Added ssl connection attributes into reusable_connection struct to keep it
when connection is shared. Added socket_fd into ssl_connection_attr struct.
---
gateway.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++-------
gateway.h | 6 +++--
project.h | 7 +++--
3 files changed, 77 insertions(+), 14 deletions(-)
diff --git a/gateway.c b/gateway.c
index ccb12ede..5c12044f 100644
--- a/gateway.c
+++ b/gateway.c
@@ -59,6 +59,14 @@
#include
#endif /* def __OS2__ */
+#ifdef FEATURE_MBEDTLS
+#include "ssl.h"
+#endif
+
+#ifdef FEATURE_LIBRESSL
+#include "ssl_libressl.h"
+#endif
+
#include "project.h"
#include "jcc.h"
#include "errlog.h"
@@ -176,10 +184,11 @@ extern void initialize_reusable_connections(void)
* Parameters :
* 1 : connection = The server connection to remember.
*
- * Returns : void
+ * Returns : TRUE when connection was remembered and FALSE when
+ * it wasn't possible to remember it.
*
*********************************************************************/
-void remember_connection(const struct reusable_connection *connection)
+int remember_connection(struct reusable_connection *connection)
{
unsigned int slot = 0;
int free_slot_found = FALSE;
@@ -189,7 +198,7 @@ void remember_connection(const struct reusable_connection *connection)
if (mark_connection_unused(connection))
{
- return;
+ return TRUE;
}
privoxy_mutex_lock(&connection_reuse_mutex);
@@ -214,8 +223,15 @@ void remember_connection(const struct reusable_connection *connection)
"No free slots found to remember socket for %s:%d. Last slot %d.",
connection->host, connection->port, slot);
privoxy_mutex_unlock(&connection_reuse_mutex);
+
+#ifdef FEATURE_SSL
+ if (connection->ssl)
+ {
+ close_ssl_connection((ssl_connection_attr *)(&connection->ssl_server_attr));
+ }
+#endif /* def FEATURE_SSL */
close_socket(connection->sfd);
- return;
+ return FALSE;
}
assert(NULL != connection->host);
@@ -229,6 +245,9 @@ void remember_connection(const struct reusable_connection *connection)
reusable_connection[slot].response_received = connection->response_received;
reusable_connection[slot].keep_alive_timeout = connection->keep_alive_timeout;
reusable_connection[slot].requests_sent_total = connection->requests_sent_total;
+#ifdef FEATURE_SSL
+ reusable_connection[slot].ssl_server_attr = connection->ssl_server_attr;
+#endif /* def FEATURE_SSL */
assert(reusable_connection[slot].gateway_host == NULL);
assert(reusable_connection[slot].gateway_port == 0);
@@ -258,6 +277,7 @@ void remember_connection(const struct reusable_connection *connection)
reusable_connection[slot].forward_port = connection->forward_port;
privoxy_mutex_unlock(&connection_reuse_mutex);
+ return TRUE;
}
#endif /* def FEATURE_CONNECTION_SHARING */
@@ -291,6 +311,10 @@ void mark_connection_closed(struct reusable_connection *closed_connection)
freez(closed_connection->forward_host);
closed_connection->forward_port = 0;
closed_connection->ssl = 0;
+
+#ifdef FEATURE_SSL
+ closed_connection->ssl_server_attr.socket_fd = JB_INVALID_SOCKET;
+#endif /* def FEATURE_SSL */
}
@@ -367,7 +391,7 @@ int connection_destination_matches(const struct reusable_connection *connection,
return FALSE;
}
- if (( (NULL != connection->gateway_host)
+ if (((NULL != connection->gateway_host)
&& (NULL != fwd->gateway_host)
&& strcmpic(connection->gateway_host, fwd->gateway_host))
&& (connection->gateway_host != fwd->gateway_host))
@@ -378,7 +402,7 @@ int connection_destination_matches(const struct reusable_connection *connection,
return FALSE;
}
- if (( (NULL != connection->forward_host)
+ if (((NULL != connection->forward_host)
&& (NULL != fwd->forward_host)
&& strcmpic(connection->forward_host, fwd->forward_host))
&& (connection->forward_host != fwd->forward_host))
@@ -434,16 +458,32 @@ int close_unusable_connections(void)
reusable_connection[slot].sfd,
reusable_connection[slot].keep_alive_timeout,
latency);
+#ifdef FEATURE_SSL
+ if (reusable_connection[slot].ssl)
+ {
+ close_ssl_connection(&reusable_connection[slot].ssl_server_attr);
+ }
+#endif /* def FEATURE_SSL */
close_socket(reusable_connection[slot].sfd);
mark_connection_closed(&reusable_connection[slot]);
}
+#ifdef FEATURE_SSL
+ else if (!connection_is_still_alive_ssl_attr(&reusable_connection[slot].ssl_server_attr, reusable_connection[slot].ssl))
+#else
else if (!socket_is_still_alive(reusable_connection[slot].sfd))
+#endif /* def FEATURE_SSL */
{
log_error(LOG_LEVEL_CONNECT,
"The connection to %s:%d in slot %d is no longer usable. "
"Closing socket %d.", reusable_connection[slot].host,
reusable_connection[slot].port, slot,
reusable_connection[slot].sfd);
+#ifdef FEATURE_SSL
+ if (reusable_connection[slot].ssl)
+ {
+ close_ssl_connection(&reusable_connection[slot].ssl_server_attr);
+ }
+#endif /* def FEATURE_SSL */
close_socket(reusable_connection[slot].sfd);
mark_connection_closed(&reusable_connection[slot]);
}
@@ -471,13 +511,16 @@ int close_unusable_connections(void)
* Parameters :
* 1 : http = The destination for the connection.
* 2 : fwd = The forwarder settings.
+ * 3 : ssl_server_attr = Output parameter to return ssl
+ * connection attributes when there are any.
*
* Returns : JB_INVALID_SOCKET => No reusable connection found,
* otherwise a usable socket.
*
*********************************************************************/
static jb_socket get_reusable_connection(const struct http_request *http,
- const struct forward_spec *fwd)
+ const struct forward_spec *fwd,
+ ssl_connection_attr *ssl_server_attr)
{
jb_socket sfd = JB_INVALID_SOCKET;
unsigned int slot = 0;
@@ -495,6 +538,12 @@ static jb_socket get_reusable_connection(const struct http_request *http,
{
reusable_connection[slot].in_use = TRUE;
sfd = reusable_connection[slot].sfd;
+#ifdef FEATURE_SSL
+ if (reusable_connection[slot].ssl)
+ {
+ *ssl_server_attr = reusable_connection[slot].ssl_server_attr;
+ }
+#endif /* def FEATURE_SSL */
log_error(LOG_LEVEL_CONNECT,
"Found reusable socket %d for %s:%d in slot %d. Timestamp made %d "
"seconds ago. Timeout: %d. Latency: %d. Requests served: %d",
@@ -573,25 +622,34 @@ static int mark_connection_unused(const struct reusable_connection *connection)
* 1 : fwd = the proxies to use when connecting.
* 2 : http = the http request and apropos headers
* 3 : csp = Current client state (buffers, headers, etc...)
+ * 4 : ssl_server_attr = Output parameter to return ssl connection
+ * attributes when appropriate reusable connection was found.
+ * 5 : connection_found = Output parameter to return TRUE when
+ * appropriate reusable connection was found and is returned,
+ * FALSE otherway.
*
* Returns : JB_INVALID_SOCKET => failure, else it is the socket file descriptor.
*
*********************************************************************/
-jb_socket forwarded_connect(const struct forward_spec * fwd,
+extern jb_socket forwarded_connect(const struct forward_spec * fwd,
struct http_request *http,
- struct client_state *csp)
+ struct client_state *csp,
+ ssl_connection_attr *ssl_server_attr,
+ int *connection_found)
{
const char * dest_host;
int dest_port;
jb_socket sfd = JB_INVALID_SOCKET;
+ *connection_found = FALSE;
#ifdef FEATURE_CONNECTION_SHARING
if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
&& !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED))
{
- sfd = get_reusable_connection(http, fwd);
+ sfd = get_reusable_connection(http, fwd, ssl_server_attr);
if (JB_INVALID_SOCKET != sfd)
{
+ *connection_found = TRUE;
return sfd;
}
}
diff --git a/gateway.h b/gateway.h
index 544752cd..55cbb6b4 100644
--- a/gateway.h
+++ b/gateway.h
@@ -42,12 +42,14 @@ struct client_state;
extern jb_socket forwarded_connect(const struct forward_spec * fwd,
struct http_request *http,
- struct client_state *csp);
+ struct client_state *csp,
+ ssl_connection_attr *ssl_server_attr,
+ int *connection_found);
#ifdef FEATURE_CONNECTION_SHARING
extern void initialize_reusable_connections(void);
extern void forget_connection(jb_socket sfd);
-extern void remember_connection(const struct reusable_connection *connection);
+extern int remember_connection(struct reusable_connection *connection);
extern int close_unusable_connections(void);
#endif /* FEATURE_CONNECTION_SHARING */
diff --git a/project.h b/project.h
index ecdd75a0..5c14c7eb 100644
--- a/project.h
+++ b/project.h
@@ -288,10 +288,12 @@ struct map
* Srtuct of atributes necessary for SSL/TLS connection
*/
typedef struct {
+ int socket_fd;
+
#ifdef FEATURE_MBEDTLS
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
- mbedtls_net_context socket_fd;
+ mbedtls_net_context mbedtls_fd;
mbedtls_x509_crt server_cert;
mbedtls_x509_crt ca_cert;
mbedtls_pk_context prim_key;
@@ -302,7 +304,6 @@ typedef struct {
#endif /* FEATURE_MBEDTLS */
#ifdef FEATURE_LIBRESSL
- int socket_fd;
SSL_CTX * ctx;
SSL * ssl;
BIO * bio, * ssl_bio;
@@ -804,6 +805,8 @@ struct reusable_connection
*/
struct list connect_headers[1];
#endif
+
+ ssl_connection_attr ssl_server_attr;
};
--
2.26.2
From fa9b2b98faca877378ddebe8fa7e3f19902352ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:48:42 +0200
Subject: [PATCH 76/83] Changed manipulation with shared connections, so shared
ssl connections are closed properly. Also loaded ssl connection from shared
ones doesn't create ssl session again. Added copying of ssl connection
attributes in function save_connection_destination, so these attributes will
be also saved. Removed redundant ssl connection closing.
---
jcc.c | 61 ++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 42 insertions(+), 19 deletions(-)
diff --git a/jcc.c b/jcc.c
index 15e5e375..d83899b7 100644
--- a/jcc.c
+++ b/jcc.c
@@ -182,6 +182,7 @@ static void serve(struct client_state *csp);
void save_connection_destination(jb_socket sfd,
const struct http_request *http,
const struct forward_spec *fwd,
+ const ssl_connection_attr *ssl_server_attr,
struct reusable_connection *server_connection);
static void mark_server_socket_tainted(struct client_state *csp);
@@ -748,6 +749,7 @@ static int create_server_connection(struct client_state *csp) {
struct http_response *rsp;
http = csp->http;
fwd = csp->use_fwd;
+ int connection_found = FALSE;
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
@@ -767,7 +769,10 @@ static int create_server_connection(struct client_state *csp) {
#ifdef FEATURE_CONNECTION_SHARING
if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
{
- remember_connection(&csp->server_connection);
+ if (!remember_connection(&csp->server_connection))
+ {
+ csp->ssl_with_server_is_opened = 0;
+ }
}
else
#endif /* def FEATURE_CONNECTION_SHARING */
@@ -794,7 +799,8 @@ static int create_server_connection(struct client_state *csp) {
/*
* Connecting to destination server
*/
- csp->server_connection.sfd = forwarded_connect(fwd, http, csp);
+ csp->server_connection.sfd = forwarded_connect(fwd, http, csp, &(csp->ssl_server_attr), &connection_found);
+ csp->ssl_server_attr.socket_fd = csp->server_connection.sfd;
if (csp->server_connection.sfd == JB_INVALID_SOCKET)
{
@@ -837,12 +843,24 @@ static int create_server_connection(struct client_state *csp) {
}
#ifdef FEATURE_SSL
+#ifdef FEATURE_CONNECTION_SHARING
+ if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING && http->server_ssl && connection_found)
+ {
+ csp->ssl_flags |= CSP_SSL_FLAG_SERVER_CONNECTION_REUSED;
+ csp->ssl_with_server_is_opened = TRUE;
+ }
+ else
+ {
+ csp->ssl_with_server_is_opened = FALSE;
+ }
+#endif /* def FEATURE_CONNECTION_SHARING */
+
/*
* Creating SSL/TLS connections with destinantion server or parent
* proxy. If forwarding is enabled, we must send client request to
* parent proxy and receive, parse and resend parent proxy answer.
*/
- if (http->ssl && !csp->use_ssl_tunnel)
+ if (http->ssl && !csp->use_ssl_tunnel && !csp->ssl_with_server_is_opened)
{
int ret = 0;
@@ -1026,7 +1044,7 @@ static int create_server_connection(struct client_state *csp) {
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
save_connection_destination(csp->server_connection.sfd,
- http, fwd, &csp->server_connection);
+ http, fwd, &csp->ssl_server_attr, &csp->server_connection);
csp->server_connection.keep_alive_timeout =
(unsigned)csp->config->keep_alive_timeout;
}
@@ -1112,7 +1130,6 @@ static int prepare_client_connection(struct client_state *csp)
if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
{
log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
- close_client_and_server_ssl_connections(csp);
return 1;
}
}
@@ -1122,9 +1139,6 @@ static int prepare_client_connection(struct client_state *csp)
{
log_error(LOG_LEVEL_ERROR,
"Can't open secure connection with client");
-#ifndef FEATURE_CONNECTION_KEEP_ALIVE
- close_client_and_server_ssl_connections(csp);
-#endif
return 1;
}
@@ -1140,7 +1154,6 @@ static int prepare_client_connection(struct client_state *csp)
#endif
{
ssl_send_certificate_error(csp);
- close_client_and_server_ssl_connections(csp);
return 1;
}
@@ -1171,7 +1184,6 @@ static int prepare_client_connection(struct client_state *csp)
if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
{
log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
- close_client_and_server_ssl_connections(csp);
return 1;
}
ret = create_client_ssl_connection(csp);
@@ -1655,6 +1667,7 @@ static void wait_for_alive_connections(void)
void save_connection_destination(jb_socket sfd,
const struct http_request *http,
const struct forward_spec *fwd,
+ const ssl_connection_attr *ssl_server_attr,
struct reusable_connection *server_connection)
{
assert(sfd != JB_INVALID_SOCKET);
@@ -1663,6 +1676,8 @@ void save_connection_destination(jb_socket sfd,
server_connection->sfd = sfd;
server_connection->host = strdup_or_die(http->host);
server_connection->port = http->port;
+ server_connection->ssl = http->server_ssl;
+ server_connection->ssl_server_attr = *ssl_server_attr;
assert(NULL != fwd);
assert(server_connection->gateway_host == NULL);
@@ -3735,7 +3750,6 @@ static void chat(struct client_state *csp)
if (process_client_request(csp))
{
- close_client_and_server_ssl_connections(csp);
return;
}
@@ -3808,6 +3822,7 @@ extern int fuzz_server_response(struct client_state *csp, char *fuzz_input_file)
log_error(LOG_LEVEL_FATAL, "Failed to open %s: %E",
fuzz_input_file);
}
+ csp->ssl_server_attr.socket_fd = csp->server_connection.sfd;
}
csp->fwd = &fwd;
csp->content_type |= CT_GIF;
@@ -4069,10 +4084,19 @@ static void serve(struct client_state *csp)
break;
}
- remember_connection(&csp->server_connection);
+ if (!remember_connection(&csp->server_connection))
+ {
+ csp->ssl_with_server_is_opened = 0;
+ mark_connection_closed(&csp->server_connection);
+ }
csp->server_connection.sfd = JB_INVALID_SOCKET;
+
+#ifdef FEATURE_SSL
+ close_client_ssl_connection(csp);
+#endif
drain_and_close_socket(csp->cfd);
csp->cfd = JB_INVALID_SOCKET;
+
privoxy_mutex_lock(&connection_reuse_mutex);
if (!monitor_thread_running)
{
@@ -4110,16 +4134,9 @@ static void serve(struct client_state *csp)
chat(csp);
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
-#ifdef FEATURE_SSL
/*
* Closing ssl and then tcp connections, if they were opened.
*/
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
- csp->ssl_flags = 0;
-#endif
- close_client_and_server_ssl_connections(csp);
-#endif /* def FEATURE_SSL */
-
if (csp->server_connection.sfd != JB_INVALID_SOCKET)
{
#ifdef FEATURE_CONNECTION_SHARING
@@ -4128,6 +4145,12 @@ static void serve(struct client_state *csp)
forget_connection(csp->server_connection.sfd);
}
#endif /* def FEATURE_CONNECTION_SHARING */
+#ifdef FEATURE_SSL
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ csp->ssl_flags = 0;
+#endif
+ close_server_ssl_connection(csp);
+#endif /* def FEATURE_SSL */
close_socket(csp->server_connection.sfd);
}
--
2.26.2
From d00e5bc7697e8f95be51562146fe47b20b8c4bac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:52:13 +0200
Subject: [PATCH 77/83] Added functions free_ssl_structures and
close_ssl_connection into ssl.c, which are able to work with given
ssl_connection_attr. So privoxy can use mbedtls with connection-sharing
feature. Renamed socket_fd to mbedtls_fd to avoid name colision with variable
for socket fd. Added client ssl connection closing. Added freeing of
allocated memory and structures. Added missing semicolons in cgisimple.c in
part of code to shut down Privoxy.
---
cgisimple.c | 4 +-
jcc.c | 1 +
ssl.c | 159 +++++++++++++++++++++----------------------------
ssl.h | 1 +
ssl_libressl.c | 26 ++++++--
ssl_libressl.h | 1 -
6 files changed, 93 insertions(+), 99 deletions(-)
diff --git a/cgisimple.c b/cgisimple.c
index 63cd4f95..16f551c1 100644
--- a/cgisimple.c
+++ b/cgisimple.c
@@ -201,8 +201,8 @@ jb_err cgi_die (struct client_state *csp,
const struct map *parameters)
{
static const char status[] = "200 OK Privoxy shutdown request received";
- static const char body[] = CGI_SHUTDOWN_REQUEST(CGI_PREFIX)
- static const char body_ssl[] = CGI_SHUTDOWN_REQUEST(CGI_SSL_PREFIX)
+ static const char body[] = CGI_SHUTDOWN_REQUEST(CGI_PREFIX);
+ static const char body_ssl[] = CGI_SHUTDOWN_REQUEST(CGI_SSL_PREFIX);
assert(csp);
assert(rsp);
diff --git a/jcc.c b/jcc.c
index d83899b7..14f1dc36 100644
--- a/jcc.c
+++ b/jcc.c
@@ -4160,6 +4160,7 @@ static void serve(struct client_state *csp)
if (csp->cfd != JB_INVALID_SOCKET)
{
+ close_client_ssl_connection(csp);
log_error(LOG_LEVEL_CONNECT, "Closing client socket %d. "
"Keep-alive: %u. Socket alive: %u. Data available: %u. "
"Configuration file change detected: %u. Requests received: %u.",
diff --git a/ssl.c b/ssl.c
index 3f4b7580..205014b7 100644
--- a/ssl.c
+++ b/ssl.c
@@ -79,9 +79,8 @@ static int ssl_verify_callback(void *data, mbedtls_x509_crt *crt, int depth, uin
static void free_certificate_chain(struct client_state *csp);
static unsigned int get_certificate_mutex_id(struct client_state *csp);
static unsigned long get_certificate_serial(struct client_state *csp);
-static void free_client_ssl_structures(struct client_state *csp);
-static void free_server_ssl_structures(struct client_state *csp);
static int seed_rng(struct client_state *csp);
+static void free_ssl_structures(ssl_connection_attr *connection);
/*********************************************************************
@@ -400,7 +399,7 @@ extern int create_client_ssl_connection(struct client_state *csp)
/*
* Initializing mbedtls structures for SSL/TLS connection
*/
- mbedtls_net_init(&(csp->ssl_client_attr.socket_fd));
+ mbedtls_net_init(&(csp->ssl_client_attr.mbedtls_fd));
mbedtls_ssl_init(&(csp->ssl_client_attr.ssl));
mbedtls_ssl_config_init(&(csp->ssl_client_attr.conf));
mbedtls_x509_crt_init(&(csp->ssl_client_attr.server_cert));
@@ -552,7 +551,7 @@ extern int create_client_ssl_connection(struct client_state *csp)
}
mbedtls_ssl_set_bio(&(csp->ssl_client_attr.ssl),
- &(csp->ssl_client_attr.socket_fd), mbedtls_net_send,
+ &(csp->ssl_client_attr.mbedtls_fd), mbedtls_net_send,
mbedtls_net_recv, NULL);
mbedtls_ssl_session_reset(&(csp->ssl_client_attr.ssl));
@@ -561,7 +560,7 @@ extern int create_client_ssl_connection(struct client_state *csp)
* can't be setted by mbedtls functions, because we already have created
* TCP connection when starting this function.
*/
- csp->ssl_client_attr.socket_fd.fd = csp->cfd;
+ csp->ssl_client_attr.mbedtls_fd.fd = csp->cfd;
/*
* Handshake with client
@@ -603,7 +602,7 @@ exit:
/* Freeing structures if connection wasn't created successfully */
if (ret < 0)
{
- free_client_ssl_structures(csp);
+ free_ssl_structures(&csp->ssl_client_attr);
}
return ret;
}
@@ -624,8 +623,6 @@ exit:
*********************************************************************/
extern void close_client_ssl_connection(struct client_state *csp)
{
- int ret = 0;
-
if (csp->ssl_with_client_is_opened == 0
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
|| csp->ssl_flags & CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED
@@ -635,51 +632,12 @@ extern void close_client_ssl_connection(struct client_state *csp)
return;
}
- /*
- * Notifying the peer that the connection is being closed.
- */
- do {
- ret = mbedtls_ssl_close_notify(&(csp->ssl_client_attr.ssl));
- } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
+ close_ssl_connection(&csp->ssl_client_attr);
- free_client_ssl_structures(csp);
csp->ssl_with_client_is_opened = 0;
}
-/**********************************************************************
- *
- * Function : free_client_ssl_structures
- *
- * Description : Frees structures used for SSL communication with client
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : N/A
- *
- *********************************************************************/
-static void free_client_ssl_structures(struct client_state *csp)
-{
- /*
- * We can't use function mbedtls_net_free, because this function
- * inter alia close TCP connection on setted fd. Instead of this
- * function, we change fd to -1, which is the same what does
- * rest of mbedtls_net_free function.
- */
- csp->ssl_client_attr.socket_fd.fd = -1;
-
- /* Freeing mbedtls structures */
- mbedtls_x509_crt_free(&(csp->ssl_client_attr.server_cert));
- mbedtls_pk_free(&(csp->ssl_client_attr.prim_key));
- mbedtls_ssl_free(&(csp->ssl_client_attr.ssl));
- mbedtls_ssl_config_free(&(csp->ssl_client_attr.conf));
-#if defined(MBEDTLS_SSL_CACHE_C)
- mbedtls_ssl_cache_free(&(csp->ssl_client_attr.cache));
-#endif
-}
-
-
/**********************************************************************
*
* Function : create_server_ssl_connection
@@ -711,7 +669,7 @@ extern int create_server_ssl_connection(struct client_state *csp)
/*
* Initializing mbedtls structures for SSL/TLS connection
*/
- mbedtls_net_init(&(csp->ssl_server_attr.socket_fd));
+ mbedtls_net_init(&(csp->ssl_server_attr.mbedtls_fd));
mbedtls_ssl_init(&(csp->ssl_server_attr.ssl));
mbedtls_ssl_config_init(&(csp->ssl_server_attr.conf));
mbedtls_x509_crt_init( &(csp->ssl_server_attr.ca_cert));
@@ -724,7 +682,7 @@ extern int create_server_ssl_connection(struct client_state *csp)
* can't be setted by mbedtls functions, because we already have created
* TCP connection when starting this function.
*/
- csp->ssl_server_attr.socket_fd.fd = csp->server_connection.sfd;
+ csp->ssl_server_attr.mbedtls_fd.fd = csp->server_connection.sfd;
/*
* Seed the RNG
@@ -813,7 +771,7 @@ extern int create_server_ssl_connection(struct client_state *csp)
}
mbedtls_ssl_set_bio(&(csp->ssl_server_attr.ssl),
- &(csp->ssl_server_attr.socket_fd), mbedtls_net_send,
+ &(csp->ssl_server_attr.mbedtls_fd), mbedtls_net_send,
mbedtls_net_recv, NULL);
/*
@@ -868,13 +826,70 @@ exit:
/* Freeing structures if connection wasn't created successfully */
if (ret < 0)
{
- free_server_ssl_structures(csp);
+ free_ssl_structures(&csp->ssl_server_attr);
}
return ret;
}
+/**********************************************************************
+ *
+ * Function : free_ssl_structures
+ *
+ * Description : Frees given structures used for SSL communication.
+ *
+ * Parameters :
+ * 1 : connection_attr = Attributes of ssl connection
+ *
+ * Returns : N/A
+ *
+ *********************************************************************/
+static void free_ssl_structures(ssl_connection_attr *connection)
+{
+ /*
+ * We can't use function mbedtls_net_free, because this function
+ * inter alia close TCP connection on setted fd. Instead of this
+ * function, we change fd to -1, which is the same what does
+ * rest of mbedtls_net_free function.
+ */
+ connection->mbedtls_fd.fd = JB_INVALID_SOCKET;
+
+ mbedtls_x509_crt_free(&connection->ca_cert);
+ mbedtls_ssl_free(&connection->ssl);
+ mbedtls_ssl_config_free(&connection->conf);
+}
+
+
+/**********************************************************************
+ *
+ * Function : close_ssl_connection
+ *
+ * Description : Closes SSL/TLS connection with given ssl attributes.
+ * This function doesn't check if attributes are not
+ * initialized. It must be done by caller.
+ *
+ * Parameters :
+ * 1 : connection_attr = Attributes of ssl connection
+ *
+ * Returns : N/A
+ *
+ **********************************************************************/
+extern void close_ssl_connection(ssl_connection_attr *connection)
+{
+ int ret = 0;
+
+ /*
+ * Notifying the peer that the connection is being closed.
+ */
+ do {
+ ret = mbedtls_ssl_close_notify(&connection->ssl);
+ } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
+
+ free_ssl_structures(connection);
+}
+
+
/**********************************************************************
*
* Function : close_server_ssl_connection
@@ -890,8 +905,6 @@ exit:
**********************************************************************/
extern void close_server_ssl_connection(struct client_state *csp)
{
- int ret = 0;
-
if (csp->ssl_with_server_is_opened == 0
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
|| (csp->ssl_flags & CSP_SSL_FLAG_CONNECTIONS_TO_BE_REUSED
@@ -903,14 +916,8 @@ extern void close_server_ssl_connection(struct client_state *csp)
return;
}
- /*
- * Notifying the peer that the connection is being closed.
- */
- do {
- ret = mbedtls_ssl_close_notify(&(csp->ssl_server_attr.ssl));
- } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
+ close_ssl_connection(&csp->ssl_server_attr);
- free_server_ssl_structures(csp);
csp->ssl_with_server_is_opened = 0;
csp->server_connection.ssl = 0;
@@ -921,34 +928,6 @@ extern void close_server_ssl_connection(struct client_state *csp)
/*********************************************************************
- *
- * Function : free_server_ssl_structures
- *
- * Description : Frees structures used for SSL communication with server
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : N/A
- *
- *********************************************************************/
-static void free_server_ssl_structures(struct client_state *csp)
-{
- /*
- * We can't use function mbedtls_net_free, because this function
- * inter alia close TCP connection on setted fd. Instead of this
- * function, we change fd to -1, which is the same what does
- * rest of mbedtls_net_free function.
- */
- csp->ssl_server_attr.socket_fd.fd = -1;
-
- mbedtls_x509_crt_free(&(csp->ssl_server_attr.ca_cert));
- mbedtls_ssl_free(&(csp->ssl_server_attr.ssl));
- mbedtls_ssl_config_free(&(csp->ssl_server_attr.conf));
-}
-
-
-/*
* Function : close_client_and_server_ssl_connections
*
* Description : Checks if client or server should use secured connection over
@@ -959,7 +938,7 @@ static void free_server_ssl_structures(struct client_state *csp)
*
* Returns : N/A
*
- */
+ *********************************************************************/
extern void close_client_and_server_ssl_connections(struct client_state *csp)
{
if (client_use_ssl(csp) == 1)
diff --git a/ssl.h b/ssl.h
index d4170cc6..d322f2b9 100644
--- a/ssl.h
+++ b/ssl.h
@@ -66,5 +66,6 @@ extern int create_server_ssl_connection(struct client_state *csp);
extern void close_client_and_server_ssl_connections(struct client_state *csp);
extern void close_server_ssl_connection(struct client_state *csp);
extern void close_client_ssl_connection(struct client_state *csp);
+extern void close_ssl_connection(ssl_connection_attr *connection);
#endif /* ndef SSL_H_INCLUDED */
diff --git a/ssl_libressl.c b/ssl_libressl.c
index bd6350c4..a1217bcd 100644
--- a/ssl_libressl.c
+++ b/ssl_libressl.c
@@ -67,6 +67,7 @@ static int host_to_hash(struct client_state *csp);
static int ssl_cert_verify_callback(X509_STORE_CTX * ctx, void * arg);
static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, ASN1_VALUE *ext_struc);
static char* generate_cert_info(X509* cert);
+static void free_ssl_structures(ssl_connection_attr *connection_attr);
/**********************************************************************
@@ -188,7 +189,7 @@ extern int create_server_ssl_connection(struct client_state *csp)
* Creating BIO to comunicate with server over ssl.
*/
csp->ssl_server_attr.ssl_bio = BIO_new(BIO_f_ssl());
- BIO_set_ssl(csp->ssl_server_attr.ssl_bio, csp->ssl_server_attr.ssl, BIO_CLOSE);
+ BIO_set_ssl(csp->ssl_server_attr.ssl_bio, csp->ssl_server_attr.ssl, BIO_NOCLOSE);
csp->ssl_with_server_is_opened = 1;
csp->server_connection.ssl = 1;
@@ -218,7 +219,7 @@ exit:
* Returns : N/A
*
*********************************************************************/
-extern void free_ssl_structures(ssl_connection_attr *connection_attr)
+static void free_ssl_structures(ssl_connection_attr *connection_attr)
{
SSL_free(connection_attr->ssl);
SSL_CTX_free(connection_attr->ctx);
@@ -381,6 +382,8 @@ extern int create_client_ssl_connection(struct client_state *csp) {
int ret = 0;
csp->ssl_client_attr.socket_fd = csp->cfd;
const SSL_METHOD * meth;
+ char *key_file = NULL;
+ char *cert_file = NULL;
/*
* Preparing hash of host for creating certificates
@@ -396,9 +399,6 @@ extern int create_client_ssl_connection(struct client_state *csp) {
/*
* Preparing paths to certificates files and key file
*/
- char *key_file = NULL;
- char *cert_file = NULL;
-
cert_file = make_certs_path(csp->config->certs_dir,
(const char *)csp->http->hash_of_host_hex, CERT_FILE_TYPE);
if (cert_file == NULL)
@@ -490,7 +490,7 @@ extern int create_client_ssl_connection(struct client_state *csp) {
* Creating BIO to comunicate with client over ssl.
*/
csp->ssl_client_attr.ssl_bio = BIO_new(BIO_f_ssl());
- BIO_set_ssl(csp->ssl_client_attr.ssl_bio, csp->ssl_client_attr.ssl, BIO_CLOSE);
+ BIO_set_ssl(csp->ssl_client_attr.ssl_bio, csp->ssl_client_attr.ssl, BIO_NOCLOSE);
csp->ssl_with_client_is_opened = 1;
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
@@ -498,6 +498,20 @@ extern int create_client_ssl_connection(struct client_state *csp) {
#endif
ret = 0;
exit:
+ /*
+ * Freeing allocated paths to files
+ */
+ if (cert_file != NULL)
+ {
+ log_error(LOG_LEVEL_ERROR, "freeing cert file path 1");
+ freez(cert_file);
+ }
+ if (key_file != NULL)
+ {
+ log_error(LOG_LEVEL_ERROR, "freeing cert file path 2");
+ freez(key_file);
+ }
+
if (ret != 0) {
free_ssl_structures(&csp->ssl_client_attr);
}
diff --git a/ssl_libressl.h b/ssl_libressl.h
index 66c3c615..c9a7cd2e 100644
--- a/ssl_libressl.h
+++ b/ssl_libressl.h
@@ -53,7 +53,6 @@ extern int create_server_ssl_connection(struct client_state *csp);
extern void close_client_and_server_ssl_connections(struct client_state *csp);
extern void close_server_ssl_connection(struct client_state *csp);
extern void close_client_ssl_connection(struct client_state *csp);
-extern void free_ssl_structures(ssl_connection_attr *connection);
extern void close_ssl_connection(ssl_connection_attr *connection);
--
2.26.2
From 6c3c3ae498b27839446d883ef7f09e523092b1f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:55:15 +0200
Subject: [PATCH 78/83] Renamed ssl.h and ssl.c to ssl_mbedtls.h and
ssl_mbedtls.c so it's easier to differ between used ssl libraries.
---
GNUmakefile.in | 2 +-
gateway.c | 2 +-
jbsockets.c | 2 +-
jcc.c | 2 +-
ssl.c => ssl_mbedtls.c | 4 ++--
ssl.h => ssl_mbedtls.h | 10 +++++-----
6 files changed, 11 insertions(+), 11 deletions(-)
rename ssl.c => ssl_mbedtls.c (99%)
rename ssl.h => ssl_mbedtls.h (94%)
diff --git a/GNUmakefile.in b/GNUmakefile.in
index a2d88de4..b62f51a3 100644
--- a/GNUmakefile.in
+++ b/GNUmakefile.in
@@ -231,7 +231,7 @@ W32_HDRS = @WIN_ONLY@w32log.h w32taskbar.h win32.h w32res.h w32svrapi.h
W32_LIB = @WIN_ONLY@-lwsock32 -lcomctl32
W32_INIS = @WIN_ONLY@config.txt trust.txt
-SSL_MBEDTLS_SRC = @USAGE_MBEDTLS@ssl.c
+SSL_MBEDTLS_SRC = @USAGE_MBEDTLS@ssl_mbedtls.c
SSL_MBEDTLS_OBJS = @USAGE_MBEDTLS@$(SSL_MBEDTLS_SRC:.c=.o)
SSL_MBEDTLS_HDRS = @USAGE_MBEDTLS@$(SSL_MBEDTLS_SRC:.c=.h) project.h
SSL_MBEDTLS_LIB = @USAGE_MBEDTLS@mbedtls/library/libmbedx509.a mbedtls/library/libmbedtls.a mbedtls/library/libmbedcrypto.a
diff --git a/gateway.c b/gateway.c
index 5c12044f..a8a3896b 100644
--- a/gateway.c
+++ b/gateway.c
@@ -60,7 +60,7 @@
#endif /* def __OS2__ */
#ifdef FEATURE_MBEDTLS
-#include "ssl.h"
+#include "ssl_mbedtls.h"
#endif
#ifdef FEATURE_LIBRESSL
diff --git a/jbsockets.c b/jbsockets.c
index fa89ad15..49b115a6 100644
--- a/jbsockets.c
+++ b/jbsockets.c
@@ -95,7 +95,7 @@
#include "ssl_libressl.h"
#endif
#ifdef FEATURE_MBEDTLS
-#include "ssl.h"
+#include "ssl_mbedtls.h"
#endif
#include "project.h"
diff --git a/jcc.c b/jcc.c
index 14f1dc36..c91bba13 100644
--- a/jcc.c
+++ b/jcc.c
@@ -128,7 +128,7 @@
#endif
#ifdef FEATURE_MBEDTLS
-#include "ssl.h"
+#include "ssl_mbedtls.h"
#endif
#ifdef FEATURE_LIBRESSL
diff --git a/ssl.c b/ssl_mbedtls.c
similarity index 99%
rename from ssl.c
rename to ssl_mbedtls.c
index 205014b7..1da82bb3 100644
--- a/ssl.c
+++ b/ssl_mbedtls.c
@@ -1,6 +1,6 @@
/*********************************************************************
*
- * File : $Source: /cvsroot/ijbswa/current/ssl.c,v $
+ * File : $Source: /cvsroot/ijbswa/current/ssl_mbedtls.c,v $
*
* Purpose : File with SSL/TLS extension. Contains methods for
* creating, using and closing SSL/TLS connections.
@@ -39,7 +39,7 @@
#include "miscutil.h"
#include "errlog.h"
#include "jcc.h"
-#include "ssl.h"
+#include "ssl_mbedtls.h"
/* Macros for searching begin and end of certificates
diff --git a/ssl.h b/ssl_mbedtls.h
similarity index 94%
rename from ssl.h
rename to ssl_mbedtls.h
index d322f2b9..4c6ac459 100644
--- a/ssl.h
+++ b/ssl_mbedtls.h
@@ -1,9 +1,9 @@
-#ifndef SSL_H_INCLUDED
-#define SSL_H_INCLUDED
-#define SSL_H_VERSION
+#ifndef SSL_MBEDTLS_H_INCLUDED
+#define SSL_MBEDTLS_H_INCLUDED
+#define SSL_MBEDTLS_H_VERSION
/*********************************************************************
*
-* File : $Source: /cvsroot/ijbswa/current/ssl.h,v $
+* File : $Source: /cvsroot/ijbswa/current/ssl_mbedtls.h,v $
*
* Purpose : File with SSL/TLS extension. Contains methods for
* creating, using and closing SSL/TLS connections.
@@ -68,4 +68,4 @@ extern void close_server_ssl_connection(struct client_state *csp);
extern void close_client_ssl_connection(struct client_state *csp);
extern void close_ssl_connection(ssl_connection_attr *connection);
-#endif /* ndef SSL_H_INCLUDED */
+#endif /* ndef SSL_MBEDTLS_H_INCLUDED */
--
2.26.2
From b0b074fc3aecc89efd15afb442ce8b667e1c843d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 22:58:18 +0200
Subject: [PATCH 79/83] Fixes to remove errors during WIN32 compilation using
MingW. Last change necessary to compile Privoxy for Window using MingW is to
add '-lws2_32' at the end of SSL_LIBRE_LIB and SSL_MBEDTLS_LIB in
GNUmakefile, but it can't be done generaly, because it would cause an error
during compilation for linux.
---
GNUmakefile.in | 2 +-
jcc.c | 3 ++-
miscutil.c | 2 ++
project.h | 39 +++++++++++++++++++++------------------
4 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/GNUmakefile.in b/GNUmakefile.in
index b62f51a3..141061cf 100644
--- a/GNUmakefile.in
+++ b/GNUmakefile.in
@@ -770,7 +770,7 @@ w32taskbar.@OBJEXT@: w32taskbar.c config.h w32log.h w32taskbar.h
win32.@OBJEXT@: win32.c config.h jcc.h loadcfg.h pcre/pcre.h pcre/pcreposix.h pcrs.h project.h w32log.h win32.h w32svrapi.h
w32.res: w32.rc w32res.h icons/radar-01.ico icons/radar-02.ico icons/radar-03.ico icons/radar-04.ico icons/radar-05.ico icons/radar-06.ico icons/radar-07.ico icons/radar-08.ico icons/idle.ico icons/privoxy.ico config.h
- windres -F pe-i386 -D__MINGW32__=0.2 -O coff -i $< -o $@
+ i686-w64-mingw32-windres -F pe-i386 -D__MINGW32__=0.2 -O coff -i $< -o $@
$(PROGRAM): $(OBJS) $(W32_FILES)
$(LD) $(LDFLAGS) -o $(PROGRAM) $(OBJS) $(LIBS)
diff --git a/jcc.c b/jcc.c
index c91bba13..bb433be7 100644
--- a/jcc.c
+++ b/jcc.c
@@ -2904,7 +2904,6 @@ static void handle_established_connection(struct client_state *csp)
{
log_error(LOG_LEVEL_CONNECT,
"Done reading from the client.");
- log_error(LOG_LEVEL_ERROR, "CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ SET4");
csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
}
}
@@ -4160,7 +4159,9 @@ static void serve(struct client_state *csp)
if (csp->cfd != JB_INVALID_SOCKET)
{
+#ifdef FEATURE_SSL
close_client_ssl_connection(csp);
+#endif
log_error(LOG_LEVEL_CONNECT, "Closing client socket %d. "
"Keep-alive: %u. Socket alive: %u. Data available: %u. "
"Configuration file change detected: %u. Requests received: %u.",
diff --git a/miscutil.c b/miscutil.c
index cd908ebe..8b0d5327 100644
--- a/miscutil.c
+++ b/miscutil.c
@@ -854,6 +854,7 @@ int privoxy_millisleep(unsigned milliseconds)
}
+#if !defined(_WIN32) || !defined(FEATURE_LIBRESSL)
#if !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV)
/*********************************************************************
*
@@ -924,6 +925,7 @@ time_t timegm(struct tm *tm)
return answer;
}
#endif /* !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV) */
+#endif /* !defined(_WIN32) || !defined(FEATURE_LIBRESSL) */
#ifndef HAVE_SNPRINTF
diff --git a/project.h b/project.h
index 5c14c7eb..abe8ca58 100644
--- a/project.h
+++ b/project.h
@@ -45,22 +45,6 @@
#include "config.h"
-#ifdef FEATURE_MBEDTLS
-/* Mbedtls incldues */
-#include "mbedtls/net_sockets.h"
-#include "mbedtls/entropy.h"
-#include "mbedtls/ctr_drbg.h"
-
-#if defined(MBEDTLS_SSL_CACHE_C)
-#include "mbedtls/ssl_cache.h"
-#endif
-#endif /* FEATURE_MBEDTLS */
-
-#ifdef FEATURE_LIBRESSL
-#include "openssl/ssl.h"
-#endif /* FEATURE_LIBRESSL */
-
-
/*
* Macros for SSL structures
*/
@@ -89,7 +73,7 @@
*/
#ifdef STATIC_PCRE
-# include "pcre.h"
+# include "pcre/pcre.h"
#else
# ifdef PCRE_H_IN_SUBDIR
# include
@@ -105,7 +89,7 @@
#endif
#ifdef STATIC_PCRE
-# include "pcreposix.h"
+# include "pcre/pcreposix.h"
#else
# ifdef PCRE_H_IN_SUBDIR
# include
@@ -126,6 +110,25 @@
#endif
+#ifdef FEATURE_MBEDTLS
+/* Mbedtls incldues */
+# include "mbedtls/net_sockets.h"
+# include "mbedtls/entropy.h"
+# include "mbedtls/ctr_drbg.h"
+
+# if defined(MBEDTLS_SSL_CACHE_C)
+# include "mbedtls/ssl_cache.h"
+# endif
+#endif /* FEATURE_MBEDTLS */
+
+#ifdef FEATURE_LIBRESSL
+# ifdef _WIN32
+# undef X509_NAME
+# endif
+# include "openssl/ssl.h"
+#endif /* FEATURE_LIBRESSL */
+
+
#ifdef _WIN32
typedef SOCKET jb_socket;
--
2.26.2
From bbe0604930ffd407e7ef02d2f2011468488fc88e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 23:00:06 +0200
Subject: [PATCH 80/83] Added new action to configure ciphersuites using
Libressl.
---
actionlist.h | 1 +
project.h | 6 +++++-
ssl_libressl.c | 13 +++++++++++++
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/actionlist.h b/actionlist.h
index 84fd21b6..315f0f88 100644
--- a/actionlist.h
+++ b/actionlist.h
@@ -123,6 +123,7 @@ DEFINE_CGI_PARAM_NO_RADIO("redirect", ACTION_REDIRECT,
DEFINE_ACTION_MULTI ("server-header-filter", ACTION_MULTI_SERVER_HEADER_FILTER)
DEFINE_ACTION_MULTI ("server-header-tagger", ACTION_MULTI_SERVER_HEADER_TAGGER)
DEFINE_ACTION_BOOL ("session-cookies-only", ACTION_SESSION_COOKIES_ONLY)
+DEFINE_ACTION_STRING ("set-cipher-list", ACTION_SET_CIPHER_LIST, ACTION_STRING_CIPHER_LIST)
DEFINE_ACTION_STRING ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER)
DEFINE_CGI_PARAM_RADIO ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER, "pattern", 1)
DEFINE_CGI_PARAM_RADIO ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER, "blank", 0)
diff --git a/project.h b/project.h
index abe8ca58..f81f9fb2 100644
--- a/project.h
+++ b/project.h
@@ -610,6 +610,8 @@ struct iob
#define ACTION_DISABLE_HTTPS_FILTER 0x20000000UL
/** Action bitmap: Turn certificates verification off */
#define ACTION_IGNORE_CERTIFICATE_ERRORS 0x40000000UL
+/** Action bitmap: Sets specific cipher list */
+#define ACTION_SET_CIPHER_LIST 0x80000000UL
/** Action string index: How to deanimate GIFs */
@@ -652,8 +654,10 @@ struct iob
#define ACTION_STRING_LIMIT_COOKIE_LIFETIME 18
/** Action string index: how many milliseconds writes should be delayed. */
#define ACTION_STRING_DELAY_RESPONSE 19
+/** Action string index: Cipher list. */
+#define ACTION_STRING_CIPHER_LIST 20
/** Number of string actions. */
-#define ACTION_STRING_COUNT 20
+#define ACTION_STRING_COUNT 21
/* To make the ugly hack in sed easier to understand */
diff --git a/ssl_libressl.c b/ssl_libressl.c
index a1217bcd..3518e3a5 100644
--- a/ssl_libressl.c
+++ b/ssl_libressl.c
@@ -137,6 +137,19 @@ extern int create_server_ssl_connection(struct client_state *csp)
}
csp->ssl_server_attr.ssl = SSL_new(csp->ssl_server_attr.ctx);
+
+ /* Setting ciphersuites */
+ if (csp->action->flags & ACTION_SET_CIPHER_LIST)
+ {
+ log_error(LOG_LEVEL_CONNECT, "Setting cipher list 1 \"%s\" for %s", csp->action->string[ACTION_STRING_CIPHER_LIST], csp->http->host);
+ ret = SSL_set_cipher_list(csp->ssl_server_attr.ssl, csp->action->string[ACTION_STRING_CIPHER_LIST]);
+ if (ret != 1)
+ {
+ log_error(LOG_LEVEL_ERROR, "Given cipher suite \"%s\" can't be set", csp->action->string[ACTION_STRING_CIPHER_LIST]);
+ ret = -1;
+ goto exit;
+ }
+ }
/*
* Setting hostname for handshake and server certificate verification
--
2.26.2
From ecff5560fd80854e8608c1feea65aed55a0cc7ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 23:00:36 +0200
Subject: [PATCH 81/83] Added ciphersuites configuration using Mbed TLS.
---
project.h | 1 +
ssl_mbedtls.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 91 insertions(+)
diff --git a/project.h b/project.h
index f81f9fb2..296e9816 100644
--- a/project.h
+++ b/project.h
@@ -296,6 +296,7 @@ typedef struct {
#ifdef FEATURE_MBEDTLS
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
+ int* ciphersuites_list;
mbedtls_net_context mbedtls_fd;
mbedtls_x509_crt server_cert;
mbedtls_x509_crt ca_cert;
diff --git a/ssl_mbedtls.c b/ssl_mbedtls.c
index 1da82bb3..7e629c3c 100644
--- a/ssl_mbedtls.c
+++ b/ssl_mbedtls.c
@@ -81,6 +81,7 @@ static unsigned int get_certificate_mutex_id(struct client_state *csp);
static unsigned long get_certificate_serial(struct client_state *csp);
static int seed_rng(struct client_state *csp);
static void free_ssl_structures(ssl_connection_attr *connection);
+static int* get_ciphersuites_from_string(const char* ciphersuites_string);
/*********************************************************************
@@ -746,6 +747,21 @@ extern int create_server_ssl_connection(struct client_state *csp)
mbedtls_ssl_conf_dbg(&(csp->ssl_server_attr.conf),
ssl_debug_callback, stdout);
+ /* Setting ciphersuites */
+ if (csp->action->flags & ACTION_SET_CIPHER_LIST) {
+ csp->ssl_server_attr.ciphersuites_list =
+ get_ciphersuites_from_string(csp->action->string[ACTION_STRING_CIPHER_LIST]);
+ if (csp->ssl_server_attr.ciphersuites_list == NULL)
+ {
+ log_error(LOG_LEVEL_ERROR, "Given cipher suite \"%s\" can't be set",
+ csp->action->string[ACTION_STRING_CIPHER_LIST]);
+ ret = -1;
+ goto exit;
+ }
+ mbedtls_ssl_conf_ciphersuites(&(csp->ssl_server_attr.conf),
+ csp->ssl_server_attr.ciphersuites_list);
+ }
+
ret = mbedtls_ssl_setup(&(csp->ssl_server_attr.ssl),
&(csp->ssl_server_attr.conf));
if ( ret != 0)
@@ -857,6 +873,7 @@ static void free_ssl_structures(ssl_connection_attr *connection)
mbedtls_x509_crt_free(&connection->ca_cert);
mbedtls_ssl_free(&connection->ssl);
+ freez(connection->ciphersuites_list);
mbedtls_ssl_config_free(&connection->conf);
}
@@ -952,6 +969,79 @@ extern void close_client_and_server_ssl_connections(struct client_state *csp)
}
+/*********************************************************************
+ * Function : get_ciphersuites_from_string
+ *
+ * Description : Converts string of ciphersuites marco's names to
+ * array of ciphersuite's ids.
+ *
+ * Parameters :
+ * 1 : ciphersuites_string = String containing allowed
+ * ciphersuites.
+ *
+ * Returns : Array of ciphersuite's ids
+ *
+ *********************************************************************/
+static int* get_ciphersuites_from_string(const char* parameter_string) {
+ size_t count = 2;
+ char* ciphersuites_index, *item_end, *ciphersuites_string;
+ int index = 0;
+ int *ciphersuite_ids;
+ const char separator = ':';
+ int parameter_len = strlen(parameter_string);
+
+ ciphersuites_string = calloc(parameter_len + 1, sizeof(char));
+ if (ciphersuites_string == NULL)
+ {
+ log_error(LOG_LEVEL_ERROR, "get_ciphersuites_from_string failed: calloc fail");
+ return NULL;
+ }
+ strncpy(ciphersuites_string, parameter_string, parameter_len);
+ ciphersuites_index = ciphersuites_string;
+
+ while (*ciphersuites_index)
+ {
+ if (*ciphersuites_index++ == separator)
+ {
+ ++count;
+ }
+ }
+
+ ciphersuite_ids = (int *)calloc(count, sizeof(int));
+ if (ciphersuite_ids == NULL)
+ {
+ log_error(LOG_LEVEL_ERROR, "get_ciphersuites_from_string failed: calloc fail");
+ freez(ciphersuites_string);
+ return NULL;
+ }
+
+ ciphersuites_index = ciphersuites_string;
+ do {
+ item_end = strchr(ciphersuites_index, separator);
+ if (item_end != NULL)
+ {
+ *item_end = '\0';
+ }
+
+ int val = mbedtls_ssl_get_ciphersuite_id(ciphersuites_index);
+ ciphersuite_ids[index] = val;
+ if (ciphersuite_ids[index] == 0)
+ {
+ log_error(LOG_LEVEL_ERROR, "Failed to get ciphersuite_id for %s", ciphersuites_index);
+ freez(ciphersuite_ids);
+ freez(ciphersuites_string);
+ return NULL;
+ }
+ ciphersuites_index = item_end + 1;
+ index++;
+ } while (item_end != NULL);
+
+ ciphersuite_ids[index] = 0;
+ freez(ciphersuites_string);
+ return ciphersuite_ids;
+}
+
+
/*********************************************************************
*
* Function : tunnel_established_successfully
--
2.26.2
From 5a3fe2c29f24d68a0adfef20e05ce1ebbc662ecc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 23:02:47 +0200
Subject: [PATCH 82/83] All functinos from ssl libraries were separated into
ssl_libressl.c and ssl_mbedtls.c files.
---
jbsockets.c | 27 ++-----------------------
jcc.c | 34 +++++++------------------------
ssl_libressl.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
ssl_libressl.h | 2 ++
ssl_mbedtls.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
ssl_mbedtls.h | 2 ++
6 files changed, 121 insertions(+), 52 deletions(-)
diff --git a/jbsockets.c b/jbsockets.c
index 49b115a6..778ca8e3 100644
--- a/jbsockets.c
+++ b/jbsockets.c
@@ -1744,36 +1744,13 @@ extern int connection_is_still_alive(struct client_state *csp, int src)
extern int connection_is_still_alive_ssl_attr(ssl_connection_attr *connection_attr, int is_using_ssl)
{
#ifdef FEATURE_SSL
- unsigned char tmp[10];
-#endif
-
if (is_using_ssl && data_is_available_tcp_ssl_ssl_attr(connection_attr, 0, 0))
{
-#ifdef FEATURE_MBEDTLS
- /*
- * mbedtls_ssl_read reads available data and checks connection state.
- * When connection was closed by peer, closure notifice is returned.
- * Otherway, no chars are set to given buffer and stay pending.
- */
- if (mbedtls_ssl_read(&connection_attr->ssl, tmp, 0) == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
- {
+ if (was_connection_closed_by_peer(connection_attr)) {
return FALSE;
}
-#endif /* def FEATURE_MBEDTLS */
-#ifdef FEATURE_LIBRESSL
- /*
- * We have to call data_is_available_tcp_ssl and SSL_peek, because
- * it loads SSL shutdown flag, which signals whether "close notify"
- * alert was received or not.
- */
- SSL_peek(connection_attr->ssl, tmp, 1);
- if (SSL_get_shutdown(connection_attr->ssl) & SSL_RECEIVED_SHUTDOWN)
- {
- return FALSE;
- }
-#endif /* def FEATURE_LIBRESSL */
}
-
+#endif /* def FEATURE_SSL */
return socket_is_still_alive(connection_attr->socket_fd);
}
diff --git a/jcc.c b/jcc.c
index bb433be7..ad2b2c97 100644
--- a/jcc.c
+++ b/jcc.c
@@ -965,14 +965,7 @@ static int create_server_connection(struct client_state *csp) {
*/
if (ret != 0
-#ifdef FEATURE_MBEDTLS
- && (csp->server_cert_verification_result == SSL_CERT_NOT_VERIFIED
- || csp->server_cert_verification_result == SSL_CERT_VALID)
-#endif
-#ifdef FEATURE_LIBRESSL
- && (csp->server_cert_verification_result == X509_V_OK)
-#endif
- )
+ && (is_server_certificate_valid(csp->server_cert_verification_result)))
{
rsp = error_response(csp, "connect-failed");
if (rsp)
@@ -1018,16 +1011,8 @@ static int create_server_connection(struct client_state *csp) {
* wasn't detected, we can interrupt this fuction. Otherwise, we
* must inform client about invalid server certificate.
*/
-
if (ret != 0
-#ifdef FEATURE_MBEDTLS
- && (csp->server_cert_verification_result == SSL_CERT_NOT_VERIFIED
- || csp->server_cert_verification_result == SSL_CERT_VALID)
-#endif
-#ifdef FEATURE_LIBRESSL
- && (csp->server_cert_verification_result == X509_V_OK)
-#endif
- )
+ && (is_server_certificate_valid(csp->server_cert_verification_result)))
{
rsp = error_response(csp, "connect-failed");
if (rsp)
@@ -1146,16 +1131,11 @@ static int prepare_client_connection(struct client_state *csp)
* If server certificate is invalid, we must inform client and then
* close connection with client.
*/
-#ifdef FEATURE_MBEDTLS
- if (csp->server_cert_verification_result != SSL_CERT_VALID)
-#endif
-#ifdef FEATURE_LIBRESSL
- if (csp->server_cert_verification_result != X509_V_OK)
-#endif
- {
- ssl_send_certificate_error(csp);
- return 1;
- }
+ if (!is_server_certificate_valid(csp->server_cert_verification_result))
+ {
+ ssl_send_certificate_error(csp);
+ return 1;
+ }
log_error(LOG_LEVEL_CONNECT, "SSL connection with client was created successfully");
}
diff --git a/ssl_libressl.c b/ssl_libressl.c
index 3518e3a5..53fed659 100644
--- a/ssl_libressl.c
+++ b/ssl_libressl.c
@@ -763,6 +763,60 @@ extern int tunnel_established_successfully(const char * server_response, unsigne
}
+/*********************************************************************
+ *
+ * Function : was_connection_closed_by_peer
+ *
+ * Description : Check whether peer has sent "close notify" message
+ * to the proxy server. It would mean that peer has
+ * closed TLS connection with proxy server.
+ *
+ * Parameters :
+ * 1 : connection_attr = Attributes of ssl connection
+ *
+ * Returns : 1 => Peer has closed the connection
+ * 0 => Peer hasn't closed the connection
+ *
+ *********************************************************************/
+extern int was_connection_closed_by_peer(ssl_connection_attr *connection_attr) {
+ unsigned char tmp[10];
+
+ /*
+ * We have to call data_is_available_tcp_ssl and SSL_peek, because
+ * it loads SSL shutdown flag, which signals whether "close notify"
+ * alert was received or not.
+ */
+ SSL_peek(connection_attr->ssl, tmp, 1);
+ if (SSL_get_shutdown(connection_attr->ssl) & SSL_RECEIVED_SHUTDOWN)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*********************************************************************
+ *
+ * Function : is_server_certificate_valid
+ *
+ * Description : Check whether server's certificate is valid or not.
+ * Result is determined from given parameter, which is
+ * result of certificate verification.
+ *
+ * Parameters :
+ * 1 : server_cert_verification_result = Certificate
+ verification result
+ *
+ * Returns : 1 => Certificate is valid
+ * 0 => Certificate is invalid
+ *
+ *********************************************************************/
+extern int is_server_certificate_valid(uint32_t server_cert_verification_result) {
+ return server_cert_verification_result == X509_V_OK;
+}
+
+
/*********************************************************************
*
* Function : ssl_flush_socket
diff --git a/ssl_libressl.h b/ssl_libressl.h
index c9a7cd2e..9fb0d058 100644
--- a/ssl_libressl.h
+++ b/ssl_libressl.h
@@ -39,6 +39,8 @@ extern int client_use_ssl(struct client_state *csp);
extern int server_use_ssl(struct client_state *csp);
extern size_t is_ssl_pending(const ssl_connection_attr *connection);
extern int tunnel_established_successfully(const char * response, unsigned int response_len);
+extern int was_connection_closed_by_peer(ssl_connection_attr *connection_attr);
+extern int is_server_certificate_valid(uint32_t server_cert_verification_result);
/* Functions for sending and receiving data over SSL/TLS connections */
extern int ssl_send_data(const ssl_connection_attr *connection, const unsigned char * buf, int len);
diff --git a/ssl_mbedtls.c b/ssl_mbedtls.c
index 7e629c3c..5802c48b 100644
--- a/ssl_mbedtls.c
+++ b/ssl_mbedtls.c
@@ -1101,6 +1101,60 @@ extern int tunnel_established_successfully(const char * server_response, unsigne
}
+/*********************************************************************
+ *
+ * Function : was_connection_closed_by_peer
+ *
+ * Description : Check whether peer has sent "close notify" message
+ * to the proxy server. It would mean that peer has
+ * closed TLS connection with proxy server.
+ *
+ * Parameters :
+ * 1 : connection_attr = Attributes of ssl connection
+ *
+ * Returns : 1 => Peer has closed the connection
+ * 0 => Peer hasn't closed the connection
+ *
+ *********************************************************************/
+extern int was_connection_closed_by_peer(ssl_connection_attr *connection_attr) {
+ unsigned char tmp[10];
+
+ /*
+ * mbedtls_ssl_read reads available data and checks connection state.
+ * When connection was closed by peer, closure notifice is returned.
+ * Otherway, no chars are set to given buffer and stay pending.
+ */
+ if (mbedtls_ssl_read(&connection_attr->ssl, tmp, 0) == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*********************************************************************
+ *
+ * Function : is_server_certificate_valid
+ *
+ * Description : Check whether server's certificate is valid or not.
+ * Result is determined from given parameter, which is
+ * result of certificate verification.
+ *
+ * Parameters :
+ * 1 : server_cert_verification_result = Certificate
+ verification result
+ *
+ * Returns : 1 => Certificate is valid
+ * 0 => Certificate is invalid
+ *
+ *********************************************************************/
+extern int is_server_certificate_valid(uint32_t server_cert_verification_result) {
+ return server_cert_verification_result == SSL_CERT_NOT_VERIFIED
+ || server_cert_verification_result == SSL_CERT_VALID;
+}
+
+
/*======================Certificates======================*/
/*********************************************************************
diff --git a/ssl_mbedtls.h b/ssl_mbedtls.h
index 4c6ac459..862024e7 100644
--- a/ssl_mbedtls.h
+++ b/ssl_mbedtls.h
@@ -52,6 +52,8 @@ extern int client_use_ssl(struct client_state *csp);
extern int server_use_ssl(struct client_state *csp);
extern size_t is_ssl_pending(const ssl_connection_attr *connection);
extern int tunnel_established_successfully(const char * response, unsigned int response_len);
+extern int was_connection_closed_by_peer(ssl_connection_attr *connection_attr);
+extern int is_server_certificate_valid(uint32_t server_cert_verification_result);
/* Functions for sending and receiving data over SSL/TLS connections */
extern int ssl_send_data(const ssl_connection_attr * connection, const unsigned char * buf, int len);
--
2.26.2
From b6fc6c5810dd0b1a65d878f494749061d4ddb045 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20=C5=A0vec?=
Date: Sun, 17 May 2020 23:04:18 +0200
Subject: [PATCH 83/83] Added documentation into INSTALL files and configure.in
file.
---
INSTALL | 21 +++++++++++
INSTALL.W32 | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++
configure.in | 9 +++--
3 files changed, 128 insertions(+), 3 deletions(-)
create mode 100644 INSTALL.W32
diff --git a/INSTALL b/INSTALL
index 4acc4cf9..4d547df1 100644
--- a/INSTALL
+++ b/INSTALL
@@ -95,6 +95,27 @@ configurations, configure like this:
Note that all of these options can also be disabled through the configuration
file.
+To build an executable with SSL features, which allows to filter HTTPS
+communication, some SSL library has to be used. Defaultly LibreSSL is enabled.
+To disable LibreSSL library, you can use:
+
+./configure --disable-libressl
+
+so no SSL feature will be supported. When LibreSSL is enabled, compiled
+LibreSSL library is expected in directory "libressl" in source directory.
+
+To use MbedTLS library for SSL features, use:
+
+./configure --enable-mbedtls
+
+It will cause, that MbedTLS library will be used instead of LibreSSL. When
+MbedTLS library is used, then it's expected compiled in directory "mbedtls"
+in source directory.
+
+When some SSL library is used, required SSL attributes has to be configured
+correctly in "config" file and relevant certificates, keys and directories have
+to be prepared in specified paths.
+
WARNING: If installing as root, the install will fail unless a non-root user or
group is specified, or a privoxy user and group already exist on the system. If
a non-root user is specified, and no group, then the installation will try to
diff --git a/INSTALL.W32 b/INSTALL.W32
new file mode 100644
index 00000000..fe2bd448
--- /dev/null
+++ b/INSTALL.W32
@@ -0,0 +1,101 @@
+/*********************************************************************
+ *
+ * File : $Source: /cvsroot/ijbswa/current/doc/source/install.sgml,v $
+ *
+ * Purpose : INSTALL file to help with building Privoxy for WIN32
+ * from source using wine.
+ *
+ * Copyright : Written by and Copyright (C) 2001-2009 the
+ * Privoxy team. https://www.privoxy.org/
+ *
+ * Based on the Internet Junkbuster originally written
+ * by and Copyright (C) 1997 Anonymous Coders and
+ * Junkbusters Corporation. http://www.junkbusters.com
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will
+ * be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * The GNU General Public License should be included with
+ * this file. If not, you can view it at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
+ *
+ *********************************************************************/
+
+-------------------------------------------------------------------------------
+
+To build Privoxy from source, autoconf, GNU make (gmake), and, of course, a C
+compiler like gcc are required.
+
+When building from a source tarball, first unpack the source:
+
+ tar xzvf privoxy-3.0.28-stable-src.tar.gz
+ cd privoxy-3.0.28-stable
+
+Then cryptographic library has to be prepared. Latest version of
+recomended LibreSSL library can be downloaded here:
+ https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/
+
+To prepare it for Privoxy build, move downloaded tar.gz file into
+Privoxy directory and use:
+
+ tar -xzvf ./libressl-x.x.x.tar.gz #x.x.x have to be replaced by downloaded version number
+ mv libressl-x.x.x libressl #x.x.x have to be replaced by downloaded version number
+ cd libressl
+
+ CC=i686-w64-mingw32-gcc CPPFLAGS=-D__MINGW_USE_VC2005_COMPAT ./configure --host=i686-w64-mingw32
+ make
+
+Then, to build from either unpacked tarball or CVS source:
+
+ autoheader
+ autoconf
+ ./configure --host=i686-w64-mingw32 --enable-mingw32 --disable-pthread # (--help to see options)
+ # Edit GNUmakefile and rewrite "windres" to "i686-w64-mingw32-windres"
+ make # (the make from GNU, sometimes called gmake)
+
+To build an executable with security enhanced features so that users cannot
+easily bypass the proxy (e.g. "Go There Anyway"), or alter their own
+configurations, add following options to configure script:
+
+ --disable-toggle --disable-editor --disable-force
+
+Note that all of these options can also be disabled through the configuration
+file.
+
+To build an executable with SSL features, which allows to filter HTTPS
+communication, some SSL library has to be used. Defaultly LibreSSL is enabled.
+To disable LibreSSL library, you can use:
+
+./configure --disable-libressl
+
+so no SSL feature will be supported. When LibreSSL is enabled, compiled
+LibreSSL library is expected in directory "libressl" in source directory.
+
+To use MbedTLS library for SSL features, use:
+
+./configure --enable-mbedtls
+
+It will cause, that MbedTLS library will be used instead of LibreSSL. When
+MbedTLS library is used, then it's expected compiled in directory "mbedtls"
+in source directory.
+
+When some SSL library is used, required SSL attributes has to be configured
+correctly in "config" file and relevant certificates, keys and directories have
+to be prepared in specified paths.
+
+Command make will create file privoxy.exe which can by run using wine or
+OS Windows.
+
+Alternativly Cygwin can be used to build Privoxy for Windows OS.
\ No newline at end of file
diff --git a/configure.in b/configure.in
index 5cb94456..587981ba 100644
--- a/configure.in
+++ b/configure.in
@@ -1025,7 +1025,7 @@ AC_SUBST(FEATURE_CLIENT_TAGS_ONLY)
FUZZ_ONLY="#"
AC_ARG_ENABLE(fuzz,
-[ --enable-fuzz Enable code that makes fuzzing more convenient],
+[ --enable-fuzz Enable code that makes fuzzing more convenient],
[if test $enableval = yes; then
FUZZ_ONLY=""
AC_DEFINE(FUZZ,1,[Define to make fuzzing more convenient.])
@@ -1087,12 +1087,15 @@ dnl SSL libraries
dnl =================================================================
AC_ARG_ENABLE(libressl,
-[ --disable-libressl Set Privoxy not to use libressl for SSL comunication and filtering. Libressl is defaultly enabled.],
+[ --disable-libressl Set Privoxy not to use LibreSSL for SSL communication. When no SSL library is enabled,
+ Privoxy will use SSL tunnel for SSL connections and encrypted data will not be filtered.
+ LibreSSL is defaultly enabled.],
[disablelibressl=yes],
[disablelibressl=no])
AC_ARG_ENABLE(mbedtls,
-[ --enable-mbedtls Allow Privoxy to use mbedtls for SSL comunication and filtering.],
+[ --enable-mbedtls Set Privoxy to use MbedTLS for SSL comunication. When this option is enabled, LibreSSL
+ is automatically disabled.],
[enablembedtls=$enableval],
[enablembedtls=no])
--
2.26.2