From 13008e4c5260d08625b65eb1f172ae909152b751 Mon Sep 17 00:00:00 2001 From: Christopher Puschmann Date: Tue, 4 Jan 2022 19:41:36 +0000 Subject: [PATCH] allow using `;` as RDN separator according to rfc2253 (#352) --- dn.go | 4 ++-- dn_test.go | 13 +++++++++++++ v3/dn.go | 4 ++-- v3/dn_test.go | 13 +++++++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/dn.go b/dn.go index 07c586ae..916984b9 100644 --- a/dn.go +++ b/dn.go @@ -101,7 +101,7 @@ func ParseDN(str string) (*DN, error) { buffer.WriteString(packet.Data.String()) i += len(data) - 1 } - case char == ',' || char == '+': + case char == ',' || char == '+' || char == ';': // We're done with this RDN or value, push it if len(attribute.Type) == 0 { return nil, errors.New("incomplete type, value pair") @@ -109,7 +109,7 @@ func ParseDN(str string) (*DN, error) { attribute.Value = stringFromBuffer() rdn.Attributes = append(rdn.Attributes, attribute) attribute = new(AttributeTypeAndValue) - if char == ',' { + if char == ',' || char == ';' { dn.RDNs = append(dn.RDNs, rdn) rdn = new(RelativeDN) rdn.Attributes = make([]*AttributeTypeAndValue, 0) diff --git a/dn_test.go b/dn_test.go index d93ba650..6a82c72d 100644 --- a/dn_test.go +++ b/dn_test.go @@ -45,6 +45,17 @@ func TestSuccessfulDNParsing(t *testing.T) { {[]*AttributeTypeAndValue{ {" A ", " 1 "}, {" B ", " 2 "}}}}}, + + `cn=john.doe;dc=example,dc=net`: {[]*RelativeDN{ + {[]*AttributeTypeAndValue{{"cn", "john.doe"}}}, + {[]*AttributeTypeAndValue{{"dc", "example"}}}, + {[]*AttributeTypeAndValue{{"dc", "net"}}}}}, + + // Escaped `;` should not be treated as RDN + `cn=john.doe\;weird name,dc=example,dc=net`: {[]*RelativeDN{ + {[]*AttributeTypeAndValue{{"cn", "john.doe;weird name"}}}, + {[]*AttributeTypeAndValue{{"dc", "example"}}}, + {[]*AttributeTypeAndValue{{"dc", "net"}}}}}, } for test, answer := range testcases { @@ -147,6 +158,8 @@ func TestDNEqual(t *testing.T) { "cn=John Doe, ou=People, dc=sun.com", false, }, + // Test parsing of `;` for separating RDNs + {"cn=john;dc=example,dc=com", "cn=john,dc=example,dc=com", true}, // missing values matter } for i, tc := range testcases { diff --git a/v3/dn.go b/v3/dn.go index 2b4cede9..d802580e 100644 --- a/v3/dn.go +++ b/v3/dn.go @@ -101,7 +101,7 @@ func ParseDN(str string) (*DN, error) { buffer.WriteString(packet.Data.String()) i += len(data) - 1 } - case char == ',' || char == '+': + case char == ',' || char == '+' || char == ';': // We're done with this RDN or value, push it if len(attribute.Type) == 0 { return nil, errors.New("incomplete type, value pair") @@ -109,7 +109,7 @@ func ParseDN(str string) (*DN, error) { attribute.Value = stringFromBuffer() rdn.Attributes = append(rdn.Attributes, attribute) attribute = new(AttributeTypeAndValue) - if char == ',' { + if char == ',' || char == ';' { dn.RDNs = append(dn.RDNs, rdn) rdn = new(RelativeDN) rdn.Attributes = make([]*AttributeTypeAndValue, 0) diff --git a/v3/dn_test.go b/v3/dn_test.go index d93ba650..6a82c72d 100644 --- a/v3/dn_test.go +++ b/v3/dn_test.go @@ -45,6 +45,17 @@ func TestSuccessfulDNParsing(t *testing.T) { {[]*AttributeTypeAndValue{ {" A ", " 1 "}, {" B ", " 2 "}}}}}, + + `cn=john.doe;dc=example,dc=net`: {[]*RelativeDN{ + {[]*AttributeTypeAndValue{{"cn", "john.doe"}}}, + {[]*AttributeTypeAndValue{{"dc", "example"}}}, + {[]*AttributeTypeAndValue{{"dc", "net"}}}}}, + + // Escaped `;` should not be treated as RDN + `cn=john.doe\;weird name,dc=example,dc=net`: {[]*RelativeDN{ + {[]*AttributeTypeAndValue{{"cn", "john.doe;weird name"}}}, + {[]*AttributeTypeAndValue{{"dc", "example"}}}, + {[]*AttributeTypeAndValue{{"dc", "net"}}}}}, } for test, answer := range testcases { @@ -147,6 +158,8 @@ func TestDNEqual(t *testing.T) { "cn=John Doe, ou=People, dc=sun.com", false, }, + // Test parsing of `;` for separating RDNs + {"cn=john;dc=example,dc=com", "cn=john,dc=example,dc=com", true}, // missing values matter } for i, tc := range testcases {