Mail body isolation
Signed-off-by: Tyrolyean <tyrolyean@tyrolyean.net>
This commit is contained in:
parent
f0a93c5bc2
commit
f8f513145d
3 changed files with 119 additions and 5 deletions
|
@ -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 */
|
||||
|
|
46
src/detect.c
46
src/detect.c
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
74
src/main.c
74
src/main.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue