Compare commits
No commits in common. "13125100749877b9555558fa9f7af213ebdf7911" and "f4747dcd7d20c0dda9a7275ba0718fbc067db4c2" have entirely different histories.
1312510074
...
f4747dcd7d
9 changed files with 17 additions and 126 deletions
38
README
38
README
|
@ -1,37 +1,5 @@
|
||||||
MAILATTACH
|
MAILATTACH
|
||||||
|
|
||||||
This program starts a process which listens on the LOOPBACKv4 address for
|
This program starts a process which listens on a unix socket for incoming
|
||||||
incoming connections from postfix. The postfix master should view this as an
|
milter connections. Incoming mail is scanned for large files and files above a
|
||||||
advanced filter as explained in their documentation for post queue filtering:
|
certain threshold are replaced with links which the user may specify.
|
||||||
|
|
||||||
http://www.postfix.org/FILTER_README.html
|
|
||||||
|
|
||||||
The original attempt was to implement this as a pre queue filter, but this
|
|
||||||
required the milter protocol and postfix currently does not implement the
|
|
||||||
replace body function from libmilter.
|
|
||||||
|
|
||||||
You can specify the following command line options:
|
|
||||||
|
|
||||||
--abort-pgp --noabort-pgp
|
|
||||||
To either abort the attachment process if PGP encryption or signatures
|
|
||||||
have been detected or not. If true, the mail will not be modified.
|
|
||||||
|
|
||||||
--abort-dkim --noabort-dkim
|
|
||||||
To either abort the attachment process if DKIM signatures have been
|
|
||||||
detected or not. If true, the mail will not be modified.
|
|
||||||
|
|
||||||
--in-port -i
|
|
||||||
The incoming smtp port/the port from which mail is received.
|
|
||||||
|
|
||||||
--out-port -o
|
|
||||||
The outgoing smtp port/the port to which mail ist passed through.
|
|
||||||
|
|
||||||
HOWTO
|
|
||||||
|
|
||||||
We essentially are MITM sniffing your email traffic and playing proxy from your
|
|
||||||
postfix to your postfix. That's how this is intended to work according to the
|
|
||||||
postfix website.
|
|
||||||
|
|
||||||
This program needs to be started via it's own systemd service on system boot.
|
|
||||||
You need to add the in and oputput ports to your postfix queue as described in
|
|
||||||
the link above. More documentation is to a TODO
|
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
|
|
||||||
extern uint16_t listen_port, forward_port;
|
extern uint16_t listen_port, forward_port;
|
||||||
|
|
||||||
/* Used as booleans, but integers for getops sake... */
|
extern bool abort_on_pgp, abort_on_dkim;
|
||||||
|
|
||||||
extern int abort_on_pgp, abort_on_dkim;
|
|
||||||
|
|
||||||
#endif /* CONFIG_H */
|
#endif /* CONFIG_H */
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "attach.h"
|
#include "attach.h"
|
||||||
|
|
||||||
bool detect_pgp(struct email_t* mail);
|
bool detect_pgp(struct email_t* mail);
|
||||||
bool detect_dkim(struct email_t* mail);
|
|
||||||
char* detect_start_of_body(char* message);
|
char* detect_start_of_body(char* message);
|
||||||
char* detect_end_of_body(char* message);
|
char* detect_end_of_body(char* message);
|
||||||
#endif /* DETECT_H */
|
#endif /* DETECT_H */
|
||||||
|
|
|
@ -23,5 +23,4 @@
|
||||||
const char* insert_string(char * destination, const char* source,
|
const char* insert_string(char * destination, const char* source,
|
||||||
size_t dest_orig_len, size_t offset);
|
size_t dest_orig_len, size_t offset);
|
||||||
|
|
||||||
|
|
||||||
#endif /* TOOLS_H */
|
#endif /* TOOLS_H */
|
||||||
|
|
11
src/attach.c
11
src/attach.c
|
@ -83,16 +83,17 @@ char* attach_files(char* message, size_t len){
|
||||||
|
|
||||||
struct email_t email = mail_from_text(message,len);
|
struct email_t email = mail_from_text(message,len);
|
||||||
|
|
||||||
|
printf("Received message header: [%.*s]\n", email.header_len,
|
||||||
|
email.message);
|
||||||
|
printf("Received message body: [%.*s]\n",
|
||||||
|
email.message_length-email.body_offset,
|
||||||
|
email.message + email.body_offset);
|
||||||
|
|
||||||
/* Check if mails are signed/encrypted, and abort if nescessary */
|
/* Check if mails are signed/encrypted, and abort if nescessary */
|
||||||
if(abort_on_pgp && detect_pgp(&email)){
|
if(abort_on_pgp && detect_pgp(&email)){
|
||||||
printf("PGP detected, aborting...");
|
printf("PGP detected, aborting...");
|
||||||
return email.message;
|
return email.message;
|
||||||
}
|
}
|
||||||
/* Check if mails are signed/encrypted, and abort if nescessary */
|
|
||||||
if(abort_on_dkim && detect_dkim(&email)){
|
|
||||||
printf("DKIM signature detected, aborting...");
|
|
||||||
return email.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
return email.message;
|
return email.message;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
uint16_t listen_port = 4269, forward_port = 4270;
|
uint16_t listen_port = 4269, forward_port = 4270;
|
||||||
int abort_on_pgp = true, abort_on_dkim = true;
|
bool abort_on_pgp = true, abort_on_dkim = true;
|
||||||
|
|
22
src/detect.c
22
src/detect.c
|
@ -29,11 +29,6 @@ char* pgp_signatures[] =
|
||||||
"-----BEGIN PGP MESSAGE-----"
|
"-----BEGIN PGP MESSAGE-----"
|
||||||
};
|
};
|
||||||
|
|
||||||
char* dkim_signatures[] =
|
|
||||||
{
|
|
||||||
"DKIM-Signature:"
|
|
||||||
};
|
|
||||||
|
|
||||||
bool detect_pgp(struct email_t* mail){
|
bool detect_pgp(struct email_t* mail){
|
||||||
|
|
||||||
size_t points = 0;
|
size_t points = 0;
|
||||||
|
@ -50,23 +45,6 @@ bool detect_pgp(struct email_t* mail){
|
||||||
return points >= 2;
|
return points >= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool detect_dkim(struct email_t* mail){
|
|
||||||
|
|
||||||
size_t points = 0;
|
|
||||||
|
|
||||||
for(size_t i = 0; i < (sizeof(dkim_signatures)/sizeof(char*));i++){
|
|
||||||
if(strcasestr(mail->message, dkim_signatures[i]) != NULL
|
|
||||||
&& strcasestr(mail->message, dkim_signatures[i])
|
|
||||||
<= (mail->message+mail->header_len)){
|
|
||||||
points++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return points >= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If body hasn't started yet, it returns NULL, if it has started, it returns
|
/* If body hasn't started yet, it returns NULL, if it has started, it returns
|
||||||
* the pointer to the beginning of the newline.
|
* the pointer to the beginning of the newline.
|
||||||
*/
|
*/
|
||||||
|
|
61
src/main.c
61
src/main.c
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <getopt.h>
|
|
||||||
|
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -15,66 +15,11 @@
|
||||||
int main(int argc, char* argv[]){
|
int main(int argc, char* argv[]){
|
||||||
|
|
||||||
printf("INIT\n");
|
printf("INIT\n");
|
||||||
|
|
||||||
int c;
|
|
||||||
|
|
||||||
while (1){
|
|
||||||
static struct option long_options[] =
|
|
||||||
{
|
|
||||||
{"abort-pgp", no_argument, &abort_on_pgp, 1},
|
|
||||||
{"abort-dkim", no_argument, &abort_on_dkim,1},
|
|
||||||
{"noabort-pgp", no_argument, &abort_on_pgp, 0},
|
|
||||||
{"noabort-dkim",no_argument, &abort_on_dkim,0},
|
|
||||||
{"in-port", required_argument, 0, 'i'},
|
|
||||||
{"out-port", required_argument, 0, 'o'},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
/* getopt_long stores the option index here. */
|
|
||||||
int option_index = 0;
|
|
||||||
|
|
||||||
c = getopt_long (argc, argv, "i:o:pd",
|
|
||||||
long_options, &option_index);
|
|
||||||
|
|
||||||
/* Detect the end of the options. */
|
|
||||||
if (c == -1){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (c){
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
listen_port = atoi(optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'o':
|
|
||||||
forward_port = atoi(optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '?':
|
|
||||||
/* getopt_long already printed an error message. */
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Incoming port: %u outgoing port: %u on loopback interface\n",
|
|
||||||
listen_port, forward_port);
|
|
||||||
|
|
||||||
printf("Ignoring PGP signed/encrypted messages: %s\n",
|
|
||||||
abort_on_pgp ? "true":false);
|
|
||||||
|
|
||||||
printf("Ignoring DKIM signed messages: %s\n",
|
|
||||||
abort_on_dkim ? "true" : "false");
|
|
||||||
|
|
||||||
if(init_net() < 0){
|
if(init_net() < 0){
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
loop_clients();
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,6 +273,9 @@ void loop_clients(){
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* accept: wait for a connection request
|
||||||
|
*/
|
||||||
childfd = accept(parentfd, (struct sockaddr *) &clientaddr, &clientlen);
|
childfd = accept(parentfd, (struct sockaddr *) &clientaddr, &clientlen);
|
||||||
if (childfd < 0){
|
if (childfd < 0){
|
||||||
perror("accept failed");
|
perror("accept failed");
|
||||||
|
|
Loading…
Reference in a new issue