18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP peer: Method registration 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DYNAMIC_EAP_METHODS 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <dlfcn.h> 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DYNAMIC_EAP_METHODS */ 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_i.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_methods.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eap_method *eap_methods = NULL; 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_get_eap_method - Get EAP method based on type number 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: EAP Vendor-Id (0 = IETF) 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: EAP type number 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to EAP method or %NULL if not found 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct eap_method * eap_peer_get_eap_method(int vendor, EapType method) 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) { 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->vendor == vendor && m->method == method) 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return m; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_get_type - Get EAP type for the given EAP method name 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @name: EAP method name, e.g., TLS 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: Buffer for returning EAP Vendor-Id 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: EAP method type or %EAP_TYPE_NONE if not found 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function maps EAP type names into EAP type numbers based on the list of 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods included in the build. 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtEapType eap_peer_get_type(const char *name, int *vendor) 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) { 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(m->name, name) == 0) { 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = m->vendor; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return m->method; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = EAP_VENDOR_IETF; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_TYPE_NONE; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_name - Get EAP method name for the given EAP type 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: EAP Vendor-Id (0 = IETF) 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @type: EAP method type 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: EAP method name, e.g., TLS, or %NULL if not found 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function maps EAP type numbers into EAP type names based on the list of 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods included in the build. 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * eap_get_name(int vendor, EapType type) 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (vendor == EAP_VENDOR_IETF && type == EAP_TYPE_EXPANDED) 751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return "expanded"; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) { 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->vendor == vendor && m->method == type) 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return m->name; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_names - Get space separated list of names for supported EAP methods 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for names 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: Buffer length 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of characters written into buf (not including nul 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * termination) 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtsize_t eap_get_names(char *buf, size_t buflen) 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos, *end; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buflen == 0) 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + buflen; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) { 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "%s%s", 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m == eap_methods ? "" : " ", m->name); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[buflen - 1] = '\0'; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_names_as_string_array - Get supported EAP methods as string array 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @num: Buffer for returning the number of items in array, not including %NULL 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * terminator. This parameter can be %NULL if the length is not needed. 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A %NULL-terminated array of strings, or %NULL on error. 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function returns the list of names for all supported EAP methods as an 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * array of strings. The caller must free the returned array items and the 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * array. 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar ** eap_get_names_as_string_array(size_t *num) 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t array_len = 0; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char **array; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i = 0, j; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array_len++; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array = os_zalloc(sizeof(char *) * (array_len + 1)); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (array == NULL) 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) { 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array[i++] = os_strdup(m->name); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (array[i - 1] == NULL) { 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < i; j++) 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(array[j]); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(array); 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array[i] = NULL; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num) 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *num = array_len; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return array; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_get_methods - Get a list of enabled EAP peer methods 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @count: Set to number of available methods 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: List of enabled EAP peer methods 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct eap_method * eap_peer_get_methods(size_t *count) 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int c = 0; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c++; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *count = c; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_methods; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DYNAMIC_EAP_METHODS 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_method_load - Load a dynamic EAP method library (shared object) 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @so: File path for the shared object file to load 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_method_load(const char *so) 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *handle; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int (*dyn_init)(void); 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle = dlopen(so, RTLD_LAZY); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (handle == NULL) { 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP: Failed to open dynamic EAP method " 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': %s", so, dlerror()); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dyn_init = dlsym(handle, "eap_peer_method_dynamic_init"); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dyn_init == NULL) { 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlclose(handle); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP: Invalid EAP method '%s' - no " 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "eap_peer_method_dynamic_init()", so); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = dyn_init(); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlclose(handle); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP: Failed to add EAP method '%s' - " 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ret %d", so, ret); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Store the handle for this shared object. It will be freed with 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * dlclose() when the EAP method is unregistered. */ 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_methods->dl_handle = handle; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Loaded dynamic EAP method: '%s'", so); 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_method_unload - Unload a dynamic EAP method library (shared object) 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: Pointer to the dynamically loaded EAP method 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to unload EAP methods that have been previously 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * loaded with eap_peer_method_load(). Before unloading the method, all 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * references to the method must be removed to make sure that no dereferences 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * of freed memory will occur after unloading. 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_method_unload(struct eap_method *method) 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m, *prev; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *handle; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = eap_methods; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (m) { 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m == method) 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = m; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = m->next; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m == NULL || m->dl_handle == NULL) 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = m->next; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_methods = m->next; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle = m->dl_handle; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->free) 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m->free(m); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_method_free(m); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlclose(handle); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DYNAMIC_EAP_METHODS */ 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_method_alloc - Allocate EAP peer method structure 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @version: Version of the EAP peer method interface (set to 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP_PEER_METHOD_INTERFACE_VERSION) 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF) 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: EAP type number (EAP_TYPE_*) 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @name: Name of the method (e.g., "TLS") 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Allocated EAP method structure or %NULL on failure 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The returned structure should be freed with eap_peer_method_free() when it 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is not needed anymore. 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_method * eap_peer_method_alloc(int version, int vendor, 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType method, const char *name) 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *eap; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap = os_zalloc(sizeof(*eap)); 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->version = version; 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->vendor = vendor; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->method = method; 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->name = name; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_method_free - Free EAP peer method structure 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: Method structure allocated with eap_peer_method_alloc() 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_peer_method_free(struct eap_method *method) 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(method); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_method_register - Register an EAP peer method 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: EAP method to register 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on invalid method, or -2 if a matching EAP method 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has already been registered 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Each EAP peer method needs to call this function to register itself as a 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * supported EAP method. 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_method_register(struct eap_method *method) 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m, *last = NULL; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (method == NULL || method->name == NULL || 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method->version != EAP_PEER_METHOD_INTERFACE_VERSION) 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) { 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((m->vendor == method->vendor && 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m->method == method->method) || 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(m->name, method->name) == 0) 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last = m; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (last) 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last->next = method; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_methods = method; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_unregister_methods - Unregister EAP peer methods 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called at program termination to unregister all EAP peer 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * methods. 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_peer_unregister_methods(void) 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DYNAMIC_EAP_METHODS 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *handle; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DYNAMIC_EAP_METHODS */ 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (eap_methods) { 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = eap_methods; 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_methods = eap_methods->next; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DYNAMIC_EAP_METHODS 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle = m->dl_handle; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DYNAMIC_EAP_METHODS */ 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->free) 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m->free(m); 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_method_free(m); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DYNAMIC_EAP_METHODS 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (handle) 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlclose(handle); 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DYNAMIC_EAP_METHODS */ 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 370