mirror of
https://bitbucket.org/jsuto/piler.git
synced 2025-06-13 12:27:03 +02:00
added attachment support
This commit is contained in:
@ -30,7 +30,7 @@
|
||||
#define SESSION_TIMEOUT 420
|
||||
#define MAXBUFSIZE 8192
|
||||
#define SMALLBUFSIZE 512
|
||||
#define BIGBUFSIZE 65536
|
||||
#define BIGBUFSIZE 131072
|
||||
#define REALLYBIGBUFSIZE 524288
|
||||
#define TINYBUFSIZE 128
|
||||
#define MAXVAL 256
|
||||
|
@ -80,8 +80,38 @@ void sanitiseBase64(char *s){
|
||||
}
|
||||
|
||||
|
||||
inline void pack_4_into_3(char *s, char *s2){
|
||||
int j, n[4], k1, k2;
|
||||
|
||||
memset(s2, 0, 3);
|
||||
|
||||
if(strlen(s) != 4) return;
|
||||
|
||||
for(j=0; j<4; j++){
|
||||
k1 = s[j];
|
||||
n[j] = b64[k1];
|
||||
}
|
||||
|
||||
k1 = n[0]; k1 = k1 << 2;
|
||||
k2 = n[1]; k2 = k2 >> 4;
|
||||
|
||||
s2[0] = k1 | k2;
|
||||
|
||||
k1 = (n[1] & 0x0F) << 4;
|
||||
k2 = n[2]; k2 = k2 >> 2;
|
||||
|
||||
s2[1] = k1 | k2;
|
||||
|
||||
k1 = n[2] << 6;
|
||||
k2 = n[3] >> 0;
|
||||
|
||||
|
||||
s2[2] = k1 | k2;
|
||||
}
|
||||
|
||||
|
||||
int decodeBase64(char *p){
|
||||
int i, j, n[4], k1, k2, len=0;
|
||||
int i, len=0;
|
||||
char s[5], s2[3], puf[MAXBUFSIZE];
|
||||
|
||||
if(strlen(p) < 4 || strlen(p) > MAXBUFSIZE/2)
|
||||
@ -98,29 +128,7 @@ int decodeBase64(char *p){
|
||||
if(len + 3 > sizeof(puf)-1) break;
|
||||
|
||||
if(strlen(s) == 4){
|
||||
memset(s2, 0, 3);
|
||||
|
||||
for(j=0; j<4; j++){
|
||||
k1 = s[j];
|
||||
n[j] = b64[k1];
|
||||
}
|
||||
|
||||
k1 = n[0]; k1 = k1 << 2;
|
||||
k2 = n[1]; k2 = k2 >> 4;
|
||||
|
||||
s2[0] = k1 | k2;
|
||||
|
||||
k1 = (n[1] & 0x0F) << 4;
|
||||
k2 = n[2]; k2 = k2 >> 2;
|
||||
|
||||
s2[1] = k1 | k2;
|
||||
|
||||
k1 = n[2] << 6;
|
||||
k2 = n[3] >> 0;
|
||||
|
||||
|
||||
s2[2] = k1 | k2;
|
||||
|
||||
pack_4_into_3(s, s2);
|
||||
memcpy(puf+len, s2, 3);
|
||||
|
||||
len += 3;
|
||||
@ -133,7 +141,36 @@ int decodeBase64(char *p){
|
||||
snprintf(p, MAXBUFSIZE-1, "%s", puf);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
int decode_base64_to_buffer(char *p, int plen, unsigned char *b, int blen){
|
||||
int i, len=0;
|
||||
char s[5], s2[3];
|
||||
|
||||
if(plen < 4 || plen > blen)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<plen; i++){
|
||||
memcpy(s, p+i, 4);
|
||||
s[4] = '\0';
|
||||
|
||||
i += 3;
|
||||
|
||||
/* safety check against abnormally long lines */
|
||||
|
||||
if(len + 3 > blen-1) break;
|
||||
|
||||
if(strlen(s) == 4){
|
||||
pack_4_into_3(s, s2);
|
||||
memcpy(b+len, s2, 3);
|
||||
|
||||
len += 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,6 +9,7 @@ void base64_encode(unsigned char *in, int inlen, char *out, int outlen);
|
||||
|
||||
void sanitiseBase64(char *s);
|
||||
int decodeBase64(char *p);
|
||||
int decode_base64_to_buffer(char *p, int plen, unsigned char *b, int blen);
|
||||
void decodeQP(char *p);
|
||||
void decodeHTML(char *p);
|
||||
void decodeURL(char *p);
|
||||
|
@ -68,9 +68,11 @@ struct child {
|
||||
struct attachment {
|
||||
int size;
|
||||
char type[TINYBUFSIZE];
|
||||
char aname[TINYBUFSIZE];
|
||||
char filename[TINYBUFSIZE];
|
||||
char internalname[TINYBUFSIZE];
|
||||
char digest[2*DIGEST_LENGTH+1];
|
||||
char dumped;
|
||||
};
|
||||
|
||||
|
||||
@ -125,6 +127,7 @@ struct _state {
|
||||
int skip_html;
|
||||
int has_to_dump;
|
||||
int fd;
|
||||
int b64fd;
|
||||
int mfd;
|
||||
int octetstream;
|
||||
int realbinary;
|
||||
|
33
src/extract.c
Normal file
33
src/extract.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
void extract_pdf(struct session_data *sdata, struct _state *state, char *filename, struct __config *cfg){
|
||||
int len;
|
||||
char buf[MAXBUFSIZE];
|
||||
FILE *f;
|
||||
|
||||
snprintf(buf, sizeof(buf)-1, "%s -enc UTF-8 %s -", HAVE_PDFTOTEXT, filename);
|
||||
|
||||
f = popen(buf, "r");
|
||||
if(f){
|
||||
while(fgets(buf, sizeof(buf)-1, f)){
|
||||
len = strlen(buf);
|
||||
|
||||
if(state->bodylen < BIGBUFSIZE-len-1){
|
||||
memcpy(&(state->b_body[state->bodylen]), buf, len);
|
||||
state->bodylen += len;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
else syslog(LOG_PRIORITY, "%s: popen(): %s", sdata->ttmpfile, buf);
|
||||
|
||||
}
|
||||
|
||||
|
7
src/extract.h
Normal file
7
src/extract.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef _EXTRACT_H
|
||||
#define _EXTRACT_H
|
||||
|
||||
void extract_pdf(struct session_data *sdata, struct _state *state, char *filename, struct __config *cfg);
|
||||
|
||||
|
||||
#endif /* _EXTRACT_H */
|
54
src/parser.c
54
src/parser.c
@ -129,6 +129,19 @@ void post_parse(struct session_data *sdata, struct _state *state, struct __confi
|
||||
len = strlen(p);
|
||||
|
||||
if(strlen(sdata->attachments) < SMALLBUFSIZE-len-1 && !strstr(sdata->attachments, p)) memcpy(&(sdata->attachments[strlen(sdata->attachments)]), p, len);
|
||||
|
||||
if(state->attachments[i].dumped == 1){
|
||||
|
||||
#ifdef HAVE_PDFTOTEXT
|
||||
if(
|
||||
strcmp(p, "pdf,") == 0 ||
|
||||
(strcmp(p, "other,") == 0 && strcasestr(state->attachments[i].filename, ".pdf"))
|
||||
) extract_pdf(sdata, state, state->attachments[i].aname, cfg);
|
||||
#endif
|
||||
|
||||
unlink(state->attachments[i].aname);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -138,18 +151,13 @@ void post_parse(struct session_data *sdata, struct _state *state, struct __confi
|
||||
else snprintf(state->message_id, SMALLBUFSIZE-1, "null");
|
||||
}
|
||||
|
||||
//len = strlen(state->b_from);
|
||||
//if(state->b_from[len-1] == ' ') state->b_from[len-1] = '\0';
|
||||
|
||||
//len = strlen(state->b_to);
|
||||
//if(state->b_to[len-1] == ' ') state->b_to[len-1] = '\0';
|
||||
|
||||
}
|
||||
|
||||
|
||||
int parse_line(char *buf, struct _state *state, struct session_data *sdata, int take_into_pieces, char *writebuffer, int writebuffersize, char *abuffer, int abuffersize, struct __config *cfg){
|
||||
char *p, *q, puf[SMALLBUFSIZE];
|
||||
int x, n, len, writelen, b64_len, boundary_line=0;
|
||||
unsigned char b64buffer[MAXBUFSIZE];
|
||||
int x, n, n64, len, writelen, b64_len, boundary_line=0;
|
||||
|
||||
if(cfg->debug == 1) printf("line: %s", buf);
|
||||
|
||||
@ -192,7 +200,15 @@ int parse_line(char *buf, struct _state *state, struct session_data *sdata, int
|
||||
if(state->message_state == MSG_BODY && state->fd != -1 && is_item_on_string(state->boundaries, buf) == 0){
|
||||
//n = write(state->fd, buf, len); // WRITE
|
||||
if(len + state->abufpos > abuffersize-1){
|
||||
n = write(state->fd, abuffer, state->abufpos); state->abufpos = 0; memset(abuffer, 0, abuffersize);
|
||||
n = write(state->fd, abuffer, state->abufpos);
|
||||
|
||||
if(state->b64fd != -1){
|
||||
abuffer[state->abufpos] = '\0';
|
||||
n64 = base64_decode_attachment_buffer(abuffer, state->abufpos, &b64buffer[0], sizeof(b64buffer));
|
||||
n64 = write(state->b64fd, b64buffer, n64);
|
||||
}
|
||||
|
||||
state->abufpos = 0; memset(abuffer, 0, abuffersize);
|
||||
}
|
||||
memcpy(abuffer+state->abufpos, buf, len); state->abufpos += len;
|
||||
|
||||
@ -222,14 +238,24 @@ int parse_line(char *buf, struct _state *state, struct session_data *sdata, int
|
||||
snprintf(state->attachments[state->n_attachments].filename, TINYBUFSIZE-1, "%s", state->filename);
|
||||
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);
|
||||
|
||||
//printf("DUMP FILE: %s\n", state->attachments[state->n_attachments].internalname);
|
||||
|
||||
if(take_into_pieces == 1){
|
||||
state->fd = open(state->attachments[state->n_attachments].internalname, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
|
||||
|
||||
p = determine_attachment_type(state->attachments[state->n_attachments].filename, state->attachments[state->n_attachments].type);
|
||||
|
||||
if(strcmp("pdf,", p) == 0 || strcmp("other,", p) == 0){
|
||||
state->b64fd = open(state->attachments[state->n_attachments].aname, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
|
||||
state->attachments[state->n_attachments].dumped = 1;
|
||||
}
|
||||
|
||||
if(state->fd == -1){
|
||||
|
||||
state->attachments[state->n_attachments].size = 0;
|
||||
state->attachments[state->n_attachments].dumped = 0;
|
||||
memset(state->attachments[state->n_attachments].type, 0, TINYBUFSIZE);
|
||||
memset(state->attachments[state->n_attachments].filename, 0, TINYBUFSIZE);
|
||||
memset(state->attachments[state->n_attachments].internalname, 0, TINYBUFSIZE);
|
||||
@ -425,11 +451,21 @@ int parse_line(char *buf, struct _state *state, struct session_data *sdata, int
|
||||
if(state->has_to_dump == 1){
|
||||
if(take_into_pieces == 1 && state->fd != -1){
|
||||
if(state->abufpos > 0){
|
||||
n = write(state->fd, abuffer, state->abufpos); state->abufpos = 0; memset(abuffer, 0, abuffersize);
|
||||
n = write(state->fd, abuffer, state->abufpos);
|
||||
|
||||
if(state->b64fd != -1){
|
||||
abuffer[state->abufpos] = '\0';
|
||||
n64 = base64_decode_attachment_buffer(abuffer, state->abufpos, &b64buffer[0], sizeof(b64buffer));
|
||||
n64 = write(state->b64fd, b64buffer, n64);
|
||||
}
|
||||
|
||||
state->abufpos = 0; memset(abuffer, 0, abuffersize);
|
||||
}
|
||||
close(state->fd);
|
||||
close(state->b64fd);
|
||||
}
|
||||
state->fd = -1;
|
||||
state->b64fd = -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
struct _state parse_message(struct session_data *sdata, int take_into_pieces, struct __config *cfg);
|
||||
void post_parse(struct session_data *sdata, struct _state *state, struct __config *cfg);
|
||||
//int parse_line(char *buf, struct _state *state, struct session_data *sdata, int take_into_pieces, struct __config *cfg);
|
||||
int parse_line(char *buf, struct _state *state, struct session_data *sdata, int take_into_pieces, char *writebuffer, int writebuffersize, char *abuffer, int abuffersize, struct __config *cfg);
|
||||
|
||||
void init_state(struct _state *state);
|
||||
@ -33,5 +32,6 @@ void fixURL(char *url);
|
||||
int extractNameFromHeaderLine(char *s, char *name, char *resultbuf);
|
||||
char *determine_attachment_type(char *filename, char *type);
|
||||
void parse_reference(struct _state *state, char *s);
|
||||
int base64_decode_attachment_buffer(char *p, int plen, unsigned char *b, int blen);
|
||||
|
||||
#endif /* _PARSER_H */
|
||||
|
@ -56,6 +56,7 @@ void init_state(struct _state *state){
|
||||
|
||||
state->has_to_dump = 0;
|
||||
state->fd = -1;
|
||||
state->b64fd = -1;
|
||||
state->mfd = -1;
|
||||
state->realbinary = 0;
|
||||
state->octetstream = 0;
|
||||
@ -73,7 +74,9 @@ void init_state(struct _state *state){
|
||||
|
||||
for(i=0; i<MAX_ATTACHMENTS; i++){
|
||||
state->attachments[i].size = 0;
|
||||
state->attachments[i].dumped = 0;
|
||||
memset(state->attachments[i].type, 0, TINYBUFSIZE);
|
||||
memset(state->attachments[i].aname, 0, TINYBUFSIZE);
|
||||
memset(state->attachments[i].filename, 0, TINYBUFSIZE);
|
||||
memset(state->attachments[i].internalname, 0, TINYBUFSIZE);
|
||||
memset(state->attachments[i].digest, 0, 2*DIGEST_LENGTH+1);
|
||||
@ -748,3 +751,17 @@ void parse_reference(struct _state *state, char *s){
|
||||
|
||||
}
|
||||
|
||||
|
||||
int base64_decode_attachment_buffer(char *p, int plen, unsigned char *b, int blen){
|
||||
int b64len=0;
|
||||
char puf[2*SMALLBUFSIZE];
|
||||
|
||||
do {
|
||||
p = split_str(p, "\n", puf, sizeof(puf)-1);
|
||||
trimBuffer(puf);
|
||||
b64len += decode_base64_to_buffer(puf, strlen(puf), b+b64len, blen);
|
||||
} while(p);
|
||||
|
||||
return b64len;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <decoder.h>
|
||||
#include <list.h>
|
||||
#include <rules.h>
|
||||
#include <extract.h>
|
||||
#include <defs.h>
|
||||
#include <tai.h>
|
||||
#include <sig.h>
|
||||
|
Reference in New Issue
Block a user