commit 315b61b: [Rework] Rework SSL flag operations

Vsevolod Stakhov vsevolod at highsecure.ru
Wed Dec 8 11:49:05 UTC 2021


Author: Vsevolod Stakhov
Date: 2021-12-08 11:31:35 +0000
URL: https://github.com/rspamd/rspamd/commit/315b61b3190f4b10f0710638bfaad27373fb3671

[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);
 	}
 


More information about the Commits mailing list