From 5c6356faa58d3109101e88ecfce207326d89ceab Mon Sep 17 00:00:00 2001 From: Florent Bruneau Date: Tue, 11 Nov 2008 00:46:23 +0100 Subject: [PATCH] Add log_format configuration variable. Signed-off-by: Florent Bruneau --- example/postlicyd.conf | 11 ++++++++ postlicyd/config.c | 13 +++++++++ postlicyd/config.h | 8 ++++++ postlicyd/filter.c | 2 +- postlicyd/filter.h | 4 +-- postlicyd/greylist.c | 4 +-- postlicyd/main-postlicyd.c | 55 +++++++++++++++++--------------------- postlicyd/query.c | 21 +++++++++++++++ postlicyd/query.h | 10 +++++++ 9 files changed, 92 insertions(+), 36 deletions(-) diff --git a/example/postlicyd.conf b/example/postlicyd.conf index 61b2c2c..cff01b9 100644 --- a/example/postlicyd.conf +++ b/example/postlicyd.conf @@ -346,4 +346,15 @@ recipient_filter = client_whitelist; port = 10000; + +# LOG FORMAT +# +# Format of the log printed in syslog. The actual format is "${log_format}: ..." +# +# This parameter uses the same format as used to reply to postfix (${field_name} to +# add a field name). + +log_format = "request client=${client_name}[${client_address}] from=<${sender}> " + "to=<${recipient}> at ${protocol_state}"; + # vim:set syntax=conf: diff --git a/postlicyd/config.c b/postlicyd/config.c index 9c28895..2541be6 100644 --- a/postlicyd/config.c +++ b/postlicyd/config.c @@ -79,6 +79,12 @@ config_param_register("verify_filter"); config_param_register("port"); +/* Format of the log message. + * The message exact format is $log: "reply" + */ +config_param_register("log_format"); + + static config_t *global_config = NULL; static inline config_t *config_new(void) @@ -95,6 +101,7 @@ static void config_close(config_t *config) } array_deep_wipe(config->filters, filter_wipe); array_deep_wipe(config->params, filter_params_wipe); + p_delete(&config->log_format); } void config_delete(config_t **config) @@ -396,11 +403,17 @@ static bool config_build_structure(config_t *config) CASE(ETRN, ETRN) #undef CASE FILTER_PARAM_PARSE_INT(PORT, config->port); + FILTER_PARAM_PARSE_STRING(LOG_FORMAT, config->log_format, true); default: break; } }} array_deep_wipe(config->params, filter_params_wipe); + if (config->log_format && !query_format_check(config->log_format)) { + err("invalid log format: \"%s\"", config->log_format); + return false; + } + if (!ok) { err("no entry point defined"); } diff --git a/postlicyd/config.h b/postlicyd/config.h index 26fb619..b60002d 100644 --- a/postlicyd/config.h +++ b/postlicyd/config.h @@ -65,8 +65,16 @@ struct config_t { * The parameter from CLI override the parameter from configuration file. */ uint16_t port; + + /* Log message. + */ + char *log_format; }; +#define DEFAULT_LOG_FORMAT \ + "request client=${client_name}[${client_address}] from=<${sender}> " \ + "to=<${recipient}> at ${protocol_state}" + __attribute__((nonnull(1))) config_t *config_read(const char *file); diff --git a/postlicyd/filter.c b/postlicyd/filter.c index e108b25..ab608d8 100644 --- a/postlicyd/filter.c +++ b/postlicyd/filter.c @@ -324,7 +324,7 @@ bool filter_add_hook(filter_t *filter, const char *name, int name_len, hook.cost = 0; } hook.postfix = (strncmp(value, "postfix:", 8) == 0); - if (hook.postfix && query_format(NULL, 0, value + 8, NULL) == -1) { + if (hook.postfix && !query_format_check(value + 8)) { err("invalid formatted text \"%s\"", value + 8); return false; } diff --git a/postlicyd/filter.h b/postlicyd/filter.h index 39c3119..c50169d 100644 --- a/postlicyd/filter.h +++ b/postlicyd/filter.h @@ -242,9 +242,9 @@ bool filter_test(const filter_t *filter, const query_t *query, /* Parsing Helpers */ -#define FILTER_PARAM_PARSE_STRING(Param, Dest) \ +#define FILTER_PARAM_PARSE_STRING(Param, Dest, Copy) \ case ATK_ ## Param: { \ - (Dest) = param->value; \ + (Dest) = (Copy) ? m_strdup(param->value) : param->value; \ } break #define FILTER_PARAM_PARSE_INT(Param, Dest) \ diff --git a/postlicyd/greylist.c b/postlicyd/greylist.c index 1a7d68e..9626c20 100644 --- a/postlicyd/greylist.c +++ b/postlicyd/greylist.c @@ -506,8 +506,8 @@ static bool greylist_filter_constructor(filter_t *filter) foreach (filter_param_t *param, filter->params) { switch (param->type) { - FILTER_PARAM_PARSE_STRING(PATH, path); - FILTER_PARAM_PARSE_STRING(PREFIX, prefix); + FILTER_PARAM_PARSE_STRING(PATH, path, false); + FILTER_PARAM_PARSE_STRING(PREFIX, prefix, false); FILTER_PARAM_PARSE_BOOLEAN(LOOKUP_BY_HOST, config->lookup_by_host); FILTER_PARAM_PARSE_BOOLEAN(NO_SENDER, config->no_sender); FILTER_PARAM_PARSE_BOOLEAN(NO_RECIPIENT, config->no_recipient); diff --git a/postlicyd/main-postlicyd.c b/postlicyd/main-postlicyd.c index dab0bf0..a4543ec 100644 --- a/postlicyd/main-postlicyd.c +++ b/postlicyd/main-postlicyd.c @@ -103,21 +103,8 @@ static void policy_answer(client_t *pcy, const char *message) /* Write reply "action=ACTION [text]" */ buffer_addstr(buf, "action="); - buffer_ensure(buf, m_strlen(message) + 64); - - ssize_t size = array_size(*buf) - array_len(*buf); - ssize_t format_size = query_format(array_ptr(*buf, array_len(*buf)), - size, message, query); - if (format_size == -1) { + if (!query_format_buffer(buf, message, query)) { buffer_addstr(buf, message); - } else if (format_size > size) { - buffer_ensure(buf, format_size + 1); - query_format(array_ptr(*buf, array_len(*buf)), - array_size(*buf) - array_len(*buf), - message, query); - array_len(*buf) += format_size; - } else { - array_len(*buf) += format_size; } buffer_addstr(buf, "\n\n"); @@ -129,43 +116,49 @@ static void policy_answer(client_t *pcy, const char *message) static const filter_t *next_filter(client_t *pcy, const filter_t *filter, const query_t *query, const filter_hook_t *hook, bool *ok) { -#define MESSAGE_FORMAT "request client=%s from=<%s> to=<%s> at %s: " -#define MESSAGE_PARAMS query->client_name, \ - query->sender == NULL ? "undefined" : query->sender, \ - query->recipient == NULL ? "undefined" : query->recipient, \ - smtp_state_names[query->state] + char log_prefix[BUFSIZ]; + log_prefix[0] = '\0'; + +#define log_reply(Level, Msg, ...) \ + if (log_level >= LOG_ ## Level) { \ + if (log_prefix[0] == '\0') { \ + query_format(log_prefix, BUFSIZ, \ + config->log_format && config->log_format[0] ? \ + config->log_format : DEFAULT_LOG_FORMAT, query); \ + } \ + __log(LOG_ ## Level, "%s: " Msg, log_prefix, ##__VA_ARGS__); \ + } if (hook != NULL) { query_context_t *context = client_data(pcy); if (hook->counter >= 0 && hook->counter < MAX_COUNTERS && hook->cost > 0) { context->context.counters[hook->counter] += hook->cost; - debug(MESSAGE_FORMAT "added %d to counter %d (now %u)", MESSAGE_PARAMS, - hook->cost, hook->counter, context->context.counters[hook->counter]); + log_reply(DEBUG, "added %d to counter %d (now %u)", + hook->cost, hook->counter, + context->context.counters[hook->counter]); } } if (hook == NULL) { - warn(MESSAGE_FORMAT "aborted", MESSAGE_PARAMS); + log_reply(WARNING, "aborted"); *ok = false; return NULL; } else if (hook->async) { - debug(MESSAGE_FORMAT "asynchronous filter from filter %s", - MESSAGE_PARAMS, filter->name); + log_reply(WARNING, "asynchronous filter from filter %s", filter->name); *ok = true; return NULL; } else if (hook->postfix) { - info(MESSAGE_FORMAT "awswer %s from filter %s: \"%s\"", MESSAGE_PARAMS, - htokens[hook->type], filter->name, hook->value); + log_reply(INFO, "awswer %s from filter %s: \"%s\"", + htokens[hook->type], filter->name, hook->value); policy_answer(pcy, hook->value); *ok = true; return NULL; } else { - debug(MESSAGE_FORMAT "awswer %s from filter %s: next filter %s", - MESSAGE_PARAMS, htokens[hook->type], filter->name, - (array_ptr(config->filters, hook->filter_id))->name); + log_reply(DEBUG, "awswer %s from filter %s: next filter %s", + htokens[hook->type], filter->name, + (array_ptr(config->filters, hook->filter_id))->name); return array_ptr(config->filters, hook->filter_id); } -#undef MESSAGE_PARAMS -#undef MESSAGE_FORMAT +#undef log_reply } static bool policy_process(client_t *pcy, const config_t *mconfig) diff --git a/postlicyd/query.c b/postlicyd/query.c index 4a4ae9c..599b9ec 100644 --- a/postlicyd/query.c +++ b/postlicyd/query.c @@ -259,3 +259,24 @@ ssize_t query_format(char *dest, size_t len, const char *fmt, const query_t *que } return pos; } + +bool query_format_buffer(buffer_t *buf, const char *fmt, const query_t *query) +{ + buffer_ensure(buf, m_strlen(fmt) + 64); + + ssize_t size = array_free_space(*buf); + ssize_t format_size = query_format(array_end(*buf), + size, fmt, query); + if (format_size == -1) { + return false; + } else if (format_size > size) { + buffer_ensure(buf, format_size + 1); + query_format(array_end(*buf), + array_free_space(*buf), + fmt, query); + array_len(*buf) += format_size; + } else { + array_len(*buf) += format_size; + } + return true; +} diff --git a/postlicyd/query.h b/postlicyd/query.h index 9dabfe0..7e9dc7f 100644 --- a/postlicyd/query.h +++ b/postlicyd/query.h @@ -39,6 +39,7 @@ #include "mem.h" #include "common.h" +#include "buffer.h" #include "policy_tokens.h" enum smtp_state { @@ -122,4 +123,13 @@ const char *query_field_for_id(const query_t *query, postlicyd_token id); __attribute__((nonnull(3))) ssize_t query_format(char *dest, size_t len, const char* fmt, const query_t *query); +/** Writes a query-formated string in a buffer. + */ +__attribute__((nonnull(1,2))) +bool query_format_buffer(buffer_t *buf, const char *fmt, const query_t *query); + +/** Check the query-format string. + */ +#define query_format_check(fmt) (query_format(NULL, 0, fmt, NULL) >= 0) + #endif -- 2.20.1