eap_sim_db.c

来自「hostapd无线AP工具」· C语言 代码 · 共 243 行

C
243
字号
/* * hostapd / EAP-SIM database/authenticator gateway * Copyright (c) 2005, Jouni Malinen <jkmaline@cc.hut.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 database/authentication * gateway interface that is expected to be replaced with an implementation of * SS7 gateway to GSM authentication center (HLR/AuC) or a local * implementation of SIM triplet generator. * * The example implementation here reads triplets from a text file in * IMSI:Kc:SRES:RAND format, IMSI in ASCII, other fields as hex strings. This * is used to simulate an HLR/AuC. As such, it is not very useful for real life * authentication, but it is useful both as an example implementation and for * EAP-SIM testing. */#include <stdlib.h>#include <stdio.h>#include <string.h>#include "common.h"#include "eap_sim_common.h"#include "eap_sim_db.h"/* TODO: add an alternative callback based version of the interface. This is * needed to work better with the single threaded design of hostapd. For this, * the EAP data has to be stored somewhere and eap_sim_db is given a context * pointer for this and a callback function. The callback function will re-send * the EAP data through normal operations which will eventually end up calling * eap_sim_db_get_gsm_triplets() again for the same user. This time, eap_sim_db * should have the triplets available immediately. */struct eap_sim_db_data {	char *fname;};#define KC_LEN 8#define SRES_LEN 4#define RAND_LEN 16/* Initialize EAP-SIM database/authentication gateway interface. * Returns pointer to a private data structure. */void * eap_sim_db_init(const char *config){	struct eap_sim_db_data *data;	data = malloc(sizeof(*data));	if (data == NULL) {		return NULL;	}	memset(data, 0, sizeof(*data));	data->fname = strdup(config);	if (data->fname == NULL) {		free(data);		return NULL;	}	return data;}/* Deinitialize EAP-SIM database/authentication gateway interface. * priv is the pointer from eap_sim_db_init(). */void eap_sim_db_deinit(void *priv){	struct eap_sim_db_data *data = priv;	free(data->fname);	free(data);}/* Get GSM triplets for user name identity (identity_len bytes). In most cases, * the user name is '1' | IMSI, i.e., 1 followed by the IMSI in ASCII format. * The identity may also include NAI realm (@realm). * priv is the pointer from eap_sim_db_init(). * Returns the number of triplets received (has to be less than or equal to * max_chal) or -1 on error (e.g., user not found). rand, kc, and sres are * pointers to data areas for the triplets. */int eap_sim_db_get_gsm_triplets(void *priv, const u8 *identity,				size_t identity_len, int max_chal,				u8 *rand, u8 *kc, u8 *sres){	struct eap_sim_db_data *data = priv;	FILE *f;	int count, i;	char buf[80], *pos, *next;	f = fopen(data->fname, "r");	if (f == NULL) {		wpa_printf(MSG_DEBUG, "EAP-SIM DB: could not open triplet "			   "file '%s'", data->fname);		return -1;	}	if (identity_len < 2 || identity[0] != '1') {		wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity",				  identity, identity_len);		return -1;	}	identity++;	identity_len--;	for (i = 0; i < identity_len; i++) {		if (identity[i] == '@') {			identity_len = i;			break;		}	}	wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: get triplets for IMSI",			  identity, identity_len);	count = 0;	while (count < max_chal && fgets(buf, sizeof(buf), f)) {		/* Parse IMSI:Kc:SRES:RAND and match IMSI with identity. */		buf[sizeof(buf) - 1] = '\0';		pos = buf;		while (*pos != '\0' && *pos != '\n')			pos++;		if (*pos == '\n')			*pos = '\0';		if (pos - buf < 60 || pos[0] == '#')			continue;		pos = strchr(buf, ':');		if (pos == NULL)			continue;		*pos++ = '\0';		if (strlen(buf) != identity_len ||		    memcmp(buf, identity, identity_len) != 0)			continue;		next = strchr(pos, ':');		if (next == NULL)			continue;		*next++ = '\0';		if (hexstr2bin(pos, &kc[count * KC_LEN], KC_LEN) < 0)			continue;		pos = next;		next = strchr(pos, ':');		if (next == NULL)			continue;		*next++ = '\0';		if (hexstr2bin(pos, &sres[count * SRES_LEN], SRES_LEN) < 0)			continue;		if (hexstr2bin(next, &rand[count * RAND_LEN], RAND_LEN) < 0)			continue;		count++;	}	fclose(f);	if (count == 0) {		wpa_printf(MSG_DEBUG, "EAP-SIM DB: no triplets found");		count = -1;	}	return count;}/* Verify whether the given user identity (identity_len bytes) is known. In * most cases, the user name is '1' | IMSI, i.e., 1 followed by the IMSI in * ASCII format. * priv is the pointer from eap_sim_db_init(). * Returns 0 if the user is found and GSM triplets would be available for it or * -1 on error (e.g., user not found or no triplets available). */int eap_sim_db_identity_known(void *priv, const u8 *identity,			      size_t identity_len){	struct eap_sim_db_data *data = priv;	FILE *f;	char buf[80], *pos;	int i;	if (identity_len < 1 || identity[0] != '1') {		return -1;	}	f = fopen(data->fname, "r");	if (f == NULL) {		wpa_printf(MSG_DEBUG, "EAP-SIM DB: could not open triplet "			   "file '%s'", data->fname);		return -1;	}	if (identity_len < 2 || identity[0] != '1') {		wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity",				  identity, identity_len);		return -1;	}	identity++;	identity_len--;	for (i = 0; i < identity_len; i++) {		if (identity[i] == '@') {			identity_len = i;			break;		}	}	while (fgets(buf, sizeof(buf), f)) {		/* Parse IMSI:Kc:SRES:RAND and match IMSI with identity. */		buf[sizeof(buf) - 1] = '\0';		pos = buf;		while (*pos != '\0' && *pos != '\n')			pos++;		if (*pos == '\n')			*pos = '\0';		if (pos - buf < 60 || pos[0] == '#')			continue;		pos = strchr(buf, ':');		if (pos == NULL)			continue;		*pos++ = '\0';		if (strlen(buf) != identity_len ||		    memcmp(buf, identity, identity_len) != 0)			continue;		fclose(f);		return 0;	}	/* IMSI not found */	fclose(f);	return -1;}

⌨️ 快捷键说明

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