|
45 | 45 | import email.utils |
46 | 46 | import email.message |
47 | 47 | import email.generator |
48 | | -import functools |
49 | 48 | import base64 |
50 | 49 | import hmac |
51 | 50 | import copy |
@@ -179,19 +178,12 @@ def _fix_eols(data): |
179 | 178 | return re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data) |
180 | 179 |
|
181 | 180 |
|
182 | | -# Use unbounded LRU cache instead of global variable to ease mocking. |
183 | | -@functools.cache |
184 | | -def _have_cram_md5_support(): |
185 | | - """Check if CRAM-MD5 is supported by the host. |
186 | | -
|
187 | | - Note that CRAM-MD5 may be supported by the server |
188 | | - but not by the client if HMAC-MD5 is not supported. |
189 | | - """ |
190 | | - try: |
191 | | - hmac.digest(b'', b'', 'md5') |
192 | | - return True |
193 | | - except ValueError: |
194 | | - return False |
| 181 | +try: |
| 182 | + hmac.digest(b'', b'', 'md5') |
| 183 | +except ValueError: |
| 184 | + _have_cram_md5_support = False |
| 185 | +else: |
| 186 | + _have_cram_md5_support = True |
195 | 187 |
|
196 | 188 |
|
197 | 189 | try: |
@@ -682,7 +674,7 @@ def auth_cram_md5(self, challenge=None): |
682 | 674 | # CRAM-MD5 does not support initial-response. |
683 | 675 | if challenge is None: |
684 | 676 | return None |
685 | | - if not _have_cram_md5_support(): |
| 677 | + if not _have_cram_md5_support: |
686 | 678 | raise SMTPException("CRAM-MD5 is not supported") |
687 | 679 | password = self.password.encode('ascii') |
688 | 680 | authcode = hmac.HMAC(password, challenge, 'md5') |
@@ -738,7 +730,7 @@ def login(self, user, password, *, initial_response_ok=True): |
738 | 730 | advertised_authlist = self.esmtp_features["auth"].split() |
739 | 731 |
|
740 | 732 | # Authentication methods we can handle in our preferred order: |
741 | | - if _have_cram_md5_support(): |
| 733 | + if _have_cram_md5_support: |
742 | 734 | preferred_auths = ['CRAM-MD5', 'PLAIN', 'LOGIN'] |
743 | 735 | else: |
744 | 736 | preferred_auths = ['PLAIN', 'LOGIN'] |
|
0 commit comments