diff --git a/src/defs.h b/src/defs.h index d70031a..c76221c 100644 --- a/src/defs.h +++ b/src/defs.h @@ -166,6 +166,7 @@ int style; int skip_html; int has_to_dump; + int has_to_dump_whole_body; int fd; int b64fd; int mfd; diff --git a/src/parser.c b/src/parser.c index 6b755c4..9882aad 100644 --- a/src/parser.c +++ b/src/parser.c @@ -51,6 +51,15 @@ if(take_into_pieces == 1){ close(state.mfd); state.mfd = 0; + + if(state.has_to_dump_whole_body == 1){ + if(state.abufpos > 0){ + flush_attachment_buffer(&state, &abuffer[0], sizeof(abuffer)); + } + if(state.fd != -1) close(state.fd); + if(state.b64fd != -1) close(state.b64fd); + } + } fclose(f); @@ -218,13 +227,16 @@ if(take_into_pieces == 1){ - if(state->message_state == MSG_BODY && state->fd != -1 && is_substr_in_hash(state->boundaries, buf) == 0){ + if(state->message_state == MSG_BODY && state->fd != -1 && (state->has_to_dump_whole_body == 1 || is_substr_in_hash(state->boundaries, buf) == 0) ){ if(len + state->abufpos > abuffersize-1){ flush_attachment_buffer(state, abuffer, abuffersize); } memcpy(abuffer+state->abufpos, buf, len); state->abufpos += len; state->attachments[state->n_attachments].size += len; + + // When processing the body and writing to an attachment file, then we finish here + return 0; } else { state->saved_size += len; @@ -238,7 +250,7 @@ } - if(state->message_state == MSG_BODY && state->has_to_dump == 1 && state->pushed_pointer == 0){ + if(state->message_state == MSG_BODY && state->has_to_dump == 1 && state->pushed_pointer == 0){ state->pushed_pointer = 1; @@ -340,7 +352,13 @@ else if(strncasecmp(buf, "Content-Type:", strlen("Content-Type:")) == 0){ state->message_state = MSG_CONTENT_TYPE; } - else if(strncasecmp(buf, "Content-Transfer-Encoding:", strlen("Content-Transfer-Encoding:")) == 0) state->message_state = MSG_CONTENT_TRANSFER_ENCODING; + else if(strncasecmp(buf, "Content-Transfer-Encoding:", strlen("Content-Transfer-Encoding:")) == 0){ + state->message_state = MSG_CONTENT_TRANSFER_ENCODING; + if(state->is_1st_header == 1 && strcasestr(buf, "base64")){ + state->has_to_dump = 1; + state->has_to_dump_whole_body = 1; + } + } /* * We only enter MSG_CONTENT_DISPOSITION state if we couldn't find @@ -408,6 +426,10 @@ snprintf(state->message_id, SMALLBUFSIZE-1, "%s", p); } + if(state->message_state == MSG_CONTENT_TYPE || state->message_state == MSG_CONTENT_DISPOSITION){ + fill_attachment_name_buf(state, buf); + } + /* we are interested in only From:, To:, Subject:, Received:, Content-*: header lines */ if(state->message_state <= 0) return 0; } @@ -420,7 +442,7 @@ } - /* + /* * A normal journal looks like this: * * Sender: sender@domain @@ -526,21 +548,6 @@ } - if(state->message_state == MSG_CONTENT_TYPE || state->message_state == MSG_CONTENT_DISPOSITION){ - p = &buf[0]; - for(; *p; p++){ - if(*p != ' ' && *p != '\t') break; - } - - len = strlen(p); - - if(len + state->anamepos < SMALLBUFSIZE-2){ - memcpy(&(state->attachment_name_buf[state->anamepos]), p, len); - state->anamepos += len; - } - } - - if(state->message_state == MSG_CONTENT_TRANSFER_ENCODING){ if(strcasestr(buf, "base64")) state->base64 = 1; if(strcasestr(buf, "quoted-printable")) state->qp = 1; diff --git a/src/parser.h b/src/parser.h index ef343ef..5525af8 100644 --- a/src/parser.h +++ b/src/parser.h @@ -36,5 +36,7 @@ int base64_decode_attachment_buffer(char *p, unsigned char *b, int blen); void fix_plus_sign_in_email_address(char *puf, char **at_sign, unsigned int *len); void tokenize(char *buf, struct parser_state *state, struct session_data *sdata, struct data *data, struct config *cfg); +void flush_attachment_buffer(struct parser_state *state, char *abuffer, unsigned int abuffersize); +void fill_attachment_name_buf(struct parser_state *state, char *buf); #endif /* _PARSER_H */ diff --git a/src/parser_utils.c b/src/parser_utils.c index 0d0a1f4..a00bc28 100644 --- a/src/parser_utils.c +++ b/src/parser_utils.c @@ -56,6 +56,7 @@ state->anamepos = 0; state->has_to_dump = 0; + state->has_to_dump_whole_body = 0; state->fd = -1; state->b64fd = -1; state->mfd = -1; @@ -1055,3 +1056,19 @@ *at_sign = r; } } + + +void fill_attachment_name_buf(struct parser_state *state, char *buf){ + char *p = &buf[0]; + + for(; *p; p++){ + if(*p != ' ' && *p != '\t') break; + } + + int len = strlen(p); + + if(len + state->anamepos < SMALLBUFSIZE-2){ + memcpy(&(state->attachment_name_buf[state->anamepos]), p, len); + state->anamepos += len; + } +}