示例#1
0
def validate(username, password, domain = ""):
    auth_info = username, domain, password
    ca = ClientAuth("NTLM", auth_info = auth_info)
    sa = ServerAuth("NTLM")
      
    data = err = None
    while err != 0:
        err, data = ca.authorize(data)
        err, data = sa.authorize(data)
示例#2
0
def validate(username, password, domain=""):
    auth_info = username, domain, password
    ca = ClientAuth("NTLM", auth_info=auth_info)
    sa = ServerAuth("NTLM")

    data = err = None
    while err != 0:
        err, data = ca.authorize(data)
        err, data = sa.authorize(data)
示例#3
0
 def http_error_401(self, req, fp, code, msg, headers):
     supported_schemes = [s.strip() for s in headers.get("WWW-Authenticate", "").split(",")]
     #dns_domain = os.environ['USERDNSDOMAIN']
     dns_domain = 'tranquilit.local'
     if('Negotiate' in supported_schemes):
         try:
             ca = ClientAuth("Kerberos", targetspn='HTTP/%s@%s' % (req.host.split(':')[0], dns_domain), auth_info=None)
             out_buf = ca.authorize(None)[1]
             data = out_buf[0].Buffer
             auth = encodestring(data).replace("\012", "")
             req.add_header('Authorization', 'Negotiate' + ' ' + auth)
             return self.parent.open(req)
         except:
             if('Kerberos' not in supported_schemes):
                 # if we can not fall back to NTLM, report error
                 raise
示例#4
0
 def http_error_401(self, req, fp, code, msg, headers):
     supported_schemes = [
         s.strip() for s in headers.get("WWW-Authenticate", "").split(",")
     ]
     #dns_domain = os.environ['USERDNSDOMAIN']
     dns_domain = 'tranquilit.local'
     if ('Negotiate' in supported_schemes):
         try:
             ca = ClientAuth("Kerberos",
                             targetspn='HTTP/%s@%s' %
                             (req.host.split(':')[0], dns_domain),
                             auth_info=None)
             out_buf = ca.authorize(None)[1]
             data = out_buf[0].Buffer
             auth = encodestring(data).replace("\012", "")
             req.add_header('Authorization', 'Negotiate' + ' ' + auth)
             return self.parent.open(req)
         except:
             if ('Kerberos' not in supported_schemes):
                 # if we can not fall back to NTLM, report error
                 raise
示例#5
0
    def __init__(self, host, delegate_creds):
        super().__init__(host)

        flags = ISC_REQ_MUTUAL_AUTH | ISC_REQ_INTEGRITY

        if delegate_creds:
            flags |= ISC_REQ_DELEGATE

        try:
            self._ctx = ClientAuth('Kerberos', targetspn=self._host,
                                   scflags=flags)
        except SSPIError as exc:
            raise GSSError(1, 1, details=exc.strerror) from None

        self._init_token = self.step(None)
示例#6
0
def open_url(host, url):
    h = httplib.HTTPConnection(host)
#    h.set_debuglevel(9)
    h.putrequest('GET', url)
    h.endheaders()
    resp = h.getresponse()
    print "Initial response is", resp.status, resp.reason
    body = resp.read()
    if resp.status == 302: # object moved
        url = "/" + resp.msg["location"]
        resp.close()
        h.putrequest('GET', url)
        h.endheaders()
        resp = h.getresponse()
        print "After redirect response is", resp.status, resp.reason
    if options.show_headers:
        print "Initial response headers:"
        for name, val in resp.msg.items():
            print " %s: %s" % (name, val)
    if options.show_body:
        print body
    if resp.status == 401:
        # 401: Unauthorized - here is where the real work starts
        auth_info = None
        if options.user or options.domain or options.password:
            auth_info = options.user, options.domain, options.password
        ca = ClientAuth("NTLM", auth_info=auth_info)
        auth_scheme = ca.pkg_info['Name']
        data = None
        while 1:
            err, out_buf = ca.authorize(data)
            data = out_buf[0].Buffer
            # Encode it as base64 as required by HTTP
            auth = encodestring(data).replace("\012", "")
            h.putrequest('GET', url)
            h.putheader('Authorization', auth_scheme + ' ' + auth)
            h.putheader('Content-Length', '0')
            h.endheaders()
            resp = h.getresponse()
            if options.show_headers:
                print "Token dance headers:"
                for name, val in resp.msg.items():
                    print " %s: %s" % (name, val)

            if err==0:
                break
            else:
                if resp.status != 401:
                    print "Eeek - got response", resp.status
                    cl = resp.msg.get("content-length")
                    if cl:
                        print repr(resp.read(int(cl)))
                    else:
                        print "no content!"

                assert resp.status == 401, resp.status

            assert not resp.will_close, "NTLM is per-connection - must not close"
            schemes = [s.strip() for s in resp.msg.get("WWW-Authenticate", "").split(",")]
            for scheme in schemes:
                if scheme.startswith(auth_scheme):
                    data = decodestring(scheme[len(auth_scheme)+1:])
                    break
            else:
                print "Could not find scheme '%s' in schemes %r" % (auth_scheme, schemes)
                break
        
            resp.read()
    print "Final response status is", resp.status, resp.reason
    if resp.status == 200:
        # Worked!
        # Check we can read it again without re-authenticating.
        if resp.will_close:
            print "EEEK - response will close, but NTLM is per connection - it must stay open"
        body = resp.read()
        if options.show_body:
            print "Final response body:"
            print body
        h.putrequest('GET', url)
        h.endheaders()
        resp = h.getresponse()
        print "Second fetch response is", resp.status, resp.reason
        if options.show_headers:
            print "Second response headers:"
            for name, val in resp.msg.items():
                print " %s: %s" % (name, val)
        
        resp.read(int(resp.msg.get("content-length", 0)))
    elif resp.status == 500:
        print "Error text"
        print resp.read()
    else:
        if options.show_body:
            cl = resp.msg.get("content-length")
            print resp.read(int(cl))
示例#7
0
def open_url(host, url):
    h = http.client.HTTPConnection(host)
    #    h.set_debuglevel(9)
    h.putrequest('GET', url)
    h.endheaders()
    resp = h.getresponse()
    print("Initial response is", resp.status, resp.reason)
    body = resp.read()
    if resp.status == 302:  # object moved
        url = "/" + resp.msg["location"]
        resp.close()
        h.putrequest('GET', url)
        h.endheaders()
        resp = h.getresponse()
        print("After redirect response is", resp.status, resp.reason)
    if options.show_headers:
        print("Initial response headers:")
        for name, val in list(resp.msg.items()):
            print(" %s: %s" % (name, val))
    if options.show_body:
        print(body)
    if resp.status == 401:
        # 401: Unauthorized - here is where the real work starts
        auth_info = None
        if options.user or options.domain or options.password:
            auth_info = options.user, options.domain, options.password
        ca = ClientAuth("NTLM", auth_info=auth_info)
        auth_scheme = ca.pkg_info['Name']
        data = None
        while 1:
            err, out_buf = ca.authorize(data)
            data = out_buf[0].Buffer
            # Encode it as base64 as required by HTTP
            auth = encodestring(data).replace("\012", "")
            h.putrequest('GET', url)
            h.putheader('Authorization', auth_scheme + ' ' + auth)
            h.putheader('Content-Length', '0')
            h.endheaders()
            resp = h.getresponse()
            if options.show_headers:
                print("Token dance headers:")
                for name, val in list(resp.msg.items()):
                    print(" %s: %s" % (name, val))

            if err == 0:
                break
            else:
                if resp.status != 401:
                    print("Eeek - got response", resp.status)
                    cl = resp.msg.get("content-length")
                    if cl:
                        print(repr(resp.read(int(cl))))
                    else:
                        print("no content!")

                assert resp.status == 401, resp.status

            assert not resp.will_close, "NTLM is per-connection - must not close"
            schemes = [
                s.strip()
                for s in resp.msg.get("WWW-Authenticate", "").split(",")
            ]
            for scheme in schemes:
                if scheme.startswith(auth_scheme):
                    data = decodestring(scheme[len(auth_scheme) + 1:])
                    break
            else:
                print("Could not find scheme '%s' in schemes %r" %
                      (auth_scheme, schemes))
                break

            resp.read()
    print("Final response status is", resp.status, resp.reason)
    if resp.status == 200:
        # Worked!
        # Check we can read it again without re-authenticating.
        if resp.will_close:
            print(
                "EEEK - response will close, but NTLM is per connection - it must stay open"
            )
        body = resp.read()
        if options.show_body:
            print("Final response body:")
            print(body)
        h.putrequest('GET', url)
        h.endheaders()
        resp = h.getresponse()
        print("Second fetch response is", resp.status, resp.reason)
        if options.show_headers:
            print("Second response headers:")
            for name, val in list(resp.msg.items()):
                print(" %s: %s" % (name, val))

        resp.read(int(resp.msg.get("content-length", 0)))
    elif resp.status == 500:
        print("Error text")
        print(resp.read())
    else:
        if options.show_body:
            cl = resp.msg.get("content-length")
            print(resp.read(int(cl)))
示例#8
0
    def connect(self, host, user=None, password=None, passthrough=False, trace_file=None, sock_timeout=None):
        """Opens a session to a VC/ESX server with the given credentials:
        @host: is the server's hostname or address. If the web service uses
        another protocol or port than the default, you must use the full
        service URL (e.g. http://myhost:8888/sdk)
        @user: (optional) username to connect with
        @password: (optional) password to authenticate the session
        @passthrough: (optional) use Windows session credentials
        or MIT Kerberos credentials to connect.
        User should provide user/password pair OR set passthrough to True
        @trace_file: (optional) a file path to log SOAP requests and responses
        @sock_timeout: (optional) only for python >= 2.6, sets the connection
        timeout for sockets, in python 2.5 you'll  have to use
        socket.setdefaulttimeout(secs) to change the global setting.
        """
        if (((user is None or password is None) and not passthrough)
        or ((user is not None or password is not None) and passthrough)):
            raise TypeError("connect() takes user/password pair OR passthrough=True")

        self.__user = user
        self.__password = password
        #Generate server's URL
        if not isinstance(host, basestring):
            raise VIException("'host' should be a string with the ESX/VC url."
                             ,FaultTypes.PARAMETER_ERROR)

        elif (host.lower().startswith('http://')
        or host.lower().startswith('https://')):
            server_url = host.lower()

        else:
            server_url = 'https://%s/sdk' % host

        try:
            #get the server's proxy
            locator = VI.VimServiceLocator()
            args = {'url':server_url}
            if trace_file:
                trace=open(trace_file, 'w')
                args['tracefile'] = trace
            if sock_timeout and sys.version_info >= (2, 6):
                args['transdict'] = {'timeout':sock_timeout}

            self._proxy = locator.getVimPortType(**args)

            for header, value in self.__initial_headers.iteritems():
                self._proxy.binding.AddHeader(header, value)

            #get service content from service instance
            request = VI.RetrieveServiceContentRequestMsg()
            mor_service_instance = request.new__this('ServiceInstance')
            mor_service_instance.set_attribute_type(MORTypes.ServiceInstance)
            request.set_element__this(mor_service_instance)
            self._do_service_content = self._proxy.RetrieveServiceContent(
                                                             request)._returnval
            self.__server_type = self._do_service_content.About.Name
            self.__api_version = self._do_service_content.About.ApiVersion
            self.__api_type = self._do_service_content.About.ApiType

            if not passthrough:
                #login with user/password
                request = VI.LoginRequestMsg()
                mor_session_manager = request.new__this(
                                            self._do_service_content.SessionManager)
                mor_session_manager.set_attribute_type(MORTypes.SessionManager)
                request.set_element__this(mor_session_manager)
                request.set_element_userName(user)
                request.set_element_password(password)
                self.__session = self._proxy.Login(request)._returnval
                self.__logged = True

            else:
                fqdn, aliases, addrs = gethostbyaddr(urlparse(server_url).netloc)
                if os.name == 'nt':
                    #login with Windows session credentials
                    try:
                        from sspi import ClientAuth
                    except ImportError:
                        raise ImportError("To enable passthrough authentication please"\
                            " install pywin32 (available for Windows only)")
                    spn = "host/%s" % fqdn
                    client = ClientAuth("Kerberos", targetspn=spn)

                    def get_token(serverToken=None):
                        if serverToken is not None:
                            serverToken = b64decode(serverToken)
                        err, bufs = client.authorize(serverToken)
                        return b64encode(bufs[0].Buffer)
                else:
                    #login with MIT Kerberos credentials
                    try:
                        import kerberos
                    except ImportError:
                        raise ImportError("To enable passthrough authentication please"\
                            " install python bindings for kerberos")
                    spn = "host@%s" % fqdn
                    flags = kerberos.GSS_C_INTEG_FLAG|kerberos.GSS_C_SEQUENCE_FLAG|\
                        kerberos.GSS_C_REPLAY_FLAG|kerberos.GSS_C_CONF_FLAG
                    errc, client = kerberos.authGSSClientInit(spn, gssflags=flags)

                    def get_token(serverToken=''):
                        cres = kerberos.authGSSClientStep(client, serverToken)
                        return kerberos.authGSSClientResponse(client)

                token = get_token()

                while not self.__logged:
                    try:
                        request = VI.LoginBySSPIRequestMsg()
                        mor_session_manager = request.new__this(
                                                    self._do_service_content.SessionManager)
                        mor_session_manager.set_attribute_type(MORTypes.SessionManager)
                        request.set_element__this(mor_session_manager)
                        request.set_element_base64Token(token)
                        self.__session = self._proxy.LoginBySSPI(request)._returnval
                        self.__logged = True
                    except (VI.ZSI.FaultException), e:
                        if e.fault.string == "fault.SSPIChallenge.summary":
                            serverToken = e.fault.detail[0].Base64Token
                            token = get_token(serverToken)
                        else:
                            raise e

        except (VI.ZSI.FaultException), e:
            raise VIApiException(e)
class HttpNtlmSspiAuth(AuthBase):
    """Requests extension to auto-authenticate user.

    HTTP NTLM Authentication using SSPI for passwordless login.
    """

    def __init__(self):
        self.AuthGen = ClientAuth("NTLM")

    def __call__(self, r):
        r.headers["Connection"] = "Keep-Alive"
        r.register_hook("response", self.response_hook)
        return r

    def response_hook(self, r, **kwargs):
        """
        Identifies the type of authentication needed and the header title
        and routes the information to perform the authentication dance
        """
        www_authenticate = r.headers.get("www-authenticate", "").lower()
        if r.status_code == 401 and "ntlm" in www_authenticate:
            return self.apply_sspi("www-authenticate", "Authorization", r, kwargs)

        proxy_authenticate = r.headers.get("proxy-authenticate", "").lower()
        if r.status_code == 407 and "ntlm" in proxy_authenticate:
            return self.apply_sspi("proxy-authenticate", "Proxy-authorization", r, kwargs)
        return r

    def authenticate(self, challenge=None):
        """Performs the authentication handshake

        Parameters
        ----------
        challenge : str, optional
            Challenge is the response encoded response from the web-server that is
            typically the response to the client's initial challenge. When `challenge`
            is called without a `challenge`, it generates the first challenge to the
            server that open the communication between them.

        Returns
        -------
        str
            Returns a challenge for the server. That will either initiate the
            communication, or respond to the webservice's challenge.
        """
        challenge = challenge.decode("base64") if challenge else None
        _, output_buffer = self.AuthGen.authorize(challenge)
        return "NTLM {0!s}".format(output_buffer[0].Buffer.encode("base64").replace("\n", ""))

    def new_request(self, response):
        response.content
        response.raw.release_conn()
        return response.request.copy()

    def apply_sspi(self, auth_header_field, auth_header, response, args):
        """Performs the authentication dance between server and client.
        """
        if auth_header in response.request.headers:
            return response

        # A streaming response breaks authentication. Disabled for authentication dance
        # set back to default (args) for final return
        request = self.new_request(response)
        request.headers[auth_header] = self.authenticate()
        response = response.connection.send(request, **dict(args, stream=False))

        # Previous request/response sent initial msg to begin dance.
        # Now we authenticate using the response
        request = self.new_request(response)
        ntlm_header_value = response.headers[auth_header_field][5:]
        request.headers[auth_header] = self.authenticate(ntlm_header_value)

        # In case authentication info stored in cookies
        request.headers["Cookie"] = response.headers.get("set-cookie")

        return response.connection.send(request, **args)
示例#10
0
 def __init__(self):
     self.AuthGen = ClientAuth("NTLM")