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:
Jouni Malinen 2009-11-11 23:50:17 +02:00
parent 4bb4ae0ae0
commit b345031997

View file

@ -34,11 +34,31 @@
*/ */
static void wps_er_ap_timeout(void *eloop_data, void *user_ctx); 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 {
struct wps_er_ap *next; struct wps_er_ap *next;
struct wps_er *er; struct wps_er *er;
struct wps_er_sta *sta; /* list of STAs/Enrollees using this AP */
struct in_addr addr; struct in_addr addr;
char *location; char *location;
struct http_client *http; struct http_client *http;
@ -63,7 +83,7 @@ struct wps_er_ap {
}; };
struct wps_er { struct wps_er {
struct wps_registrar *reg; struct wps_context *wps;
char ifname[17]; char ifname[17];
char *mac_addr_text; /* mac addr of network i.f. we use */ 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 */ 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, static void wps_er_pin_needed_cb(void *ctx, const u8 *uuid_e,
const struct wps_device_data *dev) 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->control_url);
os_free(ap->event_sub_url); os_free(ap->event_sub_url);
wps_er_sta_remove_all(ap);
os_free(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, static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap,
const u8 *addr, const u8 *addr,
struct wpabuf *msg) struct wpabuf *msg)
@ -553,8 +713,50 @@ static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap,
return; return;
} }
/* TODO: add STA table to the AP entry and wpa_msg indication if new wps_er_add_sta_data(ap, addr, &attr, 1);
* STA */ }
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 wpabuf *msg)
{ {
struct wps_parse_attr attr; struct wps_parse_attr attr;
struct wps_er_sta *sta;
wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - EAP - from " MACSTR, wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - EAP - from " MACSTR,
MAC2STR(addr)); MAC2STR(addr));
@ -574,8 +777,12 @@ static void wps_er_process_wlanevent_eap(struct wps_er_ap *ap, const u8 *addr,
return; return;
} }
/* TODO: add STA table to the AP entry and wpa_msg indication if new sta = wps_er_add_sta_data(ap, addr, &attr, 0);
* STA; process message if it is part of ongoing protocol run */
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; er->ssdp_sd = -1;
os_strlcpy(er->ifname, ifname, sizeof(er->ifname)); os_strlcpy(er->ifname, ifname, sizeof(er->ifname));
er->wps = wps;
os_memset(&rcfg, 0, sizeof(rcfg)); os_memset(&rcfg, 0, sizeof(rcfg));
rcfg.pin_needed_cb = wps_er_pin_needed_cb; rcfg.pin_needed_cb = wps_er_pin_needed_cb;
rcfg.cb_ctx = er; 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, if (get_netif_info(ifname,
&er->ip_addr, &er->ip_addr_text, &er->ip_addr, &er->ip_addr_text,
er->mac_addr, &er->mac_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); eloop_unregister_sock(er->ssdp_sd, EVENT_TYPE_READ);
close(er->ssdp_sd); close(er->ssdp_sd);
} }
wps_registrar_deinit(er->reg);
os_free(er->ip_addr_text); os_free(er->ip_addr_text);
os_free(er->mac_addr_text); os_free(er->mac_addr_text);
os_free(er); os_free(er);