Samfredoly commited on
Commit
84d1443
·
verified ·
1 Parent(s): 2e0f333

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -0
app.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import ssl
3
+ from aiosmtpd.controller import Controller
4
+ from aiosmtpd.handlers import Sink
5
+ from aiosmtpd.smtp import SMTP, AuthResult, LoginPassword
6
+ from email.policy import default
7
+ from typing import Optional
8
+
9
+ # Configure logging
10
+ logging.basicConfig(level=logging.INFO)
11
+ logger = logging.getLogger("smtp_server")
12
+
13
+ # SMTP Server Configuration
14
+ SMTP_HOST = "0.0.0.0" # Bind to all interfaces
15
+ SMTP_PORT = 587 # Standard SMTP submission port
16
+ TLS_CERTFILE = "cert.pem" # Path to your SSL certificate
17
+ TLS_KEYFILE = "key.pem" # Path to your SSL private key
18
+
19
+ # Authentication Credentials (for demo purposes; use a secure vault in production)
20
+ VALID_USERS = {
21
+ "user1": "password1",
22
+ "user2": "password2",
23
+ }
24
+
25
+ class AuthenticatedSMTPHandler(Sink):
26
+ async def handle_AUTH(self, server: SMTP, args: str, mechanism: str) -> Optional[AuthResult]:
27
+ if mechanism.upper() != "LOGIN":
28
+ return AuthResult(success=False, handled=False)
29
+ return None
30
+
31
+ async def handle_AUTH_LOGIN(self, server: SMTP, args: str) -> Optional[AuthResult]:
32
+ try:
33
+ username, password = args.split()
34
+ if username in VALID_USERS and VALID_USERS[username] == password:
35
+ return AuthResult(success=True, auth_data=LoginPassword(username, password))
36
+ else:
37
+ return AuthResult(success=False, message="Invalid credentials")
38
+ except Exception as e:
39
+ logger.error(f"Authentication error: {e}")
40
+ return AuthResult(success=False, message="Authentication failed")
41
+
42
+ async def handle_DATA(self, server: SMTP, session, envelope):
43
+ # Log the received email
44
+ logger.info(f"Received email from: {envelope.mail_from}")
45
+ logger.info(f"Recipients: {envelope.rcpt_tos}")
46
+ logger.info(f"Message data:\n{envelope.content.decode('utf-8')}")
47
+ return "250 Message accepted for delivery"
48
+
49
+ def start_smtp_server():
50
+ # Create SSL context for TLS
51
+ ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
52
+ ssl_context.load_cert_chain(TLS_CERTFILE, TLS_KEYFILE)
53
+
54
+ # Create the SMTP handler
55
+ handler = AuthenticatedSMTPHandler()
56
+
57
+ # Start the SMTP server with TLS and authentication
58
+ controller = Controller(
59
+ handler,
60
+ hostname=SMTP_HOST,
61
+ port=SMTP_PORT,
62
+ enable_SMTPUTF8=True,
63
+ ssl_context=ssl_context,
64
+ auth_required=True,
65
+ )
66
+
67
+ logger.info(f"Starting SMTP server on {SMTP_HOST}:{SMTP_PORT} with TLS and authentication...")
68
+ controller.start()
69
+ try:
70
+ # Keep the server running
71
+ while True:
72
+ pass
73
+ except KeyboardInterrupt:
74
+ logger.info("Shutting down SMTP server...")
75
+ controller.stop()
76
+
77
+ if __name__ == "__main__":
78
+ start_smtp_server()