Hi Alan, thanks for everything you do for the community . I came back to this after some time:
-----Original Message----- From: Freeradius-Users [mailto:freeradius-users- bounces+kylianm=plzen.eu@lists.freeradius.org] On Behalf Of Alan DeKok Sent: Friday, July 14, 2017 3:35 PM To: FreeRadius users mailing list Subject: Re: Cisco-AVPair regex
On Jul 14, 2017, at 9:22 AM, Kylián Martin <kylianm@plzen.eu> wrote:
I'm trying to save some of the Cisco-AVPair attributes into sql while
acounting. Specifically, I'm interested in the dhcp-options and http-tlv attributes. WLC describes the connected device in these.
Unfortunately, Freeradius 3.12 expands these values unregexable way. (With_cisco_vsa_hack = yes in preprocess the result is the same) Correctly expanded is just Cisco-AVPair = "audit-session-
id=1ef1a8c000014809cba76859"
That's just text. There shouldn't be a problem.
Policy file:
device_regex = '^((dhcp-option=)|(http- tlv=)){1}([\\].{2,5})([\\].{2,5})([\\].{3})([\\].{3})?(.*)'
That seems much too complicated. And doesn't match the Cisco-AVPair you have above.
(98) Cisco-AVPair = "dhcp-option=\000\014\000\0056spMK" (98) Cisco-AVPair = "http-tlv=\000\001\000\030iPhone8,2/10.3.2 (14F89)"
How to regex these ?
Use a regex library which can handle embedded NUL bytes.
Regexes normally work on strings. i.e. printable data. The attributes above are binary, not printable data.
Both attributes are expanded till first whitespace char
No, they stop on the first NUL character. i.e. embedded zero.
(98) if ("%{Foreach-Variable-0}" =~ /^((dhcp-option=)|(http- tlv=)){1}([\\].{2,5})([\\].{2,5})([\\].{3})([\\].{3})?(.*)/i) -> FALSE (98) } # foreach &Cisco-AVPair = updated (98) } # if (&Cisco-AVPair) = updated
How to get text values following whitespaces? I've already tried if ("unescape:%{Foreach-Variable-0}" =~ /${policy.device_regex}/i) with no luck
Install pcre, and use it as the regex engine. It can handle embedded NUL bytes.
I am using the debian packages (currently 3.0.16+dfsg-1+b1 from the unstable release) and I'd love to keep this approach (because of the updates). I don't know how exactly the maintainer compile the FR packages, but i would not expect the pcre support as enabled during the compilation. Does exist any other way for me how to enable the pcre support ?
Or, use another method to parse the Cisco-AVPairs. e.g. rlm_perl.
This turned out to be ideal. Howerer, passing request to the perl script fails on the same thing - attributes are passed empty aswell. (11) Received Accounting-Request Id 57 from 192.168.241.30:34261 to 172.31.12.101:1813 length 393 ... (11) Cisco-AVPair = "dhcp-option=\000\014\000\002MK" (11) Cisco-AVPair = "http-tlv=\000\001\000\031iPhone10,2/11.2.5 (15D60)" (11) # Executing section preacct from file /etc/freeradius/3.0/sites-enabled/default (11) preacct { (11) [preprocess] = ok (11) sitmp-regex-parser: $RAD_REQUEST{'Cisco-AVPair'}[0] = &request:Cisco-AVPair -> 'audit-session-id=1ef1a8c000052ac48ab18e5a' (11) sitmp-regex-parser: $RAD_REQUEST{'Cisco-AVPair'}[1] = &request:Cisco-AVPair -> 'dhcp-option=' (11) sitmp-regex-parser: $RAD_REQUEST{'Cisco-AVPair'}[2] = &request:Cisco-AVPair -> 'http-tlv='
Or, use the "unpack" module to unpack binary data. See raddb/mods- available/unpack for documentation.
I did. I tried if (&Cisco-AVPair) { foreach &Cisco-AVPair { if ("%{unpack: &Foreach-Variable-0 0 short}" =~ /${policy.device_regex}/i) {} } With the result (25) if (&Cisco-AVPair) -> TRUE (25) if (&Cisco-AVPair) { (25) foreach &Cisco-AVPair (25) if ("%{unpack: &Foreach-Variable-0 0 short}" =~ /^((dhcp-option=)|(http-tlv=)){1}([\\][0-9]{1,3}){1,5}(.*)$/i) { (25) EXPAND %{unpack: &Foreach-Variable-0 0 short} (25) --> (25) if ("%{unpack: &Foreach-Variable-0 0 short}" =~ /^((dhcp-option=)|(http-tlv=)){1}([\\][0-9]{1,3}){1,5}(.*)$/i) -> FALSE (25) if ("%{unpack: &Foreach-Variable-0 0 short}" =~ /^((dhcp-option=)|(http-tlv=)){1}([\\][0-9]{1,3}){1,5}(.*)$/i) { (25) EXPAND %{unpack: &Foreach-Variable-0 0 short} (25) --> (25) if ("%{unpack: &Foreach-Variable-0 0 short}" =~ /^((dhcp-option=)|(http-tlv=)){1}([\\][0-9]{1,3}){1,5}(.*)$/i) -> FALSE (25) if ("%{unpack: &Foreach-Variable-0 0 short}" =~ /^((dhcp-option=)|(http-tlv=)){1}([\\][0-9]{1,3}){1,5}(.*)$/i) { (25) EXPAND %{unpack: &Foreach-Variable-0 0 short} (25) --> (25) if ("%{unpack: &Foreach-Variable-0 0 short}" =~ /^((dhcp-option=)|(http-tlv=)){1}([\\][0-9]{1,3}){1,5}(.*)$/i) -> FALSE (25) } # foreach &Cisco-AVPair = ok (25) } # if (&Cisco-AVPair) = ok Thank you in advance for any idea
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html