void eap_handler_free(rlm_eap_t *inst, eap_handler_t *handler) { if (!handler) return; if (handler->identity) { talloc_free(handler->identity); handler->identity = NULL; } if (handler->prev_eapds) eap_ds_free(&(handler->prev_eapds)); if (handler->eap_ds) eap_ds_free(&(handler->eap_ds)); if ((handler->opaque) && (handler->free_opaque)) { handler->free_opaque(handler->opaque); handler->opaque = NULL; } handler->opaque = NULL; handler->free_opaque = NULL; if (handler->certs) pairfree(&handler->certs); PTHREAD_MUTEX_LOCK(&(inst->handler_mutex)); if (inst->handler_tree) { rbtree_deletebydata(inst->handler_tree, handler); } talloc_free(handler); PTHREAD_MUTEX_UNLOCK(&(inst->handler_mutex)); }
/* * Allocate a new EAP_PACKET */ EAP_DS *eap_ds_alloc(void) { EAP_DS *eap_ds; eap_ds = rad_malloc(sizeof(EAP_DS)); memset(eap_ds, 0, sizeof(EAP_DS)); if ((eap_ds->response = eap_packet_alloc()) == NULL) { eap_ds_free(&eap_ds); return NULL; } if ((eap_ds->request = eap_packet_alloc()) == NULL) { eap_ds_free(&eap_ds); return NULL; } return eap_ds; }
/* * Allocate a new eap_packet_t */ EAP_DS *eap_ds_alloc(eap_handler_t *handler) { EAP_DS *eap_ds; eap_ds = talloc_zero(handler, EAP_DS); eap_ds->response = talloc_zero(eap_ds, eap_packet_t); if (!eap_ds->response) { eap_ds_free(&eap_ds); return NULL; } eap_ds->request = talloc_zero(eap_ds, eap_packet_t); if (!eap_ds->response) { eap_ds_free(&eap_ds); return NULL; } return eap_ds; }
static int _eap_handler_free(eap_handler_t *handler) { if (handler->identity) { talloc_free(handler->identity); handler->identity = NULL; } if (handler->prev_eapds) eap_ds_free(&(handler->prev_eapds)); if (handler->eap_ds) eap_ds_free(&(handler->eap_ds)); if ((handler->opaque) && (handler->free_opaque)) { handler->free_opaque(handler->opaque); handler->opaque = NULL; } handler->opaque = NULL; handler->free_opaque = NULL; if (handler->certs) pairfree(&handler->certs); /* * Give helpful debug messages if: * * we're debugging TLS sessions, which don't finish, * and which aren't deleted early due to a likely RADIUS * retransmit which nukes our ID, and therefore our stare. */ if (fr_debug_lvl && handler->tls && !handler->finished && (time(NULL) > (handler->timestamp + 3))) { WARN("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); WARN("!! EAP session with state 0x%02x%02x%02x%02x%02x%02x%02x%02x did not finish! !!", handler->state[0], handler->state[1], handler->state[2], handler->state[3], handler->state[4], handler->state[5], handler->state[6], handler->state[7]); WARN("!! Please read http://wiki.freeradius.org/guide/Certificate_Compatibility !!"); WARN("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } talloc_free(handler); return 0; }
void eap_handler_free(EAP_HANDLER **handler_p) { EAP_HANDLER *handler; if ((handler_p == NULL) || (*handler_p == NULL)) return; handler = *handler_p; if (handler->id) { free(handler->id); handler->id = NULL; } if (handler->identity) { free(handler->identity); handler->identity = NULL; } if (handler->username) pairfree(&(handler->username)); if (handler->configured) pairfree(&(handler->configured)); if (handler->prev_eapds) eap_ds_free(&(handler->prev_eapds)); if (handler->eap_ds) eap_ds_free(&(handler->eap_ds)); if ((handler->opaque) && (handler->free_opaque)) handler->free_opaque(&(handler->opaque)); else if ((handler->opaque) && (handler->free_opaque == NULL)) radlog(L_ERR, "Possible memory leak ..."); handler->opaque = NULL; handler->free_opaque = NULL; handler->next = NULL; free(handler); *handler_p = NULL; }
/* * If the present EAP-Response is a reply to the previous * EAP-Request sent by us, then return the EAP_HANDLER * only after releasing from the eaplist * Also since we fill the eap_ds with the present EAP-Response * we got to free the prev_eapds & move the eap_ds to prev_eapds */ EAP_HANDLER *eaplist_isreply(EAP_HANDLER **first, unsigned char id[]) { EAP_HANDLER *node, *next, *ret = NULL; EAP_HANDLER **last = first; for (node = *first; node; node = next) { next = node->next; if (memcmp(node->id, id, id[0]) == 0) { DEBUG2(" rlm_eap: Request found, released from the list"); /* detach the node from the list */ *last = next; node->next = NULL; /* clean up the unwanted stuff before returning */ /* Clear the handler Id */ free(node->id); node->id = NULL; /* Move the current EAP to prev EAP after clearing prev_eap */ eap_ds_free(&(node->prev_eapds)); node->prev_eapds = node->eap_ds; node->eap_ds = NULL; ret = node; break; } else { last = &(node->next); } } if (!ret) { DEBUG2(" rlm_eap: Request not found in the list"); } return ret; }
/* * Find a a previous EAP-Request sent by us, which matches * the current EAP-Response. * * Then, release the handle from the list, and return it to * the caller. * * Also since we fill the eap_ds with the present EAP-Response we * got to free the prev_eapds & move the eap_ds to prev_eapds */ eap_handler_t *eaplist_find(rlm_eap_t *inst, REQUEST *request, eap_packet_raw_t *eap_packet) { VALUE_PAIR *state; eap_handler_t *handler, myHandler; /* * We key the sessions off of the 'state' attribute, so it * must exist. */ state = pairfind(request->packet->vps, PW_STATE, 0, TAG_ANY); if (!state || (state->length != EAP_STATE_LEN)) { return NULL; } myHandler.src_ipaddr = request->packet->src_ipaddr; myHandler.eap_id = eap_packet->id; memcpy(myHandler.state, state->vp_strvalue, sizeof(myHandler.state)); /* * Playing with a data structure shared among threads * means that we need a lock, to avoid conflict. */ PTHREAD_MUTEX_LOCK(&(inst->session_mutex)); eaplist_expire(inst, request, request->timestamp); handler = eaplist_delete(inst, request, &myHandler); PTHREAD_MUTEX_UNLOCK(&(inst->session_mutex)); /* * Might not have been there. */ if (!handler) { radlog(L_ERR, "rlm_eap (%s): No EAP session matching state " "0x%02x%02x%02x%02x%02x%02x%02x%02x", inst->xlat_name, state->vp_octets[0], state->vp_octets[1], state->vp_octets[2], state->vp_octets[3], state->vp_octets[4], state->vp_octets[5], state->vp_octets[6], state->vp_octets[7]); return NULL; } if (handler->trips >= 50) { radlog(L_ERR, "rlm_eap (%s): Aborting! More than 50 roundtrips " "made in session with state " "0x%02x%02x%02x%02x%02x%02x%02x%02x", inst->xlat_name, state->vp_octets[0], state->vp_octets[1], state->vp_octets[2], state->vp_octets[3], state->vp_octets[4], state->vp_octets[5], state->vp_octets[6], state->vp_octets[7]); eap_handler_free(inst, handler); return NULL; } handler->trips++; RDEBUG("Previous EAP request found for state " "0x%02x%02x%02x%02x%02x%02x%02x%02x, released from the list", state->vp_octets[0], state->vp_octets[1], state->vp_octets[2], state->vp_octets[3], state->vp_octets[4], state->vp_octets[5], state->vp_octets[6], state->vp_octets[7]); /* * Remember what the previous request was. */ eap_ds_free(&(handler->prev_eapds)); handler->prev_eapds = handler->eap_ds; handler->eap_ds = NULL; return handler; }