# do things here
}
else {
- update reply {
- &Reply-Message = "RP not authorized for this ABFAB request"
- }
+ &reply.Reply-Message = "RP not authorized for this ABFAB request"
+
reject
}
}
# check that the acceptor host name is correct
if ("%(client:gss_acceptor_host_name)" && &GSS-acceptor-host-name) {
if ("%(client:gss_acceptor_host_name)" != "%{gss-acceptor-host-name}") {
- update reply {
- &Reply-Message = "GSS-Acceptor-Host-Name incorrect"
- }
+ &reply.Reply-Message = "GSS-Acceptor-Host-Name incorrect"
+
reject
}
}
# set trust-router-coi attribute from the client configuration
if ("%(client:trust_router_coi)") {
- update request {
- &Trust-Router-COI := "%(client:trust_router_coi)"
- }
+ &request.Trust-Router-COI := "%(client:trust_router_coi)"
}
# set gss-acceptor-realm-name attribute from the client configuration
if ("%(client:gss_acceptor_realm_name)") {
- update request {
- &GSS-Acceptor-Realm-Name := "%(client:gss_acceptor_realm_name)"
- }
+ &request.GSS-Acceptor-Realm-Name := "%(client:gss_acceptor_realm_name)"
}
}
}
if (&GSS-Acceptor-Service-Name || &GSS-Acceptor-Realm-Name || &GSS-Acceptor-Host-Name) {
- update control {
- &Chbind-Response-Code := success
- }
+ &control.Chbind-Response-Code := success
#
# ACK the attributes in the request.
# If any one of these attributes don't exist in the request,
# then they won't be copied to the reply.
#
- update reply {
- &GSS-Acceptor-Service-Name = &GSS-Acceptor-Service-Name
- &GSS-Acceptor-Host-Name = &GSS-Acceptor-Host-Name
- &GSS-Acceptor-Realm-Name = &GSS-Acceptor-Realm-Name
- }
+ &reply.GSS-Acceptor-Service-Name = &GSS-Acceptor-Service-Name
+ &reply.GSS-Acceptor-Host-Name = &GSS-Acceptor-Host-Name
+ &reply.GSS-Acceptor-Realm-Name = &GSS-Acceptor-Realm-Name
}
#
# wireless environment).
#
if ("%{string:Class}" =~ /${policy.class_value_prefix}([0-9a-f]{32})/i) {
- update request {
- &Acct-Unique-Session-Id := "%{hex:%{md5:%{string:%{1},%{Acct-Session-ID}}}}"
- }
+ &request.Acct-Unique-Session-Id := "%{hex:%{md5:%{string:%{1},%{Acct-Session-ID}}}}"
}
#
# is not included
#
else {
- update request {
- &Acct-Unique-Session-Id := "%{hex:%{md5:%{string:%{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:%{string:%{User-Name},%{Acct-Multi-Session-ID},%{Acct-Session-ID},%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}},%{NAS-Identifier},%{NAS-Port-ID},%{NAS-Port}}}}
}
- update request {
- &Tmp-String-9 !* ANY
- }
+ &request -= &Tmp-String-9[*]
}
#
# Insert a (hopefully unique) value into class
#
insert_acct_class {
- update reply {
- &Class = "${policy.class_value_prefix}%{md5:%t,%I,%{Packet-Src-Port},%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}},%{NAS-IP-Address},%{Calling-Station-ID},%{User-Name}}"
- }
+ &reply.Class = "${policy.class_value_prefix}%{md5:%t,%I,%{Packet-Src-Port},%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}},%{NAS-IP-Address},%{Calling-Station-ID},%{User-Name}}"
}
#
#
acct_counters64.preacct {
if (!&Acct-Input-Gigawords) {
- update request {
- &Acct-Input-Octets64 := "%{%{Acct-Input-Octets}:-0}"
- }
+ &request.Acct-Input-Octets64 := "%{%{Acct-Input-Octets}:-0}"
}
else {
- update request {
- &Acct-Input-Octets64 = "%{expr:(&Acct-Input-Gigawords << 32) | &Acct-Input-Octets}"
- }
+ &request.Acct-Input-Octets64 = "%{expr:(&Acct-Input-Gigawords << 32) | &Acct-Input-Octets}"
}
if (!&Acct-Output-Gigawords) {
- update request {
- &Acct-Output-Octets64 := "%{%{Acct-Output-Octets}:-0}"
- }
+ &request.Acct-Output-Octets64 := "%{%{Acct-Output-Octets}:-0}"
}
else {
- update request {
- &Acct-Output-Octets64 = "%{expr:(&Acct-Output-Gigawords << 32) | &Acct-Output-Octets}"
- }
+ &request.Acct-Output-Octets64 = "%{expr:(&Acct-Output-Gigawords << 32) | &Acct-Output-Octets}"
}
}
split_username_nai {
if (&User-Name && (&User-Name =~ /${policy.nai_regexp}/)) {
- update request {
- &Stripped-User-Name := "%{1}"
- }
+ &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}" != '') {
- update request {
- &Stripped-User-Domain = "%{3}"
- }
+ &request.Stripped-User-Domain = "%{3}"
}
# If any of the expansions result in a null
#
rewrite_called_station_id {
if (&Called-Station-Id && (&Called-Station-Id =~ /^${policy.mac-addr-regexp}([^0-9a-f](.+))?$/i)) {
- update request {
- &Called-Station-Id := "%{toupper:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
- }
+ &request.Called-Station-Id := "%{toupper:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
# SSID component?
if ("%{8}") {
- update request {
- &Called-Station-SSID := "%{8}"
- }
+ &request.Called-Station-SSID := "%{8}"
}
updated
}
#
rewrite_calling_station_id {
if (&Calling-Station-Id && (&Calling-Station-Id =~ /^${policy.mac-addr-regexp}$/i)) {
- update request {
- &Calling-Station-Id := "%{toupper:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
- }
+ &request.Calling-Station-Id := "%{toupper:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
+
updated
}
else {
noop
}
}
-
# then use the "do_not_respond" policy.
#
do_not_respond {
- update reply {
- &Packet-Type := Do-Not-Respond
- }
+ &reply.Packet-Type := Do-Not-Respond
+
handled
}
# Send Access-Accept immediately
#
accept {
- update reply {
- &Packet-Type := Access-Accept
- }
+ &reply.Packet-Type := Access-Accept
+
handled
}
# Send Access-Challenge immediately
#
challenge {
- update reply {
- &Packet-Type := Access-Challenge
- }
+ &reply.Packet-Type := Access-Challenge
+
handled
}
# Send an Accounting-Response immediately
#
acct_response {
- update reply {
- &Packet-Type := Accounting-Response
- }
+ &reply.Packet-Type := Accounting-Response
+
handled
}
# include the original packet code in the reply.
#
protocol_error {
- update reply {
- &Packet-Type := Accounting-Response
- &Original-Packet-Code := "%{Packet-Type}"
- }
+ &reply.Packet-Type := Accounting-Response
+ &reply.Original-Packet-Code := "%{Packet-Type}"
+
handled
}
# Discard the packet without replying
#
discard {
- update reply {
- &Packet-Type := Do-Not-Respond
- }
+ &reply.Packet-Type := Do-Not-Respond
+
handled
}
#
cui.authorize {
if ("%(client:add_cui)" == 'yes') {
- update request {
- &Chargeable-User-Identity := 0x00
- }
+ &request.Chargeable-User-Identity := 0x00
}
}
cui.post-auth {
if (!&control.Proxy-To-Realm && &Chargeable-User-Identity && !&reply.Chargeable-User-Identity &&
(&Operator-Name || ('${policy.cui_require_operator_name}' != 'yes')) ) {
- update reply {
- &Chargeable-User-Identity = "%{sha1:${policy.cui_hash_key}%{tolower:%{User-Name}%{%{Operator-Name}:-}}}"
- }
+ &reply.Chargeable-User-Identity = %{sha1:${policy.cui_hash_key}%{tolower:%{User-Name}%{%{Operator-Name}:-}}}
}
#
#
if (&reply.Chargeable-User-Identity) {
# Force User-Name to be the User-Name from the request
- update {
- &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'))) {
- update reply {
- &Chargeable-User-Identity := "%{sha1:${policy.cui_hash_key}%{tolower:%{User-Name}%{%{outer.request.Operator-Name}:-}}}"
- }
+ &reply.Chargeable-User-Identity := %{sha1:${policy.cui_hash_key}%{tolower:%{User-Name}%{%{outer.request.Operator-Name}:-}}}
}
}
# in the DB.
#
if (!&Chargeable-User-Identity) {
- update request {
- &Chargeable-User-Identity := "%{cuisql:\
+ &request.Chargeable-User-Identity := %{cuisql:\
SELECT cui FROM cui \
WHERE clientipaddress = '%{%{Packet-Src-IPv6-Address}:-%{Packet-Src-IP-Address}}' \
AND callingstationid = '%{Calling-Station-Id}' \
- AND username = '%{User-Name}'}"
- }
+ AND username = '%{User-Name}'}
}
#
# The contents here are invented. Change them!
# Lease time is referencing the lease time set in the
# named module instance configuration
- update reply {
- &Domain-Name-Server = 127.0.0.1
- &Domain-Name-Server = 127.0.0.2
- &Subnet-Mask = 255.255.255.0
- &Router-Address = 192.0.2.1
- &IP-Address-Lease-Time = 7200
-# &IP-Address-Lease-Time = "${modules.sqlippool[dhcp_sqlippool].lease_duration}"
- &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[dhcp_sqlippool].lease_duration}"
+ &reply.Server-Identifier = &control.Server-Identifier
}
# Expire previous cache entry
#
if (&control.State) {
- update control {
- &Cache-TTL := 0
- }
+ &control.Cache-TTL := 0
+
cache_eap
- update control {
- &State !* ANY
- }
+ &control -= &State[*]
}
handled
#
remove_reply_message_if_eap {
if (&reply.EAP-Message && &reply.Reply-Message) {
- update reply {
- &Reply-Message !* ANY
- }
+ &reply -= &Reply-Message[*]
}
else {
noop
# to copy now have to be explicitly listed.
#
copy_request_to_tunnel {
- update request {
- Calling-Station-Id = &outer.request.Calling-Station-Id
- 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.
#
- update reply {
- User-Name !* ANY
- Message-Authenticator !* ANY
- EAP-Message !* ANY
- Proxy-State !* ANY
- MS-CHAP-NT-Enc-PW !* ANY
- MS-MPPE-Encryption-Types !* ANY
- MS-MPPE-Send-Key !* ANY
- MS-MPPE-Recv-Key !* ANY
- }
+ &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.
#
- update {
- &outer.session-state. += &reply
- }
+ &outer.session-state += &reply
}
if (&State) {
if (&User-Name) {
if (!&session-state.Session-State-User-Name) {
- update request {
- &Module-Failure-Message += 'No cached 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) {
- update request {
- &Module-Failure-Message += 'User-Name does not match cached session-state.Session-State-User-Name'
+ &request += {
+ &Module-Failure-Message = "User-Name does not match cached session-state.Session-State-User-Name"
}
reject
}
# e.g. "user@ site.com", or "us er", or " user", or "user "
#
if (&User-Name =~ / /) {
- update request {
- &Module-Failure-Message += 'User-Name contains whitespace'
+ &request += {
+ &Module-Failure-Message = "User-Name contains whitespace"
}
reject
}
# e.g. "user@site.com@site.com"
#
if (&User-Name =~ /@[^@]*@/ ) {
- update request {
- &Module-Failure-Message += 'Multiple @ in User-Name'
+ &request += {
+ &Module-Failure-Message = "Multiple @ in User-Name"
}
reject
}
# e.g. "user@site..com"
#
if (&User-Name =~ /\.\./ ) {
- update request {
- &Module-Failure-Message += 'User-Name contains multiple dots (e.g. user@site..com)'
+ &request += {
+ &Module-Failure-Message = "User-Name contains multiple dots (e.g. user@site..com)"
}
reject
}
# e.g. "user@site.com"
#
if ((&User-Name =~ /@/) && (&User-Name !~ /@[^.]+(\.[^.]+)+$/)) {
- update request {
- &Module-Failure-Message += 'Realm does not have at least one dot separator'
+ &request += {
+ &Module-Failure-Message = "Realm does not have at least one dot separator"
}
reject
}
# e.g. "user@site.com."
#
if (&User-Name =~ /\.$/) {
- update request {
- &Module-Failure-Message += 'Realm ends with a dot'
+ &request += {
+ &Module-Failure-Message = "Realm ends with a dot"
}
reject
}
# e.g. "user@.site.com"
#
if (&User-Name =~ /@\./) {
- update request {
- &Module-Failure-Message += 'Realm begins with a dot'
+ &request += {
+ &Module-Failure-Message = "Realm begins with a dot"
}
reject
}
- update session-state {
- &Session-State-User-Name := &User-Name
- }
+ &session-state.Session-State-User-Name := &User-Name
}
}
filter_password {
if (&User-Password && \
(&User-Password != "%{string:User-Password}")) {
- update request {
- &Tmp-String-0 := "%{string:User-Password}"
- &User-Password := "%{string:Tmp-String-0}"
- }
+ &request.Tmp-String-0 := %{string:User-Password}
+ &request.User-Password := %{string:Tmp-String-0}
}
}
# No names, reject.
#
if (!&outer.request.User-Name || !&User-Name) {
- update request {
- &Module-Failure-Message += "User-Name is required for tunneled authentication"
+ &request += {
+ &Module-Failure-Message = "User-Name is required for tunneled authentication"
}
reject
}
# Get the outer realm.
#
if (&outer.request.User-Name =~ /@([^@]+)$/) {
- update request {
- &Outer-Realm-Name = "%{1}"
- }
+ &request.Outer-Realm-Name = "%{1}"
#
# When we have an outer realm name, the user portion
# some vendors don't follow the standards.
#
if (&outer.request.User-Name !~ /^(anon|@)/) {
- update request {
- &Module-Failure-Message += "User-Name is not anonymized"
+ &request += {
+ &Module-Failure-Message = "User-Name is not anonymized"
}
reject
}
# and we'd have no idea which one was correct.
#
elsif (&outer.request.User-Name !~ /^anon/) {
- update request {
- &Module-Failure-Message += "User-Name is not anonymized"
+ &request += {
+ &Module-Failure-Message = "User-Name is not anonymized"
}
reject
}
# Get the inner realm.
#
if (&User-Name =~ /@([^@]+)$/) {
- update request {
- &Inner-Realm-Name = "%{1}"
- }
+ &request.Inner-Realm-Name = "%{1}"
#
# Note that we do EQUALITY checks for realm names.
if (&Outer-Realm-Name && \
(&Inner-Realm-Name != &Outer-Realm-Name) && \
(&Inner-Realm-Name !~ /\.%{Outer-Realm-Name}$/)) {
- update request {
- &Module-Failure-Message += "Inner realm '%{Inner-Realm-Name}' and outer realm '%{Outer-Realm-Name}' are not from the same domain."
+ &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)") {
- update request {
- &Operator-Name = "%(client:Operator-Name)"
- }
+ &request.Operator-Name = "%(client:Operator-Name)"
}
}
tacacs_set_authentication_status {
if (ok) {
- update reply {
- &Authentication-Status = Pass
- }
+ &reply.Authentication-Status = Pass
} else {
- update reply {
- &Authentication-Status = Fail
- }
+ &reply.Authentication-Status = Fail
}
}
tacacs_pap {
subrequest RADIUS.Access-Request {
- update {
- &request.User-Name := &parent.request.User-Name
- &request.User-Password := &parent.request.Data
- &control.Password.Cleartext := &parent.control.Password.Cleartext
- }
+ &request.User-Name := &parent.request.User-Name
+ &request.User-Password := &parent.request.Data
+ &control.Password.Cleartext := &parent.control.Password.Cleartext
+
pap.authorize
pap.authenticate
}
tacacs_chap {
subrequest RADIUS.Access-Request {
- update {
- &request.User-Name := &parent.request.User-Name
+ &request.User-Name := &parent.request.User-Name
+
+ #
+ # Data length N is 1 octet of ID, followed by
+ # N-17 octets of challenge, followed by 16 octets of
+ # CHAP-Password.
+ #
+ # @todo - update code to create these, so that the
+ # poor user doesn't need to.
+ #
+# &request.CHAP-Password := ...
+# &request.CHAP-Challenge := ...
+ &control.Password.Cleartext := &parent.control.Password.Cleartext
- #
- # Data length N is 1 octet of ID, followed by
- # N-17 octets of challenge, followed by 16 octets of
- # CHAP-Password.
- #
- # @todo - update code to create these, so that the
- # poor user doesn't need to.
- #
-# &request.CHAP-Password := ...
-# &request.CHAP-Challenge := ...
- &control.Password.Cleartext := &parent.control.Password.Cleartext
- }
chap.authenticate
}
tacacs_mschap {
subrequest RADIUS.Access-Request {
- update {
- &request.User-Name := &parent.request.User-Name
+ &request.User-Name := &parent.request.User-Name
+
+ #
+ # Data length N is 1 octet of ID, followed by
+ # N-49 octets of challenge, followed by 49 octets of
+ # MS-CHAP stuff.
+ #
+ # @todo - update code to create these, so that the
+ # poor user doesn't need to.
+ #
+# &request.MS-CHAP-Challenge := ...
+# &request.MS-CHAP-Response := ...
+ &control.Password.Cleartext := &parent.control.Password.Cleartext
- #
- # Data length N is 1 octet of ID, followed by
- # N-49 octets of challenge, followed by 49 octets of
- # MS-CHAP stuff.
- #
- # @todo - update code to create these, so that the
- # poor user doesn't need to.
- #
-# &request.MS-CHAP-Challenge := ...
-# &request.MS-CHAP-Response := ...
- &control.Password.Cleartext := &parent.control.Password.Cleartext
- }
chap.authenticate
}
#
# Sets Tmp-uint64-0 with the current epoch time in ms
time_current_ms {
- update request {
- Tmp-uint64-0 := "%{expr:(%c*1000) + (%C/1000)}"
- }
+ &request.Tmp-uint64-0 := %{expr:(%c*1000) + (%C/1000)}
}
# Returns elapsed time in ms since time_current_ms
#
# Sets Tmp-uint64-1 with number of milliseconds
time_elapsed_ms {
- update request {
- Tmp-uint64-1 := "%{expr:(%c*1000) + (%C/1000) - %{Tmp-uint64-0}}"
- }
+ &request.Tmp-uint64-1 := %{expr:(%c*1000) + (%C/1000) - %{Tmp-uint64-0}}
}
# Handles the Expiration attribute
}
elsif (!&reply.Session-Timeout || (&Session-Timeout > "%{expr:%{Expiration} - %l}")) {
- update reply {
- &Session-Timeout := "%{expr:%{Expiration} - %l}"
- }
+ &reply.Session-Timeout := %{expr:%{Expiration} - %l}
}
}
}
broadsoft-decode {
foreach &BroadSoft-Attr-255 {
if ("%{Foreach-Variable-0}" =~ /^([0-9]+)=(.*)$/) {
- update request {
-# Broadsoft-Attr-255 -= "%{Foreach-Variable-0}"
- "BroadSoft-Attr-%{1}" += "%{2}"
+# &request.Broadsoft-Attr-255 -= "%{Foreach-Variable-0}"
+ "&request.BroadSoft-Attr-%{1}" += "%{2}"
}
}
}
recv Access-Request {
radius
if (ok) {
- update reply {
- &Packet-Type := Access-Accept
- }
+ &reply.Packet-Type := Access-Accept
}
}
send Access-Accept {