From 3e22fbfd7627c45cf26d921bcbf8053711cdf9d6 Mon Sep 17 00:00:00 2001 From: Janos SUTO Date: Sun, 4 Feb 2018 10:50:42 +0100 Subject: [PATCH] parser: fix multiline attachment name Signed-off-by: Janos SUTO --- src/defs.h | 3 +-- src/parser.c | 33 ++++++--------------------------- src/parser.h | 2 +- src/parser_utils.c | 13 +++++++------ unit_tests/check_parser_utils.c | 2 +- 5 files changed, 16 insertions(+), 37 deletions(-) diff --git a/src/defs.h b/src/defs.h index 0d7a11f5..d884814d 100644 --- a/src/defs.h +++ b/src/defs.h @@ -75,7 +75,7 @@ struct attachment { char type[TINYBUFSIZE]; char shorttype[TINYBUFSIZE]; char aname[TINYBUFSIZE]; - char filename[TINYBUFSIZE]; + char filename[SMALLBUFSIZE]; char internalname[TINYBUFSIZE]; char digest[2*DIGEST_LENGTH+1]; char dumped; @@ -185,7 +185,6 @@ struct parser_state { unsigned long n_body_token; unsigned long n_chain_token; - char filename[TINYBUFSIZE]; char type[TINYBUFSIZE]; char charset[TINYBUFSIZE]; diff --git a/src/parser.c b/src/parser.c index 39af6145..04eca126 100644 --- a/src/parser.c +++ b/src/parser.c @@ -163,7 +163,7 @@ void storno_attachment(struct parser_state *state){ memset(state->attachments[state->n_attachments].type, 0, TINYBUFSIZE); memset(state->attachments[state->n_attachments].shorttype, 0, TINYBUFSIZE); memset(state->attachments[state->n_attachments].aname, 0, TINYBUFSIZE); - memset(state->attachments[state->n_attachments].filename, 0, TINYBUFSIZE); + memset(state->attachments[state->n_attachments].filename, 0, SMALLBUFSIZE); memset(state->attachments[state->n_attachments].internalname, 0, TINYBUFSIZE); memset(state->attachments[state->n_attachments].digest, 0, 2*DIGEST_LENGTH+1); @@ -220,11 +220,6 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata if(state->is_header == 1) state->is_header = 0; state->is_1st_header = 0; - - if(state->anamepos > 0){ - extractNameFromHeaderLine(state->attachment_name_buf, "name", state->filename); - } - } @@ -271,10 +266,10 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata // this is a real attachment to dump, it doesn't have to be base64 encoded! - if(strlen(state->filename) > 4 && strlen(state->type) > 3 && state->n_attachments < MAX_ATTACHMENTS-1){ + if(state->attachment_name_buf[0] != 0 && strcasestr(state->attachment_name_buf, "name") && strlen(state->type) > 3 && state->n_attachments < MAX_ATTACHMENTS-1){ state->n_attachments++; - snprintf(state->attachments[state->n_attachments].filename, TINYBUFSIZE-1, "%s", state->filename); + extractNameFromHeaderLine(state->attachment_name_buf, "name", state->attachments[state->n_attachments].filename, SMALLBUFSIZE); snprintf(state->attachments[state->n_attachments].type, TINYBUFSIZE-1, "%s", state->type); snprintf(state->attachments[state->n_attachments].internalname, TINYBUFSIZE-1, "%s.a%d", sdata->ttmpfile, state->n_attachments); snprintf(state->attachments[state->n_attachments].aname, TINYBUFSIZE-1, "%s.a%d.bin", sdata->ttmpfile, state->n_attachments); @@ -284,7 +279,7 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata if(take_into_pieces == 1){ state->fd = open(state->attachments[state->n_attachments].internalname, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); - fixupEncodedHeaderLine(state->attachments[state->n_attachments].filename, TINYBUFSIZE); + fixupEncodedHeaderLine(state->attachments[state->n_attachments].filename, SMALLBUFSIZE); p = get_attachment_extractor_by_filename(state->attachments[state->n_attachments].filename); @@ -366,24 +361,10 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata } else if(strncasecmp(buf, "Content-Type:", strlen("Content-Type:")) == 0){ state->message_state = MSG_CONTENT_TYPE; - - if(state->anamepos > 0){ - extractNameFromHeaderLine(state->attachment_name_buf, "name", state->filename); - memset(state->attachment_name_buf, 0, SMALLBUFSIZE); - state->anamepos = 0; - } - } else if(strncasecmp(buf, "Content-Transfer-Encoding:", strlen("Content-Transfer-Encoding:")) == 0) state->message_state = MSG_CONTENT_TRANSFER_ENCODING; else if(strncasecmp(buf, "Content-Disposition:", strlen("Content-Disposition:")) == 0){ state->message_state = MSG_CONTENT_DISPOSITION; - - if(state->anamepos > 0){ - extractNameFromHeaderLine(state->attachment_name_buf, "name", state->filename); - memset(state->attachment_name_buf, 0, SMALLBUFSIZE); - state->anamepos = 0; - } - } else if(strncasecmp(buf, "To:", 3) == 0){ state->message_state = MSG_TO; @@ -556,13 +537,12 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata } - if(strcasestr(buf, "charset")) extractNameFromHeaderLine(buf, "charset", state->charset); + if(strcasestr(buf, "charset")) extractNameFromHeaderLine(buf, "charset", state->charset, TINYBUFSIZE); if(strcasestr(state->charset, "UTF-8")) state->utf8 = 1; } - if((state->message_state == MSG_CONTENT_TYPE || state->message_state == MSG_CONTENT_DISPOSITION) && strlen(state->filename) < 5){ - + if(state->message_state == MSG_CONTENT_TYPE){ p = &buf[0]; for(; *p; p++){ if(*p != ' ' && *p != '\t') break; @@ -631,7 +611,6 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata state->pushed_pointer = 0; - memset(state->filename, 0, TINYBUFSIZE); memset(state->type, 0, TINYBUFSIZE); snprintf(state->charset, TINYBUFSIZE-1, "unknown"); diff --git a/src/parser.h b/src/parser.h index b6565667..a8b4d184 100644 --- a/src/parser.h +++ b/src/parser.h @@ -28,7 +28,7 @@ int does_it_seem_like_an_email_address(char *email); void reassembleToken(char *p); void degenerateToken(unsigned char *p); void fixURL(char *buf, int buflen); -void extractNameFromHeaderLine(char *s, char *name, char *resultbuf); +void extractNameFromHeaderLine(char *s, char *name, char *resultbuf, int resultbuflen); char *determine_attachment_type(char *filename, char *type); char *get_attachment_extractor_by_filename(char *filename); void parse_reference(struct parser_state *state, char *s); diff --git a/src/parser_utils.c b/src/parser_utils.c index 1a41b72b..49ab3daa 100644 --- a/src/parser_utils.c +++ b/src/parser_utils.c @@ -50,7 +50,6 @@ void init_state(struct parser_state *state){ memset(state->miscbuf, 0, MAX_TOKEN_LEN); memset(state->qpbuf, 0, MAX_TOKEN_LEN); - memset(state->filename, 0, TINYBUFSIZE); memset(state->type, 0, TINYBUFSIZE); memset(state->attachment_name_buf, 0, SMALLBUFSIZE); @@ -81,7 +80,7 @@ void init_state(struct parser_state *state){ memset(state->attachments[i].type, 0, TINYBUFSIZE); memset(state->attachments[i].shorttype, 0, TINYBUFSIZE); memset(state->attachments[i].aname, 0, TINYBUFSIZE); - memset(state->attachments[i].filename, 0, TINYBUFSIZE); + memset(state->attachments[i].filename, 0, SMALLBUFSIZE); memset(state->attachments[i].internalname, 0, TINYBUFSIZE); memset(state->attachments[i].digest, 0, 2*DIGEST_LENGTH+1); } @@ -778,12 +777,14 @@ void fixURL(char *buf, int buflen){ } -void extractNameFromHeaderLine(char *s, char *name, char *resultbuf){ +void extractNameFromHeaderLine(char *s, char *name, char *resultbuf, int resultbuflen){ int extended=0; char buf[SMALLBUFSIZE], puf[SMALLBUFSIZE], *p, *q, *encoding; snprintf(buf, sizeof(buf)-1, "%s", s); + memset(resultbuf, 0, resultbuflen); + p = strstr(buf, name); if(p){ @@ -852,15 +853,15 @@ void extractNameFromHeaderLine(char *s, char *name, char *resultbuf){ decodeURL(p); if(strlen(encoding) > 2 && strcasecmp(encoding, "utf-8")) - utf8_encode(p, strlen(p), resultbuf, TINYBUFSIZE-1, encoding); + utf8_encode(p, strlen(p), resultbuf, resultbuflen-2, encoding); else - snprintf(resultbuf, TINYBUFSIZE-1, "%s", p); + snprintf(resultbuf, resultbuflen-2, "%s", p); } else { snprintf(puf, sizeof(puf)-1, "%s", p); fixupEncodedHeaderLine(puf, sizeof(puf)); - snprintf(resultbuf, TINYBUFSIZE-1, "%s", puf); + snprintf(resultbuf, resultbuflen-2, "%s", puf); } } diff --git a/unit_tests/check_parser_utils.c b/unit_tests/check_parser_utils.c index e20ec31e..4cc9e31a 100644 --- a/unit_tests/check_parser_utils.c +++ b/unit_tests/check_parser_utils.c @@ -106,7 +106,7 @@ static void test_extractNameFromHeaderLine(){ TEST_HEADER(); for(i=0; i