⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eap_sim_db.c

📁 IEEE 802.11a/b/g 服务器端AP
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * hostapd / EAP-SIM database/authenticator gateway * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. * * This is an example implementation of the EAP-SIM/AKA database/authentication * gateway interface that is using an external program as an SS7 gateway to * GSM/UMTS authentication center (HLR/AuC). hlr_auc_gw is an example * implementation of such a gateway program. This eap_sim_db.c takes care of * EAP-SIM/AKA pseudonyms and re-auth identities. It can be used with different * gateway implementations for HLR/AuC access. Alternatively, it can also be * completely replaced if the in-memory database of pseudonyms/re-auth * identities is not suitable for some cases. */#include "includes.h"#include <sys/un.h>#include "common.h"#include "eap_common/eap_sim_common.h"#include "eap_server/eap_sim_db.h"#include "eloop.h"struct eap_sim_pseudonym {	struct eap_sim_pseudonym *next;	u8 *identity;	size_t identity_len;	char *pseudonym;};struct eap_sim_db_pending {	struct eap_sim_db_pending *next;	u8 imsi[20];	size_t imsi_len;	enum { PENDING, SUCCESS, FAILURE } state;	void *cb_session_ctx;	struct os_time timestamp;	int aka;	union {		struct {			u8 kc[EAP_SIM_MAX_CHAL][EAP_SIM_KC_LEN];			u8 sres[EAP_SIM_MAX_CHAL][EAP_SIM_SRES_LEN];			u8 rand[EAP_SIM_MAX_CHAL][GSM_RAND_LEN];			int num_chal;		} sim;		struct {			u8 rand[EAP_AKA_RAND_LEN];			u8 autn[EAP_AKA_AUTN_LEN];			u8 ik[EAP_AKA_IK_LEN];			u8 ck[EAP_AKA_CK_LEN];			u8 res[EAP_AKA_RES_MAX_LEN];			size_t res_len;		} aka;	} u;};struct eap_sim_db_data {	int sock;	char *fname;	char *local_sock;	void (*get_complete_cb)(void *ctx, void *session_ctx);	void *ctx;	struct eap_sim_pseudonym *pseudonyms;	struct eap_sim_reauth *reauths;	struct eap_sim_db_pending *pending;};static struct eap_sim_db_pending *eap_sim_db_get_pending(struct eap_sim_db_data *data, const u8 *imsi,		       size_t imsi_len, int aka){	struct eap_sim_db_pending *entry, *prev = NULL;	entry = data->pending;	while (entry) {		if (entry->aka == aka && entry->imsi_len == imsi_len &&		    os_memcmp(entry->imsi, imsi, imsi_len) == 0) {			if (prev)				prev->next = entry->next;			else				data->pending = entry->next;			break;		}		prev = entry;		entry = entry->next;	}	return entry;}static void eap_sim_db_add_pending(struct eap_sim_db_data *data,				   struct eap_sim_db_pending *entry){	entry->next = data->pending;	data->pending = entry;}static void eap_sim_db_sim_resp_auth(struct eap_sim_db_data *data,				     const char *imsi, char *buf){	char *start, *end, *pos;	struct eap_sim_db_pending *entry;	int num_chal;	/*	 * SIM-RESP-AUTH <IMSI> Kc(i):SRES(i):RAND(i) ...	 * SIM-RESP-AUTH <IMSI> FAILURE	 * (IMSI = ASCII string, Kc/SRES/RAND = hex string)	 */	entry = eap_sim_db_get_pending(data, (u8 *) imsi, os_strlen(imsi), 0);	if (entry == NULL) {		wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the "			   "received message found");		return;	}	start = buf;	if (os_strncmp(start, "FAILURE", 7) == 0) {		wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported "			   "failure");		entry->state = FAILURE;		eap_sim_db_add_pending(data, entry);		data->get_complete_cb(data->ctx, entry->cb_session_ctx);		return;	}	num_chal = 0;	while (num_chal < EAP_SIM_MAX_CHAL) {		end = os_strchr(start, ' ');		if (end)			*end = '\0';		pos = os_strchr(start, ':');		if (pos == NULL)			goto parse_fail;		*pos = '\0';		if (hexstr2bin(start, entry->u.sim.kc[num_chal],			       EAP_SIM_KC_LEN))			goto parse_fail;		start = pos + 1;		pos = os_strchr(start, ':');		if (pos == NULL)			goto parse_fail;		*pos = '\0';		if (hexstr2bin(start, entry->u.sim.sres[num_chal],			       EAP_SIM_SRES_LEN))			goto parse_fail;		start = pos + 1;		if (hexstr2bin(start, entry->u.sim.rand[num_chal],			       GSM_RAND_LEN))			goto parse_fail;		num_chal++;		if (end == NULL)			break;		else			start = end + 1;	}	entry->u.sim.num_chal = num_chal;	entry->state = SUCCESS;	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Authentication data parsed "		   "successfully - callback");	eap_sim_db_add_pending(data, entry);	data->get_complete_cb(data->ctx, entry->cb_session_ctx);	return;parse_fail:	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");	os_free(entry);}static void eap_sim_db_aka_resp_auth(struct eap_sim_db_data *data,				     const char *imsi, char *buf){	char *start, *end;	struct eap_sim_db_pending *entry;	/*	 * AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES>	 * AKA-RESP-AUTH <IMSI> FAILURE	 * (IMSI = ASCII string, RAND/AUTN/IK/CK/RES = hex string)	 */	entry = eap_sim_db_get_pending(data, (u8 *) imsi, os_strlen(imsi), 1);	if (entry == NULL) {		wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the "			   "received message found");		return;	}	start = buf;	if (os_strncmp(start, "FAILURE", 7) == 0) {		wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported "			   "failure");		entry->state = FAILURE;		eap_sim_db_add_pending(data, entry);		data->get_complete_cb(data->ctx, entry->cb_session_ctx);		return;	}	end = os_strchr(start, ' ');	if (end == NULL)		goto parse_fail;	*end = '\0';	if (hexstr2bin(start, entry->u.aka.rand, EAP_AKA_RAND_LEN))		goto parse_fail;	start = end + 1;	end = os_strchr(start, ' ');	if (end == NULL)		goto parse_fail;	*end = '\0';	if (hexstr2bin(start, entry->u.aka.autn, EAP_AKA_AUTN_LEN))		goto parse_fail;	start = end + 1;	end = os_strchr(start, ' ');	if (end == NULL)		goto parse_fail;	*end = '\0';	if (hexstr2bin(start, entry->u.aka.ik, EAP_AKA_IK_LEN))		goto parse_fail;	start = end + 1;	end = os_strchr(start, ' ');	if (end == NULL)		goto parse_fail;	*end = '\0';	if (hexstr2bin(start, entry->u.aka.ck, EAP_AKA_CK_LEN))		goto parse_fail;	start = end + 1;	end = os_strchr(start, ' ');	if (end)		*end = '\0';	else {		end = start;		while (*end)			end++;	}	entry->u.aka.res_len = (end - start) / 2;	if (entry->u.aka.res_len > EAP_AKA_RES_MAX_LEN) {		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Too long RES");		entry->u.aka.res_len = 0;		goto parse_fail;	}	if (hexstr2bin(start, entry->u.aka.res, entry->u.aka.res_len))		goto parse_fail;	entry->state = SUCCESS;	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Authentication data parsed "		   "successfully - callback");	eap_sim_db_add_pending(data, entry);	data->get_complete_cb(data->ctx, entry->cb_session_ctx);	return;parse_fail:	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");	os_free(entry);}static void eap_sim_db_receive(int sock, void *eloop_ctx, void *sock_ctx){	struct eap_sim_db_data *data = eloop_ctx;	char buf[1000], *pos, *cmd, *imsi;	int res;	res = recv(sock, buf, sizeof(buf), 0);	if (res < 0)		return;	wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-SIM DB: Received from an "			      "external source", (u8 *) buf, res);	if (res == 0)		return;	if (res >= (int) sizeof(buf))		res = sizeof(buf) - 1;	buf[res] = '\0';	if (data->get_complete_cb == NULL) {		wpa_printf(MSG_DEBUG, "EAP-SIM DB: No get_complete_cb "			   "registered");		return;	}	/* <cmd> <IMSI> ... */	cmd = buf;	pos = os_strchr(cmd, ' ');	if (pos == NULL)		goto parse_fail;	*pos = '\0';	imsi = pos + 1;	pos = os_strchr(imsi, ' ');	if (pos == NULL)		goto parse_fail;	*pos = '\0';	wpa_printf(MSG_DEBUG, "EAP-SIM DB: External response=%s for IMSI %s",		   cmd, imsi);	if (os_strcmp(cmd, "SIM-RESP-AUTH") == 0)		eap_sim_db_sim_resp_auth(data, imsi, pos + 1);	else if (os_strcmp(cmd, "AKA-RESP-AUTH") == 0)		eap_sim_db_aka_resp_auth(data, imsi, pos + 1);	else		wpa_printf(MSG_INFO, "EAP-SIM DB: Unknown external response "			   "'%s'", cmd);	return;parse_fail:	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");}static int eap_sim_db_open_socket(struct eap_sim_db_data *data){	struct sockaddr_un addr;	static int counter = 0;	if (os_strncmp(data->fname, "unix:", 5) != 0)		return -1;	data->sock = socket(PF_UNIX, SOCK_DGRAM, 0);	if (data->sock < 0) {		perror("socket(eap_sim_db)");		return -1;	}	os_memset(&addr, 0, sizeof(addr));	addr.sun_family = AF_UNIX;	os_snprintf(addr.sun_path, sizeof(addr.sun_path),		    "/tmp/eap_sim_db_%d-%d", getpid(), counter++);	data->local_sock = os_strdup(addr.sun_path);	if (bind(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {		perror("bind(eap_sim_db)");		close(data->sock);		data->sock = -1;		return -1;	}	os_memset(&addr, 0, sizeof(addr));	addr.sun_family = AF_UNIX;	os_strlcpy(addr.sun_path, data->fname + 5, sizeof(addr.sun_path));	if (connect(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {		perror("connect(eap_sim_db)");		wpa_hexdump_ascii(MSG_INFO, "HLR/AuC GW socket",				  (u8 *) addr.sun_path,				  os_strlen(addr.sun_path));		close(data->sock);		data->sock = -1;		return -1;	}	eloop_register_read_sock(data->sock, eap_sim_db_receive, data, NULL);	return 0;}static void eap_sim_db_close_socket(struct eap_sim_db_data *data){	if (data->sock >= 0) {		eloop_unregister_read_sock(data->sock);		close(data->sock);		data->sock = -1;	}	if (data->local_sock) {		unlink(data->local_sock);		os_free(data->local_sock);		data->local_sock = NULL;	}}/** * 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 */void * eap_sim_db_init(const char *config,		       void (*get_complete_cb)(void *ctx, void *session_ctx),		       void *ctx){	struct eap_sim_db_data *data;	data = os_zalloc(sizeof(*data));	if (data == NULL)		return NULL;	data->sock = -1;	data->get_complete_cb = get_complete_cb;	data->ctx = ctx;	data->fname = os_strdup(config);	if (data->fname == NULL)		goto fail;	if (os_strncmp(data->fname, "unix:", 5) == 0) {		if (eap_sim_db_open_socket(data))			goto fail;	}	return data;fail:	eap_sim_db_close_socket(data);	os_free(data->fname);	os_free(data);	return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -