]> source.dussan.org Git - rspamd.git/commitdiff
Fix peer keys handling.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 30 Jan 2015 00:56:18 +0000 (00:56 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 30 Jan 2015 00:56:18 +0000 (00:56 +0000)
src/client/rspamdclient.c
src/libserver/protocol.c
src/libserver/task.c
src/libserver/task.h
src/libutil/http.c
src/libutil/http.h
src/worker.c

index 3073b85bfd69383fca2765a181c0f6a33850f9c4..1df619437c6dc7b2000afd90621404d06a10b135 100644 (file)
@@ -39,7 +39,7 @@ struct rspamd_client_request;
 struct rspamd_client_connection {
        gint fd;
        GString *server_name;
-       GString *key;
+       gpointer key;
        gpointer keypair;
        struct event_base *ev_base;
        struct timeval timeout;
@@ -165,7 +165,7 @@ rspamd_client_init (struct event_base *ev_base, const gchar *name,
                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);
+                       rspamd_http_connection_set_key (conn->http_conn, conn->keypair);
                }
                else {
                        rspamd_client_destroy (conn);
@@ -194,7 +194,7 @@ rspamd_client_command (struct rspamd_client_connection *conn,
 
        req->msg = rspamd_http_new_message (HTTP_REQUEST);
        if (conn->key) {
-               req->msg->peer_key = g_string_new (conn->key->str);
+               req->msg->peer_key = rspamd_http_connection_key_ref (conn->key);
        }
 
        if (in != NULL) {
@@ -253,7 +253,7 @@ rspamd_client_destroy (struct rspamd_client_connection *conn)
                }
                close (conn->fd);
                if (conn->key) {
-                       g_string_free (conn->key, TRUE);
+                       rspamd_http_connection_key_unref (conn->key);
                }
                if (conn->keypair) {
                        rspamd_http_connection_key_unref (conn->keypair);
index bc64b7c31554fa87506ea34a009819a89e877676..9632418c41d85fdb2bbb62574a765a1089a7b3aa 100644 (file)
@@ -907,7 +907,7 @@ rspamd_protocol_write_reply (struct rspamd_task *task)
        msg = rspamd_http_new_message (HTTP_RESPONSE);
 
        if (task->peer_key) {
-               msg->peer_key = g_string_new (task->peer_key->str);
+               msg->peer_key = rspamd_http_connection_key_ref (task->peer_key);
                msg_info ("<%s> writing encrypted reply", task->message_id);
        }
        if (!task->is_json) {
index 18ba08dadd12a6451af3cd4ba3fa7b4d28d8a23b..3136001d66ebede1d6c519db64d3fe9923f039bd 100644 (file)
@@ -267,7 +267,7 @@ rspamd_task_free (struct rspamd_task *task, gboolean is_soft)
                        ucl_object_unref (task->settings);
                }
                if (task->peer_key != NULL) {
-                       g_string_free (task->peer_key, TRUE);
+                       rspamd_http_connection_key_unref (task->peer_key);
                }
                rspamd_mempool_delete (task->task_pool);
                g_slice_free1 (sizeof (struct rspamd_task), task);
index 9c05def82c4f1a112effe14c8b38f04a83fca686..9702befa54de9db7a9059c96b39129560ea54ac5 100644 (file)
@@ -147,7 +147,7 @@ struct rspamd_task {
        } pre_result;                                               /**< Result of pre-filters                                                  */
 
        ucl_object_t *settings;                                     /**< Settings applied to task                                               */
-       GString *peer_key;                                                                                      /**< Peer's pubkey                                                                      */
+       gpointer peer_key;                                                                                      /**< Peer's pubkey                                                                      */
 };
 
 /**
index 2569a609653ad3ecec0c024d0f55ec6ae02cc6a4..862b5df90f5f1e09d5b035016e58858e64f684bc 100644 (file)
@@ -593,6 +593,7 @@ rspamd_http_on_message_complete (http_parser * parser)
        guchar *nonce, *m;
        gsize dec_len;
        GError *err;
+       struct rspamd_http_keypair *peer_key = NULL;
 
        priv = conn->priv;
 
@@ -601,11 +602,7 @@ rspamd_http_on_message_complete (http_parser * parser)
                if (priv->encrypted) {
                        if (priv->local_key == NULL || priv->msg->peer_key == NULL ||
                                        priv->msg->body->len < crypto_box_NONCEBYTES + crypto_box_ZEROBYTES) {
-                               err = g_error_new (HTTP_ERROR, 500, "Cannot decrypt message");
-                               rspamd_http_connection_ref (conn);
-                               conn->error_handler (conn, err);
-                               rspamd_http_connection_unref (conn);
-                               g_error_free (err);
+                               msg_err ("cannot decrypt message");
                                return -1;
                        }
                        /* We have keys, so we can decrypt message */
@@ -613,14 +610,11 @@ rspamd_http_on_message_complete (http_parser * parser)
                        nonce = priv->msg->body->str;
                        m = priv->msg->body->str + crypto_box_NONCEBYTES;
                        dec_len = priv->msg->body->len - crypto_box_NONCEBYTES;
+                       peer_key = (struct rspamd_http_keypair *)priv->msg->peer_key;
 
                        if (crypto_box_open (m + crypto_box_ZEROBYTES, m, dec_len, nonce,
-                                       priv->msg->peer_key->str, priv->local_key->sk) != 0) {
-                               err = g_error_new (HTTP_ERROR, 500, "Cannot verify encrypted message");
-                               rspamd_http_connection_ref (conn);
-                               conn->error_handler (conn, err);
-                               rspamd_http_connection_unref (conn);
-                               g_error_free (err);
+                                       peer_key->pk, priv->local_key->sk) != 0) {
+                               msg_err ("cannot verify encrypted message");
                                return -1;
                        }
                        m += crypto_box_ZEROBYTES;
@@ -995,6 +989,7 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
        gchar *b32_key, *b32_id;
        guchar nonce[crypto_box_NONCEBYTES], mac[crypto_box_ZEROBYTES], id[BLAKE2B_OUTBYTES];
        guchar *np, *mp;
+       struct rspamd_http_keypair *peer_key = NULL;
 
        conn->fd = fd;
        conn->ud = ud;
@@ -1101,8 +1096,8 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
                                bodylen);
                }
                if (encrypted) {
-                       blake2b (id, priv->local_key->pk, NULL, sizeof (id),
-                                       sizeof (priv->local_key->pk), 0);
+                       peer_key = (struct rspamd_http_keypair *)msg->peer_key;
+                       memcpy (id, peer_key->id, sizeof (id));
                        b32_key = rspamd_encode_base32 (priv->local_key->pk,
                                        sizeof (priv->local_key->pk));
                        b32_id = rspamd_encode_base32 (id, RSPAMD_HTTP_KEY_ID_LEN);
@@ -1159,10 +1154,10 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
                priv->wr_total -= 2;
        }
        if (msg->body != NULL) {
-               if (encrypted) {
+               if (encrypted && peer_key != NULL) {
                        crypto_box_detached (pbody, pbody,
                                        bodylen - sizeof (nonce) - sizeof (mac), np,
-                                       msg->peer_key->str, priv->local_key->sk, mp);
+                                       peer_key->pk, priv->local_key->sk, mp);
                        priv->out[i].iov_base = np;
                        priv->out[i++].iov_len = sizeof (nonce);
                        priv->out[i].iov_base = mp;
@@ -1278,7 +1273,7 @@ rspamd_http_message_free (struct rspamd_http_message *msg)
                g_string_free (msg->status, TRUE);
        }
        if (msg->peer_key != NULL) {
-               g_string_free (msg->peer_key, TRUE);
+               rspamd_http_connection_key_unref (msg->peer_key);
        }
        g_slice_free1 (sizeof (struct rspamd_http_message), msg);
 }
@@ -1690,7 +1685,7 @@ rspamd_http_connection_make_key (gchar *key, gsize keylen)
                g_free (decoded_sk);
        }
 
-       return FALSE;
+       return NULL;
 }
 
 gpointer
@@ -1789,29 +1784,23 @@ rspamd_http_connection_key_ref (gpointer key)
        return kp;
 }
 
-GString *
+gpointer
 rspamd_http_connection_make_peer_key (const gchar *key)
 {
-       guchar hashbuf[RSPAMD_HTTP_KEY_ID_LEN];
-       gchar *b32_id;
        guchar *pk_decoded;
-       GString *res = NULL;
        gsize dec_len;
+       struct rspamd_http_keypair *kp = NULL;
 
        pk_decoded = rspamd_decode_base32 (key, strlen (key), &dec_len);
 
-       if (pk_decoded != NULL) {
-               if (dec_len == crypto_box_PUBLICKEYBYTES) {
-                       res = g_string_new (NULL);
-                       blake2b (hashbuf, pk_decoded, NULL, sizeof (hashbuf), dec_len, 0);
-                       b32_id = rspamd_encode_base32 (hashbuf, sizeof (hashbuf));
-
-                       g_string_printf (res, "%s%s", b32_id, key);
-                       g_free (b32_id);
-               }
-
-               g_free (pk_decoded);
+       if (pk_decoded != NULL && dec_len == crypto_box_PUBLICKEYBYTES) {
+               kp = g_slice_alloc (sizeof (*kp));
+               REF_INIT_RETAIN (kp, rspamd_http_keypair_dtor);
+               memcpy (kp->pk, pk_decoded, sizeof (kp->pk));
+               blake2b (kp->id, kp->pk, NULL, sizeof (kp->id), sizeof (kp->pk), 0);
        }
 
-       return res;
+       g_free (pk_decoded);
+
+       return kp;
 }
index 83a284a525e8d0596076528b1ae6f8e2dfc47ad2..c290d803ccf75da6a85150ab2ecf8faacfc53539 100644 (file)
@@ -58,7 +58,7 @@ struct rspamd_http_message {
        GString *status;
        struct rspamd_http_header *headers;
        GString *body;
-       GString *peer_key;
+       gpointer peer_key;
        enum http_parser_type type;
        time_t date;
        gint code;
@@ -201,7 +201,7 @@ void rspamd_http_connection_key_unref (gpointer key);
  */
 gpointer rspamd_http_connection_key_ref (gpointer key);
 
-GString *rspamd_http_connection_make_peer_key (const gchar *key);
+gpointer rspamd_http_connection_make_peer_key (const gchar *key);
 
 /**
  * Handle a request using socket fd and user data ud
index 91797a6dce6feeb2a3cd61a7d7a212ec4e2f9346..079fa8fae5ceebc39e16b3f5ea6fa2d4b3b58133 100644 (file)
@@ -130,7 +130,7 @@ rspamd_worker_body_handler (struct rspamd_http_connection *conn,
        }
 
        if (msg->peer_key) {
-               task->peer_key = g_string_new (msg->peer_key->str);
+               task->peer_key = rspamd_http_connection_key_ref (msg->peer_key);
        }
 
        if (!rspamd_task_process (task, msg, ctx->classify_pool, TRUE)) {