コード例 #1
0
ファイル: ldapsyntax.py プロジェクト: norox/ldaptor
    def _cbDeleteDone(self, msg):
        assert isinstance(msg, pureldap.LDAPResult)
        if not isinstance(msg, pureldap.LDAPDelResponse):
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)
        assert msg.referral is None  # TODO
        if msg.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        assert msg.matchedDN == ""
        return self
コード例 #2
0
    def _cbDeleteDone(self, msg):
        assert isinstance(msg, pureldap.LDAPResult)
        if not isinstance(msg, pureldap.LDAPDelResponse):
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)
        assert msg.referral is None  # TODO
        if msg.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        self._assertMatchedDN(msg.matchedDN)
        return self
コード例 #3
0
ファイル: client.py プロジェクト: slayer/duoauthproxy-freebsd
    def perform_bind_ntlm(
        client,
        username,
        password,
        domain,
        workstation,
        ntlm_version,
        peercert: X509 = None,
    ):
        """
        Perform bind using custom NTLM mechanism. Will return different value
        based on ntlm_version.

        NTLMv2 using session key for future sign and seal.
        We do not support NTLMv1 with sign and seal on purpose.

        :returns
            NTLMv1 : None
            NTLMv2 : session key for sign and seal
        """
        sign_seal_enable = client._ntlm_sign_seal_enable(ntlm_version)
        ntlm_negotiate_msg = ntlm.create_negotiate_msg(
            sign_seal=sign_seal_enable)
        op = pureldap.LDAPBindRequest(auth=("GSS-SPNEGO", ntlm_negotiate_msg),
                                      sasl=True)
        response = yield client.send(op)
        if response.resultCode != ldaperrors.LDAPSaslBindInProgress.resultCode:
            raise ldaperrors.get(response.resultCode, response.errorMessage)

        ntlm_challenge_msg = response.serverSaslCreds.value
        ntlm_authenticate = ntlm.create_ntlm_auth(
            ntlm_negotiate_msg,
            ntlm_challenge_msg,
            username,
            password,
            domain,
            workstation,
            ntlm_version,
            sign_seal=sign_seal_enable,
            peercert=peercert,
        )
        op = pureldap.LDAPBindRequest(
            auth=("GSS-SPNEGO", ntlm_authenticate.get_encoded_msg()),
            sasl=True)
        response = yield client.send(op)
        if response.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(response.resultCode, response.errorMessage)
        if ntlm_version == 2 and isinstance(ntlm_authenticate,
                                            ntlm.NTLMv2Auth):
            defer.returnValue(ntlm_authenticate.session_key)
コード例 #4
0
    def _cbSearchMsg(self, msg, controls, d, callback, complete,
                     sizeLimitIsNonFatal):
        if isinstance(msg, pureldap.LDAPSearchResultDone):
            assert msg.referral is None  # TODO
            e = ldaperrors.get(msg.resultCode, msg.errorMessage)
            if not isinstance(e, ldaperrors.Success):
                try:
                    raise e
                except ldaperrors.LDAPSizeLimitExceeded:
                    if sizeLimitIsNonFatal:
                        pass
                except Exception:
                    d.errback(Failure())
                    return True

            # search ended successfully
            self._assertMatchedDN(msg.matchedDN)
            d.callback(controls)
            return True
        elif isinstance(msg, pureldap.LDAPSearchResultEntry):
            self._cbSearchEntry(callback,
                                msg.objectName,
                                msg.attributes,
                                complete=complete)
            return False
        elif isinstance(msg, pureldap.LDAPSearchResultReference):
            return False
        else:
            raise ldaperrors.LDAPProtocolError("bad search response: %r" % msg)
コード例 #5
0
ファイル: test_ldaperrors.py プロジェクト: psi29a/ldaptor
 def test_get_existing_exception(self):
     """Getting existing LDAPException subclass"""
     exception = ldaperrors.get(49, 'Error message')
     self.assertEqual(exception.__class__, ldaperrors.LDAPInvalidCredentials)
     self.assertEqual(exception.resultCode, 49)
     self.assertEqual(exception.name, b'invalidCredentials')
     self.assertEqual(exception.message, 'Error message')
コード例 #6
0
ファイル: ldapsyntax.py プロジェクト: GrayAn/ldaptor
    def _cbSearchMsg(self, msg, controls, d, callback, complete, sizeLimitIsNonFatal):
        if isinstance(msg, pureldap.LDAPSearchResultDone):
            assert msg.referral is None  # TODO
            e = ldaperrors.get(msg.resultCode, msg.errorMessage)
            if not isinstance(e, ldaperrors.Success):
                try:
                    raise e
                except ldaperrors.LDAPSizeLimitExceeded:
                    if sizeLimitIsNonFatal:
                        pass
                except Exception:
                    d.errback(Failure())
                    return True

            # search ended successfully
            self._assertMatchedDN(msg.matchedDN)
            d.callback(controls)
            return True
        elif isinstance(msg, pureldap.LDAPSearchResultEntry):
            self._cbSearchEntry(callback, msg.objectName, msg.attributes,
                                complete=complete)
            return False
        elif isinstance(msg, pureldap.LDAPSearchResultReference):
            return False
        else:
            raise ldaperrors.LDAPProtocolError("bad search response: %r" % msg)
コード例 #7
0
    def _cbSetPassword_ExtendedOperation(self, msg):
        assert isinstance(msg, pureldap.LDAPExtendedResponse)
        assert msg.referral is None  # TODO
        if msg.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        self._assertMatchedDN(msg.matchedDN)
        return self
コード例 #8
0
ファイル: ldapsyntax.py プロジェクト: chevah/ldaptor
    def _cbSetPassword_ExtendedOperation(self, msg):
        assert isinstance(msg, pureldap.LDAPExtendedResponse)
        assert msg.referral is None #TODO
        if msg.resultCode!=ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        assert msg.matchedDN==''
        return self
コード例 #9
0
    def _cbStartTLS(self, msg, ctx):
        assert isinstance(msg, pureldap.LDAPExtendedResponse)
        assert msg.referral is None  #TODO
        if msg.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        self.transport.startTLS(ctx)
        return self
コード例 #10
0
 def test_get_existing_exception(self):
     """Getting existing LDAPException subclass"""
     exception = ldaperrors.get(49, "Error message")
     self.assertEqual(exception.__class__,
                      ldaperrors.LDAPInvalidCredentials)
     self.assertEqual(exception.resultCode, 49)
     self.assertEqual(exception.name, b"invalidCredentials")
     self.assertEqual(exception.message, "Error message")
コード例 #11
0
ファイル: ldapclient.py プロジェクト: KenMacD/ldaptor
    def _cbStartTLS(self, msg, ctx):
        assert isinstance(msg, pureldap.LDAPExtendedResponse)
        assert msg.referral is None #TODO
        if msg.resultCode!=ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        self.transport.startTLS(ctx)
        return self
コード例 #12
0
    def _cbMoveDone(self, msg, newDN):
        assert isinstance(msg, pureldap.LDAPModifyDNResponse)
        assert msg.referral is None  # TODO
        if msg.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        self._assertMatchedDN(msg.matchedDN)
        self.dn = newDN
        return self
コード例 #13
0
ファイル: ldapsyntax.py プロジェクト: norox/ldaptor
    def _cbAddDone(self, msg, dn):
        assert isinstance(msg, pureldap.LDAPAddResponse), "LDAPRequest response was not an LDAPAddResponse: %r" % msg
        assert msg.referral is None  # TODO
        if msg.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        assert msg.matchedDN == ""
        e = self.__class__(dn=dn, client=self.client)
        return e
コード例 #14
0
ファイル: ldapsyntax.py プロジェクト: chevah/ldaptor
    def _cbMoveDone(self, msg, newDN):
        assert isinstance(msg, pureldap.LDAPModifyDNResponse)
        assert msg.referral is None #TODO
        if msg.resultCode!=ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        assert msg.matchedDN==''
        self.dn = newDN
        return self
コード例 #15
0
    def _cbAddDone(self, msg, dn):
        assert isinstance(msg, pureldap.LDAPAddResponse), \
            "LDAPRequest response was not an LDAPAddResponse: %r" % msg
        assert msg.referral is None  # TODO
        if msg.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        self._assertMatchedDN(msg.matchedDN)
        e = self.__class__(dn=dn, client=self.client)
        return e
コード例 #16
0
    def _commit_success(self, msg):
        assert isinstance(msg, pureldap.LDAPModifyResponse)
        assert msg.referral is None  # TODO
        if msg.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        self._assertMatchedDN(msg.matchedDN)

        self._remoteData = entry.EditableLDAPEntry(self.dn, self)
        self._journal = []
        return self
コード例 #17
0
ファイル: ldapsyntax.py プロジェクト: chevah/ldaptor
    def _commit_success(self, msg):
        assert isinstance(msg, pureldap.LDAPModifyResponse)
        assert msg.referral is None #TODO
        if msg.resultCode!=ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        assert msg.matchedDN==''

        self._remoteData = entry.EditableLDAPEntry(self.dn, self)
        self._journal=[]
        return self
コード例 #18
0
ファイル: ldapsyntax.py プロジェクト: chevah/ldaptor
 def _cbSearchMsg(self, msg, d, callback, complete, sizeLimitIsNonFatal):
     if isinstance(msg, pureldap.LDAPSearchResultDone):
         assert msg.referral is None #TODO
         e = ldaperrors.get(msg.resultCode, msg.errorMessage)
         if not isinstance(e, ldaperrors.Success):
             try:
                 raise e
             except ldaperrors.LDAPSizeLimitExceeded, e:
                 if sizeLimitIsNonFatal:
                     pass
             except:
                 d.errback(Failure())
コード例 #19
0
 def _cbSearchMsg(self, msg, d, callback, complete, sizeLimitIsNonFatal):
     if isinstance(msg, pureldap.LDAPSearchResultDone):
         assert msg.referral is None  #TODO
         e = ldaperrors.get(msg.resultCode, msg.errorMessage)
         if not isinstance(e, ldaperrors.Success):
             try:
                 raise e
             except ldaperrors.LDAPSizeLimitExceeded, e:
                 if sizeLimitIsNonFatal:
                     pass
             except:
                 d.errback(Failure())
コード例 #20
0
ファイル: ldapclient.py プロジェクト: cwaldbieser/ldaptor
    def _cbStartTLS(self, msg, ctx):
        assert isinstance(msg, pureldap.LDAPExtendedResponse)
        assert msg.referral is None  # TODO
        if msg.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        if (msg.responseName is not None) and \
                (msg.responseName != pureldap.LDAPStartTLSResponse.oid):
            raise LDAPStartTLSInvalidResponseName(msg.responseName)

        self.transport.startTLS(ctx)
        return self
コード例 #21
0
    def perform_bind_ntlm(self, dn, username, password, domain, workstation,
                          ntlm_version):
        ntlm_negotiate_msg = ntlm.create_negotiate_msg()
        op = pureldap.LDAPBindRequest(dn=dn,
                                      auth=('GSS-SPNEGO', ntlm_negotiate_msg),
                                      sasl=True)
        response = yield self.send(op)
        if response.resultCode != ldaperrors.LDAPSaslBindInProgress.resultCode:
            raise ldaperrors.get(response.resultCode, response.errorMessage)

        ntlm_challenge_msg = response.serverSaslCreds.value
        ntlm_authenticate_msg = ntlm.create_authenticate_msg(
            ntlm_negotiate_msg, ntlm_challenge_msg, username, password, domain,
            workstation, ntlm_version)
        op = pureldap.LDAPBindRequest(dn=dn,
                                      auth=('GSS-SPNEGO',
                                            ntlm_authenticate_msg),
                                      sasl=True)
        response = yield self.send(op)
        if response.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(response.resultCode, response.errorMessage)
コード例 #22
0
    def _cbStartTLS(self, msg, ctx):
        assert isinstance(msg, pureldap.LDAPExtendedResponse)
        assert msg.referral is None  # TODO
        if msg.resultCode != ldaperrors.Success.resultCode:
            raise ldaperrors.get(msg.resultCode, msg.errorMessage)

        if (msg.responseName is not None) and \
                (msg.responseName != pureldap.LDAPStartTLSResponse.oid):
            raise LDAPStartTLSInvalidResponseName(msg.responseName)

        self.transport.startTLS(ctx)
        return self
コード例 #23
0
ファイル: client.py プロジェクト: slayer/duoauthproxy-freebsd
    def _send_sspi_bind(self, current_buffer):
        # format request and send it
        op = pureldap.LDAPBindRequest(
            auth=("GSS-SPNEGO", current_buffer[0].Buffer),
            sasl="True",
        )
        response = yield self.send(op)

        # If we got something other than a success or challenge back from
        # the bind, an LDAP error occurred. Halt immediately.
        if response.resultCode not in [
                ldaperrors.Success.resultCode,
                ldaperrors.LDAPSaslBindInProgress.resultCode,
        ]:
            raise ldaperrors.get(response.resultCode, response.errorMessage)

        return response
コード例 #24
0
        def handle_msg(value, controls, d):
            try:
                if isinstance(value, pureldap.LDAPSearchResultDone):
                    e = ldaperrors.get(value.resultCode, value.errorMessage)
                    if isinstance(e, (ldaperrors.Success,
                                      ldaperrors.LDAPSizeLimitExceeded)):
                        cookie = get_cookie(controls)
                        d.callback((None, cookie))
                    else:
                        d.callback((e, None))
                elif isinstance(value, pureldap.LDAPSearchResultEntry):
                    # Always send DN. Overwrite DN from attribute set, if any.
                    obj = {
                        "distinguishedname": [escape_bytes(value.objectName)]
                    }

                    for k, vs in value.attributes:
                        # Smash attribute name case.
                        k = k.decode().lower()

                        # Server may not honor attributes (e.g.
                        # SearchByTreeWalkingMixin).
                        if attributes and k.encode() not in attributes:
                            continue

                        # Covert value to list and encode for JSON.
                        vs = [escape_bytes(v) for v in vs]

                        obj[k] = vs

                    # Refuse to return certain attributes even if all
                    # attributes were requested.
                    obj.pop("userpassword", None)

                    res.append(obj)
            except Exception:
                log.failure("Unexpected error handling message")
            finally:
                return isinstance(value, (
                    pureldap.LDAPBindResponse,
                    pureldap.LDAPSearchResultDone,
                ))
コード例 #25
0
 def perform_bind_plain(self, dn, password):
     op = pureldap.LDAPBindRequest(dn=dn, auth=password, sasl=False)
     response = yield self.send(op)
     if response.resultCode != ldaperrors.Success.resultCode:
         raise ldaperrors.get(response.resultCode, response.errorMessage)
コード例 #26
0
ファイル: test_ldaperrors.py プロジェクト: psi29a/ldaptor
 def test_get_success(self):
     """Getting OK message"""
     success = ldaperrors.get(0, 'Some message')
     self.assertEqual(success.__class__, ldaperrors.Success)
     self.assertEqual(success.resultCode, 0)
     self.assertEqual(success.name, b'success')
コード例 #27
0
 def _handle_bind_msg(self, msg):
     assert isinstance(msg, pureldap.LDAPBindResponse)
     assert msg.referral is None  # TODO
     if msg.resultCode != ldaperrors.Success.resultCode:
         raise ldaperrors.get(msg.resultCode, msg.errorMessage)
     return self
コード例 #28
0
 def test_get_nonexisting_exception(self):
     """Getting non-existing LDAP error"""
     exception = ldaperrors.get(55, "Error message")
     self.assertEqual(exception.__class__, ldaperrors.LDAPUnknownError)
     self.assertEqual(exception.code, 55)
     self.assertEqual(exception.message, "Error message")
コード例 #29
0
ファイル: test_ldaperrors.py プロジェクト: psi29a/ldaptor
 def test_get_nonexisting_exception(self):
     """Getting non-existing LDAP error"""
     exception = ldaperrors.get(55, 'Error message')
     self.assertEqual(exception.__class__, ldaperrors.LDAPUnknownError)
     self.assertEqual(exception.code, 55)
     self.assertEqual(exception.message, 'Error message')
コード例 #30
0
 def test_get_success(self):
     """Getting OK message"""
     success = ldaperrors.get(0, "Some message")
     self.assertEqual(success.__class__, ldaperrors.Success)
     self.assertEqual(success.resultCode, 0)
     self.assertEqual(success.name, b"success")
コード例 #31
0
ファイル: ldapsyntax.py プロジェクト: chevah/ldaptor
 def _handle_bind_msg(self, msg):
     assert isinstance(msg, pureldap.LDAPBindResponse)
     assert msg.referral is None #TODO
     if msg.resultCode!=ldaperrors.Success.resultCode:
         raise ldaperrors.get(msg.resultCode, msg.errorMessage)
     return self
コード例 #32
0
    def perform_bind_sspi(self,
                          dn: str,
                          username: str,
                          password: str,
                          domain: str,
                          permit_implicit: bool,
                          targetspn=None):
        """Perform bind using native windows SSPI mechanism. If no
        username, password, or domain is provided, then we'll attempt
        to use the authproxy's existing process credentials to perform
        the bind.

        If targetspn is provided (and valid), then theoretically we
        might use kerberos instead of NTLM

        Returns:
            No return value from this function. Finishing without raising an exception means the
            bind succeeded
        Raises:
            LDAPUnwillingToPerform: If SSPI auth is not supported
            SSPIError: If the SSPI negotiation fails
        """

        if sspi is None:
            msg = 'The SSPI bind type is only supported on Windows.'
            log.err(msg)
            raise ldaperrors.LDAPUnwillingToPerform(msg)

        auth_info: Optional[Tuple[str, str,
                                  str]] = (username, domain, password)
        # omitting 'domain' from this if statement; that way we can
        # specify ntlm_domain in config and have it apply to user
        # auth, but not automatically trip us into using configured,
        # rather than implicit, service account creds
        if not (username or password):
            if permit_implicit:
                auth_info = None
            else:
                # even passing a tuple of empty values still appears
                # to trigger the implicit-auth mechanism, so we need
                # to be explicit
                msg = 'Implicit authentication forbidden for this request.'
                log.err(msg)
                raise ldaperrors.LDAPUnwillingToPerform(msg)

        # SSPI negotiation can request some application-level
        # encryption/authentication, but AD apparently throws a fit if
        # you leave this on when using SSL/TLS (and expects you to
        # actually somehow sign all your LDAP requests otherwise)
        scflags = ISC_REQ_NO_INTEGRITY

        # these return codes mean we need to continue the handshake
        sspi_continue = set([
            sspicon.SEC_I_CONTINUE_NEEDED, sspicon.SEC_I_COMPLETE_AND_CONTINUE
        ])
        # any return code not in this set should be considered an error
        sspi_ok = sspi_continue.union(
            [sspicon.SEC_E_OK, sspicon.SEC_I_COMPLETE_NEEDED])

        ca = self._create_sspi_authenticator(auth_info, targetspn, scflags)
        data = None
        # This negotiation is made up of challenge and response messages.
        # We will continue responding to challenges until a success or
        # failure case is hit
        while True:
            # get the next step in the handshake
            err, out_buf = ca.authorize(data)
            if err not in sspi_ok:
                raise SSPIError('SSPI negotiation failed', err)

            response = yield self._send_sspi_bind(dn, out_buf)

            if response.resultCode == ldaperrors.LDAPSaslBindInProgress.resultCode:
                data = self._recalculate_buffer_data(ca, response)
            elif response.resultCode == ldaperrors.Success.resultCode:
                break
            else:
                raise ldaperrors.get(response.resultCode,
                                     response.errorMessage)

            # if SSPI said we're done, but ldap response doesn't
            # agree, that's weird
            if err not in sspi_continue:
                raise SSPIError('SSPI negotiation should\'ve finished by now',
                                err)