|
1 | | -import kerberos |
2 | 1 | import re |
3 | 2 | import logging |
4 | 3 |
|
| 4 | +import gssapi |
| 5 | + |
5 | 6 | from requests.auth import AuthBase |
6 | 7 | from requests.models import Response |
7 | 8 | from requests.compat import urlparse, StringIO |
@@ -102,56 +103,45 @@ def generate_request_header(self, response, host, is_preemptive=False): |
102 | 103 |
|
103 | 104 | """ |
104 | 105 |
|
105 | | - # Flags used by kerberos module. |
106 | | - gssflags = kerberos.GSS_C_MUTUAL_FLAG | kerberos.GSS_C_SEQUENCE_FLAG |
| 106 | + gssflags = [gssapi.RequirementFlag.mutual_authentication, |
| 107 | + gssapi.RequirementFlag.out_of_sequence_detection] |
107 | 108 | if self.delegate: |
108 | | - gssflags |= kerberos.GSS_C_DELEG_FLAG |
| 109 | + gssflags.append(gssapi.RequirementFlag.delegate_to_peer) |
109 | 110 |
|
110 | 111 | try: |
111 | | - kerb_stage = "authGSSClientInit()" |
112 | 112 | # contexts still need to be stored by host, but hostname_override |
113 | 113 | # allows use of an arbitrary hostname for the kerberos exchange |
114 | 114 | # (eg, in cases of aliased hosts, internal vs external, CNAMEs |
115 | 115 | # w/ name-based HTTP hosting) |
116 | 116 | kerb_host = self.hostname_override if self.hostname_override is not None else host |
117 | 117 | kerb_spn = "{0}@{1}".format(self.service, kerb_host) |
118 | 118 |
|
119 | | - result, self.context[host] = kerberos.authGSSClientInit(kerb_spn, |
120 | | - gssflags=gssflags, principal=self.principal) |
121 | | - |
122 | | - if result < 1: |
123 | | - raise EnvironmentError(result, kerb_stage) |
124 | | - |
125 | | - # if we have a previous response from the server, use it to continue |
126 | | - # the auth process, otherwise use an empty value |
127 | | - negotiate_resp_value = '' if is_preemptive else _negotiate_value(response) |
128 | | - |
129 | | - kerb_stage = "authGSSClientStep()" |
130 | | - result = kerberos.authGSSClientStep(self.context[host], |
131 | | - negotiate_resp_value) |
| 119 | + creds = None |
| 120 | + if self.principal: |
| 121 | + gss_stage = "acquiring credentials" |
| 122 | + creds = gssapi.Credentials(name=gssapi.Name(self.principal), |
| 123 | + usage="initiate") |
132 | 124 |
|
133 | | - if result < 0: |
134 | | - raise EnvironmentError(result, kerb_stage) |
| 125 | + gss_stage = "initiating context" |
| 126 | + self.context[host] = gssapi.SecurityContext( |
| 127 | + usage="initiate", flags=gssflags, name=gssapi.Name(kerb_spn), |
| 128 | + creds=creds) |
135 | 129 |
|
136 | | - kerb_stage = "authGSSClientResponse()" |
137 | | - gss_response = kerberos.authGSSClientResponse(self.context[host]) |
| 130 | + gss_stage = "stepping context" |
| 131 | + if is_preemptive: |
| 132 | + gss_response = self.context[host].step() |
| 133 | + else: |
| 134 | + gss_response = self.context[host].step( |
| 135 | + _negotiate_value(response)) |
138 | 136 |
|
139 | 137 | return "Negotiate {0}".format(gss_response) |
140 | 138 |
|
141 | | - except kerberos.GSSError as error: |
| 139 | + except gssapi.exceptions.GSSError as error: |
| 140 | + msg = error.gen_message() |
142 | 141 | log.exception( |
143 | | - "generate_request_header(): {0} failed:".format(kerb_stage)) |
144 | | - log.exception(error) |
145 | | - raise KerberosExchangeError("%s failed: %s" % (kerb_stage, str(error.args))) |
146 | | - |
147 | | - except EnvironmentError as error: |
148 | | - # ensure we raised this for translation to KerberosExchangeError |
149 | | - # by comparing errno to result, re-raise if not |
150 | | - if error.errno != result: |
151 | | - raise |
152 | | - message = "{0} failed, result: {1}".format(kerb_stage, result) |
153 | | - log.error("generate_request_header(): {0}".format(message)) |
154 | | - raise KerberosExchangeError(message) |
| 142 | + "generate_request_header(): {0} failed:".format(gss_stage)) |
| 143 | + log.exception(msg) |
| 144 | + raise KerberosExchangeError("%s failed: %s" % (gss_stage, msg)) |
155 | 145 |
|
156 | 146 | def authenticate_user(self, response, **kwargs): |
157 | 147 | """Handles user authentication with gssapi/kerberos""" |
@@ -251,15 +241,10 @@ def authenticate_server(self, response): |
251 | 241 | host = urlparse(response.url).hostname |
252 | 242 |
|
253 | 243 | try: |
254 | | - result = kerberos.authGSSClientStep(self.context[host], |
255 | | - _negotiate_value(response)) |
256 | | - except kerberos.GSSError: |
257 | | - log.exception("authenticate_server(): authGSSClientStep() failed:") |
258 | | - return False |
259 | | - |
260 | | - if result < 1: |
261 | | - log.error("authenticate_server(): authGSSClientStep() failed: " |
262 | | - "{0}".format(result)) |
| 244 | + result = self.context[host].step(_negotiate_value(response)) |
| 245 | + except gssapi.exceptions.GSSError as error: |
| 246 | + log.exception("authenticate_server(): context stepping failed:") |
| 247 | + log.exception(error.gen_message()) |
263 | 248 | return False |
264 | 249 |
|
265 | 250 | log.debug("authenticate_server(): returning {0}".format(response)) |
|
0 commit comments