aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-01-28 17:25:07 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-01-28 17:25:07 +0000
commit6c5304b5da6e44cfce9b03f469fa3d3b528ed1ff (patch)
tree53389aa841cb3b5ad4c5ff869758e880423b0067 /src
parent918e002379b0ef95e10c6608c6e23d89d284a71b (diff)
downloadrspamd-6c5304b5da6e44cfce9b03f469fa3d3b528ed1ff.tar.gz
rspamd-6c5304b5da6e44cfce9b03f469fa3d3b528ed1ff.zip
Implement key parsing from an HTTP request.
Diffstat (limited to 'src')
-rw-r--r--src/libutil/http.c64
-rw-r--r--src/libutil/http.h3
2 files changed, 60 insertions, 7 deletions
diff --git a/src/libutil/http.c b/src/libutil/http.c
index 5a597fbd2..41053e9ed 100644
--- a/src/libutil/http.c
+++ b/src/libutil/http.c
@@ -28,15 +28,27 @@
#include "printf.h"
#include "logger.h"
#include "ref.h"
+#include "tweetnacl.h"
+#include "blake2.h"
#include <limits.h>
+struct rspamd_http_keypair {
+ guchar beforenm[crypto_box_BEFORENMBYTES];
+ guchar pk[crypto_box_PUBLICKEYBYTES];
+ guchar sk[crypto_box_SECRETKEYBYTES];
+ guchar id[BLAKE2B_OUTBYTES];
+};
+
struct rspamd_http_connection_private {
struct _rspamd_http_privbuf {
GString *data;
ref_entry_t ref;
} *buf;
gboolean new_header;
+ gboolean encrypted;
+ struct rspamd_http_keypair *local_key;
+ GString *peer_key;
struct rspamd_http_header *header;
struct http_parser parser;
struct http_parser_settings parser_cb;
@@ -71,9 +83,11 @@ static const struct _rspamd_http_magic {
[HTTP_MAGIC_JPG] = { "jpg", "image/jpeg" },
};
-static gchar *http_week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
-static gchar *http_month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+static const gchar *http_week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+static const gchar *http_month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+static const gchar *key_header = "Key";
+static const gchar *date_header = "Date";
#define HTTP_ERROR http_error_quark ()
@@ -387,13 +401,46 @@ rspamd_http_parse_date (const gchar *header, gsize len)
return (time_t) time;
}
+static void
+rspamd_http_parse_key (GString *data, struct rspamd_http_connection_private *priv)
+{
+ guchar *decoded;
+ gsize decoded_len;
+
+ if (priv->local_key == NULL) {
+ /* In this case we cannot do anything, e.g. we cannot decrypt payload */
+ priv->encrypted = TRUE;
+ }
+ else {
+ /* Check sanity of what we have */
+ decoded = rspamd_decode_base32 (data->str, data->len, &decoded_len);
+ if (decoded != NULL) {
+ if (decoded_len >= sizeof (priv->local_key->id) +
+ sizeof (priv->local_key->pk)) {
+ if (memcmp (priv->local_key->id, decoded,
+ sizeof (priv->local_key->id)) == 0) {
+ priv->peer_key = g_string_sized_new (sizeof (priv->local_key->pk));
+ g_string_append_len (priv->peer_key,
+ decoded + sizeof (priv->local_key->id),
+ sizeof (priv->local_key->pk));
+ }
+ }
+ }
+ priv->encrypted = TRUE;
+ g_free (decoded);
+ }
+}
+
static inline void
-rspamd_http_check_date (struct rspamd_http_connection_private *priv)
+rspamd_http_check_special_header (struct rspamd_http_connection_private *priv)
{
- if (g_ascii_strcasecmp (priv->header->name->str, "date") == 0) {
+ if (g_ascii_strcasecmp (priv->header->name->str, date_header) == 0) {
priv->msg->date = rspamd_http_parse_date (priv->header->value->str,
priv->header->value->len);
}
+ else if (g_ascii_strcasecmp (priv->header->name->str, key_header) == 0) {
+ rspamd_http_parse_key (priv->header->value, priv);
+ }
}
static gint
@@ -447,7 +494,7 @@ rspamd_http_on_header_field (http_parser * parser,
}
else if (priv->new_header) {
DL_APPEND (priv->msg->headers, priv->header);
- rspamd_http_check_date (priv);
+ rspamd_http_check_special_header (priv);
priv->header = g_slice_alloc (sizeof (struct rspamd_http_header));
priv->header->name = g_string_sized_new (32);
priv->header->value = g_string_sized_new (32);
@@ -492,7 +539,7 @@ rspamd_http_on_headers_complete (http_parser * parser)
if (priv->header != NULL) {
DL_APPEND (priv->msg->headers, priv->header);
- rspamd_http_check_date (priv);
+ rspamd_http_check_special_header (priv);
priv->header = NULL;
}
@@ -821,6 +868,11 @@ rspamd_http_connection_reset (struct rspamd_http_connection *conn)
REF_RELEASE (priv->buf);
}
+ if (priv->peer_key != NULL) {
+ g_string_free (priv->peer_key, TRUE);
+ }
+ priv->encrypted = FALSE;
+
rspamd_http_parser_reset (conn);
if (priv->out != NULL) {
diff --git a/src/libutil/http.h b/src/libutil/http.h
index c6fcf0b83..ca037c702 100644
--- a/src/libutil/http.h
+++ b/src/libutil/http.h
@@ -70,7 +70,8 @@ struct rspamd_http_message {
*/
enum rspamd_http_options {
RSPAMD_HTTP_BODY_PARTIAL = 0x1, /**< Call body handler on all body data portions */
- RSPAMD_HTTP_CLIENT_SIMPLE = 0x2 /**< Read HTTP client reply automatically */
+ RSPAMD_HTTP_CLIENT_SIMPLE = 0x2, /**< Read HTTP client reply automatically */
+ RSPAMD_HTTP_CLIENT_ENCRYPTED = 0x4 /**< Encrypt data for client */
};
struct rspamd_http_connection_private;