diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3637a4a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/kdcproxy-0.4.tar.gz diff --git a/.python-kdcproxy.metadata b/.python-kdcproxy.metadata new file mode 100644 index 0000000..bdd2b2d --- /dev/null +++ b/.python-kdcproxy.metadata @@ -0,0 +1 @@ +48cffec358fe9e15a66fb040b6b7fc87f642f6da SOURCES/kdcproxy-0.4.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..33a6a06 --- /dev/null +++ b/SOURCES/Always-buffer-TCP-data-in-__handle_recv.patch @@ -0,0 +1,84 @@ +From c1be487bb00f2e813212031d93fcebbfbd0da60b 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 6526bc9..9bc7044 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/Correct-addrs-sorting-to-be-by-TCP-UDP.patch b/SOURCES/Correct-addrs-sorting-to-be-by-TCP-UDP.patch new file mode 100644 index 0000000..46464ea --- /dev/null +++ b/SOURCES/Correct-addrs-sorting-to-be-by-TCP-UDP.patch @@ -0,0 +1,28 @@ +From 5cfde6d085320da3fb5d4c6506e6d6253438669c Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 2 Aug 2019 13:54:05 -0400 +Subject: [PATCH] Correct addrs sorting to be by TCP/UDP + +Fixes any potential cases where the resolver might yield UDP addresses +first. + +Signed-off-by: Robbie Harwood +(cherry picked from commit d0b35c2b71a172f409b4311d36538d8fa3433c58) +--- + kdcproxy/__init__.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kdcproxy/__init__.py b/kdcproxy/__init__.py +index c59f2b3..6526bc9 100644 +--- a/kdcproxy/__init__.py ++++ b/kdcproxy/__init__.py +@@ -227,7 +227,8 @@ class Application: + # + # Stick a None address on the end so we can get one + # more attempt after all servers have been contacted. +- addrs = tuple(sorted(filter(self.__filter_addr, addrs))) ++ addrs = tuple(sorted(filter(self.__filter_addr, addrs), ++ key=lambda a: a[2])) + for addr in addrs + (None,): + if addr is not None: + # Bypass unspecified socktypes diff --git a/SOURCES/Make-webtest-an-optional-dependency.patch b/SOURCES/Make-webtest-an-optional-dependency.patch new file mode 100644 index 0000000..66423c5 --- /dev/null +++ b/SOURCES/Make-webtest-an-optional-dependency.patch @@ -0,0 +1,36 @@ +From 2164f10fe5d992006f42c4a8d682f23b04ffbf12 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Thu, 9 Aug 2018 14:57:56 -0400 +Subject: [PATCH] Make webtest an optional dependency + +Resolves: #38 +(cherry picked from commit c0bee88c60deb176d420d90447d24c370d70727a) +--- + tests.py | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/tests.py b/tests.py +index 992529f..c2b1fc0 100644 +--- a/tests.py ++++ b/tests.py +@@ -33,7 +33,11 @@ from dns.rdataclass import IN as RDCLASS_IN + from dns.rdatatype import SRV as RDTYPE_SRV + from dns.rdtypes.IN.SRV import SRV + +-from webtest import TestApp as WebTestApp ++try: ++ from webtest import TestApp as WebTestApp ++except ImportError: ++ print("webtest not installed! Tests will be skipped") ++ WebTestApp = "skip" + + import kdcproxy + from kdcproxy import codec +@@ -45,6 +49,7 @@ HERE = os.path.dirname(os.path.abspath(__file__)) + KRB5_CONFIG = os.path.join(HERE, 'tests.krb5.conf') + + ++@unittest.skipIf(WebTestApp == "skip", "webtest not installed") + class KDCProxyWSGITests(unittest.TestCase): + addrinfo = [ + (2, 1, 6, '', ('128.66.0.2', 88)), diff --git a/SPECS/python-kdcproxy.spec b/SPECS/python-kdcproxy.spec new file mode 100644 index 0000000..f264986 --- /dev/null +++ b/SPECS/python-kdcproxy.spec @@ -0,0 +1,213 @@ +%global realname kdcproxy + +%if 0%{?fedora} || 0%{?rhel} > 7 +%global with_python3 1 +%else +%global with_python3 0 +%endif + +%if 0%{?fedora} || 0%{?rhel} <= 7 +%global with_python2 1 +%else +%global with_python2 0 +%endif + +Name: python-%{realname} +Version: 0.4 +Release: 5%{?dist} +Summary: MS-KKDCP (kerberos proxy) WSGI module + +License: MIT +URL: https://github.com/npmccallum/%{realname} +Source0: https://github.com/npmccallum/%{realname}/archive/%{realname}-%{version}.tar.gz + +Patch0: Make-webtest-an-optional-dependency.patch +Patch1: Correct-addrs-sorting-to-be-by-TCP-UDP.patch +Patch2: Always-buffer-TCP-data-in-__handle_recv.patch + +BuildArch: noarch +BuildRequires: git + +%if 0%{?with_python2} > 0 +BuildRequires: python2-devel +BuildRequires: python2-pytest +BuildRequires: python2-coverage +BuildRequires: python2-asn1crypto +BuildRequires: python2-dns +BuildRequires: python2-mock +%endif + +%if 0%{?with_python3} > 0 +BuildRequires: python3-devel +BuildRequires: python3-pytest +BuildRequires: python3-coverage +BuildRequires: python3-asn1crypto +BuildRequires: python3-dns +BuildRequires: python3-mock +%endif + + +%description +This package contains a Python 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%{?with_python2} > 0 +%package -n python2-%{realname} +Summary: MS-KKDCP (kerberos proxy) WSGI module +Requires: python2-dns +Requires: python2-asn1crypto + +%{?python_provide:%python_provide python2-%{realname}} + +%description -n python2-%{realname} +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. +%endif + +%if 0%{?with_python3} > 0 +%package -n python3-%{realname} +Summary: MS-KKDCP (kerberos proxy) WSGI module +Requires: python3-dns +Requires: python3-asn1crypto + +%{?python_provide:%python_provide python3-%{realname}} + +%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 +%autosetup -S git -n %{realname}-%{version} + + +%build +%if 0%{?with_python2} > 0 +%py2_build +%endif +%if 0%{?with_python3} > 0 +%py3_build +%endif + +%install +%if 0%{?with_python2} > 0 +%py2_install +%endif +%if 0%{?with_python3} > 0 +%py3_install +%endif + +%check +%if 0%{?with_python2} > 0 +KDCPROXY_ASN1MOD=asn1crypto %{__python2} -m pytest +%endif +%if 0%{?with_python3} > 0 +KDCPROXY_ASN1MOD=asn1crypto %{__python3} -m pytest +%endif + +%if 0%{?with_python2} > 0 +%files -n python2-%{realname} +%doc README +%license COPYING +%{python2_sitelib}/%{realname}/ +%{python2_sitelib}/%{realname}-%{version}-*.egg-info +%endif + +%if 0%{?with_python3} > 0 +%files -n python3-%{realname} +%doc README +%license COPYING +%{python3_sitelib}/%{realname}/ +%{python3_sitelib}/%{realname}-%{version}-*.egg-info +%endif + +%changelog +* Fri Oct 25 2019 Robbie Harwood - 0.4-5 +- Always buffer TCP data in __handle_recv() +- Resolves: #1747144 + +* Fri Oct 25 2019 Robbie Harwood - 0.4-4 +- Correct addrs sorting to be by TCP/UDP +- Resolves: #1732898 + +* Mon Nov 19 2018 Thomas Woerner - 0.4-3 +- Bump release to be able to add python-kdcpoxy to the idm module + Resolves: RHBZ#1639332 + +* Thu Aug 09 2018 Robbie Harwood - 0.4-2 +- Update dependencies in test suite + +* Thu Aug 09 2018 Robbie Harwood - 0.4-1 +- New upstream release - 0.4 +- Port to autosetup + +* Sat Jul 14 2018 Fedora Release Engineering - 0.3.2-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Jun 19 2018 Miro Hrončok - 0.3.2-13 +- Rebuilt for Python 3.7 + +* Thu Mar 22 2018 Troy Dawson - 0.3.2-12 +- Update conditionals. +- Make preperations for non-python2 builds + +* Mon Feb 12 2018 Iryna Shcherbina - 0.3.2-11 +- Update Python 2 dependency declarations to new packaging standards + (See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3) + +* Fri Feb 09 2018 Fedora Release Engineering - 0.3.2-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Sep 05 2017 Igor Gnatenko - 0.3.2-9 +- Ignore test results + +* Thu Jul 27 2017 Fedora Release Engineering - 0.3.2-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Sat Feb 11 2017 Fedora Release Engineering - 0.3.2-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Jan 16 2017 Charalampos Stratakis - 0.3.2-6 +- Fix failing tests +- Modernize the SPEC file + +* Mon Dec 19 2016 Miro Hrončok - 0.3.2-5 +- Rebuild for Python 3.6 +- BR /usr/bin/tox instead of python-tox +- Use %%{python3_version_nodots} instead of hardcoded 35 + +* Tue Jul 19 2016 Fedora Release Engineering - 0.3.2-4 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Thu Feb 04 2016 Fedora Release Engineering - 0.3.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Tue Nov 10 2015 Fedora Release Engineering - 0.3.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Changes/python3.5 + +* 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