#
#	Handle Requests from a WiMAX ASN-GW
#
#	Overall requirements for a WiMAX ASN are fairly simple. Outer tunnel
# 	will use either EAP-TLS, EAP-TTLS, or EAP-AKA. Inner tunnel may use 
#	different methods.
#
#	The post-auth section is most important as this is where EAP-TLS 
#	authorization is handled and where required WiMAX mobility keys are 
#	calcualted and cached.
#
#	Ben Wiechman - Wisper Wireless Solutions, LLC
#	February 2010
#

server wimax-asn {

	#  Authorization. First preprocess (hints and huntgroups files),
	#  then realms, and finally look in the "users" file.
	#
	#  The order of the realm modules will determine the order that
	#  we try to find a matching realm.
	#
	#  Make *sure* that 'preprocess' comes before any realm if you 
	#  need to setup hints for the remote radius server
	authorize {
		init_wimax
		verify_wimax_asn

		#  Handle special EAP Cases
#		update control {
#			Allow-Session-Resumption = No
#			EAP-TLS-Require-Client-Cert = Yes
#		}

		#
		#  Handle WiMAX Authorize-Only requests separately as the 
		#  requirements are a bit different
		#  Note: the home server can be a local virtual server or can 
		#  be hosted on another physical device 
#		if( Service-Type == Authorize-Only ) {
# 			update control {
#				Home-Server-Pool := "Authorize-Only-Pool"
#			}
#		}

                #
                #  Username not available to properly update EAP session cache.
		#  Chages were made to the code in v2.1.8 to sidestep an OpenSSL
		#  bug. Test in future releases to see if this is still required.
                update reply {
                        User-Name = "%{User-Name}"
                }

		#
		#  The preprocess module takes care of sanitizing some bizarre
		#  attributes in the request, and turning them into attributes
		#  which are more standard.
		#
		#  It takes care of processing the 'raddb/hints' and the
		#  'raddb/huntgroups' files. If huntgroups are not used this 
		#  can be disabled.
		preprocess

		#
		#  If you want to have a log of authentication requests,
		#  un-comment the following line, and the 'detail auth_log'
		#  section, above.
#		auth_log

		#
		#  The WiMAX specification says that the Calling-Station-Id
		#  is 6 octets of the MAC.  This definition conflicts with
		#  RFC 3580, and all common RADIUS practices.  Un-commenting
		#  the "wimax" module here means that it will fix the
		#  Calling-Station-Id attribute to the normal format as
		#  specified in RFC 3580 Section 3.21
		wimax

		#
		#  Look for IPASS style 'realm/', and if not found, look for
		#  '@realm', and decide whether or not to proxy, based on
		#  that.
#		IPASS

		#
		#  If you are using multiple kinds of realms, you probably
		#  want to set "ignore_null = yes" for all of them.
		#  Otherwise, when the first style of realm doesn't match,
		#  the other styles won't be checked.
		#
		suffix
#		ntdomain

		#
		#  This module takes care of EAP-MD5, EAP-TLS, and EAP-LEAP
		#  authentication.
		#
		#  It also sets the EAP-Type attribute in the request
		#  attribute list to the EAP type from the packet.
		#
		#  As of 2.0, the EAP module returns "ok" in the authorize stage
		#  for TTLS and PEAP.  In 1.x, it never returned "ok" here, so
		#  this change is compatible with older configurations.
		#
		#  The example below uses module failover to avoid querying all
		#  of the following modules if the EAP module returns "ok".
		#  Therefore, your LDAP and/or SQL servers will not be queried
		#  for the many packets that go back and forth to set up TTLS
		#  or PEAP.  The load on those servers will therefore be reduced.
		#
		eap {
			ok = return
		}

		#
		#  If using EAP-TLS authorization functions may be performed here

		#
		#  Enforce daily limits on time spent logged in.
#		daily

		#
		# Use the checkval module
#		checkval

#		expiration
#		logintime

		#
		#  If "status_server = yes", then Status-Server messages are passed
		#  through the following section, and ONLY the following section.
		#  This permits you to do DB queries, for example.  If the modules
		#  listed here return "fail", then NO response is sent.
		#
#		Autz-Type Status-Server {
#	
#		}
	}


	#  Authentication.
	#
	#  Note that Auth-Type := Accept will NOT work with EAP.
	#
	#  Please do not put "unlang" configurations into the "authenticate"
	#  section.  Put them in the "post-auth" section instead.  That's what
	#  the post-auth section is for.
	#
	authenticate {

		#
		#  Allow EAP authentication.
		eap

		#
		#  The older configurations sent a number of attributes in
		#  Access-Challenge packets, which wasn't strictly correct.
		#  If you want to filter out these attributes, uncomment
		#  the following lines.
		#
#		Auth-Type eap {
#			eap {
#				handled = 1  
#			}
#			if (handled && (Response-Packet-Type == Access-Challenge)) {
#				attr_filter.access_challenge.post_auth
#				handled  # override the "updated" code from attr_filter
#			}
#		}
	}


	#
	#  Pre-accounting.  Decide which accounting type to use.
	#
	preacct {
		preprocess

 		#
		# Session start times are *implied* in RADIUS.
		# The NAS never sends a "start time". Instead, it sends
		# a start packet, *possibly* with an Acct-Delay-Time.
		# The server is supposed to conclude that the start time
		# was "Acct-Delay-Time" seconds in the past.
		#
		# The code below creates an explicit start time, which can
		# then be used in other modules.
		#
		# The start time is: NOW - delay - session_length
		#
	
#		update request {
#			FreeRADIUS-Acct-Session-Start-Time = "%{expr: %l - %{%{Acct-Session-Time}:-0} - %{%{Acct-Delay-Time}:-0}}"
#		}

		#
		#  Ensure that we have a semi-unique identifier for every
		#  request, and many NAS boxes are broken.
		acct_unique

		#
		#  Look for IPASS-style 'realm/', and if not found, look for
		#  '@realm', and decide whether or not to proxy, based on
		#  that.
		#
		#  Accounting requests are generally proxied to the same
		#  home server as authentication requests.
#		IPASS
#		suffix
#		ntdomain

		#
		#  Fix WiMAX Calling-Station-Id
		wimax

		#
		#  Read the 'acct_users' file
#		files
	}

	#
	#  Accounting.  Log the accounting data.
	#
	#  For WiMAX we do two things here. 
	#  1) Handle accounting information
	#  2) Handle some WiMAX cache cleanup issues. The bulk of the 
	#     session cache cleanup is handled by a cron job.
	#
	accounting {
		#
		#  Create a 'detail'ed log of the packets.
		#  Note that accounting requests which are proxied
		#  are also logged in the detail file.
		detail	

#		daily

		#  Update the wtmp file
		#
		#  If you don't use "radlast", you can delete this line.
		unix

		#
		#  For Simultaneous-Use tracking.
		#
		#  Due to packet losses in the network, the data here
		#  may be incorrect.  There is little we can do about it.
		radutmp
#		sradutmp

		#  Return an address to the IP Pool when we see a stop record.
#		main_pool

		#
		#  Log traffic to an SQL database.
		#
		#  See "Accounting queries" in sql.conf
#		sql

		#
		# If you receive stop packets with zero session length,
		# they will NOT be logged in the database. The SQL module
		# will print a message (only in debugging mode), and will
		# return "noop".
		#
		# You can ignore these packets by uncommenting the following
		# three lines. Otherwise, the server will not respond to the
		# accounting request, and the NAS will retransmit.
		#
# 		if (noop) {
# 			ok
# 		}

		#
		#  Instead of sending the query to the SQL server,
		#  write it into a log file.
		#
#		sql_log

		#  Cisco VoIP specific bulk accounting
#		pgsql-voip

		#  Filter attributes from the accounting response.
		attr_filter.accounting_response

		#
		#  See "Autz-Type Status-Server" for how this works.
		#
#		Acct-Type Status-Server {
#
#		}
	}


	#  Session database, used for checking Simultaneous-Use. Either the radutmp 
	#  or rlm_sql module can handle this.
	#  The rlm_sql module is *much* faster
	session {
		radutmp

		#
		#  See "Simultaneous Use Checking Queries" in sql.conf
#		sql
	}


	#  Post-Authentication
	#  Once we KNOW that the user has been authenticated, there are
	#  additional steps we can take.
	post-auth {
		#  Get an address from the IP Pool.
#		main_pool

		#
                #  Process authorization for EAP-TLS here to prevent the
                #  authorization sql queries being executed for every
                #  request sent while handling the EAP tunnel creation and
                #  authentication. If using EAP-TTLS authorization will be
                #  handled by the inner tunnel.
#               if (EAP-Type == EAP-TLS) {
#                       sql.authorize
#               }

		#
		#  If you want to have a log of authentication replies,
		#  un-comment the following line, and the 'detail reply_log'
		#  section, above.
#		reply_log

		#
		#  After authenticating the user, do another SQL query.
		#  This logs authentication attempts to radpostauth.
		#
		#  See "Authentication Logging Queries" in sql.conf
#		sql

		#
		#  Instead of sending the query to the SQL server,
		#  write it into a log file.
		#
#		sql_log

		#
		#  Un-comment the following if you have set
		#  'edir_account_policy_check = yes' in the ldap module sub-section of
		#  the 'modules' section.
		#
#		ldap

		exec

		#
		# Generate a WiMAX-AAA-Session-Id that is unique per CSN. 
		# This should only have to be done upon new authentications, and should 
		# be constant. NSP-ID may be a better hash value than IP addresses 
		# (which change) or NAS-IDs... 
		
		#  Generate a session ID that is unique to the CSN and session. 
		#  TODO: Log error if no session id and not Framed-User ... i.e. session id is lost somehow
		if ((Service-Type == Framed-User) && !WiMAX-AAA-Session-Id) {
        		update reply {
            			WiMAX-AAA-Session-Id = "%{md5:%{Calling-Station-Id},%{%{NAS-Identifier}:-%{NAS-IP-Address}}}"
        		}
		}
		# With handoff from one asn to another does the initial access-request 
		# from the new asn-gw include the session-id?
		# If not this will need to be updated to retrieve it from the session cache... 
		else {
			update reply {
				WiMAX-AAA-Session-Id = "%{WiMAX-AAA-Session-Id}"
			}
		}

 		#
		#  Calculate the various WiMAX keys. In order for this to work,
		#  you will need to define the WiMAX NAI, usually via
		#
		#  update request {
		# 	WiMAX-MN-NAI = "%{User-Name}"
		#  }
		#  This is configured in the init_wimax policy stub - see policy.conf
		#
		#  If you want various keys to be calculated, you will need to
		#  update the reply with "template" values. The module will see
		#  this, and replace the template values with the correct ones
		#  taken from the cryptographic calculations. e.g.
		#
		#  update reply {
		#  	WiMAX-FA-RK-Key = 0x00
		#  	WiMAX-MSK = "%{EAP-MSK}"
		#  }
		#
		# 
                #  Configure WiMAX-MN-NAI and place appropriate keys in reply
                #  To enable MIP configure WiMAX-IP-Technology and ensure the
                #  appropriate HA IP address is available for key generation
		#  ... This policy needs a bit of additional work... 
#               negotiate_ip_technology

		#
		#  You may want to delete the MS-MPPE-*-Keys from the reply,
		#  as some WiMAX clients behave badly when those attributes
		#  are included. See "raddb/modules/wimax", configuration
		#  entry "delete_mppe_keys" for more information.

		#
		#  If using Simple IP and ASN-GW can use MS-MPPE-*-Keys then the 
		#  wimax module is not needed. MIP-RK and SPI will always be calculated
		#  so disabling this module will save some resources if MIP is not
		#  being used.
#		wimax

		#  Store WiMAX session information after all the required keys have 
		#  been generated by the wimax module.
		#  If not using MIP this could be relegated to the detail module
		sqlsession 

		#
		#  If using CMIP filter MN-HA key from response. These keys are sent 
		#  only to the HA for CMIP. The WMF requires that they are not sent 
		#  to the authenticator.
		#
		#  !!! Ensure that the session information is stored before
		#  !!! removing these keys from any response packets.
#		if ("%{reply:WiMAX-IP-Technology}" == CMIP4) {
#			update reply {
#				WiMAX-MN-hHA-MIP4-Key !* *
#			}
#		}
	
#	       	if ("%{reply:WiMAX-IP-Technology}" == CMIP6) {
#	       		update reply {
#                       	WiMAX-MN-hHA-MIP6-Key !* *
#              	 	}
#      		}	 

		#
		#  Access-Reject packets are sent through the REJECT sub-section of the
		#  post-auth section.
		#
		#  Add the ldap module name (or instance) if you have set 
		#  'edir_account_policy_check = yes' in the ldap module configuration
		#

		Post-Auth-Type REJECT {
 			# log failed authentications in SQL, too.
# 			sql

			attr_filter.access_reject
		}
	}

	#
	#  When the server decides to proxy a request to a home server,
	#  the proxied request is first passed through the pre-proxy
	#  stage.  This stage can re-write the request, or decide to
	#  cancel the proxy.
	#
	#  Only a few modules currently have this method.
	#
	pre-proxy {
#		attr_rewrite

		#  Uncomment the following line if you want to change attributes
		#  as defined in the preproxy_users file.
#		files

		#  Uncomment the following line if you want to filter requests
		#  sent to remote servers based on the rules defined in the
		#  'attrs.pre-proxy' file.
#		attr_filter.pre-proxy

		#  If you want to have a log of packets proxied to a home
		#  server, un-comment the following line, and the
		#  'detail pre_proxy_log' section, above.
#		pre_proxy_log
	}

	#
	#  When the server receives a reply to a request it proxied
	#  to a home server, the request may be massaged here, in the
	#  post-proxy stage.
	#
	post-proxy {

		#  If you want to have a log of replies from a home server,
		#  un-comment the following line, and the 'detail post_proxy_log'
		#  section, above.
#		post_proxy_log

#		attr_rewrite

		#  Uncomment the following line if you want to filter replies from
		#  remote proxies based on the rules defined in the 'attrs' file.
#		attr_filter.post-proxy

		#
		#  If you are proxying LEAP, you MUST configure the EAP
		#  module, and you MUST list it here, in the post-proxy
		#  stage.
		#
		#  You MUST also use the 'nostrip' option in the 'realm'
		#  configuration.  Otherwise, the User-Name attribute
		#  in the proxied request will not match the user name
		#  hidden inside of the EAP packet, and the end server will
		#  reject the EAP request.
		#
		eap

		#
		#  If the server tries to proxy a request and fails, then the
		#  request is processed through the modules in this section.
		#
		#  The main use of this section is to permit robust proxying
		#  of accounting packets.  The server can be configured to
		#  proxy accounting packets as part of normal processing.
		#  Then, if the home server goes down, accounting packets can
		#  be logged to a local "detail" file, for processing with
		#  radrelay.  When the home server comes back up, radrelay
		#  will read the detail file, and send the packets to the
		#  home server.
		#
		#  With this configuration, the server always responds to
		#  Accounting-Requests from the NAS, but only writes
		#  accounting packets to disk if the home server is down.
		#
#		Post-Proxy-Type Fail {
#			detail
#		}

	}
}
