diff --git a/src/defs.h b/src/defs.h index 66be6ab1..ba5995e0 100644 --- a/src/defs.h +++ b/src/defs.h @@ -184,11 +184,13 @@ struct parser_state { int saved_size; unsigned int writebufpos; unsigned int abufpos; + unsigned int received_header; char attachedfile[RND_STR_LEN+SMALLBUFSIZE]; char message_id[SMALLBUFSIZE]; char message_id_hash[2*DIGEST_LENGTH+1]; char miscbuf[MAX_TOKEN_LEN]; char qpbuf[MAX_TOKEN_LEN]; + char receivedbuf[SMALLBUFSIZE]; unsigned long n_token; unsigned long n_subject_token; unsigned long n_body_token; diff --git a/src/parser.c b/src/parser.c index 1a9299d8..7b1ea688 100644 --- a/src/parser.c +++ b/src/parser.c @@ -112,6 +112,15 @@ void post_parse(struct session_data *sdata, struct parser_state *state, struct c if(sdata->internal_recipient == 1 && sdata->external_recipient == 1) sdata->direction = DIRECTION_INTERNAL_AND_OUTGOING; } + char *q = strrchr(state->receivedbuf, ';'); + if(q){ + time_t received_timestamp = parse_date_header(q+1); + if(received_timestamp > 10000000){ + // If the calculated date based on Date: header line differs more than 1 week + // then we'll override it with the data parsed from the first Received: line + if(labs(received_timestamp - sdata->sent) > 604800) sdata->sent = received_timestamp; + } + } for(i=1; i<=state->n_attachments; i++){ char puf[SMALLBUFSIZE]; @@ -440,7 +449,10 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata } else if(strncasecmp(buf, "Delivery-date:", strlen("Delivery-date:")) == 0 && sdata->delivered == 0) sdata->delivered = parse_date_header(buf); - else if(strncasecmp(buf, "Received:", strlen("Received:")) == 0) state->message_state = MSG_RECEIVED; + else if(strncasecmp(buf, "Received:", strlen("Received:")) == 0){ + state->message_state = MSG_RECEIVED; + state->received_header++; + } else if(cfg->extra_to_field[0] != '\0' && strncasecmp(buf, cfg->extra_to_field, strlen(cfg->extra_to_field)) == 0){ state->message_state = MSG_TO; buf += strlen(cfg->extra_to_field); @@ -458,6 +470,10 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata fill_attachment_name_buf(state, buf); } + if(state->received_header == 1 && state->message_state == MSG_RECEIVED){ + memcpy(&(state->receivedbuf[strlen(state->receivedbuf)]), buf, len); + } + /* we are interested in only From:, To:, Subject:, Received:, Content-*: header lines */ if(state->message_state <= 0) return 0; } diff --git a/src/parser_utils.c b/src/parser_utils.c index e8c1f2c8..31cb45f8 100644 --- a/src/parser_utils.c +++ b/src/parser_utils.c @@ -49,6 +49,7 @@ void init_state(struct parser_state *state){ memset(state->message_id_hash, 0, 2*DIGEST_LENGTH+1); memset(state->miscbuf, 0, MAX_TOKEN_LEN); memset(state->qpbuf, 0, MAX_TOKEN_LEN); + memset(state->receivedbuf, 0, sizeof(state->receivedbuf)); memset(state->type, 0, TINYBUFSIZE); @@ -67,6 +68,7 @@ void init_state(struct parser_state *state){ state->writebufpos = 0; state->abufpos = 0; + state->received_header = 0; inithash(state->boundaries); inithash(state->rcpt); diff --git a/src/test.c b/src/test.c index 956910d0..0049a41e 100644 --- a/src/test.c +++ b/src/test.c @@ -195,6 +195,8 @@ int main(int argc, char **argv){ printf("spam: %d\n", sdata.spam_message); + printf("1st received line: %s\n", state.receivedbuf); + if(sdata.internal_sender == 0 && sdata.internal_recipient == 0) printf("NOT IN mydomains\n"); printf("\n\n");