mirror of
https://bitbucket.org/jsuto/piler.git
synced 2024-11-08 04:01:58 +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 rcptto[MAX_RCPT_TO][SMALLBUFSIZE];
|
||||||
char buf[MAXBUFSIZE];
|
char buf[MAXBUFSIZE];
|
||||||
char remote_host[INET6_ADDRSTRLEN+1];
|
char remote_host[INET6_ADDRSTRLEN+1];
|
||||||
|
char nullbyte;
|
||||||
time_t lasttime;
|
time_t lasttime;
|
||||||
int protocol_state;
|
int protocol_state;
|
||||||
int slot;
|
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){
|
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;
|
uint64 count=0;
|
||||||
char *p, copybuf[2*BIGBUFSIZE+1], buf[BIGBUFSIZE], savedbuf[BIGBUFSIZE], puf[BIGBUFSIZE];
|
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));
|
memset(buf, 0, sizeof(buf));
|
||||||
n = fread(buf, 1, sizeof(buf)-1, stdin);
|
n = fread(buf, 1, sizeof(buf)-1, stdin);
|
||||||
|
|
||||||
|
int remaininglen = n;
|
||||||
|
|
||||||
if(savedlen > 0){
|
if(savedlen > 0){
|
||||||
memset(copybuf, 0, sizeof(copybuf));
|
memset(copybuf, 0, sizeof(copybuf));
|
||||||
|
|
||||||
memcpy(copybuf, savedbuf, savedlen);
|
memcpy(copybuf, savedbuf, savedlen);
|
||||||
memcpy(©buf[savedlen], buf, n);
|
memcpy(©buf[savedlen], buf, n);
|
||||||
|
|
||||||
|
remaininglen += savedlen;
|
||||||
|
|
||||||
savedlen = 0;
|
savedlen = 0;
|
||||||
memset(savedbuf, 0, sizeof(savedbuf));
|
memset(savedbuf, 0, sizeof(savedbuf));
|
||||||
|
|
||||||
@ -86,8 +90,9 @@ void import_from_pilerexport(struct session_data *sdata, struct data *data, stru
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
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;
|
p += puflen;
|
||||||
|
remaininglen -= puflen;
|
||||||
|
|
||||||
if(puflen > 0){
|
if(puflen > 0){
|
||||||
if(rc == OK){
|
if(rc == OK){
|
||||||
|
24
src/misc.c
24
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);
|
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)){
|
if(rename(session->ttmpfile, buf)){
|
||||||
syslog(LOG_PRIORITY, "ERROR: couldn't rename %s to %s (reason: %s)", session->ttmpfile, buf, strerror(errno));
|
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;
|
int i=0;
|
||||||
|
|
||||||
*rc = ERR;
|
*rc = ERR;
|
||||||
|
*nullbyte = 0;
|
||||||
|
|
||||||
memset(buf, 0, buflen);
|
memset(buf, 0, buflen);
|
||||||
|
|
||||||
if(s == NULL){
|
for(int j=0; j<slen; j++){
|
||||||
return i;
|
if(i<buflen-2){
|
||||||
|
if(*(s+j) == 0){
|
||||||
|
*nullbyte = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(; *s; s++){
|
buf[i] = *(s+j);
|
||||||
if(i<buflen-2){
|
|
||||||
buf[i] = *s;
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if(*s == c){
|
if(*(s+j) == c){
|
||||||
*rc = OK;
|
*rc = OK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else break;
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
@ -46,7 +46,7 @@ int create_and_bind(char *listen_addr, int listen_port);
|
|||||||
int can_i_write_directory(char *dir);
|
int can_i_write_directory(char *dir);
|
||||||
|
|
||||||
void move_email(struct smtp_session *session);
|
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);
|
int init_ssl_to_server(struct data *data);
|
||||||
|
|
||||||
|
@ -100,11 +100,15 @@ int pop3_download_email(struct data *data, int i){
|
|||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
while((n = recvtimeoutssl(data->net, buf, sizeof(buf))) > 0){
|
while((n = recvtimeoutssl(data->net, buf, sizeof(buf))) > 0){
|
||||||
|
int remaininglen = n;
|
||||||
|
|
||||||
if(savedlen){
|
if(savedlen){
|
||||||
memset(copybuf, 0, sizeof(copybuf));
|
memset(copybuf, 0, sizeof(copybuf));
|
||||||
memcpy(copybuf, savedbuf, savedlen);
|
memcpy(copybuf, savedbuf, savedlen);
|
||||||
memcpy(©buf[savedlen], buf, n);
|
memcpy(©buf[savedlen], buf, n);
|
||||||
|
|
||||||
|
remaininglen += savedlen;
|
||||||
|
|
||||||
savedlen = 0;
|
savedlen = 0;
|
||||||
memset(savedbuf, 0, sizeof(savedbuf));
|
memset(savedbuf, 0, sizeof(savedbuf));
|
||||||
|
|
||||||
@ -115,10 +119,13 @@ int pop3_download_email(struct data *data, int i){
|
|||||||
|
|
||||||
int puflen=0;
|
int puflen=0;
|
||||||
int rc=OK;
|
int rc=OK;
|
||||||
|
int nullbyte=0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char puf[MAXBUFSIZE];
|
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++;
|
nlines++;
|
||||||
|
|
||||||
if(nlines == 1){
|
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.ctx = NULL;
|
||||||
session->net.ssl = NULL;
|
session->net.ssl = NULL;
|
||||||
|
|
||||||
|
session->nullbyte = 0;
|
||||||
session->last_data_char = 0;
|
session->last_data_char = 0;
|
||||||
|
|
||||||
session->fd = -1;
|
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){
|
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];
|
char *p, copybuf[BIGBUFSIZE+MAXBUFSIZE], puf[MAXBUFSIZE];
|
||||||
|
|
||||||
// if there's something in the saved buffer, then let's merge them
|
// if there's something in the saved buffer, then let's merge them
|
||||||
|
|
||||||
|
int remaininglen = readlen + session->buflen;
|
||||||
|
|
||||||
if(session->buflen > 0){
|
if(session->buflen > 0){
|
||||||
memset(copybuf, 0, sizeof(copybuf));
|
memset(copybuf, 0, sizeof(copybuf));
|
||||||
|
|
||||||
@ -183,8 +186,13 @@ void handle_data(struct smtp_session *session, char *readbuf, int readlen, struc
|
|||||||
|
|
||||||
|
|
||||||
do {
|
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;
|
p += puflen;
|
||||||
|
remaininglen -= puflen;
|
||||||
|
|
||||||
|
if(nullbyte){
|
||||||
|
session->nullbyte = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// complete line: rc == OK and puflen > 0
|
// complete line: rc == OK and puflen > 0
|
||||||
// incomplete line with something in the buffer: rc == ERR 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
|
// Save incomplete line to buffer
|
||||||
if(rc == ERR){
|
if(rc == ERR){
|
||||||
snprintf(session->buf, sizeof(session->buf)-1, "%s", puf);
|
memcpy(session->buf, puf, puflen);
|
||||||
session->buflen = puflen;
|
session->buflen = puflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user