config.c

来自「hostapd无线AP工具」· C语言 代码 · 共 1,216 行 · 第 1/2 页

C
1,216
字号
/* * Host AP (software wireless LAN access point) user space daemon for * Host AP kernel driver / Configuration file * Copyright (c) 2003-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. */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <netinet/in.h>#include <string.h>#include <sys/socket.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <grp.h>#include "hostapd.h"#include "driver.h"#include "sha1.h"#include "eap.h"#include "radius_client.h"static struct hostapd_config *hostapd_config_defaults(void){	struct hostapd_config *conf;	conf = malloc(sizeof(*conf) + sizeof(struct hostapd_radius_servers));	if (conf == NULL) {		printf("Failed to allocate memory for configuration data.\n");		return NULL;	}	memset(conf, 0, sizeof(*conf) + sizeof(struct hostapd_radius_servers));	conf->radius = (struct hostapd_radius_servers *) (conf + 1);	/* set default driver based on configuration */	conf->driver = driver_lookup("default");	if (conf->driver == NULL) {		printf("No default driver registered!\n");		free(conf);		return NULL;	}	conf->wep_rekeying_period = 300;	conf->eap_reauth_period = 3600;	conf->logger_syslog_level = HOSTAPD_LEVEL_INFO;	conf->logger_stdout_level = HOSTAPD_LEVEL_INFO;	conf->logger_syslog = (unsigned int) -1;	conf->logger_stdout = (unsigned int) -1;	conf->auth_algs = HOSTAPD_AUTH_OPEN | HOSTAPD_AUTH_SHARED_KEY;	conf->wpa_group_rekey = 600;	conf->wpa_gmk_rekey = 86400;	conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK;	conf->wpa_pairwise = WPA_CIPHER_TKIP;	conf->wpa_group = WPA_CIPHER_TKIP;	conf->radius_server_auth_port = 1812;	return conf;}static int hostapd_parse_ip_addr(const char *txt, struct hostapd_ip_addr *addr){	if (inet_aton(txt, &addr->u.v4)) {		addr->af = AF_INET;		return 0;	}#ifdef CONFIG_IPV6	if (inet_pton(AF_INET6, txt, &addr->u.v6) > 0) {		addr->af = AF_INET6;		return 0;	}#endif /* CONFIG_IPV6 */	return -1;}static int mac_comp(const void *a, const void *b){	return memcmp(a, b, sizeof(macaddr));}static int hostapd_config_read_maclist(const char *fname, macaddr **acl,				       int *num){	FILE *f;	char buf[128], *pos;	int line = 0;	u8 addr[ETH_ALEN];	macaddr *newacl;	if (!fname)		return 0;	f = fopen(fname, "r");	if (!f) {		printf("MAC list file '%s' not found.\n", fname);		return -1;	}	while (fgets(buf, sizeof(buf), f)) {		line++;		if (buf[0] == '#')			continue;		pos = buf;		while (*pos != '\0') {			if (*pos == '\n') {				*pos = '\0';				break;			}			pos++;		}		if (buf[0] == '\0')			continue;		if (hwaddr_aton(buf, addr)) {			printf("Invalid MAC address '%s' at line %d in '%s'\n",			       buf, line, fname);			fclose(f);			return -1;		}		newacl = (macaddr *) realloc(*acl, (*num + 1) * ETH_ALEN);		if (newacl == NULL) {			printf("MAC list reallocation failed\n");			fclose(f);			return -1;		}		*acl = newacl;		memcpy((*acl)[*num], addr, ETH_ALEN);		(*num)++;	}	fclose(f);	qsort(*acl, *num, sizeof(macaddr), mac_comp);	return 0;}static int hostapd_config_read_wpa_psk(const char *fname,				       struct hostapd_config *conf){	FILE *f;	char buf[128], *pos;	int line = 0, ret = 0, len, ok;	u8 addr[ETH_ALEN];	struct hostapd_wpa_psk *psk;	if (!fname)		return 0;	f = fopen(fname, "r");	if (!f) {		printf("WPA PSK file '%s' not found.\n", fname);		return -1;	}	while (fgets(buf, sizeof(buf), f)) {		line++;		if (buf[0] == '#')			continue;		pos = buf;		while (*pos != '\0') {			if (*pos == '\n') {				*pos = '\0';				break;			}			pos++;		}		if (buf[0] == '\0')			continue;		if (hwaddr_aton(buf, addr)) {			printf("Invalid MAC address '%s' on line %d in '%s'\n",			       buf, line, fname);			ret = -1;			break;		}		psk = malloc(sizeof(*psk));		if (psk == NULL) {			printf("WPA PSK allocation failed\n");			ret = -1;			break;		}		memset(psk, 0, sizeof(*psk));		if (memcmp(addr, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)			psk->group = 1;		else			memcpy(psk->addr, addr, ETH_ALEN);		pos = buf + 17;		if (pos == '\0') {			printf("No PSK on line %d in '%s'\n", line, fname);			free(psk);			ret = -1;			break;		}		pos++;		ok = 0;		len = strlen(pos);		if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)			ok = 1;		else if (len >= 8 && len < 64) {			pbkdf2_sha1(pos, conf->ssid, conf->ssid_len,				    4096, psk->psk, PMK_LEN);			ok = 1;		}		if (!ok) {			printf("Invalid PSK '%s' on line %d in '%s'\n",			       pos, line, fname);			free(psk);			ret = -1;			break;		}		psk->next = conf->wpa_psk;		conf->wpa_psk = psk;	}	fclose(f);	return ret;}int hostapd_setup_wpa_psk(struct hostapd_config *conf){	if (conf->wpa_passphrase != NULL) {		if (conf->wpa_psk != NULL) {			printf("Warning: both WPA PSK and passphrase set. "			       "Using passphrase.\n");			free(conf->wpa_psk);		}		conf->wpa_psk = malloc(sizeof(struct hostapd_wpa_psk));		if (conf->wpa_psk == NULL) {			printf("Unable to alloc space for PSK\n");			return -1;		}		wpa_hexdump_ascii(MSG_DEBUG, "SSID",				  (u8 *) conf->ssid, conf->ssid_len);		wpa_hexdump_ascii(MSG_DEBUG, "PSK (ASCII passphrase)",				  (u8 *) conf->wpa_passphrase,				  strlen(conf->wpa_passphrase));		memset(conf->wpa_psk, 0, sizeof(struct hostapd_wpa_psk));		pbkdf2_sha1(conf->wpa_passphrase,			    conf->ssid, conf->ssid_len,			    4096, conf->wpa_psk->psk, PMK_LEN);		wpa_hexdump(MSG_DEBUG, "PSK (from passphrase)",			    conf->wpa_psk->psk, PMK_LEN);		conf->wpa_psk->group = 1;		memset(conf->wpa_passphrase, 0, strlen(conf->wpa_passphrase));		free(conf->wpa_passphrase);		conf->wpa_passphrase = 0;	}	if (conf->wpa_psk_file) {		if (hostapd_config_read_wpa_psk(conf->wpa_psk_file, conf))			return -1;		free(conf->wpa_psk_file);		conf->wpa_psk_file = NULL;	}	return 0;}#ifdef EAP_SERVERstatic int hostapd_config_read_eap_user(const char *fname,					struct hostapd_config *conf){	FILE *f;	char buf[512], *pos, *start, *pos2;	int line = 0, ret = 0, num_methods;	struct hostapd_eap_user *user, *tail = NULL;	if (!fname)		return 0;	f = fopen(fname, "r");	if (!f) {		printf("EAP user file '%s' not found.\n", fname);		return -1;	}	/* Lines: "user" METHOD,METHOD2 "password" (password optional) */	while (fgets(buf, sizeof(buf), f)) {		line++;		if (buf[0] == '#')			continue;		pos = buf;		while (*pos != '\0') {			if (*pos == '\n') {				*pos = '\0';				break;			}			pos++;		}		if (buf[0] == '\0')			continue;		user = NULL;		if (buf[0] != '"' && buf[0] != '*') {			printf("Invalid EAP identity (no \" in start) on "			       "line %d in '%s'\n", line, fname);			goto failed;		}		user = malloc(sizeof(*user));		if (user == NULL) {			printf("EAP user allocation failed\n");			goto failed;		}		memset(user, 0, sizeof(*user));		user->force_version = -1;		if (buf[0] == '*') {			pos = buf;		} else {			pos = buf + 1;			start = pos;			while (*pos != '"' && *pos != '\0')				pos++;			if (*pos == '\0') {				printf("Invalid EAP identity (no \" in end) on"				       " line %d in '%s'\n", line, fname);				goto failed;			}			user->identity = malloc(pos - start);			if (user->identity == NULL) {				printf("Failed to allocate memory for EAP "				       "identity\n");				goto failed;			}			memcpy(user->identity, start, pos - start);			user->identity_len = pos - start;		}		pos++;		while (*pos == ' ' || *pos == '\t')			pos++;		if (*pos == '\0') {			printf("No EAP method on line %d in '%s'\n",			       line, fname);			goto failed;		}		start = pos;		while (*pos != ' ' && *pos != '\t' && *pos != '\0')			pos++;		if (*pos == '\0') {			pos = NULL;		} else {			*pos = '\0';			pos++;		}		num_methods = 0;		while (*start) {			char *pos2 = strchr(start, ',');			if (pos2) {				*pos2++ = '\0';			}			user->methods[num_methods] = eap_get_type(start);			if (user->methods[num_methods] == EAP_TYPE_NONE) {				printf("Unsupported EAP type '%s' on line %d "				       "in '%s'\n", start, line, fname);				goto failed;			}			num_methods++;			if (num_methods >= EAP_USER_MAX_METHODS)				break;			if (pos2 == NULL)				break;			start = pos2;		}		if (num_methods == 0) {			printf("No EAP types configured on line %d in '%s'\n",			       line, fname);			goto failed;		}		if (pos == NULL)			goto done;		while (*pos == ' ' || *pos == '\t')			pos++;		if (*pos == '\0')			goto done;		if (strncmp(pos, "[ver=0]", 7) == 0) {			user->force_version = 0;			goto done;		}		if (strncmp(pos, "[ver=1]", 7) == 0) {			user->force_version = 1;			goto done;		}		if (strncmp(pos, "[2]", 3) == 0) {			user->phase2 = 1;			goto done;		}		if (*pos == '"') {			pos++;			start = pos;			while (*pos != '"' && *pos != '\0')				pos++;			if (*pos == '\0') {				printf("Invalid EAP password (no \" in end) "				       "on line %d in '%s'\n", line, fname);				goto failed;			}			user->password = malloc(pos - start);			if (user->password == NULL) {				printf("Failed to allocate memory for EAP "				       "password\n");				goto failed;			}			memcpy(user->password, start, pos - start);			user->password_len = pos - start;			pos++;		} else {			pos2 = pos;			while (*pos2 != '\0' && *pos2 != ' ' &&			       *pos2 != '\t' && *pos2 != '#')				pos2++;			if ((pos2 - pos) & 1) {				printf("Invalid hex password on line %d in "				       "'%s'\n", line, fname);				goto failed;			}			user->password = malloc((pos2 - pos) / 2);			if (user->password == NULL) {				printf("Failed to allocate memory for EAP "				       "password\n");				goto failed;			}			if (hexstr2bin(pos, user->password,				       (pos2 - pos) / 2) < 0) {				printf("Invalid hex password on line %d in "				       "'%s'\n", line, fname);				goto failed;			}			user->password_len = (pos2 - pos) / 2;			pos = pos2;		}		while (*pos == ' ' || *pos == '\t')			pos++;		if (strncmp(pos, "[2]", 3) == 0) {			user->phase2 = 1;		}	done:		if (tail == NULL) {			tail = conf->eap_user = user;		} else {			tail->next = user;			tail = user;		}		continue;	failed:		if (user) {			free(user->identity);			free(user);		}		ret = -1;		break;	}	fclose(f);	return ret;}#endif /* EAP_SERVER */static inthostapd_config_read_radius_addr(struct hostapd_radius_server **server,				int *num_server, const char *val, int def_port,				struct hostapd_radius_server **curr_serv){	struct hostapd_radius_server *nserv;	int ret;	static int server_index = 1;	nserv = realloc(*server, (*num_server + 1) * sizeof(*nserv));	if (nserv == NULL)		return -1;	*server = nserv;	nserv = &nserv[*num_server];	(*num_server)++;	(*curr_serv) = nserv;	memset(nserv, 0, sizeof(*nserv));	nserv->port = def_port;	ret = hostapd_parse_ip_addr(val, &nserv->addr);	nserv->index = server_index++;	return ret;}static int hostapd_config_parse_key_mgmt(int line, const char *value){	int val = 0, last;	char *start, *end, *buf;	buf = strdup(value);	if (buf == NULL)		return -1;	start = buf;	while (start != '\0') {		while (*start == ' ' || *start == '\t')			start++;		if (*start == '\0')			break;		end = start;		while (*end != ' ' && *end != '\t' && *end != '\0')			end++;		last = *end == '\0';		*end = '\0';		if (strcmp(start, "WPA-PSK") == 0)			val |= WPA_KEY_MGMT_PSK;		else if (strcmp(start, "WPA-EAP") == 0)			val |= WPA_KEY_MGMT_IEEE8021X;		else {			printf("Line %d: invalid key_mgmt '%s'", line, start);			free(buf);			return -1;		}		if (last)			break;		start = end + 1;	}	free(buf);	if (val == 0) {		printf("Line %d: no key_mgmt values configured.", line);		return -1;	}	return val;}static int hostapd_config_parse_cipher(int line, const char *value){	int val = 0, last;	char *start, *end, *buf;	buf = strdup(value);	if (buf == NULL)		return -1;	start = buf;	while (start != '\0') {		while (*start == ' ' || *start == '\t')			start++;		if (*start == '\0')			break;		end = start;		while (*end != ' ' && *end != '\t' && *end != '\0')			end++;		last = *end == '\0';		*end = '\0';		if (strcmp(start, "CCMP") == 0)			val |= WPA_CIPHER_CCMP;		else if (strcmp(start, "TKIP") == 0)			val |= WPA_CIPHER_TKIP;		else if (strcmp(start, "WEP104") == 0)			val |= WPA_CIPHER_WEP104;

⌨️ 快捷键说明

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