mirror of
				https://bitbucket.org/jsuto/piler.git
				synced 2025-11-04 03:42:27 +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:
		@@ -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){
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										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);
 | 
					   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;
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   for(; *s; s++){
 | 
					 | 
				
			||||||
      if(i<buflen-2){
 | 
					      if(i<buflen-2){
 | 
				
			||||||
         buf[i] = *s;
 | 
					         if(*(s+j) == 0){
 | 
				
			||||||
 | 
					            *nullbyte = 1;
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         buf[i] = *(s+j);
 | 
				
			||||||
         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;
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user