static void radius_server_session_remove_timeout(void *eloop_ctx, void *timeout_ctx) { struct radius_server_data *data = eloop_ctx; struct radius_session *sess = timeout_ctx; RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id); radius_server_session_remove(data, sess); }
static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx) { struct radius_server_data *data = eloop_ctx; struct radius_session *sess = timeout_ctx; RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id); radius_server_session_remove(data, sess); }
static int radius_server_request(struct radius_server_data *data, struct radius_msg *msg, struct sockaddr_in *from, struct radius_client *client) { u8 *eap = NULL; size_t eap_len; int res, state_included; u8 statebuf[4], resp_id; unsigned int state; struct radius_session *sess; struct radius_msg *reply; struct eap_hdr *hdr; /* TODO: Implement duplicate packet processing */ res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf, sizeof(statebuf)); state_included = res >= 0; if (res == sizeof(statebuf)) { state = (statebuf[0] << 24) | (statebuf[1] << 16) | (statebuf[2] << 8) | statebuf[3]; sess = radius_server_get_session(client, state); } else { sess = NULL; } if (sess) { RADIUS_DEBUG("Request for session 0x%x", sess->sess_id); } else if (state_included) { RADIUS_DEBUG("State attribute included but no session found"); radius_server_reject(data, client, msg, from); return -1; } else { sess = radius_server_get_new_session(data, client, msg); if (sess == NULL) { RADIUS_DEBUG("Could not create a new session"); return -1; } } eap = radius_msg_get_eap(msg, &eap_len); if (eap == NULL) { RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s", inet_ntoa(from->sin_addr)); return -1; } RADIUS_DUMP("Received EAP data", eap, eap_len); if (eap_len >= sizeof(*hdr)) { hdr = (struct eap_hdr *) eap; resp_id = hdr->identifier; } else { resp_id = 0; } eap_set_eapRespData(sess->eap, eap, eap_len); free(eap); eap = NULL; sess->eapResp = TRUE; eap_sm_step(sess->eap); if (sess->eapReqData) { RADIUS_DUMP("EAP data from the state machine", sess->eapReqData, sess->eapReqDataLen); } else if (sess->eapFail) { RADIUS_DEBUG("No EAP data from the state machine, but eapFail " "set - generate EAP-Failure"); hdr = malloc(sizeof(*hdr)); if (hdr) { memset(hdr, 0, sizeof(*hdr)); hdr->identifier = resp_id; hdr->length = htons(sizeof(*hdr)); sess->eapReqData = (u8 *) hdr; sess->eapReqDataLen = sizeof(*hdr); } } else { RADIUS_DEBUG("No EAP data from the state machine - ignore this" " Access-Request silently (assuming it was a " "duplicate)"); return -1; } reply = radius_server_encapsulate_eap(data, client, sess, msg); free(sess->eapReqData); sess->eapReqData = NULL; sess->eapReqDataLen = 0; if (reply) { RADIUS_DEBUG("Reply to %s:%d", inet_ntoa(from->sin_addr), ntohs(from->sin_port)); if (wpa_debug_level <= MSG_MSGDUMP) { radius_msg_dump(reply); } res = sendto(data->auth_sock, reply->buf, reply->buf_used, 0, (struct sockaddr *) from, sizeof(*from)); if (res < 0) { perror("sendto[RADIUS SRV]"); } radius_msg_free(reply); free(reply); } if (sess->eapSuccess || sess->eapFail) { RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id); radius_server_session_remove(data, sess); } return 0; }