xref: /dflybsd-src/contrib/wpa_supplicant/src/eap_server/eap_server_methods.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
13ff40c12SJohn Marino /*
23ff40c12SJohn Marino  * EAP server method registration
33ff40c12SJohn Marino  * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
43ff40c12SJohn Marino  *
53ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino  * See README for more details.
73ff40c12SJohn Marino  */
83ff40c12SJohn Marino 
93ff40c12SJohn Marino #include "includes.h"
103ff40c12SJohn Marino 
113ff40c12SJohn Marino #include "common.h"
123ff40c12SJohn Marino #include "eap_i.h"
133ff40c12SJohn Marino #include "eap_methods.h"
143ff40c12SJohn Marino 
153ff40c12SJohn Marino 
163ff40c12SJohn Marino static struct eap_method *eap_methods;
173ff40c12SJohn Marino 
183ff40c12SJohn Marino 
193ff40c12SJohn Marino /**
203ff40c12SJohn Marino  * eap_server_get_eap_method - Get EAP method based on type number
213ff40c12SJohn Marino  * @vendor: EAP Vendor-Id (0 = IETF)
223ff40c12SJohn Marino  * @method: EAP type number
233ff40c12SJohn Marino  * Returns: Pointer to EAP method or %NULL if not found
243ff40c12SJohn Marino  */
eap_server_get_eap_method(int vendor,EapType method)253ff40c12SJohn Marino const struct eap_method * eap_server_get_eap_method(int vendor, EapType method)
263ff40c12SJohn Marino {
273ff40c12SJohn Marino 	struct eap_method *m;
283ff40c12SJohn Marino 	for (m = eap_methods; m; m = m->next) {
293ff40c12SJohn Marino 		if (m->vendor == vendor && m->method == method)
303ff40c12SJohn Marino 			return m;
313ff40c12SJohn Marino 	}
323ff40c12SJohn Marino 	return NULL;
333ff40c12SJohn Marino }
343ff40c12SJohn Marino 
353ff40c12SJohn Marino 
363ff40c12SJohn Marino /**
373ff40c12SJohn Marino  * eap_server_get_type - Get EAP type for the given EAP method name
383ff40c12SJohn Marino  * @name: EAP method name, e.g., TLS
393ff40c12SJohn Marino  * @vendor: Buffer for returning EAP Vendor-Id
403ff40c12SJohn Marino  * Returns: EAP method type or %EAP_TYPE_NONE if not found
413ff40c12SJohn Marino  *
423ff40c12SJohn Marino  * This function maps EAP type names into EAP type numbers based on the list of
433ff40c12SJohn Marino  * EAP methods included in the build.
443ff40c12SJohn Marino  */
eap_server_get_type(const char * name,int * vendor)453ff40c12SJohn Marino EapType eap_server_get_type(const char *name, int *vendor)
463ff40c12SJohn Marino {
473ff40c12SJohn Marino 	struct eap_method *m;
483ff40c12SJohn Marino 	for (m = eap_methods; m; m = m->next) {
493ff40c12SJohn Marino 		if (os_strcmp(m->name, name) == 0) {
503ff40c12SJohn Marino 			*vendor = m->vendor;
513ff40c12SJohn Marino 			return m->method;
523ff40c12SJohn Marino 		}
533ff40c12SJohn Marino 	}
543ff40c12SJohn Marino 	*vendor = EAP_VENDOR_IETF;
553ff40c12SJohn Marino 	return EAP_TYPE_NONE;
563ff40c12SJohn Marino }
573ff40c12SJohn Marino 
583ff40c12SJohn Marino 
593ff40c12SJohn Marino /**
603ff40c12SJohn Marino  * eap_server_method_alloc - Allocate EAP server method structure
613ff40c12SJohn Marino  * @version: Version of the EAP server method interface (set to
623ff40c12SJohn Marino  * EAP_SERVER_METHOD_INTERFACE_VERSION)
633ff40c12SJohn Marino  * @vendor: EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF)
643ff40c12SJohn Marino  * @method: EAP type number (EAP_TYPE_*)
653ff40c12SJohn Marino  * @name: Name of the method (e.g., "TLS")
663ff40c12SJohn Marino  * Returns: Allocated EAP method structure or %NULL on failure
673ff40c12SJohn Marino  *
683ff40c12SJohn Marino  * The returned structure should be freed with eap_server_method_free() when it
693ff40c12SJohn Marino  * is not needed anymore.
703ff40c12SJohn Marino  */
eap_server_method_alloc(int version,int vendor,EapType method,const char * name)713ff40c12SJohn Marino struct eap_method * eap_server_method_alloc(int version, int vendor,
723ff40c12SJohn Marino 					    EapType method, const char *name)
733ff40c12SJohn Marino {
743ff40c12SJohn Marino 	struct eap_method *eap;
753ff40c12SJohn Marino 	eap = os_zalloc(sizeof(*eap));
763ff40c12SJohn Marino 	if (eap == NULL)
773ff40c12SJohn Marino 		return NULL;
783ff40c12SJohn Marino 	eap->version = version;
793ff40c12SJohn Marino 	eap->vendor = vendor;
803ff40c12SJohn Marino 	eap->method = method;
813ff40c12SJohn Marino 	eap->name = name;
823ff40c12SJohn Marino 	return eap;
833ff40c12SJohn Marino }
843ff40c12SJohn Marino 
853ff40c12SJohn Marino 
863ff40c12SJohn Marino /**
873ff40c12SJohn Marino  * eap_server_method_free - Free EAP server method structure
883ff40c12SJohn Marino  * @method: Method structure allocated with eap_server_method_alloc()
893ff40c12SJohn Marino  */
eap_server_method_free(struct eap_method * method)90*a1157835SDaniel Fojt static void eap_server_method_free(struct eap_method *method)
913ff40c12SJohn Marino {
923ff40c12SJohn Marino 	os_free(method);
933ff40c12SJohn Marino }
943ff40c12SJohn Marino 
953ff40c12SJohn Marino 
963ff40c12SJohn Marino /**
973ff40c12SJohn Marino  * eap_server_method_register - Register an EAP server method
98*a1157835SDaniel Fojt  * @method: EAP method to register from eap_server_method_alloc()
993ff40c12SJohn Marino  * Returns: 0 on success, -1 on invalid method, or -2 if a matching EAP method
1003ff40c12SJohn Marino  * has already been registered
1013ff40c12SJohn Marino  *
1023ff40c12SJohn Marino  * Each EAP server method needs to call this function to register itself as a
103*a1157835SDaniel Fojt  * supported EAP method. The caller must not free the allocated method data
104*a1157835SDaniel Fojt  * regardless of the return value.
1053ff40c12SJohn Marino  */
eap_server_method_register(struct eap_method * method)1063ff40c12SJohn Marino int eap_server_method_register(struct eap_method *method)
1073ff40c12SJohn Marino {
1083ff40c12SJohn Marino 	struct eap_method *m, *last = NULL;
1093ff40c12SJohn Marino 
1103ff40c12SJohn Marino 	if (method == NULL || method->name == NULL ||
111*a1157835SDaniel Fojt 	    method->version != EAP_SERVER_METHOD_INTERFACE_VERSION) {
112*a1157835SDaniel Fojt 		eap_server_method_free(method);
1133ff40c12SJohn Marino 		return -1;
114*a1157835SDaniel Fojt 	}
1153ff40c12SJohn Marino 
1163ff40c12SJohn Marino 	for (m = eap_methods; m; m = m->next) {
1173ff40c12SJohn Marino 		if ((m->vendor == method->vendor &&
1183ff40c12SJohn Marino 		     m->method == method->method) ||
119*a1157835SDaniel Fojt 		    os_strcmp(m->name, method->name) == 0) {
120*a1157835SDaniel Fojt 			eap_server_method_free(method);
1213ff40c12SJohn Marino 			return -2;
122*a1157835SDaniel Fojt 		}
1233ff40c12SJohn Marino 		last = m;
1243ff40c12SJohn Marino 	}
1253ff40c12SJohn Marino 
1263ff40c12SJohn Marino 	if (last)
1273ff40c12SJohn Marino 		last->next = method;
1283ff40c12SJohn Marino 	else
1293ff40c12SJohn Marino 		eap_methods = method;
1303ff40c12SJohn Marino 
1313ff40c12SJohn Marino 	return 0;
1323ff40c12SJohn Marino }
1333ff40c12SJohn Marino 
1343ff40c12SJohn Marino 
1353ff40c12SJohn Marino /**
1363ff40c12SJohn Marino  * eap_server_unregister_methods - Unregister EAP server methods
1373ff40c12SJohn Marino  *
1383ff40c12SJohn Marino  * This function is called at program termination to unregister all EAP server
1393ff40c12SJohn Marino  * methods.
1403ff40c12SJohn Marino  */
eap_server_unregister_methods(void)1413ff40c12SJohn Marino void eap_server_unregister_methods(void)
1423ff40c12SJohn Marino {
1433ff40c12SJohn Marino 	struct eap_method *m;
1443ff40c12SJohn Marino 
1453ff40c12SJohn Marino 	while (eap_methods) {
1463ff40c12SJohn Marino 		m = eap_methods;
1473ff40c12SJohn Marino 		eap_methods = eap_methods->next;
1483ff40c12SJohn Marino 
1493ff40c12SJohn Marino 		if (m->free)
1503ff40c12SJohn Marino 			m->free(m);
1513ff40c12SJohn Marino 		else
1523ff40c12SJohn Marino 			eap_server_method_free(m);
1533ff40c12SJohn Marino 	}
1543ff40c12SJohn Marino }
1553ff40c12SJohn Marino 
1563ff40c12SJohn Marino 
1573ff40c12SJohn Marino /**
1583ff40c12SJohn Marino  * eap_server_get_name - Get EAP method name for the given EAP type
1593ff40c12SJohn Marino  * @vendor: EAP Vendor-Id (0 = IETF)
1603ff40c12SJohn Marino  * @type: EAP method type
161*a1157835SDaniel Fojt  * Returns: EAP method name, e.g., TLS, or "unknown" if not found
1623ff40c12SJohn Marino  *
1633ff40c12SJohn Marino  * This function maps EAP type numbers into EAP type names based on the list of
1643ff40c12SJohn Marino  * EAP methods included in the build.
1653ff40c12SJohn Marino  */
eap_server_get_name(int vendor,EapType type)1663ff40c12SJohn Marino const char * eap_server_get_name(int vendor, EapType type)
1673ff40c12SJohn Marino {
1683ff40c12SJohn Marino 	struct eap_method *m;
1693ff40c12SJohn Marino 	if (vendor == EAP_VENDOR_IETF && type == EAP_TYPE_EXPANDED)
1703ff40c12SJohn Marino 		return "expanded";
1713ff40c12SJohn Marino 	for (m = eap_methods; m; m = m->next) {
1723ff40c12SJohn Marino 		if (m->vendor == vendor && m->method == type)
1733ff40c12SJohn Marino 			return m->name;
1743ff40c12SJohn Marino 	}
175*a1157835SDaniel Fojt 	return "unknown";
1763ff40c12SJohn Marino }
177