diff options
| author | Dmitry Shmidt <dimitrysh@google.com> | 2012-01-24 16:10:04 -0800 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2012-01-24 16:44:49 -0800 |
| commit | 1f69aa52ea2e0a73ac502565df8c666ee49cab6a (patch) | |
| tree | 8ea94735f75f461769454853da0c24cbb89cc4cc /src/wps | |
| parent | bf5edf439c90418b6f4122ff5e3925123263bda4 (diff) | |
| download | android_external_wpa_supplicant_8-1f69aa52ea2e0a73ac502565df8c666ee49cab6a.tar.gz android_external_wpa_supplicant_8-1f69aa52ea2e0a73ac502565df8c666ee49cab6a.tar.bz2 android_external_wpa_supplicant_8-1f69aa52ea2e0a73ac502565df8c666ee49cab6a.zip | |
Update to new version 0.8.16 from BRCM
Sync with main tree commit b8349523e460493fa0b4de36c689595109e45e91
Author: Neeraj Kumar Garg <neerajkg@broadcom.com>
Date: Tue Dec 27 23:21:45 2011 +0200
P2P: Reject p2p_group_add if forced frequency is not acceptable
Change-Id: Icb4541a371b05c270e80440d7a7fdea7f33ff61e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src/wps')
| -rw-r--r-- | src/wps/upnp_xml.c | 4 | ||||
| -rw-r--r-- | src/wps/upnp_xml.h | 2 | ||||
| -rw-r--r-- | src/wps/wps.c | 45 | ||||
| -rw-r--r-- | src/wps/wps.h | 6 | ||||
| -rw-r--r-- | src/wps/wps_attr_parse.c | 4 | ||||
| -rw-r--r-- | src/wps/wps_common.c | 1 | ||||
| -rw-r--r-- | src/wps/wps_enrollee.c | 8 | ||||
| -rw-r--r-- | src/wps/wps_er.c | 47 | ||||
| -rw-r--r-- | src/wps/wps_registrar.c | 105 | ||||
| -rw-r--r-- | src/wps/wps_ufd.c | 1 | ||||
| -rw-r--r-- | src/wps/wps_upnp.c | 4 | ||||
| -rw-r--r-- | src/wps/wps_upnp_ssdp.c | 12 | ||||
| -rw-r--r-- | src/wps/wps_upnp_web.c | 2 |
13 files changed, 169 insertions, 72 deletions
diff --git a/src/wps/upnp_xml.c b/src/wps/upnp_xml.c index b1b1e2b1..a9958eed 100644 --- a/src/wps/upnp_xml.c +++ b/src/wps/upnp_xml.c @@ -75,8 +75,8 @@ * Note that angle brackets present in the original data must have been encoded * as < and > so they will not trouble us. */ -static int xml_next_tag(const char *in, const char **out, - const char **out_tagname, const char **end) +int xml_next_tag(const char *in, const char **out, + const char **out_tagname, const char **end) { while (*in && *in != '<') in++; diff --git a/src/wps/upnp_xml.h b/src/wps/upnp_xml.h index 62dbe602..616af3da 100644 --- a/src/wps/upnp_xml.h +++ b/src/wps/upnp_xml.h @@ -16,6 +16,8 @@ void xml_data_encode(struct wpabuf *buf, const char *data, int len); void xml_add_tagged_data(struct wpabuf *buf, const char *tag, const char *data); +int xml_next_tag(const char *in, const char **out, + const char **out_tagname, const char **end); char * xml_get_first_item(const char *doc, const char *item); struct wpabuf * xml_get_base64_item(const char *data, const char *name, enum http_reply_code *ret); diff --git a/src/wps/wps.c b/src/wps/wps.c index 5c8c25fe..2ba3d4b4 100644 --- a/src/wps/wps.c +++ b/src/wps/wps.c @@ -67,12 +67,11 @@ struct wps_data * wps_init(const struct wps_config *cfg) /* Use special PIN '00000000' for PBC */ data->dev_pw_id = DEV_PW_PUSHBUTTON; os_free(data->dev_password); - data->dev_password = os_malloc(8); + data->dev_password = (u8 *) os_strdup("00000000"); if (data->dev_password == NULL) { os_free(data); return NULL; } - os_memset(data->dev_password, '0', 8); data->dev_password_len = 8; } @@ -355,6 +354,19 @@ const u8 * wps_get_uuid_e(const struct wpabuf *msg) /** + * wps_is_20 - Check whether WPS attributes claim support for WPS 2.0 + */ +int wps_is_20(const struct wpabuf *msg) +{ + struct wps_parse_attr attr; + + if (msg == NULL || wps_parse_msg(msg, &attr) < 0) + return 0; + return attr.version2 != NULL; +} + + +/** * wps_build_assoc_req_ie - Build WPS IE for (Re)Association Request * @req_type: Value for Request Type attribute * Returns: WPS IE or %NULL on failure @@ -443,7 +455,6 @@ struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev, const u8 *req_dev_types) { struct wpabuf *ie; - u16 methods = 0; wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request"); @@ -451,35 +462,9 @@ struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev, if (ie == NULL) return NULL; - methods |= WPS_CONFIG_PUSHBUTTON; -#ifdef CONFIG_WPS2 - /* - * TODO: Should figure out whether this device has a physical or - * virtual pushbutton. - */ - methods |= WPS_CONFIG_VIRT_PUSHBUTTON; -#endif /* CONFIG_WPS2 */ - - /* - * TODO: Should figure out whether this Probe Request was triggered - * using physical or virtual display. Also, if the device has a PIN on - * a label, that should be indicated here. - */ - methods |= WPS_CONFIG_DISPLAY | -#ifdef CONFIG_WPS2 - WPS_CONFIG_VIRT_DISPLAY | -#endif /* CONFIG_WPS2 */ - WPS_CONFIG_KEYPAD; -#ifdef CONFIG_WPS_UFD - methods |= WPS_CONFIG_USBA; -#endif /* CONFIG_WPS_UFD */ -#ifdef CONFIG_WPS_NFC - methods |= WPS_CONFIG_NFC_INTERFACE; -#endif /* CONFIG_WPS_NFC */ - if (wps_build_version(ie) || wps_build_req_type(ie, req_type) || - wps_build_config_methods(ie, methods) || + wps_build_config_methods(ie, dev->config_methods) || wps_build_uuid_e(ie, uuid) || wps_build_primary_dev_type(dev, ie) || wps_build_rf_bands(dev, ie) || diff --git a/src/wps/wps.h b/src/wps/wps.h index 3e4c2185..4986881b 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -99,6 +99,7 @@ struct wps_device_data { u8 num_sec_dev_types; u32 os_version; u8 rf_bands; + u16 config_methods; struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS]; int p2p; @@ -239,6 +240,7 @@ int wps_ap_priority_compar(const struct wpabuf *wps_a, int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr, int ver1_compat); const u8 * wps_get_uuid_e(const struct wpabuf *msg); +int wps_is_20(const struct wpabuf *msg); struct wpabuf * wps_build_assoc_req_ie(enum wps_request_type req_type); struct wpabuf * wps_build_assoc_resp_ie(void); @@ -782,6 +784,7 @@ int wps_registrar_wps_cancel(struct wps_registrar *reg); int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid); int wps_registrar_button_pushed(struct wps_registrar *reg, const u8 *p2p_dev_addr); +void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e); void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr, const struct wpabuf *wps_data, int p2p_wildcard); @@ -791,6 +794,9 @@ int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr, int wps_registrar_config_ap(struct wps_registrar *reg, struct wps_credential *cred); +int wps_build_credential_wrap(struct wpabuf *msg, + const struct wps_credential *cred); + unsigned int wps_pin_checksum(unsigned int pin); unsigned int wps_pin_valid(unsigned int pin); unsigned int wps_generate_pin(void); diff --git a/src/wps/wps_attr_parse.c b/src/wps/wps_attr_parse.c index 7b462d37..55b55730 100644 --- a/src/wps/wps_attr_parse.c +++ b/src/wps/wps_attr_parse.c @@ -557,7 +557,9 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr) { const u8 *pos, *end; u16 type, len; +#ifdef WPS_WORKAROUNDS u16 prev_type = 0; +#endif /* WPS_WORKAROUNDS */ os_memset(attr, 0, sizeof(*attr)); pos = wpabuf_head(msg); @@ -622,7 +624,9 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr) if (wps_set_attr(attr, type, pos, len) < 0) return -1; +#ifdef WPS_WORKAROUNDS prev_type = type; +#endif /* WPS_WORKAROUNDS */ pos += len; } diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c index 5d0508cf..505837b1 100644 --- a/src/wps/wps_common.c +++ b/src/wps/wps_common.c @@ -22,7 +22,6 @@ #include "crypto/sha256.h" #include "crypto/random.h" #include "wps_i.h" -#include "wps_dev_attr.h" void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len, diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c index 5b3c0450..0fbaa3f6 100644 --- a/src/wps/wps_enrollee.c +++ b/src/wps/wps_enrollee.c @@ -967,7 +967,7 @@ static enum wps_process_res wps_process_m4(struct wps_data *wps, return WPS_CONTINUE; } - if (wps_validate_m4_encr(decrypted, attr->version2 != 0) < 0) { + if (wps_validate_m4_encr(decrypted, attr->version2 != NULL) < 0) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; @@ -1020,7 +1020,7 @@ static enum wps_process_res wps_process_m6(struct wps_data *wps, return WPS_CONTINUE; } - if (wps_validate_m6_encr(decrypted, attr->version2 != 0) < 0) { + if (wps_validate_m6_encr(decrypted, attr->version2 != NULL) < 0) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; @@ -1086,8 +1086,8 @@ static enum wps_process_res wps_process_m8(struct wps_data *wps, return WPS_CONTINUE; } - if (wps_validate_m8_encr(decrypted, wps->wps->ap, attr->version2 != 0) - < 0) { + if (wps_validate_m8_encr(decrypted, wps->wps->ap, + attr->version2 != NULL) < 0) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; diff --git a/src/wps/wps_er.c b/src/wps/wps_er.c index a4618369..856e9fbf 100644 --- a/src/wps/wps_er.c +++ b/src/wps/wps_er.c @@ -502,16 +502,61 @@ static void wps_er_get_device_info(struct wps_er_ap *ap) } +static const char * wps_er_find_wfadevice(const char *data) +{ + const char *tag, *tagname, *end; + char *val; + int found = 0; + + while (!found) { + /* Find next <device> */ + for (;;) { + if (xml_next_tag(data, &tag, &tagname, &end)) + return NULL; + data = end; + if (!os_strncasecmp(tagname, "device", 6) && + *tag != '/' && + (tagname[6] == '>' || !isgraph(tagname[6]))) { + break; + } + } + + /* Check whether deviceType is WFADevice */ + val = xml_get_first_item(data, "deviceType"); + if (val == NULL) + return NULL; + wpa_printf(MSG_DEBUG, "WPS ER: Found deviceType '%s'", val); + found = os_strcasecmp(val, "urn:schemas-wifialliance-org:" + "device:WFADevice:1") == 0; + os_free(val); + } + + return data; +} + + static void wps_er_parse_device_description(struct wps_er_ap *ap, struct wpabuf *reply) { /* Note: reply includes null termination after the buffer data */ - const char *data = wpabuf_head(reply); + const char *tmp, *data = wpabuf_head(reply); char *pos; wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Device info", wpabuf_head(reply), wpabuf_len(reply)); + /* + * The root device description may include multiple devices, so first + * find the beginning of the WFADevice description to allow the + * simplistic parser to pick the correct entries. + */ + tmp = wps_er_find_wfadevice(data); + if (tmp == NULL) { + wpa_printf(MSG_DEBUG, "WPS ER: WFADevice:1 device not found - " + "trying to parse invalid data"); + } else + data = tmp; + ap->friendly_name = xml_get_first_item(data, "friendlyName"); wpa_printf(MSG_DEBUG, "WPS ER: friendlyName='%s'", ap->friendly_name); diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 65ff40dd..eda1c707 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -310,13 +310,17 @@ static void wps_registrar_add_pbc_session(struct wps_registrar *reg, static void wps_registrar_remove_pbc_session(struct wps_registrar *reg, - const u8 *uuid_e) + const u8 *uuid_e, + const u8 *p2p_dev_addr) { struct wps_pbc_session *pbc, *prev = NULL, *tmp; pbc = reg->pbc_sessions; while (pbc) { - if (os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) { + if (os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0 || + (p2p_dev_addr && !is_zero_ether_addr(reg->p2p_dev_addr) && + os_memcmp(reg->p2p_dev_addr, p2p_dev_addr, ETH_ALEN) == + 0)) { if (prev) prev->next = pbc->next; else @@ -485,10 +489,8 @@ static void wps_set_pushbutton(u16 *methods, u16 conf_methods) *methods |= WPS_CONFIG_VIRT_PUSHBUTTON; if (conf_methods & WPS_CONFIG_PHY_PUSHBUTTON) *methods |= WPS_CONFIG_PHY_PUSHBUTTON; - if ((*methods & WPS_CONFIG_VIRT_PUSHBUTTON) != - WPS_CONFIG_VIRT_PUSHBUTTON || - (*methods & WPS_CONFIG_PHY_PUSHBUTTON) != - WPS_CONFIG_PHY_PUSHBUTTON) { + if (!(*methods & (WPS_CONFIG_VIRT_PUSHBUTTON | + WPS_CONFIG_PHY_PUSHBUTTON))) { /* * Required to include virtual/physical flag, but we were not * configured with push button type, so have to default to one @@ -549,15 +551,7 @@ static int wps_build_probe_config_methods(struct wps_registrar *reg, static int wps_build_config_methods_r(struct wps_registrar *reg, struct wpabuf *msg) { - u16 methods; - methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON; -#ifdef CONFIG_WPS2 - methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON | - WPS_CONFIG_PHY_PUSHBUTTON); -#endif /* CONFIG_WPS2 */ - if (reg->pbc) - wps_set_pushbutton(&methods, reg->wps->config_methods); - return wps_build_config_methods(msg, methods); + return wps_build_config_methods(msg, reg->wps->config_methods); } @@ -901,8 +895,8 @@ static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx) * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout * or when a PBC registration is completed. If more than one Enrollee in active * PBC mode has been detected during the monitor time (previous 2 minutes), the - * PBC mode is not actived and -2 is returned to indicate session overlap. This - * is skipped if a specific Enrollee is selected. + * PBC mode is not activated and -2 is returned to indicate session overlap. + * This is skipped if a specific Enrollee is selected. */ int wps_registrar_button_pushed(struct wps_registrar *reg, const u8 *p2p_dev_addr) @@ -951,6 +945,18 @@ static void wps_registrar_pin_completed(struct wps_registrar *reg) } +void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e) +{ + if (registrar->pbc) { + wps_registrar_remove_pbc_session(registrar, + uuid_e, NULL); + wps_registrar_pbc_completed(registrar); + } else { + wps_registrar_pin_completed(registrar); + } +} + + int wps_registrar_wps_cancel(struct wps_registrar *reg) { if (reg->pbc) { @@ -1420,6 +1426,25 @@ static int wps_build_credential(struct wpabuf *msg, } +int wps_build_credential_wrap(struct wpabuf *msg, + const struct wps_credential *cred) +{ + struct wpabuf *wbuf; + wbuf = wpabuf_alloc(200); + if (wbuf == NULL) + return -1; + if (wps_build_credential(wbuf, cred)) { + wpabuf_free(wbuf); + return -1; + } + wpabuf_put_be16(msg, ATTR_CRED); + wpabuf_put_be16(msg, wpabuf_len(wbuf)); + wpabuf_put_buf(msg, wbuf); + wpabuf_free(wbuf); + return 0; +} + + int wps_build_cred(struct wps_data *wps, struct wpabuf *msg) { struct wpabuf *cred; @@ -1593,6 +1618,35 @@ static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg) } +static struct wpabuf * wps_build_ap_cred(struct wps_data *wps) +{ + struct wpabuf *msg, *plain; + + msg = wpabuf_alloc(1000); + if (msg == NULL) + return NULL; + + plain = wpabuf_alloc(200); + if (plain == NULL) { + wpabuf_free(msg); + return NULL; + } + + if (wps_build_ap_settings(wps, plain)) { + wpabuf_free(plain); + wpabuf_free(msg); + return NULL; + } + + wpabuf_put_be16(msg, ATTR_CRED); + wpabuf_put_be16(msg, wpabuf_len(plain)); + wpabuf_put_buf(msg, plain); + wpabuf_free(plain); + + return msg; +} + + static struct wpabuf * wps_build_m2(struct wps_data *wps) { struct wpabuf *msg; @@ -2551,6 +2605,8 @@ static void wps_cred_update(struct wps_credential *dst, static int wps_process_ap_settings_r(struct wps_data *wps, struct wps_parse_attr *attr) { + struct wpabuf *msg; + if (wps->wps->ap || wps->er) return 0; @@ -2577,12 +2633,24 @@ static int wps_process_ap_settings_r(struct wps_data *wps, */ wps_registrar_pin_completed(wps->wps->registrar); + msg = wps_build_ap_cred(wps); + if (msg == NULL) + return -1; + wps->cred.cred_attr = wpabuf_head(msg); + wps->cred.cred_attr_len = wpabuf_len(msg); + if (wps->ap_settings_cb) { wps->ap_settings_cb(wps->ap_settings_cb_ctx, &wps->cred); + wpabuf_free(msg); return 1; } wps_sta_cred_cb(wps); + + wps->cred.cred_attr = NULL; + wps->cred.cred_attr_len = 0; + wpabuf_free(msg); + return 1; } } @@ -2983,7 +3051,8 @@ static enum wps_process_res wps_process_wsc_done(struct wps_data *wps, if (wps->pbc) { wps_registrar_remove_pbc_session(wps->wps->registrar, - wps->uuid_e); + wps->uuid_e, + wps->p2p_dev_addr); wps_registrar_pbc_completed(wps->wps->registrar); } else { wps_registrar_pin_completed(wps->wps->registrar); diff --git a/src/wps/wps_ufd.c b/src/wps/wps_ufd.c index 1a911e1d..61f65530 100644 --- a/src/wps/wps_ufd.c +++ b/src/wps/wps_ufd.c @@ -16,7 +16,6 @@ #include "common.h" #include <sys/types.h> #include <sys/stat.h> -#include <sys/wait.h> #include <fcntl.h> #include <dirent.h> diff --git a/src/wps/wps_upnp.c b/src/wps/wps_upnp.c index 763dcaf4..06dcd201 100644 --- a/src/wps/wps_upnp.c +++ b/src/wps/wps_upnp.c @@ -47,7 +47,7 @@ * -- Needs renaming with module prefix to avoid polluting the debugger * namespace and causing possible collisions with other static fncs * and structure declarations when using the debugger. - * -- The http error code generation is pretty bogus, hopefully noone cares. + * -- The http error code generation is pretty bogus, hopefully no one cares. * * Author: Ted Merrill, Atheros Communications, based upon earlier work * as explained above and below. @@ -172,7 +172,7 @@ #include "includes.h" -#include <assert.h> +#include <time.h> #include <net/if.h> #include <netdb.h> #include <sys/ioctl.h> diff --git a/src/wps/wps_upnp_ssdp.c b/src/wps/wps_upnp_ssdp.c index c7fb1583..4c4aebf6 100644 --- a/src/wps/wps_upnp_ssdp.c +++ b/src/wps/wps_upnp_ssdp.c @@ -97,16 +97,6 @@ static int line_length(const char *l) } -/* No. of chars excluding trailing whitespace */ -static int line_length_stripped(const char *l) -{ - const char *lp = l + line_length(l); - while (lp > l && !isgraph(lp[-1])) - lp--; - return lp - l; -} - - static int str_starts(const char *str, const char *start) { return os_strncmp(str, start, os_strlen(start)) == 0; @@ -530,7 +520,6 @@ static void ssdp_parse_msearch(struct upnp_wps_device_sm *sm, #ifndef CONFIG_NO_STDOUT_DEBUG const char *start = data; #endif /* CONFIG_NO_STDOUT_DEBUG */ - const char *end; int got_host = 0; int got_st = 0, st_match = 0; int got_man = 0; @@ -545,7 +534,6 @@ static void ssdp_parse_msearch(struct upnp_wps_device_sm *sm, /* Parse remaining lines */ for (; *data != '\0'; data += line_length(data)) { - end = data + line_length_stripped(data); if (token_eq(data, "host")) { /* The host line indicates who the packet * is addressed to... but do we really care? diff --git a/src/wps/wps_upnp_web.c b/src/wps/wps_upnp_web.c index 917f60b5..ce0bede8 100644 --- a/src/wps/wps_upnp_web.c +++ b/src/wps/wps_upnp_web.c @@ -956,7 +956,7 @@ static void web_connection_parse_subscribe(struct upnp_wps_device_sm *sm, break; /* no unterminated lines allowed */ /* NT assures that it is our type of subscription; - * not used for a renewl. + * not used for a renewal. **/ match = "NT:"; match_len = os_strlen(match); |
