# Decode EAP-Message attribute (concatenated by parent) into request list,
# according to the space in which the (dummy) attribute 'EAP-Packet' is defined

EAP-Message dictdecode EAP-Packet or (
  Log-Line = "EAP decode unsuccessful",
  halt
),
Ascdebug 0, del REP:int,

# Initialize reply list (on which an EAP Request to the peer is built ;-)

RAD-Code = Access-Challenge,
Id = Id + 1,

# Determine connection reference based on NAS, port and caller

link = (NAS-IP-Address or NAS-Identifier) . '/' . 
       NAS-Port . '/' . Calling-Station-Id,

# Handle Response/MD5-Challenge

Response-MD5-Challenge exists and (

  # Normally set by parent

  User-Name = -17 lastof Response-MD5-Challenge,
  clear-password = 'testuserpass!',

  # Retrieve session based on connection reference and EAP Response Id; 
  # no session is same as password mismatch, ie. reject, new challenge

  Memory(op = Load-Purge, 
	 key = REQ:link . '/' . Id), delall op, delall key,

  str = Id toraw . REQ:clear-password . strval,
  Log-Line = "EAP: [external=" . User-Name . "/ident=" . F:strval . 
	     "/internal=" . REP:User-Name . "/chal=" . hex strval . 
	     "/rep=" . hex (17 firstof Response-MD5-Challenge) . 
	     "/should=" . REQ:str . 
	     "/should=" . hex REQ:str . 
	     "/should=" . hex md5 REQ:str .
	     "]:",

  int == 2
  and 17 firstof Response-MD5-Challenge == "\x10" . md5 REQ:str
  and (
    Success = 1,
    RAD-Code := Access-Accept,
    Session-Timeout = 25,
    Log-Line := REP:Log-Line . " accepted",
  1) or (
    Failure = 1,
    RAD-Code := Access-Reject,
    Log-Line := REP:Log-Line . " rejected"
  ), 

  delall ordval, delall strval,
  EAP-Message = dictencode REP:EAP-Packet, 
  halt
),

# Handle Response/TTLS

Response-TTLS exists and (
  
  # For now, we reject anything other than V0

  Response-TTLS-Flags & TTLS-Flags-Version == TTLS-Flags-V0 or (
    Failure = 1,
    RAD-Code := Access-Reject,
    Log-Line := REP:Log-Line . " Client wants TTLS version " . 
		Response-TTLS-Flags & TTLS-Flags-Version . 
		", we want version 0 - rejected",
    EAP-Message = dictencode REP:EAP-Packet, 
    halt
  ),

  # Now we're beyond EAP-type and -version negotiation, we push to the TLS
  # module, set up in the configuration file to operate in TTLS mode. The
  # module contains the state machine and fragmentation support. It's able to
  # send us RADIUS or EAP requests using the Module Request feature; they are
  # handled from the top.
  #
  # If the upper side of TLS is 'eager', the lower side will automatically
  # follow the half duplex mode used by EAP-(T)TLS, even when always including
  # data if the TLS side has anything to send. No need for a lower layer state
  # machine.

  Ttls 0,     # uses Response-TTLS-*, Framed-MTU, link
	      # generates Request-TTLS-*, Success or Failure

  REP:Failure and (RAD-Code := Access-Reject, halt)
  or REP:Success and (RAD-Code := Access-Accept, halt)
),


###################################################################
#
# Handle Response/Identity. This is where you initiate the EAP type negotiation
# with the peer. You can only pick one fragment here. 

# This fragment is for EAP-TTLS. We suggest V1 to the client.

Response-Identity exists and (
  Request-TTLS-Flags = TTLS-Flags-Start | TTLS-Flags-V0
),

# This fragment is for EAP-MD5. 
#
# Send a Request/MD5-Challenge and remember it, keyed on connection reference
# and our EAP Request Id
#
#(Response-Identity exists 
#or Response-MD5-Challenge exists and no Response-MD5-Challenge) and (
#  str = random 16,						  # Challenge
#  Memory(op = Store, 
#	 key = REQ:link . '/' . REP:Id,				  # Request ID
#	 strval = Response-Identity,
#	 strval = REQ:str), delall op, delall key, delall ordval, delall strval,
#  Request-MD5-Challenge = "\x10" . REQ:str,   # . 'OpenRADIUS',
#  EAP-Message = dictencode REP:EAP-Packet, 
#  Session-Timeout = 15,			# User has 15 seconds to answer
#  halt
#),


Log-Line = "Got unknown EAP Response",
halt

# vim:softtabstop=2:sw=2

