# initial authentication session (Common in a
# wireless environment).
#
- if ("%{Class}" =~ /${policy.class_value_prefix}([0-9a-f]{32})/i) {
- &request.Acct-Unique-Session-Id := %hex(%md5("%{1}%{Acct-Session-ID}"))
+ if (Class =~ /${policy.class_value_prefix}([0-9a-f]{32})/i) {
+ request.Acct-Unique-Session-Id := %hex(%md5("%{1}%{Acct-Session-ID}"))
}
#
# is not included
#
else {
- &request.Acct-Unique-Session-Id := %hex(%md5("%{User-Name},%{Acct-Multi-Session-ID},%{Acct-Session-ID},%{&NAS-IPv6-Address || &NAS-IP-Address},%{NAS-Identifier},%{NAS-Port-ID},%{NAS-Port}"))
+ request.Acct-Unique-Session-Id := %hex(%md5("%{User-Name},%{Acct-Multi-Session-ID},%{Acct-Session-ID},%{&NAS-IPv6-Address || &NAS-IP-Address},%{NAS-Identifier},%{NAS-Port-ID},%{NAS-Port}"))
}
}
# Insert a (hopefully unique) value into class
#
insert_acct_class {
- &reply.Class = '${policy.class_value_prefix}' + %hex(%md5("%t%I%{Net.Src.Port}%{Net.Src.IP}%{NAS-IP-Address}%{Calling-Station-ID}%{User-Name}"))
+ reply.Class = '${policy.class_value_prefix}' + %hex(%md5("%t%I%{Net.Src.Port}%{Net.Src.IP}%{NAS-IP-Address}%{Calling-Station-ID}%{User-Name}"))
}
#
# If the &Attr-Foo doesn't exist, it's value is taken as zero.
#
acct_counters64 {
- if (!&Acct-Input-Gigawords) {
- &request.Acct-Input-Octets64 := %{&Acct-Input-Octets || 0}
+ if (!Acct-Input-Gigawords) {
+ request.Acct-Input-Octets64 := %{Acct-Input-Octets || 0}
}
else {
- &request.Acct-Input-Octets64 = (((uint64) &Acct-Input-Gigawords) << 32) | (uint64) &Acct-Input-Octets
+ request.Acct-Input-Octets64 = (((uint64) Acct-Input-Gigawords) << 32) | (uint64) Acct-Input-Octets
}
- if (!&Acct-Output-Gigawords) {
- &request.Acct-Output-Octets64 := %{&Acct-Output-Octets || 0}
+ if (!Acct-Output-Gigawords) {
+ request.Acct-Output-Octets64 := %{Acct-Output-Octets || 0}
}
else {
- &request.Acct-Output-Octets64 = (((uint64) &Acct-Output-Gigawords) << 32) | (uint64) &Acct-Output-Octets
+ request.Acct-Output-Octets64 = (((uint64) Acct-Output-Gigawords) << 32) | (uint64) Acct-Output-Octets
}
}
nai_regexp = '^([^@]*)(@([-[:alnum:]]+\.[-[:alnum:].]+))?$'
split_username_nai {
- if (&User-Name && (&User-Name =~ /${policy.nai_regexp}/)) {
- &request.Stripped-User-Name := "%{1}"
+ if (User-Name && (User-Name =~ /${policy.nai_regexp}/)) {
+ request.Stripped-User-Name := "%{1}"
# Only add the Stripped-User-Domain attribute if
# we have a domain. This means presence checks
# for Stripped-User-Domain work.
if ("%{3}" != '') {
- &request.Stripped-User-Domain = "%{3}"
+ request.Stripped-User-Domain = "%{3}"
}
# If any of the expansions result in a null
# be provided by 802.1X authenticators.
#
rewrite_called_station_id {
- if (&Called-Station-Id && (&Called-Station-Id =~ /^${policy.mac-addr-regexp}([^0-9a-f](.+))?$/i)) {
- &request.Called-Station-Id := "%toupper(%{1}-%{2}-%{3}-%{4}-%{5}-%{6})"
+ if (Called-Station-Id && (Called-Station-Id =~ /^${policy.mac-addr-regexp}([^0-9a-f](.+))?$/i)) {
+ request.Called-Station-Id := "%toupper(%{1}-%{2}-%{3}-%{4}-%{5}-%{6})"
# SSID component?
if ("%{8}") {
- &request.Called-Station-SSID := "%{8}"
+ request.Called-Station-SSID := "%{8}"
}
updated
}
# be provided by 802.1X authenticators.
#
rewrite_calling_station_id {
- if (&Calling-Station-Id && (&Calling-Station-Id =~ /^${policy.mac-addr-regexp}$/i)) {
- &request.Calling-Station-Id := "%toupper(%{1}-%{2}-%{3}-%{4}-%{5}-%{6})"
+ if (Calling-Station-Id && (Calling-Station-Id =~ /^${policy.mac-addr-regexp}$/i)) {
+ request.Calling-Station-Id := "%toupper(%{1}-%{2}-%{3}-%{4}-%{5}-%{6})"
updated
}
# then use the "do_not_respond" policy.
#
do_not_respond {
- &reply.Packet-Type := ::Do-Not-Respond
+ reply.Packet-Type := ::Do-Not-Respond
handled
}
# Send Access-Accept immediately
#
accept {
- &reply.Packet-Type := ::Access-Accept
+ reply.Packet-Type := ::Access-Accept
handled
}
# Send Access-Challenge immediately
#
challenge {
- &reply.Packet-Type := ::Access-Challenge
+ reply.Packet-Type := ::Access-Challenge
handled
}
# Send an Accounting-Response immediately
#
acct_response {
- &reply.Packet-Type := ::Accounting-Response
+ reply.Packet-Type := ::Accounting-Response
handled
}
# include the original packet code in the reply.
#
protocol_error {
- &reply.Packet-Type := Accounting-Response
- &reply.Original-Packet-Code := "%{Packet-Type}"
+ reply.Packet-Type := ::Accounting-Response
+ reply.Original-Packet-Code := Packet-Type
handled
}
# Discard the packet without replying
#
discard {
- &reply.Packet-Type := ::Do-Not-Respond
+ reply.Packet-Type := ::Do-Not-Respond
handled
}
#
cui.authorize {
if ("%client(add_cui)" == 'yes') {
- &request.Chargeable-User-Identity := 0x00
+ request.Chargeable-User-Identity := 0x00
}
}
# use_tunneled_reply parameter MUST be set to yes
#
cui.post-auth {
- if (!&control.Proxy-To-Realm && &Chargeable-User-Identity && !&reply.Chargeable-User-Identity &&
- (&Operator-Name || ('${policy.cui_require_operator_name}' != 'yes')) ) {
- &reply.Chargeable-User-Identity = "%sha1(${policy.cui_hash_key}%tolower(%{User-Name}%{&Operator-Name || ''}))"
+ if (!control.Proxy-To-Realm && Chargeable-User-Identity && !reply.Chargeable-User-Identity &&
+ (Operator-Name || ('${policy.cui_require_operator_name}' != 'yes')) ) {
+ reply.Chargeable-User-Identity = "%sha1(${policy.cui_hash_key}%tolower(%{User-Name}%{Operator-Name || ''}))"
}
#
# If your NAS can do CUI based accounting themselves or you do not care about
# accounting, comment out the 'cuisql' line below.
#
- if (&reply.Chargeable-User-Identity) {
+ if (reply.Chargeable-User-Identity) {
# Force User-Name to be the User-Name from the request
- &reply.User-Name := &request.User-Name
+ reply.User-Name := &request.User-Name
cuisql
}
cui-inner.post-auth {
- if (&outer.request.Chargeable-User-Identity && \
- (&outer.request.Operator-Name || ('${policy.cui_require_operator_name}' != 'yes'))) {
- &reply.Chargeable-User-Identity := "%sha1(${policy.cui_hash_key}%tolower(%{User-Name}%{&outer.request.Operator-Name || ''}))"
+ if (outer.request.Chargeable-User-Identity && \
+ (outer.request.Operator-Name || ('${policy.cui_require_operator_name}' != 'yes'))) {
+ reply.Chargeable-User-Identity := "%sha1(${policy.cui_hash_key}%tolower(%{User-Name}%{outer.request.Operator-Name || ''}))"
}
}
# If the CUI isn't in the packet, see if we can find it
# in the DB.
#
- if (!&Chargeable-User-Identity) {
- &request.Chargeable-User-Identity := %cuisql(\
+ if (!Chargeable-User-Identity) {
+ request.Chargeable-User-Identity := %cuisql(\
SELECT cui FROM cui \
WHERE clientipaddress = '%{Net.Src.IP}' \
AND callingstationid = '%{Calling-Station-Id}' \
# If it exists now, then write out when we last saw
# this CUI.
#
- if (&Chargeable-User-Identity && (&Chargeable-User-Identity != '')) {
+ if (Chargeable-User-Identity && (Chargeable-User-Identity != '')) {
cuisql
}
}
# The contents here are invented. Change them!
# Lease time is referencing the lease time set in the
# named module instance configuration
- &reply.Domain-Name-Server = 127.0.0.1
- &reply.Domain-Name-Server = 127.0.0.2
- &reply.Subnet-Mask = 255.255.255.0
- &reply.Router-Address = 192.0.2.1
- &reply.IP-Address-Lease-Time = 7200
-# &reply.IP-Address-Lease-Time = "${modules.sqlippool[sqlippool].lease_duration}"
- &reply.Server-Identifier = &control.Server-Identifier
+ reply.Domain-Name-Server = 127.0.0.1
+ reply.Domain-Name-Server = 127.0.0.2
+ reply.Subnet-Mask = 255.255.255.0
+ reply.Router-Address = 192.0.2.1
+ reply.IP-Address-Lease-Time = 7200
+# reply.IP-Address-Lease-Time = "${modules.sqlippool[sqlippool].lease_duration}"
+ reply.Server-Identifier = &control.Server-Identifier
}
# into the "recv Access-Request" section.
#
forbid_eap {
- if (&EAP-Message) {
+ if (EAP-Message) {
reject
}
}
# Forbid all non-EAP types outside of an EAP tunnel.
#
permit_only_eap {
- if (!&EAP-Message) {
+ if (!EAP-Message) {
# We MAY be inside of a TTLS tunnel.
# PEAP and EAP-FAST require EAP inside of
# the tunnel, so this check is OK.
# If so, then there MUST be an outer EAP message.
- if (!&outer.request || !&outer.request.EAP-Message) {
+ if (!outer.request || !outer.request.EAP-Message) {
reject
}
}
# not be present in the same response.
#
remove_reply_message_if_eap {
- if (&reply.EAP-Message && &reply.Reply-Message) {
- &reply -= &Reply-Message[*]
+ if (reply.EAP-Message && reply.Reply-Message) {
+ reply -= &Reply-Message[*]
}
else {
noop
# to copy now have to be explicitly listed.
#
copy_request_to_tunnel {
- &request.Calling-Station-Id = &outer.request.Calling-Station-Id
- &request.Called-Station-Id = &outer.request.Called-Station-Id
+ request.Calling-Station-Id = outer.request.Calling-Station-Id
+ request.Called-Station-Id = outer.request.Called-Station-Id
}
#
# These attributes are for the inner-tunnel only,
# and MUST NOT be copied to the outer reply.
#
- &reply -= &User-Name[*]
+ reply -= &User-Name[*]
#
# Copy the remaining inner reply attributes to the outer
# 'send Access-Accept' policy in sites-available/default will
# copy the outer session-state list to the final reply.
#
- &outer.session-state += &reply
+ outer.session-state += reply
}
# realms.
#
deny_realms {
- if (&User-Name && (&User-Name =~ /@|\\/)) {
+ if (User-Name && (User-Name =~ /@|\\/)) {
reject
}
}
# what constitutes a user name.
#
filter_username {
- if (&State) {
- if (&User-Name) {
- if (!&session-state.Session-State-User-Name) {
- &request += {
- &Module-Failure-Message = "No cached session-state.Session-State-User-Name"
+ if (State) {
+ if (User-Name) {
+ if (!session-state.Session-State-User-Name) {
+ request += {
+ Module-Failure-Message = "No cached session-state.Session-State-User-Name"
}
reject
}
- if (&User-Name != &session-state.Session-State-User-Name) {
- &request += {
- &Module-Failure-Message = "User-Name does not match cached session-state.Session-State-User-Name"
+ if (User-Name != session-state.Session-State-User-Name) {
+ request += {
+ Module-Failure-Message = "User-Name does not match cached session-state.Session-State-User-Name"
}
reject
}
}
}
- elsif (&User-Name) {
+ elsif (User-Name) {
#
# reject mixed case e.g. "UseRNaMe"
#
- #if (&User-Name != "%tolower(%{User-Name}}") {
+ #if (User-Name != "%tolower(%{User-Name}}") {
# reject
#}
# reject all whitespace
# e.g. "user@ site.com", or "us er", or " user", or "user "
#
- if (&User-Name =~ / /) {
- &request += {
- &Module-Failure-Message = "User-Name contains whitespace"
+ if (User-Name =~ / /) {
+ request += {
+ Module-Failure-Message = "User-Name contains whitespace"
}
reject
}
# reject Multiple @'s
# e.g. "user@site.com@site.com"
#
- if (&User-Name =~ /@[^@]*@/ ) {
- &request += {
- &Module-Failure-Message = "Multiple @ in User-Name"
+ if (User-Name =~ /@[^@]*@/ ) {
+ request += {
+ Module-Failure-Message = "Multiple @ in User-Name"
}
reject
}
# reject double dots
# e.g. "user@site..com"
#
- if (&User-Name =~ /\.\./ ) {
- &request += {
- &Module-Failure-Message = "User-Name contains multiple dots (e.g. user@site..com)"
+ if (User-Name =~ /\.\./ ) {
+ request += {
+ Module-Failure-Message = "User-Name contains multiple dots (e.g. user@site..com)"
}
reject
}
# must have at least 1 string-dot-string after @
# e.g. "user@site.com"
#
- if ((&User-Name =~ /@/) && (&User-Name !~ /@[^.]+(\.[^.]+)+$/)) {
- &request += {
- &Module-Failure-Message = "Realm does not have at least one dot separator"
+ if ((User-Name =~ /@/) && (User-Name !~ /@[^.]+(\.[^.]+)+$/)) {
+ request += {
+ Module-Failure-Message = "Realm does not have at least one dot separator"
}
reject
}
# Realm ends with a dot
# e.g. "user@site.com."
#
- if (&User-Name =~ /\.$/) {
- &request += {
- &Module-Failure-Message = "Realm ends with a dot"
+ if (User-Name =~ /\.$/) {
+ request += {
+ Module-Failure-Message = "Realm ends with a dot"
}
reject
}
# Realm begins with a dot
# e.g. "user@.site.com"
#
- if (&User-Name =~ /@\./) {
- &request += {
- &Module-Failure-Message = "Realm begins with a dot"
+ if (User-Name =~ /@\./) {
+ request += {
+ Module-Failure-Message = "Realm begins with a dot"
}
reject
}
- &session-state.Session-State-User-Name := &User-Name
+ session-state.Session-State-User-Name := User-Name
}
}
# This policy filters them out.
#
filter_password {
- if &User-Password {
+ if User-Password {
group tmp
octets delim
#
# Because "\000" yields "zero length delimiter is not allowed"
#
- &delim = 0x00
- &tmp.User-Password := %explode(%{User-Password}, "%{delim}")
+ delim = 0x00
+ tmp.User-Password := %explode(%{User-Password}, "%{delim}")
- &User-Password := &tmp.User-Password[0]
+ User-Password := tmp.User-Password[0]
}
}
#
# No names, reject.
#
- if (!&outer.request.User-Name || !&User-Name) {
- &request += {
- &Module-Failure-Message = "User-Name is required for tunneled authentication"
+ if (!outer.request.User-Name || !User-Name) {
+ request += {
+ Module-Failure-Message = "User-Name is required for tunneled authentication"
}
reject
}
# If the NAIs are the same, it violates user privacy,
# but is allowed.
#
- if (&outer.request.User-Name != &User-Name) {
+ if (outer.request.User-Name != User-Name) {
#
# Get the outer realm.
#
- if (&outer.request.User-Name =~ /@([^@]+)$/) {
- &request.Outer-Realm-Name = %{1}
+ if (outer.request.User-Name =~ /@([^@]+)$/) {
+ request.Outer-Realm-Name = %{1}
#
# When we have an outer realm name, the user portion
# We don't check for the full "anonymous", because
# some vendors don't follow the standards.
#
- if (&outer.request.User-Name !~ /^(anon|@)/) {
- &request += {
- &Module-Failure-Message = "User-Name is not anonymized"
+ if (outer.request.User-Name !~ /^(anon|@)/) {
+ request += {
+ Module-Failure-Message = "User-Name is not anonymized"
}
reject
}
# Otherwise, you could log in as outer "bob", and inner "doug",
# and we'd have no idea which one was correct.
#
- elsif (&outer.request.User-Name !~ /^anon/) {
- &request += {
- &Module-Failure-Message = "User-Name is not anonymized"
+ elsif (outer.request.User-Name !~ /^anon/) {
+ request += {
+ Module-Failure-Message = "User-Name is not anonymized"
}
reject
}
#
# Get the inner realm.
#
- if (&User-Name =~ /@([^@]+)$/) {
- &request.Inner-Realm-Name = %{1}
+ if (User-Name =~ /@([^@]+)$/) {
+ request.Inner-Realm-Name = %{1}
#
# Note that we do EQUALITY checks for realm names.
# If the inner realm isn't the same as the outer realm,
# the inner realm MUST be a subdomain of the outer realm.
#
- if (&Outer-Realm-Name && \
- (&Inner-Realm-Name != &Outer-Realm-Name) && \
- (&Inner-Realm-Name !~ /\.%{Outer-Realm-Name}$/)) {
- &request += {
- &Module-Failure-Message = "Inner realm '%{Inner-Realm-Name}' and outer realm '%{Outer-Realm-Name}' are not from the same domain."
+ if (Outer-Realm-Name && \
+ (Inner-Realm-Name != Outer-Realm-Name) && \
+ (Inner-Realm-Name !~ /\.%{Outer-Realm-Name}$/)) {
+ request += {
+ Module-Failure-Message = "Inner realm '%{Inner-Realm-Name}' and outer realm '%{Outer-Realm-Name}' are not from the same domain."
}
reject
}
#
operator-name.authorize {
if ("%client(Operator-Name)") {
- &request.Operator-Name = "%client(Operator-Name)"
+ request.Operator-Name = "%client(Operator-Name)"
}
}
# Handles the Expiration attribute
#
expiration {
- if (&control.Expiration) {
+ if (control.Expiration) {
time_delta when
#
# %l is "when the server received the request"
#
- if (&control.Expiration < %l) {
+ if (control.Expiration < %l) {
disallow
return
}
- &when = &control.Expiration - %l
+ &when = control.Expiration - %l
- &reply.Session-Timeout <= &when
+ reply.Session-Timeout <= &when
}
}
broadsoft-decode {
foreach value ( BroadSoft-Attr-255 ) {
if (value =~ /^([0-9]+)=(.*)$/) {
- "&request.BroadSoft-Attr-%{1}" += "%{2}"
+ "request.BroadSoft-Attr-%{1}" += "%{2}"
}
}