email.generator.Generator ignores policy when using `multipart/signed` → ruins signing

Abierto
#99,533 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
25/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Estancado
Stack tecnológico
python
Área
backend

Línea de trabajo

Comienza con Lib/email/generator.py en _handle_multipart_signed y reproduce el problema usando el ejemplo de EmailMessage con multipart/signed y un nombre de archivo largo. Revisa el trabajo enlazado en gh-100204 y las pruebas relevantes del paquete email; se considera terminado cuando la parte firmada conserva la policy prevista y la serialización de las cabeceras sin romper el comportamiento multipart existente.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

stdlib topic-email type-bug

Bug report

EmailMessage behaves differently when being set to multipart/signed mimetype.

from email.message import EmailMessage

inner = EmailMessage()
inner.add_attachment("some data", "text/plain", filename="*"*35)

outer1 = EmailMessage()
outer1.set_type("multipart/signed")  # affected by generator.py/_handle_multipart_signed
outer1.attach(inner)

outer2 = EmailMessage()
outer2.set_type("multipart/signeX")  # not affected by generator.py/_handle_multipart_signed
outer2.attach(inner)

# When accessing given submessage, nothing weird happens
outer1.get_payload()[0].as_string() == outer2.get_payload()[0].as_string()  # True

# However, when accessing whole message at once, headers folding change for the outer1 `multipart/signed` message
inner.as_string() in outer1.as_string()  # !False!
inner.as_string() in outer2.as_string()  # True

This is due to a 13 years old generator.py code that for an unknown reason rewrites the policy so that no header was folded:

    def _handle_multipart_signed(self, msg):
        # The contents of signed parts has to stay unmodified in order to keep
        # the signature intact per RFC1847 2.1, so we disable header wrapping.
        # RDM: This isn't enough to completely preserve the part, but it helps.
        p = self.policy
        self.policy = p.clone(max_line_length=0)
        try:
            self._handle_multipart(msg)
        finally:
            self.policy = p

As a result, when I GPG-sign the inner message and attach it to a wrapping-outer message along with the signature (which is the right thing), the signature is void because policy being ignored, the headers folding got disabled on the output. I understand the method _handle_multipart_signed should help the message signing but it ruins it instead. One dirty solution would be to set the policy to max_line_length=0 which fails for whatever reason:

from email import policy
pol = policy.default.clone(max_line_length=0)
inner = EmailMessage(policy=pol)
inner.add_attachment("some data", "text/plain", filename="*"*35)  # ValueError: maxlinelen must be at least 4

Therefore, I am not able to sign the inner message with the headers fold (as it is output unfold), not I am able to sign the inner message with the headers unfold (as ValueError prevents me to set the policy to not stop folding headers).

So my proposal is to remove _handle_multipart_signed altogether (which would be sufficient) or to find a use-case where it does make sense (I could not find any).

Your environment

  • CPython versions tested on: Python 3.10.6
  • Operating system and architecture: Ubuntu 22.04.1 LTS x86_64
Linked PRs
  • gh-100204
Lenguaje dominante
Python
Estrellas
77.2k
Forks
36k
Merge medio
1 d 9 h
PR fusionados (30 d)
558

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de python/cpython

Todos los issues de python/cpython

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.