hostapd的radius/eap server代码分析(4)-在windows下启动hostapd的radius/eap server
NJZhuJinhua@csdn May.14, 2010
mail:jinhua1982@gmail.com
http://blog.csdn.net/njzhujinhua
转载请注明出处。
为了更好的调测hostapd,通过删减及增加必要代码实现了windows下的hostapd框架,框架仍然读的是hostapd的配置文件,安全关联,用户信息等。
这个架子仅简单搭建,仅为实现hostapd的启动,用于协议研究。同时也描述了实现backend authentication server要做的一些事情。
1:main函数,很简单就两大步 @main.cpp
int main(int argc,char ** const argv)
{
// 初始化radius及EAP server
InitEAP();
if (argc == 1)
{
cout<<"usage:prog ip:port"<
return -1;
}
// 启动业务线程,处理消息。我是通过ACE的ACE_Event_Handler及ACE_Reactor实现的,这不是重点,不放出。
RunEapServer(argv[1]);
return 0;
};
2:@initeap.cpp
//extern hostapd_data *g_hostapdcfg;
extern void *g_ssl_context;
extern void *g_eap_sim_db_priv;
char *g_config_fname = "./config/hostapd.conf";
radius_server_data *g_radius_server_data = NULL;
/**************************************************
function:int InitEAP()
Detail: register eap methods, apply hostapd config and openssl init
para In: N/A
para Out:N/A
return value: 0 success
Author:Zhu.Jinhua 2010.05.01
***************************************************/
int InitEAP()
{
//eap方法注册
if (eap_server_register_methods())
{
cout<<"Failed to register EAP methods"<
return -1;
}
//读取配置文件,同时获知用户信息,安全关联等的配置文件目录及文件名
struct hostapd_config *hostapdconf = NULL;
hostapdconf = hostapd_config_read((const char *)g_config_fname);
if (NULL == hostapdconf)
{
return -1;
}
//初始化Openssl
if(InitOpenssl(hostapdconf))
{
PTRACE(1,"Failed to InitOpenssl");
}
//radius server的设置
hostapd_setup_radius_srv(hostapdconf);
//add for openssl Multi Thread using,
thread_setup();
return 0;
};
int InitOpenssl(/*struct hostapd_data *hostapddata, */hostapd_config *hostapdconf)
{
struct tls_connection_params params;
memset(¶ms, 0, sizeof(params));
struct hostapd_bss_config *bssconf = hostapdconf->bss;
// call tls_init initialize ssl context
g_ssl_context = tls_init(NULL);
if (g_ssl_context == NULL)
{
return -1;
}
os_memset(¶ms, 0, sizeof(params));
params.ca_cert = bssconf->ca_cert;
params.server_cert = bssconf->server_cert;
params.private_key = bssconf->private_key;
params.private_key_passwd = bssconf->private_key_passwd;
// params.dh_file = hapd->conf->dh_file;
if (tls_global_set_params(g_ssl_context, ¶ms)) {
wpa_printf(MSG_ERROR, "Failed to set TLS parameters");
return -1;
}
if (tls_global_set_verify(g_ssl_context,
0/*hapd->conf->check_crl*/))
{
wpa_printf(MSG_ERROR, "Failed to enable check_crl");
return -1;
}
/**
* eap_sim_db_init - Initialize EAP-SIM DB / authentication gateway interface
* @config: Configuration data (e.g., file name)
* @get_complete_cb: Callback function for reporting availability of triplets
* @ctx: Context pointer for get_complete_cb
* Returns: Pointer to a private data structure or %NULL on failure
*/
//虽然这部分有了,但是具体eap_sim/aka还没完成,暂时没试验这个
#ifdef EAP_SERVER
if (bssconf->eap_sim_db)
{
g_eap_sim_db_priv =
eap_sim_db_init(bssconf->eap_sim_db,
hostapd_sim_db_cb, g_radius_server_data);
if (g_eap_sim_db_priv == NULL)
{
wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM "
"database interface");
return -1;
}
}
#endif /* EAP_SERVER */
return 0;
}
static int hostapd_setup_radius_srv(struct hostapd_config *hostapdconf)
{
struct radius_server_conf srv;
os_memset(&srv, 0, sizeof(srv));
struct hostapd_bss_config *conf = hostapdconf->bss;
//安全关联
srv.client_file = conf->radius_server_clients;
//鉴权端口,在我们的实现中,由RunEapServer实现了,这里的并没用到
srv.auth_port = conf->radius_server_auth_port;
srv.conf_ctx = conf;
//eap_sim/aka用到的数据
srv.eap_sim_db_priv = g_eap_sim_db_priv;//hostapdconf->eap_sim_db_priv;
//ssl相关用到的全局上下文
srv.ssl_ctx = g_ssl_context;
srv.pac_opaque_encr_key = conf->pac_opaque_encr_key;
srv.eap_fast_a_id = conf->eap_fast_a_id;
srv.eap_fast_a_id_len = conf->eap_fast_a_id_len;
srv.eap_fast_a_id_info = conf->eap_fast_a_id_info;
srv.eap_fast_prov = conf->eap_fast_prov;
srv.pac_key_lifetime = conf->pac_key_lifetime;
srv.pac_key_refresh_time = conf->pac_key_refresh_time;
srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
srv.tnc = conf->tnc;
srv.wps = NULL;//hapd->wps;
srv.ipv6 = 0;
//获取用户信息的回调函数
srv.get_eap_user = hostapd_radius_get_eap_user;
srv.eap_req_id_text = conf->eap_req_id_text;
srv.eap_req_id_text_len = conf->eap_req_id_text_len;
g_radius_server_data = radius_server_init(&srv);
//g_radius_server_data = radius_server_init(&srv);
if (g_radius_server_data == NULL) {
wpa_printf(MSG_ERROR, "RADIUS server initialization failed.");
return -1;
}
return 0;
}
/**************************************************
function:int hostapd_radius_get_eap_user()
Detail: callback of get eap user for radius_server_init
para In: void *ctx, config
const u8 *identity,
size_t identity_len,
int phase2: is phase2?
para Out:struct eap_user *user
return value: 0 success
Author:Zhu.Jinhua 2010.05.01
***************************************************/
static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity,
size_t identity_len, int phase2,
struct eap_user *user)
{
const struct hostapd_eap_user *eap_user;
int i, count;
eap_user = hostapd_get_eap_user((hostapd_bss_config *)ctx, identity, identity_len, phase2);
if (eap_user == NULL)
return -1;
if (user == NULL)
return 0;
os_memset(user, 0, sizeof(*user));
count = EAP_USER_MAX_METHODS;
if (count > EAP_MAX_METHODS)
count = EAP_MAX_METHODS;
for (i = 0; i < count; i++) {
user->methods[i].vendor = eap_user->methods[i].vendor;
user->methods[i].method = eap_user->methods[i].method;
}
if (eap_user->password) {
user->password = (unsigned char *)os_malloc(eap_user->password_len);
if (user->password == NULL)
return -1;
os_memcpy(user->password, eap_user->password,
eap_user->password_len);
user->password_len = eap_user->password_len;
user->password_hash = eap_user->password_hash;
}
user->force_version = eap_user->force_version;
user->ttls_auth = eap_user->ttls_auth;
return 0;
}