在 asn1c 中打印 LDAP 协议字段的人类可读值
Print human readable values for LDAP protocol fields in asn1c
我使用 asn1c 来解析 LDAP 消息。
为此,在编译 rfc4511 中定义的 ASN.1 定义后,我使用 ber_decode 和 xer_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>
可以看到,取值为name、simple、present和选择器字段显示为十六进制。虽然我希望它们显示为 人类可读 值(类似于 wireshark 所做的)。
second message on the wireshark (present field have ObjectClass Value)
我知道这个 link (decoding asn.1 compiler output as strings) 中也有人问过同样的问题。 Lev Walkin 说 OCTET STRING 应该替换为 IA5String 或 UTF8String。但是在LDAP ASN.1 Definition中,很多地方都用到了OCTET STRING。
我应该换哪一个?我对用 IA5String 或 UTF8String 替换 OCTET STRING 的看法是否正确?这应该在 LDAP ASN.1 定义中还是在其他地方完成?更改LDAP标准定义有什么问题吗?例如,我只将 LDAPDN :: = LDAPString
更改为 LDAPDN :: = UTF8String
,但我在 ber_decode 函数中遇到了错误。
以人类可读的方式显示所有值的一般解决方案是什么?
谢谢...
您无法更改 LDAP asn1 规范来解决您的问题。
例如:当您解码 BindRequest
时,要解码 name
(LDAPDN
类型)ber_decode 期望OCTET STRING
的标签。如果您按照您的建议更改规范,您将期望 UTF8String
的标签并收到 OCTET STRING
的标签(因此错误)
不幸的是,使用通用工具,无法在规范使用 OCTET STRING
时显示人类可读的文本
有一个相当骇人听闻的解决方案,您可以更改 xer_encoder
需要打印为人类可读值的类型的函数。
在 asn.1 文件中,在 LDAPString 定义旁边添加一个引用 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
header.
如果您使用来自 asn1c 示例
的 converter-example.c
和 rfc4511-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>
我使用 asn1c 来解析 LDAP 消息。
为此,在编译 rfc4511 中定义的 ASN.1 定义后,我使用 ber_decode 和 xer_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>
可以看到,取值为name、simple、present和选择器字段显示为十六进制。虽然我希望它们显示为 人类可读 值(类似于 wireshark 所做的)。
second message on the wireshark (present field have ObjectClass Value)
我知道这个 link (decoding asn.1 compiler output as strings) 中也有人问过同样的问题。 Lev Walkin 说 OCTET STRING 应该替换为 IA5String 或 UTF8String。但是在LDAP ASN.1 Definition中,很多地方都用到了OCTET STRING。
我应该换哪一个?我对用 IA5String 或 UTF8String 替换 OCTET STRING 的看法是否正确?这应该在 LDAP ASN.1 定义中还是在其他地方完成?更改LDAP标准定义有什么问题吗?例如,我只将 LDAPDN :: = LDAPString
更改为 LDAPDN :: = UTF8String
,但我在 ber_decode 函数中遇到了错误。
以人类可读的方式显示所有值的一般解决方案是什么?
谢谢...
您无法更改 LDAP asn1 规范来解决您的问题。
例如:当您解码 BindRequest
时,要解码 name
(LDAPDN
类型)ber_decode 期望OCTET STRING
的标签。如果您按照您的建议更改规范,您将期望 UTF8String
的标签并收到 OCTET STRING
的标签(因此错误)
不幸的是,使用通用工具,无法在规范使用 OCTET STRING
有一个相当骇人听闻的解决方案,您可以更改 xer_encoder
需要打印为人类可读值的类型的函数。
在 asn.1 文件中,在 LDAPString 定义旁边添加一个引用 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
header.
如果您使用来自 asn1c 示例
的converter-example.c
和 rfc4511-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>