aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-05-20 14:46:44 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-05-20 14:46:44 +0100
commit6f6cc0bf2f27ace6cd773d03148fb41742dab1fc (patch)
tree20c042e52a7fea34dc7542e516c74e316c7a760a
parent84d6c763cff06ad975b343bed281763273e5e0a6 (diff)
downloadrspamd-6f6cc0bf2f27ace6cd773d03148fb41742dab1fc.tar.gz
rspamd-6f6cc0bf2f27ace6cd773d03148fb41742dab1fc.zip
[Minor] Add public function to perform headers canonicalisation
-rw-r--r--src/libserver/dkim.c85
-rw-r--r--src/libserver/dkim.h13
2 files changed, 72 insertions, 26 deletions
diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c
index bb1113d00..a83b20dc3 100644
--- a/src/libserver/dkim.c
+++ b/src/libserver/dkim.c
@@ -1614,44 +1614,40 @@ rspamd_dkim_signature_update (struct rspamd_dkim_common_ctx *ctx,
}
}
-static gboolean
-rspamd_dkim_canonize_header_relaxed (struct rspamd_dkim_common_ctx *ctx,
- const gchar *header,
- const gchar *header_name,
- gboolean is_sign)
+goffset
+rspamd_dkim_canonize_header_relaxed_str (const gchar *hname,
+ const gchar *hvalue,
+ gchar *out,
+ gsize outlen)
{
- const gchar *h;
- gchar *t, *buf;
- guint inlen;
- gboolean got_sp, allocated = FALSE;
+ gchar *t;
+ const guchar *h;
+ gboolean got_sp;
- inlen = strlen (header) + strlen (header_name) + sizeof (":" CRLF);
- if (inlen > BUFSIZ) {
- buf = g_malloc (inlen);
- allocated = TRUE;
- }
- else {
- /* Faster */
- buf = g_alloca (inlen);
+ /* Name part */
+ t = out;
+ h = hname;
+
+ while (*h && t - out < outlen) {
+ *t++ = lc_map[*h++];
}
- /* Name part */
- t = buf;
- h = header_name;
- while (*h) {
- *t++ = g_ascii_tolower (*h++);
+ if (t - out >= outlen) {
+ return -1;
}
+
*t++ = ':';
/* Value part */
- h = header;
+ h = hvalue;
/* Skip spaces at the beginning */
while (g_ascii_isspace (*h)) {
h++;
}
+
got_sp = FALSE;
- while (*h) {
+ while (*h && (t - out < outlen)) {
if (g_ascii_isspace (*h)) {
if (got_sp) {
h++;
@@ -1667,21 +1663,58 @@ rspamd_dkim_canonize_header_relaxed (struct rspamd_dkim_common_ctx *ctx,
else {
got_sp = FALSE;
}
+
*t++ = *h++;
}
+
if (g_ascii_isspace (*(t - 1))) {
t--;
}
+
+ if (t - out >= outlen - 2) {
+ return -1;
+ }
+
*t++ = '\r';
*t++ = '\n';
*t = '\0';
+ return t - out;
+}
+
+static gboolean
+rspamd_dkim_canonize_header_relaxed (struct rspamd_dkim_common_ctx *ctx,
+ const gchar *header,
+ const gchar *header_name,
+ gboolean is_sign)
+{
+ static gchar st_buf[8192];
+ gchar *buf;
+ guint inlen;
+ goffset r;
+ gboolean allocated = FALSE;
+
+ inlen = strlen (header) + strlen (header_name) + sizeof (":" CRLF);
+
+ if (inlen > sizeof (st_buf)) {
+ buf = g_malloc (inlen);
+ allocated = TRUE;
+ }
+ else {
+ /* Faster */
+ buf = st_buf;
+ }
+
+ r = rspamd_dkim_canonize_header_relaxed_str (header_name, header, buf, inlen);
+
+ g_assert (r != -1);
+
if (!is_sign) {
msg_debug_dkim ("update signature with header: %s", buf);
- EVP_DigestUpdate (ctx->headers_hash, buf, t - buf);
+ EVP_DigestUpdate (ctx->headers_hash, buf, r);
}
else {
- rspamd_dkim_signature_update (ctx, buf, t - buf);
+ rspamd_dkim_signature_update (ctx, buf, r);
}
if (allocated) {
diff --git a/src/libserver/dkim.h b/src/libserver/dkim.h
index 7e025a4c0..bd7ddfeb1 100644
--- a/src/libserver/dkim.h
+++ b/src/libserver/dkim.h
@@ -196,6 +196,19 @@ const gchar* rspamd_dkim_get_dns_key (rspamd_dkim_context_t *ctx);
guint rspamd_dkim_key_get_ttl (rspamd_dkim_key_t *k);
/**
+ * Canonocalise header using relaxed algorithm
+ * @param hname
+ * @param hvalue
+ * @param out
+ * @param outlen
+ * @return
+ */
+goffset rspamd_dkim_canonize_header_relaxed_str (const gchar *hname,
+ const gchar *hvalue,
+ gchar *out,
+ gsize outlen);
+
+/**
* Free DKIM key
* @param key
*/