From 315b61b3190f4b10f0710638bfaad27373fb3671 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 8 Dec 2021 11:31:35 +0000 Subject: [PATCH] [Rework] Rework SSL flag operations --- src/libserver/http/http_connection.c | 46 +++++++++++++++++++--------- src/libserver/http/http_connection.h | 12 +++++--- src/libserver/http/http_message.c | 4 +-- src/libserver/http/http_private.h | 2 +- src/libserver/maps/map.c | 13 +++++--- src/lua/lua_http.c | 10 ++++-- 6 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/libserver/http/http_connection.c b/src/libserver/http/http_connection.c index 478e00984..3dfe8e86c 100644 --- a/src/libserver/http/http_connection.c +++ b/src/libserver/http/http_connection.c @@ -1242,12 +1242,13 @@ rspamd_http_connection_new_client (struct rspamd_http_context *ctx, } struct rspamd_http_connection * -rspamd_http_connection_new_keepalive (struct rspamd_http_context *ctx, - rspamd_http_body_handler_t body_handler, - rspamd_http_error_handler_t error_handler, - rspamd_http_finish_handler_t finish_handler, - rspamd_inet_addr_t *addr, - const gchar *host) +rspamd_http_connection_new_client_keepalive (struct rspamd_http_context *ctx, + rspamd_http_body_handler_t body_handler, + rspamd_http_error_handler_t error_handler, + rspamd_http_finish_handler_t finish_handler, + unsigned opts, + rspamd_inet_addr_t *addr, + const gchar *host) { struct rspamd_http_connection *conn; @@ -1255,7 +1256,8 @@ rspamd_http_connection_new_keepalive (struct rspamd_http_context *ctx, ctx = rspamd_http_context_default (); } - conn = rspamd_http_context_check_keepalive(ctx, addr, host, false); + conn = rspamd_http_context_check_keepalive(ctx, addr, host, + opts & RSPAMD_HTTP_CLIENT_SSL); if (conn) { return conn; @@ -1263,11 +1265,12 @@ rspamd_http_connection_new_keepalive (struct rspamd_http_context *ctx, conn = rspamd_http_connection_new_client (ctx, body_handler, error_handler, finish_handler, - RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_KEEP_ALIVE, + opts|RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_KEEP_ALIVE, addr); if (conn) { - rspamd_http_context_prepare_keepalive(ctx, conn, addr, host, ); + rspamd_http_context_prepare_keepalive(ctx, conn, addr, host, + opts & RSPAMD_HTTP_CLIENT_SSL); } return conn; @@ -1879,7 +1882,7 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted, "Connection: %s\r\n" "Content-Length: %z\r\n", http_method_str(msg->method), - (msg->flags & RSPAMD_HTTP_FLAG_SSL) ? "https" : "http", + (conn->opts & RSPAMD_HTTP_CLIENT_SSL) ? "https" : "http", host, msg->port, msg->url, @@ -1893,7 +1896,7 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted, "Host: %s\r\n" "Content-Length: %z\r\n", http_method_str(msg->method), - (msg->flags & RSPAMD_HTTP_FLAG_SSL) ? "https" : "http", + (conn->opts & RSPAMD_HTTP_CLIENT_SSL) ? "https" : "http", host, msg->port, msg->url, @@ -1986,6 +1989,16 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn priv->buf->data = rspamd_fstring_sized_new (512); buf = priv->buf->data; + if ((msg->flags & RSPAMD_HTTP_FLAG_WANT_SSL) && !(conn->opts & RSPAMD_HTTP_CLIENT_SSL)) { + err = g_error_new (HTTP_ERROR, 400, + "SSL connection requested but not created properly, internal error"); + rspamd_http_connection_ref (conn); + conn->error_handler (conn, err); + rspamd_http_connection_unref (conn); + g_error_free (err); + return FALSE; + } + if (priv->peer_key && priv->local_key) { priv->msg->peer_key = priv->peer_key; priv->peer_key = NULL; @@ -2282,14 +2295,19 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_RESETED; - if (priv->flags & RSPAMD_HTTP_CONN_FLAG_PROXY) { + if ((priv->flags & RSPAMD_HTTP_CONN_FLAG_PROXY) && (conn->opts & RSPAMD_HTTP_CLIENT_SSL)) { /* We need to disable SSL flag! */ - msg->flags &=~ RSPAMD_HTTP_FLAG_SSL; + err = g_error_new (HTTP_ERROR, 400, "cannot use proxy for SSL connections"); + rspamd_http_connection_ref (conn); + conn->error_handler (conn, err); + rspamd_http_connection_unref (conn); + g_error_free (err); + return FALSE; } rspamd_ev_watcher_stop (priv->ctx->event_loop, &priv->ev); - if (msg->flags & RSPAMD_HTTP_FLAG_SSL) { + if (conn->opts & RSPAMD_HTTP_CLIENT_SSL) { gpointer ssl_ctx = (msg->flags & RSPAMD_HTTP_FLAG_SSL_NOVERIFY) ? priv->ctx->ssl_ctx_noverify : priv->ctx->ssl_ctx; diff --git a/src/libserver/http/http_connection.h b/src/libserver/http/http_connection.h index cc7c8a8f1..029dbc745 100644 --- a/src/libserver/http/http_connection.h +++ b/src/libserver/http/http_connection.h @@ -67,10 +67,6 @@ struct rspamd_storage_shmem { * Store body of the message in an immutable shared memory segment */ #define RSPAMD_HTTP_FLAG_SHMEM_IMMUTABLE (1 << 3) -/** - * Use tls for this message (how the fuck SSL flag could be used PER MESSAGE???) - */ -#define RSPAMD_HTTP_FLAG_SSL (1 << 4) /** * Body has been set for a message */ @@ -83,6 +79,10 @@ struct rspamd_storage_shmem { * Body has been set for a message */ #define RSPAMD_HTTP_FLAG_HAS_HOST_HEADER (1 << 7) +/** + * Message is intended for SSL connection + */ +#define RSPAMD_HTTP_FLAG_WANT_SSL (1 << 8) /** * Options for HTTP connection */ @@ -93,6 +93,7 @@ enum rspamd_http_options { RSPAMD_HTTP_CLIENT_SHARED = 1u << 3, /**< Store reply in shared memory */ RSPAMD_HTTP_REQUIRE_ENCRYPTION = 1u << 4, RSPAMD_HTTP_CLIENT_KEEP_ALIVE = 1u << 5, + RSPAMD_HTTP_CLIENT_SSL = 1u << 6u, }; typedef int (*rspamd_http_body_handler_t) (struct rspamd_http_connection *conn, @@ -154,11 +155,12 @@ struct rspamd_http_connection *rspamd_http_connection_new_server ( * @param host * @return */ -struct rspamd_http_connection *rspamd_http_connection_new_keepalive ( +struct rspamd_http_connection *rspamd_http_connection_new_client_keepalive ( struct rspamd_http_context *ctx, rspamd_http_body_handler_t body_handler, rspamd_http_error_handler_t error_handler, rspamd_http_finish_handler_t finish_handler, + unsigned opts, rspamd_inet_addr_t *addr, const gchar *host); diff --git a/src/libserver/http/http_message.c b/src/libserver/http/http_message.c index d15856956..962699a9c 100644 --- a/src/libserver/http/http_message.c +++ b/src/libserver/http/http_message.c @@ -75,7 +75,7 @@ rspamd_http_message_from_url (const gchar *url) if ((pu.field_set & (1 << UF_SCHEMA))) { if (pu.field_data[UF_SCHEMA].len == sizeof ("https") - 1 && memcmp (url + pu.field_data[UF_SCHEMA].off, "https", 5) == 0) { - flags |= RSPAMD_HTTP_FLAG_SSL; + flags |= RSPAMD_HTTP_FLAG_WANT_SSL; } } @@ -97,7 +97,7 @@ rspamd_http_message_from_url (const gchar *url) } else { /* XXX: magic constant */ - if (flags & RSPAMD_HTTP_FLAG_SSL) { + if (flags & RSPAMD_HTTP_FLAG_WANT_SSL) { msg->port = 443; } else { diff --git a/src/libserver/http/http_private.h b/src/libserver/http/http_private.h index 6306d197b..c6a5b497b 100644 --- a/src/libserver/http/http_private.h +++ b/src/libserver/http/http_private.h @@ -86,7 +86,7 @@ struct rspamd_http_message { struct rspamd_keepalive_hash_key { rspamd_inet_addr_t *addr; gchar *host; - bool is_ssl; + gboolean is_ssl; GQueue conns; }; diff --git a/src/libserver/maps/map.c b/src/libserver/maps/map.c index 938f4a47f..531a7ce10 100644 --- a/src/libserver/maps/map.c +++ b/src/libserver/maps/map.c @@ -91,11 +91,6 @@ write_http_request (struct http_callback_data *cbd) struct rspamd_http_message *msg; msg = rspamd_http_new_message (HTTP_REQUEST); - - if (cbd->bk->protocol == MAP_PROTO_HTTPS) { - msg->flags |= RSPAMD_HTTP_FLAG_SSL; - } - if (cbd->check) { msg->method = HTTP_HEAD; } @@ -1268,6 +1263,9 @@ rspamd_map_dns_callback (struct rdns_reply *reply, void *arg) retry: msg_debug_map ("try open http connection to %s", rspamd_inet_address_to_string_pretty (cbd->addr)); + if (cbd->bk->protocol == MAP_PROTO_HTTPS) { + flags |= RSPAMD_HTTP_CLIENT_SSL; + } cbd->conn = rspamd_http_connection_new_client (NULL, NULL, http_map_error, @@ -1792,6 +1790,11 @@ check: strlen (data->host), RSPAMD_INET_ADDRESS_PARSE_DEFAULT)) { rspamd_inet_address_set_port (addr, cbd->data->port); g_ptr_array_add (cbd->addrs, (void *)addr); + + if (bk->protocol == MAP_PROTO_HTTPS) { + flags |= RSPAMD_HTTP_CLIENT_SSL; + } + cbd->conn = rspamd_http_connection_new_client ( NULL, NULL, diff --git a/src/lua/lua_http.c b/src/lua/lua_http.c index 2f1a1c5a7..1fee9e313 100644 --- a/src/lua/lua_http.c +++ b/src/lua/lua_http.c @@ -388,14 +388,20 @@ static gboolean lua_http_make_connection (struct lua_http_cbdata *cbd) { rspamd_inet_address_set_port (cbd->addr, cbd->msg->port); + unsigned http_opts = RSPAMD_HTTP_CLIENT_SIMPLE; + + if (cbd->msg->flags & RSPAMD_HTTP_FLAG_WANT_SSL) { + http_opts |= RSPAMD_HTTP_CLIENT_SSL; + } if (cbd->flags & RSPAMD_LUA_HTTP_FLAG_KEEP_ALIVE) { cbd->fd = -1; /* FD is owned by keepalive connection */ - cbd->conn = rspamd_http_connection_new_keepalive ( + cbd->conn = rspamd_http_connection_new_client_keepalive( NULL, /* Default context */ NULL, lua_http_error_handler, lua_http_finish_handler, + http_opts, cbd->addr, cbd->host); } @@ -406,7 +412,7 @@ lua_http_make_connection (struct lua_http_cbdata *cbd) NULL, lua_http_error_handler, lua_http_finish_handler, - RSPAMD_HTTP_CLIENT_SIMPLE, + http_opts, cbd->addr); } -- 2.39.5