Exemple #1
0
 def clean_context(self):
     """
     taken from urllib2_kerberos, see http://limedav.com/hg/urllib2_kerberos
     """
     if self.context is not None:
         kerberos.authGSSClientClean(self.context)
         self.context = None
    def __request_authenticate(self, method, url, body, extra_hdrs):
        self.__probe_mechanisms()

        try:
            result, gssctx = kerberos.authGSSClientInit(self.__spn, principal=self.__upn)
        except kerberos.GSSError as ex:
            raise Krb5Error('%s (%s)' % (ex[0][0], ex[1][0]))
            
        response = None
        blob = ''

        while True:
            try:
                result, blob = self.__challenge(gssctx, blob)
            except Krb5Error as ex:
                kerberos.authGSSClientClean(gssctx)
                raise ex

            if result:
                self.__upn = kerberos.authGSSClientUserName(gssctx)
                break

            self.close()
            extra_hdrs['Authorization'] = 'Negotiate %s' % (blob, )
            response =  davlib.DAV._request(self, method, url, body, extra_hdrs)

            self.__store_cookies(response)
            authstr = response.getheader('www-authenticate')
            (mech, blob) = authstr.split(' ')

            persistauth = response.getheader('persistent-auth')
            self.__persistauth = persistauth == 'true'

        kerberos.authGSSClientClean(gssctx)
        return response
Exemple #3
0
        def process(self, challenge=b''):
            b64_challenge = b64encode(challenge)
            try:
                if self.step == 0:
                    result = kerberos.authGSSClientStep(
                        self.gss, b64_challenge)
                    if result != kerberos.AUTH_GSS_CONTINUE:
                        self.step = 1
                elif not challenge:
                    kerberos.authGSSClientClean(self.gss)
                    return b''
                elif self.step == 1:
                    username = self.credentials['username']

                    kerberos.authGSSClientUnwrap(self.gss, b64_challenge)
                    resp = kerberos.authGSSClientResponse(self.gss)
                    kerberos.authGSSClientWrap(self.gss, resp, username)

                resp = kerberos.authGSSClientResponse(self.gss)
            except kerberos.GSSError as e:
                raise SASLCancelled('Kerberos error: %s' % e)
            if not resp:
                return b''
            else:
                return b64decode(resp)
Exemple #4
0
 def clean_context(self):
     """
     taken from urllib2_kerberos, see http://limedav.com/hg/urllib2_kerberos
     """
     if self.context is not None:
         kerberos.authGSSClientClean(self.context)
         self.context = None
Exemple #5
0
def get_current_principal():
    try:
        import kerberos
        rc, vc = kerberos.authGSSClientInit("notempty")
        rc = kerberos.authGSSClientInquireCred(vc)
        username = kerberos.authGSSClientUserName(vc)
        kerberos.authGSSClientClean(vc)
        return unicode(username)
    except ImportError:
        raise RuntimeError('python-kerberos is not available.')
    except kerberos.GSSError, e:
        #TODO: do a kinit?
        raise errors.CCacheError()
Exemple #6
0
 def check_auth_header(self, auth_header):
     if not self.ctx:
         raise RuntimeError("Invalid context: " + self.ctx)
     if not auth_header:
         raise RuntimeError("www-authenticate header is not valid: " +
                            auth_header)
     auth_val = auth_header.split(" ", 1)
     if len(auth_val) != 2 or auth_val[0].lower() != "negotiate":
         raise RuntimeError("www-authenticate header is not valid: " +
                            auth_header)
     kerberos.authGSSClientStep(self.ctx, auth_val[1])
     kerberos.authGSSClientClean(self.ctx)
     self.ctx = None
Exemple #7
0
def get_current_principal():
    try:
        import kerberos
        rc, vc = kerberos.authGSSClientInit("notempty")
        rc = kerberos.authGSSClientInquireCred(vc)
        username = kerberos.authGSSClientUserName(vc)
        kerberos.authGSSClientClean(vc)
        return unicode(username)
    except ImportError:
        raise RuntimeError('python-kerberos is not available.')
    except kerberos.GSSError, e:
        #TODO: do a kinit?
        raise errors.CCacheError()
Exemple #8
0
    def _set_kerberos_header(transport, kerberos_service_name, host):
        import kerberos

        __, krb_context = kerberos.authGSSClientInit(
            service="{kerberos_service_name}@{host}".format(
                kerberos_service_name=kerberos_service_name, host=host))
        kerberos.authGSSClientClean(krb_context, "")
        kerberos.authGSSClientStep(krb_context, "")
        auth_header = kerberos.authGSSClientResponse(krb_context)

        transport.setCustomHeaders({
            "Authorization":
            "Negotiate {auth_header}".format(auth_header=auth_header)
        })
Exemple #9
0
def noImpersonationCalls(args):
   """
   A non impersonated call using the kerberos package.
   """
   
   import kerberos
   _ignore, ctx = kerberos.authGSSClientInit(args.servicename)

   h = getConn(args.host, args.port)
   callserver(h, args.path, ctx, kerberos.authGSSClientStep, kerberos.authGSSClientResponse)

   callserver(h, args.path, ctx, kerberos.authGSSClientStep, kerberos.authGSSClientResponse)
   print "username", kerberos.authGSSClientUserName(ctx)
   kerberos.authGSSClientClean(ctx) # clean up
Exemple #10
0
 def verify_response(self, auth_header):
     for field in auth_header.split(","):
         kind, __, details = field.strip().partition(" ")
         if kind.lower() == "negotiate":
             auth_details = details.strip()
             break
     else:
         raise ValueError("Negotiate not found in %s" % auth_header)
     krb_context = self._krb_context
     if krb_context is None:
         raise RuntimeError("Ticket already used for verification")
     self._krb_context = None
     kerberos.authGSSClientStep(krb_context, auth_details)
     kerberos.authGSSClientClean(krb_context)
Exemple #11
0
def noImpersonationCalls(args):
    """
   A non impersonated call using the kerberos package.
   """

    import kerberos
    _ignore, ctx = kerberos.authGSSClientInit(args.servicename)

    h = getConn(args.host, args.port)
    callserver(h, args.path, ctx, kerberos.authGSSClientStep,
               kerberos.authGSSClientResponse)

    callserver(h, args.path, ctx, kerberos.authGSSClientStep,
               kerberos.authGSSClientResponse)
    print "username", kerberos.authGSSClientUserName(ctx)
    kerberos.authGSSClientClean(ctx)  # clean up
Exemple #12
0
    def _kerberos_verify_response(self, vc, host, handler, errcode, errmsg, headers):
        """Kerberos auth - verify client identity"""
        # verify that headers contain WWW-Authenticate header
        auth_header = headers.get("WWW-Authenticate", None)
        if auth_header is None:
            errcode = 401
            errmsg = "KERBEROS: No WWW-Authenticate header in second HTTP response"
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # verify that WWW-Authenticate contains Negotiate
        splits = auth_header.split(" ", 1)
        if (len(splits) != 2) or (splits[0].lower() != "negotiate"):
            errcode = 401
            errmsg = "KERBEROS: Incorrect WWW-Authenticate header in second HTTP response: %s" % auth_header
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # do another client step to verify response from server
        errmsg = "KERBEROS: Could not verify server WWW-Authenticate header in second HTTP response"
        try:
            rc = kerberos.authGSSClientStep(vc, splits[1])
            if rc == -1:
                errcode = 401
                raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)
        except kerberos.GSSError as ex:
            errcode = 401
            errmsg += ": %s/%s" % (ex[0][0], ex[1][0])
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # cleanup
        rc = kerberos.authGSSClientClean(vc)
        if rc != 1:
            errcode = 401
            errmsg = "KERBEROS: Could not clean-up GSSAPI: %s/%s" % (ex[0][0], ex[1][0])
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)
Exemple #13
0
    def _kerberos_verify_response(self, vc, host, handler, errcode, errmsg, headers):
        """Kerberos auth - verify client identity"""
        # verify that headers contain WWW-Authenticate header
        auth_header = headers.get("WWW-Authenticate", None)
        if auth_header is None:
            errcode = 401
            errmsg = "KERBEROS: No WWW-Authenticate header in second HTTP response"
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # verify that WWW-Authenticate contains Negotiate
        splits = auth_header.split(" ", 1)
        if (len(splits) != 2) or (splits[0].lower() != "negotiate"):
            errcode = 401
            errmsg = "KERBEROS: Incorrect WWW-Authenticate header in second HTTP response: %s" % auth_header
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # do another client step to verify response from server
        errmsg = "KERBEROS: Could not verify server WWW-Authenticate header in second HTTP response"
        try:
            rc = kerberos.authGSSClientStep(vc, splits[1])
            if rc == -1:
                errcode = 401
                raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)
        except kerberos.GSSError as ex:
            errcode = 401
            errmsg += ": %s/%s" % (ex[0][0], ex[1][0])
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # cleanup
        rc = kerberos.authGSSClientClean(vc)
        if rc != 1:
            errcode = 401
            errmsg = "KERBEROS: Could not clean-up GSSAPI: %s/%s" % (ex[0][0], ex[1][0])
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)
Exemple #14
0
 def verify_response(self, auth_header):
     """Handle comma-separated lists of authentication fields."""
     for field in auth_header.split(","):
         kind, __, details = field.strip().partition(" ")
         if kind.lower() == "negotiate":
             auth_details = details.strip()
             break
     else:
         raise ValueError("Negotiate not found in %s" % auth_header)
     # Finish the Kerberos handshake
     krb_context = self._krb_context
     if krb_context is None:
         raise RuntimeError("Ticket already used for verification")
     self._krb_context = None
     kerberos.authGSSClientStep(krb_context, auth_details)
     kerberos.authGSSClientClean(krb_context)
Exemple #15
0
 def verify_response(self, auth_header):
     # Handle comma-separated lists of authentication fields
     for field in auth_header.split(","):
         kind, ignored_space, details = field.strip().partition(" ")
         if kind.lower() == "negotiate":
             auth_details = details.strip()
             break
     else:
         raise ValueError("Negotiate not found in {0}".format(auth_header))
         # Finish the Kerberos handshake
     krb_context = self._krb_context
     if krb_context is None:
         raise RuntimeError("Ticket already used for verification")
     self._krb_context = None
     kerberos.authGSSClientStep(krb_context, auth_details)
     # print('User {0} authenticated successfully using Kerberos authentication'.format(kerberos.authGSSClientUserName(krb_context)))
     kerberos.authGSSClientClean(krb_context)
Exemple #16
0
 def clean_client_context(self):
     # Destroy the context for client-side authentication
     try:
         result = kerberos.authGSSClientClean(self.krb_context)
         logger.debug("authGSSClientClean result:{0}".format(result))
     except kerberos.GSSError, e:
         logger.warn('authGSSClientClean exception: %s' % str(e))
         result = -1
Exemple #17
0
 def verify_response(self, auth_header):
     # Handle comma-separated lists of authentication fields
     for field in auth_header.split(','):
         kind, ignored_space, details = field.strip().partition(' ')
         if kind.lower() == 'negotiate':
             auth_details = details.strip()
             break
     else:
         raise ValueError('Negotiate not found in {0}'.format(auth_header))
         # Finish the Kerberos handshake
     krb_context = self._krb_context
     if krb_context is None:
         raise RuntimeError('Ticket already used for verification')
     self._krb_context = None
     kerberos.authGSSClientStep(krb_context, auth_details)
     print('User {0} authenticated successfully using Kerberos authentication'.format(kerberos.authGSSClientUserName(krb_context)))
     kerberos.authGSSClientClean(krb_context)
Exemple #18
0
    def __del__(self):
        if self._context is not None:
            if not kerberos:
                return
            result_code = kerberos.authGSSClientClean(self._context)

            if result_code != kerberos.AUTH_GSS_COMPLETE:
                raise Exception('kerberos authGSSClientClean failed')
 def verify_response(self, auth_header):
     # Handle comma-separated lists of authentication fields
     for field in auth_header.split(","):
         kind, __, details = field.strip().partition(" ")
         print(kind)
         if kind.lower() == "negotiate":
             auth_details = details.strip()
             break
     else:
         raise ValueError("Negotiate not found in %s" % auth_header)
     # Finish the Kerberos handshake
     krb_context = self._krb_context
     if krb_context is None:
         raise RuntimeError("Ticket already used for verification")
     self._krb_context = None
     kerberos.authGSSClientStep(krb_context, auth_details)
     kerberos.authGSSClientClean(krb_context)
Exemple #20
0
   def _PassthroughLoginGSSAPI(self, host, sessionMgr, passthroughAuthPackage):
      """ Passthrough Authentication """

      userSession = None
      try:
         import kerberos
      except ImportError as err:
         LogException(err)
         return userSession

      context = None
      service = "host@%s" % host
      try:
         result, context = kerberos.authGSSClientInit(service, 0)
         challenge = ""
         while True:
            # Call GSS step
            result = kerberos.authGSSClientStep(context, challenge)
            if result < 0:
               logging.error("authGSSClientStep failed for %s" % service)
               break
            secToken = kerberos.authGSSClientResponse(context)
            try:
               userSession = sessionMgr.LoginBySSPI(secToken)
               # No exception => logged in
               userName = kerberos.authGSSClientUserName(context)
               logging.info("Passthru authentication: Logged in %s as %s" % \
                                                            service, userName)
               del secToken
               break
            except vim.fault.SSPIChallenge as err:
               # Continue gssapi challenges
               challenge = err.base64Token

         del challenge
      except Exception as err:
         LogException(err)
         logging.error("Login failed for %s" % service)

      if context:
         try:
            kerberos.authGSSClientClean(context)
         except Exception as err:
            LogException(err)

      return userSession
Exemple #21
0
def test_http_endpoint():
    service = "HTTP@%s" % hostname
    url = "http://%s:%s/" % (hostname, port)

    session = requests.Session()

    # Send the initial request un-authenticated
    request = requests.Request('GET', url)
    prepared_request = session.prepare_request(request)
    response = session.send(prepared_request)

    # Expect a 401 response
    assert response.status_code == 401, "Initial HTTP request did not result in a 401 response"

    # Validate the response supports the Negotiate protocol
    header = response.headers.get('www-authenticate', None)
    assert header is not None, "Initial HTTP response did not contain the www-authenticate header"
    assert header == 'Negotiate', "Initial HTTP response header www-authenticate does not support Negotiate"

    # Generate the first Kerberos token
    mech_oid = kerberos.GSS_MECH_OID_KRB5
    rc, vc = kerberos.authGSSClientInit(service=service, mech_oid=mech_oid)
    kerberos.authGSSClientStep(vc, "")
    kerberos_token = kerberos.authGSSClientResponse(vc)

    # Attach the Kerberos token and resend back to the host
    request = requests.Request('GET', url)
    prepared_request = session.prepare_request(request)
    prepared_request.headers['Authorization'] = "Negotiate %s" % kerberos_token
    response = session.send(prepared_request)

    # Expect a 200 response
    assert response.status_code == 200, "Second HTTP request did not result in a 200 response"

    # Validate the headers exist and contain a www-authenticate message
    header = response.headers.get('www-authenticate', None)
    assert header is not None, "Second HTTP response did not contain the www-authenticate header"
    assert header.startswith("Negotiate ")

    # Verify the return Kerberos token
    server_kerberos_token = header.split(' ')[-1]
    kerberos.authGSSClientStep(vc, server_kerberos_token)

    # Cleanup any objects still stored in memory
    kerberos.authGSSClientClean(vc)
Exemple #22
0
    def __authn_gssapi(self, imapobj):
        if not have_gss:
            return False

        self.connectionlock.acquire()
        try:
            imapobj.authenticate('GSSAPI', self.__gssauth)
            return True
        except imapobj.error as e:
            self.gssapi = False
            raise
        else:
            self.gssapi = True
            kerberos.authGSSClientClean(self.gss_vc)
            self.gss_vc = None
            self.gss_step = self.GSS_STATE_STEP
        finally:
            self.connectionlock.release()
    def __authn_gssapi(self, imapobj):
        if not have_gss:
            return False

        self.connectionlock.acquire()
        try:
            imapobj.authenticate('GSSAPI', self.__gssauth)
            return True
        except imapobj.error as e:
            self.gssapi = False
            raise
        else:
            self.gssapi = True
            kerberos.authGSSClientClean(self.gss_vc)
            self.gss_vc = None
            self.gss_step = self.GSS_STATE_STEP
        finally:
            self.connectionlock.release()
Exemple #24
0
    def create_http_transport(host, port, http_path, username, password,
                              kerberos_service_name, auth):
        if port is None:
            port = 10001
        if auth is None:
            auth = 'NONE'
        if http_path is None:
            http_path = '/'

        socket = TCookieHttpClient('http://{}:{}{}'.format(
            host, port, http_path))

        if auth == 'KERBEROS':
            import kerberos

            __, krb_context = kerberos.authGSSClientInit(
                service='{}@{}'.format(kerberos_service_name, host))
            kerberos.authGSSClientClean(krb_context, '')
            kerberos.authGSSClientStep(krb_context, '')
            auth_header = kerberos.authGSSClientResponse(krb_context)

            socket.setCustomHeaders(
                {'Authorization': 'Negotiate {}'.format(auth_header)})

        elif auth in ('BASIC', 'NOSASL', 'NONE'):
            if auth == 'BASIC' and password is None:
                raise ValueError("BASIC authentication requires password.")

            auth_credentials = '{}:{}'.format(username, password)\
                .encode('UTF-8')
            auth_credentials_base64 = base64.standard_b64encode(
                auth_credentials).decode('UTF-8')

            # we're using the Authorization header for auth NONE or NOSASL because that's where
            # Hive gets the username when doAs is enabled
            socket.setCustomHeaders(
                {'Authorization': 'Basic {}'.format(auth_credentials_base64)})

        else:
            raise NotImplementedError(
                "Only NONE, NOSASL, BASIC and KERBEROS authentication are supported "
                "when using HTTP transport, got {}".format(auth))

        return thrift.transport.TTransport.TBufferedTransport(socket)
Exemple #25
0
    def http_error_401(self, req, fp, code, msg, headers):
        logger.debug("INSIDE http_error_401")
        try:
            try:
                krb_req = self._extract_krb_value(headers)
            except ValueError:
                # Negotiate header not found or a similar error
                # we can't handle this, let the next handler have a go
                return None

            if not krb_req:
                # First reply from server (no neg value)
                self.tries = 0
                krb_req = ""
            else:
                if self.tries > self.max_tries:
                    raise error.HTTPError(
                        req.get_full_url(), 401, "Negotiate auth failed",
                        headers, None)

            self.tries += 1
            try:
                krb_resp = self._krb_response(req.get_host(), krb_req)

                req.add_unredirected_header('Authorization',
                                            "Negotiate %s" % krb_resp)

                resp = self.parent.open(req, timeout=req.timeout)
                self._authenticate_server(resp.headers)
                return resp

            except kerberos.GSSError as err:
                try:
                    msg = err.args[1][0]
                except Exception:
                    msg = "Negotiate auth failed"
                logger.debug(msg)
                return None  # let the next handler (if any) have a go

        finally:
            if self.krb_context is not None:
                kerberos.authGSSClientClean(self.krb_context)
                self.krb_context = None
Exemple #26
0
    def __create_http_transport(host, username, password, kerberos_service_name,
                                port=10001, auth='KERBEROS'):
        if auth == 'KERBEROS':
            import kerberos

            __, krb_context = kerberos.authGSSClientInit(
                service='{}@{}'.format(kerberos_service_name, host))
            kerberos.authGSSClientClean(krb_context, '')
            kerberos.authGSSClientStep(krb_context, '')
            auth_header = kerberos.authGSSClientResponse(krb_context)

            socket = TCookieHttpClient(uri_or_host=host,
                                       port=port,
                                       path='/')

            socket.setCustomHeaders(
                {'Authorization': 'Negotiate {}'.format(auth_header)})

        elif auth == 'BASIC':
            if username is None or password is None:
                raise ValueError("BASIC authentication require username and password.")

            socket = TCookieHttpClient(uri_or_host=host,
                                       port=port,
                                       path='/')

            auth_credentials = '{}:{}'.format(username, password)\
                .encode('UTF-8')
            auth_credentials_base64 = base64.standard_b64encode(
                auth_credentials).decode('UTF-8')

            socket.setCustomHeaders(
                {'Authorization': 'Basic {}'.format(auth_credentials_base64)})

        elif auth == 'NONE':
            socket = thrift.transport.THttpClient.THttpClient(host, port, '/')

        else:
            raise NotImplementedError(
                "Only NONE, BASIC and KERBEROS authentication are supported "
                "when using HTTP transport, got {}".format(auth))

        return thrift.transport.TTransport.TBufferedTransport(socket)
Exemple #27
0
    def get_ticket(self, hostname, service_type):
        status, context = kerberos.authGSSClientInit('%s@%s' % (
            service_type,
            hostname,
        ))

        if not status:
            ERROR('Kerberos: Could not initialize context')
            return ''

        status = kerberos.authGSSClientStep(context, '')
        if status:
            ERROR('Kerberos: Client step failed')
            return ''

        ticket = kerberos.authGSSClientResponse(context)
        kerberos.authGSSClientClean(context)

        return ticket
Exemple #28
0
    def http_error_401(self, req, fp, code, msg, headers):
        logger.debug("INSIDE http_error_401")
        try:
            try:
                krb_req = self._extract_krb_value(headers)
            except ValueError:
                # Negotiate header not found or a similar error
                # we can't handle this, let the next handler have a go
                return None

            if not krb_req:
                # First reply from server (no neg value)
                self.tries = 0
                krb_req = ""
            else:
                if self.tries > self.max_tries:
                    raise error.HTTPError(req.get_full_url(), 401,
                                          "Negotiate auth failed", headers,
                                          None)

            self.tries += 1
            try:
                krb_resp = self._krb_response(req.get_host(), krb_req)

                req.add_unredirected_header('Authorization',
                                            "Negotiate %s" % krb_resp)

                resp = self.parent.open(req, timeout=req.timeout)
                self._authenticate_server(resp.headers)
                return resp

            except kerberos.GSSError as err:
                try:
                    msg = err.args[1][0]
                except Exception:
                    msg = "Negotiate auth failed"
                logger.debug(msg)
                return None  # let the next handler (if any) have a go

        finally:
            if self.krb_context is not None:
                kerberos.authGSSClientClean(self.krb_context)
                self.krb_context = None
Exemple #29
0
    def __request_authenticate(self, method, url, body, extra_hdrs):
        self.__probe_mechanisms()

        try:
            result, gssctx = kerberos.authGSSClientInit(self.__spn,
                                                        principal=self.__upn)
        except kerberos.GSSError as ex:
            raise Krb5Error('%s (%s)' % (ex[0][0], ex[1][0]))

        response = None
        blob = ''

        while True:
            try:
                result, blob = self.__challenge(gssctx, blob)
            except Krb5Error as ex:
                kerberos.authGSSClientClean(gssctx)
                raise ex

            if result:
                self.__upn = kerberos.authGSSClientUserName(gssctx)
                break

            self.close()
            extra_hdrs['Authorization'] = 'Negotiate %s' % (blob, )
            response = davlib.DAV._request(self, method, url, body, extra_hdrs)

            self.__store_cookies(response)
            authstr = response.getheader('www-authenticate')
            (mech, blob) = authstr.split(' ')

            persistauth = response.getheader('persistent-auth')
            self.__persistauth = persistauth == 'true'

        kerberos.authGSSClientClean(gssctx)
        return response
Exemple #30
0
        def process(self, challenge=b''):
            b64_challenge = b64encode(challenge)
            try:
                if self.step == 0:
                    result = kerberos.authGSSClientStep(self.gss, b64_challenge)
                    if result != kerberos.AUTH_GSS_CONTINUE:
                        self.step = 1
                elif not challenge:
                    kerberos.authGSSClientClean(self.gss)
                    return b''
                elif self.step == 1:
                    username = self.credentials['username']

                    kerberos.authGSSClientUnwrap(self.gss, b64_challenge)
                    resp = kerberos.authGSSClientResponse(self.gss)
                    kerberos.authGSSClientWrap(self.gss, resp, username)

                resp = kerberos.authGSSClientResponse(self.gss)
            except kerberos.GSSError as e:
                raise SASLCancelled('Kerberos error: %s' % e)
            if not resp:
                return b''
            else:
                return b64decode(resp)
Exemple #31
0
def testGSSAPI(service):
    def statusText(r):
        if r == 1:
            return "Complete"
        elif r == 0:
            return "Continue"
        else:
            return "Error"

    rc, vc = kerberos.authGSSClientInit(service)
    print("Status for authGSSClientInit = %s" % statusText(rc))
    if rc != 1:
        return

    rs, vs = kerberos.authGSSServerInit(service)
    print("Status for authGSSServerInit = %s" % statusText(rs))
    if rs != 1:
        return

    rc = kerberos.authGSSClientStep(vc, "")
    print("Status for authGSSClientStep = %s" % statusText(rc))
    if rc != 0:
        return

    rs = kerberos.authGSSServerStep(vs, kerberos.authGSSClientResponse(vc))
    print("Status for authGSSServerStep = %s" % statusText(rs))
    if rs == -1:
        return

    rc = kerberos.authGSSClientStep(vc, kerberos.authGSSServerResponse(vs))
    print("Status for authGSSClientStep = %s" % statusText(rc))
    if rc == -1:
        return

    print("Server user name: %s" % kerberos.authGSSServerUserName(vs))
    print("Server target name: %s" % kerberos.authGSSServerTargetName(vs))
    print("Client user name: %s" % kerberos.authGSSClientUserName(vc))

    rc = kerberos.authGSSClientClean(vc)
    print("Status for authGSSClientClean = %s" % statusText(rc))

    rs = kerberos.authGSSServerClean(vs)
    print("Status for authGSSServerClean = %s" % statusText(rs))
Exemple #32
0
def testGSSAPI(service):
    def statusText(r):
        if r == 1:
            return "Complete"
        elif r == 0:
            return "Continue"
        else:
            return "Error"

    rc, vc = kerberos.authGSSClientInit(service);
    print "Status for authGSSClientInit = %s" % statusText(rc);
    if rc != 1:
        return
    
    rs, vs = kerberos.authGSSServerInit(service);
    print "Status for authGSSServerInit = %s" % statusText(rs);
    if rs != 1:
        return
    
    rc = kerberos.authGSSClientStep(vc, "");
    print "Status for authGSSClientStep = %s" % statusText(rc);
    if rc != 0:
        return
    
    rs = kerberos.authGSSServerStep(vs, kerberos.authGSSClientResponse(vc));
    print "Status for authGSSServerStep = %s" % statusText(rs);
    if rs == -1:
        return
    
    rc = kerberos.authGSSClientStep(vc, kerberos.authGSSServerResponse(vs));
    print "Status for authGSSClientStep = %s" % statusText(rc);
    if rc == -1:
        return

    print "Server user name: %s" % kerberos.authGSSServerUserName(vs);
    print "Server target name: %s" % kerberos.authGSSServerTargetName(vs);
    print "Client user name: %s" % kerberos.authGSSClientUserName(vc);
    
    rc = kerberos.authGSSClientClean(vc);
    print "Status for authGSSClientClean = %s" % statusText(rc);
    
    rs = kerberos.authGSSServerClean(vs);
    print "Status for authGSSServerClean = %s" % statusText(rs);
Exemple #33
0
def test_gssapi():
    """
    Return Code Values
        0 = Continue
        1 = Complete
        Other = Error
    """
    service = "HTTP@%s" % hostname
    rc, vc = kerberos.authGSSClientInit(service)
    assert rc == 1, "authGSSClientInit = %d, expecting 1" % rc

    rs, vs = kerberos.authGSSServerInit(service)
    assert rs == 1, "authGSSServerInit = %d, expecting 1" % rs

    rc = kerberos.authGSSClientStep(vc, "")
    assert rc == 0, "authGSSClientStep = %d, expecting 0" % rc

    rs = kerberos.authGSSServerStep(vs, kerberos.authGSSClientResponse(vc))
    assert rs != -1, "authGSSServerStep = %d, not expecting it to be -1" % rs

    rc = kerberos.authGSSClientStep(vc, kerberos.authGSSServerResponse(vs))
    assert rc != -1, "authGSSClientStep = %d, not expecting it to be -1" % rc

    expected_username = "******" % (username, realm.upper())
    server_user_name = kerberos.authGSSServerUserName(vs)
    assert server_user_name == expected_username, "Invalid server username returned"

    client_user_name = kerberos.authGSSClientUserName(vc)
    assert client_user_name == expected_username, "Invalid client username returned"

    server_target_name = kerberos.authGSSServerTargetName(vs)
    assert server_target_name is None, "Server target name is not None"

    rc = kerberos.authGSSClientClean(vc)
    assert rc == 1, "authGSSClientClean = %d, expecting it to be 0" % rc

    rs = kerberos.authGSSServerClean(vs)
    assert rs == 1, "authGSSServerClean = %d, expecting it to be 0" % rs
Exemple #34
0
 def __del__(self):
     result_code = kerberos.authGSSClientClean(self._context)
     if result_code != kerberos.AUTH_GSS_COMPLETE:
         raise Exception('kerberos authGSSClientClean failed')
Exemple #35
0
 def _clean_context(self):
   if self.context is not None:
     kerberos.authGSSClientClean(self.context)
     self.context = None
Exemple #36
0
def _authenticate_gssapi(credentials, sock_info, cmd_func):
    """Authenticate using GSSAPI.
    """
    try:
        dummy, username, gsn = credentials
        # Starting here and continuing through the while loop below - establish
        # the security context. See RFC 4752, Section 3.1, first paragraph.
        result, ctx = kerberos.authGSSClientInit(
            gsn + '@' + sock_info.host, gssflags=kerberos.GSS_C_MUTUAL_FLAG)

        if result != kerberos.AUTH_GSS_COMPLETE:
            raise OperationFailure('Kerberos context failed to initialize.')

        try:
            # pykerberos uses a weird mix of exceptions and return values
            # to indicate errors.
            # 0 == continue, 1 == complete, -1 == error
            # Only authGSSClientStep can return 0.
            if kerberos.authGSSClientStep(ctx, '') != 0:
                raise OperationFailure('Unknown kerberos '
                                       'failure in step function.')

            # Start a SASL conversation with mongod/s
            # Note: pykerberos deals with base64 encoded byte strings.
            # Since mongo accepts base64 strings as the payload we don't
            # have to use bson.binary.Binary.
            payload = kerberos.authGSSClientResponse(ctx)
            cmd = SON([('saslStart', 1), ('mechanism', 'GSSAPI'),
                       ('payload', payload), ('autoAuthorize', 1)])
            response, _ = cmd_func(sock_info, '$external', cmd)

            # Limit how many times we loop to catch protocol / library issues
            for _ in xrange(10):
                result = kerberos.authGSSClientStep(ctx,
                                                    str(response['payload']))
                if result == -1:
                    raise OperationFailure('Unknown kerberos '
                                           'failure in step function.')

                payload = kerberos.authGSSClientResponse(ctx) or ''

                cmd = SON([('saslContinue', 1),
                           ('conversationId', response['conversationId']),
                           ('payload', payload)])
                response, _ = cmd_func(sock_info, '$external', cmd)

                if result == kerberos.AUTH_GSS_COMPLETE:
                    break
            else:
                raise OperationFailure('Kerberos '
                                       'authentication failed to complete.')

            # Once the security context is established actually authenticate.
            # See RFC 4752, Section 3.1, last two paragraphs.
            if kerberos.authGSSClientUnwrap(ctx, str(
                    response['payload'])) != 1:
                raise OperationFailure('Unknown kerberos '
                                       'failure during GSS_Unwrap step.')

            if kerberos.authGSSClientWrap(
                    ctx, kerberos.authGSSClientResponse(ctx), username) != 1:
                raise OperationFailure('Unknown kerberos '
                                       'failure during GSS_Wrap step.')

            payload = kerberos.authGSSClientResponse(ctx)
            cmd = SON([('saslContinue', 1),
                       ('conversationId', response['conversationId']),
                       ('payload', payload)])
            response, _ = cmd_func(sock_info, '$external', cmd)

        finally:
            kerberos.authGSSClientClean(ctx)

    except kerberos.KrbError, exc:
        raise OperationFailure(str(exc))
Exemple #37
0
def testHTTP(host, port, use_ssl, service):
    class HTTPSConnection_SSLv3(httplib.HTTPSConnection):
        "This class allows communication via SSL."

        def connect(self):
            "Connect to a host on a given (SSL) port."

            sock = socket.create_connection((self.host, self.port), self.timeout)
            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_SSLv3)

    def sendRequest(host, port, ssl, method, uri, headers):
        response = None
        if use_ssl:
            http = HTTPSConnection_SSLv3(host, port)
        else:
            http = httplib.HTTPConnection(host, port)
        try:
            http.request(method, uri, "", headers)
            response = http.getresponse()
        finally:
            http.close()

        return response

    # Initial request without auth header
    uri = "/principals/"
    response = sendRequest(host, port, use_ssl, "OPTIONS", uri, {})

    if response is None:
        print("Initial HTTP request to server failed")
        return

    if response.status != 401:
        print("Initial HTTP request did not result in a 401 response")
        return

    hdrs = response.msg.getheaders("www-authenticate")
    if (hdrs is None) or (len(hdrs) == 0):
        print("No www-authenticate header in initial HTTP response.")
    for hdr in hdrs:
        hdr = hdr.strip()
        splits = hdr.split(" ", 1)
        if (len(splits) != 1) or (splits[0].lower() != "negotiate"):
            continue
        else:
            break
    else:
        print("No www-authenticate header with negotiate in initial HTTP response.")
        return

    try:
        rc, vc = kerberos.authGSSClientInit(service=service)
    except kerberos.GSSError as e:
        print("Could not initialize GSSAPI: %s/%s" % (e[0][0], e[1][0]))
        return

    try:
        kerberos.authGSSClientStep(vc, "")
    except kerberos.GSSError as e:
        print("Could not do GSSAPI step with continue: %s/%s" % (e[0][0], e[1][0]))
        return

    hdrs = {}
    hdrs["Authorization"] = "negotiate %s" % kerberos.authGSSClientResponse(vc)

    # Second request with auth header
    response = sendRequest(host, port, use_ssl, "OPTIONS", uri, hdrs)

    if response is None:
        print("Second HTTP request to server failed")
        return

    if response.status / 100 != 2:
        print("Second HTTP request did not result in a 2xx response: %d" % (response.status,))
        return

    hdrs = response.msg.getheaders("www-authenticate")
    if (hdrs is None) or (len(hdrs) == 0):
        print("No www-authenticate header in second HTTP response.")
        return
    for hdr in hdrs:
        hdr = hdr.strip()
        splits = hdr.split(" ", 1)
        if (len(splits) != 2) or (splits[0].lower() != "negotiate"):
            continue
        else:
            break
    else:
        print("No www-authenticate header with negotiate in second HTTP response.")
        return

    try:
        kerberos.authGSSClientStep(vc, splits[1])
    except kerberos.GSSError as e:
        print("Could not verify server www-authenticate header in second HTTP response: %s/%s" % (e[0][0], e[1][0]))
        return

    try:
        rc = kerberos.authGSSClientClean(vc)
    except kerberos.GSSError as e:
        print("Could not clean-up GSSAPI: %s/%s" % (e[0][0], e[1][0]))
        return

    print("Authenticated successfully")
    return
Exemple #38
0
        print "No www-authenticate header in second HTTP response."
        return
    for hdr in hdrs:
        hdr = hdr.strip()
        splits = hdr.split(' ', 1)
        if (len(splits) != 2) or (splits[0].lower() != "negotiate"):
            continue
        else:
            break
    else:
        print "No www-authenticate header with negotiate in second HTTP response."
        return        

    try:
        kerberos.authGSSClientStep(vc, splits[1])
    except kerberos.GSSError, e:
        print "Could not verify server www-authenticate header in second HTTP response: %s/%s" % (e[0][0], e[1][0])
        return
    
    try:
        rc = kerberos.authGSSClientClean(vc);
    except kerberos.GSSError, e:
        print "Could not clean-up GSSAPI: %s/%s" % (e[0][0], e[1][0])
        return

    print "Authenticated successfully"
    return

if __name__=='__main__':
    main()
Exemple #39
0
        print "No www-authenticate header in second HTTP response."
        return
    for hdr in hdrs:
        hdr = hdr.strip()
        splits = hdr.split(' ', 1)
        if (len(splits) != 2) or (splits[0].lower() != "negotiate"):
            continue
        else:
            break
    else:
        print "No www-authenticate header with negotiate in second HTTP response."
        return        

    try:
        kerberos.authGSSClientStep(vc, splits[1])
    except kerberos.GSSError, e:
        print "Could not verify server www-authenticate header in second HTTP response: %s/%s" % (e[0][0], e[1][0])
        return
    
    try:
        rc = kerberos.authGSSClientClean(vc);
    except kerberos.GSSError, e:
        print "Could not clean-up GSSAPI: %s/%s" % (e[0][0], e[1][0])
        return

    print "Authenticated successfully"
    return

if __name__=='__main__':
    main()
Exemple #40
0
 def clean_context(self):
     if self._context is not None:
         krb.authGSSClientClean(self._context)
    def acquireconnection(self):
        """Fetches a connection from the pool, making sure to create a new one
        if needed, to obey the maximum connection limits, etc.
        Opens a connection to the server and returns an appropriate
        object."""

        self.semaphore.acquire()
        self.connectionlock.acquire()
        curThread = currentThread()
        imapobj = None

        if len(self.availableconnections): # One is available.
            # Try to find one that previously belonged to this thread
            # as an optimization.  Start from the back since that's where
            # they're popped on.
            imapobj = None
            for i in range(len(self.availableconnections) - 1, -1, -1):
                tryobj = self.availableconnections[i]
                if self.lastowner[tryobj] == curThread.ident:
                    imapobj = tryobj
                    del(self.availableconnections[i])
                    break
            if not imapobj:
                imapobj = self.availableconnections[0]
                del(self.availableconnections[0])
            self.assignedconnections.append(imapobj)
            self.lastowner[imapobj] = curThread.ident
            self.connectionlock.release()
            return imapobj
        
        self.connectionlock.release()   # Release until need to modify data

        """ Must be careful here that if we fail we should bail out gracefully
        and release locks / threads so that the next attempt can try...
        """
        success = 0
        try:
            while not success:
                # Generate a new connection.
                if self.tunnel:
                    self.ui.connecting('tunnel', self.tunnel)
                    imapobj = imaplibutil.IMAP4_Tunnel(self.tunnel,
                                                       timeout=socket.getdefaulttimeout())
                    success = 1
                elif self.usessl:
                    self.ui.connecting(self.hostname, self.port)
                    fingerprint = self.repos.get_ssl_fingerprint()
                    imapobj = imaplibutil.WrappedIMAP4_SSL(self.hostname,
                                                           self.port,
                                                           self.sslclientkey,
                                                           self.sslclientcert,
                                                           self.sslcacertfile,
                                                           self.verifycert,
                                                           timeout=socket.getdefaulttimeout(),
                                                           fingerprint=fingerprint
                                                           )
                else:
                    self.ui.connecting(self.hostname, self.port)
                    imapobj = imaplibutil.WrappedIMAP4(self.hostname, self.port,
                                                       timeout=socket.getdefaulttimeout())

                if not self.tunnel:
                    try:
                        # Try GSSAPI and continue if it fails
                        if 'AUTH=GSSAPI' in imapobj.capabilities and have_gss:
                            self.connectionlock.acquire()
                            self.ui.debug('imap',
                                'Attempting GSSAPI authentication')
                            try:
                                imapobj.authenticate('GSSAPI', self.gssauth)
                            except imapobj.error as val:
                                self.gssapi = False
                                self.ui.debug('imap',
                                    'GSSAPI Authentication failed')
                            else:
                                self.gssapi = True
                                kerberos.authGSSClientClean(self.gss_vc)
                                self.gss_vc = None
                                self.gss_step = self.GSS_STATE_STEP
                                #if we do self.password = None then the next attempt cannot try...
                                #self.password = None
                            self.connectionlock.release()

                        if not self.gssapi:
                            if 'STARTTLS' in imapobj.capabilities and not\
                                    self.usessl:
                                self.ui.debug('imap',
                                              'Using STARTTLS connection')
                                imapobj.starttls()

                            if 'AUTH=CRAM-MD5' in imapobj.capabilities:
                                self.ui.debug('imap',
                                           'Attempting CRAM-MD5 authentication')
                                try:
                                    imapobj.authenticate('CRAM-MD5',
                                                         self.md5handler)
                                except imapobj.error as val:
                                    self.plainauth(imapobj)
                            else:
                                # Use plaintext login, unless
                                # LOGINDISABLED (RFC2595)
                                if 'LOGINDISABLED' in imapobj.capabilities:
                                    raise OfflineImapError("Plaintext login "
                                       "disabled by server. Need to use SSL?",
                                        OfflineImapError.ERROR.REPO)
                                self.plainauth(imapobj)
                        # Would bail by here if there was a failure.
                        success = 1
                        self.goodpassword = self.password
                    except imapobj.error as val:
                        self.passworderror = str(val)
                        raise

            # update capabilities after login, e.g. gmail serves different ones
            typ, dat = imapobj.capability()
            if dat != [None]:
                imapobj.capabilities = tuple(dat[-1].upper().split())

            if self.delim == None:
                listres = imapobj.list(self.reference, '""')[1]
                if listres == [None] or listres == None:
                    # Some buggy IMAP servers do not respond well to LIST "" ""
                    # Work around them.
                    listres = imapobj.list(self.reference, '"*"')[1]
                if listres == [None] or listres == None:
                    # No Folders were returned. This occurs, e.g. if the
                    # 'reference' prefix does not exist on the mail
                    # server. Raise exception.
                    err = "Server '%s' returned no folders in '%s'" % \
                        (self.repos.getname(), self.reference)
                    self.ui.warn(err)
                    raise Exception(err)
                self.delim, self.root = \
                            imaputil.imapsplit(listres[0])[1:]
                self.delim = imaputil.dequote(self.delim)
                self.root = imaputil.dequote(self.root)

            self.connectionlock.acquire()
            self.assignedconnections.append(imapobj)
            self.lastowner[imapobj] = curThread.ident
            self.connectionlock.release()
            return imapobj
        except Exception as e:
            """If we are here then we did not succeed in getting a
            connection - we should clean up and then re-raise the
            error..."""
            self.semaphore.release()

            if(self.connectionlock.locked()):
                self.connectionlock.release()

            severity = OfflineImapError.ERROR.REPO
            if type(e) == gaierror:
                #DNS related errors. Abort Repo sync
                #TODO: special error msg for e.errno == 2 "Name or service not known"?
                reason = "Could not resolve name '%s' for repository "\
                         "'%s'. Make sure you have configured the ser"\
                         "ver name correctly and that you are online."%\
                         (self.hostname, self.repos)
                raise OfflineImapError(reason, severity)

            elif isinstance(e, SSLError) and e.errno == 1:
                # SSL unknown protocol error
                # happens e.g. when connecting via SSL to a non-SSL service
                if self.port != 993:
                    reason = "Could not connect via SSL to host '%s' and non-s"\
                        "tandard ssl port %d configured. Make sure you connect"\
                        " to the correct port." % (self.hostname, self.port)
                else:
                    reason = "Unknown SSL protocol connecting to host '%s' for"\
                         "repository '%s'. OpenSSL responded:\n%s"\
                         % (self.hostname, self.repos, e)
                raise OfflineImapError(reason, severity)

            elif isinstance(e, socket.error) and e.args[0] == errno.ECONNREFUSED:
                # "Connection refused", can be a non-existing port, or an unauthorized
                # webproxy (open WLAN?)
                reason = "Connection to host '%s:%d' for repository '%s' was "\
                    "refused. Make sure you have the right host and port "\
                    "configured and that you are actually able to access the "\
                    "network." % (self.hostname, self.port, self.reposname)
                raise OfflineImapError(reason, severity)
            # Could not acquire connection to the remote;
            # socket.error(last_error) raised
            if str(e)[:24] == "can't open socket; error":
                raise OfflineImapError("Could not connect to remote server '%s' "\
                    "for repository '%s'. Remote does not answer."
                    % (self.hostname, self.repos),
                    OfflineImapError.ERROR.REPO)
            else:
                # re-raise all other errors
                raise
Exemple #42
0
 def clean_context(self):
     if self._context is not None:
         krb.authGSSClientClean(self._context)
Exemple #43
0
 def dispose(self):
     kerberos.authGSSClientClean(self.context)
Exemple #44
0
 def clean_context(self):
     if self.context is not None:
         log.debug("cleaning context")
         k.authGSSClientClean(self.context)
         self.context = None
Exemple #45
0
    def acquireconnection(self):
        """Fetches a connection from the pool, making sure to create a new one
        if needed, to obey the maximum connection limits, etc.
        Opens a connection to the server and returns an appropriate
        object."""

        self.semaphore.acquire()
        self.connectionlock.acquire()
        imapobj = None

        if len(self.availableconnections): # One is available.
            # Try to find one that previously belonged to this thread
            # as an optimization.  Start from the back since that's where
            # they're popped on.
            imapobj = None
            for i in range(len(self.availableconnections) - 1, -1, -1):
                tryobj = self.availableconnections[i]
                if self.lastowner[tryobj] == get_ident():
                    imapobj = tryobj
                    del(self.availableconnections[i])
                    break
            if not imapobj:
                imapobj = self.availableconnections[0]
                del(self.availableconnections[0])
            self.assignedconnections.append(imapobj)
            self.lastowner[imapobj] = get_ident()
            self.connectionlock.release()
            return imapobj
        
        self.connectionlock.release()   # Release until need to modify data

        """ Must be careful here that if we fail we should bail out gracefully
        and release locks / threads so that the next attempt can try...
        """
        success = 0
        try:
            while not success:
                # Generate a new connection.
                if self.tunnel:
                    self.ui.connecting('tunnel', self.tunnel)
                    imapobj = imaplibutil.IMAP4_Tunnel(self.tunnel,
                                                       timeout=socket.getdefaulttimeout())
                    success = 1
                elif self.usessl:
                    self.ui.connecting(self.hostname, self.port)
                    fingerprint = self.repos.get_ssl_fingerprint()
                    imapobj = imaplibutil.WrappedIMAP4_SSL(self.hostname,
                                                           self.port,
                                                           self.sslclientkey,
                                                           self.sslclientcert,
                                                           self.sslcacertfile,
                                                           self.verifycert,
                                                           timeout=socket.getdefaulttimeout(),
                                                           fingerprint=fingerprint
                                                           )
                else:
                    self.ui.connecting(self.hostname, self.port)
                    imapobj = imaplibutil.WrappedIMAP4(self.hostname, self.port,
                                                       timeout=socket.getdefaulttimeout())

                if not self.tunnel:
                    try:
                        # Try GSSAPI and continue if it fails
                        if 'AUTH=GSSAPI' in imapobj.capabilities and have_gss:
                            self.connectionlock.acquire()
                            self.ui.debug('imap',
                                'Attempting GSSAPI authentication')
                            try:
                                imapobj.authenticate('GSSAPI', self.gssauth)
                            except imapobj.error, val:
                                self.gssapi = False
                                self.ui.debug('imap',
                                    'GSSAPI Authentication failed')
                            else:
                                self.gssapi = True
                                kerberos.authGSSClientClean(self.gss_vc)
                                self.gss_vc = None
                                self.gss_step = self.GSS_STATE_STEP
                                #if we do self.password = None then the next attempt cannot try...
                                #self.password = None
                            self.connectionlock.release()

                        if not self.gssapi:
                            if 'STARTTLS' in imapobj.capabilities and not\
                                    self.usessl:
                                self.ui.debug('imap',
                                              'Using STARTTLS connection')
                                imapobj.starttls()

                            if 'AUTH=CRAM-MD5' in imapobj.capabilities:
                                self.ui.debug('imap',
                                           'Attempting CRAM-MD5 authentication')
                                try:
                                    imapobj.authenticate('CRAM-MD5',
                                                         self.md5handler)
                                except imapobj.error, val:
                                    self.plainauth(imapobj)
                            else:
                                self.plainauth(imapobj)
                        # Would bail by here if there was a failure.
                        success = 1
                        self.goodpassword = self.password
                    except imapobj.error, val:
                        self.passworderror = str(val)
                        raise
Exemple #46
0
 def _clean_context(self):
   if self.context is not None:
     kerberos.authGSSClientClean(self.context)
     self.context = None
Exemple #47
0
    def acquireconnection(self):
        """Fetches a connection from the pool, making sure to create a new one
        if needed, to obey the maximum connection limits, etc.
        Opens a connection to the server and returns an appropriate
        object."""

        self.semaphore.acquire()
        self.connectionlock.acquire()
        curThread = currentThread()
        imapobj = None

        if len(self.availableconnections):  # One is available.
            # Try to find one that previously belonged to this thread
            # as an optimization.  Start from the back since that's where
            # they're popped on.
            imapobj = None
            for i in range(len(self.availableconnections) - 1, -1, -1):
                tryobj = self.availableconnections[i]
                if self.lastowner[tryobj] == curThread.ident:
                    imapobj = tryobj
                    del (self.availableconnections[i])
                    break
            if not imapobj:
                imapobj = self.availableconnections[0]
                del (self.availableconnections[0])
            self.assignedconnections.append(imapobj)
            self.lastowner[imapobj] = curThread.ident
            self.connectionlock.release()
            return imapobj

        self.connectionlock.release()  # Release until need to modify data
        """ Must be careful here that if we fail we should bail out gracefully
        and release locks / threads so that the next attempt can try...
        """
        success = 0
        try:
            while not success:
                # Generate a new connection.
                if self.tunnel:
                    self.ui.connecting('tunnel', self.tunnel)
                    imapobj = imaplibutil.IMAP4_Tunnel(
                        self.tunnel, timeout=socket.getdefaulttimeout())
                    success = 1
                elif self.usessl:
                    self.ui.connecting(self.hostname, self.port)
                    fingerprint = self.repos.get_ssl_fingerprint()
                    imapobj = imaplibutil.WrappedIMAP4_SSL(
                        self.hostname,
                        self.port,
                        self.sslclientkey,
                        self.sslclientcert,
                        self.sslcacertfile,
                        self.verifycert,
                        timeout=socket.getdefaulttimeout(),
                        fingerprint=fingerprint)
                else:
                    self.ui.connecting(self.hostname, self.port)
                    imapobj = imaplibutil.WrappedIMAP4(
                        self.hostname,
                        self.port,
                        timeout=socket.getdefaulttimeout())

                if not self.tunnel:
                    try:
                        # Try GSSAPI and continue if it fails
                        if 'AUTH=GSSAPI' in imapobj.capabilities and have_gss:
                            self.connectionlock.acquire()
                            self.ui.debug('imap',
                                          'Attempting GSSAPI authentication')
                            try:
                                imapobj.authenticate('GSSAPI', self.gssauth)
                            except imapobj.error as val:
                                self.gssapi = False
                                self.ui.debug('imap',
                                              'GSSAPI Authentication failed')
                            else:
                                self.gssapi = True
                                kerberos.authGSSClientClean(self.gss_vc)
                                self.gss_vc = None
                                self.gss_step = self.GSS_STATE_STEP
                                #if we do self.password = None then the next attempt cannot try...
                                #self.password = None
                            self.connectionlock.release()

                        if not self.gssapi:
                            if 'STARTTLS' in imapobj.capabilities and not\
                                    self.usessl:
                                self.ui.debug('imap',
                                              'Using STARTTLS connection')
                                imapobj.starttls()

                            if 'AUTH=CRAM-MD5' in imapobj.capabilities:
                                self.ui.debug(
                                    'imap',
                                    'Attempting CRAM-MD5 authentication')
                                try:
                                    imapobj.authenticate(
                                        'CRAM-MD5', self.md5handler)
                                except imapobj.error as val:
                                    self.plainauth(imapobj)
                            else:
                                # Use plaintext login, unless
                                # LOGINDISABLED (RFC2595)
                                if 'LOGINDISABLED' in imapobj.capabilities:
                                    raise OfflineImapError(
                                        "Plaintext login "
                                        "disabled by server. Need to use SSL?",
                                        OfflineImapError.ERROR.REPO)
                                self.plainauth(imapobj)
                        # Would bail by here if there was a failure.
                        success = 1
                        self.goodpassword = self.password
                    except imapobj.error as val:
                        self.passworderror = str(val)
                        raise

            # update capabilities after login, e.g. gmail serves different ones
            typ, dat = imapobj.capability()
            if dat != [None]:
                imapobj.capabilities = tuple(dat[-1].upper().split())

            if self.delim == None:
                listres = imapobj.list(self.reference, '""')[1]
                if listres == [None] or listres == None:
                    # Some buggy IMAP servers do not respond well to LIST "" ""
                    # Work around them.
                    listres = imapobj.list(self.reference, '"*"')[1]
                if listres == [None] or listres == None:
                    # No Folders were returned. This occurs, e.g. if the
                    # 'reference' prefix does not exist on the mail
                    # server. Raise exception.
                    err = "Server '%s' returned no folders in '%s'" % \
                        (self.repos.getname(), self.reference)
                    self.ui.warn(err)
                    raise Exception(err)
                self.delim, self.root = \
                            imaputil.imapsplit(listres[0])[1:]
                self.delim = imaputil.dequote(self.delim)
                self.root = imaputil.dequote(self.root)

            self.connectionlock.acquire()
            self.assignedconnections.append(imapobj)
            self.lastowner[imapobj] = curThread.ident
            self.connectionlock.release()
            return imapobj
        except Exception as e:
            """If we are here then we did not succeed in getting a
            connection - we should clean up and then re-raise the
            error..."""
            self.semaphore.release()

            if (self.connectionlock.locked()):
                self.connectionlock.release()

            severity = OfflineImapError.ERROR.REPO
            if type(e) == gaierror:
                #DNS related errors. Abort Repo sync
                #TODO: special error msg for e.errno == 2 "Name or service not known"?
                reason = "Could not resolve name '%s' for repository "\
                         "'%s'. Make sure you have configured the ser"\
                         "ver name correctly and that you are online."%\
                         (self.hostname, self.repos)
                raise OfflineImapError(reason, severity)

            elif isinstance(e, SSLError) and e.errno == 1:
                # SSL unknown protocol error
                # happens e.g. when connecting via SSL to a non-SSL service
                if self.port != 993:
                    reason = "Could not connect via SSL to host '%s' and non-s"\
                        "tandard ssl port %d configured. Make sure you connect"\
                        " to the correct port." % (self.hostname, self.port)
                else:
                    reason = "Unknown SSL protocol connecting to host '%s' for"\
                         "repository '%s'. OpenSSL responded:\n%s"\
                         % (self.hostname, self.repos, e)
                raise OfflineImapError(reason, severity)

            elif isinstance(e,
                            socket.error) and e.args[0] == errno.ECONNREFUSED:
                # "Connection refused", can be a non-existing port, or an unauthorized
                # webproxy (open WLAN?)
                reason = "Connection to host '%s:%d' for repository '%s' was "\
                    "refused. Make sure you have the right host and port "\
                    "configured and that you are actually able to access the "\
                    "network." % (self.hostname, self.port, self.reposname)
                raise OfflineImapError(reason, severity)
            # Could not acquire connection to the remote;
            # socket.error(last_error) raised
            if str(e)[:24] == "can't open socket; error":
                raise OfflineImapError("Could not connect to remote server '%s' "\
                    "for repository '%s'. Remote does not answer."
                    % (self.hostname, self.repos),
                    OfflineImapError.ERROR.REPO)
            else:
                # re-raise all other errors
                raise
Exemple #48
0
def _authenticate_gssapi(credentials, sock_info, cmd_func):
    """Authenticate using GSSAPI.
    """
    try:
        dummy, username, gsn = credentials
        # Starting here and continuing through the while loop below - establish
        # the security context. See RFC 4752, Section 3.1, first paragraph.
        result, ctx = kerberos.authGSSClientInit(
            gsn + '@' + sock_info.host, gssflags=kerberos.GSS_C_MUTUAL_FLAG)

        if result != kerberos.AUTH_GSS_COMPLETE:
            raise OperationFailure('Kerberos context failed to initialize.')

        try:
            # pykerberos uses a weird mix of exceptions and return values
            # to indicate errors.
            # 0 == continue, 1 == complete, -1 == error
            # Only authGSSClientStep can return 0.
            if kerberos.authGSSClientStep(ctx, '') != 0:
                raise OperationFailure('Unknown kerberos '
                                       'failure in step function.')

            # Start a SASL conversation with mongod/s
            # Note: pykerberos deals with base64 encoded byte strings.
            # Since mongo accepts base64 strings as the payload we don't
            # have to use bson.binary.Binary.
            payload = kerberos.authGSSClientResponse(ctx)
            cmd = SON([('saslStart', 1),
                       ('mechanism', 'GSSAPI'),
                       ('payload', payload),
                       ('autoAuthorize', 1)])
            response, _ = cmd_func(sock_info, '$external', cmd)

            # Limit how many times we loop to catch protocol / library issues
            for _ in xrange(10):
                result = kerberos.authGSSClientStep(ctx,
                                                    str(response['payload']))
                if result == -1:
                    raise OperationFailure('Unknown kerberos '
                                           'failure in step function.')

                payload = kerberos.authGSSClientResponse(ctx) or ''

                cmd = SON([('saslContinue', 1),
                           ('conversationId', response['conversationId']),
                           ('payload', payload)])
                response, _ = cmd_func(sock_info, '$external', cmd)

                if result == kerberos.AUTH_GSS_COMPLETE:
                    break
            else:
                raise OperationFailure('Kerberos '
                                       'authentication failed to complete.')

            # Once the security context is established actually authenticate.
            # See RFC 4752, Section 3.1, last two paragraphs.
            if kerberos.authGSSClientUnwrap(ctx,
                                            str(response['payload'])) != 1:
                raise OperationFailure('Unknown kerberos '
                                       'failure during GSS_Unwrap step.')

            if kerberos.authGSSClientWrap(ctx,
                                          kerberos.authGSSClientResponse(ctx),
                                          username) != 1:
                raise OperationFailure('Unknown kerberos '
                                       'failure during GSS_Wrap step.')

            payload = kerberos.authGSSClientResponse(ctx)
            cmd = SON([('saslContinue', 1),
                       ('conversationId', response['conversationId']),
                       ('payload', payload)])
            response, _ = cmd_func(sock_info, '$external', cmd)

        finally:
            kerberos.authGSSClientClean(ctx)

    except kerberos.KrbError, exc:
        raise OperationFailure(str(exc))
 def clean_context(self):
     if self.context is not None:
         log.debug("cleaning context")
         k.authGSSClientClean(self.context)
         self.context = None
Exemple #50
0
 def cleanup(self):
     kerberos.authGSSClientClean(self._context)
     self._context = None
Exemple #51
0
class CookieTransport(xmlrpclib.Transport):
    """
    Cookie enabled XML-RPC transport.

    USAGE:
    >>> import xmlrpclib
        import kobo.xmlrpc
        client = xmlrpclib.ServerProxy("http://<server>/xmlrpc", transport=kobo.xmlrpc.CookieTransport())
        # for https:// connections use kobo.xmlrpc.SafeCookieTransport() instead.
    """

    _use_datetime = False # fix for python 2.5+
    scheme = "http"

    def __init__(self, *args, **kwargs):
        cookiejar = kwargs.pop("cookiejar", None)
        self.timeout = kwargs.pop("timeout", 0)
        self.proxy_config = self._get_proxy(**kwargs)
        self.no_proxy = os.environ.get("no_proxy", "").lower().split(',')
        self.context = kwargs.pop('context', None)

        if hasattr(xmlrpclib.Transport, "__init__"):
            xmlrpclib.Transport.__init__(self, *args, **kwargs)

        self.cookiejar = cookiejar or cookielib.CookieJar()

        if hasattr(self.cookiejar, "load"):
            if not os.path.exists(self.cookiejar.filename):
                if hasattr(self.cookiejar, "save"):
                    self.cookiejar.save(self.cookiejar.filename)
            self.cookiejar.load(self.cookiejar.filename)

    def _get_proxy(self, **kwargs):
        """Return dict with appropriate proxy settings"""
        proxy = None
        proxy_user = None
        proxy_password = None

        if kwargs.get("proxy", None):
            # Use proxy from __init__ params
            proxy = kwargs["proxy"]
            if kwargs.get("proxy_user", None):
                proxy_user = kwargs["proxy_user"]
                if kwargs.get("proxy_password", None):
                    proxy_password = kwargs["proxy_user"]
        else:
            # Try to get proxy settings from environmental vars
            if self.scheme == "http" and os.environ.get("http_proxy", None):
                proxy = os.environ["http_proxy"]
            elif self.scheme == "https" and os.environ.get("https_proxy", None):
                proxy = os.environ["https_proxy"]

        if proxy:
            # Parse proxy address
            # e.g. http://user:[email protected]:8001/foo/bar

            # Get raw location without path
            location = urlparse.urlparse(proxy)[1]
            if not location:
                # proxy probably doesn't have a protocol in prefix
                location = urlparse.urlparse("http://%s" % proxy)[1]

            # Parse out username and password if present
            if '@' in location:
                userpas, location = location.split('@', 1)
                if userpas and location and not proxy_user:
                    # Set proxy user only if proxy_user is not set yet
                    proxy_user = userpas
                    if ':' in userpas:
                        proxy_user, proxy_password = userpas.split(':', 1)

            proxy = location

        proxy_settings = {
            "proxy": proxy,
            "proxy_user": proxy_user,
            "proxy_password": proxy_password,
        }

        return proxy_settings

    def make_connection(self, host):
        host.lower()
        host_ = host  # Host with(out) port
        if ':' in host:
            # Remove port from the host
            host_ = host.split(':')[0]
        else:
            host_ = "%s:%s" % (host, TimeoutHTTPProxyConnection.default_port)

        if self.proxy_config["proxy"] and host not in self.no_proxy and host_ not in self.no_proxy:
            if sys.version_info[:2] < (2, 7):
                host, extra_headers, x509 = self.get_host_info(host)
                conn = TimeoutProxyHTTP(host, **self.proxy_config)
                conn.set_timeout(self.timeout)
                return conn
            else:
                CONNECTION_LOCK.acquire()
                host, extra_headers, x509 = self.get_host_info(host)
                conn = TimeoutProxyHTTPS(host, **self.proxy_config)
                conn.set_timeout(self.timeout)
                CONNECTION_LOCK.release()
                return conn

        if sys.version_info[:2] < (2, 7):
            host, extra_headers, x509 = self.get_host_info(host)
            conn = TimeoutHTTP(host)
            conn.set_timeout(self.timeout)
            return conn
        else:
            CONNECTION_LOCK.acquire()
            self._connection = (None, None) # this disables connection caching which causes a race condition when running in threads
            conn = xmlrpclib.Transport.make_connection(self, host)
            CONNECTION_LOCK.release()
            if self.timeout:
                conn.timeout = self.timeout
            return conn

    def send_request(self, connection, handler, request_body):
        return xmlrpclib.Transport.send_request(self, connection, handler, request_body)

    def send_host(self, connection, host):
        return xmlrpclib.Transport.send_host(self, connection, host)

    def send_cookies(self, connection, cookie_request):
        """Add cookies to the header."""
        self.cookiejar.add_cookie_header(cookie_request)

        for header, value in cookie_request.header_items():
            if header.startswith("Cookie"):
                connection.putheader(header, value)

    def _save_cookies(self, headers, cookie_request):
        cookie_response = CookieResponse(headers)
        self.cookiejar.extract_cookies(cookie_response, cookie_request)
        if hasattr(self.cookiejar, "save"):
            self.cookiejar.save(self.cookiejar.filename)

    def _kerberos_client_request(self, host, handler, errcode, errmsg, headers):
        """Kerberos auth - create a client request string"""

        # check if "Negotiate" challenge is present in headers
        negotiate = [i.lower() for i in headers.get("WWW-Authenticate", "").split(", ")]
        if "negotiate" not in negotiate:
            # negotiate not supported, raise 401 error
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # initialize GSSAPI
        service = "HTTP@%s" % host
        rc, vc = kerberos.authGSSClientInit(service)
        if rc != 1:
            errmsg = "KERBEROS: Could not initialize GSSAPI"
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # do a client step
        rc = kerberos.authGSSClientStep(vc, "")
        if rc != 0:
            errmsg = "KERBEROS: Client step failed"
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        return vc, kerberos.authGSSClientResponse(vc)

    def _kerberos_verify_response(self, vc, host, handler, errcode, errmsg, headers):
        """Kerberos auth - verify client identity"""
        # verify that headers contain WWW-Authenticate header
        auth_header = headers.get("WWW-Authenticate", None)
        if auth_header is None:
            errcode = 401
            errmsg = "KERBEROS: No WWW-Authenticate header in second HTTP response"
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # verify that WWW-Authenticate contains Negotiate
        splits = auth_header.split(" ", 1)
        if (len(splits) != 2) or (splits[0].lower() != "negotiate"):
            errcode = 401
            errmsg = "KERBEROS: Incorrect WWW-Authenticate header in second HTTP response: %s" % auth_header
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # do another client step to verify response from server
        errmsg = "KERBEROS: Could not verify server WWW-Authenticate header in second HTTP response"
        try:
            rc = kerberos.authGSSClientStep(vc, splits[1])
            if rc == -1:
                errcode = 401
                raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)
        except kerberos.GSSError, ex:
            errcode = 401
            errmsg += ": %s/%s" % (ex[0][0], ex[1][0])
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # cleanup
        rc = kerberos.authGSSClientClean(vc)
        if rc != 1:
            errcode = 401
            errmsg = "KERBEROS: Could not clean-up GSSAPI: %s/%s" % (ex[0][0], ex[1][0])
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)
Exemple #52
0
resp = s.request('POST', url, headers=k_headers,data=body)
if resp.status_code == httplib.FORBIDDEN:
    logging.error(
        "Forbidden: Check WinRM port and version")
elif resp.status_code == httplib.UNAUTHORIZED:
    logging.error(
        "Unauthorized: Check username and password")
elif resp.status_code == httplib.OK:
    logging.debug("HTTP OK!  Query Sent")
    print("HTTP OK!  Query Sent")
    print_body = ''.join([i if isprint(i) else '.' for i in resp.content])
    print("Response from server:\n{0}".format(print_body))
    b_start = resp.content.index("Content-Type: application/octet-stream") + \
              len("Content-Type: application/octet-stream\r\n")
    b_end = resp.content.index("--Encrypted Boundary",b_start)
    ebody = base64.b64encode(resp.content[b_start:b_end])
    rc = kerberos.authGSSClientUnwrapIov(context, ebody)
    if rc == kerberos.AUTH_GSS_COMPLETE:
        body = base64.b64decode(kerberos.authGSSClientResponse(context))
        body_xml = xml.dom.minidom.parseString(body)
        pretty_xml_as_string = body_xml.toprettyxml(indent="  ")
        print("{0}".format(pretty_xml_as_string))
else:
    logging.debug("HTTP status: {0}, {1}".format(
        resp.status_code,resp.content))


s.close()
kerberos.authGSSClientClean(context)

Exemple #53
0
 def dispose(self):
     kerberos.authGSSClientClean(self.context)