-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathppsmtpd.py
120 lines (99 loc) · 3.36 KB
/
ppsmtpd.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"""
PPFilter simple smtpd server handler
@author Leandro Mendes
@copyright Leandro Mendes <[email protected]>
"""
import socket
import SocketServer
import threading
import sys, time, errno
import re
import signal
class SMTPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
def process_message(self, mail_from, rcpts_to, message):
pass
class SMTPRequestHandler(SocketServer.BaseRequestHandler):
read_data = False
helo_host = None
mail_from = None
rcpts_to = []
message = None
hostname = socket.gethostname()
message = ''
def handle(self):
try:
self.f_socket = self.request.makefile()
self.send_data("220 %s PPFilter ESMTP" % (self.hostname) )
self.rcpts_to = []
while True:
if self.read_data:
self.data = self.request.recv(4096)
if len(self.data) == 0:
self.request.close()
for text in self.data.split('\r\n'):
# print ">", text, "<"
if text and text.strip() == '.':
self.data = 'DOT'
self.parse_commands()
return
else:
self.message += text + "\r\n"
else:
self.data = self.request.recv(1024)
# print threading.currentThread()
if len(self.data) != 0:
# print self.data
self.parse_commands()
except IOError, e:
if e.errno == errno.EPIPE:
self.f_socket.close()
return
except AttributeError:
self.request.send('500 Unknown command\r\n')
#self.request.close()
finally:
#print "Finish"
self.request.close()
return
def send_data(self, data):
# print data
self.request.send(data + "\r\n")
self.f_socket.flush()
def parse_commands(self):
cmd = []
cmd = self.data.split(' ')
if (len(cmd) < 2):
cmd[0] = self.data.strip()
method = (('self.smtp_' + cmd[0].upper().strip()) + '()')
# print method
eval(method)
def smtp_MAIL(self):
self.mail_from = self.data.split(':')[1].strip()
self.send_data('250 Ok')
def smtp_EHLO(self):
self.smtp_HELO()
def smtp_HELO(self):
self.helo_host = self.data.split(' ')[1].strip()
self.send_data(("250 %s" % self.hostname))
def smtp_QUIT(self):
self.send_data('221 Bye')
self.request.close()
def smtp_RSET(self):
self.mail_from = None
self.rcpts_to = []
self.message = ''
self.send_data('250 Ok')
def smtp_DOT(self):
response = self.server.process_message(self.mail_from, self.rcpts_to, self.message)
if type(response).__name__ == 'str':
self.send_data((response))
else:
self.send_data('250 Ok')
self.read_data = False
def smtp_RCPT(self):
self.rcpts_to.append(self.data.split(':')[1].strip())
self.send_data('250 Ok')
def smtp_DATA(self):
print 'waiting for data'
self.send_data("354 Start mail input; end with '.'")
self.read_data = True