X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fap%2Fwps_hostapd.c;h=ff435d6dd014e05a117cb1e222518710b25feef1;hb=4e698e5c30b7693a1ed600093fd8ae30b6841e8d;hp=7963d608062f124233b1d6ae2550ddaccfa895b3;hpb=fa37511fa7e9d6a8f4fdaa8ec2df4af71bac7941;p=libeap.git diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c index 7963d60..ff435d6 100644 --- a/src/ap/wps_hostapd.c +++ b/src/ap/wps_hostapd.c @@ -45,6 +45,45 @@ static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr, static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx); +struct wps_for_each_data { + int (*func)(struct hostapd_data *h, void *ctx); + void *ctx; +}; + + +static int wps_for_each(struct hostapd_iface *iface, void *ctx) +{ + struct wps_for_each_data *data = ctx; + size_t j; + + if (iface == NULL) + return 0; + for (j = 0; j < iface->num_bss; j++) { + struct hostapd_data *hapd = iface->bss[j]; + int ret = data->func(hapd, data->ctx); + if (ret) + return ret; + } + + return 0; +} + + +static int hostapd_wps_for_each(struct hostapd_data *hapd, + int (*func)(struct hostapd_data *h, void *ctx), + void *ctx) +{ + struct hostapd_iface *iface = hapd->iface; + struct wps_for_each_data data; + data.func = func; + data.ctx = ctx; + if (iface->for_each_interface == NULL) + return wps_for_each(iface, &data); + return iface->for_each_interface(iface->interfaces, wps_for_each, + &data); +} + + static int hostapd_wps_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *psk, size_t psk_len) { @@ -200,9 +239,9 @@ static void wps_reload_config(void *eloop_data, void *user_ctx) } -static int hostapd_wps_cred_cb(void *ctx, const struct wps_credential *cred) +static int hapd_wps_cred_cb(struct hostapd_data *hapd, void *ctx) { - struct hostapd_data *hapd = ctx; + const struct wps_credential *cred = ctx; FILE *oconf, *nconf; size_t len, i; char *tmp_fname; @@ -210,6 +249,9 @@ static int hostapd_wps_cred_cb(void *ctx, const struct wps_credential *cred) int multi_bss; int wpa; + if (hapd->wps == NULL) + return 0; + wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", cred->cred_attr, cred->cred_attr_len); @@ -414,14 +456,19 @@ static int hostapd_wps_cred_cb(void *ctx, const struct wps_credential *cred) 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 int hostapd_wps_cred_cb(void *ctx, const struct wps_credential *cred) +{ + struct hostapd_data *hapd = ctx; + return hostapd_wps_for_each(hapd, hapd_wps_cred_cb, (void *) cred); +} + + static void hostapd_wps_reenable_ap_pin(void *eloop_data, void *user_ctx) { struct hostapd_data *hapd = eloop_data; @@ -436,11 +483,12 @@ static void hostapd_wps_reenable_ap_pin(void *eloop_data, void *user_ctx) } -static void hostapd_pwd_auth_fail(struct hostapd_data *hapd, - struct wps_event_pwd_auth_fail *data) +static int wps_pwd_auth_fail(struct hostapd_data *hapd, void *ctx) { - if (!data->enrollee || hapd->conf->ap_pin == NULL) - return; + struct wps_event_pwd_auth_fail *data = ctx; + + if (!data->enrollee || hapd->conf->ap_pin == NULL || hapd->wps == NULL) + return 0; /* * Registrar failed to prove its knowledge of the AP PIN. Lock AP setup @@ -451,7 +499,7 @@ static void hostapd_pwd_auth_fail(struct hostapd_data *hapd, wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u", hapd->ap_pin_failures); if (hapd->ap_pin_failures < 3) - return; + return 0; wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_LOCKED); hapd->wps->ap_setup_locked = 1; @@ -473,7 +521,14 @@ static void hostapd_pwd_auth_fail(struct hostapd_data *hapd, NULL); } - /* TODO: dualband AP may need to update other interfaces */ + return 0; +} + + +static void hostapd_pwd_auth_fail(struct hostapd_data *hapd, + struct wps_event_pwd_auth_fail *data) +{ + hostapd_wps_for_each(hapd, wps_pwd_auth_fail, data); } @@ -540,6 +595,8 @@ static int count_interface_cb(struct hostapd_iface *iface, void *ctx) static int interface_count(struct hostapd_iface *iface) { int count = 0; + if (iface->for_each_interface == NULL) + return 0; iface->for_each_interface(iface->interfaces, count_interface_cb, &count); return count; @@ -800,33 +857,72 @@ void hostapd_update_wps(struct hostapd_data *hapd) } +struct wps_add_pin_data { + const u8 *addr; + const u8 *uuid; + const u8 *pin; + size_t pin_len; + int timeout; + int added; +}; + + +static int wps_add_pin(struct hostapd_data *hapd, void *ctx) +{ + struct wps_add_pin_data *data = ctx; + int ret; + + if (hapd->wps == NULL) + return 0; + ret = wps_registrar_add_pin(hapd->wps->registrar, data->addr, + data->uuid, data->pin, data->pin_len, + data->timeout); + if (ret == 0) + data->added++; + return ret; +} + + int hostapd_wps_add_pin(struct hostapd_data *hapd, const u8 *addr, const char *uuid, const char *pin, int timeout) { u8 u[UUID_LEN]; - int any = 0; + struct wps_add_pin_data data; + + data.addr = addr; + data.uuid = u; + data.pin = (const u8 *) pin; + data.pin_len = os_strlen(pin); + data.timeout = timeout; + data.added = 0; - if (hapd->wps == NULL) - return -1; if (os_strcmp(uuid, "any") == 0) - any = 1; - else if (uuid_str2bin(uuid, u)) + data.uuid = NULL; + else { + if (uuid_str2bin(uuid, u)) + return -1; + data.uuid = u; + } + if (hostapd_wps_for_each(hapd, wps_add_pin, &data) < 0) return -1; - return wps_registrar_add_pin(hapd->wps->registrar, addr, - any ? NULL : u, - (const u8 *) pin, os_strlen(pin), - timeout); + return data.added ? 0 : -1; } -int hostapd_wps_button_pushed(struct hostapd_data *hapd) +static int wps_button_pushed(struct hostapd_data *hapd, void *ctx) { if (hapd->wps == NULL) - return -1; + return 0; return wps_registrar_button_pushed(hapd->wps->registrar); } +int hostapd_wps_button_pushed(struct hostapd_data *hapd) +{ + return hostapd_wps_for_each(hapd, wps_button_pushed, NULL); +} + + #ifdef CONFIG_WPS_OOB int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type, char *path, char *method, char *name) @@ -1072,31 +1168,53 @@ static void hostapd_wps_ap_pin_enable(struct hostapd_data *hapd, int timeout) } -void hostapd_wps_ap_pin_disable(struct hostapd_data *hapd) +static int wps_ap_pin_disable(struct hostapd_data *hapd, void *ctx) { - wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN"); os_free(hapd->conf->ap_pin); hapd->conf->ap_pin = NULL; #ifdef CONFIG_WPS_UPNP upnp_wps_set_ap_pin(hapd->wps_upnp, NULL); #endif /* CONFIG_WPS_UPNP */ eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL); + return 0; } -const char * hostapd_wps_ap_pin_random(struct hostapd_data *hapd, int timeout) +void hostapd_wps_ap_pin_disable(struct hostapd_data *hapd) { - unsigned int pin; + wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN"); + hostapd_wps_for_each(hapd, wps_ap_pin_disable, NULL); +} + + +struct wps_ap_pin_data { char pin_txt[9]; + int timeout; +}; - pin = wps_generate_pin(); - os_snprintf(pin_txt, sizeof(pin_txt), "%u", pin); + +static int wps_ap_pin_set(struct hostapd_data *hapd, void *ctx) +{ + struct wps_ap_pin_data *data = ctx; os_free(hapd->conf->ap_pin); - hapd->conf->ap_pin = os_strdup(pin_txt); + hapd->conf->ap_pin = os_strdup(data->pin_txt); #ifdef CONFIG_WPS_UPNP - upnp_wps_set_ap_pin(hapd->wps_upnp, pin_txt); + upnp_wps_set_ap_pin(hapd->wps_upnp, data->pin_txt); #endif /* CONFIG_WPS_UPNP */ - hostapd_wps_ap_pin_enable(hapd, timeout); + hostapd_wps_ap_pin_enable(hapd, data->timeout); + return 0; +} + + +const char * hostapd_wps_ap_pin_random(struct hostapd_data *hapd, int timeout) +{ + unsigned int pin; + struct wps_ap_pin_data data; + + pin = wps_generate_pin(); + os_snprintf(data.pin_txt, sizeof(data.pin_txt), "%u", pin); + data.timeout = timeout; + hostapd_wps_for_each(hapd, wps_ap_pin_set, &data); return hapd->conf->ap_pin; } @@ -1110,13 +1228,12 @@ const char * hostapd_wps_ap_pin_get(struct hostapd_data *hapd) int hostapd_wps_ap_pin_set(struct hostapd_data *hapd, const char *pin, int timeout) { - os_free(hapd->conf->ap_pin); - hapd->conf->ap_pin = os_strdup(pin); - if (hapd->conf->ap_pin == NULL) + struct wps_ap_pin_data data; + int ret; + + ret = os_snprintf(data.pin_txt, sizeof(data.pin_txt), "%s", pin); + if (ret < 0 || ret >= (int) sizeof(data.pin_txt)) return -1; -#ifdef CONFIG_WPS_UPNP - upnp_wps_set_ap_pin(hapd->wps_upnp, hapd->conf->ap_pin); -#endif /* CONFIG_WPS_UPNP */ - hostapd_wps_ap_pin_enable(hapd, timeout); - return 0; + data.timeout = timeout; + return hostapd_wps_for_each(hapd, wps_ap_pin_set, &data); }