我正在尝试将查询LDAP服务器的程序从Perl移植到Go,而使用Go版本我收到过滤器格式错误的响应:
00000057:LdapErr:DSID-0C0C0968,评论:服务器无法解码搜索请求过滤器,数据0,v1db1 \ x00
我已经使用tcpdump来捕获使用我的程序的Perl和Go版本传输到服务器的数据,并且发现它们发送稍微不同的过滤器数据包。这个问题不是关于Go程序中任何可能的错误,而只是关于理解LDAP过滤器数据包的内容。
编码过滤器是:
(objectClass=*)
Perl生成的数据包(服务器喜欢的)看起来像这样:
ASCII . . o b j e c t C l a s s
Hex 87 0b 6f 62 6a 65 63 74 43 6c 61 73 73
Byte# 0 1 2 3 4 5 6 7 8 9 10 11 12
Go生成的数据包(服务器不喜欢)如下所示:
ASCII . . . . o b j e c t C l a s s
Hex a7 0d 04 0b 6f 62 6a 65 63 74 43 6c 61 73 73
Byte# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
这是我自己的数据包细分:
当我从两个数据包中剖析字节0时,我看到它们是相同的,除了Primitive / Constructed位,它在Perl版本中设置为Primitive,在Go版本中构造。有关详细信息,请参阅DER encoding。
Bit# 87 6 54321
Perl 10 0 00111
Go 10 1 00111
Perl版本为11个字节,Go版本为13个
对于这两个数据包,这只是ASCII文本objectClass
我对RFC 4511 section 4.5.1的解读表明Go版本是"更多"正确,但Perl版本是与服务器一起使用的版本。是什么给了什么?
Wireshark能够解析这两个数据包,并同等地解释它们。
答案 0 :(得分:2)
Perl版本是正确的,Go版本不正确。
正如您所指出的,RFC 4511第4.5.1节规定了过滤器元素的编码,例如:
Filter ::= CHOICE {
and [0] SET SIZE (1..MAX) OF filter Filter,
or [1] SET SIZE (1..MAX) OF filter Filter,
not [2] Filter,
equalityMatch [3] AttributeValueAssertion,
substrings [4] SubstringFilter,
greaterOrEqual [5] AttributeValueAssertion,
lessOrEqual [6] AttributeValueAssertion,
present [7] AttributeDescription,
approxMatch [8] AttributeValueAssertion,
extensibleMatch [9] MatchingRuleAssertion,
... }
在这种情况下,相关部分是:
present [7] AttributeDescription,
AttributeDescription元素在相同规范的4.1.4节中定义:
AttributeDescription ::= LDAPString
-- Constrained to <attributedescription>
-- [RFC4512]
从第4.1.2节开始:
LDAPString ::= OCTET STRING -- UTF-8 encoded,
-- [ISO10646] characters
所以这意味着当前的过滤器组件是一个八位字符串,它是一个原始元素。 Go错误地将其转换为构造元素,并且目录服务器正确拒绝该格式错误的请求。