#
# PROXY - Proxies request to server(s) given by REP:Target-Server. First
#	  strips realm from REQ:User-Name if REQ:strip-realm is true.
#
# Return value: always true.
# Side effects: adds a REP:result set to RADIUS response code
# 		given by authentication server or RADIUS client, resp.
#

function PROXY (

  # for these things you'd want negative ACLs in the module interface, 
  # but we don't have them yet.

  delall REQ:RAD-Identifier,
  delall REQ:RAD-Length,
  delall REQ:RAD-Authenticator,
  delall REQ:RAD-Attributes,

  # strip realm before proxying if asked to

  strip-realm and REQ:User-Name := (User-Name afterfirst "/" or
				    User-Name beforelast "@" or
				    User-Name),

  # Proxy; drop request if radclient gave us a real error

  Radiusclient(moveall REP:Target-Server),
  REP:result = int, del REP:int,

  # for such things you'd want negative ACLs, but we don't have them yet.

  del F:RAD-Code,	# delete our own default, keep value added by proxy
  del RAD-Identifier,	# keep our own, delete values added by proxy
  del RAD-Length,
  del RAD-Authenticator,
  del RAD-Attributes,

1),


#
# COMMONAUTHEN - Authentication tail common for all types (PAP, CHAP, EAP);
#		 contains verification schemes that are independent of the
#		 authentication protocol.
#
#		 At this point it's proxy or reject.
#
# return value: always true
# side effects: one instance of REP:result added containing Accept, Reject
#	        or a RADIUS client error code.
#

function COMMONAUTHEN (

  # All authentication schemes allow proxying

  REP:Target-Server exists and return (PROXY),

  # We have no ways to verify the credentials we were given, so reject.

  # Uncomment if you want to log passwords
  Log-Line := REP:Log-Line . " - insufficient data to authenticate user",

  REP:result = Access-Reject
),


#
# PAP - Decrypts and verifies the last instance of REQ:User-Password based 
#	on attributes from the database. Supported are clear-password,
#	md5-hex-password and Target-Server. Other schemes may be added here as
#	well.
#
# Return value: always true.
# Side effects:	adds a REP:result set to Access-Accept or -Reject.
#

function PAP (

  # Decrypt password

  REQ:User-Password := 
    (User-Password papdecrypt (REP:Secret . RAD-Authenticator) . "\x00") 
    beforefirst "\x00",

  # Uncomment if you want to log passwords
  #
  Log-Line := REP:Log-Line . " [" . User-Password . "]",

  # PAP using stored cleartext

  clear-password exists and (

    User-Password == clear-password and (

      # Uncomment if you want to log passwords
      Log-Line := REP:Log-Line . " - matches [" . clear-password . "]",

      return (REP:result = Access-Accept)
    ),

    # Uncomment if you want to log passwords
    Log-Line := REP:Log-Line . " - does not match [" . clear-password . "]",

    return (REP:result = Access-Reject)
  ),

  # PAP using stored MD5 hash (salted)

  REP:md5-hex-password exists and (

    # Hash password with stored salt and compare to stored hash

    32 lastof REP:md5-hex-password == 
	hex md5 (User-Password . 4 firstof REP:md5-hex-password) and (

      # Uncomment if you want to log passwords
      Log-Line := REP:Log-Line . " - matches MD5 password [" .
		  REP:md5-hex-password . "]",

      return (REP:result = Access-Accept)
    ),

    # Uncomment if you want to log passwords
    Log-Line := REP:Log-Line . " - does not match MD5 password [" .
		REP:md5-hex-password . "]",

    return (REP:result = Access-Reject)
  ),

  # Shared with other authentication types

  COMMONAUTHEN,

1),


#
# CHAP - Verifies the last instance of REQ:CHAP-Password using on 
#	 REQ:CHAP-Challenge or REQ:RAD-Authenticator and attributes from
#	 the database. Supported verifiers are clear-password and
#	 Target-Server. Other schemes may be added here as well.
#
# Return value: always true.
# Side effects:	adds a REP:result set to Access-Accept or -Reject.
#

function CHAP (

  # Set challenge from authenticator if not given separately

  CHAP-Challenge or (REQ:CHAP-Challenge = RAD-Authenticator),

  # Uncomment if you want to log passwords
  #
  Log-Line := REP:Log-Line . " response [" . hex CHAP-Password . 
			     "] to challenge [" . hex CHAP-Challenge . "]",

  # CHAP using cleartext password

  clear-password exists and (

    # compare received hash to hash calculated from cleartext and challenge

    16 lastof CHAP-Password == md5 (1 firstof CHAP-Password . 
				    clear-password . CHAP-Challenge) and (

      # Uncomment if you want to log passwords
      Log-Line := REP:Log-Line . " - matches [" . clear-password . "]",

      return (REP:result = Access-Accept)
    ),

    # Uncomment if you want to log passwords
    Log-Line := REP:Log-Line . " - does not match [" . clear-password . "]",

    return (REP:result = Access-Reject)
  ),

  # Shared with other authentication types

  COMMONAUTHEN,

1),

# vim:softtabstop=2:sw=2

1

