Mail body isolation

Signed-off-by: Tyrolyean <tyrolyean@tyrolyean.net>
This commit is contained in:
Tyrolyean 2020-04-26 21:57:43 +02:00
parent f0a93c5bc2
commit f8f513145d
No known key found for this signature in database
GPG key ID: 81EC9BAC5E9667C6
3 changed files with 119 additions and 5 deletions

View file

@ -19,7 +19,9 @@
#define DETECT_H
#include <stdbool.h>
#include <stddef.h>
bool detect_pgp(const char* message);
char* detect_start_of_body(char* message);
char* detect_end_of_body(char* message);
#endif /* DETECT_H */

View file

@ -16,9 +16,55 @@
*/
#include "detect.h"
#include <stddef.h>
#define _GNU_SOURCE
#include <string.h>
bool detect_pgp(const char* message){
return false;
}
/* If body hasn't started yet, it returns NULL, if it has started, it returns
* the pointer to the beginning of the newline.
*/
char* detect_start_of_body(char* message){
const char* data = "DATA";
char* data_cmd = strcasestr(message, data);
for(;data_cmd != NULL; data_cmd = strcasestr(data_cmd+1, data)){
if(data_cmd == NULL){
return NULL;
}
if(data_cmd == message){
/* You don't start an smtp conversation with data eh? */
return NULL;
}
char before = data_cmd[-1];
char after = data_cmd[strlen(data)+1];
if(before == '\n' || after == '\r'){
/* Find the end of that line, otherwise fail... */
for(size_t i = 0; data_cmd[i] != '\0'; i++){
if(data_cmd[i] == '\n'){
return data_cmd+i+1;
}
}
}
}
return NULL;
}
char* detect_end_of_body(char* message){
const char* data = "\r\n.\r\n";
return strstr(message, data);
}

View file

@ -9,6 +9,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sysexits.h>
#include <unistd.h>
#include <sys/stat.h>
@ -24,6 +25,7 @@
#include "version.h"
#include "config.h"
#include "attach.h"
#include "detect.h"
/*
* error - wrapper for perror
@ -63,7 +65,7 @@ void* client_handle_async(void* params){
}
int n; /* message byte size */
char buf[1024];
char buf[10];
struct pollfd fds[2];
memset(fds, 0 , sizeof(fds));
fds[0].fd = cli->fd;
@ -73,6 +75,13 @@ void* client_handle_async(void* params){
int timeout = (10 * 1000); /* 10 seconds */
char * input_buffer = malloc(1);
input_buffer[0]=0;
size_t in_len = 1;
bool in_body = false, after_body = false;
char* body_p = NULL;
size_t body_offs = 0;
while(poll(fds, 2, timeout) > 0){
for(size_t i = 0; i < 2; i++){
if(!(fds[i].revents & POLLIN)){
@ -84,18 +93,75 @@ void* client_handle_async(void* params){
if (n <= 0) {
goto closeup;
}
printf("%lu: %s\n", i, buf);
write((fds[!i].fd), buf, n);
if(i==0 && !in_body){
/* As long as we are outside the real mail body
* we can basically passthrough the commands
*/
in_len += n;
input_buffer = realloc(input_buffer, in_len);
strncat(input_buffer,buf, n);
body_p = detect_start_of_body(input_buffer);
if(body_p != NULL){
/* We reached the beginning of the body
* now! */
body_offs = body_p - input_buffer;
in_body = true;
write((fds[!i].fd),
input_buffer+(in_len-n),
body_offs-(in_len-n));
printf("Beginning of body found! "
"Awaiting end...\n");
}else{
write((fds[!i].fd), buf, n);
}
} else if(i==0 && !after_body){
/* We keep the body until we have it completetly
*/
in_len += n;
input_buffer = realloc(input_buffer, in_len);
strncat(input_buffer,buf, n);
body_p = detect_end_of_body(input_buffer+
body_offs);
if(body_p != NULL){
printf("We found the body:\n%.*s\n",
body_p-(input_buffer+body_offs),
input_buffer+body_offs);
size_t body_len = body_p-
(input_buffer+body_offs);
write((fds[!i].fd),
input_buffer+body_offs,
body_len);
write((fds[!i].fd),
input_buffer+body_offs+body_len,
in_len-(body_offs+body_len));
after_body = true;
}
}else{
write((fds[!i].fd), buf, n);
}
}
}
closeup:
printf("Disconnecting clients");
printf("Disconnecting clients\n");
close(cli->fd);
close(remote_fd);
free(cli);
free(input_buffer);
return NULL;
}