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

📄 wps_hostapd.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * hostapd / WPS integration * Copyright (c) 2008, 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. */#include "includes.h"#include "hostapd.h"#include "driver.h"#include "eloop.h"#include "uuid.h"#include "wpa_ctrl.h"#include "ieee802_11_defs.h"#include "sta_info.h"#include "eapol_sm.h"#include "wps/wps.h"#include "wps/wps_defs.h"#include "wps/wps_dev_attr.h"#include "wps_hostapd.h"#ifdef CONFIG_WPS_UPNP#include "wps/wps_upnp.h"static int hostapd_wps_upnp_init(struct hostapd_data *hapd,				 struct wps_context *wps);static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd);#endif /* CONFIG_WPS_UPNP */static int hostapd_wps_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *psk,				  size_t psk_len){	struct hostapd_data *hapd = ctx;	struct hostapd_wpa_psk *p;	struct hostapd_ssid *ssid = &hapd->conf->ssid;	wpa_printf(MSG_DEBUG, "Received new WPA/WPA2-PSK from WPS for STA "		   MACSTR, MAC2STR(mac_addr));	wpa_hexdump_key(MSG_DEBUG, "Per-device PSK", psk, psk_len);	if (psk_len != PMK_LEN) {		wpa_printf(MSG_DEBUG, "Unexpected PSK length %lu",			   (unsigned long) psk_len);		return -1;	}	/* Add the new PSK to runtime PSK list */	p = os_zalloc(sizeof(*p));	if (p == NULL)		return -1;	os_memcpy(p->addr, mac_addr, ETH_ALEN);	os_memcpy(p->psk, psk, PMK_LEN);	p->next = ssid->wpa_psk;	ssid->wpa_psk = p;	if (ssid->wpa_psk_file) {		FILE *f;		char hex[PMK_LEN * 2 + 1];		/* Add the new PSK to PSK list file */		f = fopen(ssid->wpa_psk_file, "a");		if (f == NULL) {			wpa_printf(MSG_DEBUG, "Failed to add the PSK to "				   "'%s'", ssid->wpa_psk_file);			return -1;		}		wpa_snprintf_hex(hex, sizeof(hex), psk, psk_len);		fprintf(f, MACSTR " %s\n", MAC2STR(mac_addr), hex);		fclose(f);	}	return 0;}static int hostapd_wps_set_ie_cb(void *ctx, const u8 *beacon_ie,				 size_t beacon_ie_len, const u8 *probe_resp_ie,				 size_t probe_resp_ie_len){	struct hostapd_data *hapd = ctx;	os_free(hapd->wps_beacon_ie);	if (beacon_ie_len == 0) {		hapd->wps_beacon_ie = NULL;		hapd->wps_beacon_ie_len = 0;	} else {		hapd->wps_beacon_ie = os_malloc(beacon_ie_len);		if (hapd->wps_beacon_ie == NULL) {			hapd->wps_beacon_ie_len = 0;			return -1;		}		os_memcpy(hapd->wps_beacon_ie, beacon_ie, beacon_ie_len);		hapd->wps_beacon_ie_len = beacon_ie_len;	}	hostapd_set_wps_beacon_ie(hapd, hapd->wps_beacon_ie,				  hapd->wps_beacon_ie_len);	os_free(hapd->wps_probe_resp_ie);	if (probe_resp_ie_len == 0) {		hapd->wps_probe_resp_ie = NULL;		hapd->wps_probe_resp_ie_len = 0;	} else {		hapd->wps_probe_resp_ie = os_malloc(probe_resp_ie_len);		if (hapd->wps_probe_resp_ie == NULL) {			hapd->wps_probe_resp_ie_len = 0;			return -1;		}		os_memcpy(hapd->wps_probe_resp_ie, probe_resp_ie,			  probe_resp_ie_len);		hapd->wps_probe_resp_ie_len = probe_resp_ie_len;	}	hostapd_set_wps_probe_resp_ie(hapd, hapd->wps_probe_resp_ie,				      hapd->wps_probe_resp_ie_len);	return 0;}static void hostapd_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,				      const struct wps_device_data *dev){	struct hostapd_data *hapd = ctx;	char uuid[40], txt[400];	int len;	if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))		return;	wpa_printf(MSG_DEBUG, "WPS: PIN needed for E-UUID %s", uuid);	len = os_snprintf(txt, sizeof(txt), WPS_EVENT_PIN_NEEDED			  "%s " MACSTR " [%s|%s|%s|%s|%s|%d-%08X-%d]",			  uuid, MAC2STR(dev->mac_addr), dev->device_name,			  dev->manufacturer, dev->model_name,			  dev->model_number, dev->serial_number,			  dev->categ, dev->oui, dev->sub_categ);	if (len > 0 && len < (int) sizeof(txt))		wpa_msg(hapd, MSG_INFO, "%s", txt);	if (hapd->conf->wps_pin_requests) {		FILE *f;		struct os_time t;		f = fopen(hapd->conf->wps_pin_requests, "a");		if (f == NULL)			return;		os_get_time(&t);		fprintf(f, "%ld\t%s\t" MACSTR "\t%s\t%s\t%s\t%s\t%s"			"\t%d-%08X-%d\n",			t.sec, uuid, MAC2STR(dev->mac_addr), dev->device_name,			dev->manufacturer, dev->model_name, dev->model_number,			dev->serial_number,			dev->categ, dev->oui, dev->sub_categ);		fclose(f);	}}static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,				       const u8 *uuid_e){	struct hostapd_data *hapd = ctx;	char uuid[40];	if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))		return;	wpa_msg(hapd, MSG_INFO, WPS_EVENT_REG_SUCCESS MACSTR " %s",		MAC2STR(mac_addr), uuid);}static int str_starts(const char *str, const char *start){	return os_strncmp(str, start, os_strlen(start)) == 0;}static void wps_reload_config(void *eloop_data, void *user_ctx){	struct hostapd_iface *iface = eloop_data;	wpa_printf(MSG_DEBUG, "WPS: Reload configuration data");	if (hostapd_reload_config(iface) < 0) {		wpa_printf(MSG_WARNING, "WPS: Failed to reload the updated "			   "configuration");	}}static int hostapd_wps_cred_cb(void *ctx, const struct wps_credential *cred){	struct hostapd_data *hapd = ctx;	FILE *oconf, *nconf;	size_t len, i;	char *tmp_fname;	char buf[1024];	int multi_bss;	int wpa;	wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",			cred->cred_attr, cred->cred_attr_len);	wpa_printf(MSG_DEBUG, "WPS: Received new AP Settings");	wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len);	wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x",		   cred->auth_type);	wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type);	wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx);	wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",			cred->key, cred->key_len);	wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR,		   MAC2STR(cred->mac_addr));	if ((hapd->conf->wps_cred_processing == 1 ||	     hapd->conf->wps_cred_processing == 2) && cred->cred_attr) {		size_t blen = cred->cred_attr_len * 2 + 1;		char *buf = os_malloc(blen);		if (buf) {			wpa_snprintf_hex(buf, blen,					 cred->cred_attr, cred->cred_attr_len);			wpa_msg(hapd, MSG_INFO, "%s%s",				WPS_EVENT_NEW_AP_SETTINGS, buf);			os_free(buf);		}	} else		wpa_msg(hapd, MSG_INFO, WPS_EVENT_NEW_AP_SETTINGS);	if (hapd->conf->wps_cred_processing == 1)		return 0;	len = os_strlen(hapd->iface->config_fname) + 5;	tmp_fname = os_malloc(len);	if (tmp_fname == NULL)		return -1;	os_snprintf(tmp_fname, len, "%s-new", hapd->iface->config_fname);	oconf = fopen(hapd->iface->config_fname, "r");	if (oconf == NULL) {		wpa_printf(MSG_WARNING, "WPS: Could not open current "			   "configuration file");		os_free(tmp_fname);		return -1;	}	nconf = fopen(tmp_fname, "w");	if (nconf == NULL) {		wpa_printf(MSG_WARNING, "WPS: Could not write updated "			   "configuration file");		os_free(tmp_fname);		fclose(oconf);		return -1;	}	fprintf(nconf, "# WPS configuration - START\n");	fprintf(nconf, "wps_state=2\n");	fprintf(nconf, "ssid=");	for (i = 0; i < cred->ssid_len; i++)		fputc(cred->ssid[i], nconf);	fprintf(nconf, "\n");	if ((cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) &&	    (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK)))		wpa = 3;	else if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK))		wpa = 2;	else if (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK))		wpa = 1;	else		wpa = 0;	if (wpa) {		char *prefix;		fprintf(nconf, "wpa=%d\n", wpa);		fprintf(nconf, "wpa_key_mgmt=");		prefix = "";		if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA)) {			fprintf(nconf, "WPA-EAP");			prefix = " ";		}		if (cred->auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK))			fprintf(nconf, "%sWPA-PSK", prefix);		fprintf(nconf, "\n");		fprintf(nconf, "wpa_pairwise=");		prefix = "";		if (cred->encr_type & WPS_ENCR_AES) {			fprintf(nconf, "CCMP");			prefix = " ";		}		if (cred->encr_type & WPS_ENCR_TKIP) {			fprintf(nconf, "%sTKIP", prefix);		}		fprintf(nconf, "\n");		if (cred->key_len >= 8 && cred->key_len < 64) {			fprintf(nconf, "wpa_passphrase=");			for (i = 0; i < cred->key_len; i++)				fputc(cred->key[i], nconf);			fprintf(nconf, "\n");		} else if (cred->key_len == 64) {			fprintf(nconf, "wpa_psk=");			for (i = 0; i < cred->key_len; i++)				fputc(cred->key[i], nconf);			fprintf(nconf, "\n");		} else {			wpa_printf(MSG_WARNING, "WPS: Invalid key length %lu "				   "for WPA/WPA2",				   (unsigned long) cred->key_len);		}		fprintf(nconf, "auth_algs=1\n");	} else {		if ((cred->auth_type & WPS_AUTH_OPEN) &&		    (cred->auth_type & WPS_AUTH_SHARED))			fprintf(nconf, "auth_algs=3\n");		else if (cred->auth_type & WPS_AUTH_SHARED)			fprintf(nconf, "auth_algs=2\n");		else			fprintf(nconf, "auth_algs=1\n");		if (cred->encr_type & WPS_ENCR_WEP && cred->key_idx <= 4) {			int key_idx = cred->key_idx;			if (key_idx)				key_idx--;			fprintf(nconf, "wep_default_key=%d\n", key_idx);			fprintf(nconf, "wep_key%d=", key_idx);			if (cred->key_len == 10 || cred->key_len == 26) {				/* WEP key as a hex string */				for (i = 0; i < cred->key_len; i++)					fputc(cred->key[i], nconf);			} else {				/* Raw WEP key; convert to hex */				for (i = 0; i < cred->key_len; i++)					fprintf(nconf, "%02x", cred->key[i]);			}			fprintf(nconf, "\n");		}	}	fprintf(nconf, "# WPS configuration - END\n");	multi_bss = 0;	while (fgets(buf, sizeof(buf), oconf)) {		if (os_strncmp(buf, "bss=", 4) == 0)			multi_bss = 1;		if (!multi_bss &&		    (str_starts(buf, "ssid=") ||		     str_starts(buf, "auth_algs=") ||		     str_starts(buf, "wps_state=") ||		     str_starts(buf, "wpa=") ||		     str_starts(buf, "wpa_psk=") ||		     str_starts(buf, "wpa_pairwise=") ||		     str_starts(buf, "rsn_pairwise=") ||		     str_starts(buf, "wpa_key_mgmt=") ||		     str_starts(buf, "wpa_passphrase="))) {			fprintf(nconf, "#WPS# %s", buf);		} else			fprintf(nconf, "%s", buf);	}	fclose(nconf);	fclose(oconf);	if (rename(tmp_fname, hapd->iface->config_fname) < 0) {		wpa_printf(MSG_WARNING, "WPS: Failed to rename the updated "			   "configuration file: %s", strerror(errno));		os_free(tmp_fname);		return -1;	}	os_free(tmp_fname);	/* Schedule configuration reload after short period of time to allow	 * EAP-WSC to be finished.	 */	eloop_register_timeout(0, 100000, wps_reload_config, hapd->iface,			       NULL);	/* TODO: dualband AP may need to update multiple configuration files */	wpa_printf(MSG_DEBUG, "WPS: AP configuration updated");	return 0;}static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,				  struct wps_event_pwd_auth_fail *data){	FILE *f;	if (!data->enrollee)		return;	/*	 * Registrar failed to prove its knowledge of the AP PIN. Lock AP setup	 * if this happens multiple times.	 */	hapd->ap_pin_failures++;	if (hapd->ap_pin_failures < 4)		return;	wpa_msg(hapd, MSG_INFO, WPS_EVENT_AP_SETUP_LOCKED);	hapd->wps->ap_setup_locked = 1;	wps_registrar_update_ie(hapd->wps->registrar);	if (hapd->conf->wps_cred_processing == 1)		return;	f = fopen(hapd->iface->config_fname, "a");	if (f == NULL) {		wpa_printf(MSG_WARNING, "WPS: Could not append to the current "			   "configuration file");		return;	}	fprintf(f, "# WPS AP Setup Locked based on possible attack\n");	fprintf(f, "ap_setup_locked=1\n");	fclose(f);	/* TODO: dualband AP may need to update multiple configuration files */	wpa_printf(MSG_DEBUG, "WPS: AP configuration updated");}static void hostapd_wps_event_cb(void *ctx, enum wps_event event,				 union wps_event_data *data){	struct hostapd_data *hapd = ctx;	if (event == WPS_EV_PWD_AUTH_FAIL)		hostapd_pwd_auth_fail(hapd, &data->pwd_auth_fail);}static void hostapd_wps_clear_ies(struct hostapd_data *hapd){	os_free(hapd->wps_beacon_ie);	hapd->wps_beacon_ie = NULL;	hapd->wps_beacon_ie_len = 0;	hostapd_set_wps_beacon_ie(hapd, NULL, 0);	os_free(hapd->wps_probe_resp_ie);	hapd->wps_probe_resp_ie = NULL;	hapd->wps_probe_resp_ie_len = 0;	hostapd_set_wps_probe_resp_ie(hapd, NULL, 0);}int hostapd_init_wps(struct hostapd_data *hapd,		     struct hostapd_bss_config *conf){	struct wps_context *wps;	struct wps_registrar_config cfg;	if (conf->wps_state == 0) {		hostapd_wps_clear_ies(hapd);		return 0;	}	wps = os_zalloc(sizeof(*wps));	if (wps == NULL)		return -1;	wps->cred_cb = hostapd_wps_cred_cb;	wps->event_cb = hostapd_wps_event_cb;	wps->cb_ctx = hapd;	os_memset(&cfg, 0, sizeof(cfg));	wps->wps_state = hapd->conf->wps_state;	wps->ap_setup_locked = hapd->conf->ap_setup_locked;	if (is_nil_uuid(hapd->conf->uuid)) {		uuid_gen_mac_addr(hapd->own_addr, wps->uuid);		wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC address",			    wps->uuid, UUID_LEN);	} else		os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN);	wps->ssid_len = hapd->conf->ssid.ssid_len;	os_memcpy(wps->ssid, hapd->conf->ssid.ssid, wps->ssid_len);	wps->ap = 1;	os_memcpy(wps->dev.mac_addr, hapd->own_addr, ETH_ALEN);	wps->dev.device_name = hapd->conf->device_name ?		os_strdup(hapd->conf->device_name) : NULL;	wps->dev.manufacturer = hapd->conf->manufacturer ?		os_strdup(hapd->conf->manufacturer) : NULL;	wps->dev.model_name = hapd->conf->model_name ?		os_strdup(hapd->conf->model_name) : NULL;	wps->dev.model_number = hapd->conf->model_number ?		os_strdup(hapd->conf->model_number) : NULL;	wps->dev.serial_number = hapd->conf->serial_number ?		os_strdup(hapd->conf->serial_number) : NULL;	if (hapd->conf->config_methods) {		char *m = hapd->conf->config_methods;		if (os_strstr(m, "label"))

⌨️ 快捷键说明

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