Skip to content

Commit

Permalink
Add support for inline username with SMTP LOGIN (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonrob committed Jun 13, 2022
1 parent ef6b0fd commit 1e28891
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions emailproxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
__author__ = 'Simon Robinson'
__copyright__ = 'Copyright (c) 2022 Simon Robinson'
__license__ = 'Apache 2.0'
__version__ = '2022-06-09' # ISO 8601 (YYYY-MM-DD)
__version__ = '2022-06-13' # ISO 8601 (YYYY-MM-DD)

import argparse
import asyncore
Expand Down Expand Up @@ -772,17 +772,14 @@ def process_data(self, byte_data, censor_server_log=False):
self.send_authentication_request()

elif self.authentication_state is self.AUTH.PENDING and str_data_lower.startswith('auth login'):
self.authentication_state = self.AUTH.LOGIN_AWAITING_USERNAME
self.send(b'334 %s\r\n' % base64.b64encode(b'Username:'))
if len(str_data) > 11: # 11 = len('AUTH LOGIN ') - this method can have the username either inline...
self.decode_username_and_request_password(str_data[11:])
else: # ...or requested separately
self.authentication_state = self.AUTH.LOGIN_AWAITING_USERNAME
self.send(b'334 %s\r\n' % base64.b64encode(b'Username:'))

elif self.authentication_state is self.AUTH.LOGIN_AWAITING_USERNAME:
try:
self.server_connection.username = base64.b64decode(str_data).decode('utf-8')
except binascii.Error:
self.server_connection.username = ''
self.authentication_state = self.AUTH.LOGIN_AWAITING_PASSWORD
self.censor_next_log = True
self.send(b'334 %s\r\n' % base64.b64encode(b'Password:'))
self.decode_username_and_request_password(str_data)

elif self.authentication_state is self.AUTH.LOGIN_AWAITING_PASSWORD:
try:
Expand All @@ -795,6 +792,15 @@ def process_data(self, byte_data, censor_server_log=False):
else:
super().process_data(byte_data)

def decode_username_and_request_password(self, encoded_username):
try:
self.server_connection.username = base64.b64decode(encoded_username).decode('utf-8')
except binascii.Error:
self.server_connection.username = ''
self.authentication_state = self.AUTH.LOGIN_AWAITING_PASSWORD
self.censor_next_log = True
self.send(b'334 %s\r\n' % base64.b64encode(b'Password:'))

def send_authentication_request(self):
self.authentication_state = self.AUTH.PENDING
self.server_connection.authentication_state = SMTPOAuth2ServerConnection.AUTH.STARTED
Expand Down

0 comments on commit 1e28891

Please sign in to comment.