Cisco-AVPair regex

Kylián Martin kylianm at plzen.eu
Thu Feb 22 13:53:40 CET 2018


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 at 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 at 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



More information about the Freeradius-Users mailing list