Browse Source

[Feature] Allow to pass sign key directly from Lua

tags/1.5.0
Vsevolod Stakhov 7 years ago
parent
commit
02b3c52472
3 changed files with 113 additions and 15 deletions
  1. 53
    0
      src/libserver/dkim.c
  2. 9
    0
      src/libserver/dkim.h
  3. 51
    15
      src/plugins/dkim_check.c

+ 53
- 0
src/libserver/dkim.c View File

@@ -2025,6 +2025,59 @@ rspamd_dkim_sign_key_load (const gchar *path, GError **err)
return nkey;
}

rspamd_dkim_sign_key_t*
rspamd_dkim_sign_key_from_memory (const guchar *data,
gsize len, GError **err)
{
rspamd_dkim_sign_key_t *nkey;
gpointer map;

map = mmap (NULL, len, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);

if (map == MAP_FAILED) {
g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
"cannot map in-memory private key %s",
strerror (errno));

return NULL;
}

/* Initialize memory and set the appropriate access mode */
memcpy (map, data, len);
(void)mprotect (map, len, PROT_READ);
(void)mlock (map, len);

nkey = g_slice_alloc0 (sizeof (*nkey));
nkey->keydata = map;
nkey->keylen = len;
nkey->key_bio = BIO_new_mem_buf (map, len);

if (!PEM_read_bio_PrivateKey (nkey->key_bio, &nkey->key_evp, NULL, NULL)) {
g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
"cannot read private key from memory: %s",
ERR_error_string (ERR_get_error (), NULL));
rspamd_dkim_sign_key_free (nkey);

return NULL;
}

nkey->key_rsa = EVP_PKEY_get1_RSA (nkey->key_evp);
if (nkey->key_rsa == NULL) {
g_set_error (err,
DKIM_ERROR,
DKIM_SIGERROR_KEYFAIL,
"cannot extract rsa key from evp key");
rspamd_dkim_sign_key_free (nkey);

return NULL;
}

REF_INIT_RETAIN (nkey, rspamd_dkim_sign_key_free);

return nkey;
}

rspamd_dkim_sign_context_t *
rspamd_create_dkim_sign_context (struct rspamd_task *task,
rspamd_dkim_sign_key_t *priv_key,

+ 9
- 0
src/libserver/dkim.h View File

@@ -141,6 +141,15 @@ rspamd_dkim_sign_context_t * rspamd_create_dkim_sign_context (struct rspamd_task
*/
rspamd_dkim_sign_key_t* rspamd_dkim_sign_key_load (const gchar *path, GError **err);

/**
* Load dkim key from memory chunk
* @param path
* @param err
* @return
*/
rspamd_dkim_sign_key_t* rspamd_dkim_sign_key_from_memory (const guchar *data,
gsize len, GError **err);

/**
* Make DNS request for specified context and obtain and parse key
* @param ctx dkim context from signature

+ 51
- 15
src/plugins/dkim_check.c View File

@@ -553,9 +553,10 @@ lua_dkim_sign_handler (lua_State *L)

GError *err = NULL;
GString *hdr;
const gchar *selector = NULL, *domain = NULL, *key = NULL;
const gchar *selector = NULL, *domain = NULL, *key = NULL, *rawkey = NULL;
rspamd_dkim_sign_context_t *ctx;
rspamd_dkim_sign_key_t *dkim_key;
gsize rawlen = 0;
/*
* Get the following elements:
* - selector
@@ -563,8 +564,8 @@ lua_dkim_sign_handler (lua_State *L)
* - key
*/
if (!rspamd_lua_parse_table_arguments (L, 2, &err,
"*key=S;*domain=S;*selector=S",
&key, &domain, &selector)) {
"key=S;rawkey=V;*domain=S;*selector=S",
&key, &rawlen, rawkey, &domain, &selector)) {
msg_err_task ("invalid return value from sign condition: %e",
err);
g_error_free (err);
@@ -580,24 +581,59 @@ lua_dkim_sign_handler (lua_State *L)
(GDestroyNotify)rspamd_dkim_sign_key_unref);
}

dkim_key = rspamd_lru_hash_lookup (dkim_module_ctx->dkim_sign_hash,
key, time (NULL));
if (key) {
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, &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 (rawkey) {
guchar h[rspamd_cryptobox_HASHBYTES],
hex_hash[rspamd_cryptobox_HASHBYTES * 2 + 1];

if (dkim_key == NULL) {
dkim_key = rspamd_dkim_sign_key_load (key, &err);
memset (hex_hash, 0, sizeof (hex_hash));
rspamd_cryptobox_hash (h, rawkey, rawlen, NULL, 0);
rspamd_encode_hex_buf (h, sizeof (h), hex_hash, sizeof (hex_hash));
dkim_key = rspamd_lru_hash_lookup (dkim_module_ctx->dkim_sign_hash,
hex_hash, time (NULL));

if (dkim_key == NULL) {
msg_err_task ("cannot load dkim key %s: %e",
key, err);
g_error_free (err);
dkim_key = rspamd_dkim_sign_key_from_memory (rawkey, rawlen, &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;
}

lua_pushboolean (L, FALSE);
return 1;
rspamd_lru_hash_insert (dkim_module_ctx->dkim_sign_hash,
g_strdup (hex_hash), dkim_key,
time (NULL), 0);
}
}
else {
msg_err_task ("neither key nor rawkey are specified", err);
lua_pushboolean (L, FALSE);

rspamd_lru_hash_insert (dkim_module_ctx->dkim_sign_hash,
g_strdup (key), dkim_key,
time (NULL), 0);
return 1;
}

ctx = rspamd_create_dkim_sign_context (task, dkim_key,

Loading…
Cancel
Save