1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* 20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * EAP server method registration 30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> 40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This software may be distributed under the terms of the BSD license. 60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * See README for more details. 70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "includes.h" 100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "common.h" 120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "eap_i.h" 130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "eap_methods.h" 140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct eap_method *eap_methods; 170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/** 200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * eap_server_get_eap_method - Get EAP method based on type number 210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @vendor: EAP Vendor-Id (0 = IETF) 220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @method: EAP type number 230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Returns: Pointer to EAP method or %NULL if not found 240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangconst struct eap_method * eap_server_get_eap_method(int vendor, EapType method) 260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct eap_method *m; 280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (m = eap_methods; m; m = m->next) { 290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (m->vendor == vendor && m->method == method) 300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return m; 310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/** 370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * eap_server_get_type - Get EAP type for the given EAP method name 380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @name: EAP method name, e.g., TLS 390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @vendor: Buffer for returning EAP Vendor-Id 400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Returns: EAP method type or %EAP_TYPE_NONE if not found 410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function maps EAP type names into EAP type numbers based on the list of 430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * EAP methods included in the build. 440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangEapType eap_server_get_type(const char *name, int *vendor) 460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct eap_method *m; 480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (m = eap_methods; m; m = m->next) { 490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (os_strcmp(m->name, name) == 0) { 500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *vendor = m->vendor; 510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return m->method; 520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *vendor = EAP_VENDOR_IETF; 550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return EAP_TYPE_NONE; 560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/** 600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * eap_server_method_alloc - Allocate EAP server method structure 610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @version: Version of the EAP server method interface (set to 620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * EAP_SERVER_METHOD_INTERFACE_VERSION) 630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @vendor: EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF) 640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @method: EAP type number (EAP_TYPE_*) 650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @name: Name of the method (e.g., "TLS") 660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Returns: Allocated EAP method structure or %NULL on failure 670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * The returned structure should be freed with eap_server_method_free() when it 690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * is not needed anymore. 700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct eap_method * eap_server_method_alloc(int version, int vendor, 720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang EapType method, const char *name) 730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct eap_method *eap; 750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eap = os_zalloc(sizeof(*eap)); 760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (eap == NULL) 770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eap->version = version; 790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eap->vendor = vendor; 800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eap->method = method; 810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eap->name = name; 820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return eap; 830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/** 870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * eap_server_method_free - Free EAP server method structure 880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @method: Method structure allocated with eap_server_method_alloc() 890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid eap_server_method_free(struct eap_method *method) 910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang os_free(method); 930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/** 970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * eap_server_method_register - Register an EAP server method 980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @method: EAP method to register 990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Returns: 0 on success, -1 on invalid method, or -2 if a matching EAP method 1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * has already been registered 1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Each EAP server method needs to call this function to register itself as a 1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * supported EAP method. 1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint eap_server_method_register(struct eap_method *method) 1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct eap_method *m, *last = NULL; 1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (method == NULL || method->name == NULL || 110c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh method->version != EAP_SERVER_METHOD_INTERFACE_VERSION) 1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (m = eap_methods; m; m = m->next) { 114c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if ((m->vendor == method->vendor && 1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang m->method == method->method) || 1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang os_strcmp(m->name, method->name) == 0) 1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -2; 1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang last = m; 1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (last) 1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang last->next = method; 1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else 1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eap_methods = method; 1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/** 1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * eap_server_unregister_methods - Unregister EAP server methods 1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function is called at program termination to unregister all EAP server 1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * methods. 1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid eap_server_unregister_methods(void) 1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct eap_method *m; 1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang while (eap_methods) { 1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang m = eap_methods; 1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eap_methods = eap_methods->next; 1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (m->free) 1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang m->free(m); 1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else 1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eap_server_method_free(m); 1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/** 1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * eap_server_get_name - Get EAP method name for the given EAP type 1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @vendor: EAP Vendor-Id (0 = IETF) 1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * @type: EAP method type 1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Returns: EAP method name, e.g., TLS, or %NULL if not found 1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function maps EAP type numbers into EAP type names based on the list of 1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * EAP methods included in the build. 1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangconst char * eap_server_get_name(int vendor, EapType type) 1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct eap_method *m; 1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (vendor == EAP_VENDOR_IETF && type == EAP_TYPE_EXPANDED) 1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return "expanded"; 1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (m = eap_methods; m; m = m->next) { 1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (m->vendor == vendor && m->method == type) 1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return m->name; 1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 171c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh} 1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang