commit ea07b60: [Minor] Move DKIM keys load to DKIM common code
Vsevolod Stakhov
vsevolod at highsecure.ru
Mon Feb 11 17:28:07 UTC 2019
Author: Vsevolod Stakhov
Date: 2019-02-11 14:21:29 +0000
URL: https://github.com/rspamd/rspamd/commit/ea07b601a62c68334e27a93c7b35e47e7fd16001
[Minor] Move DKIM keys load to DKIM common code
---
src/libserver/dkim.c | 96 +++++++++++++++++++++++++++++++++++++++-------
src/plugins/dkim_check.c | 99 +++++++-----------------------------------------
2 files changed, 96 insertions(+), 99 deletions(-)
diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c
index bbaa6b90f..2a66146ed 100644
--- a/src/libserver/dkim.c
+++ b/src/libserver/dkim.c
@@ -2604,29 +2604,83 @@ rspamd_dkim_get_dns_key (rspamd_dkim_context_t *ctx)
return NULL;
}
+#define PEM_SIG "-----BEGIN"
+
rspamd_dkim_sign_key_t*
rspamd_dkim_sign_key_load (const gchar *key, gsize len,
enum rspamd_dkim_key_format type,
GError **err)
{
+ guchar *map = NULL, *tmp = NULL;
+ gsize maplen;
rspamd_dkim_sign_key_t *nkey;
time_t mtime = time (NULL);
- switch (type) {
- case RSPAMD_DKIM_KEY_PEM:
- /* fallthrough */
- case RSPAMD_DKIM_KEY_RAW:
- break;
- default:
- g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
- "invalid key type to load: %d", type);
- return NULL;
+ if (type < 0 || type > RSPAMD_DKIM_KEY_UNKNOWN || len == 0 || key == NULL) {
+ g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
+ "invalid key type to load: %d", type);
+ return NULL;
}
nkey = g_malloc0 (sizeof (*nkey));
nkey->mtime = mtime;
- msg_debug_dkim_taskless ("got public key with length %d and type %d", len, type);
+ msg_debug_dkim_taskless ("got public key with length %d and type %d",
+ len, type);
+
+ /* Load key file if needed */
+ if (type == RSPAMD_DKIM_KEY_FILE) {
+ struct stat st;
+
+ if (stat (key, &st) != 0) {
+ g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
+ "cannot stat key file: '%s' %s", key, strerror (errno));
+
+ return NULL;
+ }
+
+ nkey->mtime = st.st_mtime;
+ map = rspamd_file_xmap (key, PROT_READ, &maplen, TRUE);
+
+ if (map == NULL) {
+ g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
+ "cannot map key file: '%s' %s", key, strerror (errno));
+
+ return NULL;
+ }
+
+ key = map;
+ len = maplen;
+
+ if (maplen > sizeof (PEM_SIG) &&
+ strncmp (map, PEM_SIG, sizeof (PEM_SIG) - 1) == 0) {
+ type = RSPAMD_DKIM_KEY_PEM;
+ }
+ else if (rspamd_cryptobox_base64_is_valid (map, maplen)) {
+ type = RSPAMD_DKIM_KEY_BASE64;
+ }
+ else {
+ type = RSPAMD_DKIM_KEY_RAW;
+ }
+ }
+
+ if (type == RSPAMD_DKIM_KEY_UNKNOWN) {
+ if (len > sizeof (PEM_SIG) &&
+ memcmp (key, PEM_SIG, sizeof (PEM_SIG) - 1) == 0) {
+ type = RSPAMD_DKIM_KEY_PEM;
+ }
+ else {
+ type = RSPAMD_DKIM_KEY_RAW;
+ }
+ }
+
+ if (type == RSPAMD_DKIM_KEY_BASE64) {
+ type = RSPAMD_DKIM_KEY_RAW;
+ tmp = g_malloc (len);
+ rspamd_cryptobox_base64_decode (key, len, tmp, &len);
+ key = tmp;
+ }
+
if (type == RSPAMD_DKIM_KEY_RAW && len == 32) {
unsigned char pk[32];
nkey->type = RSPAMD_DKIM_KEY_EDDSA;
@@ -2645,8 +2699,9 @@ rspamd_dkim_sign_key_load (const gchar *key, gsize len,
ERR_error_string (ERR_get_error (), NULL));
rspamd_dkim_sign_key_free (nkey);
+ nkey = NULL;
- return NULL;
+ goto end;
}
}
else {
@@ -2655,8 +2710,9 @@ rspamd_dkim_sign_key_load (const gchar *key, gsize len,
"cannot parse pem private key: %s",
ERR_error_string (ERR_get_error (), NULL));
rspamd_dkim_sign_key_free (nkey);
+ nkey = NULL;
- return NULL;
+ goto end;
}
}
@@ -2667,17 +2723,31 @@ rspamd_dkim_sign_key_load (const gchar *key, gsize len,
DKIM_SIGERROR_KEYFAIL,
"cannot extract rsa key from evp key");
rspamd_dkim_sign_key_free (nkey);
+ nkey = NULL;
- return NULL;
+ goto end;
}
nkey->type = RSPAMD_DKIM_KEY_RSA;
}
REF_INIT_RETAIN (nkey, rspamd_dkim_sign_key_free);
+end:
+
+ if (map != NULL) {
+ munmap (map, maplen);
+ }
+
+ if (tmp != NULL) {
+ rspamd_explicit_memzero (tmp, len);
+ g_free (tmp);
+ }
+
return nkey;
}
+#undef PEM_SIG
+
gboolean
rspamd_dkim_sign_key_maybe_invalidate (rspamd_dkim_sign_key_t *key, time_t mtime)
{
diff --git a/src/plugins/dkim_check.c b/src/plugins/dkim_check.c
index 278a8e1e1..bb66e5ccc 100644
--- a/src/plugins/dkim_check.c
+++ b/src/plugins/dkim_check.c
@@ -641,58 +641,23 @@ dkim_module_config (struct rspamd_config *cfg)
return res;
}
-/**
- * helper to see if valid base64, minus newline
- */
-static gboolean
-is_valid_base64(const uint8_t *in, size_t len) {
- int i;
- if (in[len - 1] == '\n')
- len--;
- if (in[len - 1] == '\r')
- len--;
- if (len % 4 != 0)
- return FALSE;
-
- if (in[len - 1] == '=')
- len--;
- if (in[len - 1] == '=')
- len--;
-
- for (i = 0; i < len; i++) {
- if ('a' <= in[i] && in[i] <= 'z')
- continue;
- if ('A' <= in[i] && in[i] <= 'Z')
- continue;
- if ('0' <= in[i] && in[i] <= '9')
- continue;
- if (in[i] == '/')
- continue;
- if (in[i] == '+')
- continue;
- return FALSE;
- }
- return TRUE;
-}
-
-#define PEM_SIG "-----BEGIN"
/**
* Grab a private key from the cache
* or from the key content provided
*/
rspamd_dkim_sign_key_t *
-dkim_module_load_key_format (struct rspamd_task *task, struct dkim_ctx *dkim_module_ctx,
- const gchar *key, gsize keylen, enum rspamd_dkim_key_format key_format)
+dkim_module_load_key_format (struct rspamd_task *task,
+ struct dkim_ctx *dkim_module_ctx,
+ const gchar *key, gsize keylen,
+ enum rspamd_dkim_key_format key_format)
{
guchar h[rspamd_cryptobox_HASHBYTES],
hex_hash[rspamd_cryptobox_HASHBYTES * 2 + 1];
rspamd_dkim_sign_key_t *ret;
GError *err = NULL;
- gpointer map = NULL, tmp = NULL;
struct stat st;
- ssize_t maplen;
memset (hex_hash, 0, sizeof (hex_hash));
rspamd_cryptobox_hash (h, key, keylen, NULL, 0);
@@ -706,16 +671,19 @@ dkim_module_load_key_format (struct rspamd_task *task, struct dkim_ctx *dkim_mod
*/
if (key_format == RSPAMD_DKIM_KEY_UNKNOWN &&
(key[0] == '.' || key[0] == '/')) {
- if (!is_valid_base64 (key, keylen))
+ if (!rspamd_cryptobox_base64_is_valid (key, keylen)) {
key_format = RSPAMD_DKIM_KEY_FILE;
+ }
}
if (ret != NULL && key_format == RSPAMD_DKIM_KEY_FILE) {
msg_debug_task("checking for stale file key");
+
if (stat (key, &st) != 0) {
msg_err_task("cannot stat key file: %s", strerror (errno));
return NULL;
}
+
if (rspamd_dkim_sign_key_maybe_invalidate (ret, st.st_mtime)) {
msg_debug_task("removing stale file key");
/*
@@ -729,43 +697,8 @@ dkim_module_load_key_format (struct rspamd_task *task, struct dkim_ctx *dkim_mod
}
/* found key; done */
- if (ret != NULL)
+ if (ret != NULL) {
return ret;
-
- if (key_format == RSPAMD_DKIM_KEY_FILE) {
- if (stat (key, &st) != 0) {
- msg_err_task("cannot stat key file: %s", strerror (errno));
- return NULL;
- }
- map = rspamd_file_xmap (key, PROT_READ, &maplen, TRUE);
- if (map == NULL) {
- msg_err_task("cannot open key file \'%s\'", key);
- return NULL;
- }
- key = map;
- keylen = maplen;
- if (maplen > sizeof (PEM_SIG) &&
- strncmp (map, PEM_SIG, sizeof (PEM_SIG) - 1) == 0) {
- key_format = RSPAMD_DKIM_KEY_PEM;
- } else if (is_valid_base64 ((uint8_t *)map, maplen)) {
- key_format = RSPAMD_DKIM_KEY_BASE64;
- } else {
- key_format = RSPAMD_DKIM_KEY_RAW;
- }
- }
- if (key_format == RSPAMD_DKIM_KEY_UNKNOWN) {
- if (keylen > sizeof (PEM_SIG) &&
- strncmp (key, PEM_SIG, sizeof (PEM_SIG) - 1) == 0) {
- key_format = RSPAMD_DKIM_KEY_PEM;
- } else {
- key_format = RSPAMD_DKIM_KEY_RAW;
- }
- }
- if (key_format == RSPAMD_DKIM_KEY_BASE64) {
- key_format = RSPAMD_DKIM_KEY_RAW;
- tmp = g_malloc (keylen);
- rspamd_cryptobox_base64_decode (key, keylen, tmp, &keylen);
- key = tmp;
}
ret = rspamd_dkim_sign_key_load (key, keylen, key_format, &err);
@@ -779,16 +712,8 @@ dkim_module_load_key_format (struct rspamd_task *task, struct dkim_ctx *dkim_mod
g_strdup (hex_hash), ret, time (NULL), 0);
}
- if (map != NULL)
- munmap (map, maplen);
- if (tmp != NULL) {
- rspamd_explicit_memzero (tmp, keylen);
- g_free (tmp);
- }
-
return ret;
}
-#undef PEM_SIG
static gint
lua_dkim_sign_handler (lua_State *L)
@@ -844,10 +769,12 @@ lua_dkim_sign_handler (lua_State *L)
if (key) {
dkim_key = dkim_module_load_key_format (task, dkim_module_ctx, key,
keylen, RSPAMD_DKIM_KEY_UNKNOWN);
- } else if(rawkey) {
+ }
+ else if(rawkey) {
dkim_key = dkim_module_load_key_format (task, dkim_module_ctx, rawkey,
rawlen, RSPAMD_DKIM_KEY_UNKNOWN);
- } else {
+ }
+ else {
msg_err_task ("neither key nor rawkey are specified");
lua_pushboolean (L, FALSE);
More information about the Commits
mailing list