From: Peter M. <pet...@ma...> - 2002-01-06 13:19:32
|
Sorry,=20 a few small errors in my last mail's listings. Here's the corrected version Yours Peter ---------- Forwarded Message ---------- Subject: canonical_dn Date: Sun, 6 Jan 2002 13:45:17 +0100 From: Peter Marschall <pet...@ma...> To: per...@li... Hi, i have tried to use canonical_dn with UTF 8 and I think it treats strings with UTF8 encoded values wrong. Characters with codes > 127 have UTF8 encodings that consist of 2 or more bytes that have all codes > 127. Since these characters are legal in LDAPv3 DNs they should not get escaped. So line 310 of Net/LDAP/Util.pm should read $val =3D~ s/([\x00-\x1f])/sprintf("\\%02x",ord($1))/eg; instead of the current version: $val =3D~ s/([\x00-\x1f\x7f-\xff])/sprintf("\\%02x",ord($1))/eg; When changing canonical_dn() anyway, maybe changing the implementation into three functions would be helpful. It would give users of Net::LDAP a standardized way of dealing with DNs and parts of it (very helpful when moving entries, ..) without having to reimplement the wheel themselves. Here is my idea: ## split a DN string into its parts; code stolen from canonical_dn() ## # Synopsis: @rdns =3D splitDN($dn, %optionHash) # allowed options: # * lowercase: convert attribute names to lower case # * uppercase: convert attribute names to upper case # * sortRDN: sort RDN values # * splitRDN: split multi part RDNs into their parts sub splitDN($%) { my $dn =3D shift; my %opt =3D @_; my @dn; my @rdn; $dn =3D $dn->dn if ref($dn); while ($dn =3D~ /\G(?: \s* ([a-zA-Z][-a-zA-Z0-9]*|(?:[Oo][Ii][Dd]\.)?\d+(?:\.\d+)*) \s* =3D \s* ( (?:[^\\",=3D+<>\#;]*[^\\",=3D+<>\#;\s]|\\(?:[\\ ",=3D+<>#;]|[0-9a-fA-F]{2}))* \#(?:[0-9a-fA-F]{2})+ "(?:[^\\"]+|\\(?:[\\",=3D+<>#;]|[0-9a-fA-F]{2}))*" ) \s* (?:([;,+])\s*(?=3D\S)|$) )\s*/gcx) { my ($type,$val,$sep) =3D ($1,$2,$3); $type =3D~ s/^oid\.(\d+(\.\d+)*)$/$1/i; $type =3D lc($type) if ($opt{lowercase}); $type =3D uc($type) if ($opt{uppercase}); if ($val !~ /^#/) { $val =3D~ s/^"(.*)"$/$1/; $val =3D~ s/\\([\\ ",=3D+<>#;]|[0-9a-fA-F]{2}) /length($1)=3D=3D1 ? $1 : chr(hex($1)) /xeg; $val =3D~ s/([\\",=3D+<>#;])/\\$1/g; $val =3D~ s/([\x00-\x1F])/sprintf("\\%02x",ord($1))/eg; $val =3D~ s/(^\s+|\s+$)/"\\20" x length $1/ge; } push @rdn, "$type=3D$val"; unless (defined $sep and $sep eq '+') { @rdn =3D sort(@rdn) if ($opt{sortRDN}); push @dn, ($opt{splitRDN}) ? ((scalar(@rdn) > 1) ? [ @rdn ] : ($rdn[0] || '')) : join('+', @rdn); @rdn =3D (); } } return((length($dn) !=3D (pos($dn) || 0)) ? () : @dn); } ## join RDNs and RDN parts into a DN string ## # Synopsis: $dn =3D joinDN(@dnpartref, %optionhash) sub joinDN(\@%) { my @dnparts =3D @i{+shift}; my %opt =3D @_; my $dn =3D ''; @dnparts =3D reverse(@dnparts) if ($opt{reversed}); foreach my $part (@dnparts) { $dn .=3D (($opt{reversed}) ? '\000' : ',') if ($dn); if (ref($part)) # multi part RDN { my $rdn; foreach my $rdnpart (@$part) { return if (!$rdnpart); $rdn .=3D (($opt{reversed}) ? '\001' : '+') if ($rdn); $rdn .=3D $rdnpart; } $dn .=3D $rdn; } else # single part RDN { return if (!$part); $dn .=3D $part; } } return($dn); } These two basic functions now allow to implement canonical_dn() with only a few lines: sub canonical_dn($;$) { my ($dn, $rev) =3D @_; $dn =3D $dn->dn if ref($dn); my @dnparts =3D splitDN($dn, uppercase =3D> 1, splitRDN =3D> 1, sortRDN= =3D> 1); joinDN(@dnparts, reversed =3D> ($rev||0)); } Yours Peter -- Peter Marschall | eMail: pet...@ma... Scheffelstra=DFe 15 | pet...@is... 97072 W=FCrzburg | Tel: 0931/14721 PGP: D7 FF 20 FE E6 6B 31 74 D1 10 88 E0 3C FE 28 35 ------------------------------------------------------- --=20 Peter Marschall | eMail: pet...@ma... Scheffelstra=DFe 15 | pet...@is... 97072 W=FCrzburg | Tel: 0931/14721 PGP: D7 FF 20 FE E6 6B 31 74 D1 10 88 E0 3C FE 28 35 |
From: Graham B. <gb...@po...> - 2002-01-08 18:19:56
|
On Sun, Jan 06, 2002 at 01:57:37PM +0100, Peter Marschall wrote: > Sorry, > > a few small errors in my last mail's listings. > Here's the corrected version Can you get it so that it will pass the t/01canon.t testcase ? Also can explode_dn share the same code ? Graham. |
From: Graham B. <gb...@po...> - 2002-01-08 20:23:41
|
On Tue, Jan 08, 2002 at 06:19:44PM +0000, Graham Barr wrote: > On Sun, Jan 06, 2002 at 01:57:37PM +0100, Peter Marschall wrote: > > Sorry, > > > > a few small errors in my last mail's listings. > > Here's the corrected version > > Can you get it so that it will pass the t/01canon.t testcase ? Also can > explode_dn share the same code ? I already did :). This is what I got. Graham. ## split a DN string into its parts # Synopsis: @rdns = split_dn($dn, %optionHash) # allowed options: # * lowercase: convert attribute names to lower case # * uppercase: convert attribute names to upper case # * sort_rdn: sort RDN values # * split_rdn: split multi part RDNs into their parts sub split_dn($%) { my $dn = shift; my %opt = @_; my (@dn, @rdn); $dn = $dn->dn if ref($dn); while ($dn =~ /\G(?: \s* ([a-zA-Z][-a-zA-Z0-9]*|(?:[Oo][Ii][Dd]\.)?\d+(?:\.\d+)*) \s* = \s* ( (?:[^\\",=+<>\#;]*[^\\",=+<>\#;\s]|\\(?:[\\ ",=+<>#;]|[0-9a-fA-F]{2}))* | \#(?:[0-9a-fA-F]{2})+ | "(?:[^\\"]+|\\(?:[\\",=+<>#;]|[0-9a-fA-F]{2}))*" ) \s* (?:([;,+])\s*(?=\S)|$) )\s*/gcx) { my ($type,$val,$sep) = ($1,$2,$3); $type =~ s/^oid\.(\d+(\.\d+)*)$/$1/i; $type = lc($type) if $opt{lowercase}; $type = uc($type) if $opt{uppercase}; if ($val !~ /^#/) { $val =~ s/^"(.*)"$/$1/; $val =~ s/\\([\\ ",=+<>#;]|[0-9a-fA-F]{2}) /length($1)==1 ? $1 : chr(hex($1)) /xeg; $val =~ s/([\\",=+<>#;])/\\$1/g; $val =~ s/([\x00-\x1F])/sprintf("\\%02x",ord($1))/eg; $val =~ s/(^\s+|\s+$)/"\\20" x length $1/ge; } push @rdn, "$type=$val"; unless (defined $sep and $sep eq '+') { @rdn = sort(@rdn) if $opt{sort_rdn}; push @dn, ($opt{split_rdn}) ? ((scalar(@rdn) > 1) ? [ @rdn ] : ($rdn[0] || '')) : join('+', @rdn); @rdn = (); } } (length($dn) != (pos($dn) || 0)) ? wantarray ? () : undef : wantarray ? @dn : \@dn; } ## join RDNs and RDN parts into a DN string ## # Synopsis: $dn = join_dn(@dnpartref, %optionhash) sub join_dn(\@%) { my $dnparts = shift or return undef; my %opt = @_; my @dn = map { ref($_) ? join($opt{reversed} ? '\001' : '+', @$_) : $_ } @$dnparts or return undef; $opt{reversed} ? join('\000', reverse @dn) : join(',' , @dn); } sub canonical_dn($;$) { my ($dn, $rev) = @_; $dn = $dn->dn if ref($dn); &join_dn( scalar split_dn($dn, uppercase => 1, split_rdn => 1, sort_rdn => 1), reversed => $rev ); } |
From: Chris R. <chr...@me...> - 2002-01-09 08:31:32
|
Graham Barr <gb...@po...> wrote: > On Sun, Jan 06, 2002 at 01:57:37PM +0100, Peter Marschall wrote: >> Sorry, >> >> a few small errors in my last mail's listings. >> Here's the corrected version > > Can you get it so that it will pass the t/01canon.t testcase ? Also can > explode_dn share the same code ? > > Graham. > > There are some other DN test cases at: <http://www.openldap.org/ietf/ldapbis/dn.txt> Cheers, Chris |
From: Graham B. <gb...@po...> - 2002-01-09 14:35:47
|
On Wed, Jan 09, 2002 at 08:28:08AM -0000, Chris Ridd wrote: > Graham Barr <gb...@po...> wrote: > > On Sun, Jan 06, 2002 at 01:57:37PM +0100, Peter Marschall wrote: > >> Sorry, > >> > >> a few small errors in my last mail's listings. > >> Here's the corrected version > > > > Can you get it so that it will pass the t/01canon.t testcase ? Also can > > explode_dn share the same code ? > > > > Graham. > > > > > > There are some other DN test cases at: > > <http://www.openldap.org/ietf/ldapbis/dn.txt> Thanks, After adding those the only failure we have is in accepting the following bad DNs, although I am not convinced that they are all bad. OID.1.1=jsmith // invalid attribute type name why ? is 1.1 an invalid OID ? UID=jsmith, DC=example, DC=net // spaces I dont think this is bad. Th RFC states that you should accept spaces around the ,s UID=jsmith;DC=example;DC=net // semi-colons The RFC states that implementations should allow for the use of a ; instead of a , CN="John Smith",DC=example,DC=net // quotes Again, the RFC states that values may be surrounded with "s 01.1=jsmith // invalid numeric OID This one could be easily fixed as we just change \d+ to [0-9]\d* but I dont really feel the need. Graham. |
From: Chris R. <chr...@me...> - 2002-01-09 15:56:38
|
Graham Barr <gb...@po...> wrote: > On Wed, Jan 09, 2002 at 08:28:08AM -0000, Chris Ridd wrote: >> Graham Barr <gb...@po...> wrote: >> > On Sun, Jan 06, 2002 at 01:57:37PM +0100, Peter Marschall wrote: >> >> Sorry, >> >> >> >> a few small errors in my last mail's listings. >> >> Here's the corrected version >> > >> > Can you get it so that it will pass the t/01canon.t testcase ? Also can >> > explode_dn share the same code ? >> > >> > Graham. >> > >> > >> >> There are some other DN test cases at: >> >> <http://www.openldap.org/ietf/ldapbis/dn.txt> > > Thanks, > > After adding those the only failure we have is in accepting the following > bad DNs, although I am not convinced that they are all bad. > > OID.1.1=jsmith // invalid attribute type name > > why ? is 1.1 an invalid OID ? OIDs in attribute types don't have an "OID." prefix. The DN should be "1.1=jsmith" The BNF in RFC 2253 doesn't permit "." in attribute types unless the entire attribute type is an OID. It is a valid OID, but defined by X.208 to not exist. > UID=jsmith, DC=example, DC=net // spaces > > I dont think this is bad. Th RFC states that you should accept spaces > around the ,s Agreed. It is bad in the sense that an implementation shouldn't generate it, but it must be able to parsed it. > UID=jsmith;DC=example;DC=net // semi-colons > > The RFC states that implementations should allow for the use of a ; > instead of a , Ditto. > > CN="John Smith",DC=example,DC=net // quotes > > Again, the RFC states that values may be surrounded with "s Ditto. > 01.1=jsmith // invalid numeric OID > > This one could be easily fixed as we just change \d+ to [0-9]\d* > but I dont really feel the need. Given the number of DNs containing OIDs as attribute types (approx 0) I concur. > Graham. > Cheers, Chris |
From: Graham B. <gb...@po...> - 2002-01-09 16:14:39
|
On Wed, Jan 09, 2002 at 03:56:21PM -0000, Chris Ridd wrote: > Graham Barr <gb...@po...> wrote: > > On Wed, Jan 09, 2002 at 08:28:08AM -0000, Chris Ridd wrote: > >> Graham Barr <gb...@po...> wrote: > >> > On Sun, Jan 06, 2002 at 01:57:37PM +0100, Peter Marschall wrote: > >> >> Sorry, > >> >> > >> >> a few small errors in my last mail's listings. > >> >> Here's the corrected version > >> > > >> > Can you get it so that it will pass the t/01canon.t testcase ? Also can > >> > explode_dn share the same code ? > >> > > >> > Graham. > >> > > >> > > >> > >> There are some other DN test cases at: > >> > >> <http://www.openldap.org/ietf/ldapbis/dn.txt> > > > > Thanks, > > > > After adding those the only failure we have is in accepting the following > > bad DNs, although I am not convinced that they are all bad. > > > > OID.1.1=jsmith // invalid attribute type name > > > > why ? is 1.1 an invalid OID ? > > OIDs in attribute types don't have an "OID." prefix. > > The DN should be "1.1=jsmith" > > The BNF in RFC 2253 doesn't permit "." in attribute types unless the entire > attribute type is an OID. > > It is a valid OID, but defined by X.208 to not exist. From RFC2253 4. Relationship with RFC 1779 and LDAPv2 ... Implementations MUST allow an oid in the attribute type to be prefixed by one of the character strings "oid." or "OID.". ... So IMO, it is valid to accept it, but not generate it. The oid. prefix is simply ignored. Graham. > > > UID=jsmith, DC=example, DC=net // spaces > > > > I dont think this is bad. Th RFC states that you should accept spaces > > around the ,s > > Agreed. It is bad in the sense that an implementation shouldn't generate > it, but it must be able to parsed it. > > > UID=jsmith;DC=example;DC=net // semi-colons > > > > The RFC states that implementations should allow for the use of a ; > > instead of a , > > Ditto. > > > > > CN="John Smith",DC=example,DC=net // quotes > > > > Again, the RFC states that values may be surrounded with "s > > Ditto. > > > 01.1=jsmith // invalid numeric OID > > > > This one could be easily fixed as we just change \d+ to [0-9]\d* > > but I dont really feel the need. > > Given the number of DNs containing OIDs as attribute types (approx 0) I > concur. > > > Graham. > > > > Cheers, > > Chris > |
From: Chris R. <chr...@me...> - 2002-01-09 17:12:16
|
Graham Barr <gb...@po...> wrote: > On Wed, Jan 09, 2002 at 03:56:21PM -0000, Chris Ridd wrote: >> Graham Barr <gb...@po...> wrote: >> > On Wed, Jan 09, 2002 at 08:28:08AM -0000, Chris Ridd wrote: >> >> Graham Barr <gb...@po...> wrote: >> >> > On Sun, Jan 06, 2002 at 01:57:37PM +0100, Peter Marschall wrote: >> >> >> Sorry, >> >> >> >> >> >> a few small errors in my last mail's listings. >> >> >> Here's the corrected version >> >> > >> >> > Can you get it so that it will pass the t/01canon.t testcase ? Also >> >> > can explode_dn share the same code ? >> >> > >> >> > Graham. >> >> > >> >> > >> >> >> >> There are some other DN test cases at: >> >> >> >> <http://www.openldap.org/ietf/ldapbis/dn.txt> >> > >> > Thanks, >> > >> > After adding those the only failure we have is in accepting the >> > following bad DNs, although I am not convinced that they are all bad. >> > >> > OID.1.1=jsmith // invalid attribute type name >> > >> > why ? is 1.1 an invalid OID ? >> >> OIDs in attribute types don't have an "OID." prefix. >> >> The DN should be "1.1=jsmith" >> >> The BNF in RFC 2253 doesn't permit "." in attribute types unless the >> entire attribute type is an OID. >> >> It is a valid OID, but defined by X.208 to not exist. > > From RFC2253 > > 4. Relationship with RFC 1779 and LDAPv2 > > ... > > Implementations MUST allow an oid in the attribute type to be > prefixed by one of the character strings "oid." or "OID.". > > ... > > So IMO, it is valid to accept it, but not generate it. The oid. prefix > is simply ignored. Rats, I forgot about that. Failing because the actual OID is explicitly defined to not exist would be a little excessive... So I agree, that DN should pass. Cheers, Chris |
From: Graham B. <gb...@po...> - 2002-01-09 16:15:16
|
On Wed, Jan 09, 2002 at 08:28:08AM -0000, Chris Ridd wrote: > Graham Barr <gb...@po...> wrote: > > On Sun, Jan 06, 2002 at 01:57:37PM +0100, Peter Marschall wrote: > >> Sorry, > >> > >> a few small errors in my last mail's listings. > >> Here's the corrected version > > > > Can you get it so that it will pass the t/01canon.t testcase ? Also can > > explode_dn share the same code ? > > > > Graham. > > > > > > There are some other DN test cases at: > > <http://www.openldap.org/ietf/ldapbis/dn.txt> There is also a filter.txt in the same directory, which has found a few issues in our implementation. Graham. |