Compare commits

..

No commits in common. "c9511d03fa2b55c7252bae9e450468c805a93822" and "4166ffbf8f74473698fa57857433ce2e3447160f" have entirely different histories.

5 changed files with 8 additions and 224 deletions

BIN
1.2.2.tar.gz Normal file

Binary file not shown.

View File

@ -1,160 +0,0 @@
From 24b6c79c8921cf1800e27ca144f4f37023982bbb Mon Sep 17 00:00:00 2001
From: Login <84237895+The-Login@users.noreply.github.com>
Date: Sat, 2 Mar 2024 15:55:13 +0100
Subject: [PATCH] Merge pull request from GHSA-pr2m-px7j-xg65
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Origin: https://github.com/aio-libs/aiosmtpd/commit/24b6c79c8921cf1800e27ca144f4f37023982bbb
* SMTP Smuggling Fix
Adapted adherence to RFC 5321 § 2.3.8 to fix SMTP smuggling issues (https://www.rfc-editor.org/rfc/rfc5321#section-2.3.8)
* Apply suggestions from code review
Co-authored-by: Sam Bull <git@sambull.org>
* Add files via upload
* Update test_smtpsmuggling.py
---------
Co-authored-by: Sam Bull <git@sambull.org>
---
aiosmtpd/smtp.py | 11 ++--
aiosmtpd/tests/test_smtpsmuggling.py | 79 ++++++++++++++++++++++++++++
2 files changed, 85 insertions(+), 5 deletions(-)
create mode 100644 aiosmtpd/tests/test_smtpsmuggling.py
diff --git a/aiosmtpd/smtp.py b/aiosmtpd/smtp.py
index 39e70d8b..00902c1e 100644
--- a/aiosmtpd/smtp.py
+++ b/aiosmtpd/smtp.py
@@ -87,7 +87,7 @@ class _DataState(enum.Enum):
EMPTY_BARR = bytearray()
EMPTYBYTES = b''
MISSING = _Missing()
-NEWLINE = '\n'
+NEWLINE = '\r\n'
VALID_AUTHMECH = re.compile(r"[A-Z0-9_-]+\Z")
# https://tools.ietf.org/html/rfc3207.html#page-3
@@ -1427,9 +1427,10 @@ async def smtp_DATA(self, arg: str) -> None:
# Since eof_received cancels this coroutine,
# readuntil() can never raise asyncio.IncompleteReadError.
try:
- line: bytes = await self._reader.readuntil()
+ # https://datatracker.ietf.org/doc/html/rfc5321#section-2.3.8
+ line: bytes = await self._reader.readuntil(b'\r\n')
log.debug('DATA readline: %s', line)
- assert line.endswith(b'\n')
+ assert line.endswith(b'\r\n')
except asyncio.CancelledError:
# The connection got reset during the DATA command.
log.info('Connection lost during DATA')
@@ -1446,7 +1447,7 @@ async def smtp_DATA(self, arg: str) -> None:
data *= 0
# Drain the stream anyways
line = await self._reader.read(e.consumed)
- assert not line.endswith(b'\n')
+ assert not line.endswith(b'\r\n')
# A lone dot in a line signals the end of DATA.
if not line_fragments and line == b'.\r\n':
break
@@ -1458,7 +1459,7 @@ async def smtp_DATA(self, arg: str) -> None:
# Discard data immediately to prevent memory pressure
data *= 0
line_fragments.append(line)
- if line.endswith(b'\n'):
+ if line.endswith(b'\r\n'):
# Record data only if state is "NOMINAL"
if state == _DataState.NOMINAL:
line = EMPTY_BARR.join(line_fragments)
diff --git a/aiosmtpd/tests/test_smtpsmuggling.py b/aiosmtpd/tests/test_smtpsmuggling.py
new file mode 100644
index 00000000..b5d37851
--- /dev/null
+++ b/aiosmtpd/tests/test_smtpsmuggling.py
@@ -0,0 +1,79 @@
+# Copyright 2014-2021 The aiosmtpd Developers
+# SPDX-License-Identifier: Apache-2.0
+
+"""Test SMTP smuggling."""
+
+from email.mime.text import MIMEText
+from smtplib import SMTP, SMTP_SSL
+from typing import Generator, Union
+
+import pytest
+import smtplib
+
+from aiosmtpd.controller import Controller
+from aiosmtpd.testing.helpers import ReceivingHandler
+from aiosmtpd.testing.statuscodes import SMTP_STATUS_CODES as S
+
+from aiosmtpd.smtp import SMTP as Server
+from aiosmtpd.smtp import Session as ServerSession
+from aiosmtpd.smtp import Envelope
+
+from .conftest import Global, controller_data, handler_data
+
+from aiosmtpd.testing.helpers import (
+ ReceivingHandler
+)
+
+def new_data(self, msg):
+ self.putcmd("data")
+
+ (code, repl) = self.getreply()
+ if self.debuglevel > 0:
+ self._print_debug('data:', (code, repl))
+ if code != 354:
+ raise SMTPDataError(code, repl)
+ else:
+ ##### Patching input encoding so we can send raw messages
+ #if isinstance(msg, str):
+ # msg = smtplib._fix_eols(msg).encode('ascii')
+ #q = smtplib._quote_periods(msg)
+ #if q[-2:] != smtplib.bCRLF:
+ # q = q + smtplib.bCRLF
+ #q = q + b"." + smtplib.bCRLF
+ q = msg
+ self.send(q)
+ (code, msg) = self.getreply()
+ if self.debuglevel > 0:
+ self._print_debug('data:', (code, msg))
+ return (code, msg)
+
+def return_unchanged(data):
+ return data
+
+class TestSmuggling:
+ @handler_data(class_=ReceivingHandler)
+ def test_smtp_smuggling(self, plain_controller, client):
+ smtplib._fix_eols = return_unchanged
+ smtplib._quote_periods = return_unchanged
+ smtplib.SMTP.data = new_data
+
+ handler = plain_controller.handler
+ sender = "sender@example.com"
+ recipients = ["rcpt1@example.com"]
+ resp = client.helo("example.com")
+ assert resp == S.S250_FQDN
+ # Trying SMTP smuggling with a fake \n.\r\n end-of-data sequence.
+ message_data = b"""\
+From: Anne Person <anne@example.com>\r\n\
+To: Bart Person <bart@example.com>\r\n\
+Subject: A test\r\n\
+Message-ID: <ant>\r\n\
+\r\n\
+Testing\
+\n.\r\n\
+NO SMUGGLING
+\r\n.\r\n\
+"""
+ results = client.sendmail(sender, recipients, message_data)
+ client.quit()
+ assert b"NO SMUGGLING" in handler.box[0].content

View File

@ -1,43 +0,0 @@
From 0360116a634a842b2bbe93528284679587a7c6c2 Mon Sep 17 00:00:00 2001
From: Arusekk <Arusekk@aio-libs>
Date: Mon, 20 May 2024 08:57:18 +0800
Subject: [PATCH] CVE-2024-34083
---
aiosmtpd/docs/NEWS.rst | 5 +++++
aiosmtpd/smtp.py | 3 +++
2 files changed, 8 insertions(+)
diff --git a/aiosmtpd/docs/NEWS.rst b/aiosmtpd/docs/NEWS.rst
index 875ead0..fa8089b 100644
--- a/aiosmtpd/docs/NEWS.rst
+++ b/aiosmtpd/docs/NEWS.rst
@@ -15,6 +15,11 @@ Fixed/Improved
* All Controllers now have more rationale design, as they are now composited from a Base + a Mixin
* A whole bunch of annotations
+1.4.6 (2024-05-06)
+==================
+
+* STARTTLS is now fully enforced if used.
+
1.4.4 (2023-01-17)
==================
diff --git a/aiosmtpd/smtp.py b/aiosmtpd/smtp.py
index 09c85bf..8a20d13 100644
--- a/aiosmtpd/smtp.py
+++ b/aiosmtpd/smtp.py
@@ -504,6 +504,9 @@ class SMTP(asyncio.StreamReaderProtocol):
self._reader._transport = transport
self._writer._transport = transport
self.transport = transport
+ # Discard any leftover unencrypted data
+ # See https://tools.ietf.org/html/rfc3207#page-7
+ self._reader._buffer.clear() # type: ignore[attr-defined]
# Do SSL certificate checking as rfc3207 part 4.1 says. Why is
# _extra a protected attribute?
self.session.ssl = self._tls_protocol._extra
--
2.27.0

Binary file not shown.

View File

@ -1,16 +1,13 @@
%global _empty_manifest_terminate_build 0 %global _empty_manifest_terminate_build 0
Name: python-aiosmtpd Name: python-aiosmtpd
Version: 1.4.4 Version: 1.2.2
Release: 3 Release: 1
Summary: aiosmtpd - asyncio based SMTP server Summary: aiosmtpd - asyncio based SMTP server
License: Apache 2.0 License: Apache 2.0
URL: https://github.com/aio-libs/aiosmtpd URL: https://github.com/aio-libs/aiosmtpd
Source0: https://github.com/aio-libs/aiosmtpd/archive/%{version}.tar.gz#/aiosmtpd-%{version}.tar.gz Source0: https://github.com/aio-libs/aiosmtpd/archive/%{version}.tar.gz
Patch0: CVE-2024-27305.patch
Patch1: CVE-2024-34083.patch
BuildArch: noarch BuildArch: noarch
%description %description
This is a server for SMTP and related protocols, similar in utility to the This is a server for SMTP and related protocols, similar in utility to the
standard library's smtpd.py module, but rewritten to be based on asyncio for standard library's smtpd.py module, but rewritten to be based on asyncio for
@ -18,9 +15,10 @@ Python 3.
%package -n python3-aiosmtpd %package -n python3-aiosmtpd
Summary: aiosmtpd - asyncio based SMTP server Summary: aiosmtpd - asyncio based SMTP server
Provides: python-aiosmtpd = %{version}-%{release} Provides: python-aiosmtpd
BuildRequires: python3-devel BuildRequires: python3-devel
BuildRequires: python3-setuptools BuildRequires: python3-setuptools
%description -n python3-aiosmtpd %description -n python3-aiosmtpd
This is a server for SMTP and related protocols, similar in utility to the This is a server for SMTP and related protocols, similar in utility to the
standard library's smtpd.py module, but rewritten to be based on asyncio for standard library's smtpd.py module, but rewritten to be based on asyncio for
@ -29,11 +27,12 @@ Python 3.
%package help %package help
Summary: Development documents and examples for aiosmtpd Summary: Development documents and examples for aiosmtpd
Provides: python3-aiosmtpd-doc Provides: python3-aiosmtpd-doc
%description help %description help
Development documents and examples for aiosmtpd. Development documents and examples for aiosmtpd.
%prep %prep
%autosetup -n aiosmtpd-%{version} -p1 %autosetup -n aiosmtpd-%{version}
%build %build
%py3_build %py3_build
@ -73,17 +72,5 @@ mv %{buildroot}/doclist.lst .
%{_pkgdocdir} %{_pkgdocdir}
%changelog %changelog
* Mon May 20 2024 lvfei <lvfei@kylinos.cn> - 1.4.4-3 * Thu Dec 17 2020 Python_Bot <Python_Bot@openeuler.org>
- Fix CVE-2024-34083
* Wed Mar 13 2024 wangkai <13474090681@163.com> - 1.4.4-2
- Fix CVE-2024-27305
* Mon Mar 20 2023 jiangxinyu <jiangxinyu@kylinos.cn> - 1.4.4-1
- Update package to version 1.4.4
* Tue Jun 07 2022 SimpleUpdate Robot <tc@openeuler.org> - 1.4.2-1
- Upgrade to version 1.4.2
* Thu Dec 17 2020 Python_Bot <Python_Bot@openeuler.org> - 1.2.2-1
- Package Spec generated - Package Spec generated