Exemplo n.º 1
0
static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
					   char *cmd)
{
	char *pos;
	int id;
	struct wpa_ssid *ssid;
	u8 bssid[ETH_ALEN];

	/* cmd: "<network id> <BSSID>" */
	pos = os_strchr(cmd, ' ');
	if (pos == NULL)
		return -1;
	*pos++ = '\0';
	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
	if (hwaddr_aton(pos, bssid)) {
		wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
		return -1;
	}

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
			   "to update", id);
		return -1;
	}

	os_memcpy(ssid->bssid, bssid, ETH_ALEN);
	ssid->bssid_set =
		os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0;
		

	return 0;
}
Exemplo n.º 2
0
/**
 * wpas_dbus_iface_select_network - Attempt association with a configured network
 * @message: Pointer to incoming dbus message
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: A dbus message containing a UINT32 indicating success (1) or
 *          failure (0)
 *
 * Handler function for "selectNetwork" method call of network interface.
 */
DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
					     struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;
	const char *op;
	struct wpa_ssid *ssid;
	char *iface_obj_path = NULL;
	char *network = NULL;

	if (os_strlen(dbus_message_get_signature(message)) == 0) {
		/* Any network */
		ssid = NULL;
	} else {
		int nid;

		if (!dbus_message_get_args(message, NULL,
					   DBUS_TYPE_OBJECT_PATH, &op,
					   DBUS_TYPE_INVALID)) {
			reply = wpas_dbus_new_invalid_opts_error(message,
								 NULL);
			goto out;
		}

		/* Extract the network number */
		iface_obj_path = wpas_dbus_decompose_object_path(op,
								 &network,
								 NULL);
		if (iface_obj_path == NULL) {
			reply = wpas_dbus_new_invalid_iface_error(message);
			goto out;
		}
		/* Ensure the object path really points to this interface */
		if (os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}

		nid = strtoul(network, NULL, 10);
		if (errno == EINVAL) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}

		ssid = wpa_config_get_network(wpa_s->conf, nid);
		if (ssid == NULL) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}
	}

	/* Finally, associate with the network */
	wpa_supplicant_select_network(wpa_s, ssid);

	reply = wpas_dbus_new_success_reply(message);

out:
	os_free(iface_obj_path);
	os_free(network);
	return reply;
}
Exemplo n.º 3
0
static int wpa_supplicant_ctrl_iface_enable_network(
	struct wpa_supplicant *wpa_s, char *cmd)
{
	int id;
	struct wpa_ssid *ssid;

	/* cmd: "<network id>" */
	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
			   "id=%d", id);
		return -1;
	}

	if (wpa_s->current_ssid == NULL && ssid->disabled) {
		/*
		 * Try to reassociate since there is no current configuration
		 * and a new network was made available. */
		wpa_s->reassociate = 1;
#ifdef ANDROID
		wpa_supplicant_req_scan(wpa_s, 2, 0);
#else
		wpa_supplicant_req_scan(wpa_s, 0, 0);
#endif
	}
	ssid->disabled = 0;

	return 0;
}
Exemplo n.º 4
0
static int wpa_supplicant_ctrl_iface_remove_network(
	struct wpa_supplicant *wpa_s, char *cmd)
{
	int id;
	struct wpa_ssid *ssid;

	/* cmd: "<network id>" */
	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL ||
	    wpa_config_remove_network(wpa_s->conf, id) < 0) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
			   "id=%d", id);
		return -1;
	}

	if (ssid == wpa_s->current_ssid) {
		/*
		 * Invalidate the EAP session cache if the current network is
		 * removed.
		 */
		eapol_sm_invalidate_cached_session(wpa_s->eapol);

		wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
	}

	return 0;
}
Exemplo n.º 5
0
/**
 * wpas_dbus_iface_remove_network - Remove a configured network
 * @message: Pointer to incoming dbus message
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: A dbus message containing a UINT32 indicating success (1) or
 *          failure (0)
 *
 * Handler function for "removeNetwork" method call of a network interface.
 */
DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,
					     struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;
	const char *op;
	char *iface = NULL, *net_id = NULL;
	int id;
	struct wpa_ssid *ssid;

	if (!dbus_message_get_args(message, NULL,
	                           DBUS_TYPE_OBJECT_PATH, &op,
	                           DBUS_TYPE_INVALID)) {
		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
		goto out;
	}

	/* Extract the network ID */
	iface = wpas_dbus_decompose_object_path(op, &net_id, NULL);
	if (iface == NULL) {
		reply = wpas_dbus_new_invalid_network_error(message);
		goto out;
	}

	/* Ensure the network is actually a child of this interface */
	if (os_strcmp(iface, wpa_s->dbus_path) != 0) {
		reply = wpas_dbus_new_invalid_network_error(message);
		goto out;
	}

	id = strtoul(net_id, NULL, 10);
	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		reply = wpas_dbus_new_invalid_network_error(message);
		goto out;
	}

	wpas_notify_network_removed(wpa_s, ssid);

	if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
		reply = dbus_message_new_error(message,
					       WPAS_ERROR_REMOVE_NETWORK_ERROR,
					       "error removing the specified "
					       "on this interface.");
		goto out;
	}

	if (ssid == wpa_s->current_ssid)
		wpa_supplicant_deauthenticate(wpa_s,
					      WLAN_REASON_DEAUTH_LEAVING);
	reply = wpas_dbus_new_success_reply(message);

out:
	os_free(iface);
	os_free(net_id);
	return reply;
}
Exemplo n.º 6
0
static int wpa_supplicant_ctrl_iface_set_network(
	struct wpa_supplicant *wpa_s, char *cmd)
{
	int id;
	struct wpa_ssid *ssid;
	char *name, *value;

	/* cmd: "<network id> <variable name> <value>" */
	name = os_strchr(cmd, ' ');
	if (name == NULL)
		return -1;
	*name++ = '\0';

	value = os_strchr(name, ' ');
	if (value == NULL)
		return -1;
	*value++ = '\0';

	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
		   id, name);
	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
			      (u8 *) value, os_strlen(value));

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
			   "id=%d", id);
		return -1;
	}

	if (wpa_config_set(ssid, name, value, 0) < 0) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
			   "variable '%s'", name);
		return -1;
	} else {
		if (os_strcmp(name, "priority") == 0) {
			wpa_config_update_prio_list(wpa_s->conf);
		}
	}

	if (wpa_s->current_ssid == ssid) {
		/*
		 * Invalidate the EAP session cache if anything in the current
		 * configuration changes.
		 */
		eapol_sm_invalidate_cached_session(wpa_s->eapol);
	}

	if ((os_strcmp(name, "psk") == 0 &&
	     value[0] == '"' && ssid->ssid_len) ||
	    (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
		wpa_config_update_psk(ssid);

	return 0;
}
Exemplo n.º 7
0
static int wpa_supplicant_ctrl_iface_select_network(
	struct wpa_supplicant *wpa_s, char *cmd)
{
	int id;
	struct wpa_ssid *ssid;

	/* cmd: "<network id>" or "any" */
	if (os_strcmp(cmd, "any") == 0) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
		ssid = wpa_s->conf->ssid;
		while (ssid) {
			ssid->disabled = 0;
			ssid = ssid->next;
		}
		wpa_s->reassociate = 1;
		wpa_supplicant_req_scan(wpa_s, 0, 0);
		return 0;
	}

	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
			   "id=%d", id);
		return -1;
	}

	if (ssid != wpa_s->current_ssid && wpa_s->current_ssid)
		wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);

	/* Mark all other networks disabled and trigger reassociation */
	ssid = wpa_s->conf->ssid;
	while (ssid) {
		ssid->disabled = id != ssid->id;
		ssid = ssid->next;
	}
	wpa_s->reassociate = 1;
	wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
	wpa_supplicant_req_scan(wpa_s, 0, 0);

	return 0;
}
Exemplo n.º 8
0
static int wpa_supplicant_ctrl_iface_disable_network(
	struct wpa_supplicant *wpa_s, char *cmd)
{
	int id;
	struct wpa_ssid *ssid;

	/* cmd: "<network id>" or "all" */
	if (os_strcmp(cmd, "all") == 0) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
		ssid = wpa_s->conf->ssid;
		while (ssid) {
			ssid->disabled = 1;
			ssid = ssid->next;
		}
		if (wpa_s->current_ssid)
			wpa_supplicant_disassociate(wpa_s,
				                    WLAN_REASON_DEAUTH_LEAVING);
		return 0;
	}

	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
			   "id=%d", id);
		return -1;
	}

#ifdef ANDROID
	if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not disable WPS network "
			   "id=%d", id);
		return -1;
	}
#endif

	if (ssid == wpa_s->current_ssid)
		wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
	ssid->disabled = 1;

	return 0;
}
static int wpa_supplicant_ctrl_iface_get_network(
	struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
{
	int id;
	struct wpa_ssid *ssid;
	char *name, *value;

	/* cmd: "<network id> <variable name>" */
	name = os_strchr(cmd, ' ');
	if (name == NULL || buflen == 0)
		return -1;
	*name++ = '\0';

	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
		   id, name);

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
			   "id=%d", id);
		return -1;
	}

	value = wpa_config_get_no_key(ssid, name);
	if (value == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
			   "variable '%s'", name);
		return -1;
	}

#ifdef ANDROID_IBSS_HACK
	if ((os_strcmp(name, "ssid") == 0) && (ssid->mode == IEEE80211_MODE_IBSS))
		os_snprintf(buf, buflen, "\"%s%s", ANDROID_IBSS_PREFIX, value+1);
	else
#endif
	os_snprintf(buf, buflen, "%s", value);
	buf[buflen - 1] = '\0';

	os_free(value);

	return os_strlen(buf);
}
Exemplo n.º 10
0
static int wpa_supplicant_ctrl_iface_enable_network(
	struct wpa_supplicant *wpa_s, char *cmd)
{
	int id;
	struct wpa_ssid *ssid;

	/* cmd: "<network id>" or "all" */
	if (os_strcmp(cmd, "all") == 0) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
		ssid = wpa_s->conf->ssid;
		while (ssid) {
			if (ssid == wpa_s->current_ssid && ssid->disabled)
				wpa_s->reassociate = 1;
			ssid->disabled = 0;
			ssid = ssid->next;
		}
		if (wpa_s->reassociate)
			wpa_supplicant_req_scan(wpa_s, 0, 0);
		return 0;
	}

	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
			   "id=%d", id);
		return -1;
	}

	if (wpa_s->current_ssid == NULL && ssid->disabled) {
		/*
		 * Try to reassociate since there is no current configuration
		 * and a new network was made available. */
		wpa_s->reassociate = 1;
		wpa_supplicant_req_scan(wpa_s, 0, 0);
	}
	ssid->disabled = 0;

	return 0;
}
Exemplo n.º 11
0
static int wpa_supplicant_ctrl_iface_get_network(
	struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
{
	int id;
	size_t res;
	struct wpa_ssid *ssid;
	char *name, *value;

	/* cmd: "<network id> <variable name>" */
	name = os_strchr(cmd, ' ');
	if (name == NULL || buflen == 0)
		return -1;
	*name++ = '\0';

	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
		   id, name);

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
			   "id=%d", id);
		return -1;
	}

	value = wpa_config_get_no_key(ssid, name);
	if (value == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
			   "variable '%s'", name);
		return -1;
	}

	res = os_strlcpy(buf, value, buflen);
	if (res >= buflen) {
		os_free(value);
		return -1;
	}

	os_free(value);

	return res;
}
Exemplo n.º 12
0
int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
			   int id)
{
	u8 u[UUID_LEN];
	struct wpa_ssid *ssid;
	struct wps_credential cred;

	if (uuid_str2bin(uuid, u))
		return -1;
	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL || ssid->ssid == NULL)
		return -1;

	os_memset(&cred, 0, sizeof(cred));
	if (ssid->ssid_len > 32)
		return -1;
	os_memcpy(cred.ssid, ssid->ssid, ssid->ssid_len);
	cred.ssid_len = ssid->ssid_len;
	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
		cred.auth_type = (ssid->proto & WPA_PROTO_RSN) ?
			WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
		if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
			cred.encr_type = WPS_ENCR_AES;
		else
			cred.encr_type = WPS_ENCR_TKIP;
		if (ssid->passphrase) {
			cred.key_len = os_strlen(ssid->passphrase);
			if (cred.key_len >= 64)
				return -1;
			os_memcpy(cred.key, ssid->passphrase, cred.key_len);
		} else if (ssid->psk_set) {
			cred.key_len = 32;
			os_memcpy(cred.key, ssid->psk, 32);
		} else
			return -1;
	} else {
		cred.auth_type = WPS_AUTH_OPEN;
		cred.encr_type = WPS_ENCR_NONE;
	}
	return wps_er_set_config(wpa_s->wps_er, u, &cred);
}
Exemplo n.º 13
0
/**
 * wpas_dispatch_network_method - dispatch messages for configured networks
 * @message: the incoming dbus message
 * @wpa_s: a network interface's data
 * @network_id: id of the configured network we're interested in
 * Returns: a reply dbus message, or a dbus error message
 *
 * This function dispatches all incoming dbus messages for configured networks.
 */
static DBusMessage * wpas_dispatch_network_method(DBusMessage *message,
						  struct wpa_supplicant *wpa_s,
						  int network_id)
{
	DBusMessage *reply = NULL;
	const char *method = dbus_message_get_member(message);
	struct wpa_ssid *ssid;

	ssid = wpa_config_get_network(wpa_s->conf, network_id);
	if (ssid == NULL)
		return wpas_dbus_new_invalid_network_error(message);

	if (!strcmp(method, "set"))
		reply = wpas_dbus_iface_set_network(message, wpa_s, ssid);
	else if (!strcmp(method, "enable"))
		reply = wpas_dbus_iface_enable_network(message, wpa_s, ssid);
	else if (!strcmp(method, "disable"))
		reply = wpas_dbus_iface_disable_network(message, wpa_s, ssid);

	return reply;
}
Exemplo n.º 14
0
static int wpa_supplicant_ctrl_iface_disable_network(
	struct wpa_supplicant *wpa_s, char *cmd)
{
	int id;
	struct wpa_ssid *ssid;

	/* cmd: "<network id>" */
	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
			   "id=%d", id);
		return -1;
	}

	if (ssid == wpa_s->current_ssid)
		wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
	ssid->disabled = 1;

	return 0;
}
Exemplo n.º 15
0
/**
 * wpas_dbus_iface_select_network - Attempt association with a configured network
 * @message: Pointer to incoming dbus message
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: A dbus message containing a UINT32 indicating success (1) or
 *          failure (0)
 *
 * Handler function for "selectNetwork" method call of network interface.
 */
DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
					     struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;
	const char *op;
	struct wpa_ssid *ssid;
	char *iface_obj_path = NULL;
	char *network = NULL;

	if (strlen(dbus_message_get_signature(message)) == 0) {
		/* Any network */
		ssid = wpa_s->conf->ssid;
		while (ssid) {
			ssid->disabled = 0;
			ssid = ssid->next;
		}
		wpa_s->reassociate = 1;
		wpa_supplicant_req_scan(wpa_s, 0, 0);
	} else {
		const char *obj_path;
		int nid;

		if (!dbus_message_get_args(message, NULL,
					   DBUS_TYPE_OBJECT_PATH, &op,
					   DBUS_TYPE_INVALID)) {
			reply = wpas_dbus_new_invalid_opts_error(message,
								 NULL);
			goto out;
		}

		/* Extract the network number */
		iface_obj_path = wpas_dbus_decompose_object_path(op,
								 &network,
								 NULL);
		if (iface_obj_path == NULL) {
			reply = wpas_dbus_new_invalid_iface_error(message);
			goto out;
		}
		/* Ensure the object path really points to this interface */
		obj_path = wpa_supplicant_get_dbus_path(wpa_s);
		if (strcmp(iface_obj_path, obj_path) != 0) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}

		nid = strtoul(network, NULL, 10);
		if (errno == EINVAL) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}

		ssid = wpa_config_get_network(wpa_s->conf, nid);
		if (ssid == NULL) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}

		/* Finally, associate with the network */
		if (ssid != wpa_s->current_ssid && wpa_s->current_ssid)
			wpa_supplicant_disassociate(
				wpa_s, WLAN_REASON_DEAUTH_LEAVING);

		/* Mark all other networks disabled and trigger reassociation
		 */
		ssid = wpa_s->conf->ssid;
		while (ssid) {
			ssid->disabled = (nid != ssid->id);
			ssid = ssid->next;
		}
		wpa_s->disconnected = 0;
		wpa_s->reassociate = 1;
		wpa_supplicant_req_scan(wpa_s, 0, 0);
	}

	reply = wpas_dbus_new_success_reply(message);

out:
	free(iface_obj_path);
	free(network);
	return reply;
}
Exemplo n.º 16
0
static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
					      char *rsp)
{
#ifdef IEEE8021X_EAPOL
	char *pos, *id_pos;
	int id;
	struct wpa_ssid *ssid;

	pos = os_strchr(rsp, '-');
	if (pos == NULL)
		return -1;
	*pos++ = '\0';
	id_pos = pos;
	pos = os_strchr(pos, ':');
	if (pos == NULL)
		return -1;
	*pos++ = '\0';
	id = atoi(id_pos);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
			      (u8 *) pos, os_strlen(pos));

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
			   "to update", id);
		return -1;
	}

	if (os_strcmp(rsp, "IDENTITY") == 0) {
		os_free(ssid->identity);
		ssid->identity = (u8 *) os_strdup(pos);
		ssid->identity_len = os_strlen(pos);
		ssid->pending_req_identity = 0;
		if (ssid == wpa_s->current_ssid)
			wpa_s->reassociate = 1;
	} else if (os_strcmp(rsp, "PASSWORD") == 0) {
		os_free(ssid->password);
		ssid->password = (u8 *) os_strdup(pos);
		ssid->password_len = os_strlen(pos);
		ssid->pending_req_password = 0;
		if (ssid == wpa_s->current_ssid)
			wpa_s->reassociate = 1;
	} else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) {
		os_free(ssid->new_password);
		ssid->new_password = (u8 *) os_strdup(pos);
		ssid->new_password_len = os_strlen(pos);
		ssid->pending_req_new_password = 0;
		if (ssid == wpa_s->current_ssid)
			wpa_s->reassociate = 1;
	} else if (os_strcmp(rsp, "PIN") == 0) {
		os_free(ssid->pin);
		ssid->pin = os_strdup(pos);
		ssid->pending_req_pin = 0;
		if (ssid == wpa_s->current_ssid)
			wpa_s->reassociate = 1;
	} else if (os_strcmp(rsp, "OTP") == 0) {
		os_free(ssid->otp);
		ssid->otp = (u8 *) os_strdup(pos);
		ssid->otp_len = os_strlen(pos);
		os_free(ssid->pending_req_otp);
		ssid->pending_req_otp = NULL;
		ssid->pending_req_otp_len = 0;
	} else if (os_strcmp(rsp, "PASSPHRASE") == 0) {
		os_free(ssid->private_key_passwd);
		ssid->private_key_passwd = (u8 *) os_strdup(pos);
		ssid->pending_req_passphrase = 0;
		if (ssid == wpa_s->current_ssid)
			wpa_s->reassociate = 1;
	} else {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);
		return -1;
	}

	return 0;
#else /* IEEE8021X_EAPOL */
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
	return -1;
#endif /* IEEE8021X_EAPOL */
}
Exemplo n.º 17
0
int wps_get_supplicant_ssid_configuration(void *ctx, int index, u8 **buf, size_t *len)
{
	int ret = -1;
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_ssid *ssid;
	struct wps_data *wps = 0;
	u16 auth, encr;
	Boolean enabled8021x = 0;
	u8 nwKeyIdx = -1;
	u8 nwKey[64 + 1];
	Boolean blval;
	size_t length;
	u8 nwIdx;

	do {
		if (!buf || !len)
			break;
		*buf = 0;
		*len = 0;

		ssid = wpa_config_get_network(wpa_s->conf, index);
		if (!ssid)
			break;

		if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
			if (ssid->proto & WPA_PROTO_RSN)
				auth = WPS_AUTHTYPE_WPA2;
			else
				auth = WPS_AUTHTYPE_WPA;

			if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
				encr = WPS_ENCRTYPE_AES;
			else
				encr = WPS_ENCRTYPE_TKIP;
			enabled8021x = 1;
		} else if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
			if (ssid->proto & WPA_PROTO_RSN)
				auth = WPS_AUTHTYPE_WPA2PSK;
			else
				auth = WPS_AUTHTYPE_WPAPSK;

			if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
				encr = WPS_ENCRTYPE_AES;
			else
				encr = WPS_ENCRTYPE_TKIP;
			nwKeyIdx = 0;
		} else if (ssid->key_mgmt & WPA_KEY_MGMT_NONE) {
			if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) {
				auth = WPS_AUTHTYPE_SHARED;
				nwKeyIdx = ssid->wep_tx_keyidx + 1;
			} else
				auth = WPS_AUTHTYPE_OPEN;

			if ((ssid->pairwise_cipher & (WPA_CIPHER_WEP40|WPA_CIPHER_WEP104)) ||
				(ssid->group_cipher & (WPA_CIPHER_WEP40|WPA_CIPHER_WEP104))) {
				encr = WPS_ENCRTYPE_WEP;
				nwKeyIdx = ssid->wep_tx_keyidx + 1;
			} else
				encr = WPS_ENCRTYPE_NONE;
		} else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
			auth = WPS_AUTHTYPE_OPEN;
			encr = WPS_ENCRTYPE_WEP;
			enabled8021x = 1;
		}

		if (wps_create_wps_data(&wps))
			break;

		/* Network Index */
		nwIdx = ssid->id;
		if (wps_set_value(wps, WPS_TYPE_NW_INDEX, &nwIdx, 0))
			break;

		/* SSID */
		if (wps_set_value(wps, WPS_TYPE_SSID, ssid->ssid, ssid->ssid_len))
			break;

		/* Authentication Type */
		if (wps_set_value(wps, WPS_TYPE_AUTH_TYPE, &auth, 0))
			break;

		/* Encryption Type */
		if (wps_set_value(wps, WPS_TYPE_ENCR_TYPE, &encr, 0))
			break;

		if (nwKeyIdx != (u8)-1) {
			if (encr == WPS_ENCRTYPE_WEP) {
				if ((1 > nwKeyIdx) || (4 < nwKeyIdx)) {
					wpa_printf(MSG_WARNING, "Network Key Index is fixed. %d -> 1\n", nwKeyIdx);
					nwKeyIdx = 1;
				}

				/* Network Key Index (Option) */
				if (wps_set_value(wps, WPS_TYPE_NW_KEY_INDEX, &nwKeyIdx, 0))
					break;
			}

			/* Network Key */
			if (ssid->passphrase) {
				length = os_strlen(ssid->passphrase);
				strncpy((char *)nwKey, ssid->passphrase, length);
				nwKey[length] = 0;
			} else if (ssid->psk_set) {
				length = PMK_LEN * 2;
				wpa_snprintf_hex_uppercase((char *)nwKey, sizeof(nwKey), ssid->psk, length);
				nwKey[length] = 0;
			} else {
				if (is_hex(ssid->wep_key[nwKeyIdx - 1], ssid->wep_key_len[nwKeyIdx - 1])) {
					length = (u16)ssid->wep_key_len[nwKeyIdx - 1] * 2;
					wpa_snprintf_hex_uppercase((char *)nwKey, sizeof(nwKey), ssid->wep_key[nwKeyIdx - 1], length);
					nwKey[length] = 0;
				} else {
					length = (u16)ssid->wep_key_len[nwKeyIdx - 1];
					strncpy((char *)nwKey, (char *)ssid->wep_key[nwKeyIdx - 1], length);
					nwKey[length] = 0;
				}
			}
			if (wps_set_value(wps, WPS_TYPE_NW_KEY, nwKey, length))
				break;
		} else {
			/* Network Key (No Key) */
			if (wps_set_value(wps, WPS_TYPE_NW_KEY, 0, 0)) {
				break;
			}
		}

		/* MAC Address */
		if (wps_set_value(wps, WPS_TYPE_MAC_ADDR, wpa_s->own_addr, ETH_ALEN))
			break;

		if (enabled8021x) {
			char *value;

			/* EAP Type (Option) */
			value = wpa_config_get(ssid, "eap");
			if (value) {
				if (wps_set_value(wps, WPS_TYPE_EAP_TYPE, value, os_strlen(value))) {
					free(value);
					break;
				}
				free(value);
			}

			/* EAP Identity (Option) */
			value = wpa_config_get(ssid, "identity");
			if (value) {
				if (wps_set_value(wps, WPS_TYPE_EAP_IDENTITY, value, os_strlen(value))) {
					free(value);
					break;
				}
				free(value);
			}

			/* Key Provided Automaticaly (Option) */
			blval = 1;
			if (wps_set_value(wps, WPS_TYPE_KEY_PROVIDED_AUTO, &blval, 0))
				break;

			/* 802.1X Enabled (Option) */
			if (wps_set_value(wps, WPS_TYPE_8021X_ENABLED, &enabled8021x, 0))
				break;
		}

		if (wps_write_wps_data(wps, buf, len))
			break;

		ret = 0;
	} while (0);

	(void)wps_destroy_wps_data(&wps);

	if (ret) {
		if (buf && *buf) {
			free(*buf);
			*buf = 0;
		}
		if (len)
			*len = 0;
	}

	return ret;
}
Exemplo n.º 18
0
status_t
WPASupplicantApp::_JoinNetwork(BMessage *message)
{
	const char *interfaceName = NULL;
	status_t status = message->FindString("device", &interfaceName);
	if (status != B_OK)
		return status;

	// Check if we already registered this interface.
	wpa_supplicant *interface = wpa_supplicant_get_iface(fWPAGlobal,
		interfaceName);
	if (interface == NULL) {
		wpa_interface interfaceOptions;
		memset(&interfaceOptions, 0, sizeof(wpa_interface));

		interfaceOptions.ifname = interfaceName;

		interface = wpa_supplicant_add_iface(fWPAGlobal, &interfaceOptions);
		if (interface == NULL)
			return B_NO_MEMORY;
	} else {
		// Disable everything
		wpa_supplicant_disable_network(interface, NULL);

		// Try to remove any existing network
		while (true) {
			wpa_ssid *network = wpa_config_get_network(interface->conf, 0);
			if (network == NULL)
				break;

			wpas_notify_network_removed(interface, network);
			wpa_config_remove_network(interface->conf, network->id);
		}
	}

	const char *networkName = NULL;
	status = message->FindString("name", &networkName);
	if (status != B_OK)
		return status;

	uint32 authMode = B_NETWORK_AUTHENTICATION_NONE;
	status = message->FindUInt32("authentication", &authMode);
	if (status != B_OK)
		return status;

	uint32 encapMode = B_NETWORK_EAP_ENCAPSULATION_NONE;
	if (authMode == B_NETWORK_AUTHENTICATION_EAP)
		message->FindUInt32("encapsulation", &encapMode);

	const char *username = NULL;
	if (encapMode > B_NETWORK_EAP_ENCAPSULATION_NONE) {
		status = message->FindString("username", &username);
		if (status != B_OK)
			return status;
	}

	const char *password = NULL;
	if (authMode > B_NETWORK_AUTHENTICATION_NONE) {
		status = message->FindString("password", &password);
		if (status != B_OK)
			return status;
	}

	wpa_ssid *network = wpa_config_add_network(interface->conf);
	if (network == NULL)
		return B_NO_MEMORY;

	wpas_notify_network_added(interface, network);

	network->disabled = 1;
	wpa_config_set_network_defaults(network);

	// Fill in the info from the join request

	// The format includes the quotes
	BString value;
	value = "\"";
	value += networkName;
	value += "\"";
	int result = wpa_config_set(network, "ssid", value.String(), 0);

	if (result == 0)
		result = wpa_config_set(network, "scan_ssid", "1", 1);

	if (authMode >= B_NETWORK_AUTHENTICATION_WPA) {
		if (result == 0)
			result = wpa_config_set(network, "proto", "WPA RSN", 2);
		if (result == 0) {
			switch (authMode) {
				case B_NETWORK_AUTHENTICATION_WPA:
				case B_NETWORK_AUTHENTICATION_WPA2:
				default:
					result = wpa_config_set(network, "key_mgmt", "WPA-PSK", 3);
					break;
				case B_NETWORK_AUTHENTICATION_EAP:
					result = wpa_config_set(network, "key_mgmt", "WPA-EAP", 3);
					break;
			}
		}
		if (result == 0)
			result = wpa_config_set(network, "pairwise", "CCMP TKIP NONE", 4);
		if (result == 0) {
			result = wpa_config_set(network, "group",
				"CCMP TKIP WEP104 WEP40", 5);
		}
		if (result == 0) {
			if (encapMode > B_NETWORK_EAP_ENCAPSULATION_NONE) {
				switch (encapMode) {
					case B_NETWORK_EAP_ENCAPSULATION_PEAP:
						result = wpa_config_set(network, "eap", "PEAP", 6);
						break;
					case B_NETWORK_EAP_ENCAPSULATION_TLS:
						result = wpa_config_set(network, "eap", "TLS", 6);
						break;
				}
			}
		}
	} else {
		// Open or WEP.
		if (result == 0)
			result = wpa_config_set(network, "key_mgmt", "NONE", 6);
	}

	if (result == 0) {
		if (authMode == B_NETWORK_AUTHENTICATION_WEP) {
			if (strncmp("0x", password, 2) == 0) {
				// interpret as hex key
				// TODO: make this non-ambiguous
				result = wpa_config_set(network, "wep_key0", password + 2, 7);
			} else {
				value = "\"";
				value += password;
				value += "\"";
				result = wpa_config_set(network, "wep_key0", value.String(), 8);
			}

			if (result == 0)
				result = wpa_config_set(network, "wep_tx_keyidx", "0", 9);
		} else if (authMode == B_NETWORK_AUTHENTICATION_EAP) {
			// EAP
			value = "\"";
			value += password;
			value += "\"";
			result = wpa_config_set(network, "password", value.String(), 10);
			if (encapMode > B_NETWORK_EAP_ENCAPSULATION_NONE) {
				value = "\"";
				value += username;
				value += "\"";
				result = wpa_config_set(network, "identity",
					value.String(), 11);
			}
			// TODO: Does EAP need the same thing?
			#if 0
			if (result == 0) {
				// We need to actually "apply" the PSK
				wpa_config_update_psk(network);
			}
			#endif
		} else if (authMode >= B_NETWORK_AUTHENTICATION_WPA) {
			// WPA/WPA2
			value = "\"";
			value += password;
			value += "\"";
			result = wpa_config_set(network, "psk", value.String(), 10);

			if (result == 0) {
				// We need to actually "apply" the PSK
				wpa_config_update_psk(network);
			}
		}

		if (result != 0) {
			// The key format is invalid, we need to ask for another password.
			BMessage newJoinRequest = *message;
			newJoinRequest.RemoveName("password");
			newJoinRequest.AddString("error", "Password format invalid");
			newJoinRequest.AddBool("forceDialog", true);
			PostMessage(&newJoinRequest);
		}
	}

	if (result != 0) {
		wpas_notify_network_removed(interface, network);
		wpa_config_remove_network(interface->conf, network->id);
		return B_ERROR;
	}

	// Set up watching for the completion event
	_StartWatchingInterfaceChanges(interface, _InterfaceStateChangeCallback,
		message);

	// Now attempt to connect
	wpa_supplicant_select_network(interface, network);

	// Use a message runner to return a timeout and stop watching after a while
	BMessage timeout(kMsgJoinTimeout);
	timeout.AddPointer("interface", interface);

	BMessageRunner::StartSending(be_app_messenger, &timeout,
		15 * 1000 * 1000, 1);
		// Note that we don't need to cancel this. If joining works before the
		// timeout happens, it will take the StateChangeWatchingEntry with it
		// and the timeout message won't match anything and be discarded.

	return B_OK;
}