1 /*
2  * eap.c    rfc2284 & rfc2869 implementation
3  *
4  * Version:     $Id: f0452b43f4f887e9872363cfa6df53c25359b207 $
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2000-2003,2006  The FreeRADIUS server project
21  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
22  * Copyright 2003  Alan DeKok <aland@freeradius.org>
23  */
24 /*
25  *  EAP PACKET FORMAT
26  *  --- ------ ------
27  *  0		   1		   2		   3
28  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
29  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30  * |     Code      |  Identifier   |	    Length	     |
31  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32  * |    Data ...
33  * +-+-+-+-+
34  *
35  *
36  * EAP Request and Response Packet Format
37  * --- ------- --- -------- ------ ------
38  *  0		   1		   2		   3
39  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
40  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41  * |     Code      |  Identifier   |	    Length	     |
42  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43  * |     Type      |  Type-Data ...
44  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
45  *
46  *
47  * EAP Success and Failure Packet Format
48  * --- ------- --- ------- ------ ------
49  *  0		   1		   2		   3
50  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
51  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52  * |     Code      |  Identifier   |	    Length	     |
53  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54  *
55  */
56 
57 #include <freeradius-devel/modpriv.h>
58 
59 RCSID("$Id: f0452b43f4f887e9872363cfa6df53c25359b207 $")
60 
61 #include "rlm_eap.h"
62 #include <ctype.h>
63 
64 static char const *eap_codes[] = {
65 	 "",				/* 0 is invalid */
66 	"Request",
67 	"Response",
68 	"Success",
69 	"Failure"
70 };
71 
_eap_module_free(eap_module_t * inst)72 static int _eap_module_free(eap_module_t *inst)
73 {
74 	/*
75 	 *	We have to check inst->type as it's only allocated
76 	 *	if we loaded the eap method.
77 	 */
78 	if (inst->type && inst->type->detach) (inst->type->detach)(inst->instance);
79 
80 #ifndef NDEBUG
81 	/*
82 	 *	Don't dlclose() modules if we're doing memory
83 	 *	debugging.  This removes the symbols needed by
84 	 *	valgrind.
85 	 */
86 	if (!main_config.debug_memory)
87 #endif
88 	if (inst->handle) dlclose(inst->handle);
89 
90 	return 0;
91 }
92 
93 /** Load required EAP sub-modules (methods)
94  *
95  */
eap_module_instantiate(rlm_eap_t * inst,eap_module_t ** m_inst,eap_type_t num,CONF_SECTION * cs)96 int eap_module_instantiate(rlm_eap_t *inst, eap_module_t **m_inst, eap_type_t num, CONF_SECTION *cs)
97 {
98 	eap_module_t *method;
99 	char *mod_name, *p;
100 
101 	/* Make room for the EAP-Type */
102 	*m_inst = method = talloc_zero(cs, eap_module_t);
103 	if (!inst) return -1;
104 
105 	talloc_set_destructor(method, _eap_module_free);
106 
107 	/* fill in the structure */
108 	method->cs = cs;
109 	method->name = eap_type2name(num);
110 
111 	/*
112 	 *	The name of the module were trying to load
113 	 */
114 	mod_name = talloc_typed_asprintf(method, "rlm_eap_%s", method->name);
115 
116 	/*
117 	 *	dlopen is case sensitive
118 	 */
119 	p = mod_name;
120 	while (*p) {
121 		*p = tolower(*p);
122 		p++;
123 	}
124 
125 	/*
126 	 *	Link the loaded EAP-Type
127 	 */
128 	method->handle = fr_dlopenext(mod_name);
129 	if (!method->handle) {
130 		ERROR("rlm_eap (%s): Failed to link %s: %s", inst->xlat_name, mod_name, fr_strerror());
131 
132 		return -1;
133 	}
134 
135 	method->type = dlsym(method->handle, mod_name);
136 	if (!method->type) {
137 		ERROR("rlm_eap (%s): Failed linking to structure in %s: %s", inst->xlat_name,
138 		       method->name, dlerror());
139 
140 		return -1;
141 	}
142 
143 	cf_log_module(cs, "Linked to sub-module %s", mod_name);
144 
145 	/*
146 	 *	Call the attach num in the EAP num module
147 	 */
148 	if ((method->type->instantiate) && ((method->type->instantiate)(method->cs, &(method->instance)) < 0)) {
149 		ERROR("rlm_eap (%s): Failed to initialise %s", inst->xlat_name, mod_name);
150 
151 		if (method->instance) {
152 			(void) talloc_steal(method, method->instance);
153 		}
154 
155 		return -1;
156 	}
157 
158 	if (method->instance) {
159 		(void) talloc_steal(method, method->instance);
160 	}
161 
162 	return 0;
163 }
164 
165 /*
166  * Call the appropriate handle with the right eap_method.
167  */
eap_module_call(eap_module_t * module,eap_handler_t * handler)168 static int eap_module_call(eap_module_t *module, eap_handler_t *handler)
169 {
170 	int rcode = 1;
171 	REQUEST *request = handler->request;
172 
173 	char const *caller = request->module;
174 
175 	rad_assert(module != NULL);
176 
177 	RDEBUG2("Calling submodule %s to process data", module->type->name);
178 
179 	request->module = module->type->name;
180 
181 	switch (handler->stage) {
182 	case INITIATE:
183 		if (!module->type->session_init(module->instance, handler)) {
184 			rcode = 0;
185 		}
186 
187 		break;
188 
189 	case PROCESS:
190 		/*
191 		 *   The called function updates the EAP reply packet.
192 		 */
193 		if (!module->type->process ||
194 		    !module->type->process(module->instance, handler)) {
195 			rcode = 0;
196 		}
197 
198 		break;
199 
200 	default:
201 		/* Should never enter here */
202 		RDEBUG("Internal sanity check failed on EAP");
203 		rcode = 0;
204 		break;
205 	}
206 
207 	request->module = caller;
208 	return rcode;
209 }
210 
211 /** Process NAK data from EAP peer
212  *
213  */
eap_process_nak(rlm_eap_t * inst,REQUEST * request,eap_type_t type,eap_type_data_t * nak)214 static eap_type_t eap_process_nak(rlm_eap_t *inst, REQUEST *request,
215 				    eap_type_t type,
216 				    eap_type_data_t *nak)
217 {
218 	unsigned int i;
219 	VALUE_PAIR *vp;
220 	eap_type_t method = PW_EAP_INVALID;
221 
222 	/*
223 	 *	The NAK data is the preferred EAP type(s) of
224 	 *	the client.
225 	 *
226 	 *	RFC 3748 says to list one or more proposed
227 	 *	alternative types, one per octet, or to use
228 	 *	0 for no alternative.
229 	 */
230 	if (!nak->data) {
231 		REDEBUG("Peer sent empty (invalid) NAK. "
232 			"Can't select method to continue with");
233 
234 		return PW_EAP_INVALID;
235 	}
236 
237 	/*
238 	 *	Pick one type out of the one they asked for,
239 	 *	as they may have asked for many.
240 	 */
241 	vp = fr_pair_find_by_num(request->config, PW_EAP_TYPE, 0, TAG_ANY);
242 	for (i = 0; i < nak->length; i++) {
243 		/*
244 		 *	Type 0 is valid, and means there are no
245 		 *	common choices.
246 		 */
247 		if (nak->data[i] == 0) {
248 			RDEBUG("Peer NAK'd indicating it is not willing to "
249 			       "continue ");
250 
251 			return PW_EAP_INVALID;
252 		}
253 
254 		/*
255 		 *	It is invalid to request identity,
256 		 *	notification & nak in nak.
257 		 */
258 		if (nak->data[i] < PW_EAP_MD5) {
259 			REDEBUG("Peer NAK'd asking for bad "
260 				"type %s (%d)",
261 				eap_type2name(nak->data[i]),
262 				nak->data[i]);
263 
264 			return PW_EAP_INVALID;
265 		}
266 
267 		if ((nak->data[i] >= PW_EAP_MAX_TYPES) ||
268 		    !inst->methods[nak->data[i]]) {
269 			RDEBUG2("Peer NAK'd asking for "
270 				"unsupported EAP type %s (%d), skipping...",
271 				eap_type2name(nak->data[i]),
272 				nak->data[i]);
273 
274 			continue;
275 		}
276 
277 		/*
278 		 *	Prevent a firestorm if the client is confused.
279 		 */
280 		if (type == nak->data[i]) {
281 			RDEBUG2("Peer NAK'd our request for "
282 				"%s (%d) with a request for "
283 				"%s (%d), skipping...",
284 				eap_type2name(nak->data[i]),
285 				nak->data[i],
286 				eap_type2name(nak->data[i]),
287 				nak->data[i]);
288 
289 			RWARN("!!! We requested to use an EAP type as normal.");
290 			RWARN("!!! The supplicant rejected that, and requested to use the same EAP type.");
291 			RWARN("!!!     i.e. the supplicant said 'I don't like X, please use X instead.");
292 			RWARN("!!! The supplicant software is broken and does not work properly.");
293 			RWARN("!!! Please upgrade it to software that works.");
294 
295 			continue;
296 		}
297 
298 		/*
299 		 *	Enforce per-user configuration of EAP
300 		 *	types.
301 		 */
302 		if (vp && (vp->vp_integer != nak->data[i])) {
303 			RDEBUG2("Peer wants %s (%d), while we "
304 				"require %s (%d), skipping",
305 				eap_type2name(nak->data[i]),
306 				nak->data[i],
307 				eap_type2name(vp->vp_integer),
308 				vp->vp_integer);
309 
310 			continue;
311 		}
312 
313 		RDEBUG("Found mutually acceptable type %s (%d)",
314 		       eap_type2name(nak->data[i]), nak->data[i]);
315 
316 		method = nak->data[i];
317 
318 		break;
319 	}
320 
321 	if (method == PW_EAP_INVALID) {
322 		REDEBUG("No mutually acceptable types found");
323 	}
324 
325 	return method;
326 }
327 
328 /** Select the correct callback based on a response
329  *
330  * Based on the EAP response from the supplicant, call the appropriate
331  * method callback.
332  *
333  * Default to the configured EAP-Type for all Unsupported EAP-Types.
334  *
335  * @param inst Configuration data for this instance of rlm_eap.
336  * @param handler State data that persists over multiple rounds of EAP.
337  * @return a status code.
338  */
eap_method_select(rlm_eap_t * inst,eap_handler_t * handler)339 eap_rcode_t eap_method_select(rlm_eap_t *inst, eap_handler_t *handler)
340 {
341 	eap_type_data_t		*type = &handler->eap_ds->response->type;
342 	REQUEST			*request = handler->request;
343 
344 	eap_type_t		next = inst->default_method;
345 	VALUE_PAIR		*vp;
346 
347 	/*
348 	 *	Don't trust anyone.
349 	 */
350 	if ((type->num == 0) || (type->num >= PW_EAP_MAX_TYPES)) {
351 		REDEBUG("Peer sent EAP method number %d, which is outside known range", type->num);
352 
353 		return EAP_INVALID;
354 	}
355 
356 	/*
357 	 *	Multiple levels of TLS nesting are invalid.  But if
358 	 *	the parent has a home_server defined, then this
359 	 *	request is being processed through a virtual
360 	 *	server... so that's OK.
361 	 *
362 	 *	i.e. we're inside an EAP tunnel, which means we have a
363 	 *	parent.  If the outer session exists, and doesn't have
364 	 *	a home server, then it's multiple layers of tunneling.
365 	 */
366 	if (handler->request->parent &&
367 	    handler->request->parent->parent &&
368 	    !handler->request->parent->parent->home_server) {
369 		RERROR("Multiple levels of TLS nesting are invalid");
370 
371 		return EAP_INVALID;
372 	}
373 
374 	RDEBUG2("Peer sent packet with method EAP %s (%d)", eap_type2name(type->num), type->num);
375 	/*
376 	 *	Figure out what to do.
377 	 */
378 	switch (type->num) {
379 	case PW_EAP_IDENTITY:
380 		/*
381 		 *	Allow per-user configuration of EAP types.
382 		 */
383 		vp = fr_pair_find_by_num(handler->request->config, PW_EAP_TYPE, 0,
384 			      TAG_ANY);
385 		if (vp) next = vp->vp_integer;
386 
387 		/*
388 		 *	Ensure it's valid.
389 		 */
390 		if ((next < PW_EAP_MD5) ||
391 		    (next >= PW_EAP_MAX_TYPES) ||
392 		    (!inst->methods[next])) {
393 			REDEBUG2("Tried to start unsupported EAP type %s (%d)",
394 				 eap_type2name(next), next);
395 
396 			return EAP_INVALID;
397 		}
398 
399 	do_initiate:
400 		/*
401 		 *	If any of these fail, we messed badly somewhere
402 		 */
403 		rad_assert(next >= PW_EAP_MD5);
404 		rad_assert(next < PW_EAP_MAX_TYPES);
405 		rad_assert(inst->methods[next]);
406 
407 		handler->stage = INITIATE;
408 		handler->type = next;
409 
410 		if (eap_module_call(inst->methods[next], handler) == 0) {
411 			REDEBUG2("Failed starting EAP %s (%d) session.  EAP sub-module failed",
412 				 eap_type2name(next), next);
413 
414 			return EAP_INVALID;
415 		}
416 		break;
417 
418 	case PW_EAP_NAK:
419 		/*
420 		 *	Delete old data, if necessary.
421 		 */
422 		if (handler->opaque && handler->free_opaque) {
423 			handler->free_opaque(handler->opaque);
424 			handler->free_opaque = NULL;
425 			handler->opaque = NULL;
426 		}
427 
428 		/*
429 		 *	We got a NAK after the peer started doing a
430 		 *	particular EAP type.  That's rude, tell the
431 		 *	peer to go away.
432 		 */
433 		if (handler->started) return EAP_INVALID;
434 
435 		next = eap_process_nak(inst, handler->request,
436 				       handler->type, type);
437 
438 		/*
439 		 *	We probably want to return 'fail' here...
440 		 */
441 		if (!next) {
442 			return EAP_INVALID;
443 		}
444 
445 		goto do_initiate;
446 
447 		/*
448 		 *	Key off of the configured sub-modules.
449 		 */
450 	default:
451 		/*
452 		 *	We haven't configured it, it doesn't exist.
453 		 */
454 		if (!inst->methods[type->num]) {
455 			REDEBUG2("Client asked for unsupported EAP type %s (%d)",
456 				 eap_type2name(type->num),
457 				 type->num);
458 
459 			return EAP_INVALID;
460 		}
461 
462 		rad_assert(handler->stage == PROCESS);
463 		handler->type = type->num;
464 		if (eap_module_call(inst->methods[type->num],
465 				    handler) == 0) {
466 			REDEBUG2("Failed continuing EAP %s (%d) session.  EAP sub-module failed",
467 				 eap_type2name(type->num),
468 				 type->num);
469 
470 			return EAP_INVALID;
471 		}
472 		handler->started = true;
473 		break;
474 	}
475 
476 	return EAP_OK;
477 }
478 
479 
480 /*
481  *	compose EAP reply packet in EAP-Message attr of RADIUS.
482  *
483  *	Set the RADIUS reply codes based on EAP request codes.  Append
484  *	any additonal VPs to RADIUS reply
485  */
eap_compose(eap_handler_t * handler)486 rlm_rcode_t eap_compose(eap_handler_t *handler)
487 {
488 	VALUE_PAIR *vp;
489 	eap_packet_raw_t *eap_packet;
490 	REQUEST *request;
491 	EAP_DS *eap_ds;
492 	eap_packet_t *reply;
493 	int rcode;
494 
495 #ifndef NDEBUG
496 	handler = talloc_get_type_abort(handler, eap_handler_t);
497 	request = talloc_get_type_abort(handler->request, REQUEST);
498 	eap_ds = talloc_get_type_abort(handler->eap_ds, EAP_DS);
499 	reply = talloc_get_type_abort(eap_ds->request, eap_packet_t);
500 #else
501 	request = handler->request;
502 	eap_ds = handler->eap_ds;
503 	reply = eap_ds->request;
504 #endif
505 
506 	/*
507 	 *	The Id for the EAP packet to the NAS wasn't set.
508 	 *	Do so now.
509 	 */
510 	if (!eap_ds->set_request_id) {
511 		/*
512 		 *	Id serves to suppport request/response
513 		 *	retransmission in the EAP layer and as such
514 		 *	must be different for 'adjacent' packets
515 		 *	except in case of success/failure-replies.
516 		 *
517 		 *	RFC2716 (EAP-TLS) requires this to be
518 		 *	incremented, RFC2284 only makes the above-
519 		 *	mentioned restriction.
520 		 */
521 		reply->id = handler->eap_ds->response->id;
522 
523 		switch (reply->code) {
524 			/*
525 			 *	The Id is a simple "ack" for success
526 			 *	and failure.
527 			 *
528 			 *	RFC 3748 section 4.2 says
529 			 *
530 			 *	... The Identifier field MUST match
531 			 *	the Identifier field of the Response
532 			 *	packet that it is sent in response
533 			 *	to.
534 			 */
535 		case PW_EAP_SUCCESS:
536 		case PW_EAP_FAILURE:
537 			break;
538 
539 			/*
540 			 *	We've sent a response to their
541 			 *	request, the Id is incremented.
542 			 */
543 		default:
544 			++reply->id;
545 		}
546 	}
547 
548 	/*
549 	 *	For Request & Response packets, set the EAP sub-type,
550 	 *	if the EAP sub-module didn't already set it.
551 	 *
552 	 *	This allows the TLS module to be "morphic", and means
553 	 *	that the TTLS and PEAP modules can call it to do most
554 	 *	of their dirty work.
555 	 */
556 	if (((eap_ds->request->code == PW_EAP_REQUEST) ||
557 	     (eap_ds->request->code == PW_EAP_RESPONSE)) &&
558 	    (eap_ds->request->type.num == 0)) {
559 		rad_assert(handler->type >= PW_EAP_MD5);
560 		rad_assert(handler->type < PW_EAP_MAX_TYPES);
561 
562 		eap_ds->request->type.num = handler->type;
563 	}
564 
565 	if (eap_wireformat(reply) == EAP_INVALID) {
566 		return RLM_MODULE_INVALID;
567 	}
568 	eap_packet = (eap_packet_raw_t *)reply->packet;
569 
570 	vp = radius_pair_create(request->reply, &request->reply->vps, PW_EAP_MESSAGE, 0);
571 	if (!vp) return RLM_MODULE_INVALID;
572 
573 	vp->vp_length = eap_packet->length[0] * 256 + eap_packet->length[1];
574 	vp->vp_octets = talloc_steal(vp, reply->packet);
575 	reply->packet = NULL;
576 
577 	/*
578 	 *	EAP-Message is always associated with
579 	 *	Message-Authenticator but not vice-versa.
580 	 *
581 	 *	Don't add a Message-Authenticator if it's already
582 	 *	there.
583 	 */
584 	vp = fr_pair_find_by_num(request->reply->vps, PW_MESSAGE_AUTHENTICATOR, 0, TAG_ANY);
585 	if (!vp) {
586 		vp = fr_pair_afrom_num(request->reply, PW_MESSAGE_AUTHENTICATOR, 0);
587 		vp->vp_length = AUTH_VECTOR_LEN;
588 		vp->vp_octets = talloc_zero_array(vp, uint8_t, vp->vp_length);
589 		fr_pair_add(&(request->reply->vps), vp);
590 	}
591 
592 	/* Set request reply code, but only if it's not already set. */
593 	rcode = RLM_MODULE_OK;
594 	if (!request->reply->code) switch (reply->code) {
595 	case PW_EAP_RESPONSE:
596 		request->reply->code = PW_CODE_ACCESS_REJECT;
597 		rcode = RLM_MODULE_REJECT;
598 		break;
599 	case PW_EAP_SUCCESS:
600 		request->reply->code = PW_CODE_ACCESS_ACCEPT;
601 		rcode = RLM_MODULE_OK;
602 		break;
603 	case PW_EAP_FAILURE:
604 		request->reply->code = PW_CODE_ACCESS_REJECT;
605 		rcode = RLM_MODULE_REJECT;
606 		break;
607 	case PW_EAP_REQUEST:
608 		request->reply->code = PW_CODE_ACCESS_CHALLENGE;
609 		rcode = RLM_MODULE_HANDLED;
610 		break;
611 	default:
612 		/*
613 		 *	When we're pulling MS-CHAPv2 out of EAP-MS-CHAPv2,
614 		 *	we do so WITHOUT setting a reply code, as the
615 		 *	request is being proxied.
616 		 */
617 		if (request->options & RAD_REQUEST_OPTION_PROXY_EAP) {
618 			return RLM_MODULE_HANDLED;
619 		}
620 
621 		/* Should never enter here */
622 		REDEBUG("Reply code %d is unknown, rejecting the request", reply->code);
623 		request->reply->code = PW_CODE_ACCESS_REJECT;
624 		reply->code = PW_EAP_FAILURE;
625 		rcode = RLM_MODULE_REJECT;
626 		break;
627 	}
628 
629 	RDEBUG2("Sending EAP %s (code %i) ID %d length %i",
630 		eap_codes[eap_packet->code], eap_packet->code, reply->id,
631 		eap_packet->length[0] * 256 + eap_packet->length[1]);
632 
633 	return rcode;
634 }
635 
636 /*
637  * Radius criteria, EAP-Message is invalid without Message-Authenticator
638  * For EAP_START, send Access-Challenge with EAP Identity request.
639  */
eap_start(rlm_eap_t * inst,REQUEST * request)640 int eap_start(rlm_eap_t *inst, REQUEST *request)
641 {
642 	VALUE_PAIR *vp, *proxy;
643 	VALUE_PAIR *eap_msg;
644 
645 	eap_msg = fr_pair_find_by_num(request->packet->vps, PW_EAP_MESSAGE, 0, TAG_ANY);
646 	if (!eap_msg) {
647 		RDEBUG2("No EAP-Message, not doing EAP");
648 		return EAP_NOOP;
649 	}
650 
651 	/*
652 	 *	Look for EAP-Type = None (FreeRADIUS specific attribute)
653 	 *	this allows you to NOT do EAP for some users.
654 	 */
655 	vp = fr_pair_find_by_num(request->packet->vps, PW_EAP_TYPE, 0, TAG_ANY);
656 	if (vp && vp->vp_integer == 0) {
657 		RDEBUG2("Found EAP-Message, but EAP-Type = None, so we're not doing EAP");
658 		return EAP_NOOP;
659 	}
660 
661 	/*
662 	 *	http://www.freeradius.org/rfc/rfc2869.html#EAP-Message
663 	 *
664 	 *	Checks for Message-Authenticator are handled by rad_recv().
665 	 */
666 
667 	/*
668 	 *	Check for a Proxy-To-Realm.  Don't get excited over LOCAL
669 	 *	realms (sigh).
670 	 */
671 	proxy = fr_pair_find_by_num(request->config, PW_PROXY_TO_REALM, 0, TAG_ANY);
672 	if (proxy) {
673 		REALM *realm;
674 
675 		/*
676 		 *	If it's a LOCAL realm, then we're not proxying
677 		 *	to it.
678 		 */
679 		realm = realm_find(proxy->vp_strvalue);
680 		if (!realm || (realm && (!realm->auth_pool))) {
681 			proxy = NULL;
682 		}
683 	}
684 
685 	/*
686 	 *	Check the length before de-referencing the contents.
687 	 *
688 	 *	Lengths of zero are required by the RFC for EAP-Start,
689 	 *	but we've never seen them in practice.
690 	 *
691 	 *	Lengths of two are what we see in practice as
692 	 *	EAP-Starts.
693 	 */
694 	if ((eap_msg->vp_length == 0) || (eap_msg->vp_length == 2)) {
695 		uint8_t *p;
696 
697 		/*
698 		 *	It's a valid EAP-Start, but the request
699 		 *	was marked as being proxied.  So we don't
700 		 *	do EAP, as the home server will do it.
701 		 */
702 		if (proxy) {
703 		do_proxy:
704 			RDEBUG2("Request is supposed to be proxied to "
705 				"Realm %s. Not doing EAP.", proxy->vp_strvalue);
706 			return EAP_NOOP;
707 		}
708 
709 		RDEBUG2("Got EAP_START message");
710 		vp = fr_pair_afrom_num(request->reply, PW_EAP_MESSAGE, 0);
711 		if (!vp) return EAP_FAIL;
712 		fr_pair_add(&request->reply->vps, vp);
713 
714 		/*
715 		 *	Manually create an EAP Identity request
716 		 */
717 		vp->vp_length = 5;
718 		vp->vp_octets = p = talloc_array(vp, uint8_t, vp->vp_length);
719 
720 		p[0] = PW_EAP_REQUEST;
721 		p[1] = 0; /* ID */
722 		p[2] = 0;
723 		p[3] = 5; /* length */
724 		p[4] = PW_EAP_IDENTITY;
725 
726 		request->reply->code = PW_CODE_ACCESS_CHALLENGE;
727 		return EAP_FOUND;
728 	} /* end of handling EAP-Start */
729 
730 	/*
731 	 *	The EAP packet header is 4 bytes, plus one byte of
732 	 *	EAP sub-type.  Short packets are discarded, unless
733 	 *	we're proxying.
734 	 */
735 	if (eap_msg->vp_length < (EAP_HEADER_LEN + 1)) {
736 		if (proxy) goto do_proxy;
737 
738 		RDEBUG2("Ignoring EAP-Message which is too short to be meaningful");
739 		return EAP_FAIL;
740 	}
741 
742 	/*
743 	 *	Create an EAP-Type containing the EAP-type
744 	 *	from the packet.
745 	 */
746 	vp = fr_pair_afrom_num(request->packet, PW_EAP_TYPE, 0);
747 	if (vp) {
748 		vp->vp_integer = eap_msg->vp_octets[4];
749 		fr_pair_add(&(request->packet->vps), vp);
750 	}
751 
752 	/*
753 	 *	If the request was marked to be proxied, do it now.
754 	 *	This is done after checking for a valid length
755 	 *	(which may not be good), and after adding the EAP-Type
756 	 *	attribute.  This lets other modules selectively cancel
757 	 *	proxying based on EAP-Type.
758 	 */
759 	if (proxy) goto do_proxy;
760 
761 	/*
762 	 *	From now on, we're supposed to be handling the
763 	 *	EAP packet.  We better understand it...
764 	 */
765 
766 	/*
767 	 *	We're allowed only a few codes.  Request, Response,
768 	 *	Success, or Failure.
769 	 */
770 	if ((eap_msg->vp_octets[0] == 0) ||
771 	    (eap_msg->vp_octets[0] >= PW_EAP_MAX_CODES)) {
772 		RDEBUG2("Peer sent EAP packet with unknown code %i", eap_msg->vp_octets[0]);
773 	} else {
774 		RDEBUG2("Peer sent EAP %s (code %i) ID %d length %zu",
775 		        eap_codes[eap_msg->vp_octets[0]],
776 		        eap_msg->vp_octets[0],
777 		        eap_msg->vp_octets[1],
778 		        eap_msg->vp_length);
779 	}
780 
781 	/*
782 	 *	We handle request and responses.  The only other defined
783 	 *	codes are success and fail.  The client SHOULD NOT be
784 	 *	sending success/fail packets to us, as it doesn't make
785 	 *	sense.
786 	 */
787 	if ((eap_msg->vp_octets[0] != PW_EAP_REQUEST) &&
788 	    (eap_msg->vp_octets[0] != PW_EAP_RESPONSE)) {
789 		RDEBUG2("Ignoring EAP packet which we don't know how to handle");
790 		return EAP_FAIL;
791 	}
792 
793 	/*
794 	 *	We've been told to ignore unknown EAP types, AND it's
795 	 *	an unknown type.  Return "NOOP", which will cause the
796 	 *	mod_authorize() to return NOOP.
797 	 *
798 	 *	EAP-Identity, Notification, and NAK are all handled
799 	 *	internally, so they never have handlers.
800 	 */
801 	if ((eap_msg->vp_octets[4] >= PW_EAP_MD5) &&
802 	    inst->ignore_unknown_types &&
803 	    ((eap_msg->vp_octets[4] == 0) ||
804 	     (eap_msg->vp_octets[4] >= PW_EAP_MAX_TYPES) ||
805 	     (!inst->methods[eap_msg->vp_octets[4]]))) {
806 		RDEBUG2("Ignoring Unknown EAP type");
807 		return EAP_NOOP;
808 	}
809 
810 	/*
811 	 *	They're NAKing the EAP type we wanted to use, and
812 	 *	asking for one which we don't support.
813 	 *
814 	 *	NAK is code + id + length1 + length + NAK
815 	 *	     + requested EAP type(s).
816 	 *
817 	 *	We know at this point that we can't handle the
818 	 *	request.  We could either return an EAP-Fail here, but
819 	 *	it's not too critical.
820 	 *
821 	 *	By returning "noop", we can ensure that authorize()
822 	 *	returns NOOP, and another module may choose to proxy
823 	 *	the request.
824 	 */
825 	if ((eap_msg->vp_octets[4] == PW_EAP_NAK) &&
826 	    (eap_msg->vp_length >= (EAP_HEADER_LEN + 2)) &&
827 	    inst->ignore_unknown_types &&
828 	    ((eap_msg->vp_octets[5] == 0) ||
829 	     (eap_msg->vp_octets[5] >= PW_EAP_MAX_TYPES) ||
830 	     (!inst->methods[eap_msg->vp_octets[5]]))) {
831 		RDEBUG2("Ignoring NAK with request for unknown EAP type");
832 		return EAP_NOOP;
833 	}
834 
835 	if ((eap_msg->vp_octets[4] == PW_EAP_TTLS) ||
836 	    (eap_msg->vp_octets[4] == PW_EAP_PEAP)) {
837 		RDEBUG2("Continuing tunnel setup");
838 		return EAP_OK;
839 	}
840 	/*
841 	 * We return ok in response to EAP identity
842 	 * This means we can write:
843 	 *
844 	 * eap {
845 	 *   ok = return
846 	 * }
847 	 * ldap
848 	 * sql
849 	 *
850 	 * ...in the inner-tunnel, to avoid expensive and unnecessary SQL/LDAP lookups
851 	 */
852 	if (eap_msg->vp_octets[4] == PW_EAP_IDENTITY) {
853 		RDEBUG2("EAP-Identity reply, returning 'ok' so we can short-circuit the rest of authorize");
854 		return EAP_OK;
855 	}
856 
857 	/*
858 	 *	Later EAP messages are longer than the 'start'
859 	 *	message, so if everything is OK, this function returns
860 	 *	'no start found', so that the rest of the EAP code can
861 	 *	use the State attribute to match this EAP-Message to
862 	 *	an ongoing conversation.
863 	 */
864 	RDEBUG2("No EAP Start, assuming it's an on-going EAP conversation");
865 
866 	return EAP_NOTFOUND;
867 }
868 
869 /*
870  *	compose EAP FAILURE packet in EAP-Message
871  */
eap_fail(eap_handler_t * handler)872 void eap_fail(eap_handler_t *handler)
873 {
874 	/*
875 	 *	Delete any previous replies.
876 	 */
877 	fr_pair_delete_by_num(&handler->request->reply->vps, PW_EAP_MESSAGE, 0, TAG_ANY);
878 	fr_pair_delete_by_num(&handler->request->reply->vps, PW_STATE, 0, TAG_ANY);
879 
880 	talloc_free(handler->eap_ds->request);
881 	handler->eap_ds->request = talloc_zero(handler->eap_ds, eap_packet_t);
882 	handler->eap_ds->request->code = PW_EAP_FAILURE;
883 	handler->finished = true;
884 	eap_compose(handler);
885 }
886 
887 /*
888  *	compose EAP SUCCESS packet in EAP-Message
889  */
eap_success(eap_handler_t * handler)890 void eap_success(eap_handler_t *handler)
891 {
892 	handler->eap_ds->request->code = PW_EAP_SUCCESS;
893 	handler->finished = true;
894 	eap_compose(handler);
895 }
896 
897 /*
898  * Basic EAP packet verfications & validations
899  */
eap_validation(REQUEST * request,eap_packet_raw_t ** eap_packet_p)900 static int eap_validation(REQUEST *request, eap_packet_raw_t **eap_packet_p)
901 {
902 	uint16_t len;
903 	eap_packet_raw_t *eap_packet = *eap_packet_p;
904 
905 	memcpy(&len, eap_packet->length, sizeof(uint16_t));
906 	len = ntohs(len);
907 
908 	/*
909 	 *	High level EAP packet checks
910 	 */
911 	if (len <= EAP_HEADER_LEN) {
912 		RAUTH("EAP packet is too small: Ignoring it.");
913 		return EAP_INVALID;
914 	}
915 
916 	if (eap_packet->code == PW_EAP_REQUEST) {
917 		VALUE_PAIR *vp;
918 		RAUTH("Unexpected EAP-Request.  NAKing it.");
919 
920 		vp = pair_make_reply("EAP-Message", "123456", T_OP_SET);
921 		if (vp) {
922 			uint8_t buffer[6];
923 
924 			buffer[0] = PW_EAP_RESPONSE;
925 			buffer[1] = eap_packet->id;
926 			buffer[2] = 0;
927 			buffer[3] = 6;
928 			buffer[4] = PW_EAP_NAK;
929 			buffer[5] = 0; /* no overlapping EAP types */
930 
931 			fr_pair_value_memcpy(vp, buffer, 6);
932 		}
933 
934 		/*
935 		 *	Ensure that the Access-Reject has a Message-Authenticator
936 		 */
937 		vp = fr_pair_find_by_num(request->reply->vps, PW_MESSAGE_AUTHENTICATOR, 0, TAG_ANY);
938 		if (!vp) {
939 			vp = fr_pair_afrom_num(request->reply, PW_MESSAGE_AUTHENTICATOR, 0);
940 			vp->vp_length = AUTH_VECTOR_LEN;
941 			vp->vp_octets = talloc_zero_array(vp, uint8_t, vp->vp_length);
942 			fr_pair_add(&(request->reply->vps), vp);
943 		}
944 		request->reply->code = PW_CODE_ACCESS_REJECT;
945 
946 		return EAP_INVALID;
947 	}
948 
949 	/*
950 	 *	We only allow responses from the peer.  The peer
951 	 *	CANNOT ask us to authenticate outselves.
952 	 */
953 	if (eap_packet->code != PW_EAP_RESPONSE) {
954 		RAUTH("Unexpected packet code %02x: Ignoring it.", eap_packet->code);
955 		return EAP_INVALID;
956 	}
957 
958 	if ((eap_packet->data[0] <= 0) ||
959 	    (eap_packet->data[0] >= PW_EAP_MAX_TYPES)) {
960 		/*
961 		 *	Handle expanded types by smashing them to
962 		 *	normal types.
963 		 */
964 		if (eap_packet->data[0] == PW_EAP_EXPANDED_TYPE) {
965 			uint8_t *p, *q;
966 
967 			if (len <= (EAP_HEADER_LEN + 1 + 3 + 4)) {
968 				RAUTH("Expanded EAP type is too short: ignoring the packet");
969 				return EAP_INVALID;
970 			}
971 
972 			if ((eap_packet->data[1] != 0) ||
973 			    (eap_packet->data[2] != 0) ||
974 			    (eap_packet->data[3] != 0)) {
975 				RAUTH("Expanded EAP type has unknown Vendor-ID: ignoring the packet");
976 				return EAP_INVALID;
977 			}
978 
979 			if ((eap_packet->data[4] != 0) ||
980 			    (eap_packet->data[5] != 0) ||
981 			    (eap_packet->data[6] != 0)) {
982 				RAUTH("Expanded EAP type has unknown Vendor-Type: ignoring the packet");
983 				return EAP_INVALID;
984 			}
985 
986 			if ((eap_packet->data[7] == 0) ||
987 			    (eap_packet->data[7] >= PW_EAP_MAX_TYPES)) {
988 				RAUTH("Unsupported Expanded EAP type %s (%u): ignoring the packet",
989 				      eap_type2name(eap_packet->data[7]), eap_packet->data[7]);
990 				return EAP_INVALID;
991 			}
992 
993 			if (eap_packet->data[7] == PW_EAP_NAK) {
994 				RAUTH("Unsupported Expanded EAP-NAK: ignoring the packet");
995 				return EAP_INVALID;
996 			}
997 
998 			/*
999 			 *	Re-write the EAP packet to NOT have the expanded type.
1000 			 */
1001 			q = (uint8_t *) eap_packet;
1002 			memmove(q + EAP_HEADER_LEN, q + EAP_HEADER_LEN + 7, len - 7 - EAP_HEADER_LEN);
1003 
1004 			p = talloc_realloc(talloc_parent(eap_packet), eap_packet, uint8_t, len - 7);
1005 			if (!p) {
1006 				RAUTH("Unsupported EAP type %s (%u): ignoring the packet",
1007 				      eap_type2name(eap_packet->data[0]), eap_packet->data[0]);
1008 				return EAP_INVALID;
1009 			}
1010 
1011 			len -= 7;
1012 			p[2] = (len >> 8) & 0xff;
1013 			p[3] = len & 0xff;
1014 
1015 			*eap_packet_p = (eap_packet_raw_t *) p;
1016 			RWARN("Converting Expanded EAP to normal EAP.");
1017 			RWARN("Unnecessary use of Expanded EAP types is not recommended.");
1018 
1019 			return EAP_VALID;
1020 		}
1021 
1022 		RAUTH("Unsupported EAP type %s (%u): ignoring the packet",
1023 		      eap_type2name(eap_packet->data[0]), eap_packet->data[0]);
1024 		return EAP_INVALID;
1025 	}
1026 
1027 	/* we don't expect notification, but we send it */
1028 	if (eap_packet->data[0] == PW_EAP_NOTIFICATION) {
1029 		RAUTH("Got NOTIFICATION, "
1030 			       "Ignoring the packet");
1031 		return EAP_INVALID;
1032 	}
1033 
1034 	return EAP_VALID;
1035 }
1036 
1037 
1038 /*
1039  *  Get the user Identity only from EAP-Identity packets
1040  */
eap_identity(REQUEST * request,eap_handler_t * handler,eap_packet_raw_t * eap_packet)1041 static char *eap_identity(REQUEST *request, eap_handler_t *handler, eap_packet_raw_t *eap_packet)
1042 {
1043 	int size;
1044 	uint16_t len;
1045 	char *identity;
1046 
1047 	if ((!eap_packet) ||
1048 	    (eap_packet->code != PW_EAP_RESPONSE) ||
1049 	    (eap_packet->data[0] != PW_EAP_IDENTITY)) {
1050 		return NULL;
1051 	}
1052 
1053 	memcpy(&len, eap_packet->length, sizeof(uint16_t));
1054 	len = ntohs(len);
1055 
1056 	if ((len <= 5) || (eap_packet->data[1] == 0x00)) {
1057 		REDEBUG("EAP-Identity Unknown");
1058 		return NULL;
1059 	}
1060 
1061 	if (len > 1024) {
1062 		REDEBUG("EAP-Identity too long");
1063 		return NULL;
1064 	}
1065 
1066 	size = len - 5;
1067 	identity = talloc_array(handler, char, size + 1);
1068 	memcpy(identity, &eap_packet->data[1], size);
1069 	identity[size] = '\0';
1070 
1071 	return identity;
1072 }
1073 
1074 
1075 /*
1076  *	Create our Request-Response data structure with the eap packet
1077  */
eap_buildds(eap_handler_t * handler,eap_packet_raw_t ** eap_packet_p)1078 static EAP_DS *eap_buildds(eap_handler_t *handler,
1079 			   eap_packet_raw_t **eap_packet_p)
1080 {
1081 	EAP_DS		*eap_ds = NULL;
1082 	eap_packet_raw_t	*eap_packet = *eap_packet_p;
1083 	int		typelen;
1084 	uint16_t	len;
1085 
1086 	if ((eap_ds = eap_ds_alloc(handler)) == NULL) {
1087 		return NULL;
1088 	}
1089 
1090 	eap_ds->response->packet = (uint8_t *) eap_packet;
1091 	(void) talloc_steal(eap_ds, eap_packet);
1092 	eap_ds->response->code = eap_packet->code;
1093 	eap_ds->response->id = eap_packet->id;
1094 	eap_ds->response->type.num = eap_packet->data[0];
1095 
1096 	memcpy(&len, eap_packet->length, sizeof(uint16_t));
1097 	len = ntohs(len);
1098 	eap_ds->response->length = len;
1099 
1100 	/*
1101 	 *	We've eaten the eap packet into the eap_ds.
1102 	 */
1103 	*eap_packet_p = NULL;
1104 
1105 	/*
1106 	 *	First 5 bytes in eap, are code + id + length(2) + type.
1107 	 *
1108 	 *	The rest is type-specific data.  We skip type while
1109 	 *	getting typedata from data.
1110 	 */
1111 	typelen = len - 5/*code + id + length + type */;
1112 	if (typelen > 0) {
1113 		/*
1114 		 *	Since the packet contains the complete
1115 		 *	eap_packet, typedata will be a ptr in packet
1116 		 *	to its typedata
1117 		 */
1118 		eap_ds->response->type.data = eap_ds->response->packet + 5/*code+id+length+type*/;
1119 		eap_ds->response->type.length = typelen;
1120 	} else {
1121 		eap_ds->response->type.length = 0;
1122 		eap_ds->response->type.data = NULL;
1123 	}
1124 
1125 	return eap_ds;
1126 }
1127 
1128 
1129 /*
1130  * If identity response then create a fresh handler & fill the identity
1131  * else handler MUST be in our list, get that.
1132  * This handler creation cannot fail
1133  *
1134  * username contains REQUEST->username which might have been stripped.
1135  * identity contains the one sent in EAP-Identity response
1136  */
eap_handler(rlm_eap_t * inst,eap_packet_raw_t ** eap_packet_p,REQUEST * request)1137 eap_handler_t *eap_handler(rlm_eap_t *inst, eap_packet_raw_t **eap_packet_p,
1138 			   REQUEST *request)
1139 {
1140 	eap_handler_t	*handler = NULL;
1141 	eap_packet_raw_t *eap_packet;
1142 	VALUE_PAIR	*vp;
1143 
1144 	/*
1145 	 *	Ensure it's a valid EAP-Request, or EAP-Response.
1146 	 */
1147 	if (eap_validation(request, eap_packet_p) == EAP_INVALID) {
1148 	error:
1149 		talloc_free(*eap_packet_p);
1150 		*eap_packet_p = NULL;
1151 		return NULL;
1152 	}
1153 
1154 	eap_packet = *eap_packet_p;
1155 
1156 	/*
1157 	 *	eap_handler_t MUST be found in the list if it is not
1158 	 *	EAP-Identity response
1159 	 */
1160 	if (eap_packet->data[0] != PW_EAP_IDENTITY) {
1161 		handler = eaplist_find(inst, request, eap_packet);
1162 		if (!handler) {
1163 			/* Either send EAP_Identity or EAP-Fail */
1164 			RDEBUG("Either EAP-request timed out OR EAP-response to an unknown EAP-request");
1165 			goto error;
1166 		}
1167 
1168 		/*
1169 		 *	Even more paranoia.  Without this, some weird
1170 		 *	clients could do crazy things.
1171 		 *
1172 		 *	It's ok to send EAP sub-type NAK in response
1173 		 *	to a request for a particular type, but it's NOT
1174 		 *	OK to blindly return data for another type.
1175 		 */
1176 		if ((eap_packet->data[0] != PW_EAP_NAK) &&
1177 		    (eap_packet->data[0] != handler->type)) {
1178 			RERROR("Response appears to match a previous request, but the EAP type is wrong");
1179 			RERROR("We expected EAP type %s, but received type %s",
1180 			       eap_type2name(handler->type),
1181 			       eap_type2name(eap_packet->data[0]));
1182 			RERROR("Your Supplicant or NAS is probably broken");
1183 			goto error;
1184 		}
1185 
1186 	       vp = fr_pair_find_by_num(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);
1187 	       if (!vp) {
1188 		       /*
1189 			*	NAS did not set the User-Name
1190 			*	attribute, so we set it here and
1191 			*	prepend it to the beginning of the
1192 			*	request vps so that autz's work
1193 			*	correctly
1194 			*/
1195 		       RDEBUG2("Broken NAS did not set User-Name, setting from EAP Identity");
1196 		       vp = fr_pair_make(request->packet, &request->packet->vps, "User-Name", handler->identity, T_OP_EQ);
1197 		       if (!vp) {
1198 			       goto error;
1199 		       }
1200 	       } else {
1201 		       /*
1202 			*      A little more paranoia.  If the NAS
1203 			*      *did* set the User-Name, and it doesn't
1204 			*      match the identity, (i.e. If they
1205 			*      change their User-Name part way through
1206 			*      the EAP transaction), then reject the
1207 			*      request as the NAS is doing something
1208 			*      funny.
1209 			*/
1210 		       if (strncmp(handler->identity, vp->vp_strvalue,
1211 				   MAX_STRING_LEN) != 0) {
1212 			       RDEBUG("Identity does not match User-Name.  Authentication failed");
1213 			       goto error;
1214 		       }
1215 	       }
1216 	} else {		/* packet was EAP identity */
1217 		handler = eap_handler_alloc(inst);
1218 		if (!handler) {
1219 			goto error;
1220 		}
1221 
1222 		/*
1223 		 *	All fields in the handler are set to zero.
1224 		 */
1225 		handler->identity = eap_identity(request, handler, eap_packet);
1226 		if (!handler->identity) {
1227 			RDEBUG("Identity Unknown, authentication failed");
1228 		error2:
1229 			talloc_free(handler);
1230 			goto error;
1231 		}
1232 
1233 	       vp = fr_pair_find_by_num(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);
1234 	       if (!vp) {
1235 		       /*
1236 			*	NAS did not set the User-Name
1237 			*	attribute, so we set it here and
1238 			*	prepend it to the beginning of the
1239 			*	request vps so that autz's work
1240 			*	correctly
1241 			*/
1242 		       RWDEBUG2("NAS did not set User-Name.  Setting it locally from EAP Identity");
1243 		       vp = fr_pair_make(request->packet, &request->packet->vps, "User-Name", handler->identity, T_OP_EQ);
1244 		       if (!vp) {
1245 			       goto error2;
1246 		       }
1247 	       } else {
1248 		       /*
1249 			*      Paranoia.  If the NAS *did* set the
1250 			*      User-Name, and it doesn't match the
1251 			*      identity, the NAS is doing something
1252 			*      funny, so reject the request.
1253 			*/
1254 		       if (strncmp(handler->identity, vp->vp_strvalue,
1255 				   MAX_STRING_LEN) != 0) {
1256 			       RDEBUG("Identity does not match User-Name, setting from EAP Identity");
1257 			       goto error2;
1258 		       }
1259 	       }
1260 	}
1261 
1262 	handler->eap_ds = eap_buildds(handler, eap_packet_p);
1263 	if (!handler->eap_ds) {
1264 		goto error2;
1265 	}
1266 
1267 	handler->timestamp = request->timestamp;
1268 	handler->request = request;
1269 	return handler;
1270 }
1271