Mail body isolation
Signed-off-by: Tyrolyean <tyrolyean@tyrolyean.net>
This commit is contained in:
parent
f0a93c5bc2
commit
f8f513145d
|
@ -19,7 +19,9 @@
|
||||||
#define DETECT_H
|
#define DETECT_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
bool detect_pgp(const char* message);
|
bool detect_pgp(const char* message);
|
||||||
|
char* detect_start_of_body(char* message);
|
||||||
|
char* detect_end_of_body(char* message);
|
||||||
#endif /* DETECT_H */
|
#endif /* DETECT_H */
|
||||||
|
|
46
src/detect.c
46
src/detect.c
|
@ -16,9 +16,55 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "detect.h"
|
#include "detect.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
bool detect_pgp(const char* message){
|
bool detect_pgp(const char* message){
|
||||||
|
|
||||||
return false;
|
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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "attach.h"
|
#include "attach.h"
|
||||||
|
#include "detect.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* error - wrapper for perror
|
* error - wrapper for perror
|
||||||
|
@ -63,7 +65,7 @@ void* client_handle_async(void* params){
|
||||||
}
|
}
|
||||||
|
|
||||||
int n; /* message byte size */
|
int n; /* message byte size */
|
||||||
char buf[1024];
|
char buf[10];
|
||||||
struct pollfd fds[2];
|
struct pollfd fds[2];
|
||||||
memset(fds, 0 , sizeof(fds));
|
memset(fds, 0 , sizeof(fds));
|
||||||
fds[0].fd = cli->fd;
|
fds[0].fd = cli->fd;
|
||||||
|
@ -73,6 +75,13 @@ void* client_handle_async(void* params){
|
||||||
|
|
||||||
int timeout = (10 * 1000); /* 10 seconds */
|
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){
|
while(poll(fds, 2, timeout) > 0){
|
||||||
for(size_t i = 0; i < 2; i++){
|
for(size_t i = 0; i < 2; i++){
|
||||||
if(!(fds[i].revents & POLLIN)){
|
if(!(fds[i].revents & POLLIN)){
|
||||||
|
@ -84,18 +93,75 @@ void* client_handle_async(void* params){
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
goto closeup;
|
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:
|
closeup:
|
||||||
|
|
||||||
printf("Disconnecting clients");
|
printf("Disconnecting clients\n");
|
||||||
close(cli->fd);
|
close(cli->fd);
|
||||||
close(remote_fd);
|
close(remote_fd);
|
||||||
free(cli);
|
free(cli);
|
||||||
|
free(input_buffer);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue