From 7190809e19680ec753e3bde866f0c3f81fafae21 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 30 Jan 2015 00:56:18 +0000 Subject: [PATCH] Fix peer keys handling. --- src/client/rspamdclient.c | 8 +++--- src/libserver/protocol.c | 2 +- src/libserver/task.c | 2 +- src/libserver/task.h | 2 +- src/libutil/http.c | 55 ++++++++++++++++----------------------- src/libutil/http.h | 4 +-- src/worker.c | 2 +- 7 files changed, 32 insertions(+), 43 deletions(-) diff --git a/src/client/rspamdclient.c b/src/client/rspamdclient.c index 3073b85bf..1df619437 100644 --- a/src/client/rspamdclient.c +++ b/src/client/rspamdclient.c @@ -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); diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index bc64b7c31..9632418c4 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -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) { diff --git a/src/libserver/task.c b/src/libserver/task.c index 18ba08dad..3136001d6 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -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); diff --git a/src/libserver/task.h b/src/libserver/task.h index 9c05def82..9702befa5 100644 --- a/src/libserver/task.h +++ b/src/libserver/task.h @@ -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 */ }; /** diff --git a/src/libutil/http.c b/src/libutil/http.c index 2569a6096..862b5df90 100644 --- a/src/libutil/http.c +++ b/src/libutil/http.c @@ -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; } diff --git a/src/libutil/http.h b/src/libutil/http.h index 83a284a52..c290d803c 100644 --- a/src/libutil/http.h +++ b/src/libutil/http.h @@ -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 diff --git a/src/worker.c b/src/worker.c index 91797a6dc..079fa8fae 100644 --- a/src/worker.c +++ b/src/worker.c @@ -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)) { -- 2.39.5