コード例 #1
0
static struct wpabuf * eap_aka_process(struct eap_sm *sm, void *priv,
                                       struct eap_method_ret *ret,
                                       const struct wpabuf *reqData)
{
    struct eap_aka_data *data = priv;
    const struct eap_hdr *req;
    u8 subtype, id;
    struct wpabuf *res;
    const u8 *pos;
    struct eap_sim_attrs attr;
    size_t len;

    wpa_hexdump_buf(MSG_DEBUG, "EAP-AKA: EAP data", reqData);
    if (eap_get_config_identity(sm, &len) == NULL) {
        wpa_printf(MSG_INFO, "EAP-AKA: Identity not configured");
        eap_sm_request_identity(sm);
        ret->ignore = TRUE;
        return NULL;
    }

    pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, reqData,
                           &len);
    if (pos == NULL || len < 1) {
        ret->ignore = TRUE;
        return NULL;
    }
    req = wpabuf_head(reqData);
    id = req->identifier;
    len = be_to_host16(req->length);

    ret->ignore = FALSE;
    ret->methodState = METHOD_MAY_CONT;
    ret->decision = DECISION_FAIL;
    ret->allowNotifications = TRUE;

    subtype = *pos++;
    wpa_printf(MSG_DEBUG, "EAP-AKA: Subtype=%d", subtype);
    pos += 2; /* Reserved */

    if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr,
                           data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1,
                           0)) {
        res = eap_aka_client_error(data, id,
                                   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
        goto done;
    }

    switch (subtype) {
    case EAP_AKA_SUBTYPE_IDENTITY:
        res = eap_aka_process_identity(sm, data, id, reqData, &attr);
        break;
    case EAP_AKA_SUBTYPE_CHALLENGE:
        res = eap_aka_process_challenge(sm, data, id, reqData, &attr);
        break;
    case EAP_AKA_SUBTYPE_NOTIFICATION:
        res = eap_aka_process_notification(sm, data, id, reqData,
                                           &attr);
        break;
    case EAP_AKA_SUBTYPE_REAUTHENTICATION:
        res = eap_aka_process_reauthentication(sm, data, id, reqData,
                                               &attr);
        break;
    case EAP_AKA_SUBTYPE_CLIENT_ERROR:
        wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Client-Error");
        res = eap_aka_client_error(data, id,
                                   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
        break;
    default:
        wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown subtype=%d", subtype);
        res = eap_aka_client_error(data, id,
                                   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
        break;
    }

done:
    if (data->state == FAILURE) {
        ret->decision = DECISION_FAIL;
        ret->methodState = METHOD_DONE;
    } else if (data->state == SUCCESS) {
        ret->decision = data->use_result_ind ?
                        DECISION_UNCOND_SUCC : DECISION_COND_SUCC;
        /*
         * It is possible for the server to reply with AKA
         * Notification, so we must allow the method to continue and
         * not only accept EAP-Success at this point.
         */
        ret->methodState = data->use_result_ind ?
                           METHOD_DONE : METHOD_MAY_CONT;
    } else if (data->state == RESULT_FAILURE)
        ret->methodState = METHOD_CONT;
    else if (data->state == RESULT_SUCCESS)
        ret->methodState = METHOD_CONT;

    if (ret->methodState == METHOD_DONE) {
        ret->allowNotifications = FALSE;
    }

    return res;
}
コード例 #2
0
ファイル: eap_server_aka.c プロジェクト: OpenPANA/openpana
static void eap_aka_process(struct eap_sm *sm, void *priv,
			    struct wpabuf *respData)
{
	struct eap_aka_data *data = priv;
	const u8 *pos, *end;
	u8 subtype;
	size_t len;
	struct eap_sim_attrs attr;

	pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, respData,
			       &len);
	if (pos == NULL || len < 3)
		return;

	end = pos + len;
	subtype = *pos;
	pos += 3;

	if (eap_aka_subtype_ok(data, subtype)) {
		wpa_printf(MSG_DEBUG, "EAP-AKA: Unrecognized or unexpected "
			   "EAP-AKA Subtype in EAP Response");
		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
		eap_aka_state(data, NOTIFICATION);
		return;
	}

	if (eap_sim_parse_attr(pos, end, &attr,
			       data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1,
			       0)) {
		wpa_printf(MSG_DEBUG, "EAP-AKA: Failed to parse attributes");
		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
		eap_aka_state(data, NOTIFICATION);
		return;
	}

	if (subtype == EAP_AKA_SUBTYPE_CLIENT_ERROR) {
		eap_aka_process_client_error(sm, data, respData, &attr);
		return;
	}

	if (subtype == EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT) {
		eap_aka_process_authentication_reject(sm, data, respData,
						      &attr);
		return;
	}

	switch (data->state) {
	case IDENTITY:
		eap_aka_process_identity(sm, data, respData, &attr);
		break;
	case CHALLENGE:
		if (subtype == EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE) {
			eap_aka_process_sync_failure(sm, data, respData,
						     &attr);
		} else {
			eap_aka_process_challenge(sm, data, respData, &attr);
		}
		break;
	case REAUTH:
		eap_aka_process_reauth(sm, data, respData, &attr);
		break;
	case NOTIFICATION:
		eap_aka_process_notification(sm, data, respData, &attr);
		break;
	default:
		wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown state %d in "
			   "process", data->state);
		break;
	}
}