pgreco / rpms / ipa

Forked from forks/areguera/rpms/ipa 4 years ago
Clone

Blame SOURCES/0040-Handle-failed-authentication-via-cookie.patch

483b06
From d1a482316296d32551470de698a1bdd6a7efed1a Mon Sep 17 00:00:00 2001
483b06
From: Simo Sorce <simo@redhat.com>
483b06
Date: Wed, 22 Mar 2017 18:38:22 -0400
483b06
Subject: [PATCH] Handle failed authentication via cookie
483b06
483b06
If cookie authentication fails and we get back a 401 see if we
483b06
tried a SPNEGO auth by checking if we had a GSSAPI context. If not
483b06
it means our session cookie was invalid or expired or some other
483b06
error happened on the server that requires us to try a full SPNEGO
483b06
handshake, so go ahead and try it.
483b06
483b06
Fixes https://pagure.io/freeipa/issue/6775
483b06
483b06
Signed-off-by: Simo Sorce <simo@redhat.com>
483b06
Reviewed-By: Christian Heimes <cheimes@redhat.com>
483b06
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
483b06
---
483b06
 ipalib/rpc.py | 52 ++++++++++++++++++++++++++++++++--------------------
483b06
 1 file changed, 32 insertions(+), 20 deletions(-)
483b06
483b06
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
483b06
index 38321d17cf2c9529738aa45cc44bbd38b08b032b..c1ceeec197c4a9c55f303f0fd431e86adb389598 100644
483b06
--- a/ipalib/rpc.py
483b06
+++ b/ipalib/rpc.py
483b06
@@ -586,22 +586,33 @@ class KerbTransport(SSLTransport):
483b06
         else:
483b06
             raise errors.KerberosError(message=unicode(e))
483b06
 
483b06
-    def get_host_info(self, host):
483b06
+    def _get_host(self):
483b06
+        return self._connection[0]
483b06
+
483b06
+    def _remove_extra_header(self, name):
483b06
+        for (h, v) in self._extra_headers:
483b06
+            if h == name:
483b06
+                self._extra_headers.remove((h, v))
483b06
+                break
483b06
+
483b06
+    def get_auth_info(self, use_cookie=True):
483b06
         """
483b06
         Two things can happen here. If we have a session we will add
483b06
         a cookie for that. If not we will set an Authorization header.
483b06
         """
483b06
-        (host, extra_headers, x509) = SSLTransport.get_host_info(self, host)
483b06
-
483b06
-        if not isinstance(extra_headers, list):
483b06
-            extra_headers = []
483b06
+        if not isinstance(self._extra_headers, list):
483b06
+            self._extra_headers = []
483b06
 
483b06
-        session_cookie = getattr(context, 'session_cookie', None)
483b06
-        if session_cookie:
483b06
-            extra_headers.append(('Cookie', session_cookie))
483b06
-            return (host, extra_headers, x509)
483b06
+        # Remove any existing Cookie first
483b06
+        self._remove_extra_header('Cookie')
483b06
+        if use_cookie:
483b06
+            session_cookie = getattr(context, 'session_cookie', None)
483b06
+            if session_cookie:
483b06
+                self._extra_headers.append(('Cookie', session_cookie))
483b06
+                return
483b06
 
483b06
         # Set the remote host principal
483b06
+        host = self._get_host()
483b06
         service = self.service + "@" + host.split(':')[0]
483b06
 
483b06
         try:
483b06
@@ -616,18 +627,14 @@ class KerbTransport(SSLTransport):
483b06
         except gssapi.exceptions.GSSError as e:
483b06
             self._handle_exception(e, service=service)
483b06
 
483b06
-        self._set_auth_header(extra_headers, response)
483b06
-
483b06
-        return (host, extra_headers, x509)
483b06
+        self._set_auth_header(response)
483b06
 
483b06
-    def _set_auth_header(self, extra_headers, token):
483b06
-        for (h, v) in extra_headers:
483b06
-            if h == 'Authorization':
483b06
-                extra_headers.remove((h, v))
483b06
-                break
483b06
+    def _set_auth_header(self, token):
483b06
+        # Remove any existing authorization header first
483b06
+        self._remove_extra_header('Authorization')
483b06
 
483b06
         if token:
483b06
-            extra_headers.append(
483b06
+            self._extra_headers.append(
483b06
                 ('Authorization', 'negotiate %s' % base64.b64encode(token).decode('ascii'))
483b06
             )
483b06
 
483b06
@@ -651,18 +658,23 @@ class KerbTransport(SSLTransport):
483b06
             if self._sec_context.complete:
483b06
                 self._sec_context = None
483b06
                 return True
483b06
-            self._set_auth_header(self._extra_headers, token)
483b06
+            self._set_auth_header(token)
483b06
+            return False
483b06
+        elif response.status == 401:
483b06
+            self.get_auth_info(use_cookie=False)
483b06
             return False
483b06
         return True
483b06
 
483b06
     def single_request(self, host, handler, request_body, verbose=0):
483b06
         # Based on Python 2.7's xmllib.Transport.single_request
483b06
         try:
483b06
-            h = SSLTransport.make_connection(self, host)
483b06
+            h = self.make_connection(host)
483b06
 
483b06
             if verbose:
483b06
                 h.set_debuglevel(1)
483b06
 
483b06
+            self.get_auth_info()
483b06
+
483b06
             while True:
483b06
                 if six.PY2:
483b06
                     # pylint: disable=no-value-for-parameter
483b06
-- 
483b06
2.12.1
483b06