preparations of crazy fever dream implementation
to be able to use a POP3 Email client to receive emails from OpenTrashmail
This commit is contained in:
parent
7fe3c94953
commit
f62f3f56de
|
@ -11,10 +11,14 @@ DOMAINS=yourdomain,sub.yourdomain
|
||||||
[MAILSERVER]
|
[MAILSERVER]
|
||||||
; Port that the Mailserver will run on (default 25 but that needs root)
|
; Port that the Mailserver will run on (default 25 but that needs root)
|
||||||
MAILPORT=25
|
MAILPORT=25
|
||||||
|
|
||||||
; true or false depending on if you only want to save emails to the above set domains
|
; true or false depending on if you only want to save emails to the above set domains
|
||||||
; this greatly reduces the amount of spam you will receive
|
; this greatly reduces the amount of spam you will receive
|
||||||
DISCARD_UNKNOWN=true
|
DISCARD_UNKNOWN=true
|
||||||
|
|
||||||
|
; Port number of the !! HIGHLY EXPERIMENTAL !! POP3 server
|
||||||
|
POP3PORT=110
|
||||||
|
|
||||||
[DATETIME]
|
[DATETIME]
|
||||||
; The moment.js format you'd like your date to be formatted in
|
; The moment.js format you'd like your date to be formatted in
|
||||||
DATEFORMAT="D.M.YYYY HH:mm"
|
DATEFORMAT="D.M.YYYY HH:mm"
|
||||||
|
|
194
tools/pop3_server.php
Normal file
194
tools/pop3_server.php
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
define('DS', DIRECTORY_SEPARATOR);
|
||||||
|
define('ROOT', dirname(__FILE__).DS.'..'.DS.'web');
|
||||||
|
|
||||||
|
define('DEBUG', true);
|
||||||
|
|
||||||
|
error_reporting(E_ALL || ~E_NOTICE);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
|
||||||
|
include_once(ROOT.DS.'inc'.DS.'core.php');
|
||||||
|
|
||||||
|
$settings = loadSettings();
|
||||||
|
if(!$settings['POP3PORT'])
|
||||||
|
$pop3port = $settings['POP3PORT']?:110;
|
||||||
|
|
||||||
|
echo "[i] Server started\n";
|
||||||
|
flush();
|
||||||
|
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
// listen for incoming connection
|
||||||
|
$listen_socket = socket_create_listen($pop3port, 1);
|
||||||
|
$r = $w = $e = array($listen_socket);
|
||||||
|
$n = socket_select($r, $w, $e, 120);
|
||||||
|
$client_socket = ($n == 1) ? socket_accept($listen_socket) : null;
|
||||||
|
socket_close($listen_socket);
|
||||||
|
|
||||||
|
if(DEBUG===true)
|
||||||
|
echo("[+] New client connected").PHP_EOL;
|
||||||
|
|
||||||
|
if(!$client_socket) {
|
||||||
|
// timed out
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start handling the session
|
||||||
|
$read_buffer = "";
|
||||||
|
$write_buffer = "+OK POP3 server ready\r\n";
|
||||||
|
$active = true;
|
||||||
|
|
||||||
|
$messages = [];
|
||||||
|
|
||||||
|
|
||||||
|
$idle_start = time();
|
||||||
|
while(true) {
|
||||||
|
$r = $w = $e = array($client_socket);
|
||||||
|
$n = socket_select($r, $w, $e, 60);
|
||||||
|
if($n) {
|
||||||
|
if($r) {
|
||||||
|
// read from the socket
|
||||||
|
//error_log("reading from socket");
|
||||||
|
$read_buffer .= socket_read($client_socket, 128);
|
||||||
|
$idle_start = time();
|
||||||
|
}
|
||||||
|
if($w) {
|
||||||
|
if($write_buffer) {
|
||||||
|
// write to the socket
|
||||||
|
//error_log("writing to socket");
|
||||||
|
$written = socket_write($client_socket, $write_buffer);
|
||||||
|
$write_buffer = substr($write_buffer, $written);
|
||||||
|
$idle_start = time();
|
||||||
|
} else if($active) {
|
||||||
|
$now = time();
|
||||||
|
$idle_time = $now - $idle_start;
|
||||||
|
if($idle_time > 10) {
|
||||||
|
// exit if nothing happened for 10 seconds
|
||||||
|
error_log("timeout 1");
|
||||||
|
break;
|
||||||
|
} else if($idle_time > 2) {
|
||||||
|
// start napping when the client is too slow
|
||||||
|
error_log("timeout 2");
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if($read_buffer) {
|
||||||
|
|
||||||
|
if(preg_match('/(.*?)(?:\s+(.*?))?[\r\n]+/', $read_buffer, $matches)) {
|
||||||
|
$read_buffer = substr($read_buffer, strlen($matches[0]));
|
||||||
|
$tmatches = array_map('trim', $matches);
|
||||||
|
|
||||||
|
if(DEBUG===true)
|
||||||
|
echo(" [READING FROM CLIENT] ".$tmatches[0]).PHP_EOL;
|
||||||
|
|
||||||
|
$command = $matches[1];
|
||||||
|
$argument = $matches[2];
|
||||||
|
switch($command) {
|
||||||
|
case 'CAPA':
|
||||||
|
$write_buffer = "+OK Capability list follows\r\n";
|
||||||
|
$write_buffer.= implode("\r\n",["USER","PASS","UIDL"]);
|
||||||
|
$write_buffer .= "\r\n.\r\n";
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
case 'USER':
|
||||||
|
$username = $argument;
|
||||||
|
$write_buffer .= "+OK $username is welcome here\r\n";
|
||||||
|
|
||||||
|
$messages = getEmailsOfEmail($username);
|
||||||
|
|
||||||
|
if(DEBUG===true)
|
||||||
|
echo(" [+] Loaded ".count($messages)." for email $username").PHP_EOL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'PASS':
|
||||||
|
$message_count = count($messages);
|
||||||
|
$write_buffer .= "+OK mailbox has $message_count message(s)\r\n";
|
||||||
|
break;
|
||||||
|
case 'QUIT':
|
||||||
|
$write_buffer .= "+OK POP3 server signing off\r\n";
|
||||||
|
$active = false;
|
||||||
|
break;
|
||||||
|
case 'STAT':
|
||||||
|
$message_count = count($messages);
|
||||||
|
$mailbox_size = 0;
|
||||||
|
foreach($messages as $message) {
|
||||||
|
$mailbox_size += $message['maillen'];
|
||||||
|
}
|
||||||
|
$write_buffer .= "+OK $message_count $mailbox_size\r\n";
|
||||||
|
break;
|
||||||
|
case 'LIST':
|
||||||
|
$start_index = (int) $argument;
|
||||||
|
$message_count = count($messages) - $start_index;
|
||||||
|
$total_size = 0;
|
||||||
|
for($i = $start_index; $i < count($messages); $i++) {
|
||||||
|
$msg = array_values(array_slice($messages, $i, 1, true))[0];
|
||||||
|
$total_size += $msg['maillen'];
|
||||||
|
}
|
||||||
|
$write_buffer .= "+OK $message_count messages ($total_size octets)\r\n";
|
||||||
|
for($i = $start_index; $i < count($messages); $i++) {
|
||||||
|
$msg = array_values(array_slice($messages, $i, 1, true))[0];
|
||||||
|
$message_id = $i + 1;
|
||||||
|
$message_size = $msg['maillen'];
|
||||||
|
$write_buffer .= "$message_id $message_size\r\n";
|
||||||
|
}
|
||||||
|
$write_buffer .= ".\r\n";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'UIDL':
|
||||||
|
$start_index = (int) $argument;
|
||||||
|
$message_count = count($messages) - $start_index;
|
||||||
|
$write_buffer .= "+OK $message_count messages\r\n";
|
||||||
|
for($i = $start_index; $i < count($messages); $i++) {
|
||||||
|
$message_id = $i + 1;
|
||||||
|
$msg = array_values(array_slice($messages, $i, 1, true))[0];
|
||||||
|
$write_buffer .= "$message_id ".$msg['md5']."\r\n";
|
||||||
|
}
|
||||||
|
$write_buffer .= ".\r\n";
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'RETR':
|
||||||
|
$message_id = (int) $argument;
|
||||||
|
$message = array_values(array_slice($messages, ($message_id-1), 1, true))[0];
|
||||||
|
$message_size = $message['maillen'];
|
||||||
|
$write_buffer .= "+OK $message_size octets\r\n";
|
||||||
|
$write_buffer .= getRawEmail($message['email'],$message['id'])."\r\n";
|
||||||
|
$write_buffer .= ".\r\n";
|
||||||
|
break;
|
||||||
|
case 'DELE':
|
||||||
|
$write_buffer .= "+OK\r\n";
|
||||||
|
break;
|
||||||
|
case 'NOOP':
|
||||||
|
$write_buffer .= "+OK\r\n";
|
||||||
|
break;
|
||||||
|
case 'LAST':
|
||||||
|
$message_count = count($messages) - $start_index;
|
||||||
|
$write_buffer .= "+OK $message_count\r\n";
|
||||||
|
break;
|
||||||
|
case 'RSET':
|
||||||
|
$write_buffer .= "+OK\r\n";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$write_buffer .= "-ERR Unknown command '$command'\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(DEBUG===true)
|
||||||
|
echo(" [MY ANSWER] ".trim($write_buffer)).PHP_EOL;
|
||||||
|
|
||||||
|
if(!$active && DEBUG===true)
|
||||||
|
echo("[-] Client disconnected").PHP_EOL;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,13 @@ function getEmail($email,$id)
|
||||||
return json_decode(file_get_contents(getDirForEmail($email).DS.$id.'.json'),true);
|
return json_decode(file_get_contents(getDirForEmail($email).DS.$id.'.json'),true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRawEmail($email,$id)
|
||||||
|
{
|
||||||
|
$data = json_decode(file_get_contents(getDirForEmail($email).DS.$id.'.json'),true);
|
||||||
|
|
||||||
|
return $data['raw'];
|
||||||
|
}
|
||||||
|
|
||||||
function emailIDExists($email,$id)
|
function emailIDExists($email,$id)
|
||||||
{
|
{
|
||||||
return file_exists(getDirForEmail($email).DS.$id.'.json');
|
return file_exists(getDirForEmail($email).DS.$id.'.json');
|
||||||
|
@ -39,7 +46,7 @@ function getEmailsOfEmail($email)
|
||||||
if (endsWith($entry,'.json')) {
|
if (endsWith($entry,'.json')) {
|
||||||
$time = substr($entry,0,-5);
|
$time = substr($entry,0,-5);
|
||||||
$json = json_decode(file_get_contents(getDirForEmail($email).DS.$entry),true);
|
$json = json_decode(file_get_contents(getDirForEmail($email).DS.$entry),true);
|
||||||
$o[$time] = array('from'=>$json['parsed']['from'],'subject'=>$json['parsed']['subject']);
|
$o[$time] = array('email'=>$email,'id'=>$time,'from'=>$json['parsed']['from'],'subject'=>$json['parsed']['subject'],'md5'=>md5($time.$json['raw']),'maillen'=>strlen($json['raw']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir($handle);
|
closedir($handle);
|
||||||
|
|
Loading…
Reference in a new issue