Skip to content

Latest commit

 

History

History
409 lines (296 loc) · 15.1 KB

File metadata and controls

409 lines (296 loc) · 15.1 KB

Changelog

5.1.4 (unreleased)

  • Bugfix: SMTPRecipientsRefused now exposes the message attribute shared by all SMTPException subclasses
  • Bugfix: resolve the SMTPProtocol close waiter on connection loss, so asyncio.StreamWriter.wait_closed() on a writer wrapping the protocol no longer hangs forever
  • Bugfix: the async context manager no longer sends QUIT on exit when the block was cancelled, so a timed-out send cannot block for another round trip
  • Bugfix: cancelling sendmail between commands now closes the connection instead of leaving a half-open envelope on the server
  • Bugfix: cancelling a command while waiting for its reply (e.g. via asyncio.wait_for or asyncio.timeout) now closes the connection, so the in-flight reply can no longer be paired with the next command sent
  • Bugfix: sendmail now checks that addresses are encodable and that at least one recipient was given before sending MAIL FROM, so a non-ASCII recipient without SMTPUTF8 or an empty recipient list no longer leaves a half-open envelope on the server. An empty recipient list now raises ValueError (matching send_message and send) instead of SMTPRecipientsRefused
  • Bugfix: data and starttls raise SMTPServerDisconnected instead of AttributeError when the connection is lost during the preceding EHLO
  • Bugfix: sendmail no longer adds its own SIZE parameter to MAIL FROM when the caller already supplied one in mail_options
  • Bugfix: a malformed or oversized server reply now closes the connection. The unparseable bytes were previously left in the buffer, so every later command on the connection failed with the same SMTPResponseException
  • Bugfix: data (and so sendmail, send_message and send) now writes the message in chunks and waits for the transport to accept each one before continuing, so the reply timeout no longer starts until the whole message has been handed off. Previously a large message over a slow link could time out while still uploading, and the client then dropped a message the server went on to deliver. The timeout now bounds inactivity during the upload rather than total upload time, and a stalled upload raises SMTPTimeoutError

5.1.3

  • Security: reject addresses containing whitespace or angle brackets outside of a quoted local part in mail, rcpt, vrfy, expn and sendmail. Previously, a caller supplied address such as user@example.com> AUTH=<attacker@example.com could smuggle additional ESMTP parameters onto the command line. This is a follow up to the fix in 5.1.1 for CVE-2026-53533 (GHSA-v3q9-hj7j-63hq), which only rejected control characters. sendmail now validates all addresses before sending any commands.
  • Bugfix: reject local_hostname values (and the hostname argument to helo/ehlo) containing whitespace or control characters, so a hostname such as me.example.com XCLIENT ADDR=1.2.3.4 can no longer smuggle extra parameters onto the EHLO/HELO command line. Surrounding whitespace is stripped.
  • Bugfix: raise SMTPAuthenticationError instead of binascii.Error when the server sends a malformed (non-base64) CRAM-MD5 challenge, so login can fall back to the next auth method
  • Bugfix: prevent SMTP command/response desync from unsolicited server data (thanks @Charisn for contributing)
  • Bugfix: handle protocol connection lost callback arriving after reconnect
  • Bugfix: close connection on async context manager exit in cases of a server error response
  • Bugfix: release connection lock on connect timeout
  • Bugfix: re-derive the default port on each connect() so changing use_tls/start_tls between connects no longer reuses a stale default. Defaulted port/hostname are now resolved per-connect rather than written back onto the instance, so they read back as None when unset
  • Bugfix: typeerror in latest ty
  • Bugfix: mark response waiter exceptions as retrieved when they are set, so Future exception was never retrieved is no longer logged on free-threaded builds where the previous __del__ based cleanup ran too late
  • CI: test on free-threaded 3.14 and on 3.15 (standard and free-threaded)
  • Bugfix: the SIZE parameter sent with MAIL FROM now reports the number of octets as the message will be transmitted (with CRLF line endings), rather than the raw length of the message argument
  • Bugfix: data arriving on the transport after the connection is lost is now dropped instead of raising RuntimeError from the protocol callback
  • Bugfix: SMTPProtocol now records that it is using TLS after a successful start_tls, so a second upgrade attempt on the protocol is rejected
  • Bugfix: starttls now validates its TLS options before sending EHLO, so invalid options raise ValueError without touching the connection
  • Bugfix: helo no longer records a failed response as last_helo_response, so a rejected HELO does not leave the session looking as if a greeting succeeded
  • Bugfix: bytearray and memoryview values are no longer silently passed through the auth encoding helpers; only str and bytes are accepted, as the type annotations already stated
  • Bugfix: TLS context setup now run in thread (thanks @tr4nt0r)

5.1.2

  • Security: Discard any buffered server data before the STARTTLS handshake, preventing a response-injection attack where a man-in-the-middle pre-stages plaintext that would otherwise be read as part of the encrypted session. More details: https://github.com/cole/aiosmtplib/security/advisories/GHSA-vxj7-4xrp-5vr4
  • Bugfix: Corrected SMTPResponse __repr__ result
  • Bugfix: Calling connect() on an already-connected client now raises SMTPException instead of deadlocking on the connection lock
  • Feature: Poe command runner for dev tasks
  • Bugfix: Timeout ignored during CRAM-MD5 verification
  • Bugfix: Only parse EHLO response after validating success
  • Bugfix: return None from extract_sender when address list is empty
  • Bugfix: Enforce a maximum total response size, preventing unbounded memory use if a server streams data with no line ending or endless multiline continuation lines
  • Bugfix: Use the invalid_response status code (-1) instead of 500 when a server response line exceeds the maximum length
  • Bugfix: A read timeout now closes the connection instead of leaving it in a desynced state, where a late server response could be mispaired with a subsequent command
  • Bugfix: Correctly parse old-style AUTH= extension advertisements; all advertised methods are now kept (e.g. both PLAIN and LOGIN from AUTH=PLAIN LOGIN)
  • Bugfix: ESMTP extension lines with leading whitespace are no longer ignored

5.1.1

  • Security: Reject control characters (the C0 range 0x00-0x1F and DEL 0x7F, including CR, LF, and NUL) in SMTP command arguments, preventing command injection via input passed to mail(), rcpt(), vrfy(), expn() or sendmail(). Such input now raises ValueError before anything is written to the connection. More details: https://github.com/cole/aiosmtplib/security/advisories/GHSA-v3q9-hj7j-63hq Thanks to @tonghuaroot for the report.
  • Bugfix: SMTP.quit() no longer hangs until the read timeout when the peer drops the transport with an exception after QUIT is sent but before the 221 reply is parsed (e.g. AWS SES closing TLS without close_notify).

5.1.0

  • Feature: Add XOAUTH2 authentication support

5.0.0

  • BREAKING: Drop Python 3.9 support

4.0.2

  • Bugfix: correct aexit signature to comply with async context manager protocol (thanks @oliverlambson)

4.0.1

  • Bugfix: Always clear the connect lock on connection lost, allowing client reconnect

4.0.0

  • BREAKING: Drop Python 3.8 support
  • Bugfix: Run socket.getfqdn in thread to avoid blocking event loop if local_hostname not provided (thanks @Raidzin)
  • Bugfix: Clear connect lock on connection lost, allowing client reconnect
  • Bugfix: Allow socket connections to use TLS by providing hostname and use_tls=True

3.0.2

  • Bugfix: Type of "send" is partially unknown with pyright
  • Bugfix: Fix asyncio deadlock trying to reconnect after error (thanks @Voldemat)
  • Change: Switched from Poetry to build/hatch/twine for packaging.

3.0.1

  • Bugfix: 'Future exception was never retrieved' warning in SMTPProtocol after successful connection close and garbage collection.
  • Cleanup: Updated FlowControlMixin logic from stdlib

3.0.0

  • BREAKING: Drop Python 3.7 support.
  • BREAKING: Positional arguments are now positional only, and keyword arguments are keyword only.
  • BREAKING: Passing source_address as a string argument (deprecated in 2.0) is now an error. source_address takes a (addr, port) tuple that is used as the local_addr param of asyncio.create_connection, allowing for binding to a specific IP. The local_hostname argument takes the value to be sent to the server with the EHLO/HELO message (which is what source_address was used for prior to 2.0).
  • Change: don't use timeout value passed to connect everywhere, only for the initial connection (credit @wombatonfire)
  • Change: removed unnecessary connection lost callback
  • Change: revised handling for 'Future exception was never retrieved' warnings in protocol

2.0.2

  • Bugfix: don't send extra EHLO/HELO before QUIT (credit @ikrivosheev)
  • Change: added SMTPConnectionResponseError for invalid response on connect only (credit @ikrivosheev)

2.0.1

  • Bugfix: "tests" and "docs" in the sdist should be includes, not packages, so that they do not get put in site-packages.

2.0.0

  • BREAKING: Drop Python 3.5 and 3.6 support.

  • BREAKING: On connect, if the server supports STARTTLS, automatically try to upgrade the connection. STARTTLS after connect can be turned on or off explicitly by passing start_tls=True or start_tls=False respectively.

  • BREAKING: Remove deprecated loop keyword argument for the SMTP class.

  • Change: The source_address argument now takes a (addr, port) tuple that is passed as the local_addr param to asyncio.create_connection, allowing for binding to a specific IP. The new local_hostname argument that takes the value to be sent to the server with the EHLO/HELO message. This behaviour more closely matches smtplib.

    In order to not break existing usage, passing a string instead of a tuple to source_address will give a DeprecationWarning, and use the value as it if had been passed for local_hostname.

    Thanks @rafaelrds and @davidmcnabnz for raising and contributing work on this issue.

  • Bugfix: the mail_options and rcpt_options arguments to the send coroutine no longer cause errors

  • Cleanup: Refactored SMTP parent classes to remove complex inheritance structure.

  • Cleanup: Switched to asyncio.run for sync client methods.

  • Cleanup: Don't use private email.message.Message policy attribute (instead, set an appropriate policy based on message class)

1.1.7

  • Security: Fix a possible injection vulnerability (a variant of https://consensys.net/diligence/vulnerabilities/python-smtplib-multiple-crlf-injection/)

    Note that in order to exploit this vulnerability in aiosmtplib, the attacker would need control of the hostname or source_address parameters. Thanks Sam Sanoop @ Snyk for bringing this to my attention.

  • Bugfix: include CHANGLOG in sdist release

  • Type hints: fix type hints for async context exit (credit @JelleZijlstra)

1.1.6

  • Bugfix: fix authenticated test failures (credit @P-EB)

1.1.5

  • Bugfix: avoid raising asyncio.CancelledError on connection lost
  • Bugfix: allow UTF-8 chars in usernames and password strings
  • Feature: allow bytes type args for login usernames and passwords

1.1.4

  • Bugfix: parsing comma separated addresses in to header (credit @gjcarneiro)
  • Feature: add py.typed file (PEP 561, credit @retnikt)

1.1.3

  • Feature: add pause and resume writing methods to SMTPProcotol, via asyncio.streams.FlowControlMixin (thanks @ikrivosheev).
  • Bugfix: allow an empty sender (credit @ikrivosheev)
  • Cleanup: more useful error message when login called without TLS

1.1.2

  • Bugfix: removed docs and tests from wheel, they should only be in the source distribution.

1.1.1

  • Bugfix: Fix handling of sending legacy email API (Message) objects.
  • Bugfix: Fix SMTPNotSupported error with UTF8 sender/recipient names on servers that don't support SMTPUTF8.

1.1.0

  • Feature: Added send coroutine api.
  • Feature: Added SMTPUTF8 support for UTF8 chars in addresses.
  • Feature: Added connected socket and Unix socket path connection options.
  • Feature: Wait until the connect coroutine is awaited to get the event loop. Passing an explicit event loop via the loop keyword argument is deprecated and will be removed in version 2.0.
  • Cleanup: Set context for timeout and connection exceptions properly.
  • Cleanup: Use built in start_tls method on Python 3.7+.
  • Cleanup: Timeout correctly if TLS handshake takes too long on Python 3.7+.
  • Cleanup: Updated SMTPProcotol class and removed StreamReader/StreamWriter usage to remove deprecation warnings in 3.8.
  • Bugfix: EHLO/HELO if required before any command, not just when using higher level commands.
  • Cleanup: Replaced asserts in functions with more useful errors (e.g. RuntimeError).
  • Cleanup: More useful error messages for timeouts (thanks ikrivosheev!), including two new exception classes, SMTPConnectTimeoutError and SMTPReadTimeoutError

1.0.6

  • Bugfix: Set default timeout to 60 seconds as per documentation (previously it was unlimited).

1.0.5

  • Bugfix: Connection is now closed if an error response is received immediately after connecting.

1.0.4

  • Bugfix: Badly encoded server response messages are now decoded to utf-8, with error chars escaped.
  • Cleanup: Removed handling for exceptions not raised by asyncio (in SMTPProtocol._readline)

1.0.3

  • Bugfix: Removed buggy close connection on __del__
  • Bugfix: Fixed old style auth method parsing in ESMTP response.
  • Bugfix: Cleanup transport on exception in connect method.
  • Cleanup: Simplified SMTPProtocol.connection_made, __main__

1.0.2

  • Bugfix: Close connection lock on on SMTPServerDisconnected
  • Feature: Added cert_bundle argument to connection init, connect and starttls methods
  • Bugfix: Disconnected clients would raise SMTPResponseException: (-1 ...) instead of SMTPServerDisconnected

1.0.1

  • Bugfix: Commands were getting out of order when using the client as a context manager within a task
  • Bugfix: multiple tasks calling connect would get confused
  • Bugfix: EHLO/HELO responses were being saved even after disconnect
  • Bugfix: RuntimeError on client cleanup if event loop was closed
  • Bugfix: CRAM-MD5 auth was not working
  • Bugfix: AttributeError on STARTTLS under uvloop

1.0.0

Initial feature complete release with stable API; future changes will be documented here.