#ifndef _IPXE_EAP_H #define _IPXE_EAP_H /** @file * * Extensible Authentication Protocol * */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include #include /** EAP header */ struct eap_header { /** Code */ uint8_t code; /** Identifier */ uint8_t id; /** Length */ uint16_t len; } __attribute__ (( packed )); /** EAP request */ #define EAP_CODE_REQUEST 1 /** EAP response */ #define EAP_CODE_RESPONSE 2 /** EAP request/response message */ struct eap_message { /** Header */ struct eap_header hdr; /** Type */ uint8_t type; /** Type data */ uint8_t data[0]; } __attribute__ (( packed )); /** EAP "no available types" marker */ #define EAP_TYPE_NONE 0 /** EAP identity */ #define EAP_TYPE_IDENTITY 1 /** EAP NAK */ #define EAP_TYPE_NAK 3 /** EAP MD5 challenge request/response */ #define EAP_TYPE_MD5 4 /** EAP MD5 challenge request/response type data */ struct eap_md5 { /** Value length */ uint8_t len; /** Value */ uint8_t value[0]; } __attribute__ (( packed )); /** EAP MS-CHAPv2 request/response */ #define EAP_TYPE_MSCHAPV2 26 /** EAP MS-CHAPv2 request/response type data */ struct eap_mschapv2 { /** Code * * This is in the same namespace as the EAP header's code * field, but is used to extend the handshake by allowing for * "success request" and "success response" packets. */ uint8_t code; /** Identifier * * This field serves no purposes: it always has the same value * as the EAP header's identifier field (located 5 bytes * earlier in the same packet). */ uint8_t id; /** Length * * This field serves no purpose: it always has the same value * as the EAP header's length field (located 5 bytes earlier * in the same packet), minus the 5 byte length of the EAP * header. */ uint16_t len; } __attribute__ (( packed )); /** EAP success */ #define EAP_CODE_SUCCESS 3 /** EAP failure */ #define EAP_CODE_FAILURE 4 /** EAP packet */ union eap_packet { /** Header */ struct eap_header hdr; /** Request/response message */ struct eap_message msg; }; /** EAP link block timeout * * We mark the link as blocked upon receiving a Request-Identity, on * the basis that this most likely indicates that the switch will not * yet be forwarding packets. * * There is no way to tell how frequently the Request-Identity packet * will be retransmitted by the switch. The default value for Cisco * switches seems to be 30 seconds, so treat the link as blocked for * 45 seconds. */ #define EAP_BLOCK_TIMEOUT ( 45 * TICKS_PER_SEC ) /** EAP protocol wait timeout * * In the EAP model, the supplicant is a pure responder. The model * also defines no acknowledgement response for the final Success or * Failure "requests". This leaves open the possibility that the * final Success or Failure packet is lost, with the supplicant having * no way to determine the final authentication status. * * Sideband mechanisms such as EAPoL-Start may be used to restart the * entire EAP process, as a (crude) workaround for this protocol flaw. * When expecting to receive a further EAP request (e.g. an * authentication challenge), we may wait for some length of time * before triggering this restart. Choose a duration that is shorter * than the link block timeout, so that there is no period during * which we erroneously leave the link marked as not blocked. */ #define EAP_WAIT_TIMEOUT ( EAP_BLOCK_TIMEOUT * 7 / 8 ) /** An EAP supplicant */ struct eap_supplicant { /** Network device */ struct net_device *netdev; /** Flags */ uint16_t flags; /** ID for current request/response */ uint8_t id; /** Type for current request/response */ uint8_t type; /** * Transmit EAP response * * @v supplicant EAP supplicant * @v data Response data * @v len Length of response data * @ret rc Return status code */ int ( * tx ) ( struct eap_supplicant *supplicant, const void *data, size_t len ); }; /** EAP authentication is in progress * * This indicates that we have received an EAP Request-Identity, but * have not yet received a final EAP Success or EAP Failure. */ #define EAP_FL_ONGOING 0x0001 /** EAP supplicant is passive * * This indicates that the supplicant should not transmit any futher * unsolicited packets (e.g. EAPoL-Start for a supplicant running over * EAPoL). This could be because authentication has already * completed, or because we are relying upon MAC Authentication Bypass * (MAB) which may have a very long timeout. */ #define EAP_FL_PASSIVE 0x0002 /** An EAP method */ struct eap_method { /** Type */ uint8_t type; /** * Handle EAP request * * @v supplicant EAP supplicant * @v req Request type data * @v req_len Length of request type data * @ret rc Return status code */ int ( * rx ) ( struct eap_supplicant *supplicant, const void *req, size_t req_len ); }; /** EAP method table */ #define EAP_METHODS __table ( struct eap_method, "eap_methods" ) /** Declare an EAP method */ #define __eap_method __table_entry ( EAP_METHODS, 01 ) extern int eap_tx_response ( struct eap_supplicant *supplicant, const void *rsp, size_t rsp_len ); extern int eap_rx ( struct eap_supplicant *supplicant, const void *data, size_t len ); #endif /* _IPXE_EAP_H */