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 index dac556a..66423c5 100644 --- a/SOURCES/Make-webtest-an-optional-dependency.patch +++ b/SOURCES/Make-webtest-an-optional-dependency.patch @@ -1,4 +1,4 @@ -From 903d77cb73bd6713279f1d9920f5f665293a26c2 Mon Sep 17 00:00:00 2001 +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 diff --git a/SPECS/python-kdcproxy.spec b/SPECS/python-kdcproxy.spec index f1d123a..f264986 100644 --- a/SPECS/python-kdcproxy.spec +++ b/SPECS/python-kdcproxy.spec @@ -14,14 +14,16 @@ Name: python-%{realname} Version: 0.4 -Release: 3%{?dist} +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 +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 @@ -123,6 +125,14 @@ KDCPROXY_ASN1MOD=asn1crypto %{__python3} -m pytest %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