]> source.dussan.org Git - rspamd.git/commitdiff
Fix issues with base32 encoding.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 29 Jan 2015 23:34:23 +0000 (23:34 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 29 Jan 2015 23:34:23 +0000 (23:34 +0000)
src/client/rspamdclient.c
src/libutil/http.c
src/libutil/util.c

index 1d119eb18154252523faca66cfda43ace9c3b413..3073b85bfd69383fca2765a181c0f6a33850f9c4 100644 (file)
@@ -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;
 }
index 1b2338509ce639fa8517c1b0e821f4b24d827975..2569a609653ad3ecec0c024d0f55ec6ae02cc6a4 100644 (file)
@@ -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;
index f62022f776a27481072cef9219dc906f38819422..6d5682f25f6ced9d26f6e8a290d97ead05d4bcd2 100644 (file)
@@ -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;
 }