Browse Source

[Fix] Fix host header usage in lua_http

The issue is that `rspamd_http_message_get_http_host` actually returns
non zero-terminated string in the case where `Host` header is found in a
message. Hence, we *cannot* treat it as a zero terminated string.

The proper approach is to use `rspamd_ftok_t` everywhere for strings
but the change will be too intrusive, since it also involves many libraries,
e.g. `rdns` and others.

The current approach is much simplier: just copy a string into a temporary
buffer ensuring that it is zero terminated in all the cases.

Issue: #4051
tags/3.2
Vsevolod Stakhov 2 years ago
parent
commit
00927e0ef0
No account linked to committer's email address
3 changed files with 25 additions and 7 deletions
  1. 5
    1
      src/libserver/http/http_message.c
  2. 3
    1
      src/libserver/http/http_message.h
  3. 17
    5
      src/lua/lua_http.c

+ 5
- 1
src/libserver/http/http_message.c View File

@@ -693,7 +693,8 @@ rspamd_http_message_remove_header (struct rspamd_http_message *msg,
}

const gchar*
rspamd_http_message_get_http_host (struct rspamd_http_message *msg)
rspamd_http_message_get_http_host (struct rspamd_http_message *msg,
gsize *hostlen)
{
if (msg->flags & RSPAMD_HTTP_FLAG_HAS_HOST_HEADER) {
rspamd_ftok_t srch;
@@ -703,14 +704,17 @@ rspamd_http_message_get_http_host (struct rspamd_http_message *msg)
khiter_t k = kh_get (rspamd_http_headers_hash, msg->headers, &srch);

if (k != kh_end (msg->headers)) {
*hostlen = (kh_value (msg->headers, k)->value).len;
return (kh_value (msg->headers, k)->value).begin;
}
else if (msg->host) {
*hostlen = msg->host->len;
return msg->host->str;
}
}
else {
if (msg->host) {
*hostlen = msg->host->len;
return msg->host->str;
}
}

+ 3
- 1
src/libserver/http/http_message.h View File

@@ -233,9 +233,11 @@ guint rspamd_http_message_get_flags (struct rspamd_http_message *msg);
* Returns an HTTP hostname for a message, derived from a header if it has it
* or from a url if it doesn't
* @param msg
* @param hostlen output of the host length
* @return
*/
const gchar* rspamd_http_message_get_http_host (struct rspamd_http_message *msg);
const gchar* rspamd_http_message_get_http_host (struct rspamd_http_message *msg,
gsize *hostlen);

#ifdef __cplusplus
}

+ 17
- 5
src/lua/lua_http.c View File

@@ -75,7 +75,7 @@ struct lua_http_cbdata {
struct rspamd_cryptobox_pubkey *peer_pk;
rspamd_inet_addr_t *addr;
gchar *mime_type;
const gchar *host;
gchar *host;
gchar *auth;
const gchar *url;
gsize max_size;
@@ -134,6 +134,10 @@ lua_http_fin (gpointer arg)
g_free (cbd->auth);
}

if (cbd->host) {
g_free (cbd->host);
}

if (cbd->local_kp) {
rspamd_keypair_unref (cbd->local_kp);
}
@@ -1060,13 +1064,18 @@ lua_http_request (lua_State *L)
bool numeric_ip = false;

/* Check if we can skip resolving */
cbd->host = rspamd_http_message_get_http_host (msg);
gsize hostlen = 0;
const gchar *host = rspamd_http_message_get_http_host (msg, &hostlen);

if (host) {
cbd->host = malloc (hostlen + 1);
rspamd_strlcpy (cbd->host, host, hostlen + 1);

if (cbd->host) {
if (cbd->flags & RSPAMD_LUA_HTTP_FLAG_KEEP_ALIVE) {
const rspamd_inet_addr_t *ka_addr = rspamd_http_context_has_keepalive(NULL,
rspamd_http_message_get_http_host (msg),
msg->port, msg->flags & RSPAMD_HTTP_FLAG_WANT_SSL);
cbd->host,
msg->port,
msg->flags & RSPAMD_HTTP_FLAG_WANT_SSL);

if (ka_addr) {
cbd->addr = rspamd_inet_address_copy(ka_addr);
@@ -1083,6 +1092,9 @@ lua_http_request (lua_State *L)
}
}
}
else {
cbd->host = NULL;
}

if (numeric_ip) {
/* Host is numeric IP, no need to resolve */

Loading…
Cancel
Save