diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-01-29 23:34:23 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-01-29 23:34:23 +0000 |
commit | 6eac3649f809f91e3ee53e8d7ace2c4ead8b848c (patch) | |
tree | cca2610c513cc1d3b6f3a185d71fd125034c5979 /src | |
parent | 9bcf7906eeb645e18f6ac95b5544f0da2c169eb2 (diff) | |
download | rspamd-6eac3649f809f91e3ee53e8d7ace2c4ead8b848c.tar.gz rspamd-6eac3649f809f91e3ee53e8d7ace2c4ead8b848c.zip |
Fix issues with base32 encoding.
Diffstat (limited to 'src')
-rw-r--r-- | src/client/rspamdclient.c | 17 | ||||
-rw-r--r-- | src/libutil/http.c | 54 | ||||
-rw-r--r-- | src/libutil/util.c | 18 |
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; } |