]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Move policy.conf stanzas into individual configuration files 69/head
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 17 Jul 2012 20:43:16 +0000 (21:43 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 18 Jul 2012 07:55:01 +0000 (08:55 +0100)
.gitignore
raddb/Makefile
raddb/policy.conf [deleted file]
raddb/policy.d/accounting [new file with mode: 0644]
raddb/policy.d/canonicalization [new file with mode: 0644]
raddb/policy.d/control [new file with mode: 0644]
raddb/policy.d/cui [new file with mode: 0644]
raddb/policy.d/dhcp [new file with mode: 0644]
raddb/policy.d/filter [new file with mode: 0644]
raddb/radiusd.conf.in

index 5df228454cdc4ea032484df14efb8dd20ad1c4a5..3d2c460424b5c3de0448770153ab9ec8d9f8d682 100644 (file)
@@ -1,7 +1,6 @@
 *~
 *.o
 *.a
-*.d
 *.lo
 *.loT
 *.la
index 6e81ce253331e5d3235b57563e1443b7cb336cd0..23ecf371769b3257b6f99cf8c23955c3e6fe28c3 100644 (file)
@@ -13,7 +13,7 @@ FILES = acct_users attrs attrs.access_reject attrs.accounting_response        \
        attrs.pre-proxy clients.conf dictionary templates.conf  \
        experimental.conf hints huntgroups ldap.attrmap                 \
        policy.txt preproxy_users proxy.conf radiusd.conf trigger.conf  \
-       users policy.conf attrs.access_challenge README
+       users attrs.access_challenge README.rst
 
 DEFAULT_SITES = default inner-tunnel
 
@@ -58,8 +58,9 @@ install:
        $(INSTALL) -d -m 750    $(R)$(raddbdir)/sites-enabled
        $(INSTALL) -d -m 750    $(R)$(raddbdir)/mods-available
        $(INSTALL) -d -m 750    $(R)$(raddbdir)/mods-enabled
+       $(INSTALL) -d -m 750    $(R)$(raddbdir)/policy.d
        @echo "Creating/updating files in $(R)$(raddbdir)"; \
-       for i in $(FILES) `find sites-available/ mods-available/ -type f -print | sed 's/.*~//;s/.*#.*//' `; do \
+       for i in $(FILES) `find sites-available/ mods-available/ policy.d/ -type f -print | sed 's/.*~//;s/.*#.*//' `; do \
                [ ! -f $(R)$(raddbdir)/$$i ] && $(INSTALL) -m 640 $$i $(R)$(raddbdir)/$$i; \
                if [ "`find $$i -newer $(R)$(raddbdir)/$$i`" ]; then \
                        echo "** $(R)$(raddbdir)/$$i"; \
diff --git a/raddb/policy.conf b/raddb/policy.conf
deleted file mode 100644 (file)
index 7a935b5..0000000
+++ /dev/null
@@ -1,419 +0,0 @@
-# -*- text -*-
-##
-## policy.conf -- FreeRADIUS server configuration file.
-##
-##     http://www.freeradius.org/
-##     $Id$
-##
-
-#
-#  Policies are virtual modules, similar to those defined in the
-#  "instantate" section of radiusd.conf.
-#
-#  Defining a policy here means that it can be referenced in multiple
-#  places as a *name*, rather than as a series of conditions to match,
-#  and actions to take.
-#
-#  Policies are something like subroutines in a normal language, but
-#  they cannot be called recursively. They MUST be defined in order.
-#  If policy A calls policy B, then B MUST be defined before A.
-#
-policy {
-       # We check for this prefix to determine whether the class
-       # value was generated by this server.  It should be changed
-       # so that it is globally unique.
-       class_value_prefix = 'ai:'
-
-       #
-       #       Overload the default acct_unique module, it's not
-       #       smart enough.
-       #
-       acct_unique {
-               #
-               #  If we have a class attribute in the format
-               #  'auth_id:[0-9a-f]{32}' it'll have a local value
-               #  (defined by insert_acct_class), this ensures
-               #  uniqueness and suitability.
-               #
-               #  We could just use the Class attribute as
-               #  Acct-Unique-Session-Id, but this may cause problems
-               #  with NAS that carry Class values across between
-               #  multiple linked sessions.  So we rehash class with
-               #  Acct-Session-ID to provide a truely unique session
-               #  identifier.
-               #
-               #  Using a Class/Session-ID combination is more robust
-               #  than using elements in the Accounting-Request,
-               #  which may be subject to change, such as
-               #  NAS-IP-Address, Client-IP-Address and
-               #  NAS-Port-ID/NAS-Port.
-               #
-               #  This policy should ensure that session data is not
-               #  affected if NAS IP addresses change, or the client
-               #  roams to a different 'port' whilst maintaining its
-               #  initial authentication session (Common in a
-               #  wireless environment).
-               #        
-               if("%{string:Class}" =~ /${policy.class_value_prefix}([0-9a-f]{32})/i) {
-                       update request {
-                               Acct-Unique-Session-Id := "%{md5:%{1}%{Acct-Session-ID}}"
-                       }
-               }        
-
-               #
-               #  Not All devices respect RFC 2865 when dealing with
-               #  the class attribute, so be prepared to use the
-               #  older style of hashing scheme if a class attribute
-               #  is not included
-               #
-               else {
-                       update request {
-                               Acct-Unique-Session-Id := "%{md5:%{User-Name}%{Acct-Session-ID}%{NAS-IP-Address}%{NAS-Port-ID}%{NAS-Port}}" 
-                        }       
-               }        
-       }        
-
-       #
-       #       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}%{NAS-IP-Address}%{Calling-Station-ID}%{User-Name}}"
-               }
-       }
-
-       #
-       #       Forbid all EAP types.  Enable this by putting "forbid_eap"
-       #       into the "authorize" section.
-       #
-       forbid_eap {
-               if (EAP-Message) {
-                       reject
-               }
-       }
-       
-       #
-       #       Forbid all non-EAP types outside of an EAP tunnel.
-       #
-       permit_only_eap {
-               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:EAP-Message}") {
-                               reject
-                       }
-               }
-       }
-
-       #
-       #       Remove Reply-Message from response if were doing EAP
-       #
-       #  Be RFC 3579 2.6.5 compliant - EAP-Message and Reply-Message should
-       #  not be present in the same response.
-       #
-       remove_reply_message_if_eap {
-               if(reply:EAP-Message && reply:Reply-Message) {
-                       update reply {
-                               Reply-Message !* ANY
-                       }
-               }
-               else {
-                       noop
-               }
-       }
-
-       #
-       #       Split User-Name in NAI format (RFC 4282) into components
-       #
-       #  This policy writes the Username and Domain portions of the
-       #  NAI into the Stripped-User-Name and Stripped-User-Domain
-       #  attributes.
-       #
-       #  The regular expression to do this is not strictly compliant
-       #  with the standard, but it is not possible to write a
-       #  compliant regexp without perl style regular expressions (or
-       #  at least not a legible one).
-       #
-       nai_regexp = "^([^@]*)(@([-[:alnum:]]+\\.[-[:alnum:].]+))?$"    
-
-       split_username_nai {
-               if(User-Name =~ /${policy.nai_regexp}/){
-                       update request {
-                               Stripped-User-Name := "%{1}"
-                               Stripped-User-Domain = "%{3}"
-                       }
-
-                       # If any of the expansions result in a null
-                       # string, the update section may return
-                       # something other than updated...
-                       updated
-               }
-               else {
-                       noop
-               }
-       }
-
-       #       
-       #  If called in post-proxy we modify the proxy-reply message
-       #
-       split_username_nai.post-proxy { 
-               if(proxy-reply:User-Name =~ /${policy.nai_regexp}/){
-                       update proxy-reply {
-                               Stripped-User-Name := "%{1}"
-                               Stripped-User-Domain = "%{3}"
-                       }
-                       updated
-               }
-               else {
-                       noop
-               }
-       }
-
-       #
-       #       Example of forbidding all attempts to login via
-       #       realms.
-       #
-       deny_realms {
-               if (User-Name =~ /@|\\/) {
-                       reject
-               }
-       }
-
-       #
-       #  If you want the server to pretend that it is dead,
-       #  then use the "do_not_respond" policy.
-       #
-       do_not_respond {
-               update control {
-                       Response-Packet-Type := Do-Not-Respond
-               }
-
-               handled
-       }
-
-       #
-       #       Filter the username
-       #
-       #  Force some sanity on User-Name. This helps to avoid issues
-       #  issues where the back-end database is "forgiving" about
-       #  what constitutes a user name.
-       #
-       filter_username {
-               #
-               #  reject mixed case
-               #  e.g. "UseRNaMe"
-               #
-               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 =~ / /) {
-                       update reply {
-                               Reply-Message += "Rejected: Username contains whitespace"
-                       }
-                       reject
-               }
-
-               #
-               #  reject Multiple @'s
-               #  e.g. "user@site.com@site.com"
-               #
-               if(User-Name =~ /@(.+)?@/i ) {
-                       update reply {
-                               Reply-Message += "Rejected: Multiple @ in username"
-                       }
-                       reject
-               }
-               
-               #
-               #  reject double dots
-               #  e.g. "user@site..com"
-               #
-               if (User-Name =~ /\\.\\./ ) {
-                       update reply {
-                               Reply-Message += "Rejected: Username comtains ..s"
-                       }
-                       reject
-               }
-               
-               #
-               #  must have at least 1 string-dot-string after @ 
-               #  e.g. "user@site.com"
-               #
-               if (User-Name !~ /@(.+)\\.(.+)$/)  {
-                       update reply {
-                               Reply-Message += "Rejected: Realm does not have at least one dot seperator"
-                       }
-                       reject
-               }
-
-               #
-               #  Realm ends with a dot
-               #  e.g. "user@site.com."
-               #
-                if (User-Name =~ /\\.$/)  {
-                        update reply {
-                                Reply-Message += "Rejected: Realm ends with a dot"
-                        }
-                        reject
-                }
-
-               #
-                #  Realm begins with a dot
-               #  e.g. "user@.site.com"
-                #
-                if (User-Name =~ /@\\./)  {
-                        update reply {
-                                Reply-Message += "Rejected: Realm begins with a dot"
-                        }
-                        reject
-                }
-       }
-
-       #       
-       #  The following policies are for the Chargeable-User-Identity
-       #  (CUI) configuration.
-       #
-       #  The policies below can be called as just 'cui' (not
-       #  cui.authorize etc..)  from the various config sections.
-       #
-
-       #
-       #  The client indicates it can do CUI by sending a CUI attribute        
-       #  containing one zero byte
-       #
-       cui.authorize {
-               update request {
-                       Chargeable-User-Identity:='\\000'
-               }
-       }
-
-       #
-       #  Add a CUI attribute based on the User-Name, and a secret key
-       #  known only to this server.
-       #
-       cui.post-auth {
-               if (FreeRadius-Proxied-To == 127.0.0.1) {
-                       if (outer.request:Chargeable-User-Identity) {
-                               update outer.reply {
-                                       Chargeable-User-Identity:="%{md5:%{config:cui_hash_key}%{User-Name}}"
-                               }
-                       }
-               }
-               else {
-                       if (Chargeable-User-Identity) {
-                               update reply {
-                                       Chargeable-User-Identity="%{md5:%{config:cui_hash_key}%{User-Name}}"
-                               }
-                       }
-               }
-       }
-
-
-       #
-       #  If we had stored a CUI for the User, add it to the request.
-       #
-       cui.accounting {
-               #
-               #  If the CUI isn't in the packet, see if we can find it
-               #  in the DB.
-               #
-               if (!Chargeable-User-Identity) {
-                       update request {
-                               Chargeable-User-Identity := "%{cui: SELECT cui FROM cui WHERE clientipaddress = '%{%{Packet-Src-IPv6-Address}:-%{Packet-Src-IP-Address}}' AND callingstationid = '%{Calling-Station-Id}' AND username = '%{User-Name}'}"
-                       }
-               }
-
-               #
-               #  If it exists now, then write out when we last saw
-               #  this CUI.
-               #
-               if (Chargeable-User-Identity && (Chargeable-User-Identity != "")) {
-                       cui
-               }
-       }
-
-       #
-       #  If there is a CUI attribute in the reply, add it to the DB.
-       #
-       cui_updatedb {
-               if (reply:Chargeable-User-Identity) {
-                       cui
-               }
-       }
-
-       #
-       #  Normalize the MAC Addresses in the Calling/Called-Station-Id
-       #
-       mac-addr-regexp = ([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})
-       
-       #
-       #  Add "rewrite_called_station_id" in the "authorize" and
-       #  "preacct" sections.
-       #
-       rewrite_called_station_id {
-               if(Called-Station-Id =~ /^${policy.mac-addr-regexp}(:(.+))?$/i) {
-                       update request {
-                               Called-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
-                       }
-
-                       # SSID component?
-                       if ("%{8}") {
-                               update request {
-                                       Called-Station-SSID := "%{8}"
-                               }
-                       }
-                       updated
-               }
-               else {
-                       noop
-               }
-       }
-
-       #
-       #  Add "rewrite_calling_station_id" in the "authorize" and
-       #  "preacct" sections.
-       #
-       rewrite_calling_station_id {
-               if(Calling-Station-Id =~ /^${policy.mac-addr-regexp}$/i) {
-                       update request {
-                               Calling-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
-                       }
-                       updated
-               }
-               else {
-                       noop
-               }
-       }
-
-       #  Assign compatibility data to request for sqlippool
-       dhcp_sqlippool.post-auth {
-
-
-               #  Do some minor hacks to the request so that it looks
-               #  like a RADIUS request to the SQL IP Pool module.
-               update request {
-                       User-Name = "DHCP-%{DHCP-Client-Hardware-Address}"
-                       Calling-Station-Id = "%{DHCP-Client-Hardware-Address}"
-                       NAS-IP-Address = "%{%{DHCP-Gateway-IP-Address}:-127.0.0.1}"
-                       Acct-Status-Type = Start
-               }
-
-               #  Call the actual module
-               dhcp_sqlippool
-
-               #  Convert Framed-IP-Address to DHCP, but only if we
-               #  actually allocated an address.
-               if (ok) {
-                       update reply {
-                               DHCP-Your-IP-Address = "%{reply:Framed-IP-Address}"
-                       }
-               }
-       }
-}
diff --git a/raddb/policy.d/accounting b/raddb/policy.d/accounting
new file mode 100644 (file)
index 0000000..02f1cc5
--- /dev/null
@@ -0,0 +1,63 @@
+# We check for this prefix to determine whether the class
+# value was generated by this server.  It should be changed
+# so that it is globally unique.
+class_value_prefix = 'ai:'
+
+#
+#      Overload the default acct_unique module, it's not
+#      smart enough.
+#
+acct_unique {
+       #
+       #  If we have a class attribute in the format
+       #  'auth_id:[0-9a-f]{32}' it'll have a local value
+       #  (defined by insert_acct_class), this ensures
+       #  uniqueness and suitability.
+       #
+       #  We could just use the Class attribute as
+       #  Acct-Unique-Session-Id, but this may cause problems
+       #  with NAS that carry Class values across between
+       #  multiple linked sessions.  So we rehash class with
+       #  Acct-Session-ID to provide a truely unique session
+       #  identifier.
+       #
+       #  Using a Class/Session-ID combination is more robust
+       #  than using elements in the Accounting-Request,
+       #  which may be subject to change, such as
+       #  NAS-IP-Address, Client-IP-Address and
+       #  NAS-Port-ID/NAS-Port.
+       #
+       #  This policy should ensure that session data is not
+       #  affected if NAS IP addresses change, or the client
+       #  roams to a different 'port' whilst maintaining its
+       #  initial authentication session (Common in a
+       #  wireless environment).
+       #        
+       if("%{string:Class}" =~ /${policy.class_value_prefix}([0-9a-f]{32})/i) {
+               update request {
+                       Acct-Unique-Session-Id := "%{md5:%{1}%{Acct-Session-ID}}"
+               }
+       }        
+
+       #
+       #  Not All devices respect RFC 2865 when dealing with
+       #  the class attribute, so be prepared to use the
+       #  older style of hashing scheme if a class attribute
+       #  is not included
+       #
+       else {
+               update request {
+                       Acct-Unique-Session-Id := "%{md5:%{User-Name}%{Acct-Session-ID}%{NAS-IP-Address}%{NAS-Port-ID}%{NAS-Port}}" 
+                }       
+       }        
+}       
+
+#
+#      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}%{NAS-IP-Address}%{Calling-Station-ID}%{User-Name}}"
+       }
+}
+
diff --git a/raddb/policy.d/canonicalization b/raddb/policy.d/canonicalization
new file mode 100644 (file)
index 0000000..f9666c1
--- /dev/null
@@ -0,0 +1,91 @@
+#
+#      Split User-Name in NAI format (RFC 4282) into components
+#
+#  This policy writes the Username and Domain portions of the
+#  NAI into the Stripped-User-Name and Stripped-User-Domain
+#  attributes.
+#
+#  The regular expression to do this is not strictly compliant
+#  with the standard, but it is not possible to write a
+#  compliant regexp without perl style regular expressions (or
+#  at least not a legible one).
+#
+nai_regexp = "^([^@]*)(@([-[:alnum:]]+\\.[-[:alnum:].]+))?$"   
+
+split_username_nai {
+       if(User-Name =~ /${policy.nai_regexp}/){
+               update request {
+                       Stripped-User-Name := "%{1}"
+                       Stripped-User-Domain = "%{3}"
+               }
+
+               # If any of the expansions result in a null
+               # string, the update section may return
+               # something other than updated...
+               updated
+       }
+       else {
+               noop
+       }
+}
+
+#      
+#  If called in post-proxy we modify the proxy-reply message
+#
+split_username_nai.post-proxy { 
+       if(proxy-reply:User-Name =~ /${policy.nai_regexp}/){
+               update proxy-reply {
+                       Stripped-User-Name := "%{1}"
+                       Stripped-User-Domain = "%{3}"
+               }
+               updated
+       }
+       else {
+               noop
+       }
+}
+
+#
+#  Normalize the MAC Addresses in the Calling/Called-Station-Id
+#
+mac-addr-regexp = ([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})
+
+#
+#  Add "rewrite_called_station_id" in the "authorize" and
+#  "preacct" sections.
+#
+rewrite_called_station_id {
+       if(Called-Station-Id =~ /^${policy.mac-addr-regexp}(:(.+))?$/i) {
+               update request {
+                       Called-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
+               }
+
+               # SSID component?
+               if ("%{8}") {
+                       update request {
+                               Called-Station-SSID := "%{8}"
+                       }
+               }
+               updated
+       }
+       else {
+               noop
+       }
+}
+
+#
+#  Add "rewrite_calling_station_id" in the "authorize" and
+#  "preacct" sections.
+#
+rewrite_calling_station_id {
+       if(Calling-Station-Id =~ /^${policy.mac-addr-regexp}$/i) {
+               update request {
+                       Calling-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
+               }
+               updated
+       }
+       else {
+               noop
+       }
+}
+
diff --git a/raddb/policy.d/control b/raddb/policy.d/control
new file mode 100644 (file)
index 0000000..cbf23af
--- /dev/null
@@ -0,0 +1,12 @@
+#
+#  If you want the server to pretend that it is dead,
+#  then use the "do_not_respond" policy.
+#
+do_not_respond {
+       update control {
+               Response-Packet-Type := Do-Not-Respond
+       }
+
+       handled
+}
+
diff --git a/raddb/policy.d/cui b/raddb/policy.d/cui
new file mode 100644 (file)
index 0000000..52c4de6
--- /dev/null
@@ -0,0 +1,72 @@
+#      
+#  The following policies are for the Chargeable-User-Identity
+#  (CUI) configuration.
+#
+#  The policies below can be called as just 'cui' (not
+#  cui.authorize etc..)  from the various config sections.
+#
+
+#
+#  The client indicates it can do CUI by sending a CUI attribute       
+#  containing one zero byte
+#
+cui.authorize {
+       update request {
+               Chargeable-User-Identity:='\\000'
+       }
+}
+
+#
+#  Add a CUI attribute based on the User-Name, and a secret key
+#  known only to this server.
+#
+cui.post-auth {
+       if (FreeRadius-Proxied-To == 127.0.0.1) {
+               if (outer.request:Chargeable-User-Identity) {
+                       update outer.reply {
+                               Chargeable-User-Identity:="%{md5:%{config:cui_hash_key}%{User-Name}}"
+                       }
+               }
+       }
+       else {
+               if (Chargeable-User-Identity) {
+                       update reply {
+                               Chargeable-User-Identity="%{md5:%{config:cui_hash_key}%{User-Name}}"
+                       }
+               }
+       }
+}
+
+
+#
+#  If we had stored a CUI for the User, add it to the request.
+#
+cui.accounting {
+       #
+       #  If the CUI isn't in the packet, see if we can find it
+       #  in the DB.
+       #
+       if (!Chargeable-User-Identity) {
+               update request {
+                       Chargeable-User-Identity := "%{cui: SELECT cui FROM cui WHERE clientipaddress = '%{%{Packet-Src-IPv6-Address}:-%{Packet-Src-IP-Address}}' AND callingstationid = '%{Calling-Station-Id}' AND username = '%{User-Name}'}"
+               }
+       }
+
+       #
+       #  If it exists now, then write out when we last saw
+       #  this CUI.
+       #
+       if (Chargeable-User-Identity && (Chargeable-User-Identity != "")) {
+               cui
+       }
+}
+
+#
+#  If there is a CUI attribute in the reply, add it to the DB.
+#
+cui_updatedb {
+       if (reply:Chargeable-User-Identity) {
+               cui
+       }
+}
+
diff --git a/raddb/policy.d/dhcp b/raddb/policy.d/dhcp
new file mode 100644 (file)
index 0000000..4396f06
--- /dev/null
@@ -0,0 +1,25 @@
+#  Assign compatibility data to request for sqlippool
+dhcp_sqlippool.post-auth {
+
+
+       #  Do some minor hacks to the request so that it looks
+       #  like a RADIUS request to the SQL IP Pool module.
+       update request {
+               User-Name = "DHCP-%{DHCP-Client-Hardware-Address}"
+               Calling-Station-Id = "%{DHCP-Client-Hardware-Address}"
+               NAS-IP-Address = "%{%{DHCP-Gateway-IP-Address}:-127.0.0.1}"
+               Acct-Status-Type = Start
+       }
+
+       #  Call the actual module
+       dhcp_sqlippool
+
+       #  Convert Framed-IP-Address to DHCP, but only if we
+       #  actually allocated an address.
+       if (ok) {
+               update reply {
+                       DHCP-Your-IP-Address = "%{reply:Framed-IP-Address}"
+               }
+       }
+}
+
diff --git a/raddb/policy.d/filter b/raddb/policy.d/filter
new file mode 100644 (file)
index 0000000..c3b48fa
--- /dev/null
@@ -0,0 +1,135 @@
+#
+#      Forbid all EAP types.  Enable this by putting "forbid_eap"
+#      into the "authorize" section.
+#
+forbid_eap {
+       if (EAP-Message) {
+               reject
+       }
+}
+
+#
+#      Forbid all non-EAP types outside of an EAP tunnel.
+#
+permit_only_eap {
+       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:EAP-Message}") {
+                       reject
+               }
+       }
+}
+
+#
+#      Remove Reply-Message from response if were doing EAP
+#
+#  Be RFC 3579 2.6.5 compliant - EAP-Message and Reply-Message should
+#  not be present in the same response.
+#
+remove_reply_message_if_eap {
+       if(reply:EAP-Message && reply:Reply-Message) {
+               update reply {
+                       Reply-Message !* ANY
+               }
+       }
+       else {
+               noop
+       }
+}
+
+#
+#      Example of forbidding all attempts to login via
+#      realms.
+#
+deny_realms {
+       if (User-Name =~ /@|\\/) {
+               reject
+       }
+}
+
+#
+#      Filter the username
+#
+#  Force some sanity on User-Name. This helps to avoid issues
+#  issues where the back-end database is "forgiving" about
+#  what constitutes a user name.
+#
+filter_username {
+       #
+       #  reject mixed case
+       #  e.g. "UseRNaMe"
+       #
+       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 =~ / /) {
+               update reply {
+                       Reply-Message += "Rejected: Username contains whitespace"
+               }
+               reject
+       }
+
+       #
+       #  reject Multiple @'s
+       #  e.g. "user@site.com@site.com"
+       #
+       if(User-Name =~ /@(.+)?@/i ) {
+               update reply {
+                       Reply-Message += "Rejected: Multiple @ in username"
+               }
+               reject
+       }
+       
+       #
+       #  reject double dots
+       #  e.g. "user@site..com"
+       #
+       if (User-Name =~ /\\.\\./ ) {
+               update reply {
+                       Reply-Message += "Rejected: Username comtains ..s"
+               }
+               reject
+       }
+       
+       #
+       #  must have at least 1 string-dot-string after @ 
+       #  e.g. "user@site.com"
+       #
+       if (User-Name !~ /@(.+)\\.(.+)$/)  {
+               update reply {
+                       Reply-Message += "Rejected: Realm does not have at least one dot seperator"
+               }
+               reject
+       }
+
+       #
+       #  Realm ends with a dot
+       #  e.g. "user@site.com."
+       #
+                       if (User-Name =~ /\\.$/)  {
+                                       update reply {
+                                                       Reply-Message += "Rejected: Realm ends with a dot"
+                                       }
+                                       reject
+                       }
+
+       #
+                       #  Realm begins with a dot
+       #  e.g. "user@.site.com"
+                       #
+                       if (User-Name =~ /@\\./)  {
+                                       update reply {
+                                                       Reply-Message += "Rejected: Realm begins with a dot"
+                                       }
+                                       reject
+                       }
+}
+
index 584fc34856ef1cb1ce772bbd41ab99c0040ae72c..6e68f3a979a528e00899f238468b9e00f5ee1b9c 100644 (file)
@@ -822,12 +822,21 @@ instantiate {
 
 ######################################################################
 #
-#      Policies that can be applied in multiple places are listed
-#      globally.  That way, they can be defined once, and referred
-#      to multiple times.
+#  Policies are virtual modules, similar to those defined in the
+#  "instantate" section above.
+#
+#  Defining a policy in one of the policy.d files means that it can be
+#  referenced in multiple places as a *name*, rather than as a series of
+#  conditions to match, and actions to take.
+#
+#  Policies are something like subroutines in a normal language, but
+#  they cannot be called recursively. They MUST be defined in order.
+#  If policy A calls policy B, then B MUST be defined before A.
 #
 ######################################################################
-$INCLUDE policy.conf
+policy {
+       $INCLUDE policy.d/
+}
 
 ######################################################################
 #