summaryrefslogtreecommitdiffstats
path: root/src/libutil/logger.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-08-16 16:45:34 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-08-16 17:05:02 +0100
commitdb25f46740511104bbe565f20914b4aabec7864e (patch)
treec0c52c829d5639d445b48466db4d54a7c9d863e3 /src/libutil/logger.c
parent13aa518f897059689fb71d3896956f6f7be21224 (diff)
downloadrspamd-db25f46740511104bbe565f20914b4aabec7864e.tar.gz
rspamd-db25f46740511104bbe565f20914b4aabec7864e.zip
[Feature] Implement encrypted logs
Diffstat (limited to 'src/libutil/logger.c')
-rw-r--r--src/libutil/logger.c143
1 files changed, 110 insertions, 33 deletions
diff --git a/src/libutil/logger.c b/src/libutil/logger.c
index 3f49d430d..a57eacfa6 100644
--- a/src/libutil/logger.c
+++ b/src/libutil/logger.c
@@ -19,6 +19,8 @@
#include "rspamd.h"
#include "map.h"
#include "cryptobox.h"
+#include "ottery.h"
+#include "keypair.h"
#include "unix-std.h"
#ifdef HAVE_SYSLOG_H
@@ -38,6 +40,8 @@
struct rspamd_logger_s {
rspamd_log_func_t log_func;
struct rspamd_config *cfg;
+ struct rspamd_cryptobox_pubkey *pk;
+ struct rspamd_cryptobox_keypair *keypair;
struct {
guint32 size;
guint32 used;
@@ -311,59 +315,80 @@ rspamd_set_logger (struct rspamd_config *cfg,
GQuark ptype,
struct rspamd_main *rspamd)
{
+ rspamd_logger_t *logger;
+
if (rspamd->logger == NULL) {
rspamd->logger = g_slice_alloc0 (sizeof (rspamd_logger_t));
}
- rspamd->logger->type = cfg->log_type;
- rspamd->logger->pid = getpid ();
- rspamd->logger->process_type = ptype;
+ logger = rspamd->logger;
+
+ logger->type = cfg->log_type;
+ logger->pid = getpid ();
+ logger->process_type = ptype;
switch (cfg->log_type) {
case RSPAMD_LOG_CONSOLE:
- rspamd->logger->log_func = file_log_function;
- rspamd->logger->fd = STDERR_FILENO;
+ logger->log_func = file_log_function;
+ logger->fd = STDERR_FILENO;
break;
case RSPAMD_LOG_SYSLOG:
- rspamd->logger->log_func = syslog_log_function;
+ logger->log_func = syslog_log_function;
break;
case RSPAMD_LOG_FILE:
- rspamd->logger->log_func = file_log_function;
+ logger->log_func = file_log_function;
break;
}
- rspamd->logger->cfg = cfg;
+ logger->cfg = cfg;
+
/* Set up buffer */
- if (rspamd->cfg->log_buffered) {
- if (rspamd->cfg->log_buf_size != 0) {
- rspamd->logger->io_buf.size = rspamd->cfg->log_buf_size;
+ if (cfg->log_buffered) {
+ if (cfg->log_buf_size != 0) {
+ logger->io_buf.size = cfg->log_buf_size;
}
else {
- rspamd->logger->io_buf.size = BUFSIZ;
+ logger->io_buf.size = BUFSIZ;
}
- rspamd->logger->is_buffered = TRUE;
- rspamd->logger->io_buf.buf = g_malloc (rspamd->logger->io_buf.size);
+ logger->is_buffered = TRUE;
+ logger->io_buf.buf = g_malloc (logger->io_buf.size);
}
/* Set up conditional logging */
- if (rspamd->cfg->debug_ip_map != NULL) {
+ if (cfg->debug_ip_map != NULL) {
/* Try to add it as map first of all */
- if (rspamd->logger->debug_ip) {
- radix_destroy_compressed (rspamd->logger->debug_ip);
+ if (logger->debug_ip) {
+ radix_destroy_compressed (logger->debug_ip);
}
- rspamd->logger->debug_ip = NULL;
-
- rspamd_config_radix_from_ucl (rspamd->cfg,
- rspamd->cfg->debug_ip_map,
+ logger->debug_ip = NULL;
+ rspamd_config_radix_from_ucl (cfg,
+ cfg->debug_ip_map,
"IP addresses for which debug logs are enabled",
- &rspamd->logger->debug_ip, NULL);
+ &logger->debug_ip, NULL);
+ }
+ else if (logger->debug_ip) {
+ radix_destroy_compressed (logger->debug_ip);
+ logger->debug_ip = NULL;
+ }
+
+ if (logger->pk) {
+ rspamd_pubkey_unref (logger->pk);
+ }
+ logger->pk = NULL;
+
+ if (logger->keypair) {
+ rspamd_keypair_unref (logger->keypair);
}
- else if (rspamd->logger->debug_ip) {
- radix_destroy_compressed (rspamd->logger->debug_ip);
- rspamd->logger->debug_ip = NULL;
+ logger->keypair = NULL;
+
+ if (cfg->log_encryption_key) {
+ logger->pk = rspamd_pubkey_ref (cfg->log_encryption_key);
+ logger->keypair = rspamd_keypair_new (RSPAMD_KEYPAIR_KEX,
+ RSPAMD_CRYPTOBOX_MODE_25519);
+ rspamd_pubkey_calculate_nm (logger->pk, logger->keypair);
}
- default_logger = rspamd->logger;
+ default_logger = logger;
}
/**
@@ -428,12 +453,50 @@ rspamd_logger_need_log (rspamd_logger_t *rspamd_log, GLogLevelFlags log_level,
return FALSE;
}
+static gchar *
+rspamd_log_encrypt_message (const gchar *begin, const gchar *end,
+ rspamd_logger_t *rspamd_log)
+{
+ guchar *out;
+ gchar *b64;
+ guchar *p, *nonce, *mac;
+ const guchar *comp;
+ guint len, inlen;
+
+ g_assert (end > begin);
+ /* base64 (pubkey | nonce | message) */
+ inlen = rspamd_cryptobox_nonce_bytes (RSPAMD_CRYPTOBOX_MODE_25519) +
+ rspamd_cryptobox_pk_bytes (RSPAMD_CRYPTOBOX_MODE_25519) +
+ rspamd_cryptobox_mac_bytes (RSPAMD_CRYPTOBOX_MODE_25519) +
+ (end - begin);
+ out = g_malloc (inlen);
+
+ p = out;
+ comp = rspamd_pubkey_get_pk (rspamd_log->pk, &len);
+ memcpy (p, comp, len);
+ p += len;
+ ottery_rand_bytes (p, rspamd_cryptobox_nonce_bytes (RSPAMD_CRYPTOBOX_MODE_25519));
+ nonce = p;
+ p += rspamd_cryptobox_nonce_bytes (RSPAMD_CRYPTOBOX_MODE_25519);
+ mac = p;
+ p += rspamd_cryptobox_mac_bytes (RSPAMD_CRYPTOBOX_MODE_25519);
+ memcpy (p, begin, end - begin);
+ comp = rspamd_pubkey_get_nm (rspamd_log->pk);
+ g_assert (comp != NULL);
+ rspamd_cryptobox_encrypt_nm_inplace (p, end - begin, nonce, comp, mac,
+ RSPAMD_CRYPTOBOX_MODE_25519);
+ b64 = rspamd_encode_base64 (out, inlen, 0, NULL);
+ g_free (out);
+
+ return b64;
+}
+
void
rspamd_common_logv (rspamd_logger_t *rspamd_log, gint level_flags,
const gchar *module, const gchar *id, const gchar *function,
const gchar *fmt, va_list args)
{
- gchar logbuf[RSPAMD_LOGBUF_SIZE];
+ gchar logbuf[RSPAMD_LOGBUF_SIZE], *end;
gint level = level_flags & (RSPAMD_LOG_LEVEL_MASK|G_LOG_LEVEL_MASK);
if (rspamd_log == NULL) {
@@ -449,12 +512,26 @@ rspamd_common_logv (rspamd_logger_t *rspamd_log, gint level_flags,
}
else {
if (rspamd_logger_need_log (rspamd_log, level, module)) {
- rspamd_vsnprintf (logbuf, sizeof (logbuf), fmt, args);
- rspamd_log->log_func (module, id,
- function,
- level_flags,
- logbuf,
- rspamd_log);
+ end = rspamd_vsnprintf (logbuf, sizeof (logbuf), fmt, args);
+
+ if ((level_flags & RSPAMD_LOG_ENCRYPTED) && rspamd_log->pk) {
+ gchar *encrypted;
+
+ encrypted = rspamd_log_encrypt_message (logbuf, end, rspamd_log);
+ rspamd_log->log_func (module, id,
+ function,
+ level_flags,
+ encrypted,
+ rspamd_log);
+ g_free (encrypted);
+ }
+ else {
+ rspamd_log->log_func (module, id,
+ function,
+ level_flags,
+ logbuf,
+ rspamd_log);
+ }
switch (level) {
case G_LOG_LEVEL_CRITICAL: