【问题标题】:Print human readable values for LDAP protocol fields in asn1c在 asn1c 中打印 LDAP 协议字段的人类可读值
【发布时间】:2018-12-15 14:00:33
【问题描述】:

我使用 asn1c 来解析 LDAP 消息

为此,在编译了rfc4511中定义的ASN.1定义后,我使用ber_decodexer_fprint函数进行解码和打印我的程序中的内容。

例如,下面指出的两个输出与两个不同的 LDAP 消息相关:

<LDAPMessage>
    <messageID>1</messageID>
    <protocolOp>
        <bindRequest>
            <version>3</version>
            <name>75 69 64 3D 61 2C 64 63 3D 63 6F 6D</name>
            <authentication>
                <simple>70 61 73 73 77 6F 72 64</simple>
            </authentication>
        </bindRequest>
    </protocolOp>
</LDAPMessage>

<LDAPMessage>
    <messageID>5</messageID>
    <protocolOp>
        <searchRequest>
            <baseObject></baseObject>
            <scope><baseObject/></scope>
            <derefAliases><neverDerefAliases/></derefAliases>
            <sizeLimit>0</sizeLimit>
            <timeLimit>0</timeLimit>
            <typesOnly><true/></typesOnly>
            <filter>
                <present>4F 62 6A 65 63 74 43 6C 61 73 73</present>
            </filter>
            <attributes>
                <selector>31 2E 31</selector>
            </attributes>
        </searchRequest>
    </protocolOp>
</LDAPMessage>

如您所见,namesimplepresentselector字段的值显示为十六进制。虽然我希望它们显示为人类可读值(类似于wireshark所做的)。

second message on the wireshark (present field have ObjectClass Value)

我知道在此链接 (decoding asn.1 compiler output as strings) 中提出了同样的问题。 Lev Walkin 说 OCTET STRING 应该替换为 IA5StringUTF8String。但在 LDAP ASN.1 定义中,OCTET STRING 已经在很多地方使用。

我应该改变哪一个?我对用 IA5String 或 UTF8String 替换 OCTET STRING 的看法是否正确?这应该在 LDAP ASN.1 定义中还是在其他地方完成?更改 LDAP 标准定义有什么问题吗?比如我只把LDAPDN :: = LDAPString改成了LDAPDN :: = UTF8String,但是在ber_decode函数中遇到了错误。

以人类可读的方式显示所有值的一般解决方案是什么?

谢谢...

【问题讨论】:

    标签: ldap asn.1


    【解决方案1】:

    有一个相当老套的解决方案,您可以更改需要打印为人类可读值的类型的 xer_encoder 函数。

    在 LDAPString 定义旁边的 asn.1 文件中,添加一个引用 UTF8String 类型的新类型

        LDAPString ::= OCTET STRING -- UTF-8 encoded,
                                     -- [ISO10646] characters
    
        LDAPStringUTF8 ::= UTF8String
                          -- [RFC4514]
    

    如果没有这个,asn1c 将无法复制我们需要的 UTF8String.[hc] 文件。

    在您的 main 函数中,或者在使用 ATS_BASIC_XER/ATS_CANONICAL_XER 调用 asn_encode 之前添加以下内容

    asn_DEF_LDAPDN.op->xer_encoder = OCTET_STRING_encode_xer_utf8;
    

    并包含LDAPDN.h 标头。

    如果您使用的是 asn1c 示例中的 converter-example.crfc4511-Lightweight-Directory-Access-Protocol-V3.asn1,这是完整的补丁

    diff --git a/converter-example.c b/converter-example.c
    index b540452..bb883b4 100644
    --- a/converter-example.c
    +++ b/converter-example.c
    @@ -189,6 +189,8 @@ ats_by_name(const char *name, const asn_TYPE_descriptor_t *td,
         return NULL;
     }
    
    +#include "LDAPDN.h"
    +
     int
     main(int ac, char *av[]) {
         FILE *binary_out;
    @@ -216,6 +218,8 @@ main(int ac, char *av[]) {
     #endif
         }
    
    +    asn_DEF_LDAPDN.op->xer_encoder = OCTET_STRING_encode_xer_utf8;
    +
         /* Figure out if a specialty decoder needs to be default */
     #ifndef ASN_DISABLE_OER_SUPPORT
         isyntax = ATS_BASIC_OER;
    diff --git a/pdu_collection.c b/pdu_collection.c
    index 4fde16b..55e2c2f 100644
    --- a/pdu_collection.c
    +++ b/pdu_collection.c
    @@ -7,6 +7,7 @@ struct asn_TYPE_descriptor_s;   /* Forward declaration */
     extern struct asn_TYPE_descriptor_s asn_DEF_LDAPMessage;
     extern struct asn_TYPE_descriptor_s asn_DEF_MessageID;
     extern struct asn_TYPE_descriptor_s asn_DEF_LDAPString;
    +extern struct asn_TYPE_descriptor_s asn_DEF_LDAPStringUTF8;
     extern struct asn_TYPE_descriptor_s asn_DEF_LDAPOID;
     extern struct asn_TYPE_descriptor_s asn_DEF_LDAPDN;
     extern struct asn_TYPE_descriptor_s asn_DEF_RelativeLDAPDN;
    @@ -58,6 +59,7 @@ struct asn_TYPE_descriptor_s *asn_pdu_collection[] = {
        &asn_DEF_LDAPMessage,   
        &asn_DEF_MessageID, 
        &asn_DEF_LDAPString,    
    +   &asn_DEF_LDAPStringUTF8,    
        &asn_DEF_LDAPOID,   
        &asn_DEF_LDAPDN,    
        &asn_DEF_RelativeLDAPDN,    
    diff --git a/rfc4511-Lightweight-Directory-Access-Protocol-V3.asn1 b/rfc4511-Lightweight-Directory-Access-Protocol-V3.asn1
    index 53de3cf..b29ec11 100644
    --- a/rfc4511-Lightweight-Directory-Access-Protocol-V3.asn1
    +++ b/rfc4511-Lightweight-Directory-Access-Protocol-V3.asn1
    @@ -47,6 +47,7 @@
             LDAPString ::= OCTET STRING -- UTF-8 encoded,
                                         -- [ISO10646] characters
    
    +        LDAPStringUTF8 ::= UTF8String
    

    这是输出

    ./converter-example -iber ldap1.der
    <LDAPMessage>
        <messageID>1</messageID>
        <protocolOp>
            <bindRequest>
                <version>3</version>
                <name>uid=a,dc=com</name>
                <authentication>
                    <simple>password</simple>
                </authentication>
            </bindRequest>
        </protocolOp>
    </LDAPMessage>
    

    【讨论】:

    • 感谢您的精彩回答。只是为了完成答案以及对于将来想要使用此解决方案的人:要使用asn_fprint功能打印输出,需要添加以下代码asn_DEF_LDAPDN.op-&gt; print_struct = OCTET_STRING_print_utf8;
    【解决方案2】:

    您无法更改 LDAP asn1 规范来解决您的问题。

    例如:当您解码BindRequest 时,要解码nameLDAPDN 类型)ber_decode 需要OCTET STRING 的标签。如果您按照您的建议更改规范,您将期待UTF8String 的标签并收到OCTET STRING 的标签(因此出现错误)

    不幸的是,使用通用工具,当规范使用OCTET STRING时,无法显示人类可读的文本

    【讨论】:

    • 感谢您的回答。我试图改变OCTET_STRING_encode_xerOCTET_STRING_print 函数来打印出我想要的输出。但是 vasko 提供的解决方案非常简单好用,解决了我的问题。
    猜你喜欢
    • 1970-01-01
    • 2013-02-22
    • 2015-05-30
    • 1970-01-01
    • 2018-06-01
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    相关资源
    最近更新 更多