Added security header feature

Signed-off-by: Janos SUTO <sj@acts.hu>
This commit is contained in:
Janos SUTO 2020-11-26 19:01:45 +01:00
parent bb8f6b1e00
commit 535a4aa61c
9 changed files with 61 additions and 26 deletions

View File

@ -1,3 +1,9 @@
1.3.10:
-------
- Added security header feature
1.3.9: 1.3.9:
------ ------

View File

@ -1 +1 @@
1.3.9 1.3.10

View File

@ -221,3 +221,11 @@ tweak_sent_time_offset=0
; whether to enable (1) or not (0) the extra mmap dedup test feature ; whether to enable (1) or not (0) the extra mmap dedup test feature
; if you change it, be sure to stop, then start piler ; if you change it, be sure to stop, then start piler
mmap_dedup_test=0 mmap_dedup_test=0
; security header that must be present in the first mail header of
; the message. If the security_header value is not empty, then the
; parser checks for this header line. Unless it's found it will discard
; the given email. Note that this feature is supposed to be a security
; mechanism against unwanted email in the archive if limiting smtp
; clients via an IP-address list is not feasible.
security_header=

View File

@ -84,6 +84,7 @@ struct _parse_rule config_parse_rules[] =
{ "piler_header_field", "string", (void*) string_parser, offsetof(struct config, piler_header_field), "X-piler-id:", MAXVAL-1}, { "piler_header_field", "string", (void*) string_parser, offsetof(struct config, piler_header_field), "X-piler-id:", MAXVAL-1},
{ "process_rcpt_to_addresses", "integer", (void*) int_parser, offsetof(struct config, process_rcpt_to_addresses), "0", sizeof(int)}, { "process_rcpt_to_addresses", "integer", (void*) int_parser, offsetof(struct config, process_rcpt_to_addresses), "0", sizeof(int)},
{ "queuedir", "string", (void*) string_parser, offsetof(struct config, queuedir), QUEUE_DIR, MAXVAL-1}, { "queuedir", "string", (void*) string_parser, offsetof(struct config, queuedir), QUEUE_DIR, MAXVAL-1},
{ "security_header", "string", (void*) string_parser, offsetof(struct config, security_header), "", MAXVAL-1},
{ "server_id", "integer", (void*) int_parser, offsetof(struct config, server_id), "0", sizeof(int)}, { "server_id", "integer", (void*) int_parser, offsetof(struct config, server_id), "0", sizeof(int)},
{ "smtp_timeout", "integer", (void*) int_parser, offsetof(struct config, smtp_timeout), "60", sizeof(int)}, { "smtp_timeout", "integer", (void*) int_parser, offsetof(struct config, smtp_timeout), "60", sizeof(int)},
{ "spam_header_line", "string", (void*) string_parser, offsetof(struct config, spam_header_line), "", MAXVAL-1}, { "spam_header_line", "string", (void*) string_parser, offsetof(struct config, spam_header_line), "", MAXVAL-1},

View File

@ -64,6 +64,8 @@ struct config {
int default_retention_days; int default_retention_days;
char security_header[MAXVAL];
// mysql stuff // mysql stuff
char mysqlcharset[MAXVAL]; char mysqlcharset[MAXVAL];

View File

@ -209,6 +209,8 @@ struct parser_state {
unsigned int bodylen; unsigned int bodylen;
unsigned int tolen; unsigned int tolen;
unsigned int todomainlen; unsigned int todomainlen;
unsigned int found_security_header;
int journaltolen; int journaltolen;
int retention; int retention;

View File

@ -199,6 +199,10 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata
sdata->restored_copy = 1; sdata->restored_copy = 1;
} }
if(cfg->security_header && state->found_security_header == 0 && strstr(buf, cfg->security_header)){
state->found_security_header = 1;
}
if(*(cfg->piler_header_field) != 0 && strncmp(buf, cfg->piler_header_field, strlen(cfg->piler_header_field)) == 0){ if(*(cfg->piler_header_field) != 0 && strncmp(buf, cfg->piler_header_field, strlen(cfg->piler_header_field)) == 0){
sdata->restored_copy = 1; sdata->restored_copy = 1;
} }

View File

@ -102,6 +102,8 @@ void init_state(struct parser_state *state){
state->journaltolen = 0; state->journaltolen = 0;
state->retention = 0; state->retention = 0;
state->found_security_header = 0;
} }

View File

@ -101,11 +101,43 @@ void child_sighup_handler(int sig){
} }
int perform_checks(char *filename, struct session_data *sdata, struct data *data, struct parser_state *parser_state, struct config *cfg){
if(cfg->security_header && parser_state->found_security_header == 0){
syslog(LOG_PRIORITY, "%s: discarding: missing security header", filename);
return ERR_DISCARDED;
}
char *arule = check_against_ruleset(data->archiving_rules, parser_state, sdata->tot_len, sdata->spam_message);
if(arule){
syslog(LOG_PRIORITY, "%s: discarding: archiving policy: *%s*", filename, arule);
return ERR_DISCARDED;
}
if(cfg->archive_only_mydomains == 1 && sdata->internal_sender == 0 && sdata->internal_recipient == 0){
syslog(LOG_PRIORITY, "%s: discarding: not on mydomains", filename);
return ERR_DISCARDED;
}
make_digests(sdata, cfg);
if(sdata->hdr_len < 10){
syslog(LOG_PRIORITY, "%s: invalid message, hdr_len: %d", filename, sdata->hdr_len);
return ERR;
}
int rc = process_message(sdata, parser_state, data, cfg);
unlink(parser_state->message_id_hash);
return rc;
}
int process_email(char *filename, struct session_data *sdata, struct data *data, int size, struct config *cfg){ int process_email(char *filename, struct session_data *sdata, struct data *data, int size, struct config *cfg){
int rc;
char tmpbuf[SMALLBUFSIZE]; char tmpbuf[SMALLBUFSIZE];
char *status=S_STATUS_UNDEF; char *status=S_STATUS_UNDEF;
char *arule;
char *p; char *p;
struct timezone tz; struct timezone tz;
struct timeval tv1, tv2; struct timeval tv1, tv2;
@ -144,29 +176,7 @@ int process_email(char *filename, struct session_data *sdata, struct data *data,
} while(rcpt); } while(rcpt);
} }
arule = check_against_ruleset(data->archiving_rules, &parser_state, sdata->tot_len, sdata->spam_message); int rc = perform_checks(filename, sdata, data, &parser_state, cfg);
if(arule){
syslog(LOG_PRIORITY, "%s: discarding: archiving policy: *%s*", filename, arule);
rc = ERR_DISCARDED;
}
else if(cfg->archive_only_mydomains == 1 && sdata->internal_sender == 0 && sdata->internal_recipient == 0){
syslog(LOG_PRIORITY, "%s: discarding: not on mydomains", filename);
rc = ERR_DISCARDED;
}
else {
make_digests(sdata, cfg);
if(sdata->hdr_len < 10){
syslog(LOG_PRIORITY, "%s: invalid message, hdr_len: %d", filename, sdata->hdr_len);
rc = ERR;
}
else {
rc = process_message(sdata, &parser_state, data, cfg);
unlink(parser_state.message_id_hash);
}
}
unlink(sdata->tmpframe); unlink(sdata->tmpframe);
remove_stripped_attachments(&parser_state); remove_stripped_attachments(&parser_state);