aiosmtpd
aiosmtpd copied to clipboard
Starttls session erase old session instance, including proxy_arg details
Hi,
I noticed that when a StartTls connection is made over an existing connection, a entirely new Session object is created, which erase the previous one that contained the PROXY details (when used).
In order to avoid this issue, a simple solution could be to pass the previous session into the new one, such as:
def _create_session(self):
return Session(self.loop, self.session)
And the Session object:
@public
class Session:
def __init__(self, loop, session: Optional[Session] = None):
self.peer = None
self.ssl = None
self.host_name = session.host_name if session else None
self.extended_smtp = session.extended_smtp if session else False
self.loop = loop
self.proxy_data: Optional[ProxyData] = session.proxy_data if session else None
@cnicodeme I think I may be facing the same issue, but I was not able to track where the Session is being recreated on the code. I only spot one _create_session call on the def connection_made(self, transport: asyncio.transports.BaseTransport) -> None: method.
In order to resolve this, I created a class that wraps the SMTP class, and added the function _create_session(self) to return a new Session with the the current one as a parameter:
def _create_session(self):
return Session(self.loop, self.session)
And in my Session.__init__ class, I either set the old value or None:
class Session:
def __init__(self, loop, session=None):
# Data from the original Session
self.peer = None
self.ssl = None
self.host_name = session.host_name if session else None
self.extended_smtp = session.extended_smtp if session else False
self.loop = loop
self._proxy_data = session._proxy_data if session else None
# Auth data
self.auth_data = None
self.authenticated = False
self.reset()
def reset(self):
self.started_at = int(timer() * 1000)
self.received_at = int(datetime.datetime.utcnow().timestamp() * 1000)
self.mail_from = None # MAIL FROM SMTP command | List of name/email
self.sender = None # From header in the email content | List of name/email
self.size = None # Origina size
self.subject = None
self.message_id = None
self.session_id = str(uuid.uuid4())
(Some are custom data)