Beispiel #1
0
static void shift_right_block(u8 *v)
{
	u32 val;

	val = WPA_GET_BE32(v + 12);
	val >>= 1;
	if (v[11] & 0x01)
		val |= 0x80000000;
	WPA_PUT_BE32(v + 12, val);

	val = WPA_GET_BE32(v + 8);
	val >>= 1;
	if (v[7] & 0x01)
		val |= 0x80000000;
	WPA_PUT_BE32(v + 8, val);

	val = WPA_GET_BE32(v + 4);
	val >>= 1;
	if (v[3] & 0x01)
		val |= 0x80000000;
	WPA_PUT_BE32(v + 4, val);

	val = WPA_GET_BE32(v);
	val >>= 1;
	WPA_PUT_BE32(v, val);
}
Beispiel #2
0
static u8 * attr_get(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr,
		     size_t *len)
{
	u8 *pos = buf;

	while (pos + 8 <= buf + buflen) {
		enum wlantest_ctrl_attr a;
		size_t alen;
		a = WPA_GET_BE32(pos);
		pos += 4;
		alen = WPA_GET_BE32(pos);
		pos += 4;
		if (pos + alen > buf + buflen) {
			wpa_printf(MSG_DEBUG, "Invalid control message "
				   "attribute");
			return NULL;
		}
		if (a == attr) {
			*len = alen;
			return pos;
		}
		pos += alen;
	}

	return NULL;
}
Beispiel #3
0
static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
{
#ifdef CONFIG_CTRL_IFACE
	wpa_config_write_reg_string(hk, "ctrl_interface",
				    config->ctrl_interface);
#endif /* CONFIG_CTRL_IFACE */

	wpa_config_write_reg_dword(hk, TEXT("eapol_version"),
				   config->eapol_version,
				   DEFAULT_EAPOL_VERSION);
	wpa_config_write_reg_dword(hk, TEXT("ap_scan"), config->ap_scan,
				   DEFAULT_AP_SCAN);
	wpa_config_write_reg_dword(hk, TEXT("fast_reauth"),
				   config->fast_reauth, DEFAULT_FAST_REAUTH);
	wpa_config_write_reg_dword(hk, TEXT("dot11RSNAConfigPMKLifetime"),
				   config->dot11RSNAConfigPMKLifetime, 0);
	wpa_config_write_reg_dword(hk,
				   TEXT("dot11RSNAConfigPMKReauthThreshold"),
				   config->dot11RSNAConfigPMKReauthThreshold,
				   0);
	wpa_config_write_reg_dword(hk, TEXT("dot11RSNAConfigSATimeout"),
				   config->dot11RSNAConfigSATimeout, 0);
	wpa_config_write_reg_dword(hk, TEXT("update_config"),
				   config->update_config,
				   0);
#ifdef CONFIG_WPS
	if (!is_nil_uuid(config->uuid)) {
		char buf[40];
		uuid_bin2str(config->uuid, buf, sizeof(buf));
		wpa_config_write_reg_string(hk, "uuid", buf);
	}
	wpa_config_write_reg_string(hk, "device_name", config->device_name);
	wpa_config_write_reg_string(hk, "manufacturer", config->manufacturer);
	wpa_config_write_reg_string(hk, "model_name", config->model_name);
	wpa_config_write_reg_string(hk, "model_number", config->model_number);
	wpa_config_write_reg_string(hk, "serial_number",
				    config->serial_number);
	wpa_config_write_reg_string(hk, "device_type", config->device_type);
	wpa_config_write_reg_string(hk, "config_methods",
				    config->config_methods);
	if (WPA_GET_BE32(config->os_version)) {
		char vbuf[10];
		os_snprintf(vbuf, sizeof(vbuf), "%08x",
			    WPA_GET_BE32(config->os_version));
		wpa_config_write_reg_string(hk, "os_version", vbuf);
	}
	wpa_config_write_reg_dword(hk, TEXT("wps_cred_processing"),
				   config->wps_cred_processing, 0);
#endif /* CONFIG_WPS */

	wpa_config_write_reg_dword(hk, TEXT("bss_max_count"),
				   config->bss_max_count,
				   DEFAULT_BSS_MAX_COUNT);
	wpa_config_write_reg_dword(hk, TEXT("filter_ssids"),
				   config->filter_ssids, 0);

	return 0;
}
void hostapd_wps_probe_req_rx(struct hostapd_data *hapd, const u8 *addr,
			      const u8 *ie, size_t ie_len)
{
	struct wpabuf *wps_ie;
	const u8 *end, *pos, *wps;

	if (hapd->wps == NULL)
		return;

	pos = ie;
	end = ie + ie_len;
	wps = NULL;

	while (pos + 1 < end) {
		if (pos + 2 + pos[1] > end)
			return;
		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
		    WPA_GET_BE32(&pos[2]) == WPS_DEV_OUI_WFA) {
			wps = pos;
			break;
		}
		pos += 2 + pos[1];
	}

	if (wps == NULL)
		return; /* No WPS IE in Probe Request */

	wps_ie = wpabuf_alloc(ie_len);
	if (wps_ie == NULL)
		return;

	/* There may be multiple WPS IEs in the message, so need to concatenate
	 * their WPS Data fields */
	while (pos + 1 < end) {
		if (pos + 2 + pos[1] > end)
			break;
		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
		    WPA_GET_BE32(&pos[2]) == WPS_DEV_OUI_WFA)
			wpabuf_put_data(wps_ie, pos + 6, pos[1] - 4);
		pos += 2 + pos[1];
	}

	if (wpabuf_len(wps_ie) > 0) {
		wps_registrar_probe_req_rx(hapd->wps->registrar, addr, wps_ie);
#ifdef CONFIG_WPS_UPNP
		/* FIX: what exactly should be included in the WLANEvent?
		 * WPS attributes? Full ProbeReq frame? */
		upnp_wps_device_send_wlan_event(hapd->wps_upnp, addr,
						UPNP_WPS_WLANEVENT_TYPE_PROBE,
						wps_ie);
#endif /* CONFIG_WPS_UPNP */
	}

	wpabuf_free(wps_ie);
}
Beispiel #5
0
/**
 * wpa_bss_get_vendor_ie_multi - Fetch vendor IE data from a BSS entry
 * @bss: BSS table entry
 * @vendor_type: Vendor type (four octets starting the IE payload)
 * Returns: Pointer to the information element payload or %NULL if not found
 *
 * This function returns concatenated payload of possibly fragmented vendor
 * specific information elements in the BSS entry. The caller is responsible for
 * freeing the returned buffer.
 */
struct wpabuf * wpa_bss_get_vendor_ie_multi(const struct wpa_bss *bss,
					    u32 vendor_type)
{
	struct wpabuf *buf;
	const u8 *end, *pos;

	buf = wpabuf_alloc(bss->ie_len);
	if (buf == NULL)
		return NULL;

	pos = (const u8 *) (bss + 1);
	end = pos + bss->ie_len;

	while (end - pos > 1) {
		if (2 + pos[1] > end - pos)
			break;
		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
		    vendor_type == WPA_GET_BE32(&pos[2]))
			wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
		pos += 2 + pos[1];
	}

	if (wpabuf_len(buf) == 0) {
		wpabuf_free(buf);
		buf = NULL;
	}

	return buf;
}
Beispiel #6
0
static void ctrl_get_bss_counter(struct wlantest *wt, int sock, u8 *cmd,
				 size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	u32 counter;
	u8 buf[4 + 12], *end, *pos;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	if (bss == NULL)
		return;

	addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_COUNTER, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	counter = WPA_GET_BE32(addr);
	if (counter >= NUM_WLANTEST_BSS_COUNTER) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
			    bss->counters[counter]);
	ctrl_send(wt, sock, buf, pos - buf);
}
Beispiel #7
0
static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm,
					       struct wpa_peerkey *peerkey,
					       struct wpa_eapol_ie_parse *kde)
{
	u32 lifetime;
	struct os_time now;

	if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime))
		return;

	lifetime = WPA_GET_BE32(kde->lifetime);

	if (lifetime >= peerkey->lifetime) {
		wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds "
			   "which is larger than or equal to own value %u "
			   "seconds - ignored", lifetime, peerkey->lifetime);
		return;
	}

	wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds "
		   "(own was %u seconds) - updated",
		   lifetime, peerkey->lifetime);
	peerkey->lifetime = lifetime;

	os_get_time(&now);
	peerkey->expiration = now.sec + lifetime;
	eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
	eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
			       sm, peerkey);
}
Beispiel #8
0
static const u8 * eap_gpsk_validate_csuite(struct eap_gpsk_data *data,
        const u8 *pos, const u8 *end)
{
    int vendor, specifier;
    const struct eap_gpsk_csuite *csuite;

    if (pos == NULL)
        return NULL;

    if (end - pos < (int) sizeof(*csuite)) {
        wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for "
                   "CSuite_Sel");
        return NULL;
    }
    csuite = (const struct eap_gpsk_csuite *) pos;
    vendor = WPA_GET_BE32(csuite->vendor);
    specifier = WPA_GET_BE16(csuite->specifier);
    pos += sizeof(*csuite);
    if (vendor != data->vendor || specifier != data->specifier) {
        wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_Sel (%d:%d) does not "
                   "match with the one sent in GPSK-2 (%d:%d)",
                   vendor, specifier, data->vendor, data->specifier);
        return NULL;
    }

    return pos;
}
Beispiel #9
0
/* compress 512-bits */
static int sha256_compress(struct sha256_state *md,
                           unsigned char *buf)
{
  unsigned long S[8], W[64], t0, t1;
  unsigned long t;
  int i;
  /* copy state into S */
  for(i = 0; i < 8; i++) {
    S[i] = md->state[i];
  }
  /* copy the state into 512-bits into W[0..15] */
  for(i = 0; i < 16; i++)
    W[i] = WPA_GET_BE32(buf + (4 * i));
  /* fill W[16..63] */
  for(i = 16; i < 64; i++) {
    W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
      W[i - 16];
  }
  /* Compress */
#define RND(a,b,c,d,e,f,g,h,i)                    \
  t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
  t1 = Sigma0(a) + Maj(a, b, c);                  \
  d += t0;                                        \
  h = t0 + t1;
  for(i = 0; i < 64; ++i) {
    RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
    t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
    S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
  }
  /* feedback */
  for(i = 0; i < 8; i++) {
    md->state[i] = md->state[i] + S[i];
  }
  return 0;
}
Beispiel #10
0
static void inc32(u8 *block)
{
	u32 val;
	val = WPA_GET_BE32(block + AES_BLOCK_SIZE - 4);
	val++;
	WPA_PUT_BE32(block + AES_BLOCK_SIZE - 4, val);
}
Beispiel #11
0
static Boolean eap_vendor_test_check(struct eap_sm *sm, void *priv,
				     u8 *respData, size_t respDataLen)
{
	struct eap_hdr *resp;
	u8 *pos;
	size_t len;
	int vendor;
	u32 method;

	resp = (struct eap_hdr *) respData;
	pos = (u8 *) (resp + 1);
	if (respDataLen < sizeof(*resp))
		return TRUE;
	len = ntohs(resp->length);
	if (len > respDataLen)
		return TRUE;

	if (len < sizeof(*resp) + 8 || *pos != EAP_TYPE_EXPANDED) {
		wpa_printf(MSG_INFO, "EAP-VENDOR-TEST: Invalid frame");
		return TRUE;
	}
	pos++;

	vendor = WPA_GET_BE24(pos);
	pos += 3;
	method = WPA_GET_BE32(pos);
	pos++;

	if (vendor != EAP_VENDOR_ID || method != EAP_VENDOR_TYPE)
		return TRUE;

	return FALSE;
}
Beispiel #12
0
struct wpabuf * wpa_scan_get_vendor_ie_multi_beacon(
	const struct wpa_scan_res *res, u32 vendor_type)
{
	struct wpabuf *buf;
	const u8 *end, *pos;

	if (res->beacon_ie_len == 0)
		return NULL;
	buf = wpabuf_alloc(res->beacon_ie_len);
	if (buf == NULL)
		return NULL;

	pos = (const u8 *) (res + 1);
	pos += res->ie_len;
	end = pos + res->beacon_ie_len;

	while (pos + 1 < end) {
		if (pos + 2 + pos[1] > end)
			break;
		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
		    vendor_type == WPA_GET_BE32(&pos[2]))
			wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
		pos += 2 + pos[1];
	}

	if (wpabuf_len(buf) == 0) {
		wpabuf_free(buf);
		buf = NULL;
	}

	return buf;
}
Beispiel #13
0
struct wpabuf * tncc_process_soh_request(int ver, const u8 *data, size_t len)
{
	const u8 *pos;

	wpa_hexdump(MSG_DEBUG, "TNC: SoH Request", data, len);

	if (len < 12)
		return NULL;

	/* SoH Request */
	pos = data;

	/* TLV Type */
	if (WPA_GET_BE16(pos) != EAP_TLV_VENDOR_SPECIFIC_TLV)
		return NULL;
	pos += 2;

	/* Length */
	if (WPA_GET_BE16(pos) < 8)
		return NULL;
	pos += 2;

	/* Vendor_Id */
	if (WPA_GET_BE32(pos) != EAP_VENDOR_MICROSOFT)
		return NULL;
	pos += 4;

	/* TLV Type */
	if (WPA_GET_BE16(pos) != 0x02 /* SoH request TLV */)
		return NULL;

	wpa_printf(MSG_DEBUG, "TNC: SoH Request TLV received");

	return tncc_build_soh(2);
}
static int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags,
				     const u8 **pos, size_t *left)
{
	unsigned int tls_msg_len = 0;
	const u8 *end = *pos + *left;

	if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
		if (*left < 4) {
			wpa_printf(MSG_INFO, "SSL: Short frame with TLS "
				   "length");
			return -1;
		}
		tls_msg_len = WPA_GET_BE32(*pos);
		wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d",
			   tls_msg_len);
		*pos += 4;
		*left -= 4;
	}

	wpa_printf(MSG_DEBUG, "SSL: Received packet: Flags 0x%x "
		   "Message Length %u", flags, tls_msg_len);

	if (data->state == WAIT_FRAG_ACK) {
		if (*left != 0) {
			wpa_printf(MSG_DEBUG, "SSL: Unexpected payload in "
				   "WAIT_FRAG_ACK state");
			return -1;
		}
		wpa_printf(MSG_DEBUG, "SSL: Fragment acknowledged");
		return 1;
	}

	if (data->tls_in &&
	    eap_server_tls_process_cont(data, *pos, end - *pos) < 0)
		return -1;
		
	if (flags & EAP_TLS_FLAGS_MORE_FRAGMENTS) {
		if (eap_server_tls_process_fragment(data, flags, tls_msg_len,
						    *pos, end - *pos) < 0)
			return -1;

		data->state = FRAG_ACK;
		return 1;
	}

	if (data->state == FRAG_ACK) {
		wpa_printf(MSG_DEBUG, "SSL: All fragments received");
		data->state = MSG;
	}

	if (data->tls_in == NULL) {
		/* Wrap unfragmented messages as wpabuf without extra copy */
		wpabuf_set(&data->tmpbuf, *pos, end - *pos);
		data->tls_in = &data->tmpbuf;
	}

	return 0;
}
Beispiel #15
0
static int attr_get_int(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr)
{
	u8 *pos;
	size_t len;
	pos = attr_get(buf, buflen, attr, &len);
	if (pos == NULL || len != 4)
		return -1;
	return WPA_GET_BE32(pos);
}
Beispiel #16
0
int wpas_wps_init(struct wpa_supplicant *wpa_s)
{
	struct wps_context *wps;
	struct wps_registrar_config rcfg;

	wps = os_zalloc(sizeof(*wps));
	if (wps == NULL)
		return -1;

	wps->cred_cb = wpa_supplicant_wps_cred;
	wps->event_cb = wpa_supplicant_wps_event;
	wps->cb_ctx = wpa_s;

	wps->dev.device_name = wpa_s->conf->device_name;
	wps->dev.manufacturer = wpa_s->conf->manufacturer;
	wps->dev.model_name = wpa_s->conf->model_name;
	wps->dev.model_number = wpa_s->conf->model_number;
	wps->dev.serial_number = wpa_s->conf->serial_number;
	wps->config_methods =
		wps_config_methods_str2bin(wpa_s->conf->config_methods);
	if (wpa_s->conf->device_type &&
	    wps_dev_type_str2bin(wpa_s->conf->device_type,
				 wps->dev.pri_dev_type) < 0) {
		wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
		os_free(wps);
		return -1;
	}
	wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
	wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */
	os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN);
	if (is_nil_uuid(wpa_s->conf->uuid)) {
		uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid);
		wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC address",
			    wps->uuid, WPS_UUID_LEN);
	} else
		os_memcpy(wps->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);

	wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
	wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;

	os_memset(&rcfg, 0, sizeof(rcfg));
	rcfg.new_psk_cb = wpas_wps_new_psk_cb;
	rcfg.pin_needed_cb = wpas_wps_pin_needed_cb;
	rcfg.set_sel_reg_cb = wpas_wps_set_sel_reg_cb;
	rcfg.cb_ctx = wpa_s;

	wps->registrar = wps_registrar_init(wps, &rcfg);
	if (wps->registrar == NULL) {
		wpa_printf(MSG_DEBUG, "Failed to initialize WPS Registrar");
		os_free(wps);
		return -1;
	}

	wpa_s->wps = wps;

	return 0;
}
static int cmd_get_sta_counter(int s, int argc, char *argv[])
{
    u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
    u8 buf[100], *end, *pos;
    int rlen, i;
    size_t len;

    if (argc != 3) {
        printf("get_sta_counter needs at three arguments: "
               "counter name, BSSID, and STA address\n");
        return -1;
    }

    pos = buf;
    end = buf + sizeof(buf);
    WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_STA_COUNTER);
    pos += 4;

    for (i = 0; sta_counters[i].name; i++) {
        if (os_strcasecmp(sta_counters[i].name, argv[0]) == 0)
            break;
    }
    if (sta_counters[i].name == NULL) {
        printf("Unknown STA counter '%s'\n", argv[0]);
        printf("Counters:");
        for (i = 0; sta_counters[i].name; i++)
            printf(" %s", sta_counters[i].name);
        printf("\n");
        return -1;
    }

    pos = attr_add_be32(pos, end, WLANTEST_ATTR_STA_COUNTER,
                        sta_counters[i].num);
    pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
    if (hwaddr_aton(argv[1], pos) < 0) {
        printf("Invalid BSSID '%s'\n", argv[1]);
        return -1;
    }
    pos += ETH_ALEN;

    pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
    if (hwaddr_aton(argv[2], pos) < 0) {
        printf("Invalid STA address '%s'\n", argv[2]);
        return -1;
    }
    pos += ETH_ALEN;

    rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
    if (rlen < 0)
        return -1;

    pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
    if (pos == NULL || len != 4)
        return -1;
    printf("%u\n", WPA_GET_BE32(pos));
    return 0;
}
struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
					    u32 oui_type)
{
	struct wpabuf *buf;
	const u8 *end, *pos, *ie;

	pos = ies;
	end = ies + ies_len;
	ie = NULL;

	while (pos + 1 < end) {
		if (pos + 2 + pos[1] > end)
			return NULL;
		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
		    WPA_GET_BE32(&pos[2]) == oui_type) {
			ie = pos;
			break;
		}
		pos += 2 + pos[1];
	}

	if (ie == NULL)
		return NULL; /* No specified vendor IE found */

	buf = wpabuf_alloc(ies_len);
	if (buf == NULL)
		return NULL;

	/*
	 * There may be multiple vendor IEs in the message, so need to
	 * concatenate their data fields.
	 */
	while (pos + 1 < end) {
		if (pos + 2 + pos[1] > end)
			break;
		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
		    WPA_GET_BE32(&pos[2]) == oui_type)
			wpabuf_put_data(buf, pos + 6, pos[1] - 4);
		pos += 2 + pos[1];
	}

	return buf;
}
Beispiel #19
0
static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp)
{
	const struct eap_hdr *hdr;
	size_t plen;

	/* parse rxResp, respId, respMethod */
	sm->rxResp = FALSE;
	sm->respId = -1;
	sm->respMethod = EAP_TYPE_NONE;
	sm->respVendor = EAP_VENDOR_IETF;
	sm->respVendorMethod = EAP_TYPE_NONE;

	if (resp == NULL || wpabuf_len(resp) < sizeof(*hdr)) {
		wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p "
			   "len=%lu", resp,
			   resp ? (unsigned long) wpabuf_len(resp) : 0);
		return;
	}

	hdr = wpabuf_head(resp);
	plen = be_to_host16(hdr->length);
	if (plen > wpabuf_len(resp)) {
		wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
			   "(len=%lu plen=%lu)",
			   (unsigned long) wpabuf_len(resp),
			   (unsigned long) plen);
		return;
	}

	sm->respId = hdr->identifier;

	if (hdr->code == EAP_CODE_RESPONSE)
		sm->rxResp = TRUE;

	if (plen > sizeof(*hdr)) {
		u8 *pos = (u8 *) (hdr + 1);
		sm->respMethod = *pos++;
		if (sm->respMethod == EAP_TYPE_EXPANDED) {
			if (plen < sizeof(*hdr) + 8) {
				wpa_printf(MSG_DEBUG, "EAP: Ignored truncated "
					   "expanded EAP-Packet (plen=%lu)",
					   (unsigned long) plen);
				return;
			}
			sm->respVendor = WPA_GET_BE24(pos);
			pos += 3;
			sm->respVendorMethod = WPA_GET_BE32(pos);
		}
	}

	wpa_printf(MSG_DEBUG, "EAP: parseEapResp: rxResp=%d respId=%d "
		   "respMethod=%u respVendor=%u respVendorMethod=%u",
		   sm->rxResp, sm->respId, sm->respMethod, sm->respVendor,
		   sm->respVendorMethod);
}
Beispiel #20
0
/**
 * wpa_parse_wpa_ie - Parse WPA/RSN IE
 * @wpa_ie: Pointer to WPA or RSN IE
 * @wpa_ie_len: Length of the WPA/RSN IE
 * @data: Pointer to data area for parsing results
 * Returns: 0 on success, -1 on failure
 *
 * Parse the contents of WPA or RSN IE and write the parsed data into data.
 */
int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
		     struct wpa_ie_data *data)
{
	if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN)
		return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
	if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC &&
	    wpa_ie[1] >= 4 && WPA_GET_BE32(&wpa_ie[2]) == OSEN_IE_VENDOR_TYPE)
		return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
	else
		return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
}
const u8 * eap_tls_process_init(struct eap_sm *sm, struct eap_ssl_data *data,
				EapType eap_type, struct eap_method_ret *ret,
				const u8 *reqData, size_t reqDataLen,
				size_t *len, u8 *flags)
{
	const u8 *pos;
	size_t left;
	unsigned int tls_msg_len;

	if (tls_get_errors(sm->ssl_ctx)) {
		wpa_printf(MSG_INFO, "SSL: TLS errors detected");
		ret->ignore = TRUE;
		return NULL;
	}

	pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, reqData, reqDataLen,
			       &left);
	if (pos == NULL) {
		ret->ignore = TRUE;
		return NULL;
	}
	*flags = *pos++;
	left--;
	wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - "
		   "Flags 0x%02x", (unsigned long) reqDataLen, *flags);
	if (*flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
		if (left < 4) {
			wpa_printf(MSG_INFO, "SSL: Short frame with TLS "
				   "length");
			ret->ignore = TRUE;
			return NULL;
		}
		tls_msg_len = WPA_GET_BE32(pos);
		wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d",
			   tls_msg_len);
		if (data->tls_in_left == 0) {
			data->tls_in_total = tls_msg_len;
			data->tls_in_left = tls_msg_len;
			os_free(data->tls_in);
			data->tls_in = NULL;
			data->tls_in_len = 0;
		}
		pos += 4;
		left -= 4;
	}

	ret->ignore = FALSE;
	ret->methodState = METHOD_MAY_CONT;
	ret->decision = DECISION_FAIL;
	ret->allowNotifications = TRUE;

	*len = (size_t) left;
	return pos;
}
Beispiel #22
0
static void ctrl_info_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	enum wlantest_sta_info info;
	u8 buf[4 + 108], *end, *pos;
	char resp[100];

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	if (sta == NULL)
		return;

	addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_INFO, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	info = WPA_GET_BE32(addr);

	resp[0] = '\0';
	switch (info) {
	case WLANTEST_STA_INFO_PROTO:
		info_print_proto(resp, sizeof(resp), sta->proto);
		break;
	case WLANTEST_STA_INFO_PAIRWISE:
		info_print_cipher(resp, sizeof(resp), sta->pairwise_cipher);
		break;
	case WLANTEST_STA_INFO_KEY_MGMT:
		info_print_key_mgmt(resp, sizeof(resp), sta->key_mgmt);
		break;
	case WLANTEST_STA_INFO_RSN_CAPAB:
		info_print_rsn_capab(resp, sizeof(resp), sta->rsn_capab);
		break;
	case WLANTEST_STA_INFO_STATE:
		info_print_state(resp, sizeof(resp), sta->state);
		break;
	case WLANTEST_STA_INFO_GTK:
		info_print_gtk(resp, sizeof(resp), sta);
		break;
	default:
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp);
	ctrl_send(wt, sock, buf, pos - buf);
}
static int wpa_config_process_os_version(const struct global_parse_data *data,
					 struct wpa_config *config, int line,
					 const char *pos)
{
	if (hexstr2bin(pos, config->os_version, 4)) {
		wpa_printf(MSG_ERROR, "Line %d: invalid os_version", line);
		return -1;
	}
	wpa_printf(MSG_DEBUG, "os_version=%08x",
		   WPA_GET_BE32(config->os_version));
	return 0;
}
Beispiel #24
0
int wps_process_os_version(struct wps_device_data *dev, const u8 *ver)
{
    if (ver == NULL) {
        wpa_printf(MSG_DEBUG, "WPS: No OS Version received");
        return -1;
    }

    dev->os_version = WPA_GET_BE32(ver);
    wpa_printf(MSG_DEBUG, "WPS: OS Version %08x", dev->os_version);

    return 0;
}
Beispiel #25
0
static void ctrl_get_tdls_counter(struct wlantest *wt, int sock, u8 *cmd,
				  size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	struct wlantest_sta *sta2;
	struct wlantest_tdls *tdls;
	u32 counter;
	u8 buf[4 + 12], *end, *pos;
	int found = 0;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	sta2 = ctrl_get_sta2(wt, sock, cmd, clen, bss);
	if (sta == NULL || sta2 == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	addr = attr_get(cmd, clen, WLANTEST_ATTR_TDLS_COUNTER, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	counter = WPA_GET_BE32(addr);
	if (counter >= NUM_WLANTEST_TDLS_COUNTER) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
		if (tdls->init == sta && tdls->resp == sta2) {
			found = 1;
			break;
		}
	}

	if (!found) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
			    tdls->counters[counter]);
	ctrl_send(wt, sock, buf, pos - buf);
}
Beispiel #26
0
const u8 * eap_hdr_validate(int vendor, EapType eap_type,
			    const struct wpabuf *msg, size_t *plen)
{
	const struct eap_hdr *hdr;
	const u8 *pos;
	size_t len;

	hdr = wpabuf_head(msg);

	if (wpabuf_len(msg) < sizeof(*hdr)) {
		wpa_printf(MSG_INFO, "EAP: Too short EAP frame");
		return NULL;
	}

	len = be_to_host16(hdr->length);
	if (len < sizeof(*hdr) + 1 || len > wpabuf_len(msg)) {
		wpa_printf(MSG_INFO, "EAP: Invalid EAP length");
		return NULL;
	}

	pos = (const u8 *) (hdr + 1);

	if (*pos == EAP_TYPE_EXPANDED) {
		int exp_vendor;
		u32 exp_type;
		if (len < sizeof(*hdr) + 8) {
			wpa_printf(MSG_INFO, "EAP: Invalid expanded EAP "
				   "length");
			return NULL;
		}
		pos++;
		exp_vendor = WPA_GET_BE24(pos);
		pos += 3;
		exp_type = WPA_GET_BE32(pos);
		pos += 4;
		if (exp_vendor != vendor || exp_type != (u32) eap_type) {
			wpa_printf(MSG_INFO, "EAP: Invalid expanded frame "
				   "type");
			return NULL;
		}

		*plen = len - sizeof(*hdr) - 8;
		return pos;
	} else {
		if (vendor != EAP_VENDOR_IETF || *pos != eap_type) {
			wpa_printf(MSG_INFO, "EAP: Invalid frame type");
			return NULL;
		}
		*plen = len - sizeof(*hdr) - 1;
		return pos + 1;
	}
}
Beispiel #27
0
char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
			    size_t buf_len)
{
	int ret;

	ret = os_snprintf(buf, buf_len, "%u-%08X-%u",
			  WPA_GET_BE16(dev_type), WPA_GET_BE32(&dev_type[2]),
			  WPA_GET_BE16(&dev_type[6]));
	if (ret < 0 || (unsigned int) ret >= buf_len)
		return NULL;

	return buf;
}
static void eap_sm_parseEapResp(struct eap_sm *sm, u8 *resp, size_t len)
{
	struct eap_hdr *hdr;
	size_t plen;

	/* parse rxResp, respId, respMethod */
	sm->rxResp = FALSE;
	sm->respId = -1;
	sm->respMethod = EAP_TYPE_NONE;
	sm->respVendor = EAP_VENDOR_IETF;
	sm->respVendorMethod = EAP_TYPE_NONE;

	if (resp == NULL || len < sizeof(*hdr))
		return;

	hdr = (struct eap_hdr *) resp;
	plen = ntohs(hdr->length);
	if (plen > len) {
		wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
			   "(len=%lu plen=%lu)", (unsigned long) len,
			   (unsigned long) plen);
		return;
	}

	sm->respId = hdr->identifier;

	if (hdr->code == EAP_CODE_RESPONSE)
		sm->rxResp = TRUE;

	if (plen > sizeof(*hdr)) {
		u8 *pos = (u8 *) (hdr + 1);
		sm->respMethod = *pos++;
		if (sm->respMethod == EAP_TYPE_EXPANDED) {
			if (plen < sizeof(*hdr) + 8) {
				wpa_printf(MSG_DEBUG, "EAP: Ignored truncated "
					   "expanded EAP-Packet (plen=%lu)",
					   (unsigned long) plen);
				return;
			}
			sm->respVendor = WPA_GET_BE24(pos);
			pos += 3;
			sm->respVendorMethod = WPA_GET_BE32(pos);
		}
	}

	wpa_printf(MSG_DEBUG, "EAP: parseEapResp: rxResp=%d respId=%d "
		   "respMethod=%u respVendor=%u respVendorMethod=%u",
		   sm->rxResp, sm->respId, sm->respMethod, sm->respVendor,
		   sm->respVendorMethod);
}
Beispiel #29
0
void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
{
	struct wps_context *wps = wpa_s->wps;

	if (wps == NULL)
		return;

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS) {
		wps->config_methods = wps_config_methods_str2bin(
			wpa_s->conf->config_methods);
		if ((wps->config_methods &
		     (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
		    (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
			wpa_printf(MSG_ERROR, "WPS: Both Label and Display "
				   "config methods are not allowed at the "
				   "same time");
			wps->config_methods &= ~WPS_CONFIG_LABEL;
		}
	}
	wps->config_methods = wps_fix_config_methods(wps->config_methods);

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
		os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
			  WPS_DEV_TYPE_LEN);

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) {
		wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
		os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
			  wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN);
	}

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)
		wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID)
		wpas_wps_set_uuid(wpa_s, wps);

	if (wpa_s->conf->changed_parameters &
	    (CFG_CHANGED_DEVICE_NAME | CFG_CHANGED_WPS_STRING)) {
		/* Update pointers to make sure they refer current values */
		wps->dev.device_name = wpa_s->conf->device_name;
		wps->dev.manufacturer = wpa_s->conf->manufacturer;
		wps->dev.model_name = wpa_s->conf->model_name;
		wps->dev.model_number = wpa_s->conf->model_number;
		wps->dev.serial_number = wpa_s->conf->serial_number;
	}
}
Beispiel #30
0
/**
 * wpa_bss_get_vendor_ie - Fetch a vendor information element from a BSS entry
 * @bss: BSS table entry
 * @vendor_type: Vendor type (four octets starting the IE payload)
 * Returns: Pointer to the information element (id field) or %NULL if not found
 *
 * This function returns the first matching information element in the BSS
 * entry.
 */
const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type)
{
	const u8 *end, *pos;

	pos = (const u8 *) (bss + 1);
	end = pos + bss->ie_len;

	while (pos + 1 < end) {
		if (pos + 2 + pos[1] > end)
			break;
		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
		    vendor_type == WPA_GET_BE32(&pos[2]))
			return pos;
		pos += 2 + pos[1];
	}

	return NULL;
}