config.c

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

C
1,216
字号
		else if (strcmp(start, "WEP40") == 0)			val |= WPA_CIPHER_WEP40;		else if (strcmp(start, "NONE") == 0)			val |= WPA_CIPHER_NONE;		else {			printf("Line %d: invalid cipher '%s'.", line, start);			free(buf);			return -1;		}		if (last)			break;		start = end + 1;	}	free(buf);	if (val == 0) {		printf("Line %d: no cipher values configured.", line);		return -1;	}	return val;}static int hostapd_config_check(struct hostapd_config *conf){	if (conf->ieee802_1x && !conf->eap_server &&	    !conf->radius->auth_servers) {		printf("Invalid IEEE 802.1X configuration (no EAP "		       "authenticator configured).\n");		return -1;	}	if (conf->wpa && (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&	    conf->wpa_psk == NULL && conf->wpa_passphrase == NULL &&	    conf->wpa_psk_file == NULL) {		printf("WPA-PSK enabled, but PSK or passphrase is not "		       "configured.\n");		return -1;	}	return 0;}struct hostapd_config * hostapd_config_read(const char *fname){	struct hostapd_config *conf;	FILE *f;	char buf[256], *pos;	int line = 0;	int errors = 0;	char *accept_mac_file = NULL, *deny_mac_file = NULL;#ifdef EAP_SERVER	char *eap_user_file = NULL;#endif /* EAP_SERVER */	f = fopen(fname, "r");	if (f == NULL) {		printf("Could not open configuration file '%s' for reading.\n",		       fname);		return NULL;	}	conf = hostapd_config_defaults();	if (conf == NULL) {		fclose(f);		return NULL;	}	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;		pos = strchr(buf, '=');		if (pos == NULL) {			printf("Line %d: invalid line '%s'\n", line, buf);			errors++;			continue;		}		*pos = '\0';		pos++;		if (strcmp(buf, "interface") == 0) {			snprintf(conf->iface, sizeof(conf->iface), "%s", pos);		} else if (strcmp(buf, "bridge") == 0) {			snprintf(conf->bridge, sizeof(conf->bridge), "%s",				 pos);		} else if (strcmp(buf, "driver") == 0) {			conf->driver = driver_lookup(pos);			if (conf->driver == NULL) {				printf("Line %d: invalid/unknown driver "				       "'%s'\n", line, pos);				errors++;			}		} else if (strcmp(buf, "debug") == 0) {			conf->debug = atoi(pos);		} else if (strcmp(buf, "logger_syslog_level") == 0) {			conf->logger_syslog_level = atoi(pos);		} else if (strcmp(buf, "logger_stdout_level") == 0) {			conf->logger_stdout_level = atoi(pos);		} else if (strcmp(buf, "logger_syslog") == 0) {			conf->logger_syslog = atoi(pos);		} else if (strcmp(buf, "logger_stdout") == 0) {			conf->logger_stdout = atoi(pos);		} else if (strcmp(buf, "dump_file") == 0) {			conf->dump_log_name = strdup(pos);		} else if (strcmp(buf, "ssid") == 0) {			conf->ssid_len = strlen(pos);			if (conf->ssid_len >= HOSTAPD_SSID_LEN ||			    conf->ssid_len < 1) {				printf("Line %d: invalid SSID '%s'\n", line,				       pos);				errors++;			}			memcpy(conf->ssid, pos, conf->ssid_len);			conf->ssid[conf->ssid_len] = '\0';			conf->ssid_set = 1;		} else if (strcmp(buf, "macaddr_acl") == 0) {			conf->macaddr_acl = atoi(pos);			if (conf->macaddr_acl != ACCEPT_UNLESS_DENIED &&			    conf->macaddr_acl != DENY_UNLESS_ACCEPTED &&			    conf->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {				printf("Line %d: unknown macaddr_acl %d\n",				       line, conf->macaddr_acl);			}		} else if (strcmp(buf, "accept_mac_file") == 0) {			accept_mac_file = strdup(pos);			if (!accept_mac_file) {				printf("Line %d: allocation failed\n", line);				errors++;			}		} else if (strcmp(buf, "deny_mac_file") == 0) {			deny_mac_file = strdup(pos);			if (!deny_mac_file) {				printf("Line %d: allocation failed\n", line);				errors++;			}		} else if (strcmp(buf, "assoc_ap_addr") == 0) {			if (hwaddr_aton(pos, conf->assoc_ap_addr)) {				printf("Line %d: invalid MAC address '%s'\n",				       line, pos);				errors++;			}			conf->assoc_ap = 1;		} else if (strcmp(buf, "ieee8021x") == 0) {			conf->ieee802_1x = atoi(pos);#ifdef EAP_SERVER		} else if (strcmp(buf, "eap_authenticator") == 0) {			conf->eap_server = atoi(pos);			printf("Line %d: obsolete eap_authenticator used; "			       "this has been renamed to eap_server\n", line);		} else if (strcmp(buf, "eap_server") == 0) {			conf->eap_server = atoi(pos);		} else if (strcmp(buf, "eap_user_file") == 0) {			free(eap_user_file);			eap_user_file = strdup(pos);			if (!eap_user_file) {				printf("Line %d: allocation failed\n", line);				errors++;			}		} else if (strcmp(buf, "ca_cert") == 0) {			free(conf->ca_cert);			conf->ca_cert = strdup(pos);		} else if (strcmp(buf, "server_cert") == 0) {			free(conf->server_cert);			conf->server_cert = strdup(pos);		} else if (strcmp(buf, "private_key") == 0) {			free(conf->private_key);			conf->private_key = strdup(pos);		} else if (strcmp(buf, "private_key_passwd") == 0) {			free(conf->private_key_passwd);			conf->private_key_passwd = strdup(pos);		} else if (strcmp(buf, "check_crl") == 0) {			conf->check_crl = atoi(pos);#ifdef EAP_SIM		} else if (strcmp(buf, "eap_sim_db") == 0) {			free(conf->eap_sim_db);			conf->eap_sim_db = strdup(pos);#endif /* EAP_SIM */#endif /* EAP_SERVER */		} else if (strcmp(buf, "eap_message") == 0) {			char *term;			conf->eap_req_id_text = strdup(pos);			if (conf->eap_req_id_text == NULL) {				printf("Line %d: Failed to allocate memory "				       "for eap_req_id_text\n", line);				errors++;				continue;			}			conf->eap_req_id_text_len =				strlen(conf->eap_req_id_text);			term = strstr(conf->eap_req_id_text, "\\0");			if (term) {				*term++ = '\0';				memmove(term, term + 1,					conf->eap_req_id_text_len -					(term - conf->eap_req_id_text) - 1);				conf->eap_req_id_text_len--;			}		} else if (strcmp(buf, "wep_key_len_broadcast") == 0) {			conf->default_wep_key_len = atoi(pos);			if (conf->default_wep_key_len > 13) {				printf("Line %d: invalid WEP key len %lu "				       "(= %lu bits)\n", line,				       (unsigned long)				       conf->default_wep_key_len,				       (unsigned long)				       conf->default_wep_key_len * 8);				errors++;			}		} else if (strcmp(buf, "wep_key_len_unicast") == 0) {			conf->individual_wep_key_len = atoi(pos);			if (conf->individual_wep_key_len < 0 ||			    conf->individual_wep_key_len > 13) {				printf("Line %d: invalid WEP key len %d "				       "(= %d bits)\n", line,				       conf->individual_wep_key_len,				       conf->individual_wep_key_len * 8);				errors++;			}		} else if (strcmp(buf, "wep_rekey_period") == 0) {			conf->wep_rekeying_period = atoi(pos);			if (conf->wep_rekeying_period < 0) {				printf("Line %d: invalid period %d\n",				       line, conf->wep_rekeying_period);				errors++;			}		} else if (strcmp(buf, "eap_reauth_period") == 0) {			conf->eap_reauth_period = atoi(pos);			if (conf->eap_reauth_period < 0) {				printf("Line %d: invalid period %d\n",				       line, conf->eap_reauth_period);				errors++;			}		} else if (strcmp(buf, "eapol_key_index_workaround") == 0) {			conf->eapol_key_index_workaround = atoi(pos);#ifdef CONFIG_IAPP		} else if (strcmp(buf, "iapp_interface") == 0) {			conf->ieee802_11f = 1;			snprintf(conf->iapp_iface, sizeof(conf->iapp_iface),				 "%s", pos);#endif /* CONFIG_IAPP */		} else if (strcmp(buf, "own_ip_addr") == 0) {			if (hostapd_parse_ip_addr(pos, &conf->own_ip_addr)) {				printf("Line %d: invalid IP address '%s'\n",				       line, pos);				errors++;			}		} else if (strcmp(buf, "nas_identifier") == 0) {			conf->nas_identifier = strdup(pos);		} else if (strcmp(buf, "auth_server_addr") == 0) {			if (hostapd_config_read_radius_addr(				    &conf->radius->auth_servers,				    &conf->radius->num_auth_servers, pos, 1812,				    &conf->radius->auth_server)) {				printf("Line %d: invalid IP address '%s'\n",				       line, pos);				errors++;			}		} else if (conf->radius->auth_server &&			   strcmp(buf, "auth_server_port") == 0) {			conf->radius->auth_server->port = atoi(pos);		} else if (conf->radius->auth_server &&			   strcmp(buf, "auth_server_shared_secret") == 0) {			int len = strlen(pos);			if (len == 0) {				/* RFC 2865, Ch. 3 */				printf("Line %d: empty shared secret is not "				       "allowed.\n", line);				errors++;			}			conf->radius->auth_server->shared_secret =				(u8 *) strdup(pos);			conf->radius->auth_server->shared_secret_len = len;		} else if (strcmp(buf, "acct_server_addr") == 0) {			if (hostapd_config_read_radius_addr(				    &conf->radius->acct_servers,				    &conf->radius->num_acct_servers, pos, 1813,				    &conf->radius->acct_server)) {				printf("Line %d: invalid IP address '%s'\n",				       line, pos);				errors++;			}		} else if (conf->radius->acct_server &&			   strcmp(buf, "acct_server_port") == 0) {			conf->radius->acct_server->port = atoi(pos);		} else if (conf->radius->acct_server &&			   strcmp(buf, "acct_server_shared_secret") == 0) {			int len = strlen(pos);			if (len == 0) {				/* RFC 2865, Ch. 3 */				printf("Line %d: empty shared secret is not "				       "allowed.\n", line);				errors++;			}			conf->radius->acct_server->shared_secret =				(u8 *) strdup(pos);			conf->radius->acct_server->shared_secret_len = len;		} else if (strcmp(buf, "radius_retry_primary_interval") == 0) {			conf->radius->retry_primary_interval = atoi(pos);		} else if (strcmp(buf, "radius_acct_interim_interval") == 0) {			conf->radius->acct_interim_interval = atoi(pos);		} else if (strcmp(buf, "auth_algs") == 0) {			conf->auth_algs = atoi(pos);			if (conf->auth_algs == 0) {				printf("Line %d: no authentication algorithms "				       "allowed\n",				       line);				errors++;			}		} else if (strcmp(buf, "wpa") == 0) {			conf->wpa = atoi(pos);		} else if (strcmp(buf, "wpa_group_rekey") == 0) {			conf->wpa_group_rekey = atoi(pos);		} else if (strcmp(buf, "wpa_strict_rekey") == 0) {			conf->wpa_strict_rekey = atoi(pos);		} else if (strcmp(buf, "wpa_gmk_rekey") == 0) {			conf->wpa_gmk_rekey = atoi(pos);		} else if (strcmp(buf, "wpa_passphrase") == 0) {			int len = strlen(pos);			if (len < 8 || len > 63) {				printf("Line %d: invalid WPA passphrase length"				       " %d (expected 8..63)\n", line, len);				errors++;			} else {				free(conf->wpa_passphrase);				conf->wpa_passphrase = strdup(pos);			}		} else if (strcmp(buf, "wpa_psk") == 0) {			free(conf->wpa_psk);			conf->wpa_psk = malloc(sizeof(struct hostapd_wpa_psk));			if (conf->wpa_psk) {				memset(conf->wpa_psk, 0,				       sizeof(struct hostapd_wpa_psk));			}			if (conf->wpa_psk == NULL)				errors++;			else if (hexstr2bin(pos, conf->wpa_psk->psk, PMK_LEN)				 || pos[PMK_LEN * 2] != '\0') {				printf("Line %d: Invalid PSK '%s'.\n", line,				       pos);				errors++;			} else {				conf->wpa_psk->group = 1;			}		} else if (strcmp(buf, "wpa_psk_file") == 0) {			free(conf->wpa_psk_file);			conf->wpa_psk_file = strdup(pos);			if (!conf->wpa_psk_file) {				printf("Line %d: allocation failed\n", line);				errors++;			}		} else if (strcmp(buf, "wpa_key_mgmt") == 0) {			conf->wpa_key_mgmt =				hostapd_config_parse_key_mgmt(line, pos);			if (conf->wpa_key_mgmt == -1)				errors++;		} else if (strcmp(buf, "wpa_pairwise") == 0) {			conf->wpa_pairwise =				hostapd_config_parse_cipher(line, pos);			if (conf->wpa_pairwise == -1 ||			    conf->wpa_pairwise == 0)				errors++;			else if (conf->wpa_pairwise &				 (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |				  WPA_CIPHER_WEP104)) {				printf("Line %d: unsupported pairwise "				       "cipher suite '%s'\n",				       conf->wpa_pairwise, pos);				errors++;			} else {				if (conf->wpa_pairwise & WPA_CIPHER_TKIP)					conf->wpa_group = WPA_CIPHER_TKIP;				else					conf->wpa_group = WPA_CIPHER_CCMP;			}#ifdef CONFIG_RSN_PREAUTH		} else if (strcmp(buf, "rsn_preauth") == 0) {			conf->rsn_preauth = atoi(pos);		} else if (strcmp(buf, "rsn_preauth_interfaces") == 0) {			conf->rsn_preauth_interfaces = strdup(pos);#endif /* CONFIG_RSN_PREAUTH */		} else if (strcmp(buf, "ctrl_interface") == 0) {			free(conf->ctrl_interface);			conf->ctrl_interface = strdup(pos);		} else if (strcmp(buf, "ctrl_interface_group") == 0) {			struct group *grp;			char *endp;			const char *group = pos;			grp = getgrnam(group);			if (grp) {				conf->ctrl_interface_gid = grp->gr_gid;				conf->ctrl_interface_gid_set = 1;				wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"					   " (from group name '%s')",					   conf->ctrl_interface_gid, group);				continue;			}			/* Group name not found - try to parse this as gid */			conf->ctrl_interface_gid = strtol(group, &endp, 10);			if (*group == '\0' || *endp != '\0') {				wpa_printf(MSG_DEBUG, "Line %d: Invalid group "					   "'%s'", line, group);				errors++;				continue;			}			conf->ctrl_interface_gid_set = 1;			wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",				   conf->ctrl_interface_gid);#ifdef RADIUS_SERVER		} else if (strcmp(buf, "radius_server_clients") == 0) {			free(conf->radius_server_clients);			conf->radius_server_clients = strdup(pos);		} else if (strcmp(buf, "radius_server_auth_port") == 0) {			conf->radius_server_auth_port = atoi(pos);		} else if (strcmp(buf, "radius_server_ipv6") == 0) {			conf->radius_server_ipv6 = atoi(pos);#endif /* RADIUS_SERVER */		} else if (strcmp(buf, "test_socket") == 0) {			free(conf->test_socket);			conf->test_socket = strdup(pos);		} else {			printf("Line %d: unknown configuration item '%s'\n",			       line, buf);			errors++;		}	}	fclose(f);	if (hostapd_config_read_maclist(accept_mac_file, &conf->accept_mac,					&conf->num_accept_mac))		errors++;	free(accept_mac_file);	if (hostapd_config_read_maclist(deny_mac_file, &conf->deny_mac,					&conf->num_deny_mac))		errors++;	free(deny_mac_file);#ifdef EAP_SERVER	if (hostapd_config_read_eap_user(eap_user_file, conf))		errors++;	free(eap_user_file);#endif /* EAP_SERVER */	conf->radius->auth_server = conf->radius->auth_servers;	conf->radius->acct_server = conf->radius->acct_servers;	if (hostapd_config_check(conf))		errors++;	if (errors) {		printf("%d errors found in configuration file '%s'\n",		       errors, fname);		hostapd_config_free(conf);		conf = NULL;	}	return conf;}static void hostapd_config_free_radius(struct hostapd_radius_server *servers,				       int num_servers){	int i;	for (i = 0; i < num_servers; i++) {		free(servers[i].shared_secret);	}	free(servers);}static void hostapd_config_free_eap_user(struct hostapd_eap_user *user){	free(user->identity);	free(user->password);	free(user);}void hostapd_config_free(struct hostapd_config *conf){	struct hostapd_wpa_psk *psk, *prev;	struct hostapd_eap_user *user, *prev_user;	if (conf == NULL)		return;	psk = conf->wpa_psk;	while (psk) {		prev = psk;		psk = psk->next;		free(prev);	}	free(conf->wpa_passphrase);	free(conf->wpa_psk_file);	user = conf->eap_user;	while (user) {		prev_user = user;		user = user->next;		hostapd_config_free_eap_user(prev_user);	}	free(conf->dump_log_name);	free(conf->eap_req_id_text);	free(conf->accept_mac);	free(conf->deny_mac);	free(conf->nas_identifier);	hostapd_config_free_radius(conf->radius->auth_servers,				   conf->radius->num_auth_servers);	hostapd_config_free_radius(conf->radius->acct_servers,				   conf->radius->num_acct_servers);	free(conf->rsn_preauth_interfaces);	free(conf->ctrl_interface);	free(conf->ca_cert);	free(conf->server_cert);	free(conf->private_key);	free(conf->private_key_passwd);	free(conf->eap_sim_db);	free(conf->radius_server_clients);	free(conf->test_socket);	free(conf);}/* Perform a binary search for given MAC address from a pre-sorted list. * Returns 1 if address is in the list or 0 if not. */int hostapd_maclist_found(macaddr *list, int num_entries, u8 *addr){	int start, end, middle, res;	start = 0;	end = num_entries - 1;	while (start <= end) {		middle = (start + end) / 2;		res = memcmp(list[middle], addr, ETH_ALEN);		if (res == 0)			return 1;		if (res < 0)			start = middle + 1;		else			end = middle - 1;	}	return 0;}const u8 * hostapd_get_psk(const struct hostapd_config *conf, const u8 *addr,			   const u8 *prev_psk){	struct hostapd_wpa_psk *psk;	int next_ok = prev_psk == NULL;	for (psk = conf->wpa_psk; psk != NULL; psk = psk->next) {		if (next_ok &&		    (psk->group || memcmp(psk->addr, addr, ETH_ALEN) == 0))			return psk->psk;		if (psk->psk == prev_psk)			next_ok = 1;	}	return NULL;}const struct hostapd_eap_user *hostapd_get_eap_user(const struct hostapd_config *conf, const u8 *identity,		     size_t identity_len, int phase2){	struct hostapd_eap_user *user = conf->eap_user;	while (user) {		if (!phase2 && user->identity == NULL) {			/* Wildcard match */			break;		}		if (user->phase2 == !!phase2 &&		    user->identity_len == identity_len &&		    memcmp(user->identity, identity, identity_len) == 0)			break;		user = user->next;	}	return user;}

⌨️ 快捷键说明

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