Exemple #1
0
 def cookie(self):
     if self.remain_count <= 0:
         return b''
     return pureber.BERSequence([
         pureber.BERInteger(self.remain_count),
         pureber.BERInteger(self.last_id),
     ]).toWire()
Exemple #2
0
class BERBaseEquality(unittest.TestCase):
    valuesToTest=(
        (pureber.BERInteger, [0]),
        (pureber.BERInteger, [1]),
        (pureber.BERInteger, [4000]),
        (pureber.BERSequence, [[pureber.BERInteger(1000), pureber.BERInteger(2000)]]),
        (pureber.BERSequence, [[pureber.BERInteger(2000), pureber.BERInteger(1000)]]),
        (pureber.BEROctetString, ["foo"]),
        (pureber.BEROctetString, ["b"+chr(0xe4)+chr(0xe4)]),
        )

    def testBERBaseEquality(self):
        """BER objects equal BER objects with same type and content"""
        for class_, args in self.valuesToTest:
            x=class_(*args)
            y=class_(*args)
            assert x==x
            assert x==y

    def testBERBaseInEquality(self):
        """BER objects do not equal BER objects with different type or content"""
        for i in xrange(len(self.valuesToTest)):
            for j in xrange(len(self.valuesToTest)):
                if i!=j:
                    i_class, i_args = self.valuesToTest[i]
                    j_class, j_args = self.valuesToTest[j]
                    x=i_class(*i_args)
                    y=j_class(*j_args)
                    assert x!=y
Exemple #3
0
class BERBaseTests(unittest.TestCase):
    """
    Unit tests for generic BERBase.
    """

    valuesToTest = (
        (pureber.BERBase, []),
        (pureber.BERInteger, [0]),
        (pureber.BERInteger, [1]),
        (pureber.BERInteger, [4000]),
        (pureber.BERSequence,
         [[pureber.BERInteger(1000),
           pureber.BERInteger(2000)]]),
        (pureber.BERSequence,
         [[pureber.BERInteger(2000),
           pureber.BERInteger(1000)]]),
        (pureber.BEROctetString, ["foo"]),
        (pureber.BEROctetString, ["b" + chr(0xE4) + chr(0xE4)]),
    )

    def testEquality(self):
        """
        BER objects equal BER objects with same type and content
        """
        for class_, args in self.valuesToTest:
            x = class_(*args)
            y = class_(*args)
            self.assertEqual(x, x)
            self.assertEqual(x, y)

    def testInequalityWithBER(self):
        """
        BER objects do not equal BER objects with different type or content
        """
        for i in range(len(self.valuesToTest)):
            for j in range(len(self.valuesToTest)):
                if i != j:
                    i_class, i_args = self.valuesToTest[i]
                    j_class, j_args = self.valuesToTest[j]
                    x = i_class(*i_args)
                    y = j_class(*j_args)
                    self.assertNotEqual(x, y)

    def testInequalityWithNonBER(self):
        """
        BER objects are not equal with non-BER objects.
        """
        sut = pureber.BERInteger([0])

        self.assertFalse(0 == sut)
        self.assertNotEqual(0, sut)

    def testHashEquality(self):
        """
        Objects which are equal have the same hash.
        """
        for klass, arguments in self.valuesToTest:
            first = klass(*arguments)
            second = klass(*arguments)
            self.assertEqual(hash(first), hash(second))
Exemple #4
0
    def testStringRepresentatinMultipleIntegers(self):
        """
        It can represent a sequence of multiple integer.
        """
        sut = pureber.BERSequence(
            [pureber.BERInteger(3),
             pureber.BERInteger(128)])

        result = sut.toWire()

        self.assertEqual(b"0\x07\x02\x01\x03\x02\x02\x00\x80", result)
Exemple #5
0
 def create_paged_search_controls(self, page_size=10, cookie=b''):
     control_value = pureber.BERSequence([
         pureber.BERInteger(page_size),
         pureber.BEROctetString(cookie),
     ])
     controls = [(b'1.2.840.113556.1.4.319', None, control_value.toWire())]
     return controls
Exemple #6
0
 def testToBERIntegerKnownValues(self):
     """str(BERInteger(n)) should give known result with known input"""
     for integer, encoded in self.knownValues:
         result = pureber.BERInteger(integer)
         result = str(result)
         result = list(map(ord, result))
         self.assertEqual(encoded, result)
Exemple #7
0
 def testToBERIntegerKnownValues(self):
     """BERInteger(n).toWire() should give known result with known input"""
     for integer, encoded in self.knownValues:
         result = pureber.BERInteger(integer)
         result = result.toWire()
         result = l(result)
         self.assertEqual(encoded, result)
Exemple #8
0
    def testDecdeInvalidInput(self):
        """
        It raises BERExceptionInsufficientData when trying to decode from
        data which is not valid.
        """
        m = pureber.BERSequence([pureber.BERInteger(2)]).toWire()
        self.assertEqual(5, len(m))

        self.assertRaises(
            pureber.BERExceptionInsufficientData,
            pureber.berDecodeObject,
            pureber.BERDecoderContext(),
            m[:4],
        )
        self.assertRaises(
            pureber.BERExceptionInsufficientData,
            pureber.berDecodeObject,
            pureber.BERDecoderContext(),
            m[:3],
        )
        self.assertRaises(
            pureber.BERExceptionInsufficientData,
            pureber.berDecodeObject,
            pureber.BERDecoderContext(),
            m[:2],
        )
        self.assertRaises(
            pureber.BERExceptionInsufficientData,
            pureber.berDecodeObject,
            pureber.BERDecoderContext(),
            m[:1],
        )
        self.assertEqual((None, 0),
                         pureber.berDecodeObject(pureber.BERDecoderContext(),
                                                 ""))
Exemple #9
0
 def testPartialBERIntegerEncodings(self):
     """BERInteger(encoded="...") with too short input should throw BERExceptionInsufficientData"""
     m=str(pureber.BERInteger(42))
     assert len(m)==3
     self.assertRaises(pureber.BERExceptionInsufficientData, pureber.berDecodeObject, pureber.BERDecoderContext(), m[:2])
     self.assertRaises(pureber.BERExceptionInsufficientData, pureber.berDecodeObject, pureber.BERDecoderContext(), m[:1])
     self.assertEquals((None, 0), pureber.berDecodeObject(pureber.BERDecoderContext(), ''))
Exemple #10
0
    def testInequalityWithNonBER(self):
        """
        BER objects are not equal with non-BER objects.
        """
        sut = pureber.BERInteger([0])

        self.assertFalse(0 == sut)
        self.assertNotEqual(0, sut)
Exemple #11
0
 def testSanity(self):
     """BERInteger(encoded=BERInteger(n)).value==n for -1000..1000"""
     for n in range(-1000, 1001, 10):
         encoded = str(pureber.BERInteger(n))
         result, bytes = pureber.berDecodeObject(pureber.BERDecoderContext(), encoded)
         self.assertEquals(bytes, len(encoded))
         assert isinstance(result, pureber.BERInteger)
         result = result.value
         assert n==result
Exemple #12
0
 def testSanity(self):
     """BERInteger(encoded=BERInteger(n)).value==n for -1000..1000"""
     for n in range(-1000, 1001, 10):
         encoded = pureber.BERInteger(n).toWire()
         result, bytes = pureber.berDecodeObject(
             pureber.BERDecoderContext(), encoded)
         self.assertEqual(bytes, len(encoded))
         self.assertIsInstance(result, pureber.BERInteger)
         result = result.value
         self.assertEqual(n, result)
Exemple #13
0
    def testStringRepresentatinSmallInteger(self):
        """
        It can represent a sequence of a single integer which has a
        single byte value.
        """
        sut = pureber.BERSequence([pureber.BERInteger(2)])

        result = sut.toWire()

        self.assertEqual(b"0\x03\x02\x01\x02", result)
 def create_paged_search_controls(self, page_size=10, cookie=b''):
     control_value = pureber.BERSequence([
         pureber.BERInteger(page_size),
         pureber.BEROctetString(cookie),
     ])
     # DUO EDIT D46281: Make criticality optional
     # controls = [(b'1.2.840.113556.1.4.319', None, control_value.toWire())]
     controls = [(b'1.2.840.113556.1.4.319', False, control_value.toWire())]
     # END EDIT
     return controls
Exemple #15
0
    def testStringRepresentatinLargerInteger(self):
        """
        It can represent a sequence of a single integer which has a
        multi bites value.
        """
        sut = pureber.BERSequence([pureber.BERInteger(128)])

        result = sut.toWire()

        self.assertEqual(b"0\x04\x02\x02\x00\x80", result)
Exemple #16
0
 def test_lessOrEqual_noMatch(self):
     o = inmemory.ReadOnlyInMemoryLDAPEntry(dn='cn=foo,dc=example,dc=com',
                                            attributes={
                                                'objectClass': ['a', 'b'],
                                                'aValue': ['b'],
                                                'num': [4],
                                            })
     result = o.match(
         pureldap.LDAPFilter_lessOrEqual(pureber.BEROctetString('num'),
                                         pureber.BERInteger(3)))
     self.assertEqual(result, False)
def request_page_(client, basedn, page_size=100, cookie='', **search_kwds):
    control_value = pureber.BERSequence([
        pureber.BERInteger(page_size),
        pureber.BEROctetString(cookie),
    ])
    controls = [('1.2.840.113556.1.4.319', None, control_value)]
    search_kwds['controls'] = controls
    search_kwds['return_controls'] = True
    o = LDAPEntry(client, basedn)
    results, resp_controls = yield o.search(**search_kwds)
    cookie = get_paged_search_cookie_(resp_controls)
    defer.returnValue((results, cookie))
Exemple #18
0
    def testDecodeValidInput(self):
        """
        It can be decoded from its bytes serialization.
        """
        knownValues = (
            ([], [0x30, 0x00]),
            ([pureber.BERInteger(2)], [0x30, 0x03, 0x02, 0x01, 2]),
            ([pureber.BERInteger(3)], [0x30, 0x03, 0x02, 0x01, 3]),
            ([pureber.BERInteger(128)], [0x30, 0x04, 0x02, 0x02, 0, 128]),
            (
                [
                    pureber.BERInteger(2),
                    pureber.BERInteger(3),
                    pureber.BERInteger(128),
                ],
                [0x30, 0x0A] + [0x02, 0x01, 2] + [0x02, 0x01, 3] +
                [0x02, 0x02, 0, 128],
            ),
        )

        for content, encoded in knownValues:
            m = s(*encoded)
            result, bytes = pureber.berDecodeObject(
                pureber.BERDecoderContext(), m)
            self.assertEqual(bytes, len(m))
            self.assertIsInstance(result, pureber.BERSequence)
            result = result.data
            self.assertEqual(len(content), len(result))
            for i in range(len(content)):
                self.assertEqual(content[i], result[i])
            self.assertEqual(content, result)
Exemple #19
0
 def test_lessOrEqual_noMatch(self):
     o = inmemory.ReadOnlyInMemoryLDAPEntry(
         dn="cn=foo,dc=example,dc=com",
         attributes={
             "objectClass": ["a", "b"],
             "aValue": ["b"],
             "num": [4],
         },
     )
     result = o.match(
         pureldap.LDAPFilter_lessOrEqual(pureber.BEROctetString("num"),
                                         pureber.BERInteger(3)))
     self.assertEqual(result, False)
Exemple #20
0
def process_entry(client, args, search_filter, page_size=100, cookie=''):
    basedn = args.base_dn
    control_value = pureber.BERSequence([
        pureber.BERInteger(page_size),
        pureber.BEROctetString(cookie),
    ])
    controls = [('1.2.840.113556.1.4.319', None, control_value)]
    o = LDAPEntry(client, basedn)
    results, resp_controls = yield o.search(filterText=search_filter,
                                            attributes=['dn'],
                                            controls=controls,
                                            return_controls=True)
    cookie = get_paged_search_cookie(resp_controls)
    defer.returnValue((results, cookie))
Exemple #21
0
 def test_message_repr(self):
     page_size = 10
     cookie = "xyzzy"
     control_value = pureber.BERSequence([
         pureber.BERInteger(page_size),
         pureber.BEROctetString(cookie),
     ])
     controls = [('1.2.840.113556.1.4.319', None, control_value)]
     search_request = pureldap.LDAPSearchRequest(
         "cn=foo,ou=baz,dc=example,dc=org")
     ldap_msg = pureldap.LDAPMessage(id=1,
                                     value=search_request,
                                     controls=controls,
                                     tag=1)
     expected_value = "LDAPMessage(id=1, value=LDAPSearchRequest(baseObject='cn=foo,ou=baz,dc=example,dc=org', scope=2, derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=LDAPFilter_present(value='objectClass'), attributes=[]), controls=[('1.2.840.113556.1.4.319', None, BERSequence(value=[BERInteger(value=10), BEROctetString(value='xyzzy')]))], tag=1)"
     self.assertEqual(expected_value, repr(ldap_msg))
Exemple #22
0
 def testPartialBERIntegerEncodings(self):
     """BERInteger(encoded="...") with too short input should throw BERExceptionInsufficientData"""
     m = pureber.BERInteger(42).toWire()
     self.assertEqual(3, len(m))
     self.assertRaises(
         pureber.BERExceptionInsufficientData,
         pureber.berDecodeObject,
         pureber.BERDecoderContext(),
         m[:2],
     )
     self.assertRaises(
         pureber.BERExceptionInsufficientData,
         pureber.berDecodeObject,
         pureber.BERDecoderContext(),
         m[:1],
     )
     self.assertEqual((None, 0),
                      pureber.berDecodeObject(pureber.BERDecoderContext(),
                                              ""))
Exemple #23
0
class BERSequenceKnownValues(unittest.TestCase):
    knownValues=(
        ([], [0x30, 0x00]),
        ([pureber.BERInteger(2)], [0x30, 0x03, 0x02, 0x01, 2]),
        ([pureber.BERInteger(3)], [0x30, 0x03, 0x02, 0x01, 3]),
        ([pureber.BERInteger(128)], [0x30, 0x04, 0x02, 0x02, 0, 128]),
        ([pureber.BERInteger(2), pureber.BERInteger(3), pureber.BERInteger(128)],
         [0x30, 0x0a]+[0x02, 0x01, 2]+[0x02, 0x01, 3]+[0x02, 0x02, 0, 128]),
        )

    def testToBERSequenceKnownValues(self):
        """str(BERSequence(x)) should give known result with known input"""
        for content, encoded in self.knownValues:
            result = pureber.BERSequence(content)
            result = str(result)
            result = map(ord, result)
            assert encoded==result

    def testFromBERSequenceKnownValues(self):
        """BERSequence(encoded="...") should give known result with known input"""
        for content, encoded in self.knownValues:
            m=s(*encoded)
            result, bytes = pureber.berDecodeObject(pureber.BERDecoderContext(), m)
            self.assertEquals(bytes, len(m))
            assert isinstance(result, pureber.BERSequence)
            result = result.data
            assert len(content)==len(result)
            for i in xrange(len(content)):
                assert content[i]==result[i]
            assert content==result

    def testPartialBERSequenceEncodings(self):
        """BERSequence(encoded="...") with too short input should throw BERExceptionInsufficientData"""
        m=str(pureber.BERSequence([pureber.BERInteger(2)]))
        assert len(m)==5

        self.assertRaises(pureber.BERExceptionInsufficientData, pureber.berDecodeObject, pureber.BERDecoderContext(), m[:4])
        self.assertRaises(pureber.BERExceptionInsufficientData, pureber.berDecodeObject, pureber.BERDecoderContext(), m[:3])
        self.assertRaises(pureber.BERExceptionInsufficientData, pureber.berDecodeObject, pureber.BERDecoderContext(), m[:2])
        self.assertRaises(pureber.BERExceptionInsufficientData, pureber.berDecodeObject, pureber.BERDecoderContext(), m[:1])
        self.assertEquals((None, 0), pureber.berDecodeObject(pureber.BERDecoderContext(), ''))
Exemple #24
0
 def encode_control_value(self):
     return pureber.BERSequence([
         pureber.BERInteger(self.size),
         pureber.BEROctetString(self.cookie),
     ]).toWire()
Exemple #25
0
    def _paged_search(
        self,
        client,
        base_dn,
        filter_text,
        attributes,
        pagination=PAGINATION_TYPE_CRITICAL,
        max_result_size=None,
        page_size=DEFAULT_PAGE_SIZE,
    ):
        """
        Given a bound client, search exhaustively using RFC 2696.
        Return a list of dictionaries containing the attributes
        of the resulting entries.

        * attributes: Set of lower-case byte-strings.
        """
        res = []

        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,
                ))

        if filter_text:
            filter_obj = ldapfilter.parseFilter(filter_text)
        else:
            filter_obj = None
        op = pureldap.LDAPSearchRequest(
            baseObject=base_dn,
            scope=pureldap.LDAP_SCOPE_wholeSubtree,
            derefAliases=0,
            sizeLimit=0,
            timeLimit=0,
            typesOnly=0,
            filter=filter_obj,
            attributes=attributes,
        )

        if pagination == PAGINATION_TYPE_CRITICAL:
            # AD may ignore the RFC 2696 control if it is not
            # critical. The caller can override this default if the
            # control should be present but not critical or absent.
            criticality = True
        else:
            criticality = False

        cookie = pureber.BEROctetString("")
        while True:
            if pagination == PAGINATION_TYPE_DISABLE:
                controls = None
            else:
                controls = [
                    (
                        RFC_2696_CONTROL_TYPE,
                        criticality,
                        pureber.BERSequence([
                            pureber.BERInteger(page_size),
                            cookie,
                        ]),
                    ),
                ]

            d = defer.Deferred()
            yield client.send(
                op=op,
                controls=controls,
                handler=functools.partial(handle_msg, d=d),
                return_controls=True,
            )

            # handle_msg() is synchronous so d should be called by the
            # time it returns to LDAPClient.handle().
            if d.called:
                e, cookie = yield d
            else:
                log.error("Paging cookie not found!")
                break
            if e is not None:
                # So the RPC caller can distinguish between problems
                # with the search (e.g. bad configuration) and
                # searches that return no results.
                if isinstance(e, ldaperrors.LDAPOperationsError
                              ) and e.message.decode().startswith(
                                  const.LDAP_SUCCESSFUL_BIND_NEEDED_ERROR):
                    raise ldap.client.ConnectionNotProperlyBoundError(
                        "Search failed because either there was no bind on this connection or there were insufficient privileges with the bound user. If you are attempting to use integrated authentication with SSPI please make sure the server running the Authentication Proxy is domain joined."
                    )
                else:
                    raise e
            if not cookie.value:
                break
            if max_result_size is not None and len(res) > max_result_size:
                break
        defer.returnValue(res)