mirror of
https://bitbucket.org/jsuto/piler.git
synced 2024-12-24 19:30:12 +01:00
Added security header feature
Signed-off-by: Janos SUTO <sj@acts.hu>
This commit is contained in:
parent
bb8f6b1e00
commit
535a4aa61c
@ -1,3 +1,9 @@
|
|||||||
|
1.3.10:
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Added security header feature
|
||||||
|
|
||||||
|
|
||||||
1.3.9:
|
1.3.9:
|
||||||
------
|
------
|
||||||
|
|
||||||
|
@ -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=
|
||||||
|
@ -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},
|
||||||
|
@ -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];
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
60
src/piler.c
60
src/piler.c
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user