22import email .mime .text
33from email .message import EmailMessage
44from email .base64mime import body_encode as encode_base64
5+ from saslprep import saslprep
56import email .utils
67import hashlib
78import hmac
@@ -808,6 +809,10 @@ def testLineTooLong(self):
808809 }
809810
810811sim_auth = ('Mr.A@somewhere.com' , 'somepassword' )
812+ sim_auths = {
813+ 'Mr.A@somewhere.com' : 'somepassword' ,
814+ 'भारत@भारत' : 'भारत@' ,
815+ 'Mr.C@somewhere.com' : 'IX' }
811816sim_cram_md5_challenge = ('PENCeUxFREJoU0NnbmhNWitOMjNGNn'
812817 'dAZWx3b29kLmlubm9zb2Z0LmNvbT4=' )
813818sim_lists = {'list-1' :['Mr.A@somewhere.com' ,'Mrs.C@somewhereesle.com' ],
@@ -895,7 +900,7 @@ def _auth_plain(self, arg=None):
895900 self .push ('535 Splitting response {!r} into user and password'
896901 ' failed: {}' .format (logpass , e ))
897902 return
898- self ._authenticated (user , password == sim_auth [ 1 ])
903+ self ._authenticated (user , saslprep ( password ) == sim_auths [ user ])
899904
900905 def _auth_login (self , arg = None ):
901906 if arg is None :
@@ -907,7 +912,8 @@ def _auth_login(self, arg=None):
907912 self .push ('334 UGFzc3dvcmQ6' )
908913 else :
909914 password = self ._decode_base64 (arg )
910- self ._authenticated (self ._auth_login_user , password == sim_auth [1 ])
915+ self ._authenticated (self ._auth_login_user ,
916+ saslprep (password ) == sim_auths [self ._auth_login_user ])
911917 del self ._auth_login_user
912918
913919 def _auth_buggy (self , arg = None ):
@@ -927,8 +933,8 @@ def _auth_cram_md5(self, arg=None):
927933 'failed: {}' .format (logpass , e ))
928934 return False
929935 valid_hashed_pass = hmac .HMAC (
930- sim_auth [ 1 ].encode ('ascii' ),
931- self ._decode_base64 (sim_cram_md5_challenge ).encode ('ascii ' ),
936+ saslprep ( sim_auths [ user ].encode ('utf-8' ) ),
937+ self ._decode_base64 (sim_cram_md5_challenge ).encode ('utf-8 ' ),
932938 'md5' ).hexdigest ()
933939 self ._authenticated (user , hashed_pass == valid_hashed_pass )
934940 # end AUTH related stuff.
@@ -1117,30 +1123,41 @@ def testEXPN(self):
11171123 self .assertEqual (smtp .expn (u ), expected_unknown )
11181124 smtp .quit ()
11191125
1126+ def helpAUTH_x (self , feature ):
1127+ self .serv .add_feature (feature )
1128+ for username in sim_auths .keys ():
1129+ with self .subTest (username = username ):
1130+ smtp = smtplib .SMTP (HOST , self .port , local_hostname = 'localhost' , timeout = 15 )
1131+ resp = smtp .login (username , sim_auths [username ])
1132+ self .assertEqual (resp , (235 , b'Authentication Succeeded' ))
1133+ smtp .close ()
1134+ with self .subTest (username = username ):
1135+ smtp = smtplib .SMTP (HOST , self .port , local_hostname = 'localhost' , timeout = 15 )
1136+ with self .assertRaises (smtplib .SMTPAuthenticationError ):
1137+ smtp .login (username , "No" + sim_auths [username ])
1138+ smtp .close ()
1139+ with self .subTest (username = username ):
1140+ smtp = smtplib .SMTP (HOST , self .port , local_hostname = 'localhost' , timeout = 15 )
1141+ resp = smtp .login (username , sim_auths [username ] + u"\u00AD " )
1142+ self .assertEqual (resp , (235 , b'Authentication Succeeded' ))
1143+ smtp .close ()
1144+
11201145 def testAUTH_PLAIN (self ):
1121- self .serv .add_feature ("AUTH PLAIN" )
1122- smtp = smtplib .SMTP (HOST , self .port , local_hostname = 'localhost' ,
1123- timeout = support .LOOPBACK_TIMEOUT )
1124- resp = smtp .login (sim_auth [0 ], sim_auth [1 ])
1125- self .assertEqual (resp , (235 , b'Authentication Succeeded' ))
1126- smtp .close ()
1146+ self .helpAUTH_x ("AUTH PLAIN" )
11271147
11281148 def testAUTH_LOGIN (self ):
1129- self .serv .add_feature ("AUTH LOGIN" )
1130- smtp = smtplib .SMTP (HOST , self .port , local_hostname = 'localhost' ,
1131- timeout = support .LOOPBACK_TIMEOUT )
1132- resp = smtp .login (sim_auth [0 ], sim_auth [1 ])
1133- self .assertEqual (resp , (235 , b'Authentication Succeeded' ))
1134- smtp .close ()
1149+ self .helpAUTH_x ("AUTH LOGIN" )
11351150
11361151 def testAUTH_LOGIN_initial_response_ok (self ):
11371152 self .serv .add_feature ("AUTH LOGIN" )
1138- with smtplib .SMTP (HOST , self .port , local_hostname = 'localhost' ,
1139- timeout = support .LOOPBACK_TIMEOUT ) as smtp :
1140- smtp .user , smtp .password = sim_auth
1141- smtp .ehlo ("test_auth_login" )
1142- resp = smtp .auth ("LOGIN" , smtp .auth_login , initial_response_ok = True )
1143- self .assertEqual (resp , (235 , b'Authentication Succeeded' ))
1153+ for username in sim_auths .keys ():
1154+ with smtplib .SMTP (HOST , self .port , local_hostname = 'localhost' ,
1155+ timeout = support .LOOPBACK_TIMEOUT ) as smtp :
1156+ smtp .user = username
1157+ smtp .password = sim_auths [username ]
1158+ smtp .ehlo ("test_auth_login" )
1159+ resp = smtp .auth ("LOGIN" , smtp .auth_login , initial_response_ok = True )
1160+ self .assertEqual (resp , (235 , b'Authentication Succeeded' ))
11441161
11451162 def testAUTH_LOGIN_initial_response_notok (self ):
11461163 self .serv .add_feature ("AUTH LOGIN" )
@@ -1183,12 +1200,7 @@ def testAUTH_CRAM_MD5(self):
11831200 @hashlib_helper .requires_hashdigest ('md5' , openssl = True )
11841201 def testAUTH_multiple (self ):
11851202 # Test that multiple authentication methods are tried.
1186- self .serv .add_feature ("AUTH BOGUS PLAIN LOGIN CRAM-MD5" )
1187- smtp = smtplib .SMTP (HOST , self .port , local_hostname = 'localhost' ,
1188- timeout = support .LOOPBACK_TIMEOUT )
1189- resp = smtp .login (sim_auth [0 ], sim_auth [1 ])
1190- self .assertEqual (resp , (235 , b'Authentication Succeeded' ))
1191- smtp .close ()
1203+ self .helpAUTH_x ("AUTH BOGUS PLAIN LOGIN CRAM-MD5" )
11921204
11931205 def test_auth_function (self ):
11941206 supported = {'PLAIN' , 'LOGIN' }
0 commit comments