X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fwps%2Fwps_upnp.c;h=410df463a2b74dc15915a4d730ea49506f78b0fc;hb=3904567d0bd5b5ae946ae0e954da257f960e77f8;hp=f4f209ce53c1a6b9f665746a92e6ae6f47141ebf;hpb=09bd6e8cca713adc35dac214daa8d71c254a651d;p=libeap.git diff --git a/src/wps/wps_upnp.c b/src/wps/wps_upnp.c index f4f209c..410df46 100644 --- a/src/wps/wps_upnp.c +++ b/src/wps/wps_upnp.c @@ -3,7 +3,7 @@ * Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2006-2007 Sony Corporation * Copyright (c) 2008-2009 Atheros Communications - * Copyright (c) 2009, Jouni Malinen + * Copyright (c) 2009-2010, Jouni Malinen * * See below for more details on licensing and code history. */ @@ -270,7 +270,7 @@ static void uuid_make(u8 uuid[UUID_LEN]) /* subscr_addr_delete -- delete single unlinked subscriber address * (be sure to unlink first if need be) */ -static void subscr_addr_delete(struct subscr_addr *a) +void subscr_addr_delete(struct subscr_addr *a) { /* * Note: do NOT free domain_and_port or path because they point to @@ -293,7 +293,8 @@ static void subscr_addr_free_all(struct subscription *s) /* subscr_addr_add_url -- add address(es) for one url to subscription */ -static void subscr_addr_add_url(struct subscription *s, const char *url) +static void subscr_addr_add_url(struct subscription *s, const char *url, + size_t url_len) { int alloc_len; char *scratch_mem = NULL; @@ -307,20 +308,21 @@ static void subscr_addr_add_url(struct subscription *s, const char *url) struct addrinfo *result = NULL; struct addrinfo *rp; int rerr; - struct subscr_addr *a = NULL; /* url MUST begin with http: */ - if (os_strncasecmp(url, "http://", 7)) + if (url_len < 7 || os_strncasecmp(url, "http://", 7)) goto fail; url += 7; + url_len -= 7; /* allocate memory for the extra stuff we need */ - alloc_len = (2 * (os_strlen(url) + 1)); + alloc_len = 2 * (url_len + 1); scratch_mem = os_zalloc(alloc_len); if (scratch_mem == NULL) goto fail; mem = scratch_mem; - strcpy(mem, url); + os_strncpy(mem, url, url_len); + wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", mem); domain_and_port = mem; mem += 1 + os_strlen(mem); delim = os_strchr(domain_and_port, '/'); @@ -332,7 +334,7 @@ static void subscr_addr_add_url(struct subscription *s, const char *url) } domain = mem; strcpy(domain, domain_and_port); - delim = strchr(domain, ':'); + delim = os_strchr(domain, ':'); if (delim) { *delim++ = 0; /* null terminate domain */ if (isdigit(*delim)) @@ -367,6 +369,8 @@ static void subscr_addr_add_url(struct subscription *s, const char *url) goto fail; } for (rp = result; rp; rp = rp->ai_next) { + struct subscr_addr *a; + /* Limit no. of address to avoid denial of service attack */ if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) { wpa_printf(MSG_INFO, "WPS UPnP: subscr_addr_add_url: " @@ -385,19 +389,17 @@ static void subscr_addr_add_url(struct subscription *s, const char *url) if (path[0] != '/') *mem++ = '/'; strcpy(mem, path); - mem += 1 + strlen(mem); + mem += 1 + os_strlen(mem); os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr)); a->saddr.sin_port = htons(port); dl_list_add(&s->addr_list, &a->list); - a = NULL; /* don't free it below */ } fail: if (result) freeaddrinfo(result); os_free(scratch_mem); - os_free(a); } @@ -407,7 +409,8 @@ fail: static void subscr_addr_list_create(struct subscription *s, const char *url_list) { - char *end; + const char *end; + wpa_printf(MSG_DEBUG, "WPS UPnP: Parsing URL list '%s'", url_list); for (;;) { while (*url_list == ' ' || *url_list == '\t') url_list++; @@ -417,9 +420,8 @@ static void subscr_addr_list_create(struct subscription *s, end = os_strchr(url_list, '>'); if (end == NULL) break; - *end++ = 0; - subscr_addr_add_url(s, url_list); - url_list = end; + subscr_addr_add_url(s, url_list, end - url_list); + url_list = end + 1; } } @@ -497,9 +499,10 @@ static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm) dl_list_for_each_safe(s, tmp, &sm->subscriptions, struct subscription, list) { - if (event_add(s, buf)) { + if (event_add(s, buf, sm->wlanevent_type == + UPNP_WPS_WLANEVENT_TYPE_PROBE) == 1) { wpa_printf(MSG_INFO, "WPS UPnP: Dropping " - "subscriber due to event backlog"); + "subscriber %p due to event backlog", s); dl_list_del(&s->list); subscription_destroy(s); } @@ -578,6 +581,7 @@ static struct wpabuf * build_fake_wsc_ack(void) wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE); wpabuf_put_be16(msg, WPS_NONCE_LEN); wpabuf_put(msg, WPS_NONCE_LEN); + wps_build_wfa_ext(msg, 0, NULL, 0); return msg; } @@ -605,6 +609,7 @@ static int subscription_first_event(struct subscription *s) "\n"; const char *tail = "\n"; char txt[10]; + int ret; if (s->sm->wlanevent == NULL) { /* @@ -636,7 +641,7 @@ static int subscription_first_event(struct subscription *s) } buf = wpabuf_alloc(500 + os_strlen(wlan_event)); if (buf == NULL) - return 1; + return -1; wpabuf_put_str(buf, head); wpabuf_put_property(buf, "STAStatus", "1"); @@ -646,9 +651,10 @@ static int subscription_first_event(struct subscription *s) wpabuf_put_property(buf, "WLANEvent", wlan_event); wpabuf_put_str(buf, tail); - if (event_add(s, buf)) { + ret = event_add(s, buf, 0); + if (ret) { wpabuf_free(buf); - return 1; + return ret; } wpabuf_free(buf); @@ -692,6 +698,13 @@ struct subscription * subscription_start(struct upnp_wps_device_sm *sm, s->timeout_time = expire; uuid_make(s->uuid); subscr_addr_list_create(s, callback_urls); + if (dl_list_empty(&s->addr_list)) { + wpa_printf(MSG_DEBUG, "WPS UPnP: No valid callback URLs in " + "'%s' - drop subscription", callback_urls); + subscription_destroy(s); + return NULL; + } + /* Add to end of list, since it has the highest expiration time */ dl_list_add_tail(&sm->subscriptions, &s->list); /* Queue up immediate event message (our last event) @@ -786,6 +799,7 @@ int upnp_wps_device_send_wlan_event(struct upnp_wps_device_sm *sm, os_free(sm->wlanevent); sm->wlanevent = val; + sm->wlanevent_type = ev_type; upnp_wps_device_send_event(sm); ret = 0; @@ -1074,3 +1088,20 @@ int upnp_wps_subscribers(struct upnp_wps_device_sm *sm) { return !dl_list_empty(&sm->subscriptions); } + + +int upnp_wps_set_ap_pin(struct upnp_wps_device_sm *sm, const char *ap_pin) +{ + if (sm == NULL) + return 0; + + os_free(sm->ctx->ap_pin); + if (ap_pin) { + sm->ctx->ap_pin = os_strdup(ap_pin); + if (sm->ctx->ap_pin == NULL) + return -1; + } else + sm->ctx->ap_pin = NULL; + + return 0; +}