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