commit 875f80e: Refactor dkim private key loads
John McKay
adenosine3p at gmail.com
Mon Feb 4 14:35:10 UTC 2019
Author: John McKay
Date: 2019-01-24 01:26:21 +0000
URL: https://github.com/rspamd/rspamd/commit/875f80ee9aa1ff58463f32864ec5fcd57558b0a5
Refactor dkim private key loads
---
src/libserver/dkim.c | 174 +++-------------
src/libserver/dkim.h | 22 +-
src/plugins/dkim_check.c | 528 +++++++++++++++++++++++------------------------
3 files changed, 302 insertions(+), 422 deletions(-)
diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c
index d4c54b422..5144c0517 100644
--- a/src/libserver/dkim.c
+++ b/src/libserver/dkim.c
@@ -144,7 +144,7 @@ struct rspamd_dkim_context_s {
struct rspamd_dkim_key_s {
guint8 *keydata;
- guint keylen;
+ gsize keylen;
gsize decoded_len;
guint ttl;
union {
@@ -155,6 +155,7 @@ struct rspamd_dkim_key_s {
enum rspamd_dkim_key_type type;
BIO *key_bio;
EVP_PKEY *key_evp;
+ time_t mtime;
ref_entry_t ref;
};
@@ -163,22 +164,6 @@ struct rspamd_dkim_sign_context_s {
rspamd_dkim_sign_key_t *key;
};
-struct rspamd_dkim_sign_key_s {
- enum rspamd_dkim_key_type type;
- guint8 *keydata;
- gpointer map;
- gsize keylen;
- union {
- RSA *key_rsa;
- guchar *key_eddsa;
- } key;
- BIO *key_bio;
- EVP_PKEY *key_evp;
- time_t mtime;
- ref_entry_t ref;
-};
-
-
struct rspamd_dkim_header {
const gchar *name;
guint count;
@@ -1364,15 +1349,9 @@ rspamd_dkim_sign_key_free (rspamd_dkim_sign_key_t *key)
BIO_free (key->key_bio);
}
- if (key->keydata && key->keylen > 0) {
-
- if (key->map) {
- munmap (key->map, key->keylen);
- }
- else {
- rspamd_explicit_memzero (key->keydata, key->keylen);
- g_free (key->keydata);
- }
+ if (key->type == RSPAMD_DKIM_KEY_EDDSA) {
+ rspamd_explicit_memzero (key->key.key_eddsa, key->keylen);
+ g_free (key->keydata);
}
g_free (key);
@@ -2626,107 +2605,44 @@ rspamd_dkim_get_dns_key (rspamd_dkim_context_t *ctx)
}
rspamd_dkim_sign_key_t*
-rspamd_dkim_sign_key_load (const gchar *what, gsize len,
- enum rspamd_dkim_sign_key_type type,
+rspamd_dkim_sign_key_load (const gchar *key, gsize len,
+ enum rspamd_dkim_key_format type,
GError **err)
{
- gpointer map;
- gsize map_len = 0;
rspamd_dkim_sign_key_t *nkey;
- struct stat st;
- time_t mtime = 0;
-
- if (type == RSPAMD_DKIM_SIGN_KEY_FILE) {
- gchar fpath[PATH_MAX];
+ time_t mtime = time (NULL);
- rspamd_snprintf (fpath, sizeof (fpath), "%*s", (gint)len, what);
-
- if (stat (fpath, &st) == -1) {
- g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
- "cannot stat private key %s: %s",
- fpath, strerror (errno));
-
- return NULL;
- }
-
- mtime = st.st_mtime;
- map = rspamd_file_xmap (fpath, PROT_READ, &map_len, TRUE);
-
- if (map == 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,
- "cannot map private key %s: %s",
- fpath, strerror (errno));
-
+ "invalid key type to load: %d", type);
return NULL;
- }
}
nkey = g_malloc0 (sizeof (*nkey));
- nkey->type = type;
nkey->mtime = mtime;
- switch (type) {
- case RSPAMD_DKIM_SIGN_KEY_FILE:
- (void)mlock (map, len);
- nkey->map = map;
- nkey->keydata = map;
- nkey->keylen = map_len;
- break;
- case RSPAMD_DKIM_SIGN_KEY_BASE64:
- nkey->keydata = g_malloc (len);
- nkey->keylen = len;
- rspamd_cryptobox_base64_decode (what, len, nkey->keydata,
- &nkey->keylen);
- break;
- case RSPAMD_DKIM_SIGN_KEY_DER:
- case RSPAMD_DKIM_SIGN_KEY_PEM:
- nkey->keydata = g_malloc (len);
- memcpy (nkey->keydata, what, len);
- nkey->keylen = len;
- }
-
- msg_debug2_dkim("got public key with length %d and type %d", nkey->keylen, type);
- (void)mlock (nkey->keydata, nkey->keylen);
- if (type == RSPAMD_DKIM_SIGN_KEY_FILE && nkey->keylen == ED25519_B64_BYTES) {
- unsigned char seed[32];
+ msg_debug2_dkim("got public key with length %d and type %d", len, type);
+ if (type == RSPAMD_DKIM_KEY_RAW && len == 32) {
unsigned char pk[32];
nkey->type = RSPAMD_DKIM_KEY_EDDSA;
- nkey->keydata = g_malloc (rspamd_cryptobox_sk_sig_bytes (RSPAMD_CRYPTOBOX_MODE_25519));
- rspamd_cryptobox_base64_decode (nkey->map, ED25519_B64_BYTES, seed, &nkey->keylen);
- ed25519_seed_keypair (pk, nkey->keydata, seed);
- nkey->key.key_eddsa = nkey->keydata;
- nkey->keylen = rspamd_cryptobox_sk_sig_bytes (RSPAMD_CRYPTOBOX_MODE_25519);
- rspamd_explicit_memzero (seed, 32);
- munmap (nkey->map, ED25519_B64_BYTES);
- nkey->map = NULL;
- }
- else if (type == RSPAMD_DKIM_SIGN_KEY_BASE64 && nkey->keylen == ED25519_BYTES) {
- unsigned char pk[32];
- nkey->type = RSPAMD_DKIM_KEY_EDDSA;
- nkey->key.key_eddsa =
- g_malloc (rspamd_cryptobox_sk_sig_bytes (RSPAMD_CRYPTOBOX_MODE_25519));
- ed25519_seed_keypair (pk, nkey->key.key_eddsa, nkey->keydata);
- rspamd_explicit_memzero (nkey->keydata, nkey->keylen);
- g_free (nkey->keydata);
- nkey->keydata = nkey->key.key_eddsa;
+ nkey->key.key_eddsa = g_malloc (
+ rspamd_cryptobox_sk_sig_bytes (RSPAMD_CRYPTOBOX_MODE_25519));
+ ed25519_seed_keypair (pk, nkey->key.key_eddsa, (char *)key);
nkey->keylen = rspamd_cryptobox_sk_sig_bytes (RSPAMD_CRYPTOBOX_MODE_25519);
}
else {
- nkey->key_bio = BIO_new_mem_buf (nkey->keydata, nkey->keylen);
+ nkey->key_bio = BIO_new_mem_buf (key, len);
- if (type == RSPAMD_DKIM_SIGN_KEY_DER || type == RSPAMD_DKIM_SIGN_KEY_BASE64) {
+ if (type == RSPAMD_DKIM_KEY_RAW) {
if (d2i_PrivateKey_bio (nkey->key_bio, &nkey->key_evp) == NULL) {
- if (type == RSPAMD_DKIM_SIGN_KEY_FILE) {
- g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
- "cannot read private key from %*s: %s",
- (gint)len, what,
- ERR_error_string (ERR_get_error (), NULL));
- }
- else {
- g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
- "cannot read private key from string: %s",
- ERR_error_string (ERR_get_error (), NULL));
- }
+ g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
+ "cannot parse raw private key: %s",
+ ERR_error_string (ERR_get_error (), NULL));
rspamd_dkim_sign_key_free (nkey);
@@ -2735,18 +2651,9 @@ rspamd_dkim_sign_key_load (const gchar *what, gsize len,
}
else {
if (!PEM_read_bio_PrivateKey (nkey->key_bio, &nkey->key_evp, NULL, NULL)) {
- if (type == RSPAMD_DKIM_SIGN_KEY_FILE) {
- g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
- "cannot read private key from %*s: %s",
- (gint)len, what,
- ERR_error_string (ERR_get_error (), NULL));
- }
- else {
- g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
- "cannot read private key from string: %s",
- ERR_error_string (ERR_get_error (), NULL));
- }
-
+ g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
+ "cannot parse pem private key: %s",
+ ERR_error_string (ERR_get_error (), NULL));
rspamd_dkim_sign_key_free (nkey);
return NULL;
@@ -2772,32 +2679,11 @@ rspamd_dkim_sign_key_load (const gchar *what, gsize len,
}
gboolean
-rspamd_dkim_sign_key_maybe_invalidate (rspamd_dkim_sign_key_t *key,
- enum rspamd_dkim_sign_key_type type,
- const gchar *what, gsize len)
+rspamd_dkim_sign_key_maybe_invalidate (rspamd_dkim_sign_key_t *key, time_t mtime)
{
- struct stat st;
-
- if (type == RSPAMD_DKIM_SIGN_KEY_FILE) {
- gchar fpath[PATH_MAX];
-
- if (len >= PATH_MAX) {
- /* Bad thing */
+ if (mtime > key->mtime) {
return TRUE;
- }
-
- rspamd_snprintf (fpath, sizeof (fpath), "%*s", (gint) len, what);
-
- if (stat (fpath, &st) == -1) {
- /* Wrong: do NOT prefer to use cached key since it is absent on FS */
- return TRUE;
- }
-
- if (st.st_mtime > key->mtime) {
- return TRUE;
- }
}
-
return FALSE;
}
diff --git a/src/libserver/dkim.h b/src/libserver/dkim.h
index 46953a21c..d57c923bb 100644
--- a/src/libserver/dkim.h
+++ b/src/libserver/dkim.h
@@ -102,16 +102,17 @@ typedef struct rspamd_dkim_sign_context_s rspamd_dkim_sign_context_t;
struct rspamd_dkim_key_s;
typedef struct rspamd_dkim_key_s rspamd_dkim_key_t;
-struct rspamd_dkim_sign_key_s;
-typedef struct rspamd_dkim_sign_key_s rspamd_dkim_sign_key_t;
+struct rspamd_dkim_key_s;
+typedef struct rspamd_dkim_key_s rspamd_dkim_sign_key_t;
struct rspamd_task;
-enum rspamd_dkim_sign_key_type {
- RSPAMD_DKIM_SIGN_KEY_FILE = 0,
- RSPAMD_DKIM_SIGN_KEY_PEM,
- RSPAMD_DKIM_SIGN_KEY_BASE64,
- RSPAMD_DKIM_SIGN_KEY_DER
+enum rspamd_dkim_key_format {
+ RSPAMD_DKIM_KEY_FILE = 0,
+ RSPAMD_DKIM_KEY_PEM,
+ RSPAMD_DKIM_KEY_BASE64,
+ RSPAMD_DKIM_KEY_RAW,
+ RSPAMD_DKIM_KEY_UNKNOWN
};
enum rspamd_dkim_type {
@@ -188,17 +189,16 @@ rspamd_dkim_sign_context_t * rspamd_create_dkim_sign_context (struct rspamd_task
* @return
*/
rspamd_dkim_sign_key_t* rspamd_dkim_sign_key_load (const gchar *what, gsize len,
- enum rspamd_dkim_sign_key_type type,
+ enum rspamd_dkim_key_format type,
GError **err);
/**
* Invalidate modified sign key
* @param key
* @return
- */
+*/
gboolean rspamd_dkim_sign_key_maybe_invalidate (rspamd_dkim_sign_key_t *key,
- enum rspamd_dkim_sign_key_type type,
- const gchar *what, gsize len);
+ time_t mtime);
/**
* Make DNS request for specified context and obtain and parse key
diff --git a/src/plugins/dkim_check.c b/src/plugins/dkim_check.c
index 92354529f..06c039ea4 100644
--- a/src/plugins/dkim_check.c
+++ b/src/plugins/dkim_check.c
@@ -38,6 +38,7 @@
#include "libutil/map_helpers.h"
#include "rspamd.h"
#include "utlist.h"
+#include "unix-std.h"
#include "lua/lua_common.h"
#include "libserver/mempool_vars_internal.h"
@@ -634,16 +635,58 @@ 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 (lua_State *L, struct rspamd_task *task,
- const gchar *key, gsize keylen,
- enum rspamd_dkim_sign_key_type kt)
+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;
- struct dkim_ctx *dkim_module_ctx = dkim_get_context (task->cfg);
+ 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);
@@ -651,23 +694,95 @@ dkim_module_load_key_format (lua_State *L, struct rspamd_task *task,
ret = rspamd_lru_hash_lookup (dkim_module_ctx->dkim_sign_hash,
hex_hash, time (NULL));
- if (ret == NULL) {
- ret = rspamd_dkim_sign_key_load (key, keylen, kt, &err);
+ /*
+ * This fails for paths that are also valid base64.
+ * Maybe the caller should have specified a format.
+ */
+ if (key_format == RSPAMD_DKIM_KEY_UNKNOWN &&
+ (key[0] == '.' || key[0] == '/')) {
+ if (!is_valid_base64 (key, keylen))
+ key_format = RSPAMD_DKIM_KEY_FILE;
+ }
- if (ret == NULL) {
- msg_err_task ("cannot load private key: %e", err);
- g_error_free (err);
+ 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");
+ /*
+ * Invalidate DKIM key
+ * removal from lru cache also cleanup the key and value
+ */
+ rspamd_lru_hash_remove (dkim_module_ctx->dkim_sign_hash,
+ hex_hash);
+ ret = NULL;
+ }
+ }
- return NULL;
- }
+ /* found key; done */
+ if (ret != NULL)
+ return ret;
- rspamd_lru_hash_insert (dkim_module_ctx->dkim_sign_hash,
- g_strdup (hex_hash), ret,
- time (NULL), 0);
+ 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);
+
+ if (ret == NULL) {
+ msg_err_task ("cannot load dkim key %s: %e",
+ key, err);
+ g_error_free (err);
+ } else {
+ rspamd_lru_hash_insert (dkim_module_ctx->dkim_sign_hash,
+ 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)
@@ -718,86 +833,24 @@ lua_dkim_sign_handler (lua_State *L)
(GDestroyNotify)rspamd_dkim_sign_key_unref);
}
-#define PEM_SIG "-----BEGIN"
if (key) {
- if (key[0] == '.' || key[0] == '/') {
- /* Likely raw path */
- dkim_key = rspamd_lru_hash_lookup (dkim_module_ctx->dkim_sign_hash,
- key, time (NULL));
-
- if (dkim_key == NULL) {
- dkim_key = rspamd_dkim_sign_key_load (key, strlen (key),
- RSPAMD_DKIM_SIGN_KEY_FILE, &err);
-
- if (dkim_key == NULL) {
- msg_err_task ("cannot load dkim key %s: %e",
- key, err);
- g_error_free (err);
-
- lua_pushboolean (L, FALSE);
- return 1;
- }
-
- rspamd_lru_hash_insert (dkim_module_ctx->dkim_sign_hash,
- g_strdup (key), dkim_key,
- time (NULL), 0);
- }
- }
- else if (keylen > sizeof (PEM_SIG) &&
- strncmp (key, PEM_SIG, sizeof (PEM_SIG) - 1) == 0) {
- /* Pem header found */
- dkim_key = dkim_module_load_key_format (L, task, key, keylen,
- RSPAMD_DKIM_SIGN_KEY_PEM);
-
- if (dkim_key == NULL) {
- lua_pushboolean (L, FALSE);
- return 1;
- }
- }
- else {
- dkim_key = dkim_module_load_key_format (L, task, key, keylen,
- RSPAMD_DKIM_SIGN_KEY_BASE64);
-
- if (dkim_key == NULL) {
- lua_pushboolean (L, FALSE);
- return 1;
- }
- }
- }
- else if (rawkey) {
- key = rawkey;
- keylen = rawlen;
-
- if (keylen > sizeof (PEM_SIG) &&
- strncmp (key, PEM_SIG, sizeof (PEM_SIG) - 1) == 0) {
- /* Pem header found */
- dkim_key = dkim_module_load_key_format (L, task, key, keylen,
- RSPAMD_DKIM_SIGN_KEY_PEM);
-
- if (dkim_key == NULL) {
- lua_pushboolean (L, FALSE);
- return 1;
- }
- }
- else {
- dkim_key = dkim_module_load_key_format (L, task, key, keylen,
- RSPAMD_DKIM_SIGN_KEY_BASE64);
-
- if (dkim_key == NULL) {
- lua_pushboolean (L, FALSE);
- return 1;
- }
- }
- }
- else {
+ dkim_key = dkim_module_load_key_format (task, dkim_module_ctx, key,
+ keylen, RSPAMD_DKIM_KEY_UNKNOWN);
+ } else if(rawkey) {
+ dkim_key = dkim_module_load_key_format (task, dkim_module_ctx, rawkey,
+ rawlen, RSPAMD_DKIM_KEY_UNKNOWN);
+ } else {
msg_err_task ("neither key nor rawkey are specified");
lua_pushboolean (L, FALSE);
return 1;
}
-#undef PEM_SIG
+ if (dkim_key == NULL) {
+ lua_pushboolean (L, FALSE);
+ return 1;
+ }
if (sign_type_str) {
if (strcmp (sign_type_str, "dkim") == 0) {
@@ -1311,226 +1364,167 @@ dkim_sign_callback (struct rspamd_task *task,
GString *tb, *hdr;
GError *err = NULL;
const gchar *selector = NULL, *domain = NULL, *key = NULL, *key_type = NULL,
- *sign_type_str = NULL, *lru_key, *arc_cv = NULL;
+ *sign_type_str = NULL, *arc_cv = NULL;
rspamd_dkim_sign_context_t *ctx;
- rspamd_dkim_sign_key_t *dkim_key;
- enum rspamd_dkim_sign_key_type key_sign_type = RSPAMD_DKIM_SIGN_KEY_FILE;
+ rspamd_dkim_key_t *dkim_key;
+ enum rspamd_dkim_key_format key_format = RSPAMD_DKIM_KEY_FILE;
enum rspamd_dkim_type sign_type = RSPAMD_DKIM_NORMAL;
- guchar h[rspamd_cryptobox_HASHBYTES],
- hex_hash[rspamd_cryptobox_HASHBYTES * 2 + 1];
struct dkim_ctx *dkim_module_ctx = dkim_get_context (task->cfg);
- if (dkim_module_ctx->sign_condition_ref != -1) {
- sign = FALSE;
- L = task->cfg->lua_state;
- lua_pushcfunction (L, &rspamd_lua_traceback);
- err_idx = lua_gettop (L);
-
- lua_rawgeti (L, LUA_REGISTRYINDEX, dkim_module_ctx->sign_condition_ref);
- ptask = lua_newuserdata (L, sizeof (struct rspamd_task *));
- *ptask = task;
- rspamd_lua_setclass (L, "rspamd{task}", -1);
-
- if (lua_pcall (L, 1, 1, err_idx) != 0) {
- tb = lua_touserdata (L, -1);
- msg_err_task ("call to user extraction script failed: %v", tb);
- g_string_free (tb, TRUE);
- }
- else {
- if (lua_istable (L, -1)) {
- /*
- * Get the following elements:
- * - selector
- * - domain
- * - key
- */
- if (!rspamd_lua_parse_table_arguments (L, -1, &err,
- "*key=V;*domain=S;*selector=S;type=S;key_type=S;"
- "sign_type=S;arc_cv=S;arc_idx=I",
- &len, &key, &domain, &selector,
- &key_type, &key_type, &sign_type_str, &arc_cv,
- &arc_idx)) {
- msg_err_task ("invalid return value from sign condition: %e",
- err);
- g_error_free (err);
- rspamd_symcache_finalize_item (task, item);
+ if (dkim_module_ctx->sign_condition_ref == -1) {
+ rspamd_symcache_finalize_item (task, item);
+ return;
+ }
- return;
- }
+ sign = FALSE;
+ L = task->cfg->lua_state;
+ lua_pushcfunction (L, &rspamd_lua_traceback);
+ err_idx = lua_gettop (L);
- if (key_type) {
- if (strcmp (key_type, "file") == 0) {
- key_sign_type = RSPAMD_DKIM_SIGN_KEY_FILE;
- }
- else if (strcmp (key_type, "base64") == 0) {
- key_sign_type = RSPAMD_DKIM_SIGN_KEY_BASE64;
- }
- else if (strcmp (key_type, "pem") == 0) {
- key_sign_type = RSPAMD_DKIM_SIGN_KEY_PEM;
- }
- else if (strcmp (key_type, "der") == 0 ||
- strcmp (key_type, "raw") == 0) {
- key_sign_type = RSPAMD_DKIM_SIGN_KEY_DER;
- }
- else {
- lua_settop (L, 0);
- luaL_error (L, "unknown key type: %s",
- key_type);
- rspamd_symcache_finalize_item (task, item);
+ lua_rawgeti (L, LUA_REGISTRYINDEX, dkim_module_ctx->sign_condition_ref);
+ ptask = lua_newuserdata (L, sizeof (struct rspamd_task *));
+ *ptask = task;
+ rspamd_lua_setclass (L, "rspamd{task}", -1);
- return;
- }
- }
+ if (lua_pcall (L, 1, 1, err_idx) != 0) {
+ tb = lua_touserdata (L, -1);
+ msg_err_task ("call to user extraction script failed: %v", tb);
+ g_string_free (tb, TRUE);
+ }
+ else {
+ if (lua_istable (L, -1)) {
+ /*
+ * Get the following elements:
+ * - selector
+ * - domain
+ * - key
+ */
+ if (!rspamd_lua_parse_table_arguments (L, -1, &err,
+ "*key=V;*domain=S;*selector=S;type=S;key_type=S;"
+ "sign_type=S;arc_cv=S;arc_idx=I",
+ &len, &key, &domain, &selector,
+ &key_type, &key_type, &sign_type_str, &arc_cv,
+ &arc_idx)) {
+ msg_err_task ("invalid return value from sign condition: %e",
+ err);
+ g_error_free (err);
+ rspamd_symcache_finalize_item (task, item);
*** OUTPUT TRUNCATED, 237 LINES SKIPPED ***
More information about the Commits
mailing list