Skip to content

logging.handlers.SMTPHandler: secure argument is broken in Python 3.12+ #127712

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
s-hamann opened this issue Dec 6, 2024 · 0 comments
Closed
Labels
3.12 only security fixes 3.13 bugs and security fixes 3.14 bugs and security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@s-hamann
Copy link
Contributor

s-hamann commented Dec 6, 2024

Bug report

Bug description:

The documentation for logging.handlers.SMTPHandler describes the secure argument as follows:

To specify the use of a secure protocol (TLS), pass in a tuple to the secure argument. This will only be used when authentication credentials are supplied. The tuple should be either an empty tuple, or a single-value tuple with the name of a keyfile, or a 2-value tuple with the names of the keyfile and certificate file. (This tuple is passed to the smtplib.SMTP.starttls() method.)

However, from Python 3.12 on, only the empty tuple actually works.
With a single-value-tuple or a two-value-tuple, smtplib.SMTP.starttls() throws an exception like this:

Traceback (most recent call last):
  File "/usr/lib/python3.13/logging/handlers.py", line 1097, in emit
    smtp.starttls(*self.secure)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^
TypeError: SMTP.starttls() takes 1 positional argument but 3 were given

The reason seems immediately obvious from the last sentence in the description of the secure argument: The tuple is passed to smtplib.SMTP.starttls().
The documentation for this method states:

Changed in version 3.12: The deprecated keyfile and certfile parameters have been removed.

SMTPHandler still relies on the these parameters.

Here's a minimal script to reproduce the error (requires a mocked SMTP server on port 1025):

#!/usr/bin/env python3

import logging
from logging.handlers import SMTPHandler

logger = logging.getLogger()
handler = SMTPHandler(
    mailhost=("localhost", 1025),
    fromaddr="foo@localhost",
    toaddrs="bar@localhost",
    subject="Test",
    credentials=("foo", "bar"),
    secure=(
        "/path/to/private.key",
        "/path/to/cert.pem"
    ),
)
logger.addHandler(handler)
logger.error("SMTPHandler is broken")

Note that Python 3.11 is not affected and the above code successfully attempts to issue a STARTTLS command.

CPython versions tested on:

3.11, 3.12, 3.13

Operating systems tested on:

Linux

Linked PRs

@s-hamann s-hamann added the type-bug An unexpected behavior, bug, or error label Dec 6, 2024
@skirpichev skirpichev added the stdlib Python modules in the Lib dir label Dec 6, 2024
@picnixz picnixz added 3.12 only security fixes 3.13 bugs and security fixes 3.14 bugs and security fixes labels Dec 8, 2024
vsajip pushed a commit that referenced this issue Feb 10, 2025
…H-127726)

GH-127712: Fix `secure` argument of `logging.handlers.SMTPHandler`

Python 3.12 removed support for the `keyfile` and `certfile` parameters
in `smtplib.SMTP.starttls()`, requiring a `ssl.SSLContext` instead.
`SMTPHandler` now creates a context from the `secure` tuple and passes
that to `starttls`.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Feb 10, 2025
…er` (pythonGH-127726)

pythonGH-127712: Fix `secure` argument of `logging.handlers.SMTPHandler`

Python 3.12 removed support for the `keyfile` and `certfile` parameters
in `smtplib.SMTP.starttls()`, requiring a `ssl.SSLContext` instead.
`SMTPHandler` now creates a context from the `secure` tuple and passes
that to `starttls`.
(cherry picked from commit d7672e5)

Co-authored-by: s-hamann <[email protected]>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Feb 10, 2025
…er` (pythonGH-127726)

pythonGH-127712: Fix `secure` argument of `logging.handlers.SMTPHandler`

Python 3.12 removed support for the `keyfile` and `certfile` parameters
in `smtplib.SMTP.starttls()`, requiring a `ssl.SSLContext` instead.
`SMTPHandler` now creates a context from the `secure` tuple and passes
that to `starttls`.
(cherry picked from commit d7672e5)

Co-authored-by: s-hamann <[email protected]>
vsajip pushed a commit that referenced this issue Feb 10, 2025
vsajip pushed a commit that referenced this issue Feb 10, 2025
@vsajip vsajip closed this as completed Feb 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 only security fixes 3.13 bugs and security fixes 3.14 bugs and security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
Development

No branches or pull requests

4 participants