Help in understanding variable expansion

Luca Cavana Luca.Cavana at cavanasystems.com
Tue Feb 11 15:09:00 UTC 2025


Hello,

this environment is used to perform (also) EAP-TLS, which is working fine.
The supplicants in this environment are a mixture of Linux and Windows that all send the User-Name attribute in the form used by Windows, which is: host/UPPERCASE_HOSTNAME.lowercase.fqdn.
To be able to match the certificate's Subject to the User-Name attribute I am using the following piece of unlang (in post-auth) which matches the full fqdn and compares it with the certificate subject with a case insensitive regular expression.

cavanasystems_verify_tls_client_common_name {
        if (&User-Name =~ /^host\/([A-Z0-9]{13}.corp\.cavanasystems\.com)/) {
                update request {
                        &Sanitized-Host-Name := "%{1}"
                }
        }
        if ((&User-Name !~ /^@/) && &TLS-Client-Cert-Common-Name && (&TLS-Client-Cert-Common-Name !~ /%{&Sanitized-Host-Name}/i)) {
                reject
        }
}


This works but I have to instruct the Linux supplicants to send their User-Name as Windows does, which I do not like.
If I change my regular expression match using variable substitution while defaulting another variable, like this:

/%{%{&Sanitized-Host-Name}:-%{&User-Name}}/i

... which I expect to firstly match the Sanitized-Host-Name (which will exist only if a Windows supplicant is trying to authenticate) and if that does not exist, match with the User-Name (which is sent "good" by a Linux client).
The problem is that this is what actually happens: the following debug is from a Linux client mimicking the Windows behavior.

(8)         if ((&User-Name !~ /^@/) && &TLS-Client-Cert-Common-Name && (&TLS-Client-Cert-Common-Name !~ /%{%{&Sanitized-Host-Name}:-%{&User-Name}}/i)) {
(8)         EXPAND %{%{&Sanitized-Host-Name}:-%{&User-Name}}
(8)            --> ITMIL01CD0002\\.corp\\.cavanasystems\\.com
(8)         if ((&User-Name !~ /^@/) && &TLS-Client-Cert-Common-Name && (&TLS-Client-Cert-Common-Name !~ /%{%{&Sanitized-Host-Name}:-%{&User-Name}}/i))  -> TRUE
(8)         if ((&User-Name !~ /^@/) && &TLS-Client-Cert-Common-Name && (&TLS-Client-Cert-Common-Name !~ /%{%{&Sanitized-Host-Name}:-%{&User-Name}}/i))  {
(8)           [reject] = reject
(8)         } # if ((&User-Name !~ /^@/) && &TLS-Client-Cert-Common-Name && (&TLS-Client-Cert-Common-Name !~ /%{%{&Sanitized-Host-Name}:-%{&User-Name}}/i))  = reject
(8)       } # policy cavanasystems_verify_tls_client_common_name = reject

I've enabled some debug and this is the state the AVPs are in:
(8)             Attributes matching "request:"
(8)               &request:User-Name = host/ITMIL01CD0002.corp.cavanasystems.com
(8)               &request:Sanitized-Host-Name := ITMIL01CD0002.corp.cavanasystems.com

I don't understand why it looks like the server is escaping the dots "\\." while doing the EXPAND operation.

Thank you very much,
Luca Cavana


More information about the Freeradius-Users mailing list