18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP server method registration 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2009, 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 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_i.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_methods.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eap_method *eap_methods; 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_get_eap_method - Get EAP method based on type number 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: EAP Vendor-Id (0 = IETF) 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: EAP type number 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to EAP method or %NULL if not found 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct eap_method * eap_server_get_eap_method(int vendor, EapType method) 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) { 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->vendor == vendor && m->method == method) 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return m; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_get_type - Get EAP type for the given EAP method name 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @name: EAP method name, e.g., TLS 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: Buffer for returning EAP Vendor-Id 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: EAP method type or %EAP_TYPE_NONE if not found 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function maps EAP type names into EAP type numbers based on the list of 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods included in the build. 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtEapType eap_server_get_type(const char *name, int *vendor) 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) { 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(m->name, name) == 0) { 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = m->vendor; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return m->method; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = EAP_VENDOR_IETF; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_TYPE_NONE; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_method_alloc - Allocate EAP server method structure 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @version: Version of the EAP server method interface (set to 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP_SERVER_METHOD_INTERFACE_VERSION) 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF) 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: EAP type number (EAP_TYPE_*) 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @name: Name of the method (e.g., "TLS") 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Allocated EAP method structure or %NULL on failure 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The returned structure should be freed with eap_server_method_free() when it 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is not needed anymore. 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_method * eap_server_method_alloc(int version, int vendor, 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType method, const char *name) 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *eap; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap = os_zalloc(sizeof(*eap)); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->version = version; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->vendor = vendor; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->method = method; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->name = name; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_method_free - Free EAP server method structure 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: Method structure allocated with eap_server_method_alloc() 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_server_method_free(struct eap_method *method) 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(method); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_method_register - Register an EAP server method 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: EAP method to register 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on invalid method, or -2 if a matching EAP method 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has already been registered 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Each EAP server method needs to call this function to register itself as a 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * supported EAP method. 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_server_method_register(struct eap_method *method) 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m, *last = NULL; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (method == NULL || method->name == NULL || 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method->version != EAP_SERVER_METHOD_INTERFACE_VERSION) 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) { 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((m->vendor == method->vendor && 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m->method == method->method) || 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(m->name, method->name) == 0) 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last = m; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (last) 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last->next = method; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_methods = method; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_unregister_methods - Unregister EAP server methods 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called at program termination to unregister all EAP server 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * methods. 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_server_unregister_methods(void) 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (eap_methods) { 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = eap_methods; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_methods = eap_methods->next; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->free) 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m->free(m); 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_method_free(m); 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_get_name - Get EAP method name for the given EAP type 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: EAP Vendor-Id (0 = IETF) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @type: EAP method type 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: EAP method name, e.g., TLS, or %NULL if not found 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function maps EAP type numbers into EAP type names based on the list of 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods included in the build. 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * eap_server_get_name(int vendor, EapType type) 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *m; 1641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (vendor == EAP_VENDOR_IETF && type == EAP_TYPE_EXPANDED) 1651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return "expanded"; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = eap_methods; m; m = m->next) { 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->vendor == vendor && m->method == type) 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return m->name; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 172