aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-01-29 23:34:23 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-01-29 23:34:23 +0000
commit6eac3649f809f91e3ee53e8d7ace2c4ead8b848c (patch)
treecca2610c513cc1d3b6f3a185d71fd125034c5979 /src
parent9bcf7906eeb645e18f6ac95b5544f0da2c169eb2 (diff)
downloadrspamd-6eac3649f809f91e3ee53e8d7ace2c4ead8b848c.tar.gz
rspamd-6eac3649f809f91e3ee53e8d7ace2c4ead8b848c.zip
Fix issues with base32 encoding.
Diffstat (limited to 'src')
-rw-r--r--src/client/rspamdclient.c17
-rw-r--r--src/libutil/http.c54
-rw-r--r--src/libutil/util.c18
3 files changed, 53 insertions, 36 deletions
diff --git a/src/client/rspamdclient.c b/src/client/rspamdclient.c
index 1d119eb18..3073b85bf 100644
--- a/src/client/rspamdclient.c
+++ b/src/client/rspamdclient.c
@@ -154,19 +154,24 @@ rspamd_client_init (struct event_base *ev_base, const gchar *name,
0,
RSPAMD_HTTP_CLIENT);
+ conn->server_name = g_string_new (name);
+ if (port != 0) {
+ rspamd_printf_gstring (conn->server_name, ":%d", (int)port);
+ }
+
+ double_to_tv (timeout, &conn->timeout);
+
if (key) {
conn->key = rspamd_http_connection_make_peer_key (key);
if (conn->key) {
conn->keypair = rspamd_http_connection_gen_key ();
rspamd_http_connection_set_key (conn->http_conn, conn->key);
}
+ else {
+ rspamd_client_destroy (conn);
+ return NULL;
+ }
}
- conn->server_name = g_string_new (name);
- if (port != 0) {
- rspamd_printf_gstring (conn->server_name, ":%d", (int)port);
- }
-
- double_to_tv (timeout, &conn->timeout);
return conn;
}
diff --git a/src/libutil/http.c b/src/libutil/http.c
index 1b2338509..2569a6096 100644
--- a/src/libutil/http.c
+++ b/src/libutil/http.c
@@ -405,8 +405,9 @@ rspamd_http_parse_date (const gchar *header, gsize len)
static void
rspamd_http_parse_key (GString *data, struct rspamd_http_connection_private *priv)
{
- guchar *decoded;
- gsize decoded_len;
+ guchar *decoded_id, *decoded_key;
+ const gchar *eq_pos;
+ gsize id_len, key_len;
if (priv->local_key == NULL) {
/* In this case we cannot do anything, e.g. we cannot decrypt payload */
@@ -414,21 +415,27 @@ rspamd_http_parse_key (GString *data, struct rspamd_http_connection_private *pri
}
else {
/* Check sanity of what we have */
- decoded = rspamd_decode_base32 (data->str, data->len, &decoded_len);
- if (decoded != NULL) {
- if (decoded_len >= RSPAMD_HTTP_KEY_ID_LEN +
- sizeof (priv->local_key->pk)) {
- if (memcmp (priv->local_key->id, decoded,
- RSPAMD_HTTP_KEY_ID_LEN) == 0) {
- priv->msg->peer_key = g_string_sized_new (sizeof (priv->local_key->pk));
- g_string_append_len (priv->msg->peer_key,
- decoded + sizeof (priv->local_key->id),
- sizeof (priv->local_key->pk));
+ eq_pos = memchr (data->str, '=', data->len);
+ if (eq_pos != NULL) {
+ decoded_id = rspamd_decode_base32 (data->str, eq_pos - data->str,
+ &id_len);
+ decoded_key = rspamd_decode_base32 (eq_pos + 1, data->str + data->len -
+ eq_pos - 1, &key_len);
+ if (decoded_id != NULL && decoded_key != NULL) {
+ if (id_len >= RSPAMD_HTTP_KEY_ID_LEN &&
+ key_len >= sizeof (priv->local_key->pk)) {
+ if (memcmp (priv->local_key->id, decoded_id,
+ RSPAMD_HTTP_KEY_ID_LEN) == 0) {
+ priv->msg->peer_key = g_string_sized_new (sizeof (priv->local_key->pk));
+ g_string_append_len (priv->msg->peer_key,
+ decoded_key, sizeof (priv->local_key->pk));
+ }
}
}
+ priv->encrypted = TRUE;
+ g_free (decoded_key);
+ g_free (decoded_id);
}
- priv->encrypted = TRUE;
- g_free (decoded);
}
}
@@ -1100,7 +1107,7 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
sizeof (priv->local_key->pk));
b32_id = rspamd_encode_base32 (id, RSPAMD_HTTP_KEY_ID_LEN);
/* XXX: add some fuzz here */
- rspamd_printf_gstring (buf, "Key: %s%s\r\n", b32_id, b32_key);
+ rspamd_printf_gstring (buf, "Key: %s=%s\r\n", b32_id, b32_key);
g_free (b32_key);
g_free (b32_id);
}
@@ -1662,24 +1669,25 @@ rspamd_http_keypair_dtor (struct rspamd_http_keypair *kp)
gpointer
rspamd_http_connection_make_key (gchar *key, gsize keylen)
{
- guchar *decoded;
+ guchar *decoded_sk, *decoded_pk;
gsize decoded_len;
struct rspamd_http_keypair *kp;
- decoded = rspamd_decode_base32 (key, keylen, &decoded_len);
+ decoded_sk = rspamd_decode_base32 (key, keylen / 2, &decoded_len);
+ decoded_pk = rspamd_decode_base32 (key + keylen / 2, keylen / 2, &decoded_len);
- if (decoded != NULL) {
- if (decoded_len == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES) {
+ if (decoded_pk != NULL && decoded_sk != NULL) {
+ if (decoded_len == crypto_box_PUBLICKEYBYTES) {
kp = g_slice_alloc (sizeof (*kp));
REF_INIT_RETAIN (kp, rspamd_http_keypair_dtor);
- memcpy (kp->sk, decoded, crypto_box_SECRETKEYBYTES);
- memcpy (kp->pk, decoded + crypto_box_SECRETKEYBYTES,
- crypto_box_PUBLICKEYBYTES);
+ memcpy (kp->sk, decoded_sk, crypto_box_SECRETKEYBYTES);
+ memcpy (kp->pk, decoded_pk, crypto_box_PUBLICKEYBYTES);
blake2b (kp->id, kp->pk, NULL, sizeof (kp->id), sizeof (kp->pk), 0);
return (gpointer)kp;
}
- g_free (decoded);
+ g_free (decoded_pk);
+ g_free (decoded_sk);
}
return FALSE;
diff --git a/src/libutil/util.c b/src/libutil/util.c
index f62022f77..6d5682f25 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -2061,13 +2061,13 @@ rspamd_ucl_emit_gstring (ucl_object_t *obj,
gchar *
rspamd_encode_base32 (const guchar *in, gsize inlen)
{
- gint remain = -1, r, x;
- gsize i;
- gsize outlen = inlen * 8 / 5 + 1;
+ gint remain = -1, x;
+ gsize i, r;
+ gsize allocated_len = inlen * 8 / 5 + 2;
gchar *out;
static const char b32[]="ybndrfg8ejkmcpqxot1uwisza345h769";
- out = g_malloc (outlen);
+ out = g_malloc (allocated_len);
for (i = 0, r = 0; i < inlen; i++) {
switch (i % 5) {
case 0:
@@ -2109,10 +2109,12 @@ rspamd_encode_base32 (const guchar *in, gsize inlen)
}
}
- if (remain >= 0)
+ if (remain >= 0) {
out[r++] = b32[remain];
+ }
out[r] = 0;
+ g_assert (r < allocated_len);
return out;
}
@@ -2159,7 +2161,7 @@ rspamd_decode_base32 (const gchar *in, gsize inlen, gsize *outlen)
guchar c;
guint acc = 0U;
guint processed_bits = 0;
- gsize olen = 0, i, allocated_len = inlen * 8 / 5 + 1;
+ gsize olen = 0, i, allocated_len = inlen / 8 * 5 + 2;
res = g_malloc (allocated_len);
@@ -2186,7 +2188,9 @@ rspamd_decode_base32 (const gchar *in, gsize inlen, gsize *outlen)
res[olen++] = (acc & 0xFF);
}
- *outlen = olen > 0 ? olen - 1 : 0;
+ g_assert (olen <= allocated_len);
+
+ *outlen = olen;
return res;
}