aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-12-24 09:49:32 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-12-24 09:49:32 +0000
commitccf2cbc6d00b0e8a2f63be214b6ccf121aa77c99 (patch)
tree1fc795e1ffa2348ccbaa597b1e28c57a6323ae45 /src/libserver
parent3c0b096b026aee96c2b8ff88dfa5d909c398fa2b (diff)
downloadrspamd-ccf2cbc6d00b0e8a2f63be214b6ccf121aa77c99.tar.gz
rspamd-ccf2cbc6d00b0e8a2f63be214b6ccf121aa77c99.zip
Use refcounting logic for dkim keys to avoid some races
Diffstat (limited to 'src/libserver')
-rw-r--r--src/libserver/dkim.c28
-rw-r--r--src/libserver/dkim.h5
2 files changed, 22 insertions, 11 deletions
diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c
index 3b8fc63b5..d1542c1a0 100644
--- a/src/libserver/dkim.c
+++ b/src/libserver/dkim.c
@@ -840,6 +840,7 @@ rspamd_dkim_make_key (rspamd_dkim_context_t *ctx, const gchar *keydata,
msg_err_dkim ("DKIM key is too short to be valid");
return NULL;
}
+
key = g_slice_alloc0 (sizeof (rspamd_dkim_key_t));
key->keydata = g_slice_alloc (keylen + 1);
rspamd_strlcpy (key->keydata, keydata, keylen + 1);
@@ -855,6 +856,8 @@ rspamd_dkim_make_key (rspamd_dkim_context_t *ctx, const gchar *keydata,
#else
g_base64_decode_inplace (key->keydata, &key->decoded_len);
#endif
+ REF_INIT_RETAIN (key, rspamd_dkim_key_free);
+
#ifdef HAVE_OPENSSL
key->key_bio = BIO_new_mem_buf (key->keydata, key->decoded_len);
if (key->key_bio == NULL) {
@@ -862,7 +865,8 @@ rspamd_dkim_make_key (rspamd_dkim_context_t *ctx, const gchar *keydata,
DKIM_ERROR,
DKIM_SIGERROR_KEYFAIL,
"cannot make ssl bio from key");
- rspamd_dkim_key_free (key);
+ REF_RELEASE (key);
+
return NULL;
}
@@ -872,7 +876,8 @@ rspamd_dkim_make_key (rspamd_dkim_context_t *ctx, const gchar *keydata,
DKIM_ERROR,
DKIM_SIGERROR_KEYFAIL,
"cannot extract pubkey from bio");
- rspamd_dkim_key_free (key);
+ REF_RELEASE (key);
+
return NULL;
}
@@ -882,10 +887,10 @@ rspamd_dkim_make_key (rspamd_dkim_context_t *ctx, const gchar *keydata,
DKIM_ERROR,
DKIM_SIGERROR_KEYFAIL,
"cannot extract rsa key from evp key");
- rspamd_dkim_key_free (key);
+ REF_RELEASE (key);
+
return NULL;
}
-
#endif
return key;
@@ -899,12 +904,12 @@ void
rspamd_dkim_key_free (rspamd_dkim_key_t *key)
{
#ifdef HAVE_OPENSSL
- if (key->key_rsa) {
- RSA_free (key->key_rsa);
- }
if (key->key_evp) {
EVP_PKEY_free (key->key_evp);
}
+ if (key->key_rsa) {
+ RSA_free (key->key_rsa);
+ }
if (key->key_bio) {
BIO_free (key->key_bio);
}
@@ -914,8 +919,8 @@ rspamd_dkim_key_free (rspamd_dkim_key_t *key)
}
static rspamd_dkim_key_t *
-rspamd_dkim_parse_key (rspamd_dkim_context_t *ctx, const gchar *txt, gsize
-*keylen, GError **err)
+rspamd_dkim_parse_key (rspamd_dkim_context_t *ctx, const gchar *txt,
+ gsize *keylen, GError **err)
{
const gchar *c, *p, *end;
gint state = 0;
@@ -943,6 +948,11 @@ rspamd_dkim_parse_key (rspamd_dkim_context_t *ctx, const gchar *txt, gsize
/* State when we got p= and looking for some public key */
if ((*p == ';' || p == end) && p > c) {
len = p - c;
+
+ if (keylen) {
+ *keylen = len;
+ }
+
return rspamd_dkim_make_key (ctx, c, len, err);
}
else {
diff --git a/src/libserver/dkim.h b/src/libserver/dkim.h
index 97f54b912..59735aefe 100644
--- a/src/libserver/dkim.h
+++ b/src/libserver/dkim.h
@@ -28,6 +28,7 @@
#include "config.h"
#include "event.h"
#include "dns.h"
+#include "ref.h"
#ifdef HAVE_OPENSSL
#include <openssl/rsa.h>
#include <openssl/engine.h>
@@ -162,8 +163,8 @@ typedef struct rspamd_dkim_key_s {
BIO *key_bio;
EVP_PKEY *key_evp;
#endif
-}
-rspamd_dkim_key_t;
+ ref_entry_t ref;
+} rspamd_dkim_key_t;
struct rspamd_task;