Пример #1
0
static int vector_gsm_from_triplets(eap_session_t *eap_session, VALUE_PAIR *vps,
				    int idx, fr_sim_keys_t *keys)
{
	REQUEST		*request = eap_session->request;
	VALUE_PAIR	*rand = NULL, *sres = NULL, *kc = NULL;
	fr_cursor_t	cursor;
	int		i;

	for (i = 0, (kc = fr_cursor_iter_by_da_init(&cursor, &vps, attr_eap_sim_kc));
	     (i < idx) && (kc = fr_cursor_next(&cursor));
	     i++);
	if (!kc) {
		RDEBUG3("No &control:%s[%i] attribute found, not using GSM triplets",
			attr_eap_sim_kc->name, idx);
		return 1;
	}
	if (kc->vp_length != SIM_VECTOR_GSM_KC_SIZE) {
		REDEBUG("&control:%s[%i] is not " STRINGIFY(SIM_VECTOR_GSM_KC_SIZE) " bytes, got %zu bytes",
			attr_eap_sim_kc->name, idx, kc->vp_length);
		return -1;
	}

	for (i = 0, (rand = fr_cursor_iter_by_da_init(&cursor, &vps, attr_eap_sim_rand));
	     (i < idx) && (rand = fr_cursor_next(&cursor));
	     i++);
	if (!rand) {
		RDEBUG3("No &control:%s[%i] attribute found, not using GSM triplets",
			attr_eap_sim_rand->name, idx);
		return 1;
	}
	if (rand->vp_length != SIM_VECTOR_GSM_RAND_SIZE) {
		REDEBUG("&control:EAP-SIM-Rand[%i] is not " STRINGIFY(SIM_RAND_SIZE) " bytes, got %zu bytes",
			idx, rand->vp_length);
		return -1;
	}

	for (i = 0, (sres = fr_cursor_iter_by_da_init(&cursor, &vps, attr_eap_sim_sres));
	     (i < idx) && (sres = fr_cursor_next(&cursor));
	     i++);
	if (!sres) {
		RDEBUG3("No &control:%s[%i] attribute found, not using GSM triplets",
			attr_eap_sim_sres->name, idx);
		return 1;
	}
	if (sres->vp_length != SIM_VECTOR_GSM_SRES_SIZE) {
		REDEBUG("&control:%s[%i] is not " STRINGIFY(SIM_VECTOR_GSM_SRES_SIZE) " bytes, got %zu bytes",
			attr_eap_sim_sres->name, idx, sres->vp_length);
		return -1;
	}

	memcpy(keys->gsm.vector[idx].kc, kc->vp_strvalue, SIM_VECTOR_GSM_KC_SIZE);
	memcpy(keys->gsm.vector[idx].rand, rand->vp_octets, SIM_VECTOR_GSM_RAND_SIZE);
	memcpy(keys->gsm.vector[idx].sres, sres->vp_octets, SIM_VECTOR_GSM_SRES_SIZE);

	return 0;
}
Пример #2
0
/** Do any RADIUS-layer fixups for proxying.
 *
 */
static void radius_fixups(rlm_radius_t *inst, REQUEST *request)
{
	VALUE_PAIR *vp;

	/*
	 *	Check for proxy loops.
	 */
	if (RDEBUG_ENABLED) {
		fr_cursor_t cursor;

		for (vp = fr_cursor_iter_by_da_init(&cursor, &request->packet->vps, attr_proxy_state);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			if (vp->vp_length != 4) continue;

			if (memcmp(&inst->proxy_state, vp->vp_octets, 4) == 0) {
				RWARN("Possible proxy loop - please check server configuration.");
				break;
			}
		}
	}

	if (request->packet->code != FR_CODE_ACCESS_REQUEST) return;

	if (fr_pair_find_by_da(request->packet->vps, attr_chap_password, TAG_ANY) &&
	    !fr_pair_find_by_da(request->packet->vps, attr_chap_challenge, TAG_ANY)) {
	    	MEM(pair_add_request(&vp, attr_chap_challenge) >= 0);
		fr_pair_value_memcpy(vp, request->packet->vector, sizeof(request->packet->vector));
	}
}
Пример #3
0
/** Derive triplets from quintuplets
 *
 */
static int vector_gsm_from_quintuplets(eap_session_t *eap_session, VALUE_PAIR *vps,
				       int idx, fr_sim_keys_t *keys)
{
	REQUEST		*request = eap_session->request;
	fr_cursor_t	cursor;

	VALUE_PAIR	*ck = NULL, *ik = NULL, *rand = NULL, *xres = NULL;

	int		i;

	/*
	 *	Fetch CK
	 */
	for (i = 0, (ck = fr_cursor_iter_by_da_init(&cursor, &vps, attr_eap_aka_ck));
	     (i < idx) && (ck = fr_cursor_next(&cursor));
	     i++);
	if (!ck) {
		RDEBUG3("No &control:%s[%i] attribute found, not using quintuplet derivation",
			attr_eap_aka_ck->name, idx);
		return 1;
	}

	/*
	 *	Fetch IK
	 */
	for (i = 0, (ik = fr_cursor_iter_by_da_init(&cursor, &vps, attr_eap_aka_ik));
	     (i < idx) && (ik = fr_cursor_next(&cursor));
	     i++);
	if (!ik) {
		RDEBUG3("No &control:%s[%i] attribute found, not using quintuplet derivation",
			attr_eap_aka_ik->name, idx);
		return 1;
	}

	/*
	 *	Fetch RAND
	 */
	for (i = 0, (rand = fr_cursor_iter_by_da_init(&cursor, &vps, attr_eap_aka_rand));
	     (i < idx) && (rand = fr_cursor_next(&cursor));
	     i++);
	if (!rand) {
		RDEBUG3("No &control:%s[%i] attribute found, not using quintuplet derivation",
			attr_eap_aka_rand->name, idx);
		return 1;
	}

	if (rand->vp_length != SIM_VECTOR_UMTS_RAND_SIZE) {
		REDEBUG("&control:%s[%i] incorrect length.  Expected "
			STRINGIFY(SIM_VECTOR_UMTS_RAND_SIZE) " bytes, "
			"got %zu bytes", attr_eap_aka_rand->name, idx, rand->vp_length);
		return -1;
	}

	/*
	 *	Fetch XRES
	 */
	for (i = 0, (xres = fr_cursor_iter_by_da_init(&cursor, &vps, attr_eap_aka_xres));
	     (i < idx) && (xres = fr_cursor_next(&cursor));
	     i++);
	if (!xres) {
		RDEBUG3("No &control:%s[%i] attribute found, not using quintuplet derivation",
			attr_eap_aka_xres->name, idx);
		return 1;
	}

	memcpy(keys->gsm.vector[idx].rand, rand->vp_octets, SIM_VECTOR_GSM_RAND_SIZE);

	milenage_gsm_from_umts(keys->gsm.vector[idx].sres,
			       keys->gsm.vector[idx].kc,
			       ik->vp_octets,
			       ck->vp_octets,
			       xres->vp_octets);

	return 0;
}
Пример #4
0
/*
 * Use a reply packet to determine what to do.
 */
static rlm_rcode_t CC_HINT(nonnull) process_reply(NDEBUG_UNUSED eap_session_t *eap_session,
						  tls_session_t *tls_session,
						  REQUEST *request, RADIUS_PACKET *reply)
{
	rlm_rcode_t			rcode = RLM_MODULE_REJECT;
	VALUE_PAIR			*vp;
	fr_cursor_t			cursor;

	eap_fast_tunnel_t	*t = talloc_get_type_abort(tls_session->opaque, eap_fast_tunnel_t);

	rad_assert(eap_session->request == request);

	/*
	 * If the response packet was Access-Accept, then
	 * we're OK.  If not, die horribly.
	 *
	 * FIXME: EAP-Messages can only start with 'identity',
	 * NOT 'eap start', so we should check for that....
	 */
	switch (reply->code) {
	case FR_CODE_ACCESS_ACCEPT:
		RDEBUG2("Got tunneled Access-Accept");

		rcode = RLM_MODULE_OK;

		/*
		 * Copy what we need into the TTLS tunnel and leave
		 * the rest to be cleaned up.
		 */
		for (vp = fr_cursor_init(&cursor, &reply->vps); vp; vp = fr_cursor_next(&cursor)) {
			if (fr_dict_vendor_num_by_da(vp->da) != VENDORPEC_MICROSOFT) continue;

			/* FIXME must be a better way to capture/re-derive this later for ISK */
			switch (vp->da->attr) {
			case FR_MSCHAP_MPPE_SEND_KEY:
				if (vp->vp_length != RADIUS_CHAP_CHALLENGE_LENGTH) {
				wrong_length:
					REDEBUG("Found %s with incorrect length.  Expected %u, got %zu",
						vp->da->name, RADIUS_CHAP_CHALLENGE_LENGTH, vp->vp_length);
					rcode = RLM_MODULE_INVALID;
					break;
				}

				memcpy(t->isk.mppe_send, vp->vp_octets, RADIUS_CHAP_CHALLENGE_LENGTH);
				break;

			case FR_MSCHAP_MPPE_RECV_KEY:
				if (vp->vp_length != RADIUS_CHAP_CHALLENGE_LENGTH) goto wrong_length;
				memcpy(t->isk.mppe_recv, vp->vp_octets, RADIUS_CHAP_CHALLENGE_LENGTH);
				break;

			case FR_MSCHAP2_SUCCESS:
				RDEBUG2("Got %s, tunneling it to the client in a challenge", vp->da->name);
				rcode = RLM_MODULE_HANDLED;
				t->authenticated = true;
				break;

			default:
				break;
			}
		}
		RHEXDUMP(L_DBG_LVL_MAX,
			 (uint8_t *)&t->isk, 2 * RADIUS_CHAP_CHALLENGE_LENGTH, "ISK[j]"); /* FIXME (part of above) */
		break;

	case FR_CODE_ACCESS_REJECT:
		REDEBUG("Got tunneled Access-Reject");
		rcode = RLM_MODULE_REJECT;
		break;

	case FR_CODE_ACCESS_CHALLENGE:
		RDEBUG2("Got tunneled Access-Challenge");

		/*
		 *	Copy the EAP-Message back to the tunnel.
		 */
		(void) fr_cursor_init(&cursor, &reply->vps);

		for (vp = fr_cursor_iter_by_da_init(&cursor, &reply->vps, attr_eap_message);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			eap_fast_tlv_append(tls_session, attr_eap_fast_eap_payload, true, vp->vp_length, vp->vp_octets);
		}

		rcode = RLM_MODULE_HANDLED;
		break;

	default:
		REDEBUG("Unknown RADIUS packet type %d: rejecting tunneled user", reply->code);
		rcode = RLM_MODULE_INVALID;
		break;
	}

	return rcode;
}