Skip to content

Commit

Permalink
Make channel binding data per-host
Browse files Browse the repository at this point in the history
Previously, once you successfully generated channel binding data for one
host, it would be stored in self.cbt_struct, and self.cbt_binding_tried
would be set to True, preventing ever recalculating self.cbt_struct.
This means that once you used an HTTPKerberosAuth object to talk to one
host, it would keep sending that channel binding data to other hosts,
resulting in failures for servers that enforce channel binding.

Instead, store CBTs in a per-host dictionary as we do with GSSAPI
contexts.
  • Loading branch information
geofft committed Feb 11, 2023
1 parent cf45bba commit 1ede418
Showing 1 changed file with 13 additions and 12 deletions.
25 changes: 13 additions & 12 deletions requests_kerberos/kerberos_.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,7 @@ def __init__(

# Set the CBT values populated after the first response
self.send_cbt = send_cbt
self.cbt_binding_tried = False
self.cbt_struct = None
self._cbts = {}

def generate_request_header(self, response, host, is_preemptive=False):
"""
Expand Down Expand Up @@ -214,7 +213,7 @@ def generate_request_header(self, response, host, is_preemptive=False):
username=self.principal,
hostname=kerb_host,
service=self.service,
channel_bindings=self.cbt_struct,
channel_bindings=self._cbts.get(host, None),
context_req=gssflags,
protocol="kerberos",
)
Expand Down Expand Up @@ -371,16 +370,18 @@ def handle_response(self, response, **kwargs):
num_407s = kwargs.pop('num_407s', 0)

# Check if we have already tried to get the CBT data value
if not self.cbt_binding_tried and self.send_cbt:
if self.send_cbt:
host = urlparse(response.url).hostname
# If we haven't tried, try getting it now
cbt_application_data = _get_channel_bindings_application_data(response)
if cbt_application_data:
self.cbt_struct = spnego.channel_bindings.GssChannelBindings(
application_data=cbt_application_data,
)

# Regardless of the result, set tried to True so we don't waste time next time
self.cbt_binding_tried = True
if host not in self._cbts:
cbt_application_data = _get_channel_bindings_application_data(response)
if cbt_application_data:
self._cbts[host] = spnego.channel_bindings.GssChannelBindings(
application_data=cbt_application_data,
)
else:
# Store None so we don't waste time next time
self._cbts[host] = None

if self.pos is not None:
# Rewind the file position indicator of the body to where
Expand Down

0 comments on commit 1ede418

Please sign in to comment.