diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..769c6b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/v0.3.2.tar.gz diff --git a/.python-kdcproxy.metadata b/.python-kdcproxy.metadata new file mode 100644 index 0000000..15ad324 --- /dev/null +++ b/.python-kdcproxy.metadata @@ -0,0 +1 @@ +1272d602e088e8608d3c02d6eb7c29c74c46c8e2 SOURCES/v0.3.2.tar.gz diff --git a/SOURCES/Always-buffer-TCP-data-in-__handle_recv.patch b/SOURCES/Always-buffer-TCP-data-in-__handle_recv.patch new file mode 100644 index 0000000..4a8e6ea --- /dev/null +++ b/SOURCES/Always-buffer-TCP-data-in-__handle_recv.patch @@ -0,0 +1,84 @@ +From 0472f5b12beb845515b6ef8a339b7223189112fd Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Thu, 29 Aug 2019 11:13:41 -0400 +Subject: [PATCH] Always buffer TCP data in __handle_recv() + +Refactor __handle_recv() to always create a BytesIO() object for TCP +data. Linearize control flow for ease of debugging. Always apply +length checks so that we don't have to wait for EOF in the multiple-recv +case. + +Fixes a bug where we wouldn't return any data because we never received +the EOF, or didn't receive it fast enough. + +Signed-off-by: Robbie Harwood +(cherry picked from commit 7e2b1ab27b843c220fe301b74bab01ed61b0f59a) +--- + kdcproxy/__init__.py | 54 +++++++++++++++++++++++++------------------- + 1 file changed, 31 insertions(+), 23 deletions(-) + +diff --git a/kdcproxy/__init__.py b/kdcproxy/__init__.py +index ab6ed8a..67680c5 100644 +--- a/kdcproxy/__init__.py ++++ b/kdcproxy/__init__.py +@@ -128,29 +128,37 @@ class Application: + # length prefix. So add it. + reply = struct.pack("!I", len(reply)) + reply + return reply +- else: +- # TCP is a different story. The reply must be buffered +- # until the full answer is accumulated. +- buf = read_buffers.get(sock) +- part = sock.recv(1048576) +- if buf is None: +- if len(part) > 4: +- # got enough data in the initial package. Now check +- # if we got the full package in the first run. +- (length, ) = struct.unpack("!I", part[0:4]) +- if length + 4 == len(part): +- return part +- read_buffers[sock] = buf = io.BytesIO() +- +- if part: +- # data received, accumulate it in a buffer +- buf.write(part) +- return None +- else: +- # EOF received +- read_buffers.pop(sock) +- reply = buf.getvalue() +- return reply ++ ++ # TCP is a different story. The reply must be buffered until the full ++ # answer is accumulated. ++ buf = read_buffers.get(sock) ++ if buf is None: ++ read_buffers[sock] = buf = io.BytesIO() ++ ++ part = sock.recv(1048576) ++ if not part: ++ # EOF received. Return any incomplete data we have on the theory ++ # that a decode error is more apparent than silent failure. The ++ # client will fail faster, at least. ++ read_buffers.pop(sock) ++ reply = buf.getvalue() ++ return reply ++ ++ # Data received, accumulate it in a buffer. ++ buf.write(part) ++ ++ reply = buf.getvalue() ++ if len(reply) < 4: ++ # We don't have the length yet. ++ return None ++ ++ # Got enough data to check if we have the full package. ++ (length, ) = struct.unpack("!I", reply[0:4]) ++ if length + 4 == len(reply): ++ read_buffers.pop(sock) ++ return reply ++ ++ return None + + def __filter_addr(self, addr): + if addr[0] not in (socket.AF_INET, socket.AF_INET6): diff --git a/SOURCES/Downgrade-socket-problems-to-warnings.patch b/SOURCES/Downgrade-socket-problems-to-warnings.patch new file mode 100644 index 0000000..5eeabac --- /dev/null +++ b/SOURCES/Downgrade-socket-problems-to-warnings.patch @@ -0,0 +1,45 @@ +From 9ee34b339ccf0525dc3f724c22120338156353f6 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 3 Jul 2018 15:04:28 -0400 +Subject: [PATCH] Downgrade socket problems to warnings + +Previously, these were logged at exception - which logs at ERROR and +prints a traceback. This led to two problems: first, that they're not +kdcproxy errors (rather problems with the other end); and second, that +the traceback is quite noisy. Log a simplified version of the +exception instead of the traceback. + +In the process, correct the sendall() error message to refer to +sendall(), not recv(). + +(cherry picked from commit 074fda5394b5ae201da1ceb6d61ad55f8557db50) +--- + kdcproxy/__init__.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/kdcproxy/__init__.py b/kdcproxy/__init__.py +index 9fc1418..ab6ed8a 100644 +--- a/kdcproxy/__init__.py ++++ b/kdcproxy/__init__.py +@@ -99,8 +99,8 @@ class Application: + else: + sock.sendall(pr.request) + extra = 10 # New connections get 10 extra seconds +- except Exception: +- logging.exception('Error in recv() of %s', sock) ++ except Exception as e: ++ logging.warning("Conection broken while writing (%s)", e) + continue + rsocks.append(sock) + wsocks.remove(sock) +@@ -108,8 +108,8 @@ class Application: + for sock in r: + try: + reply = self.__handle_recv(sock, read_buffers) +- except Exception: +- logging.exception('Error in recv() of %s', sock) ++ except Exception as e: ++ logging.warning("Connection broken while reading (%s)", e) + if self.sock_type(sock) == socket.SOCK_STREAM: + # Remove broken TCP socket from readers + rsocks.remove(sock) diff --git a/SPECS/python-kdcproxy.spec b/SPECS/python-kdcproxy.spec new file mode 100644 index 0000000..16fdbc1 --- /dev/null +++ b/SPECS/python-kdcproxy.spec @@ -0,0 +1,122 @@ +%global realname kdcproxy + +Name: python-%{realname} +Version: 0.3.2 +Release: 3%{?dist} +Summary: MS-KKDCP (kerberos proxy) WSGI module + +License: MIT +URL: https://github.com/npmccallum/%{realname} +Source0: https://github.com/npmccallum/%{realname}/archive/v%{version}.tar.gz + +BuildArch: noarch +BuildRequires: python2-devel + +Patch0: Downgrade-socket-problems-to-warnings.patch +Patch1: Always-buffer-TCP-data-in-__handle_recv.patch + +%if 0%{?rhel} == 0 +BuildRequires: python-tox +BuildRequires: pytest +BuildRequires: python-coverage +BuildRequires: python-webtest +BuildRequires: python-pyasn1 +BuildRequires: python-dns +BuildRequires: python-mock + +BuildRequires: python3-devel +BuildRequires: python3-pytest +BuildRequires: python3-coverage +BuildRequires: python3-webtest +BuildRequires: python3-pyasn1 +BuildRequires: python3-dns +BuildRequires: python3-mock +%endif + +Requires: python-dns +Requires: python-pyasn1 + +%description +This package contains a Python 2.x WSGI module for proxying KDC requests over +HTTP by following the MS-KKDCP protocol. It aims to be simple to deploy, with +minimal configuration. + +%if 0%{?rhel} == 0 +%package -n python3-%{realname} +Summary: MS-KKDCP (kerberos proxy) WSGI module +Requires: python3-dns +Requires: python3-pyasn1 + +%description -n python3-%{realname} +This package contains a Python 3.x WSGI module for proxying KDC requests over +HTTP by following the MS-KKDCP protocol. It aims to be simple to deploy, with +minimal configuration. +%endif + +%prep +%setup -q -n %{realname}-%{version} +%patch0 -p1 -b .Downgrade-socket-problems-to-warnings +%patch1 -p1 -b .Always-buffer-TCP-data-in-__handle_recv + +%build +%{__python} setup.py build + +%install +rm -rf $RPM_BUILD_ROOT +%{__python2} setup.py install --skip-build --root $RPM_BUILD_ROOT +find $RPM_BUILD_ROOT%{python_sitelib}/%{realname}/ -name '*.py' -exec chmod 755 '{}' \; + +%if 0%{?rhel} == 0 +%{__python3} setup.py install --skip-build --root $RPM_BUILD_ROOT +find $RPM_BUILD_ROOT%{python3_sitelib}/%{realname}/ -name '*.py' -exec chmod 755 '{}' \; +%endif + +%check +%if 0%{?rhel} == 0 +tox --sitepackages -e py27,py34 +%endif + +%files +%doc COPYING README +%{python_sitelib}/%{realname} +%{python_sitelib}/%{realname}-%{version}-*.egg-info + +%if 0%{?rhel} == 0 +%files -n python3-%{realname} +%doc COPYING README +%{python3_sitelib}/%{realname} +%{python3_sitelib}/%{realname}-%{version}-*.egg-info +%endif + +%changelog +* Tue Sep 03 2019 Robbie Harwood - 0.3.2-3 +- Always buffer TCP data in __handle_recv() +- Resolves: #1746107 + +* Mon Dec 17 2018 Robbie Harwood - 0.3.2-2 +- Downgrade socket problems to warnings +- Resolves: #1525925 + +* Mon Aug 03 2015 Nathaniel McCallum - 0.3.2-1 +- Update to 0.3.2 +- Fixes CVE-2015-5159 + +* Wed Jul 22 2015 Nathaniel McCallum - 0.3.1-1 +- Update to 0.3.1 + +* Thu Jun 18 2015 Fedora Release Engineering - 0.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed Jun 10 2015 Nathaniel McCallum - 0.3-1 +- Update to 0.3 +- Run tests in Fedora (not RHEL due to python-tox) + +* Fri Oct 24 2014 Nathaniel McCallum - 0.2.1-1 +- Update to 0.2.1 + +* Thu Oct 23 2014 Nathaniel McCallum - 0.2-1 +- Update to 0.2 +- Fix EPEL7 build + +* Tue Jan 21 2014 Nathaniel McCallum - 0.1.1-1 +- Initial package