10000 parsing LDAP search message openldap (without ASN.1 spec) · Issue #17 · pyasn1/pyasn1 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
8000

parsing LDAP search message openldap (without ASN.1 spec) #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
8000
michael-dev opened this issue Dec 14, 2022 · 0 comments
Open

parsing LDAP search message openldap (without ASN.1 spec) #17

michael-dev opened this issue Dec 14, 2022 · 0 comments

Comments

@michael-dev
Copy link
michael-dev commented Dec 14, 2022

I've tried to parse an LDAP SearchQuery Message from ldapsearch from openldap.
It fails with specific search queries when given an ASN.1 spec for LDAP messages, but also fails when trying to decode the ldap message without any ASN.1 specification. As this is used in an ldap proxy that should just pass-through LDAP search messages, I am mostly interested in pyasn1 not failing at special messages and getting the complete messages moved around.

The message it fails at is given in hex here: 30560201026351041064633d6578616d6c652c64633d6f72670a01020a0100020100020100010100a02c870b6f626a656374436c617373a31d040e73616d4163636f756e744e616d65040b6578616d706c65557365723000

The message can be parsed by asn1js here: https://lapo.it/asn1js/#....

Testcode:

from binascii import unhexlify
from pyasn1.codec.ber.decoder import decode as ber_decoder
from pyasn1 import debug

debug.setLogger(debug.Debug('all'))

data = unhexlify('30560201026351041064633d6578616d6c652c64633d6f72670a01020a0100020100020100010100a02c870b6f626a656374436c617373a31d040e73616d4163636f756e744e616d65040b6578616d706c65557365723000')

obj, rest_of_input = ber_decoder(data)

print(data)
print(obj)
print(rest_of_input)

Output:

2022-12-14 10:44:54,783 pyasn1: running pyasn1 0.5.0.rc2, debug flags all
2022-12-14 10:44:54,783 pyasn1: debug category 'all' enabled
2022-12-14 10:44:54,783 pyasn1: decoder called at scope  with state 0, working with up to None octets of substrate: <_io.BytesIO object at 0x7f0fc41bdee0>
2022-12-14 10:44:54,783 pyasn1: tag decoded into <TagSet object, tags 0:32:16>, decoding length
2022-12-14 10:44:54,783 pyasn1: value length decoded into 86
2022-12-14 10:44:54,783 pyasn1: codec SequenceOrSequenceOfPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:44:54,783 pyasn1: decoder called at scope NoneType with state 0, working with up to None octets of substrate: <_io.BytesIO object at 0x7f0fc41bdee0>
2022-12-14 10:44:54,783 pyasn1: tag decoded into <TagSet object, tags 0:0:2>, decoding length
2022-12-14 10:44:54,783 pyasn1: value length decoded into 1
2022-12-14 10:44:54,783 pyasn1: codec IntegerPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:44:54,783 pyasn1: codec IntegerPayloadDecoder yields type Integer, value:
2
...
2022-12-14 10:44:54,783 pyasn1: decoder left scope NoneType, call completed
2022-12-14 10:44:54,783 pyasn1: decoder called at scope NoneType with state 0, working with up to None octets of substrate: <_io.BytesIO object at 0x7f0fc41bdee0>
2022-12-14 10:44:54,783 pyasn1: tag decoded into <TagSet object, tags 64:32:3>, decoding length
2022-12-14 10:44:54,783 pyasn1: value length decoded into 81
2022-12-14 10:44:54,783 pyasn1: codec <none> chosen by a built-in type, decoding as explicit tag
2022-12-14 10:44:54,783 pyasn1: codec RawPayloadDecoder chosen, decoding value
2022-12-14 10:44:54,783 pyasn1: decoder called at scope NoneType.? with state 0, working with up to 81 octets of substrate: <_io.BytesIO object at 0x7f0fc41bdee0>
2022-12-14 10:44:54,783 pyasn1: tag decoded into <TagSet object, tags 0:0:4-64:32:3>, decoding length
2022-12-14 10:44:54,784 pyasn1: value length decoded into 16
2022-12-14 10:44:54,784 pyasn1: codec OctetStringPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:44:54,784 pyasn1: codec OctetStringPayloadDecoder yields type OctetString, value:
dc=examle,dc=org
...
2022-12-14 10:44:54,784 pyasn1: decoder left scope NoneType.?, call completed
Traceback (most recent call last):
  File "test-pyasn1/test.py", line 10, in <module>
    obj, rest_of_input = ber_decoder(data)
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 2003, in __call__
    for asn1Object in streamingDecoder:
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 1918, in __iter__
    for asn1Object in self._singleItemDecoder(
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 1778, in __call__
    for value in concreteDecoder.valueDecoder(
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 660, in valueDecoder
    for asn1Object in self._decodeComponentsSchemaless(
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 596, in _decodeComponentsSchemaless
    for component in decodeFun(substrate, **options):
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 1787, in __call__
    raise PyAsn1Error(
pyasn1.error.PyAsn1Error: Read 18 bytes instead of expected 81.

After making RawValueDecoder iterate also non definite length values with the following patch:

diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index f378b6f..9bab2fc 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -96,8 +96,20 @@ class RawPayloadDecoder(AbstractSimplePayloadDecoder):
 
             return
 
-        for value in decodeFun(substrate, asn1Spec, tagSet, length, **options):
-            yield value
+        LOG("decodeFun {}".format(decodeFun))
+
+        #for value in decodeFun(substrate, asn1Spec, tagSet, length, **options):
+        #    yield value
+        while True:
+            LOG('length = {}'.format(length))
+            for value in decodeFun(
+                    substrate, asn1Spec, tagSet, length,
+                    allowEoo=False, **options):
+
+                yield value
+
+                if length <= 0:
+                    return
 
     def indefLenValueDecoder(self, substrate, asn1Spec,
                              tagSet=None, length=None, state=None,
@@ -1784,6 +1796,7 @@ class SingleItemDecoder(object):
 
                     bytesRead = substrate.tell() - original_position
                     if bytesRead != length:
+                        LOG("substrateFun {} stGetValueDecoder {} self {} cD {}".format(substrateFun, stGetValueDecoder, self, concreteDecoder))
                         raise PyAsn1Error(
                             "Read %s bytes instead of expected %s." % (bytesRead, length))
 

I get

2022-12-14 10:58:08,780 pyasn1: running pyasn1 0.5.0.rc2, debug flags all
2022-12-14 10:58:08,780 pyasn1: debug category 'all' enabled
2022-12-14 10:58:08,780 pyasn1: decoder called at scope  with state 0, working with up to None octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,780 pyasn1: tag decoded into <TagSet object, tags 0:32:16>, decoding length
2022-12-14 10:58:08,781 pyasn1: value length decoded into 86
2022-12-14 10:58:08,781 pyasn1: codec SequenceOrSequenceOfPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:58:08,781 pyasn1: decoder called at scope NoneType with state 0, working with up to None octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,781 pyasn1: tag decoded into <TagSet object, tags 0:0:2>, decoding length
2022-12-14 10:58:08,781 pyasn1: value length decoded into 1
2022-12-14 10:58:08,781 pyasn1: codec IntegerPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:58:08,781 pyasn1: codec IntegerPayloadDecoder yields type Integer, value:
2
...
2022-12-14 10:58:08,781 pyasn1: decoder left scope NoneType, call completed
2022-12-14 10:58:08,781 pyasn1: decoder called at scope NoneType with state 0, working with up to None octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,781 pyasn1: tag decoded into <TagSet object, tags 64:32:3>, decoding length
2022-12-14 10:58:08,781 pyasn1: value length decoded into 81
2022-12-14 10:58:08,781 pyasn1: codec <none> chosen by a built-in type, decoding as explicit tag
2022-12-14 10:58:08,781 pyasn1: codec RawPayloadDecoder chosen, decoding value
2022-12-14 10:58:08,781 pyasn1: decodeFun <pyasn1.codec.ber.decoder.SingleItemDecoder object at 0x7f034f62bd90>
2022-12-14 10:58:08,781 pyasn1: length = 81
2022-12-14 10:58:08,781 pyasn1: decoder called at scope NoneType.? with state 0, working with up to 81 octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,781 pyasn1: tag decoded into <TagSet object, tags 0:0:4-64:32:3>, decoding length
2022-12-14 10:58:08,781 pyasn1: value length decoded into 16
2022-12-14 10:58:08,781 pyasn1: codec OctetStringPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:58:08,781 pyasn1: codec OctetStringPayloadDecoder yields type OctetString, value:
dc=examle,dc=org
...
2022-12-14 10:58:08,782 pyasn1: decoder left scope NoneType.?, call completed
2022-12-14 10:58:08,782 pyasn1: length = 81
2022-12-14 10:58:08,782 pyasn1: decoder called at scope NoneType.? with state 0, working with up to 81 octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,782 pyasn1: tag decoded into <TagSet object, tags 0:0:10-64:32:3>, decoding len
7D20
gth
2022-12-14 10:58:08,782 pyasn1: value length decoded into 1
2022-12-14 10:58:08,782 pyasn1: codec IntegerPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:58:08,782 pyasn1: codec IntegerPayloadDecoder yields type Integer, value:
2
...
2022-12-14 10:58:08,782 pyasn1: decoder left scope NoneType.?, call completed
2022-12-14 10:58:08,782 pyasn1: length = 81
2022-12-14 10:58:08,782 pyasn1: decoder called at scope NoneType.? with state 0, working with up to 81 octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,782 pyasn1: tag decoded into <TagSet object, tags 0:0:10-64:32:3>, decoding length
2022-12-14 10:58:08,782 pyasn1: value length decoded into 1
2022-12-14 10:58:08,782 pyasn1: codec IntegerPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:58:08,782 pyasn1: codec IntegerPayloadDecoder yields type Integer, value:
0
...
2022-12-14 10:58:08,782 pyasn1: decoder left scope NoneType.?, call completed
2022-12-14 10:58:08,782 pyasn1: length = 81
2022-12-14 10:58:08,782 pyasn1: decoder called at scope NoneType.? with state 0, working with up to 81 octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,782 pyasn1: tag decoded into <TagSet object, tags 0:0:2-64:32:3>, decoding length
2022-12-14 10:58:08,782 pyasn1: value length decoded into 1
2022-12-14 10:58:08,782 pyasn1: codec IntegerPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:58:08,782 pyasn1: codec IntegerPayloadDecoder yields type Integer, value:
0
...
2022-12-14 10:58:08,783 pyasn1: decoder left scope NoneType.?, call completed
2022-12-14 10:58:08,783 pyasn1: length = 81
2022-12-14 10:58:08,783 pyasn1: decoder called at scope NoneType.? with state 0, working with up to 81 octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,783 pyasn1: tag decoded into <TagSet object, tags 0:0:2-64:32:3>, decoding length
2022-12-14 10:58:08,783 pyasn1: value length decoded into 1
2022-12-14 10:58:08,783 pyasn1: codec IntegerPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:58:08,783 pyasn1: codec IntegerPayloadDecoder yields type Integer, value:
0
...
2022-12-14 10:58:08,783 pyasn1: decoder left scope NoneType.?, call completed
2022-12-14 10:58:08,783 pyasn1: length = 81
2022-12-14 10:58:08,783 pyasn1: decoder called at scope NoneType.? with state 0, working with up to 81 octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,783 pyasn1: tag decoded into <TagSet object, tags 0:0:1-64:32:3>, decoding length
2022-12-14 10:58:08,783 pyasn1: value length decoded into 1
2022-12-14 10:58:08,783 pyasn1: codec BooleanPayloadDecoder chosen by a built-in type, decoding value
2022-12-14 10:58:08,783 pyasn1: codec BooleanPayloadDecoder yields type Boolean, value:
False
...
2022-12-14 10:58:08,783 pyasn1: decoder left scope NoneType.?, call completed
2022-12-14 10:58:08,783 pyasn1: length = 81
2022-12-14 10:58:08,783 pyasn1: decoder called at scope NoneType.? with state 0, working with up to 81 octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,783 pyasn1: tag decoded into <TagSet object, tags 128:32:0-64:32:3>, decoding length
2022-12-14 10:58:08,783 pyasn1: value length decoded into 44
2022-12-14 10:58:08,783 pyasn1: codec <none> chosen by a built-in type, decoding as explicit tag
2022-12-14 10:58:08,783 pyasn1: codec RawPayloadDecoder chosen, decoding value
2022-12-14 10:58:08,784 pyasn1: decodeFun <pyasn1.codec.ber.decoder.SingleItemDecoder object at 0x7f034f62bd90>
2022-12-14 10:58:08,784 pyasn1: length = 44
2022-12-14 10:58:08,784 pyasn1: decoder called at scope NoneType.?.? with state 0, working with up to 44 octets of substrate: <_io.BytesIO object at 0x7f034f649ee0>
2022-12-14 10:58:08,784 pyasn1: tag decoded into <TagSet object, tags 128:0:7-128:32:0-64:32:3>, decoding length
2022-12-14 10:58:08,784 pyasn1: value length decoded into 11
2022-12-14 10:58:08,784 pyasn1: codec <none> chosen by a built-in type, decoding as explicit tag
2022-12-14 10:58:08,784 pyasn1: codec <none> chosen, decoding as failure
Traceback (most recent call last):
  File "test-pyasn1/test.py", line 10, in <module>
    obj, rest_of_input = ber_decoder(data)
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 2016, in __call__
    for asn1Object in streamingDecoder:
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 1931, in __iter__
    for asn1Object in self._singleItemDecoder(
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 1790, in __call__
    for value in concreteDecoder.valueDecoder(
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 672, in valueDecoder
    for asn1Object in self._decodeComponentsSchemaless(
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 608, in _decodeComponentsSchemaless
    for component in decodeFun(substrate, **options):
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 1790, in __call__
    for value in concreteDecoder.valueDecoder(
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 105, in valueDecoder
    for value in decodeFun(
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 1790, in __call__
    for value in concreteDecoder.valueDecoder(
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 105, in valueDecoder
    for value in decodeFun(
  File "test-pyasn1/pyasn1/codec/ber/decoder.py", line 1835, in __call__
    raise error.PyAsn1Error(
pyasn1.error.PyAsn1Error: <TagSet object, tags 128:0:7-128:32:0-64:32:3> not in asn1Spec: None

Which is better but now fails at decoding the LDAP search query.

@michael-dev michael-dev changed the title parsing LDAP search message openldap parsing LDAP search message openldap (without ASN.1 spec) Dec 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant
0