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

📄 wps_registrar.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Wi-Fi Protected Setup - Registrar * 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 "common.h"#include "sha256.h"#include "base64.h"#include "ieee802_11_defs.h"#include "eloop.h"#include "wps_i.h"#include "wps_dev_attr.h"#include "wps_upnp.h"struct wps_uuid_pin {	struct wps_uuid_pin *next;	u8 uuid[WPS_UUID_LEN];	int wildcard_uuid;	u8 *pin;	size_t pin_len;	int locked;};static void wps_free_pin(struct wps_uuid_pin *pin){	os_free(pin->pin);	os_free(pin);}static void wps_free_pins(struct wps_uuid_pin *pins){	struct wps_uuid_pin *pin, *prev;	pin = pins;	while (pin) {		prev = pin;		pin = pin->next;		wps_free_pin(prev);	}}struct wps_pbc_session {	struct wps_pbc_session *next;	u8 addr[ETH_ALEN];	u8 uuid_e[WPS_UUID_LEN];	struct os_time timestamp;};static void wps_free_pbc_sessions(struct wps_pbc_session *pbc){	struct wps_pbc_session *prev;	while (pbc) {		prev = pbc;		pbc = pbc->next;		os_free(prev);	}}struct wps_registrar {	struct wps_context *wps;	int pbc;	int selected_registrar;	int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,			  size_t psk_len);	int (*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);	void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,			      const struct wps_device_data *dev);	void (*reg_success_cb)(void *ctx, const u8 *mac_addr,			       const u8 *uuid_e);	void *cb_ctx;	struct wps_uuid_pin *pins;	struct wps_pbc_session *pbc_sessions;	int skip_cred_build;	struct wpabuf *extra_cred;	int disable_auto_conf;	int sel_reg_dev_password_id_override;	int sel_reg_config_methods_override;	int static_wep_only;};static int wps_set_ie(struct wps_registrar *reg);static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);static void wps_registrar_set_selected_timeout(void *eloop_ctx,					       void *timeout_ctx);static void wps_registrar_add_pbc_session(struct wps_registrar *reg,					  const u8 *addr, const u8 *uuid_e){	struct wps_pbc_session *pbc, *prev = NULL;	struct os_time now;	os_get_time(&now);	pbc = reg->pbc_sessions;	while (pbc) {		if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&		    os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {			if (prev)				prev->next = pbc->next;			else				reg->pbc_sessions = pbc->next;			break;		}		prev = pbc;		pbc = pbc->next;	}	if (!pbc) {		pbc = os_zalloc(sizeof(*pbc));		if (pbc == NULL)			return;		os_memcpy(pbc->addr, addr, ETH_ALEN);		if (uuid_e)			os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);	}	pbc->next = reg->pbc_sessions;	reg->pbc_sessions = pbc;	pbc->timestamp = now;	/* remove entries that have timed out */	prev = pbc;	pbc = pbc->next;	while (pbc) {		if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) {			prev->next = NULL;			wps_free_pbc_sessions(pbc);			break;		}		prev = pbc;		pbc = pbc->next;	}}static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,					     const u8 *addr, const u8 *uuid_e){	struct wps_pbc_session *pbc, *prev = NULL;	pbc = reg->pbc_sessions;	while (pbc) {		if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&		    os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {			if (prev)				prev->next = pbc->next;			else				reg->pbc_sessions = pbc->next;			os_free(pbc);			break;		}		prev = pbc;		pbc = pbc->next;	}}static int wps_registrar_pbc_overlap(struct wps_registrar *reg,				     const u8 *addr, const u8 *uuid_e){	int count = 0;	struct wps_pbc_session *pbc;	struct os_time now;	os_get_time(&now);	for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {		if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME)			break;		if (addr == NULL || os_memcmp(addr, pbc->addr, ETH_ALEN) ||		    uuid_e == NULL ||		    os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN))			count++;	}	if (addr || uuid_e)		count++;	return count > 1 ? 1 : 0;}static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg){	wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",		   wps->wps_state);	wpabuf_put_be16(msg, ATTR_WPS_STATE);	wpabuf_put_be16(msg, 1);	wpabuf_put_u8(msg, wps->wps_state);	return 0;}#ifdef CONFIG_WPS_UPNPstatic void wps_registrar_free_pending_m2(struct wps_context *wps){	struct upnp_pending_message *p, *p2, *prev = NULL;	p = wps->upnp_msgs;	while (p) {		if (p->type == WPS_M2 || p->type == WPS_M2D) {			if (prev == NULL)				wps->upnp_msgs = p->next;			else				prev->next = p->next;			wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D");			p2 = p;			p = p->next;			wpabuf_free(p2->msg);			os_free(p2);			continue;		}		prev = p;		p = p->next;	}}#endif /* CONFIG_WPS_UPNP */static int wps_build_ap_setup_locked(struct wps_context *wps,				     struct wpabuf *msg){	if (wps->ap_setup_locked) {		wpa_printf(MSG_DEBUG, "WPS:  * AP Setup Locked");		wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);		wpabuf_put_be16(msg, 1);		wpabuf_put_u8(msg, 1);	}	return 0;}static int wps_build_selected_registrar(struct wps_registrar *reg,					struct wpabuf *msg){	if (!reg->selected_registrar)		return 0;	wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar");	wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);	wpabuf_put_be16(msg, 1);	wpabuf_put_u8(msg, 1);	return 0;}static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,					     struct wpabuf *msg){	u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;	if (!reg->selected_registrar)		return 0;	if (reg->sel_reg_dev_password_id_override >= 0)		id = reg->sel_reg_dev_password_id_override;	wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID (%d)", id);	wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);	wpabuf_put_be16(msg, 2);	wpabuf_put_be16(msg, id);	return 0;}static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,					    struct wpabuf *msg){	u16 methods;	if (!reg->selected_registrar)		return 0;	methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;	if (reg->pbc)		methods |= WPS_CONFIG_PUSHBUTTON;	if (reg->sel_reg_config_methods_override >= 0)		methods = reg->sel_reg_config_methods_override;	wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar Config Methods (%x)",		   methods);	wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);	wpabuf_put_be16(msg, 2);	wpabuf_put_be16(msg, methods);	return 0;}static int wps_build_probe_config_methods(struct wps_registrar *reg,					  struct wpabuf *msg){	u16 methods;	methods = 0;	wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);	wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);	wpabuf_put_be16(msg, 2);	wpabuf_put_be16(msg, methods);	return 0;}static int wps_build_config_methods_r(struct wps_registrar *reg,				      struct wpabuf *msg){	u16 methods;	methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;	if (reg->pbc)		methods |= WPS_CONFIG_PUSHBUTTON;	return wps_build_config_methods(msg, methods);}static int wps_build_resp_type(struct wps_registrar *reg, struct wpabuf *msg){	u8 resp = reg->wps->ap ? WPS_RESP_AP : WPS_RESP_REGISTRAR;	wpa_printf(MSG_DEBUG, "WPS:  * Response Type (%d)", resp);	wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);	wpabuf_put_be16(msg, 1);	wpabuf_put_u8(msg, resp);	return 0;}/** * wps_registrar_init - Initialize WPS Registrar data * @wps: Pointer to longterm WPS context * @cfg: Registrar configuration * Returns: Pointer to allocated Registrar data or %NULL on failure * * This function is used to initialize WPS Registrar functionality. It can be * used for a single Registrar run (e.g., when run in a supplicant) or multiple * runs (e.g., when run as an internal Registrar in an AP). Caller is * responsible for freeing the returned data with wps_registrar_deinit() when * Registrar functionality is not needed anymore. */struct wps_registrar *wps_registrar_init(struct wps_context *wps,		   const struct wps_registrar_config *cfg){	struct wps_registrar *reg = os_zalloc(sizeof(*reg));	if (reg == NULL)		return NULL;	reg->wps = wps;	reg->new_psk_cb = cfg->new_psk_cb;	reg->set_ie_cb = cfg->set_ie_cb;	reg->pin_needed_cb = cfg->pin_needed_cb;	reg->reg_success_cb = cfg->reg_success_cb;	reg->cb_ctx = cfg->cb_ctx;	reg->skip_cred_build = cfg->skip_cred_build;	if (cfg->extra_cred) {		reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,						    cfg->extra_cred_len);		if (reg->extra_cred == NULL) {			os_free(reg);			return NULL;		}	}	reg->disable_auto_conf = cfg->disable_auto_conf;	reg->sel_reg_dev_password_id_override = -1;	reg->sel_reg_config_methods_override = -1;	reg->static_wep_only = cfg->static_wep_only;	if (wps_set_ie(reg)) {		wps_registrar_deinit(reg);		return NULL;	}	return reg;}/** * wps_registrar_deinit - Deinitialize WPS Registrar data * @reg: Registrar data from wps_registrar_init() */void wps_registrar_deinit(struct wps_registrar *reg){	if (reg == NULL)		return;	eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);	eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);	wps_free_pins(reg->pins);	wps_free_pbc_sessions(reg->pbc_sessions);	wpabuf_free(reg->extra_cred);	os_free(reg);}/** * wps_registrar_add_pin - Configure a new PIN for Registrar * @reg: Registrar data from wps_registrar_init() * @uuid: UUID-E or %NULL for wildcard (any UUID) * @pin: PIN (Device Password) * @pin_len: Length of pin in octets * Returns: 0 on success, -1 on failure */int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,			  const u8 *pin, size_t pin_len){	struct wps_uuid_pin *p;	p = os_zalloc(sizeof(*p));	if (p == NULL)		return -1;	if (uuid == NULL)		p->wildcard_uuid = 1;	else		os_memcpy(p->uuid, uuid, WPS_UUID_LEN);	p->pin = os_malloc(pin_len);	if (p->pin == NULL) {		os_free(p);		return -1;	}	os_memcpy(p->pin, pin, pin_len);	p->pin_len = pin_len;	p->next = reg->pins;	reg->pins = p;	wpa_printf(MSG_DEBUG, "WPS: A new PIN configured");	wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);	wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);	reg->selected_registrar = 1;	reg->pbc = 0;	wps_set_ie(reg);	return 0;}/** * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E * @reg: Registrar data from wps_registrar_init() * @uuid: UUID-E * Returns: 0 on success, -1 on failure (e.g., PIN not found) */int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid){	struct wps_uuid_pin *pin, *prev;	prev = NULL;	pin = reg->pins;	while (pin) {		if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {			if (prev == NULL)				reg->pins = pin->next;			else				prev->next = pin->next;			wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",				    pin->uuid, WPS_UUID_LEN);			wps_free_pin(pin);			return 0;		}		prev = pin;		pin = pin->next;	}	return -1;}static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,					const u8 *uuid, size_t *pin_len){	struct wps_uuid_pin *pin;	pin = reg->pins;	while (pin) {		if (!pin->wildcard_uuid &&		    os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0)			break;		pin = pin->next;	}	if (!pin) {		/* Check for wildcard UUIDs since none of the UUID-specific

⌨️ 快捷键说明

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