mirror of
https://bitbucket.org/jsuto/piler.git
synced 2024-11-07 22:51:59 +01:00
Fixed piler-smtp to properly handle emails with NUL byte(s)
Signed-off-by: Janos SUTO <sj@acts.hu>
This commit is contained in:
parent
307a84b12b
commit
e1ea14374a
@ -402,6 +402,7 @@ struct smtp_session {
|
||||
char rcptto[MAX_RCPT_TO][SMALLBUFSIZE];
|
||||
char buf[MAXBUFSIZE];
|
||||
char remote_host[INET6_ADDRSTRLEN+1];
|
||||
char nullbyte;
|
||||
time_t lasttime;
|
||||
int protocol_state;
|
||||
int slot;
|
||||
|
@ -58,7 +58,7 @@ void process_buffer(char *buf, int buflen, uint64 *count, struct session_data *s
|
||||
|
||||
|
||||
void import_from_pilerexport(struct session_data *sdata, struct data *data, struct config *cfg){
|
||||
int n, rc, savedlen=0, puflen;
|
||||
int n, rc, nullbyte, savedlen=0, puflen;
|
||||
uint64 count=0;
|
||||
char *p, copybuf[2*BIGBUFSIZE+1], buf[BIGBUFSIZE], savedbuf[BIGBUFSIZE], puf[BIGBUFSIZE];
|
||||
|
||||
@ -70,12 +70,16 @@ void import_from_pilerexport(struct session_data *sdata, struct data *data, stru
|
||||
memset(buf, 0, sizeof(buf));
|
||||
n = fread(buf, 1, sizeof(buf)-1, stdin);
|
||||
|
||||
int remaininglen = n;
|
||||
|
||||
if(savedlen > 0){
|
||||
memset(copybuf, 0, sizeof(copybuf));
|
||||
|
||||
memcpy(copybuf, savedbuf, savedlen);
|
||||
memcpy(©buf[savedlen], buf, n);
|
||||
|
||||
remaininglen += savedlen;
|
||||
|
||||
savedlen = 0;
|
||||
memset(savedbuf, 0, sizeof(savedbuf));
|
||||
|
||||
@ -86,8 +90,9 @@ void import_from_pilerexport(struct session_data *sdata, struct data *data, stru
|
||||
}
|
||||
|
||||
do {
|
||||
puflen = read_one_line(p, '\n', puf, sizeof(puf), &rc);
|
||||
puflen = read_one_line(p, remaininglen, '\n', puf, sizeof(puf), &rc, &nullbyte);
|
||||
p += puflen;
|
||||
remaininglen -= puflen;
|
||||
|
||||
if(puflen > 0){
|
||||
if(rc == OK){
|
||||
|
26
src/misc.c
26
src/misc.c
@ -652,34 +652,42 @@ void move_email(struct smtp_session *session){
|
||||
|
||||
snprintf(buf, sizeof(buf)-1, "%d/%s", session->ttmpfile[0] % session->cfg->number_of_worker_processes, session->ttmpfile);
|
||||
|
||||
if(session->nullbyte){
|
||||
snprintf(buf, sizeof(buf)-1, "%s/%s", ERROR_DIR, session->ttmpfile);
|
||||
syslog(LOG_PRIORITY, "ERROR: %s contains an invalid NUL-byte, moving it to %s", session->ttmpfile, ERROR_DIR);
|
||||
}
|
||||
|
||||
if(rename(session->ttmpfile, buf)){
|
||||
syslog(LOG_PRIORITY, "ERROR: couldn't rename %s to %s (reason: %s)", session->ttmpfile, buf, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int read_one_line(char *s, int c, char *buf, int buflen, int *rc){
|
||||
int read_one_line(char *s, int slen, int c, char *buf, int buflen, int *rc, int *nullbyte){
|
||||
int i=0;
|
||||
|
||||
*rc = ERR;
|
||||
*nullbyte = 0;
|
||||
|
||||
memset(buf, 0, buflen);
|
||||
|
||||
if(s == NULL){
|
||||
return i;
|
||||
}
|
||||
|
||||
for(; *s; s++){
|
||||
for(int j=0; j<slen; j++){
|
||||
if(i<buflen-2){
|
||||
buf[i] = *s;
|
||||
if(*(s+j) == 0){
|
||||
*nullbyte = 1;
|
||||
}
|
||||
|
||||
buf[i] = *(s+j);
|
||||
i++;
|
||||
|
||||
if(*s == c){
|
||||
if(*(s+j) == c){
|
||||
*rc = OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else break;
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
|
@ -46,7 +46,7 @@ int create_and_bind(char *listen_addr, int listen_port);
|
||||
int can_i_write_directory(char *dir);
|
||||
|
||||
void move_email(struct smtp_session *session);
|
||||
int read_one_line(char *s, int c, char *buf, int buflen, int *rc);
|
||||
int read_one_line(char *s, int slen, int c, char *buf, int buflen, int *rc, int *nullbyte);
|
||||
|
||||
int init_ssl_to_server(struct data *data);
|
||||
|
||||
|
@ -100,11 +100,15 @@ int pop3_download_email(struct data *data, int i){
|
||||
int n = 0;
|
||||
|
||||
while((n = recvtimeoutssl(data->net, buf, sizeof(buf))) > 0){
|
||||
int remaininglen = n;
|
||||
|
||||
if(savedlen){
|
||||
memset(copybuf, 0, sizeof(copybuf));
|
||||
memcpy(copybuf, savedbuf, savedlen);
|
||||
memcpy(©buf[savedlen], buf, n);
|
||||
|
||||
remaininglen += savedlen;
|
||||
|
||||
savedlen = 0;
|
||||
memset(savedbuf, 0, sizeof(savedbuf));
|
||||
|
||||
@ -115,10 +119,13 @@ int pop3_download_email(struct data *data, int i){
|
||||
|
||||
int puflen=0;
|
||||
int rc=OK;
|
||||
int nullbyte=0;
|
||||
|
||||
do {
|
||||
char puf[MAXBUFSIZE];
|
||||
|
||||
puflen = read_one_line(p, '\n', puf, sizeof(puf)-1, &rc);
|
||||
puflen = read_one_line(p, remaininglen, '\n', puf, sizeof(puf)-1, &rc, &nullbyte);
|
||||
remaininglen -= puflen;
|
||||
nlines++;
|
||||
|
||||
if(nlines == 1){
|
||||
|
@ -99,6 +99,7 @@ void init_smtp_session(struct smtp_session *session, int slot, int sd, char *cli
|
||||
session->net.ctx = NULL;
|
||||
session->net.ssl = NULL;
|
||||
|
||||
session->nullbyte = 0;
|
||||
session->last_data_char = 0;
|
||||
|
||||
session->fd = -1;
|
||||
@ -160,11 +161,13 @@ void tear_down_session(struct smtp_session **sessions, int slot, int *num_connec
|
||||
|
||||
|
||||
void handle_data(struct smtp_session *session, char *readbuf, int readlen, struct config *cfg){
|
||||
int puflen, rc;
|
||||
int puflen, rc, nullbyte;
|
||||
char *p, copybuf[BIGBUFSIZE+MAXBUFSIZE], puf[MAXBUFSIZE];
|
||||
|
||||
// if there's something in the saved buffer, then let's merge them
|
||||
|
||||
int remaininglen = readlen + session->buflen;
|
||||
|
||||
if(session->buflen > 0){
|
||||
memset(copybuf, 0, sizeof(copybuf));
|
||||
|
||||
@ -183,8 +186,13 @@ void handle_data(struct smtp_session *session, char *readbuf, int readlen, struc
|
||||
|
||||
|
||||
do {
|
||||
puflen = read_one_line(p, '\n', puf, sizeof(puf)-1, &rc);
|
||||
puflen = read_one_line(p, remaininglen, '\n', puf, sizeof(puf)-1, &rc, &nullbyte);
|
||||
p += puflen;
|
||||
remaininglen -= puflen;
|
||||
|
||||
if(nullbyte){
|
||||
session->nullbyte = 1;
|
||||
}
|
||||
|
||||
// complete line: rc == OK and puflen > 0
|
||||
// incomplete line with something in the buffer: rc == ERR and puflen > 0
|
||||
@ -195,7 +203,7 @@ void handle_data(struct smtp_session *session, char *readbuf, int readlen, struc
|
||||
|
||||
// Save incomplete line to buffer
|
||||
if(rc == ERR){
|
||||
snprintf(session->buf, sizeof(session->buf)-1, "%s", puf);
|
||||
memcpy(session->buf, puf, puflen);
|
||||
session->buflen = puflen;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user