| 
12 | 12 | import socket  | 
13 | 13 | 
 
  | 
14 | 14 | from test.support import verbose, run_with_tz, run_with_locale, cpython_only  | 
15 |  | -from test.support import hashlib_helper  | 
16 |  | -from test.support import threading_helper  | 
 | 15 | +from test.support import hashlib_helper, threading_helper  | 
17 | 16 | import unittest  | 
18 | 17 | from unittest import mock  | 
19 | 18 | from datetime import datetime, timezone, timedelta  | 
@@ -256,7 +255,20 @@ def cmd_IDLE(self, tag, args):  | 
256 | 255 |             self._send_tagged(tag, 'BAD', 'Expected DONE')  | 
257 | 256 | 
 
  | 
258 | 257 | 
 
  | 
259 |  | -class NewIMAPTestsMixin():  | 
 | 258 | +class AuthHandler_CRAM_MD5(SimpleIMAPHandler):  | 
 | 259 | +    capabilities = 'LOGINDISABLED AUTH=CRAM-MD5'  | 
 | 260 | +    def cmd_AUTHENTICATE(self, tag, args):  | 
 | 261 | +        self._send_textline('+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2Uucm'  | 
 | 262 | +                            'VzdG9uLm1jaS5uZXQ=')  | 
 | 263 | +        r = yield  | 
 | 264 | +        if (r == b'dGltIGYxY2E2YmU0NjRiOWVmYT'  | 
 | 265 | +                 b'FjY2E2ZmZkNmNmMmQ5ZjMy\r\n'):  | 
 | 266 | +            self._send_tagged(tag, 'OK', 'CRAM-MD5 successful')  | 
 | 267 | +        else:  | 
 | 268 | +            self._send_tagged(tag, 'NO', 'No access')  | 
 | 269 | + | 
 | 270 | + | 
 | 271 | +class NewIMAPTestsMixin:  | 
260 | 272 |     client = None  | 
261 | 273 | 
 
  | 
262 | 274 |     def _setup(self, imap_handler, connect=True):  | 
@@ -439,40 +451,26 @@ def cmd_AUTHENTICATE(self, tag, args):  | 
439 | 451 | 
 
  | 
440 | 452 |     @hashlib_helper.requires_hashdigest('md5', openssl=True)  | 
441 | 453 |     def test_login_cram_md5_bytes(self):  | 
442 |  | -        class AuthHandler(SimpleIMAPHandler):  | 
443 |  | -            capabilities = 'LOGINDISABLED AUTH=CRAM-MD5'  | 
444 |  | -            def cmd_AUTHENTICATE(self, tag, args):  | 
445 |  | -                self._send_textline('+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2Uucm'  | 
446 |  | -                                    'VzdG9uLm1jaS5uZXQ=')  | 
447 |  | -                r = yield  | 
448 |  | -                if (r == b'dGltIGYxY2E2YmU0NjRiOWVmYT'  | 
449 |  | -                         b'FjY2E2ZmZkNmNmMmQ5ZjMy\r\n'):  | 
450 |  | -                    self._send_tagged(tag, 'OK', 'CRAM-MD5 successful')  | 
451 |  | -                else:  | 
452 |  | -                    self._send_tagged(tag, 'NO', 'No access')  | 
453 |  | -        client, _ = self._setup(AuthHandler)  | 
454 |  | -        self.assertTrue('AUTH=CRAM-MD5' in client.capabilities)  | 
 | 454 | +        client, _ = self._setup(AuthHandler_CRAM_MD5)  | 
 | 455 | +        self.assertIn('AUTH=CRAM-MD5', client.capabilities)  | 
455 | 456 |         ret, _ = client.login_cram_md5("tim", b"tanstaaftanstaaf")  | 
456 | 457 |         self.assertEqual(ret, "OK")  | 
457 | 458 | 
 
  | 
458 | 459 |     @hashlib_helper.requires_hashdigest('md5', openssl=True)  | 
459 | 460 |     def test_login_cram_md5_plain_text(self):  | 
460 |  | -        class AuthHandler(SimpleIMAPHandler):  | 
461 |  | -            capabilities = 'LOGINDISABLED AUTH=CRAM-MD5'  | 
462 |  | -            def cmd_AUTHENTICATE(self, tag, args):  | 
463 |  | -                self._send_textline('+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2Uucm'  | 
464 |  | -                                    'VzdG9uLm1jaS5uZXQ=')  | 
465 |  | -                r = yield  | 
466 |  | -                if (r == b'dGltIGYxY2E2YmU0NjRiOWVmYT'  | 
467 |  | -                         b'FjY2E2ZmZkNmNmMmQ5ZjMy\r\n'):  | 
468 |  | -                    self._send_tagged(tag, 'OK', 'CRAM-MD5 successful')  | 
469 |  | -                else:  | 
470 |  | -                    self._send_tagged(tag, 'NO', 'No access')  | 
471 |  | -        client, _ = self._setup(AuthHandler)  | 
472 |  | -        self.assertTrue('AUTH=CRAM-MD5' in client.capabilities)  | 
 | 461 | +        client, _ = self._setup(AuthHandler_CRAM_MD5)  | 
 | 462 | +        self.assertIn('AUTH=CRAM-MD5', client.capabilities)  | 
473 | 463 |         ret, _ = client.login_cram_md5("tim", "tanstaaftanstaaf")  | 
474 | 464 |         self.assertEqual(ret, "OK")  | 
475 | 465 | 
 
  | 
 | 466 | +    @hashlib_helper.block_algorithm("md5")  | 
 | 467 | +    def test_login_cram_md5_blocked(self):  | 
 | 468 | +        client, _ = self._setup(AuthHandler_CRAM_MD5)  | 
 | 469 | +        self.assertIn('AUTH=CRAM-MD5', client.capabilities)  | 
 | 470 | +        msg = re.escape("Server does not support CRAM-MD5 authentication")  | 
 | 471 | +        with self.assertRaisesRegex(imaplib.IMAP4.error, msg):  | 
 | 472 | +            client.login_cram_md5("tim", b"tanstaaftanstaaf")  | 
 | 473 | + | 
476 | 474 |     def test_aborted_authentication(self):  | 
477 | 475 |         class MyServer(SimpleIMAPHandler):  | 
478 | 476 |             def cmd_AUTHENTICATE(self, tag, args):  | 
 | 
0 commit comments