parser: fix multiline attachment name

Signed-off-by: Janos SUTO <sj@acts.hu>
This commit is contained in:
Janos SUTO 2018-02-04 10:50:42 +01:00
parent 5830bf5ef7
commit 3e22fbfd76
5 changed files with 16 additions and 37 deletions

View File

@ -75,7 +75,7 @@ struct attachment {
char type[TINYBUFSIZE]; char type[TINYBUFSIZE];
char shorttype[TINYBUFSIZE]; char shorttype[TINYBUFSIZE];
char aname[TINYBUFSIZE]; char aname[TINYBUFSIZE];
char filename[TINYBUFSIZE]; char filename[SMALLBUFSIZE];
char internalname[TINYBUFSIZE]; char internalname[TINYBUFSIZE];
char digest[2*DIGEST_LENGTH+1]; char digest[2*DIGEST_LENGTH+1];
char dumped; char dumped;
@ -185,7 +185,6 @@ struct parser_state {
unsigned long n_body_token; unsigned long n_body_token;
unsigned long n_chain_token; unsigned long n_chain_token;
char filename[TINYBUFSIZE];
char type[TINYBUFSIZE]; char type[TINYBUFSIZE];
char charset[TINYBUFSIZE]; char charset[TINYBUFSIZE];

View File

@ -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].type, 0, TINYBUFSIZE);
memset(state->attachments[state->n_attachments].shorttype, 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].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].internalname, 0, TINYBUFSIZE);
memset(state->attachments[state->n_attachments].digest, 0, 2*DIGEST_LENGTH+1); 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; if(state->is_header == 1) state->is_header = 0;
state->is_1st_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! // 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++; 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].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].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); 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){ if(take_into_pieces == 1){
state->fd = open(state->attachments[state->n_attachments].internalname, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); 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); 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){ else if(strncasecmp(buf, "Content-Type:", strlen("Content-Type:")) == 0){
state->message_state = MSG_CONTENT_TYPE; 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-Transfer-Encoding:", strlen("Content-Transfer-Encoding:")) == 0) state->message_state = MSG_CONTENT_TRANSFER_ENCODING;
else if(strncasecmp(buf, "Content-Disposition:", strlen("Content-Disposition:")) == 0){ else if(strncasecmp(buf, "Content-Disposition:", strlen("Content-Disposition:")) == 0){
state->message_state = MSG_CONTENT_DISPOSITION; 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){ else if(strncasecmp(buf, "To:", 3) == 0){
state->message_state = MSG_TO; 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(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]; p = &buf[0];
for(; *p; p++){ for(; *p; p++){
if(*p != ' ' && *p != '\t') break; 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; state->pushed_pointer = 0;
memset(state->filename, 0, TINYBUFSIZE);
memset(state->type, 0, TINYBUFSIZE); memset(state->type, 0, TINYBUFSIZE);
snprintf(state->charset, TINYBUFSIZE-1, "unknown"); snprintf(state->charset, TINYBUFSIZE-1, "unknown");

View File

@ -28,7 +28,7 @@ int does_it_seem_like_an_email_address(char *email);
void reassembleToken(char *p); void reassembleToken(char *p);
void degenerateToken(unsigned char *p); void degenerateToken(unsigned char *p);
void fixURL(char *buf, int buflen); 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 *determine_attachment_type(char *filename, char *type);
char *get_attachment_extractor_by_filename(char *filename); char *get_attachment_extractor_by_filename(char *filename);
void parse_reference(struct parser_state *state, char *s); void parse_reference(struct parser_state *state, char *s);

View File

@ -50,7 +50,6 @@ void init_state(struct parser_state *state){
memset(state->miscbuf, 0, MAX_TOKEN_LEN); memset(state->miscbuf, 0, MAX_TOKEN_LEN);
memset(state->qpbuf, 0, MAX_TOKEN_LEN); memset(state->qpbuf, 0, MAX_TOKEN_LEN);
memset(state->filename, 0, TINYBUFSIZE);
memset(state->type, 0, TINYBUFSIZE); memset(state->type, 0, TINYBUFSIZE);
memset(state->attachment_name_buf, 0, SMALLBUFSIZE); 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].type, 0, TINYBUFSIZE);
memset(state->attachments[i].shorttype, 0, TINYBUFSIZE); memset(state->attachments[i].shorttype, 0, TINYBUFSIZE);
memset(state->attachments[i].aname, 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].internalname, 0, TINYBUFSIZE);
memset(state->attachments[i].digest, 0, 2*DIGEST_LENGTH+1); 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; int extended=0;
char buf[SMALLBUFSIZE], puf[SMALLBUFSIZE], *p, *q, *encoding; char buf[SMALLBUFSIZE], puf[SMALLBUFSIZE], *p, *q, *encoding;
snprintf(buf, sizeof(buf)-1, "%s", s); snprintf(buf, sizeof(buf)-1, "%s", s);
memset(resultbuf, 0, resultbuflen);
p = strstr(buf, name); p = strstr(buf, name);
if(p){ if(p){
@ -852,15 +853,15 @@ void extractNameFromHeaderLine(char *s, char *name, char *resultbuf){
decodeURL(p); decodeURL(p);
if(strlen(encoding) > 2 && strcasecmp(encoding, "utf-8")) 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 else
snprintf(resultbuf, TINYBUFSIZE-1, "%s", p); snprintf(resultbuf, resultbuflen-2, "%s", p);
} }
else { else {
snprintf(puf, sizeof(puf)-1, "%s", p); snprintf(puf, sizeof(puf)-1, "%s", p);
fixupEncodedHeaderLine(puf, sizeof(puf)); fixupEncodedHeaderLine(puf, sizeof(puf));
snprintf(resultbuf, TINYBUFSIZE-1, "%s", puf); snprintf(resultbuf, resultbuflen-2, "%s", puf);
} }
} }

View File

@ -106,7 +106,7 @@ static void test_extractNameFromHeaderLine(){
TEST_HEADER(); TEST_HEADER();
for(i=0; i<sizeof(name_from_header_test)/sizeof(struct name_from_header_test); i++){ for(i=0; i<sizeof(name_from_header_test)/sizeof(struct name_from_header_test); i++){
extractNameFromHeaderLine(name_from_header_test[i].line, name_from_header_test[i].token, resultbuf); extractNameFromHeaderLine(name_from_header_test[i].line, name_from_header_test[i].token, resultbuf, SMALLBUFSIZE);
ASSERT(strcmp(resultbuf, name_from_header_test[i].expected_result) == 0, name_from_header_test[i].expected_result); ASSERT(strcmp(resultbuf, name_from_header_test[i].expected_result) == 0, name_from_header_test[i].expected_result);
} }