rlm_perl - Asymmetric attribute encoding
Alan DeKok
aland at deployingradius.com
Tue Apr 1 02:29:59 CEST 2014
Scott Ireland wrote:
> This isn't actually anything I'm doing, it's verbatim from the LDAP
> server. There is actually a comma in the RDN, which the directory
> escapes when it returns the full DN (wihch seems reasonable, given that
> it could otherwise be seen as a separator). The choice of values here
> isn't mine either.
OK.
> Right.. but still, no matter what kind of data I put in, I get something
> different back.
That just isn't true. Strings without backslashes work fine.
Integers work fine, as do IP addresses, dates, IPv6 addresses, etc.
> If I put in binary data, I get back a string in hex
> notation. If I put in a string, I get that string back in hex notation.
Yes. The parser is forgiving. If you give a hex string to an
attribute of "octets" type, it parses the hex into binary data. If you
give a printable string to an "octets" attribute, it assumes you're
being lazy. The printable string is used as the value for the attribute.
> Except that it isn't.. even without arbitrary binary data, the same
> attribute is written one way and read a completely different way, which
> requires mangling on one side (and only one side) of the processing.
No. The binary attributes are printed and parsed as hex strings:
0xabcdef. That is the normal (and expected) method of operation.
If you pass binary data to the parser, it will assume it's a C string.
It will parse the data as a C string. If you have a zero byte in the
string, everything after that will be ignored.
i.e. If your Perl code expects to see binary data, it MUST call pack()
after it gets the attribute, and unpack() before it hands the attribute
back.
This is consistency. As I said, the interface to the Perl code is
text. If you went with that assumption, you wouldn't see a probem.
Instead, you hand random crap to the function, and are surprised when
you get random crap back. Well... there's not much I can say to that.
> The same goes for the escaped backslash.
That, I agree is inconsistent. It should either
(a) treat the input string as needing escapes, and convert "\," to just
",", then there's no double backslash issue when outputting it
or
b) treat the input string as not needing escapes, in which case "\," is
left as-is, and then the output string should not be escaped, either.
The problem seems to be pairparsevalue(), which treats "\," as "\,",
but DOES convert "\r" and friends to their one-byte sequence.
The solution seems to be treating printable strings as special for FR
to Perl conversions. The Perl string should just be copied to the FR
string as-is, with no escaping. The FR string should be copied to the
Perl string as-is, with no escaping.
I can't do a patch now, but please check the v3.0.x branch tomorrow.
And change your use of State to use pack() and unpack(). Mixing
binary and printable forms of the attribute data is a bad idea.
Alan DeKok.
More information about the Freeradius-Users
mailing list