WPS ER: Add STA/Enrollee entries and start processing EAP messages
This keeps STA/Enrollee entries up to date and sets up registration protocol session. M1 is processed and M2D generated, but the there is no code yet to transmit the response back to the AP with PutWLANResponse.
This commit is contained in:
parent
4bb4ae0ae0
commit
b345031997
1 changed files with 213 additions and 12 deletions
225
src/wps/wps_er.c
225
src/wps/wps_er.c
|
@ -34,11 +34,31 @@
|
|||
*/
|
||||
|
||||
static void wps_er_ap_timeout(void *eloop_data, void *user_ctx);
|
||||
static void wps_er_sta_timeout(void *eloop_data, void *user_ctx);
|
||||
|
||||
|
||||
struct wps_er_sta {
|
||||
struct wps_er_sta *next;
|
||||
struct wps_er_ap *ap;
|
||||
u8 addr[ETH_ALEN];
|
||||
u16 config_methods;
|
||||
u8 uuid[WPS_UUID_LEN];
|
||||
u8 pri_dev_type[8];
|
||||
u16 dev_passwd_id;
|
||||
int m1_received;
|
||||
char *manufacturer;
|
||||
char *model_name;
|
||||
char *model_number;
|
||||
char *serial_number;
|
||||
char *dev_name;
|
||||
struct wps_data *wps;
|
||||
struct http_client *http;
|
||||
};
|
||||
|
||||
struct wps_er_ap {
|
||||
struct wps_er_ap *next;
|
||||
struct wps_er *er;
|
||||
struct wps_er_sta *sta; /* list of STAs/Enrollees using this AP */
|
||||
struct in_addr addr;
|
||||
char *location;
|
||||
struct http_client *http;
|
||||
|
@ -63,7 +83,7 @@ struct wps_er_ap {
|
|||
};
|
||||
|
||||
struct wps_er {
|
||||
struct wps_registrar *reg;
|
||||
struct wps_context *wps;
|
||||
char ifname[17];
|
||||
char *mac_addr_text; /* mac addr of network i.f. we use */
|
||||
u8 mac_addr[ETH_ALEN]; /* mac addr of network i.f. we use */
|
||||
|
@ -78,6 +98,48 @@ struct wps_er {
|
|||
};
|
||||
|
||||
|
||||
static struct wps_er_sta * wps_er_sta_get(struct wps_er_ap *ap, const u8 *addr)
|
||||
{
|
||||
struct wps_er_sta *sta = ap->sta;
|
||||
while (sta) {
|
||||
if (os_memcmp(sta->addr, addr, ETH_ALEN) == 0)
|
||||
return sta;
|
||||
sta = sta->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void wps_er_sta_free(struct wps_er_sta *sta)
|
||||
{
|
||||
if (sta->wps)
|
||||
wps_deinit(sta->wps);
|
||||
os_free(sta->manufacturer);
|
||||
os_free(sta->model_name);
|
||||
os_free(sta->model_number);
|
||||
os_free(sta->serial_number);
|
||||
os_free(sta->dev_name);
|
||||
http_client_free(sta->http);
|
||||
eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
|
||||
os_free(sta);
|
||||
}
|
||||
|
||||
|
||||
static void wps_er_sta_remove_all(struct wps_er_ap *ap)
|
||||
{
|
||||
struct wps_er_sta *prev, *sta;
|
||||
|
||||
sta = ap->sta;
|
||||
ap->sta = NULL;
|
||||
|
||||
while (sta) {
|
||||
prev = sta;
|
||||
sta = sta->next;
|
||||
wps_er_sta_free(prev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void wps_er_pin_needed_cb(void *ctx, const u8 *uuid_e,
|
||||
const struct wps_device_data *dev)
|
||||
{
|
||||
|
@ -133,6 +195,8 @@ static void wps_er_ap_free(struct wps_er *er, struct wps_er_ap *ap)
|
|||
os_free(ap->control_url);
|
||||
os_free(ap->event_sub_url);
|
||||
|
||||
wps_er_sta_remove_all(ap);
|
||||
|
||||
os_free(ap);
|
||||
}
|
||||
|
||||
|
@ -536,6 +600,102 @@ static void wps_er_http_resp_ok(struct http_request *req)
|
|||
}
|
||||
|
||||
|
||||
static void wps_er_sta_timeout(void *eloop_data, void *user_ctx)
|
||||
{
|
||||
struct wps_er_sta *sta = eloop_data;
|
||||
wpa_printf(MSG_DEBUG, "WPS ER: STA entry timed out");
|
||||
wps_er_sta_free(sta);
|
||||
}
|
||||
|
||||
|
||||
static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap,
|
||||
const u8 *addr,
|
||||
struct wps_parse_attr *attr,
|
||||
int probe_req)
|
||||
{
|
||||
struct wps_er_sta *sta = wps_er_sta_get(ap, addr);
|
||||
|
||||
if (sta == NULL) {
|
||||
sta = os_zalloc(sizeof(*sta));
|
||||
if (sta == NULL)
|
||||
return NULL;
|
||||
os_memcpy(sta->addr, addr, ETH_ALEN);
|
||||
sta->ap = ap;
|
||||
sta->next = ap->sta;
|
||||
ap->sta = sta;
|
||||
}
|
||||
|
||||
if (!probe_req)
|
||||
sta->m1_received = 1;
|
||||
|
||||
if (attr->config_methods && (!probe_req || !sta->m1_received))
|
||||
sta->config_methods = WPA_GET_BE16(attr->config_methods);
|
||||
if (attr->uuid_e && (!probe_req || !sta->m1_received))
|
||||
os_memcpy(sta->uuid, attr->uuid_e, WPS_UUID_LEN);
|
||||
if (attr->primary_dev_type && (!probe_req || !sta->m1_received))
|
||||
os_memcpy(sta->pri_dev_type, attr->primary_dev_type, 8);
|
||||
if (attr->dev_password_id && (!probe_req || !sta->m1_received))
|
||||
sta->dev_passwd_id = WPA_GET_BE16(attr->dev_password_id);
|
||||
|
||||
if (attr->manufacturer) {
|
||||
os_free(sta->manufacturer);
|
||||
sta->manufacturer = os_malloc(attr->manufacturer_len + 1);
|
||||
if (sta->manufacturer) {
|
||||
os_memcpy(sta->manufacturer, attr->manufacturer,
|
||||
attr->manufacturer_len);
|
||||
sta->manufacturer[attr->manufacturer_len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (attr->model_name) {
|
||||
os_free(sta->model_name);
|
||||
sta->model_name = os_malloc(attr->model_name_len + 1);
|
||||
if (sta->model_name) {
|
||||
os_memcpy(sta->model_name, attr->model_name,
|
||||
attr->model_name_len);
|
||||
sta->model_name[attr->model_name_len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (attr->model_number) {
|
||||
os_free(sta->model_number);
|
||||
sta->model_number = os_malloc(attr->model_number_len + 1);
|
||||
if (sta->model_number) {
|
||||
os_memcpy(sta->model_number, attr->model_number,
|
||||
attr->model_number_len);
|
||||
sta->model_number[attr->model_number_len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (attr->serial_number) {
|
||||
os_free(sta->serial_number);
|
||||
sta->serial_number = os_malloc(attr->serial_number_len + 1);
|
||||
if (sta->serial_number) {
|
||||
os_memcpy(sta->serial_number, attr->serial_number,
|
||||
attr->serial_number_len);
|
||||
sta->serial_number[attr->serial_number_len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (attr->dev_name) {
|
||||
os_free(sta->dev_name);
|
||||
sta->dev_name = os_malloc(attr->dev_name_len + 1);
|
||||
if (sta->dev_name) {
|
||||
os_memcpy(sta->dev_name, attr->dev_name,
|
||||
attr->dev_name_len);
|
||||
sta->dev_name[attr->dev_name_len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
|
||||
eloop_register_timeout(300, 0, wps_er_sta_timeout, sta, NULL);
|
||||
|
||||
/* TODO: wpa_msg indication if new STA */
|
||||
|
||||
return sta;
|
||||
}
|
||||
|
||||
|
||||
static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap,
|
||||
const u8 *addr,
|
||||
struct wpabuf *msg)
|
||||
|
@ -553,8 +713,50 @@ static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap,
|
|||
return;
|
||||
}
|
||||
|
||||
/* TODO: add STA table to the AP entry and wpa_msg indication if new
|
||||
* STA */
|
||||
wps_er_add_sta_data(ap, addr, &attr, 1);
|
||||
}
|
||||
|
||||
|
||||
static void wps_er_sta_send_msg(struct wps_er_sta *sta, struct wpabuf *msg)
|
||||
{
|
||||
/* TODO: send msg as UPnP POST: PutWLANResponse(NewMessage,
|
||||
* NewWLANEventType, NewWLANEventMAC) */
|
||||
|
||||
wpabuf_free(msg);
|
||||
}
|
||||
|
||||
|
||||
static void wps_er_sta_process(struct wps_er_sta *sta, struct wpabuf *msg)
|
||||
{
|
||||
enum wps_process_res res;
|
||||
|
||||
res = wps_process_msg(sta->wps, WSC_MSG, msg);
|
||||
if (res == WPS_CONTINUE) {
|
||||
enum wsc_op_code op_code;
|
||||
struct wpabuf *next = wps_get_msg(sta->wps, &op_code);
|
||||
if (next)
|
||||
wps_er_sta_send_msg(sta, next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void wps_er_sta_start(struct wps_er_sta *sta, struct wpabuf *msg)
|
||||
{
|
||||
struct wps_config cfg;
|
||||
|
||||
if (sta->wps)
|
||||
wps_deinit(sta->wps);
|
||||
|
||||
os_memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.wps = sta->ap->er->wps;
|
||||
cfg.registrar = 1;
|
||||
cfg.peer_addr = sta->addr;
|
||||
|
||||
sta->wps = wps_init(&cfg);
|
||||
if (sta->wps == NULL)
|
||||
return;
|
||||
|
||||
wps_er_sta_process(sta, msg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -562,6 +764,7 @@ static void wps_er_process_wlanevent_eap(struct wps_er_ap *ap, const u8 *addr,
|
|||
struct wpabuf *msg)
|
||||
{
|
||||
struct wps_parse_attr attr;
|
||||
struct wps_er_sta *sta;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - EAP - from " MACSTR,
|
||||
MAC2STR(addr));
|
||||
|
@ -574,8 +777,12 @@ static void wps_er_process_wlanevent_eap(struct wps_er_ap *ap, const u8 *addr,
|
|||
return;
|
||||
}
|
||||
|
||||
/* TODO: add STA table to the AP entry and wpa_msg indication if new
|
||||
* STA; process message if it is part of ongoing protocol run */
|
||||
sta = wps_er_add_sta_data(ap, addr, &attr, 0);
|
||||
|
||||
if (attr.msg_type && *attr.msg_type == WPS_M1)
|
||||
wps_er_sta_start(sta, msg);
|
||||
else if (sta->wps)
|
||||
wps_er_sta_process(sta, msg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -719,16 +926,11 @@ wps_er_init(struct wps_context *wps, const char *ifname)
|
|||
er->ssdp_sd = -1;
|
||||
|
||||
os_strlcpy(er->ifname, ifname, sizeof(er->ifname));
|
||||
er->wps = wps;
|
||||
os_memset(&rcfg, 0, sizeof(rcfg));
|
||||
rcfg.pin_needed_cb = wps_er_pin_needed_cb;
|
||||
rcfg.cb_ctx = er;
|
||||
|
||||
er->reg = wps_registrar_init(wps, &rcfg);
|
||||
if (er->reg == NULL) {
|
||||
wps_er_deinit(er);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (get_netif_info(ifname,
|
||||
&er->ip_addr, &er->ip_addr_text,
|
||||
er->mac_addr, &er->mac_addr_text)) {
|
||||
|
@ -794,7 +996,6 @@ void wps_er_deinit(struct wps_er *er)
|
|||
eloop_unregister_sock(er->ssdp_sd, EVENT_TYPE_READ);
|
||||
close(er->ssdp_sd);
|
||||
}
|
||||
wps_registrar_deinit(er->reg);
|
||||
os_free(er->ip_addr_text);
|
||||
os_free(er->mac_addr_text);
|
||||
os_free(er);
|
||||
|
|
Loading…
Reference in a new issue