[pkg-wpa-devel] r950 - in /wpasupplicant/branches/upstream/current: src/common/ src/drivers/ src/eap_peer/ src/l2_packet/ src/utils/ wpa_supplicant/ wpa_supplicant/doc/docbook/ wpa_supplicant/wpa_gui-qt4/ wpa_supplicant/wpa_gui/

kelmo-guest at users.alioth.debian.org kelmo-guest at users.alioth.debian.org
Wed Dec 26 23:42:19 UTC 2007


Author: kelmo-guest
Date: Wed Dec 26 23:42:18 2007
New Revision: 950

URL: http://svn.debian.org/wsvn/?sc=1&rev=950
Log:
[svn-upgrade] Integrating new upstream version, wpasupplicant (0.6.2~git20071227.00d591e)

Added:
    wpasupplicant/branches/upstream/current/src/common/privsep_commands.h
    wpasupplicant/branches/upstream/current/src/drivers/driver_privsep.c
    wpasupplicant/branches/upstream/current/src/l2_packet/l2_packet_privsep.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/dbus-wpa_supplicant.service
    wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_gui.sgml
    wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_priv.c
Modified:
    wpasupplicant/branches/upstream/current/src/drivers/driver.h
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c
    wpasupplicant/branches/upstream/current/src/utils/pcsc_funcs.c
    wpasupplicant/branches/upstream/current/src/utils/wpa_debug.c
    wpasupplicant/branches/upstream/current/src/utils/wpa_debug.h
    wpasupplicant/branches/upstream/current/wpa_supplicant/.gitignore
    wpasupplicant/branches/upstream/current/wpa_supplicant/ChangeLog
    wpasupplicant/branches/upstream/current/wpa_supplicant/Makefile
    wpasupplicant/branches/upstream/current/wpa_supplicant/README
    wpasupplicant/branches/upstream/current/wpa_supplicant/defconfig
    wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/Makefile
    wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_cli.sgml
    wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml
    wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
    wpasupplicant/branches/upstream/current/wpa_supplicant/main.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/main_winmain.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/main_winsvc.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/todo.txt
    wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
    wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui/networkconfig.ui.h
    wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant_i.h

Added: wpasupplicant/branches/upstream/current/src/common/privsep_commands.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/common/privsep_commands.h?rev=950&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/common/privsep_commands.h (added)
+++ wpasupplicant/branches/upstream/current/src/common/privsep_commands.h Wed Dec 26 23:42:18 2007
@@ -1,0 +1,75 @@
+/*
+ * WPA Supplicant - privilege separation commands
+ * Copyright (c) 2007, Jouni Malinen <j at w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef PRIVSEP_COMMANDS_H
+#define PRIVSEP_COMMANDS_H
+
+enum privsep_cmd {
+	PRIVSEP_CMD_REGISTER,
+	PRIVSEP_CMD_UNREGISTER,
+	PRIVSEP_CMD_SET_WPA,
+	PRIVSEP_CMD_SCAN,
+	PRIVSEP_CMD_GET_SCAN_RESULTS,
+	PRIVSEP_CMD_ASSOCIATE,
+	PRIVSEP_CMD_GET_BSSID,
+	PRIVSEP_CMD_GET_SSID,
+	PRIVSEP_CMD_SET_KEY,
+	PRIVSEP_CMD_GET_CAPA,
+	PRIVSEP_CMD_L2_REGISTER,
+	PRIVSEP_CMD_L2_UNREGISTER,
+	PRIVSEP_CMD_L2_NOTIFY_AUTH_START,
+	PRIVSEP_CMD_L2_SEND,
+};
+
+struct privsep_cmd_associate
+{
+	u8 bssid[ETH_ALEN];
+	u8 ssid[32];
+	size_t ssid_len;
+	int freq;
+	int pairwise_suite;
+	int group_suite;
+	int key_mgmt_suite;
+	int auth_alg;
+	int mode;
+	size_t wpa_ie_len;
+	/* followed by wpa_ie_len bytes of wpa_ie */
+};
+
+struct privsep_cmd_set_key
+{
+	int alg;
+	u8 addr[ETH_ALEN];
+	int key_idx;
+	int set_tx;
+	u8 seq[8];
+	size_t seq_len;
+	u8 key[32];
+	size_t key_len;
+};
+
+enum privsep_event {
+	PRIVSEP_EVENT_SCAN_RESULTS,
+	PRIVSEP_EVENT_ASSOC,
+	PRIVSEP_EVENT_DISASSOC,
+	PRIVSEP_EVENT_ASSOCINFO,
+	PRIVSEP_EVENT_MICHAEL_MIC_FAILURE,
+	PRIVSEP_EVENT_INTERFACE_STATUS,
+	PRIVSEP_EVENT_PMKID_CANDIDATE,
+	PRIVSEP_EVENT_STKSTART,
+	PRIVSEP_EVENT_FT_RESPONSE,
+	PRIVSEP_EVENT_RX_EAPOL,
+};
+
+#endif /* PRIVSEP_COMMANDS_H */

Modified: wpasupplicant/branches/upstream/current/src/drivers/driver.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/drivers/driver.h?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/drivers/driver.h (original)
+++ wpasupplicant/branches/upstream/current/src/drivers/driver.h Wed Dec 26 23:42:18 2007
@@ -870,7 +870,7 @@
 	 * This event needs to be delivered when the driver completes IEEE
 	 * 802.11 association or reassociation successfully.
 	 * wpa_driver_ops::get_bssid() is expected to provide the current BSSID
-	 * after this even has been generated. In addition, optional
+	 * after this event has been generated. In addition, optional
 	 * EVENT_ASSOCINFO may be generated just before EVENT_ASSOC to provide
 	 * more information about the association. If the driver interface gets
 	 * both of these events at the same time, it can also include the

Added: wpasupplicant/branches/upstream/current/src/drivers/driver_privsep.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/drivers/driver_privsep.c?rev=950&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/drivers/driver_privsep.c (added)
+++ wpasupplicant/branches/upstream/current/src/drivers/driver_privsep.c Wed Dec 26 23:42:18 2007
@@ -1,0 +1,724 @@
+/*
+ * WPA Supplicant - privilege separated driver interface
+ * Copyright (c) 2007, Jouni Malinen <j at w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+#include <sys/un.h>
+
+#include "common.h"
+#include "driver.h"
+#include "eloop.h"
+#include "privsep_commands.h"
+
+
+struct wpa_driver_privsep_data {
+	void *ctx;
+	u8 own_addr[ETH_ALEN];
+	int priv_socket;
+	char *own_socket_path;
+	int cmd_socket;
+	char *own_cmd_path;
+	struct sockaddr_un priv_addr;
+	char ifname[16];
+};
+
+
+static int wpa_priv_reg_cmd(struct wpa_driver_privsep_data *drv, int cmd)
+{
+	int res;
+
+	res = sendto(drv->priv_socket, &cmd, sizeof(cmd), 0,
+		     (struct sockaddr *) &drv->priv_addr,
+		     sizeof(drv->priv_addr));
+	if (res < 0)
+		perror("sendto");
+	return res < 0 ? -1 : 0;
+}
+
+
+static int wpa_priv_cmd(struct wpa_driver_privsep_data *drv, int cmd,
+			const void *data, size_t data_len,
+			void *reply, size_t *reply_len)
+{
+	struct msghdr msg;
+	struct iovec io[2];
+
+	io[0].iov_base = &cmd;
+	io[0].iov_len = sizeof(cmd);
+	io[1].iov_base = (u8 *) data;
+	io[1].iov_len = data_len;
+
+	os_memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = io;
+	msg.msg_iovlen = data ? 2 : 1;
+	msg.msg_name = &drv->priv_addr;
+	msg.msg_namelen = sizeof(drv->priv_addr);
+
+	if (sendmsg(drv->cmd_socket, &msg, 0) < 0) {
+		perror("sendmsg(cmd_socket)");
+		return -1;
+	}
+
+	if (reply) {
+		fd_set rfds;
+		struct timeval tv;
+		int res;
+
+		FD_ZERO(&rfds);
+		FD_SET(drv->cmd_socket, &rfds);
+		tv.tv_sec = 5;
+		tv.tv_usec = 0;
+		res = select(drv->cmd_socket + 1, &rfds, NULL, NULL, &tv);
+		if (res < 0 && errno != EINTR) {
+			perror("select");
+			return -1;
+		}
+
+		if (FD_ISSET(drv->cmd_socket, &rfds)) {
+			res = recv(drv->cmd_socket, reply, *reply_len, 0);
+			if (res < 0) {
+				perror("recv");
+				return -1;
+			}
+			*reply_len = res;
+		} else {
+			wpa_printf(MSG_DEBUG, "PRIVSEP: Timeout while waiting "
+				   "for reply (cmd=%d)", cmd);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+			     
+static int wpa_driver_privsep_set_wpa(void *priv, int enabled)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
+	return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_WPA, &enabled,
+			    sizeof(enabled), NULL, NULL);
+}
+
+
+static int wpa_driver_privsep_scan(void *priv, const u8 *ssid, size_t ssid_len)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+	wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv);
+	return wpa_priv_cmd(drv, PRIVSEP_CMD_SCAN, ssid, ssid_len,
+			    NULL, NULL);
+}
+
+
+static int wpa_driver_privsep_get_scan_results(void *priv,
+					    struct wpa_scan_result *results,
+					    size_t max_size)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+	int res;
+	int buf_size = max_size;
+	size_t reply_len = max_size * sizeof(*results);
+
+	res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_SCAN_RESULTS,
+			   &buf_size, sizeof(buf_size),
+			   results, &reply_len);
+	if (res < 0)
+		return res;
+
+	wpa_printf(MSG_DEBUG, "privsep: Received %lu bytes of scan results",
+		   (unsigned long) reply_len);
+	if (reply_len % sizeof(*results)) {
+		wpa_printf(MSG_DEBUG, "privsep: Invalid scan result len %lu",
+			   (unsigned long) reply_len);
+		return -1;
+	}
+
+	return reply_len / sizeof(*results);
+}
+
+
+static int wpa_driver_privsep_set_key(void *priv, wpa_alg alg, const u8 *addr,
+				   int key_idx, int set_tx,
+				   const u8 *seq, size_t seq_len,
+				   const u8 *key, size_t key_len)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+	struct privsep_cmd_set_key cmd;
+
+	wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d",
+		   __func__, priv, alg, key_idx, set_tx);
+
+	os_memset(&cmd, 0, sizeof(cmd));
+	cmd.alg = alg;
+	if (addr)
+		os_memcpy(cmd.addr, addr, ETH_ALEN);
+	else
+		os_memset(cmd.addr, 0xff, ETH_ALEN);
+	cmd.key_idx = key_idx;
+	cmd.set_tx = set_tx;
+	if (seq && seq_len > 0 && seq_len < sizeof(cmd.seq)) {
+		os_memcpy(cmd.seq, seq, seq_len);
+		cmd.seq_len = seq_len;
+	}
+	if (key && key_len > 0 && key_len < sizeof(cmd.key)) {
+		os_memcpy(cmd.key, key, key_len);
+		cmd.key_len = key_len;
+	}
+
+	return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_KEY, &cmd, sizeof(cmd),
+			    NULL, NULL);
+}
+
+
+static int wpa_driver_privsep_associate(
+	void *priv, struct wpa_driver_associate_params *params)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+	struct privsep_cmd_associate *data;
+	int res;
+	size_t buflen;
+
+	wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d "
+		   "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
+		   __func__, priv, params->freq, params->pairwise_suite,
+		   params->group_suite, params->key_mgmt_suite,
+		   params->auth_alg, params->mode);
+
+	buflen = sizeof(*data) + params->wpa_ie_len;
+	data = os_zalloc(buflen);
+	if (data == NULL)
+		return -1;
+
+	if (params->bssid)
+		os_memcpy(data->bssid, params->bssid, ETH_ALEN);
+	os_memcpy(data->ssid, params->ssid, params->ssid_len);
+	data->ssid_len = params->ssid_len;
+	data->freq = params->freq;
+	data->pairwise_suite = params->pairwise_suite;
+	data->group_suite = params->group_suite;
+	data->key_mgmt_suite = params->key_mgmt_suite;
+	data->auth_alg = params->auth_alg;
+	data->mode = params->mode;
+	data->wpa_ie_len = params->wpa_ie_len;
+	if (params->wpa_ie)
+		os_memcpy(data + 1, params->wpa_ie, params->wpa_ie_len);
+	/* TODO: add support for other assoc parameters */
+
+	res = wpa_priv_cmd(drv, PRIVSEP_CMD_ASSOCIATE, data, buflen,
+			   NULL, NULL);
+	os_free(data);
+
+	return res;
+}
+
+
+static int wpa_driver_privsep_get_bssid(void *priv, u8 *bssid)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+	int res;
+	size_t len = ETH_ALEN;
+
+	res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_BSSID, NULL, 0, bssid, &len);
+	if (res < 0 || len != ETH_ALEN)
+		return -1;
+	return 0;
+}
+
+
+static int wpa_driver_privsep_get_ssid(void *priv, u8 *ssid)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+	int res, ssid_len;
+	u8 reply[sizeof(int) + 32];
+	size_t len = sizeof(reply);
+
+	res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_SSID, NULL, 0, reply, &len);
+	if (res < 0 || len < sizeof(int))
+		return -1;
+	os_memcpy(&ssid_len, reply, sizeof(int));
+	if (ssid_len < 0 || ssid_len > 32 || sizeof(int) + ssid_len > len) {
+		wpa_printf(MSG_DEBUG, "privsep: Invalid get SSID reply");
+		return -1;
+	}
+	os_memcpy(ssid, &reply[sizeof(int)], ssid_len);
+	return ssid_len;
+}
+
+
+static int wpa_driver_privsep_deauthenticate(void *priv, const u8 *addr,
+					  int reason_code)
+{
+	//struct wpa_driver_privsep_data *drv = priv;
+	wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
+		   __func__, MAC2STR(addr), reason_code);
+	wpa_printf(MSG_DEBUG, "%s - TODO", __func__);
+	return 0;
+}
+
+
+static int wpa_driver_privsep_disassociate(void *priv, const u8 *addr,
+					int reason_code)
+{
+	//struct wpa_driver_privsep_data *drv = priv;
+	wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
+		   __func__, MAC2STR(addr), reason_code);
+	wpa_printf(MSG_DEBUG, "%s - TODO", __func__);
+	return 0;
+}
+
+
+static void wpa_driver_privsep_event_assoc(void *ctx, wpa_event_type event,
+					   u8 *buf, size_t len)
+{
+	union wpa_event_data data;
+	int inc_data = 0;
+	u8 *pos, *end;
+	int ie_len;
+
+	os_memset(&data, 0, sizeof(data));
+
+	pos = buf;
+	end = buf + len;
+
+	if (end - pos < (int) sizeof(int))
+		return;
+	os_memcpy(&ie_len, pos, sizeof(int));
+	pos += sizeof(int);
+	if (ie_len < 0 || ie_len > end - pos)
+		return;
+	if (ie_len) {
+		data.assoc_info.req_ies = pos;
+		data.assoc_info.req_ies_len = ie_len;
+		pos += ie_len;
+		inc_data = 1;
+	}
+
+	wpa_supplicant_event(ctx, event, inc_data ? &data : NULL);
+}
+
+
+static void wpa_driver_privsep_event_interface_status(void *ctx, u8 *buf,
+						      size_t len)
+{
+	union wpa_event_data data;
+	int ievent;
+
+	if (len < sizeof(int) ||
+	    len - sizeof(int) > sizeof(data.interface_status.ifname))
+		return;
+
+	os_memcpy(&ievent, buf, sizeof(int));
+
+	os_memset(&data, 0, sizeof(data));
+	data.interface_status.ievent = ievent;
+	os_memcpy(data.interface_status.ifname, buf + sizeof(int),
+		  len - sizeof(int));
+	wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &data);
+}
+
+
+static void wpa_driver_privsep_event_michael_mic_failure(
+	void *ctx, u8 *buf, size_t len)
+{
+	union wpa_event_data data;
+
+	if (len != sizeof(int))
+		return;
+
+	os_memset(&data, 0, sizeof(data));
+	os_memcpy(&data.michael_mic_failure.unicast, buf, sizeof(int));
+	wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
+}
+
+
+static void wpa_driver_privsep_event_pmkid_candidate(void *ctx, u8 *buf,
+						     size_t len)
+{
+	union wpa_event_data data;
+
+	if (len != sizeof(struct pmkid_candidate))
+		return;
+
+	os_memset(&data, 0, sizeof(data));
+	os_memcpy(&data.pmkid_candidate, buf, len);
+	wpa_supplicant_event(ctx, EVENT_PMKID_CANDIDATE, &data);
+}
+
+
+static void wpa_driver_privsep_event_stkstart(void *ctx, u8 *buf, size_t len)
+{
+	union wpa_event_data data;
+
+	if (len != ETH_ALEN)
+		return;
+
+	os_memset(&data, 0, sizeof(data));
+	os_memcpy(data.stkstart.peer, buf, ETH_ALEN);
+	wpa_supplicant_event(ctx, EVENT_STKSTART, &data);
+}
+
+
+static void wpa_driver_privsep_event_ft_response(void *ctx, u8 *buf,
+						 size_t len)
+{
+	union wpa_event_data data;
+
+	if (len < sizeof(int) + ETH_ALEN)
+		return;
+
+	os_memset(&data, 0, sizeof(data));
+	os_memcpy(&data.ft_ies.ft_action, buf, sizeof(int));
+	os_memcpy(data.ft_ies.target_ap, buf + sizeof(int), ETH_ALEN);
+	data.ft_ies.ies = buf + sizeof(int) + ETH_ALEN;
+	data.ft_ies.ies_len = len - sizeof(int) - ETH_ALEN;
+	wpa_supplicant_event(ctx, EVENT_FT_RESPONSE, &data);
+}
+
+
+static void wpa_driver_privsep_event_rx_eapol(void *ctx, u8 *buf, size_t len)
+{
+	if (len < ETH_ALEN)
+		return;
+
+	wpa_supplicant_rx_eapol(ctx, buf, buf + ETH_ALEN, len - ETH_ALEN);
+}
+
+
+static void wpa_driver_privsep_receive(int sock, void *eloop_ctx,
+				       void *sock_ctx)
+{
+	struct wpa_driver_privsep_data *drv = eloop_ctx;
+	u8 *buf, *event_buf;
+	size_t event_len;
+	int res, event;
+	enum privsep_event e;
+	struct sockaddr_un from;
+	socklen_t fromlen = sizeof(from);
+	const size_t buflen = 2000;
+
+	buf = os_malloc(buflen);
+	if (buf == NULL)
+		return;
+	res = recvfrom(sock, buf, buflen, 0,
+		       (struct sockaddr *) &from, &fromlen);
+	if (res < 0) {
+		perror("recvfrom(priv_socket)");
+		os_free(buf);
+		return;
+	}
+
+	wpa_printf(MSG_DEBUG, "privsep_driver: received %u bytes", res);
+
+	if (res < (int) sizeof(int)) {
+		wpa_printf(MSG_DEBUG, "Too short event message (len=%d)", res);
+		return;
+	}
+
+	os_memcpy(&event, buf, sizeof(int));
+	event_buf = &buf[sizeof(int)];
+	event_len = res - sizeof(int);
+	wpa_printf(MSG_DEBUG, "privsep: Event %d received (len=%d)",
+		   event, event_len);
+
+	e = event;
+	switch (e) {
+	case PRIVSEP_EVENT_SCAN_RESULTS:
+		wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL);
+		break;
+	case PRIVSEP_EVENT_ASSOC:
+		wpa_driver_privsep_event_assoc(drv->ctx, EVENT_ASSOC,
+					       event_buf, event_len);
+		break;
+	case PRIVSEP_EVENT_DISASSOC:
+		wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
+		break;
+	case PRIVSEP_EVENT_ASSOCINFO:
+		wpa_driver_privsep_event_assoc(drv->ctx, EVENT_ASSOCINFO,
+					       event_buf, event_len);
+		break;
+	case PRIVSEP_EVENT_MICHAEL_MIC_FAILURE:
+		wpa_driver_privsep_event_michael_mic_failure(
+			drv->ctx, event_buf, event_len);
+		break;
+	case PRIVSEP_EVENT_INTERFACE_STATUS:
+		wpa_driver_privsep_event_interface_status(drv->ctx, event_buf,
+							  event_len);
+		break;
+	case PRIVSEP_EVENT_PMKID_CANDIDATE:
+		wpa_driver_privsep_event_pmkid_candidate(drv->ctx, event_buf,
+							 event_len);
+		break;
+	case PRIVSEP_EVENT_STKSTART:
+		wpa_driver_privsep_event_stkstart(drv->ctx, event_buf,
+						  event_len);
+		break;
+	case PRIVSEP_EVENT_FT_RESPONSE:
+		wpa_driver_privsep_event_ft_response(drv->ctx, event_buf,
+						     event_len);
+		break;
+	case PRIVSEP_EVENT_RX_EAPOL:
+		wpa_driver_privsep_event_rx_eapol(drv->ctx, event_buf,
+						  event_len);
+	}
+
+	os_free(buf);
+}
+
+
+static void * wpa_driver_privsep_init(void *ctx, const char *ifname)
+{
+	struct wpa_driver_privsep_data *drv;
+
+	drv = os_zalloc(sizeof(*drv));
+	if (drv == NULL)
+		return NULL;
+	drv->ctx = ctx;
+	drv->priv_socket = -1;
+	drv->cmd_socket = -1;
+	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
+
+	return drv;
+}
+
+
+static void wpa_driver_privsep_deinit(void *priv)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+
+	if (drv->priv_socket >= 0) {
+		wpa_priv_reg_cmd(drv, PRIVSEP_CMD_UNREGISTER);
+		eloop_unregister_read_sock(drv->priv_socket);
+		close(drv->priv_socket);
+	}
+
+	if (drv->own_socket_path) {
+		unlink(drv->own_socket_path);
+		os_free(drv->own_socket_path);
+	}
+
+	if (drv->cmd_socket >= 0) {
+		eloop_unregister_read_sock(drv->cmd_socket);
+		close(drv->cmd_socket);
+	}
+
+	if (drv->own_cmd_path) {
+		unlink(drv->own_cmd_path);
+		os_free(drv->own_cmd_path);
+	}
+
+	os_free(drv);
+}
+
+
+static int wpa_driver_privsep_set_param(void *priv, const char *param)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+	const char *pos;
+	char *own_dir, *priv_dir;
+	static unsigned int counter = 0;
+	size_t len;
+	struct sockaddr_un addr;
+
+	wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);
+	if (param == NULL)
+		pos = NULL;
+	else
+		pos = os_strstr(param, "own_dir=");
+	if (pos) {
+		char *end;
+		own_dir = os_strdup(pos + 8);
+		if (own_dir == NULL)
+			return -1;
+		end = os_strchr(own_dir, ' ');
+		if (end)
+			*end = '\0';
+	} else {
+		own_dir = os_strdup("/tmp");
+		if (own_dir == NULL)
+			return -1;
+	}
+
+	if (param == NULL)
+		pos = NULL;
+	else
+		pos = os_strstr(param, "priv_dir=");
+	if (pos) {
+		char *end;
+		priv_dir = os_strdup(pos + 9);
+		if (priv_dir == NULL) {
+			os_free(own_dir);
+			return -1;
+		}
+		end = os_strchr(priv_dir, ' ');
+		if (end)
+			*end = '\0';
+	} else {
+		priv_dir = os_strdup("/var/run/wpa_priv");
+		if (priv_dir == NULL) {
+			os_free(own_dir);
+			return -1;
+		}
+	}
+
+	len = os_strlen(own_dir) + 50;
+	drv->own_socket_path = os_malloc(len);
+	if (drv->own_socket_path == NULL) {
+		os_free(priv_dir);
+		os_free(own_dir);
+		return -1;
+	}
+	os_snprintf(drv->own_socket_path, len, "%s/wpa_privsep-%d-%d",
+		    own_dir, getpid(), counter++);
+
+	len = os_strlen(own_dir) + 50;
+	drv->own_cmd_path = os_malloc(len);
+	if (drv->own_cmd_path == NULL) {
+		os_free(drv->own_socket_path);
+		drv->own_socket_path = NULL;
+		os_free(priv_dir);
+		os_free(own_dir);
+		return -1;
+	}
+	os_snprintf(drv->own_cmd_path, len, "%s/wpa_privsep-%d-%d",
+		    own_dir, getpid(), counter++);
+
+	os_free(own_dir);
+
+	drv->priv_addr.sun_family = AF_UNIX;
+	os_snprintf(drv->priv_addr.sun_path, sizeof(drv->priv_addr.sun_path),
+		    "%s/%s", priv_dir, drv->ifname);
+	os_free(priv_dir);
+
+	drv->priv_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
+	if (drv->priv_socket < 0) {
+		perror("socket(PF_UNIX)");
+		os_free(drv->own_socket_path);
+		drv->own_socket_path = NULL;
+		return -1;
+	}
+
+	os_memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path));
+	if (bind(drv->priv_socket, (struct sockaddr *) &addr, sizeof(addr)) <
+	    0) {
+		perror("bind(PF_UNIX)");
+		close(drv->priv_socket);
+		drv->priv_socket = -1;
+		unlink(drv->own_socket_path);
+		os_free(drv->own_socket_path);
+		drv->own_socket_path = NULL;
+		return -1;
+	}
+
+	eloop_register_read_sock(drv->priv_socket, wpa_driver_privsep_receive,
+				 drv, NULL);
+
+	drv->cmd_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
+	if (drv->cmd_socket < 0) {
+		perror("socket(PF_UNIX)");
+		os_free(drv->own_cmd_path);
+		drv->own_cmd_path = NULL;
+		return -1;
+	}
+
+	os_memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	os_strlcpy(addr.sun_path, drv->own_cmd_path, sizeof(addr.sun_path));
+	if (bind(drv->cmd_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0)
+	{
+		perror("bind(PF_UNIX)");
+		close(drv->cmd_socket);
+		drv->cmd_socket = -1;
+		unlink(drv->own_cmd_path);
+		os_free(drv->own_cmd_path);
+		drv->own_cmd_path = NULL;
+		return -1;
+	}
+
+	if (wpa_priv_reg_cmd(drv, PRIVSEP_CMD_REGISTER) < 0) {
+		wpa_printf(MSG_ERROR, "Failed to register with wpa_priv");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static int wpa_driver_privsep_get_capa(void *priv,
+				       struct wpa_driver_capa *capa)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+	int res;
+	size_t len = sizeof(*capa);
+
+	res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_CAPA, NULL, 0, capa, &len);
+	if (res < 0 || len != sizeof(*capa))
+		return -1;
+	return 0;
+}
+
+
+static const u8 * wpa_driver_privsep_get_mac_addr(void *priv)
+{
+	struct wpa_driver_privsep_data *drv = priv;
+	wpa_printf(MSG_DEBUG, "%s", __func__);
+	return drv->own_addr;
+}
+
+
+struct wpa_driver_ops wpa_driver_privsep_ops = {
+	"privsep",
+	"wpa_supplicant privilege separated driver",
+	wpa_driver_privsep_get_bssid,
+	wpa_driver_privsep_get_ssid,
+	wpa_driver_privsep_set_wpa,
+	wpa_driver_privsep_set_key,
+	wpa_driver_privsep_init,
+	wpa_driver_privsep_deinit,
+	wpa_driver_privsep_set_param,
+	NULL /* set_countermeasures */,
+	NULL /* set_drop_unencrypted */,
+	wpa_driver_privsep_scan,
+	wpa_driver_privsep_get_scan_results,
+	wpa_driver_privsep_deauthenticate,
+	wpa_driver_privsep_disassociate,
+	wpa_driver_privsep_associate,
+	NULL /* set_auth_alg */,
+	NULL /* add_pmkid */,
+	NULL /* remove_pmkid */,
+	NULL /* flush_pmkid */,
+	wpa_driver_privsep_get_capa,
+	NULL /* poll */,
+	NULL /* get_ifname */,
+	wpa_driver_privsep_get_mac_addr,
+	NULL /* send_eapol */,
+	NULL /* set_operstate */,
+	NULL /* mlme_setprotection */,
+	NULL /* get_hw_feature_data */,
+	NULL /* set_channel */,
+	NULL /* set_ssid */,
+	NULL /* set_bssid */,
+	NULL /* send_mlme */,
+	NULL /* mlme_add_sta */,
+	NULL /* mlme_remove_sta */,
+	NULL /* update_ft_ies */,
+	NULL /* send_ft_action */
+};
+
+
+struct wpa_driver_ops *wpa_supplicant_drivers[] =
+{
+	&wpa_driver_privsep_ops,
+	NULL
+};

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c Wed Dec 26 23:42:18 2007
@@ -257,8 +257,9 @@
 	ret->decision = DECISION_FAIL;
 
 	if (data->out_used == data->out_len) {
-		wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %u bytes "
-			   "(message sent completely)", send_len);
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %lu bytes "
+			   "(message sent completely)",
+			   (unsigned long) send_len);
 		os_free(data->out_buf);
 		data->out_buf = NULL;
 		data->out_len = data->out_used = 0;
@@ -270,9 +271,9 @@
 		} else
 			eap_wsc_state(data, MSG);
 	} else {
-		wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %u bytes "
-			   "(%u more to send)", send_len,
-			   data->out_len - data->out_used);
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %lu bytes "
+			   "(%lu more to send)", (unsigned long) send_len,
+			   (unsigned long) data->out_len - data->out_used);
 		eap_wsc_state(data, WAIT_FRAG_ACK);
 	}
 
@@ -385,8 +386,8 @@
 		os_memcpy(data->in_buf + data->in_used, pos, end - pos);
 		data->in_used += end - pos;
 		wpa_printf(MSG_DEBUG, "EAP-WSC: Received %u bytes, waiting "
-			   "for %u bytes more", end - pos,
-			   data->in_len - data->in_used);
+			   "for %lu bytes more", (unsigned int) (end - pos),
+			   (unsigned long) data->in_len - data->in_used);
 	}
 
 	if (flags & WSC_FLAGS_MF) {
@@ -410,10 +411,10 @@
 			data->in_used = end - pos;
 			data->in_op_code = op_code;
 			os_memcpy(data->in_buf, pos, data->in_used);
-			wpa_printf(MSG_DEBUG, "EAP-WSC: Received %u bytes in "
-				   "first fragment, waiting for %u bytes more",
-				   data->in_used,
-				   data->in_len - data->in_used);
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Received %lu bytes in "
+				   "first fragment, waiting for %lu bytes more",
+				   (unsigned long) data->in_used,
+				   (unsigned long) data->in_len - data->in_used);
 		}
 
 		return eap_wsc_build_frag_ack(id, EAP_CODE_RESPONSE);

Added: wpasupplicant/branches/upstream/current/src/l2_packet/l2_packet_privsep.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/l2_packet/l2_packet_privsep.c?rev=950&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/l2_packet/l2_packet_privsep.c (added)
+++ wpasupplicant/branches/upstream/current/src/l2_packet/l2_packet_privsep.c Wed Dec 26 23:42:18 2007
@@ -1,0 +1,262 @@
+/*
+ * WPA Supplicant - Layer2 packet handling with privilege separation
+ * Copyright (c) 2007, Jouni Malinen <j at w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+#include <sys/un.h>
+
+#include "common.h"
+#include "eloop.h"
+#include "l2_packet.h"
+#include "privsep_commands.h"
+
+
+struct l2_packet_data {
+	int fd; /* UNIX domain socket for privsep access */
+	void (*rx_callback)(void *ctx, const u8 *src_addr,
+			    const u8 *buf, size_t len);
+	void *rx_callback_ctx;
+	u8 own_addr[ETH_ALEN];
+	char *own_socket_path;
+	struct sockaddr_un priv_addr;
+};
+
+
+static int wpa_priv_cmd(struct l2_packet_data *l2, int cmd,
+			const void *data, size_t data_len)
+{
+	struct msghdr msg;
+	struct iovec io[2];
+
+	io[0].iov_base = &cmd;
+	io[0].iov_len = sizeof(cmd);
+	io[1].iov_base = (u8 *) data;
+	io[1].iov_len = data_len;
+
+	os_memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = io;
+	msg.msg_iovlen = data ? 2 : 1;
+	msg.msg_name = &l2->priv_addr;
+	msg.msg_namelen = sizeof(l2->priv_addr);
+
+	if (sendmsg(l2->fd, &msg, 0) < 0) {
+		perror("L2: sendmsg(cmd)");
+		return -1;
+	}
+
+	return 0;
+}
+
+			     
+int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr)
+{
+	os_memcpy(addr, l2->own_addr, ETH_ALEN);
+	return 0;
+}
+
+
+int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto,
+		   const u8 *buf, size_t len)
+{
+	struct msghdr msg;
+	struct iovec io[4];
+	int cmd = PRIVSEP_CMD_L2_SEND;
+
+	io[0].iov_base = &cmd;
+	io[0].iov_len = sizeof(cmd);
+	io[1].iov_base = &dst_addr;
+	io[1].iov_len = ETH_ALEN;
+	io[2].iov_base = &proto;
+	io[2].iov_len = 2;
+	io[3].iov_base = (u8 *) buf;
+	io[3].iov_len = len;
+
+	os_memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = io;
+	msg.msg_iovlen = 4;
+	msg.msg_name = &l2->priv_addr;
+	msg.msg_namelen = sizeof(l2->priv_addr);
+
+	if (sendmsg(l2->fd, &msg, 0) < 0) {
+		perror("L2: sendmsg(packet_send)");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
+{
+	struct l2_packet_data *l2 = eloop_ctx;
+	u8 buf[2300];
+	int res;
+	struct sockaddr_un from;
+	socklen_t fromlen = sizeof(from);
+
+	os_memset(&from, 0, sizeof(from));
+	res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &from,
+		       &fromlen);
+	if (res < 0) {
+		perror("l2_packet_receive - recvfrom");
+		return;
+	}
+	if (res < ETH_ALEN) {
+		wpa_printf(MSG_DEBUG, "L2: Too show packet received");
+		return;
+	}
+
+	if (from.sun_family != AF_UNIX ||
+	    os_strncmp(from.sun_path, l2->priv_addr.sun_path,
+		       sizeof(from.sun_path)) != 0) {
+		wpa_printf(MSG_DEBUG, "L2: Received message from unexpected "
+			   "source");
+		return;
+	}
+
+	l2->rx_callback(l2->rx_callback_ctx, buf, buf + ETH_ALEN,
+			res - ETH_ALEN);
+}
+
+
+struct l2_packet_data * l2_packet_init(
+	const char *ifname, const u8 *own_addr, unsigned short protocol,
+	void (*rx_callback)(void *ctx, const u8 *src_addr,
+			    const u8 *buf, size_t len),
+	void *rx_callback_ctx, int l2_hdr)
+{
+	struct l2_packet_data *l2;
+	char *own_dir = "/tmp";
+	char *priv_dir = "/var/run/wpa_priv";
+	size_t len;
+	static unsigned int counter = 0;
+	struct sockaddr_un addr;
+	fd_set rfds;
+	struct timeval tv;
+	int res;
+	u8 reply[ETH_ALEN + 1];
+	int reg_cmd[2];
+
+	l2 = os_zalloc(sizeof(struct l2_packet_data));
+	if (l2 == NULL)
+		return NULL;
+	l2->rx_callback = rx_callback;
+	l2->rx_callback_ctx = rx_callback_ctx;
+
+	len = os_strlen(own_dir) + 50;
+	l2->own_socket_path = os_malloc(len);
+	if (l2->own_socket_path == NULL) {
+		os_free(l2);
+		return NULL;
+	}
+	os_snprintf(l2->own_socket_path, len, "%s/wpa_privsep-l2-%d-%d",
+		    own_dir, getpid(), counter++);
+
+	l2->priv_addr.sun_family = AF_UNIX;
+	os_snprintf(l2->priv_addr.sun_path, sizeof(l2->priv_addr.sun_path),
+		    "%s/%s", priv_dir, ifname);
+
+	l2->fd = socket(PF_UNIX, SOCK_DGRAM, 0);
+	if (l2->fd < 0) {
+		perror("socket(PF_UNIX)");
+		os_free(l2->own_socket_path);
+		l2->own_socket_path = NULL;
+		os_free(l2);
+		return NULL;
+	}
+
+	os_memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	os_strlcpy(addr.sun_path, l2->own_socket_path, sizeof(addr.sun_path));
+	if (bind(l2->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		perror("bind(PF_UNIX)");
+		goto fail;
+	}
+
+	reg_cmd[0] = protocol;
+	reg_cmd[1] = l2_hdr;
+	if (wpa_priv_cmd(l2, PRIVSEP_CMD_L2_REGISTER, reg_cmd, sizeof(reg_cmd))
+	    < 0) {
+		wpa_printf(MSG_ERROR, "L2: Failed to register with wpa_priv");
+		goto fail;
+	}
+
+	FD_ZERO(&rfds);
+	FD_SET(l2->fd, &rfds);
+	tv.tv_sec = 5;
+	tv.tv_usec = 0;
+	res = select(l2->fd + 1, &rfds, NULL, NULL, &tv);
+	if (res < 0 && errno != EINTR) {
+		perror("select");
+		goto fail;
+	}
+
+	if (FD_ISSET(l2->fd, &rfds)) {
+		res = recv(l2->fd, reply, sizeof(reply), 0);
+		if (res < 0) {
+			perror("recv");
+			goto fail;
+		}
+	} else {
+		wpa_printf(MSG_DEBUG, "L2: Timeout while waiting for "
+			   "registration reply");
+		goto fail;
+	}
+
+	if (res != ETH_ALEN) {
+		wpa_printf(MSG_DEBUG, "L2: Unexpected registration reply "
+			   "(len=%d)", res);
+	}
+	os_memcpy(l2->own_addr, reply, ETH_ALEN);
+
+	eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL);
+
+	return l2;
+
+fail:
+	close(l2->fd);
+	l2->fd = -1;
+	unlink(l2->own_socket_path);
+	os_free(l2->own_socket_path);
+	l2->own_socket_path = NULL;
+	os_free(l2);
+	return NULL;
+}
+
+
+void l2_packet_deinit(struct l2_packet_data *l2)
+{
+	if (l2 == NULL)
+		return;
+
+	if (l2->fd >= 0) {
+		wpa_priv_cmd(l2, PRIVSEP_CMD_L2_UNREGISTER, NULL, 0);
+		eloop_unregister_read_sock(l2->fd);
+		close(l2->fd);
+	}
+		
+	os_free(l2);
+}
+
+
+int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
+{
+	/* TODO */
+	return -1;
+}
+
+
+void l2_packet_notify_auth_start(struct l2_packet_data *l2)
+{
+	wpa_priv_cmd(l2, PRIVSEP_CMD_L2_NOTIFY_AUTH_START, NULL, 0);
+}

Modified: wpasupplicant/branches/upstream/current/src/utils/pcsc_funcs.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/utils/pcsc_funcs.c?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/utils/pcsc_funcs.c (original)
+++ wpasupplicant/branches/upstream/current/src/utils/pcsc_funcs.c Wed Dec 26 23:42:18 2007
@@ -848,7 +848,8 @@
 	}
 	if (blen != len + 2) {
 		wpa_printf(MSG_DEBUG, "SCARD: record read returned unexpected "
-			   "length %d (expected %d)", blen, len + 2);
+			   "length %ld (expected %ld)",
+			   (long) blen, (long) len + 2);
 		os_free(buf);
 		return -3;
 	}
@@ -891,7 +892,8 @@
 	}
 	if (blen != len + 2) {
 		wpa_printf(MSG_DEBUG, "SCARD: file read returned unexpected "
-			   "length %d (expected %d)", blen, len + 2);
+			   "length %ld (expected %ld)",
+			   (long) blen, (long) len + 2);
 		os_free(buf);
 		return -3;
 	}
@@ -969,7 +971,7 @@
 		return -1;
 	if (blen < 4) {
 		wpa_printf(MSG_WARNING, "SCARD: too short (GSM) EF-IMSI "
-			   "header (len=%d)", blen);
+			   "header (len=%ld)", (long) blen);
 		return -2;
 	}
 
@@ -982,14 +984,14 @@
 		blen = file_size;
 	}
 	if (blen < 2 || blen > sizeof(buf)) {
-		wpa_printf(MSG_DEBUG, "SCARD: invalid IMSI file length=%d",
-			   blen);
+		wpa_printf(MSG_DEBUG, "SCARD: invalid IMSI file length=%ld",
+			   (long) blen);
 		return -3;
 	}
 
 	imsilen = (blen - 2) * 2 + 1;
-	wpa_printf(MSG_DEBUG, "SCARD: IMSI file length=%d imsilen=%d",
-		   blen, imsilen);
+	wpa_printf(MSG_DEBUG, "SCARD: IMSI file length=%ld imsilen=%ld",
+		   (long) blen, (long) imsilen);
 	if (blen < 2 || imsilen > *len) {
 		*len = imsilen;
 		return -4;
@@ -1071,8 +1073,8 @@
 	    (scard->sim_type == SCARD_USIM &&
 	     (len != 2 || resp[0] != 0x61 || resp[1] != 0x0e))) {
 		wpa_printf(MSG_WARNING, "SCARD: unexpected response for GSM "
-			   "auth request (len=%d resp=%02x %02x)",
-			   len, resp[0], resp[1]);
+			   "auth request (len=%ld resp=%02x %02x)",
+			   (long) len, resp[0], resp[1]);
 		return -3;
 	}
 	get_resp[4] = resp[1];
@@ -1085,8 +1087,8 @@
 	if (scard->sim_type == SCARD_GSM_SIM) {
 		if (len != 4 + 8 + 2) {
 			wpa_printf(MSG_WARNING, "SCARD: unexpected data "
-				   "length for GSM auth (len=%d, expected 14)",
-				   len);
+				   "length for GSM auth (len=%ld, expected 14)",
+				   (long) len);
 			return -5;
 		}
 		os_memcpy(sres, buf, 4);
@@ -1094,8 +1096,8 @@
 	} else {
 		if (len != 1 + 4 + 1 + 8 + 2) {
 			wpa_printf(MSG_WARNING, "SCARD: unexpected data "
-				   "length for USIM auth (len=%d, "
-				   "expected 16)", len);
+				   "length for USIM auth (len=%ld, "
+				   "expected 16)", (long) len);
 			return -5;
 		}
 		if (buf[0] != 4 || buf[5] != 8) {
@@ -1176,8 +1178,8 @@
 		return -1;
 	} else if (len != 2 || resp[0] != 0x61) {
 		wpa_printf(MSG_WARNING, "SCARD: unexpected response for UMTS "
-			   "auth request (len=%d resp=%02x %02x)",
-			   len, resp[0], resp[1]);
+			   "auth request (len=%ld resp=%02x %02x)",
+			   (long) len, resp[0], resp[1]);
 		return -1;
 	}
 	get_resp[4] = resp[1];

Modified: wpasupplicant/branches/upstream/current/src/utils/wpa_debug.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/utils/wpa_debug.c?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/utils/wpa_debug.c (original)
+++ wpasupplicant/branches/upstream/current/src/utils/wpa_debug.c Wed Dec 26 23:42:18 2007
@@ -20,7 +20,6 @@
 #ifdef CONFIG_DEBUG_FILE
 static FILE *out_file = NULL;
 #endif /* CONFIG_DEBUG_FILE */
-int wpa_debug_use_file = 0;
 int wpa_debug_level = MSG_INFO;
 int wpa_debug_show_keys = 0;
 int wpa_debug_timestamp = 0;
@@ -227,36 +226,29 @@
 }
 
 
-int wpa_debug_open_file(void)
-{
-#ifdef CONFIG_DEBUG_FILE
-	static int count = 0;
-	char fname[64];
-	if (!wpa_debug_use_file)
+int wpa_debug_open_file(const char *path)
+{
+#ifdef CONFIG_DEBUG_FILE
+	if (!path)
 		return 0;
-#ifdef _WIN32
-	os_snprintf(fname, sizeof(fname), "\\Temp\\wpa_supplicant-log-%d.txt",
-		    count++);
-#else /* _WIN32 */
-	os_snprintf(fname, sizeof(fname), "/tmp/wpa_supplicant-log-%d.txt",
-		    count++);
+	out_file = fopen(path, "a");
+	if (out_file == NULL) {
+		wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
+			   "output file, using standard output");
+		return -1;
+	}
+#ifndef _WIN32
+	setvbuf(out_file, NULL, _IOLBF, 0);
 #endif /* _WIN32 */
-	out_file = fopen(fname, "w");
-#ifndef _WIN32
-	if (out_file)
-		setvbuf(out_file, NULL, _IOLBF, 0);
-#endif /* _WIN32 */
-	return out_file == NULL ? -1 : 0;
-#else /* CONFIG_DEBUG_FILE */
+#endif /* CONFIG_DEBUG_FILE */
 	return 0;
-#endif /* CONFIG_DEBUG_FILE */
 }
 
 
 void wpa_debug_close_file(void)
 {
 #ifdef CONFIG_DEBUG_FILE
-	if (!wpa_debug_use_file)
+	if (!out_file)
 		return;
 	fclose(out_file);
 	out_file = NULL;

Modified: wpasupplicant/branches/upstream/current/src/utils/wpa_debug.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/utils/wpa_debug.h?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/utils/wpa_debug.h (original)
+++ wpasupplicant/branches/upstream/current/src/utils/wpa_debug.h Wed Dec 26 23:42:18 2007
@@ -32,12 +32,12 @@
 #define wpa_hexdump_buf_key(l,t,b) do { } while (0)
 #define wpa_hexdump_ascii(l,t,b,le) do { } while (0)
 #define wpa_hexdump_ascii_key(l,t,b,le) do { } while (0)
-#define wpa_debug_open_file() do { } while (0)
+#define wpa_debug_open_file(p) do { } while (0)
 #define wpa_debug_close_file() do { } while (0)
 
 #else /* CONFIG_NO_STDOUT_DEBUG */
 
-int wpa_debug_open_file(void);
+int wpa_debug_open_file(const char *path);
 void wpa_debug_close_file(void);
 
 /**

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/.gitignore
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/.gitignore?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/.gitignore (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/.gitignore Wed Dec 26 23:42:18 2007
@@ -5,3 +5,4 @@
 wpa_cli
 wpa_passphrase
 wpa_supplicant
+wpa_priv

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/ChangeLog
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/ChangeLog?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/ChangeLog (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/ChangeLog Wed Dec 26 23:42:18 2007
@@ -2,7 +2,7 @@
 
 ????-??-?? - v0.6.2
 	* added support for Makefile builds to include debug-log-to-a-file
-	  functionality (CONFIG_DEBUG_FILE=y and -f on command line)
+	  functionality (CONFIG_DEBUG_FILE=y and -f<path> on command line)
 	* fixed EAP-SIM and EAP-AKA message parser to validate attribute
 	  lengths properly to avoid potential crash caused by invalid messages
 	* added data structure for storing allocated buffers (struct wpabuf);
@@ -23,6 +23,11 @@
 	* stop EAPOL timer tick when no timers are in use in order to reduce
 	  power consumption (no need to wake up the process once per second)
 	  [Bug 237]
+	* added support for privilege separation (run only minimal part of
+	  wpa_supplicant functionality as root and rest as unprivileged,
+	  non-root process); see 'Privilege separation' in README for details;
+	  this is disabled by default and can be enabled with CONFIG_PRIVSEP=y
+	  in .config
 
 2007-11-24 - v0.6.1
 	* added support for configuring password as NtPasswordHash

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/Makefile
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/Makefile?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/Makefile (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/Makefile Wed Dec 26 23:42:18 2007
@@ -222,7 +222,7 @@
 CONFIG_L2_PACKET=linux
 endif
 
-OBJS += ../src/l2_packet/l2_packet_$(CONFIG_L2_PACKET).o
+OBJS_l2 += ../src/l2_packet/l2_packet_$(CONFIG_L2_PACKET).o
 
 ifeq ($(CONFIG_L2_PACKET), pcap)
 ifdef CONFIG_WINPCAP
@@ -920,7 +920,40 @@
 OBJS_t := $(OBJS) eapol_test.o ../src/radius/radius.o ../src/radius/radius_client.o
 OBJS_t += ../src/utils/ip_addr.o
 OBJS_t2 := $(OBJS) preauth_test.o
-OBJS += $(CONFIG_MAIN).o ../src/drivers/drivers.o $(OBJS_d)
+OBJS += $(CONFIG_MAIN).o
+
+ifdef CONFIG_PRIVSEP
+OBJS_priv += $(OBJS_d) ../src/drivers/drivers.o
+OBJS_priv += $(OBJS_l2)
+OBJS_priv += ../src/utils/os_$(CONFIG_OS).o
+OBJS_priv += ../src/utils/$(CONFIG_ELOOP).o
+OBJS_priv += ../src/utils/common.o
+OBJS_priv += ../src/utils/wpa_debug.o
+OBJS_priv += wpa_priv.o
+ifdef CONFIG_DRIVER_TEST
+OBJS_priv += ../src/crypto/sha1.o
+OBJS_priv += ../src/crypto/md5.o
+ifeq ($(CONFIG_TLS), openssl)
+OBJS_priv += ../src/crypto/crypto_openssl.o
+endif
+ifeq ($(CONFIG_TLS), gnutls)
+OBJS_priv += ../src/crypto/crypto_gnutls.o
+endif
+ifeq ($(CONFIG_TLS), internal)
+ifeq ($(CONFIG_CRYPTO), libtomcrypt)
+OBJS_priv += ../src/crypto/crypto_libtomcrypt.o
+else
+OBJS_priv += ../src/crypto/crypto_internal.o
+endif
+endif
+endif # CONFIG_DRIVER_TEST
+OBJS += ../src/l2_packet/l2_packet_privsep.o
+OBJS += ../src/drivers/driver_privsep.o
+EXTRA_progs += wpa_priv
+else
+OBJS += $(OBJS_d) ../src/drivers/drivers.o
+OBJS += $(OBJS_l2)
+endif
 
 ifdef CONFIG_NDIS_EVENTS_INTEGRATED
 CFLAGS += -DCONFIG_NDIS_EVENTS_INTEGRATED
@@ -939,7 +972,10 @@
 
 dynamic_eap_methods: $(EAPDYN)
 
-wpa_supplicant: .config $(OBJS)
+wpa_priv: $(OBJS_priv)
+	$(LDO) $(LDFLAGS) -o wpa_priv $(OBJS_priv) $(LIBS)
+
+wpa_supplicant: .config $(OBJS) $(EXTRA_progs)
 	$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
 
 eapol_test: .config $(OBJS_t)

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/README
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/README?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/README (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/README Wed Dec 26 23:42:18 2007
@@ -971,3 +971,58 @@
 
 # Remove network interface
 wpa_cli -g/var/run/wpa_supplicant-global interface_remove wlan0
+
+
+Privilege separation
+--------------------
+
+To minimize the size of code that needs to be run with root privileges
+(e.g., to control wireless interface operation), wpa_supplicant
+supports optional privilege separation. If enabled, this separates the
+privileged operations into a separate process (wpa_priv) while leaving
+rest of the code (e.g., EAP authentication and WPA handshakes) into an
+unprivileged process (wpa_supplicant) that can be run as non-root
+user. Privilege separation restricts the effects of potential software
+errors by containing the majority of the code in an unprivileged
+process to avoid full system compromise.
+
+Privilege separation is not enabled by default and it can be enabled
+by adding CONFIG_PRIVSEP=y to the build configuration (.config). When
+enabled, the privileged operations (driver wrapper and l2_packet) are
+linked into a separate daemon program, wpa_priv. The unprivileged
+program, wpa_supplicant, will be built with a special driver/l2_packet
+wrappers that communicate with the privileged wpa_priv process to
+perform the needed operations. wpa_priv can control what privileged
+are allowed.
+
+wpa_priv needs to be run with network admin privileges (usually, root
+user). It opens a UNIX domain socket for each interface that is
+included on the command line; any other interface will be off limits
+for wpa_supplicant in this kind of configuration. After this,
+wpa_supplicant can be run as a non-root user (e.g., all standard users
+on a laptop or as a special non-privileged user account created just
+for this purpose to limit access to user files even further).
+
+
+Example configuration:
+- create user group for users that are allowed to use wpa_supplicant
+  ('wpapriv' in this example) and assign users that should be able to
+  use wpa_supplicant into that group
+- create /var/run/wpa_priv directory for UNIX domain sockets and control
+  user access by setting it accessible only for the wpapriv group:
+  mkdir /var/run/wpa_priv
+  chown root:wpapriv /var/run/wpa_priv
+  chmod 0750 /var/run/wpa_priv
+- start wpa_priv as root (e.g., from system startup scripts) with the
+  enabled interfaces configured on the command line:
+  wpa_priv -B -P /var/run/wpa_priv.pid wext:ath0
+- run wpa_supplicant as non-root with a user that is in wpapriv group:
+  wpa_supplicant -i ath0 -c wpa_supplicant.conf
+
+wpa_priv does not use the network interface before wpa_supplicant is
+started, so it is fine to include network interfaces that are not
+available at the time wpa_priv is started. As an alternative, wpa_priv
+can be started when an interface is added (hotplug/udev/etc. scripts).
+wpa_priv can control multiple interface with one process, but it is
+also possible to run multiple wpa_priv processes at the same time, if
+desired.

Added: wpasupplicant/branches/upstream/current/wpa_supplicant/dbus-wpa_supplicant.service
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/dbus-wpa_supplicant.service?rev=950&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/dbus-wpa_supplicant.service (added)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/dbus-wpa_supplicant.service Wed Dec 26 23:42:18 2007
@@ -1,0 +1,4 @@
+[D-BUS Service]
+Name=fi.epitest.hostap.WPASupplicant
+Exec=/sbin/wpa_supplicant -u
+User=root

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/defconfig
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/defconfig?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/defconfig (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/defconfig Wed Dec 26 23:42:18 2007
@@ -357,3 +357,6 @@
 
 # Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
 #CONFIG_DEBUG_FILE=y
+
+# Enable privilege separation (see README 'Privilege separation' for details)
+#CONFIG_PRIVSEP=y

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/Makefile
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/Makefile?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/Makefile (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/Makefile Wed Dec 26 23:42:18 2007
@@ -2,6 +2,7 @@
 
 FILES += wpa_background
 FILES += wpa_cli
+FILES += wpa_gui
 FILES += wpa_passphrase
 FILES += wpa_supplicant.conf
 FILES += wpa_supplicant
@@ -18,7 +19,7 @@
 
 
 clean:
-	rm -f wpa_background.8 wpa_cli.8 wpa_passphrase.8 wpa_supplicant.8
+	rm -f wpa_background.8 wpa_cli.8 wpa_gui.8 wpa_passphrase.8 wpa_supplicant.8
 	rm -f wpa_supplicant.conf.5
 	rm -f manpage.links manpage.refs
 	rm -f $(FILES:%=%.pdf)

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_cli.sgml
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_cli.sgml?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_cli.sgml (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_cli.sgml Wed Dec 26 23:42:18 2007
@@ -44,7 +44,7 @@
     response.</para>
 
     <para>The control interface of wpa_supplicant can be configured to
-    allow non-root user access (ctrl_interface_group in the
+    allow non-root user access (ctrl_interface GROUP= parameter in the
     configuration file). This makes it possible to run wpa_cli with a
     normal user account.</para>
 

Added: wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_gui.sgml
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_gui.sgml?rev=950&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_gui.sgml (added)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_gui.sgml Wed Dec 26 23:42:18 2007
@@ -1,0 +1,76 @@
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+
+<refentry>
+  <refmeta>
+    <refentrytitle>wpa_gui</refentrytitle>
+    <manvolnum>8</manvolnum>
+  </refmeta>
+  <refnamediv>
+    <refname>wpa_gui</refname>
+
+    <refpurpose>WPA Graphical User Interface</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>wpa_gui</command>
+      <arg>-p <replaceable>path to ctrl sockets</replaceable></arg>
+      <arg>-i <replaceable>ifname</replaceable></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Overview</title>
+
+    <para>wpa_gui is a QT graphical frontend program for interacting
+    with wpa_supplicant. It is used to query current status, change
+    configuration and request interactive user input.</para>
+
+    <para>wpa_gui supports (almost) all of the interactive status and
+    configuration features of the command line client, wpa_cli. Refer
+    to the wpa_cli manpage for a comprehensive list of the
+    interactive mode features.</para>
+  </refsect1>
+  <refsect1>
+    <title>Command Arguments</title>
+    <variablelist>
+      <varlistentry>
+	<term>-p path</term>
+
+	<listitem><para>Change the path where control sockets should
+	be found.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+	<term>-i ifname</term>
+
+        <listitem><para>Specify the interface that is being
+	configured. By default, choose the first interface found with
+	a control socket in the socket path.</para></listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry>
+	<refentrytitle>wpa_cli</refentrytitle>
+	<manvolnum>8</manvolnum>
+      </citerefentry>
+      <citerefentry>
+	<refentrytitle>wpa_supplicant</refentrytitle>
+	<manvolnum>8</manvolnum>
+      </citerefentry>
+    </para>
+  </refsect1>
+  <refsect1>
+    <title>Legal</title>
+    <para>wpa_supplicant is copyright (c) 2003-2007,
+    Jouni Malinen <email>j at w1.fi</email> and
+    contributors.
+    All Rights Reserved.</para>
+
+    <para>This program is dual-licensed under both the GPL version 2
+    and BSD license. Either license may be used at your option.</para>
+  </refsect1>
+</refentry>

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml Wed Dec 26 23:42:18 2007
@@ -46,8 +46,7 @@
 
 <blockquote><programlisting>
 # allow frontend (e.g., wpa_cli) to be used by all users in 'wheel' group
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
+ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
 #
 # home network; allow all valid ciphers
 network={
@@ -80,8 +79,7 @@
         Aegis, Interlink RAD-Series)</para>
 
 <blockquote><programlisting>
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
+ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
 network={
 	ssid="example"
 	scan_ssid=1
@@ -103,8 +101,7 @@
 
 
 <blockquote><programlisting>
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
+ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
 network={
 	ssid="example"
 	scan_ssid=1
@@ -126,8 +123,7 @@
         authentication</para>
 
 <blockquote><programlisting>
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
+ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
 network={
 	ssid="1x-test"
 	scan_ssid=1
@@ -152,8 +148,7 @@
         use.</para>
 
 <blockquote><programlisting>
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
+ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
 network={
 	ssid="example"
 	scan_ssid=1
@@ -182,8 +177,7 @@
        'wired' interface (-Dwired on command line).</para>
 
 <blockquote><programlisting>
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
+ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
 ap_scan=0
 network={
 	key_mgmt=IEEE8021X

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.sgml?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.sgml (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.sgml Wed Dec 26 23:42:18 2007
@@ -17,6 +17,7 @@
       <arg>-c<replaceable>config file</replaceable></arg>
       <arg>-D<replaceable>driver</replaceable></arg>
       <arg>-P<replaceable>PID_file</replaceable></arg>
+      <arg>-f<replaceable>output file</replaceable></arg>
     </cmdsynopsis>
   </refsynopsisdiv>
   <refsect1>
@@ -376,9 +377,9 @@
       </varlistentry>
 
       <varlistentry>
-	<term>-f</term>
-	<listitem>
-	  <para>Log output to default log location (normally /tmp).</para>
+	<term>-f output file</term>
+	<listitem>
+	  <para>Log output to specified file instead of stdout.</para>
 	</listitem>
       </varlistentry>
 

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/main.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/main.c?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/main.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/main.c Wed Dec 26 23:42:18 2007
@@ -39,11 +39,12 @@
 	int i;
 	printf("%s\n\n%s\n"
 	       "usage:\n"
-	       "  wpa_supplicant [-BddfhKLqqtuvwW] [-P<pid file>] "
+	       "  wpa_supplicant [-BddhKLqqtuvwW] [-P<pid file>] "
 	       "[-g<global ctrl>] \\\n"
 	       "        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
 	       "[-p<driver_param>] \\\n"
-	       "        [-b<br_ifname> [-N -i<ifname> -c<conf> [-C<ctrl>] "
+	       "        [-b<br_ifname>] [-f<debug file>] \\\n"
+	       "        [-N -i<ifname> -c<conf> [-C<ctrl>] "
 	       "[-D<driver>] \\\n"
 	       "        [-p<driver_param>] [-b<br_ifname>] ...]\n"
 	       "\n"
@@ -66,7 +67,7 @@
 	       "  -d = increase debugging verbosity (-dd even more)\n"
 	       "  -D = driver name\n"
 #ifdef CONFIG_DEBUG_FILE
-	       "  -f = Log output to default log location (normally /tmp)\n"
+	       "  -f = log output to debug file instead of stdout\n"
 #endif /* CONFIG_DEBUG_FILE */
 	       "  -g = global ctrl_interface\n"
 	       "  -K = include keys (passwords, etc.) in debug output\n"
@@ -146,7 +147,7 @@
 	wpa_supplicant_fd_workaround();
 
 	for (;;) {
-		c = getopt(argc, argv, "b:Bc:C:D:dfg:hi:KLNp:P:qtuvwW");
+		c = getopt(argc, argv, "b:Bc:C:D:df:g:hi:KLNp:P:qtuvwW");
 		if (c < 0)
 			break;
 		switch (c) {
@@ -177,7 +178,7 @@
 #endif /* CONFIG_NO_STDOUT_DEBUG */
 #ifdef CONFIG_DEBUG_FILE
 		case 'f':
-			params.wpa_debug_use_file = 1;
+			params.wpa_debug_file_path = optarg;
 			break;
 #endif /* CONFIG_DEBUG_FILE */
 		case 'g':

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/main_winmain.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/main_winmain.c?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/main_winmain.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/main_winmain.c Wed Dec 26 23:42:18 2007
@@ -38,7 +38,7 @@
 
 	os_memset(&params, 0, sizeof(params));
 	params.wpa_debug_level = MSG_MSGDUMP;
-	params.wpa_debug_use_file = 1;
+	params.wpa_debug_file_path = "\\Temp\\wpa_supplicant-log.txt";
 	params.wpa_debug_show_keys = 1;
 
 	iface = ifaces = os_zalloc(sizeof(struct wpa_interface));

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/main_winsvc.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/main_winsvc.c?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/main_winsvc.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/main_winsvc.c Wed Dec 26 23:42:18 2007
@@ -164,8 +164,8 @@
 	buflen = sizeof(val);
 	ret = RegQueryValueEx(hk, TEXT("debug_use_file"), NULL, NULL,
 			      (LPBYTE) &val, &buflen);
-	if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
-		params.wpa_debug_use_file = val;
+	if (ret == ERROR_SUCCESS && buflen == sizeof(val) && val) {
+		params.wpa_debug_file_path = "\\Temp\\wpa_supplicant-log.txt";
 	}
 
 	exitcode = 0;

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/todo.txt
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/todo.txt?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/todo.txt (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/todo.txt Wed Dec 26 23:42:18 2007
@@ -4,13 +4,6 @@
   Firmware did not notice the current AP disappearing..
 - add support for WPA with ap_scan=0 (update selected cipher etc. based on
   AssocInfo; make sure these match with configuration)
-- optional security separation (build time option): run EAPOL state machines
-  as non-root (need to add something like socketpair between privileged root
-  process and non-root handler; send EAPOL packets between processes
-  and send keying data from non-root -> privileged)
-  EAPOL-Key processing (WPA & WEP keys) could be in privileged part
-  at least in the beginning; some parts might end up being moved to
-  non-root part eventually
 - consider closing smart card / PCSC connection when EAP-SIM/EAP-AKA
   authentication has been completed (cache scard data based on serial#(?)
   and try to optimize next connection if the same card is present for next

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp Wed Dec 26 23:42:18 2007
@@ -162,7 +162,7 @@
 
 	setNetworkParam(id, "ssid", ssidEdit->text().ascii(), true);
 
-	char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
+	const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
 	switch (auth) {
 	case AUTH_NONE:
 		key_mgmt = "NONE";

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui/networkconfig.ui.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui/networkconfig.ui.h?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui/networkconfig.ui.h (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui/networkconfig.ui.h Wed Dec 26 23:42:18 2007
@@ -131,7 +131,7 @@
 
     setNetworkParam(id, "ssid", ssidEdit->text().ascii(), true);
     
-    char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
+    const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
     switch (auth) {
     case AUTH_NONE:
 	key_mgmt = "NONE";

Added: wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_priv.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_priv.c?rev=950&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_priv.c (added)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_priv.c Wed Dec 26 23:42:18 2007
@@ -1,0 +1,1021 @@
+/*
+ * WPA Supplicant / privileged helper program
+ * Copyright (c) 2007, Jouni Malinen <j at w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+#ifdef __linux__
+#include <fcntl.h>
+#endif /* __linux__ */
+#include <sys/un.h>
+#include <sys/stat.h>
+
+#include "common.h"
+#include "eloop.h"
+#include "version.h"
+#include "drivers/driver.h"
+#include "l2_packet/l2_packet.h"
+#include "privsep_commands.h"
+
+#ifndef ETH_P_EAPOL
+#define ETH_P_EAPOL 0x888e
+#endif
+
+#ifndef ETH_P_RSN_PREAUTH
+#define ETH_P_RSN_PREAUTH 0x88c7
+#endif
+
+
+struct wpa_priv_interface {
+	struct wpa_priv_interface *next;
+	char *driver_name;
+	char *ifname;
+	char *sock_name;
+	int fd;
+
+	struct wpa_driver_ops *driver;
+	void *drv_priv;
+	struct sockaddr_un drv_addr;
+	int wpas_registered;
+
+	/* TODO: add support for multiple l2 connections */
+	struct l2_packet_data *l2;
+	struct sockaddr_un l2_addr;
+};
+
+
+static void wpa_priv_cmd_register(struct wpa_priv_interface *iface,
+				  struct sockaddr_un *from)
+{
+	if (iface->drv_priv) {
+		wpa_printf(MSG_DEBUG, "Cleaning up forgotten driver instance");
+		if (iface->driver->set_wpa)
+			iface->driver->set_wpa(iface->drv_priv, 0);
+		if (iface->driver->deinit)
+			iface->driver->deinit(iface->drv_priv);
+		iface->drv_priv = NULL;
+		iface->wpas_registered = 0;
+	}
+
+	if (iface->l2) {
+		wpa_printf(MSG_DEBUG, "Cleaning up forgotten l2_packet "
+			   "instance");
+		l2_packet_deinit(iface->l2);
+		iface->l2 = NULL;
+	}
+
+	if (iface->driver->init == NULL)
+		return;
+
+	iface->drv_priv = iface->driver->init(iface, iface->ifname);
+	if (iface->drv_priv == NULL) {
+		wpa_printf(MSG_DEBUG, "Failed to initialize driver wrapper");
+		return;
+	}
+
+	wpa_printf(MSG_DEBUG, "Driver wrapper '%s' initialized for interface "
+		   "'%s'", iface->driver_name, iface->ifname);
+
+	os_memcpy(&iface->drv_addr, from, sizeof(iface->drv_addr));
+	iface->wpas_registered = 1;
+
+	if (iface->driver->set_param &&
+	    iface->driver->set_param(iface->drv_priv, NULL) < 0) {
+		wpa_printf(MSG_ERROR, "Driver interface rejected param");
+	}
+
+	if (iface->driver->set_wpa)
+		iface->driver->set_wpa(iface->drv_priv, 1);
+}
+
+
+static void wpa_priv_cmd_unregister(struct wpa_priv_interface *iface,
+				    struct sockaddr_un *from)
+{
+	if (iface->drv_priv) {
+		if (iface->driver->set_wpa)
+			iface->driver->set_wpa(iface->drv_priv, 0);
+		if (iface->driver->deinit)
+			iface->driver->deinit(iface->drv_priv);
+		iface->drv_priv = NULL;
+		iface->wpas_registered = 0;
+	}
+}
+
+
+static void wpa_priv_cmd_set_wpa(struct wpa_priv_interface *iface,
+				 char *buf, size_t len)
+{
+	if (iface->drv_priv == NULL || len != sizeof(int))
+		return;
+
+	if (iface->driver->set_wpa)
+		iface->driver->set_wpa(iface->drv_priv, *((int *) buf));
+}
+
+
+static void wpa_priv_cmd_scan(struct wpa_priv_interface *iface,
+			      char *buf, size_t len)
+{
+	if (iface->drv_priv == NULL)
+		return;
+
+	if (iface->driver->scan)
+		iface->driver->scan(iface->drv_priv, len ? (u8 *) buf : NULL,
+				    len);
+}
+
+
+static void wpa_priv_cmd_get_scan_results(struct wpa_priv_interface *iface,
+					  struct sockaddr_un *from,
+					  char *buf, size_t len)
+{
+#define SCAN_AP_LIMIT 128
+	int max_results, res;
+	struct wpa_scan_result *results;
+
+	if (iface->drv_priv == NULL)
+		goto fail;
+
+	if (iface->driver->get_scan_results == NULL || len != sizeof(int))
+		goto fail;
+
+	os_memcpy(&max_results, buf, sizeof(int));
+	if (max_results < 0)
+		goto fail;
+	if (max_results > SCAN_AP_LIMIT)
+		max_results = SCAN_AP_LIMIT;
+
+	results = os_malloc(max_results * sizeof(*results));
+	if (results == NULL)
+		goto fail;
+
+	res = iface->driver->get_scan_results(iface->drv_priv, results,
+					      max_results);
+	if (res < 0 || res > max_results) {
+		os_free(results);
+		goto fail;
+	}
+
+	sendto(iface->fd, results, res * sizeof(*results), 0,
+	       (struct sockaddr *) from, sizeof(*from));
+
+	os_free(results);
+	return;
+
+fail:
+	sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from));
+}
+
+
+static void wpa_priv_cmd_associate(struct wpa_priv_interface *iface,
+				   void *buf, size_t len)
+{
+	struct wpa_driver_associate_params params;
+	struct privsep_cmd_associate *assoc;
+	u8 *bssid;
+	int res;
+
+	if (iface->drv_priv == NULL || iface->driver->associate == NULL)
+		return;
+
+	if (len < sizeof(*assoc)) {
+		wpa_printf(MSG_DEBUG, "Invalid association request");
+		return;
+	}
+
+	assoc = buf;
+	if (sizeof(*assoc) + assoc->wpa_ie_len > len) {
+		wpa_printf(MSG_DEBUG, "Association request overflow");
+		return;
+	}
+
+	os_memset(&params, 0, sizeof(params));
+	bssid = assoc->bssid;
+	if (bssid[0] | bssid[1] | bssid[2] | bssid[3] | bssid[4] | bssid[5])
+		params.bssid = bssid;
+	params.ssid = assoc->ssid;
+	if (assoc->ssid_len > 32)
+		return;
+	params.ssid_len = assoc->ssid_len;
+	params.freq = assoc->freq;
+	if (assoc->wpa_ie_len) {
+		params.wpa_ie = (u8 *) (assoc + 1);
+		params.wpa_ie_len = assoc->wpa_ie_len;
+	}
+	params.pairwise_suite = assoc->pairwise_suite;
+	params.group_suite = assoc->group_suite;
+	params.key_mgmt_suite = assoc->key_mgmt_suite;
+	params.auth_alg = assoc->auth_alg;
+	params.mode = assoc->mode;
+
+	res = iface->driver->associate(iface->drv_priv, &params);
+	wpa_printf(MSG_DEBUG, "drv->associate: res=%d", res);
+}
+
+
+static void wpa_priv_cmd_get_bssid(struct wpa_priv_interface *iface,
+				   struct sockaddr_un *from)
+{
+	u8 bssid[ETH_ALEN];
+
+	if (iface->drv_priv == NULL)
+		goto fail;
+
+	if (iface->driver->get_bssid == NULL ||
+	    iface->driver->get_bssid(iface->drv_priv, bssid) < 0)
+		goto fail;
+
+	sendto(iface->fd, bssid, ETH_ALEN, 0, (struct sockaddr *) from,
+	       sizeof(*from));
+	return;
+
+fail:
+	sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from));
+}
+
+
+static void wpa_priv_cmd_get_ssid(struct wpa_priv_interface *iface,
+				  struct sockaddr_un *from)
+{
+	u8 ssid[sizeof(int) + 32];
+	int res;
+
+	if (iface->drv_priv == NULL)
+		goto fail;
+
+	if (iface->driver->get_ssid == NULL)
+		goto fail;
+
+	res = iface->driver->get_ssid(iface->drv_priv, &ssid[sizeof(int)]);
+	if (res < 0 || res > 32)
+		goto fail;
+	os_memcpy(ssid, &res, sizeof(int));
+
+	sendto(iface->fd, ssid, sizeof(ssid), 0, (struct sockaddr *) from,
+	       sizeof(*from));
+	return;
+
+fail:
+	sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from));
+}
+
+
+static void wpa_priv_cmd_set_key(struct wpa_priv_interface *iface,
+				 void *buf, size_t len)
+{
+	struct privsep_cmd_set_key *params;
+	int res;
+
+	if (iface->drv_priv == NULL || iface->driver->set_key == NULL)
+		return;
+
+	if (len != sizeof(*params)) {
+		wpa_printf(MSG_DEBUG, "Invalid set_key request");
+		return;
+	}
+
+	params = buf;
+
+	res = iface->driver->set_key(iface->drv_priv, params->alg,
+				     params->addr, params->key_idx,
+				     params->set_tx,
+				     params->seq_len ? params->seq : NULL,
+				     params->seq_len,
+				     params->key_len ? params->key : NULL,
+				     params->key_len);
+	wpa_printf(MSG_DEBUG, "drv->set_key: res=%d", res);
+}
+
+
+static void wpa_priv_cmd_get_capa(struct wpa_priv_interface *iface,
+				  struct sockaddr_un *from)
+{
+	struct wpa_driver_capa capa;
+
+	if (iface->drv_priv == NULL)
+		goto fail;
+
+	if (iface->driver->get_capa == NULL ||
+	    iface->driver->get_capa(iface->drv_priv, &capa) < 0)
+		goto fail;
+
+	sendto(iface->fd, &capa, sizeof(capa), 0, (struct sockaddr *) from,
+	       sizeof(*from));
+	return;
+
+fail:
+	sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from));
+}
+
+
+static void wpa_priv_l2_rx(void *ctx, const u8 *src_addr, const u8 *buf,
+			   size_t len)
+{
+	struct wpa_priv_interface *iface = ctx;
+	struct msghdr msg;
+	struct iovec io[2];
+
+	io[0].iov_base = (u8 *) src_addr;
+	io[0].iov_len = ETH_ALEN;
+	io[1].iov_base = (u8 *) buf;
+	io[1].iov_len = len;
+
+	os_memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = io;
+	msg.msg_iovlen = 2;
+	msg.msg_name = &iface->l2_addr;
+	msg.msg_namelen = sizeof(iface->l2_addr);
+
+	if (sendmsg(iface->fd, &msg, 0) < 0) {
+		perror("sendmsg(l2 rx)");
+	}
+}
+
+
+static void wpa_priv_cmd_l2_register(struct wpa_priv_interface *iface,
+				     struct sockaddr_un *from,
+				     void *buf, size_t len)
+{
+	int *reg_cmd = buf;
+	u8 own_addr[ETH_ALEN];
+	int res;
+	u16 proto;
+
+	if (len != 2 * sizeof(int)) {
+		wpa_printf(MSG_DEBUG, "Invalid l2_register length %lu",
+			   (unsigned long) len);
+		return;
+	}
+
+	proto = reg_cmd[0];
+	if (proto != ETH_P_EAPOL && proto != ETH_P_RSN_PREAUTH) {
+		wpa_printf(MSG_DEBUG, "Refused l2_packet connection for "
+			   "ethertype 0x%x", proto);
+		return;
+	}
+
+	if (iface->l2) {
+		wpa_printf(MSG_DEBUG, "Cleaning up forgotten l2_packet "
+			   "instance");
+		l2_packet_deinit(iface->l2);
+		iface->l2 = NULL;
+	}
+
+	os_memcpy(&iface->l2_addr, from, sizeof(iface->l2_addr));
+
+	iface->l2 = l2_packet_init(iface->ifname, NULL, proto,
+				   wpa_priv_l2_rx, iface, reg_cmd[1]);
+	if (iface->l2 == NULL) {
+		wpa_printf(MSG_DEBUG, "Failed to initialize l2_packet "
+			   "instance for protocol %d", proto);
+		return;
+	}
+
+	if (l2_packet_get_own_addr(iface->l2, own_addr) < 0) {
+		wpa_printf(MSG_DEBUG, "Failed to get own address from "
+			   "l2_packet");
+		l2_packet_deinit(iface->l2);
+		iface->l2 = NULL;
+		return;
+	}
+
+	res = sendto(iface->fd, own_addr, ETH_ALEN, 0,
+		     (struct sockaddr *) from, sizeof(*from));
+	wpa_printf(MSG_DEBUG, "L2 registration: res=%d", res);
+}
+
+
+static void wpa_priv_cmd_l2_unregister(struct wpa_priv_interface *iface,
+				       struct sockaddr_un *from)
+{
+	if (iface->l2) {
+		l2_packet_deinit(iface->l2);
+		iface->l2 = NULL;
+	}
+}
+
+
+static void wpa_priv_cmd_l2_notify_auth_start(struct wpa_priv_interface *iface,
+					      struct sockaddr_un *from)
+{
+	if (iface->l2)
+		l2_packet_notify_auth_start(iface->l2);
+}
+
+
+static void wpa_priv_cmd_l2_send(struct wpa_priv_interface *iface,
+				 struct sockaddr_un *from,
+				 void *buf, size_t len)
+{
+	u8 *dst_addr;
+	u16 proto;
+	int res;
+
+	if (iface->l2 == NULL)
+		return;
+
+	if (len < ETH_ALEN + 2) {
+		wpa_printf(MSG_DEBUG, "Too short L2 send packet (len=%lu)",
+			   (unsigned long) len);
+		return;
+	}
+
+	dst_addr = buf;
+	os_memcpy(&proto, buf + ETH_ALEN, 2);
+
+	if (proto != ETH_P_EAPOL && proto != ETH_P_RSN_PREAUTH) {
+		wpa_printf(MSG_DEBUG, "Refused l2_packet send for ethertype "
+			   "0x%x", proto);
+		return;
+	}
+
+	res = l2_packet_send(iface->l2, dst_addr, proto, buf + ETH_ALEN + 2,
+			     len - ETH_ALEN - 2);
+	wpa_printf(MSG_DEBUG, "L2 send: res=%d", res);
+}
+
+
+static void wpa_priv_receive(int sock, void *eloop_ctx, void *sock_ctx)
+{
+	struct wpa_priv_interface *iface = eloop_ctx;
+	char buf[2000];
+	void *cmd_buf;
+	size_t cmd_len;
+	int res, cmd;
+	struct sockaddr_un from;
+	socklen_t fromlen = sizeof(from);
+
+	res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &from,
+		       &fromlen);
+	if (res < 0) {
+		perror("recvfrom");
+		return;
+	}
+
+	if (res < (int) sizeof(int)) {
+		wpa_printf(MSG_DEBUG, "Too short command (len=%d)", res);
+		return;
+	}
+
+	os_memcpy(&cmd, buf, sizeof(int));
+	wpa_printf(MSG_DEBUG, "Command %d for interface %s",
+		   cmd, iface->ifname);
+	cmd_buf = &buf[sizeof(int)];
+	cmd_len = res - sizeof(int);
+
+	switch (cmd) {
+	case PRIVSEP_CMD_REGISTER:
+		wpa_priv_cmd_register(iface, &from);
+		break;
+	case PRIVSEP_CMD_UNREGISTER:
+		wpa_priv_cmd_unregister(iface, &from);
+		break;
+	case PRIVSEP_CMD_SET_WPA:
+		wpa_priv_cmd_set_wpa(iface, cmd_buf, cmd_len);
+		break;
+	case PRIVSEP_CMD_SCAN:
+		wpa_priv_cmd_scan(iface, cmd_buf, cmd_len);
+		break;
+	case PRIVSEP_CMD_GET_SCAN_RESULTS:
+		wpa_priv_cmd_get_scan_results(iface, &from, cmd_buf, cmd_len);
+		break;
+	case PRIVSEP_CMD_ASSOCIATE:
+		wpa_priv_cmd_associate(iface, cmd_buf, cmd_len);
+		break;
+	case PRIVSEP_CMD_GET_BSSID:
+		wpa_priv_cmd_get_bssid(iface, &from);
+		break;
+	case PRIVSEP_CMD_GET_SSID:
+		wpa_priv_cmd_get_ssid(iface, &from);
+		break;
+	case PRIVSEP_CMD_SET_KEY:
+		wpa_priv_cmd_set_key(iface, cmd_buf, cmd_len);
+		break;
+	case PRIVSEP_CMD_GET_CAPA:
+		wpa_priv_cmd_get_capa(iface, &from);
+		break;
+	case PRIVSEP_CMD_L2_REGISTER:
+		wpa_priv_cmd_l2_register(iface, &from, cmd_buf, cmd_len);
+		break;
+	case PRIVSEP_CMD_L2_UNREGISTER:
+		wpa_priv_cmd_l2_unregister(iface, &from);
+		break;
+	case PRIVSEP_CMD_L2_NOTIFY_AUTH_START:
+		wpa_priv_cmd_l2_notify_auth_start(iface, &from);
+		break;
+	case PRIVSEP_CMD_L2_SEND:
+		wpa_priv_cmd_l2_send(iface, &from, cmd_buf, cmd_len);
+		break;
+	}
+}
+
+
+static void wpa_priv_interface_deinit(struct wpa_priv_interface *iface)
+{
+	if (iface->drv_priv && iface->driver->deinit)
+		iface->driver->deinit(iface->drv_priv);
+
+	if (iface->fd >= 0) {
+		eloop_unregister_read_sock(iface->fd);
+		close(iface->fd);
+		unlink(iface->sock_name);
+	}
+
+	if (iface->l2)
+		l2_packet_deinit(iface->l2);
+
+	os_free(iface->ifname);
+	os_free(iface->driver_name);
+	os_free(iface->sock_name);
+	os_free(iface);
+}
+
+
+extern struct wpa_driver_ops *wpa_supplicant_drivers[];
+
+static struct wpa_priv_interface *
+wpa_priv_interface_init(const char *dir, const char *params)
+{
+	struct wpa_priv_interface *iface;
+	char *pos;
+	size_t len;
+	struct sockaddr_un addr;
+	int i;
+
+	pos = os_strchr(params, ':');
+	if (pos == NULL)
+		return NULL;
+
+	iface = os_zalloc(sizeof(*iface));
+	if (iface == NULL)
+		return NULL;
+	iface->fd = -1;
+
+	len = pos - params;
+	iface->driver_name = os_malloc(len + 1);
+	if (iface->driver_name == NULL) {
+		wpa_priv_interface_deinit(iface);
+		return NULL;
+	}
+	os_memcpy(iface->driver_name, params, len);
+	iface->driver_name[len] = '\0';
+
+	for (i = 0; wpa_supplicant_drivers[i]; i++) {
+		if (os_strcmp(iface->driver_name,
+			      wpa_supplicant_drivers[i]->name) == 0) {
+			iface->driver = wpa_supplicant_drivers[i];
+			break;
+		}
+	}
+	if (iface->driver == NULL) {
+		wpa_printf(MSG_ERROR, "Unsupported driver '%s'",
+			   iface->driver_name);
+		wpa_priv_interface_deinit(iface);
+		return NULL;
+	}
+
+	pos++;
+	iface->ifname = os_strdup(pos);
+	if (iface->ifname == NULL) {
+		wpa_priv_interface_deinit(iface);
+		return NULL;
+	}
+
+	len = os_strlen(dir) + 1 + os_strlen(iface->ifname);
+	iface->sock_name = os_malloc(len + 1);
+	if (iface->sock_name == NULL) {
+		wpa_priv_interface_deinit(iface);
+		return NULL;
+	}
+
+	os_snprintf(iface->sock_name, len + 1, "%s/%s", dir, iface->ifname);
+	if (os_strlen(iface->sock_name) >= sizeof(addr.sun_path)) {
+		wpa_priv_interface_deinit(iface);
+		return NULL;
+	}
+
+	iface->fd = socket(PF_UNIX, SOCK_DGRAM, 0);
+	if (iface->fd < 0) {
+		perror("socket(PF_UNIX)");
+		wpa_priv_interface_deinit(iface);
+		return NULL;
+	}
+
+	os_memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	os_strlcpy(addr.sun_path, iface->sock_name, sizeof(addr.sun_path));
+
+	if (bind(iface->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		wpa_printf(MSG_DEBUG, "bind(PF_UNIX) failed: %s",
+			   strerror(errno));
+		if (connect(iface->fd, (struct sockaddr *) &addr,
+			    sizeof(addr)) < 0) {
+			wpa_printf(MSG_DEBUG, "Socket exists, but does not "
+				   "allow connections - assuming it was "
+				   "leftover from forced program termination");
+			if (unlink(iface->sock_name) < 0) {
+				perror("unlink[ctrl_iface]");
+				wpa_printf(MSG_ERROR, "Could not unlink "
+					   "existing ctrl_iface socket '%s'",
+					   iface->sock_name);
+				goto fail;
+			}
+			if (bind(iface->fd, (struct sockaddr *) &addr,
+				 sizeof(addr)) < 0) {
+				perror("bind(PF_UNIX)");
+				goto fail;
+			}
+			wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
+				   "socket '%s'", iface->sock_name);
+		} else {
+			wpa_printf(MSG_INFO, "Socket exists and seems to be "
+				   "in use - cannot override it");
+			wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
+				   "not used anymore", iface->sock_name);
+			goto fail;
+		}
+	}
+
+	if (chmod(iface->sock_name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
+		perror("chmod");
+		goto fail;
+	}
+
+	eloop_register_read_sock(iface->fd, wpa_priv_receive, iface, NULL);
+
+	return iface;
+
+fail:
+	wpa_priv_interface_deinit(iface);
+	return NULL;
+}
+
+
+static int wpa_priv_send_event(struct wpa_priv_interface *iface, int event,
+			       const void *data, size_t data_len)
+{
+	struct msghdr msg;
+	struct iovec io[2];
+
+	io[0].iov_base = &event;
+	io[0].iov_len = sizeof(event);
+	io[1].iov_base = (u8 *) data;
+	io[1].iov_len = data_len;
+
+	os_memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = io;
+	msg.msg_iovlen = data ? 2 : 1;
+	msg.msg_name = &iface->drv_addr;
+	msg.msg_namelen = sizeof(iface->drv_addr);
+
+	if (sendmsg(iface->fd, &msg, 0) < 0) {
+		perror("sendmsg(wpas_socket)");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static void wpa_priv_send_assoc(struct wpa_priv_interface *iface, int event,
+				union wpa_event_data *data)
+{
+	size_t buflen = 3 * sizeof(int);
+	u8 *buf, *pos;
+	int len;
+
+	if (data) {
+		buflen += data->assoc_info.req_ies_len +
+			data->assoc_info.resp_ies_len +
+			data->assoc_info.beacon_ies_len;
+	}
+
+	buf = os_malloc(buflen);
+	if (buf == NULL)
+		return;
+
+	pos = buf;
+
+	if (data && data->assoc_info.req_ies) {
+		len = data->assoc_info.req_ies_len;
+		os_memcpy(pos, &len, sizeof(int));
+		pos += sizeof(int);
+		os_memcpy(pos, data->assoc_info.req_ies, len);
+		pos += len;
+	} else {
+		len = 0;
+		os_memcpy(pos, &len, sizeof(int));
+		pos += sizeof(int);
+	}
+
+	if (data && data->assoc_info.resp_ies) {
+		len = data->assoc_info.resp_ies_len;
+		os_memcpy(pos, &len, sizeof(int));
+		pos += sizeof(int);
+		os_memcpy(pos, data->assoc_info.resp_ies, len);
+		pos += len;
+	} else {
+		len = 0;
+		os_memcpy(pos, &len, sizeof(int));
+		pos += sizeof(int);
+	}
+
+	if (data && data->assoc_info.beacon_ies) {
+		len = data->assoc_info.beacon_ies_len;
+		os_memcpy(pos, &len, sizeof(int));
+		pos += sizeof(int);
+		os_memcpy(pos, data->assoc_info.beacon_ies, len);
+		pos += len;
+	} else {
+		len = 0;
+		os_memcpy(pos, &len, sizeof(int));
+		pos += sizeof(int);
+	}
+
+	wpa_priv_send_event(iface, event, buf, buflen);
+
+	os_free(buf);
+}
+
+
+static void wpa_priv_send_interface_status(struct wpa_priv_interface *iface,
+					   union wpa_event_data *data)
+{
+	int ievent;
+	size_t len, maxlen;
+	u8 *buf;
+	char *ifname;
+
+	if (data == NULL)
+		return;
+
+	ievent = data->interface_status.ievent;
+	maxlen = sizeof(data->interface_status.ifname);
+	ifname = data->interface_status.ifname;
+	for (len = 0; len < maxlen && ifname[len]; len++)
+		;
+
+	buf = os_malloc(sizeof(int) + len);
+	if (buf == NULL)
+		return;
+
+	os_memcpy(buf, &ievent, sizeof(int));
+	os_memcpy(buf + sizeof(int), ifname, len);
+
+	wpa_priv_send_event(iface, PRIVSEP_EVENT_INTERFACE_STATUS,
+			    buf, sizeof(int) + len);
+
+	os_free(buf);
+
+}
+
+
+static void wpa_priv_send_ft_response(struct wpa_priv_interface *iface,
+				      union wpa_event_data *data)
+{
+	size_t len;
+	u8 *buf, *pos;
+
+	if (data == NULL || data->ft_ies.ies == NULL)
+		return;
+
+	len = sizeof(int) + ETH_ALEN + data->ft_ies.ies_len;
+	buf = os_malloc(len);
+	if (buf == NULL)
+		return;
+
+	pos = buf;
+	os_memcpy(pos, &data->ft_ies.ft_action, sizeof(int));
+	pos += sizeof(int);
+	os_memcpy(pos, data->ft_ies.target_ap, ETH_ALEN);
+	pos += ETH_ALEN;
+	os_memcpy(pos, data->ft_ies.ies, data->ft_ies.ies_len);
+
+	wpa_priv_send_event(iface, PRIVSEP_EVENT_FT_RESPONSE, buf, len);
+
+	os_free(buf);
+
+}
+
+
+void wpa_supplicant_event(void *ctx, wpa_event_type event,
+			  union wpa_event_data *data)
+{
+	struct wpa_priv_interface *iface = ctx;
+
+	wpa_printf(MSG_DEBUG, "%s - event=%d", __func__, event);
+
+	if (!iface->wpas_registered) {
+		wpa_printf(MSG_DEBUG, "Driver event received, but "
+			   "wpa_supplicant not registered");
+		return;
+	}
+
+	switch (event) {
+	case EVENT_ASSOC:
+		wpa_priv_send_assoc(iface, PRIVSEP_EVENT_ASSOC, data);
+		break;
+	case EVENT_DISASSOC:
+		wpa_priv_send_event(iface, PRIVSEP_EVENT_DISASSOC, NULL, 0);
+		break;
+	case EVENT_ASSOCINFO:
+		if (data == NULL)
+			return;
+		wpa_priv_send_assoc(iface, PRIVSEP_EVENT_ASSOCINFO, data);
+		break;
+	case EVENT_MICHAEL_MIC_FAILURE:
+		if (data == NULL)
+			return;
+		wpa_priv_send_event(iface, PRIVSEP_EVENT_MICHAEL_MIC_FAILURE,
+				    &data->michael_mic_failure.unicast,
+				    sizeof(int));
+		break;
+	case EVENT_SCAN_RESULTS:
+		wpa_priv_send_event(iface, PRIVSEP_EVENT_SCAN_RESULTS, NULL,
+				    0);
+		break;
+	case EVENT_INTERFACE_STATUS:
+		wpa_priv_send_interface_status(iface, data);
+		break;
+	case EVENT_PMKID_CANDIDATE:
+		if (data == NULL)
+			return;
+		wpa_priv_send_event(iface, PRIVSEP_EVENT_PMKID_CANDIDATE,
+				    &data->pmkid_candidate,
+				    sizeof(struct pmkid_candidate));
+		break;
+	case EVENT_STKSTART:
+		if (data == NULL)
+			return;
+		wpa_priv_send_event(iface, PRIVSEP_EVENT_STKSTART,
+				    &data->stkstart.peer, ETH_ALEN);
+		break;
+	case EVENT_FT_RESPONSE:
+		wpa_priv_send_ft_response(iface, data);
+		break;
+	default:
+		wpa_printf(MSG_DEBUG, "Unsupported driver event %d - TODO",
+			   event);
+		break;
+	}
+}
+
+
+void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
+			     const u8 *buf, size_t len)
+{
+	struct wpa_priv_interface *iface = ctx;
+	struct msghdr msg;
+	struct iovec io[3];
+	int event = PRIVSEP_EVENT_RX_EAPOL;
+
+	wpa_printf(MSG_DEBUG, "RX EAPOL from driver");
+	io[0].iov_base = &event;
+	io[0].iov_len = sizeof(event);
+	io[1].iov_base = (u8 *) src_addr;
+	io[1].iov_len = ETH_ALEN;
+	io[2].iov_base = (u8 *) buf;
+	io[2].iov_len = len;
+
+	os_memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = io;
+	msg.msg_iovlen = 3;
+	msg.msg_name = &iface->drv_addr;
+	msg.msg_namelen = sizeof(iface->drv_addr);
+
+	if (sendmsg(iface->fd, &msg, 0) < 0)
+		perror("sendmsg(wpas_socket)");
+}
+
+static void wpa_priv_terminate(int sig, void *eloop_ctx, void *signal_ctx)
+{
+	wpa_printf(MSG_DEBUG, "wpa_priv termination requested");
+	eloop_terminate();
+}
+
+
+static void wpa_priv_fd_workaround(void)
+{
+#ifdef __linux__
+	int s, i;
+	/* When started from pcmcia-cs scripts, wpa_supplicant might start with
+	 * fd 0, 1, and 2 closed. This will cause some issues because many
+	 * places in wpa_supplicant are still printing out to stdout. As a
+	 * workaround, make sure that fd's 0, 1, and 2 are not used for other
+	 * sockets. */
+	for (i = 0; i < 3; i++) {
+		s = open("/dev/null", O_RDWR);
+		if (s > 2) {
+			close(s);
+			break;
+		}
+	}
+#endif /* __linux__ */
+}
+
+
+static void usage(void)
+{
+	printf("wpa_priv v" VERSION_STR "\n"
+	       "Copyright (c) 2007, Jouni Malinen <j at w1.fi> and contributors\n"
+	       "\n"
+	       "usage:\n"
+	       "  wpa_priv [-Bdd] [-P<pid file>] <driver:ifname> "
+	       "[driver:ifname ...]\n");
+}
+
+
+extern int wpa_debug_level;
+
+int main(int argc, char *argv[])
+{
+	int c, i;
+	int ret = -1;
+	char *pid_file = NULL;
+	int daemonize = 0;
+	char *ctrl_dir = "/var/run/wpa_priv";
+	struct wpa_priv_interface *interfaces = NULL, *iface;
+
+	if (os_program_init())
+		return -1;
+
+	wpa_priv_fd_workaround();
+
+	for (;;) {
+		c = getopt(argc, argv, "Bc:dP:");
+		if (c < 0)
+			break;
+		switch (c) {
+		case 'B':
+			daemonize++;
+			break;
+		case 'c':
+			ctrl_dir = optarg;
+			break;
+		case 'd':
+			wpa_debug_level--;
+			break;
+		case 'P':
+			pid_file = os_rel2abs_path(optarg);
+			break;
+		default:
+			usage();
+			goto out;
+		}
+	}
+
+	if (optind >= argc) {
+		usage();
+		goto out;
+	}
+
+	wpa_printf(MSG_DEBUG, "wpa_priv control directory: '%s'", ctrl_dir);
+
+	if (eloop_init(NULL)) {
+		wpa_printf(MSG_ERROR, "Failed to initialize event loop");
+		goto out;
+	}
+
+	for (i = optind; i < argc; i++) {
+		wpa_printf(MSG_DEBUG, "Adding driver:interface %s", argv[i]);
+		iface = wpa_priv_interface_init(ctrl_dir, argv[i]);
+		if (iface == NULL)
+			goto out;
+		iface->next = interfaces;
+		interfaces = iface;
+	}
+
+	if (daemonize && os_daemonize(pid_file))
+		goto out;
+
+	eloop_register_signal_terminate(wpa_priv_terminate, NULL);
+	eloop_run();
+
+	ret = 0;
+
+out:
+	iface = interfaces;
+	while (iface) {
+		struct wpa_priv_interface *prev = iface;
+		iface = iface->next;
+		wpa_priv_interface_deinit(prev);
+	}
+
+	eloop_destroy();
+
+	os_daemonize_terminate(pid_file);
+	os_free(pid_file);
+	os_program_deinit();
+
+	return ret;
+}

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.c?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.c Wed Dec 26 23:42:18 2007
@@ -109,7 +109,6 @@
 
 extern struct wpa_driver_ops *wpa_supplicant_drivers[];
 
-extern int wpa_debug_use_file;
 extern int wpa_debug_level;
 extern int wpa_debug_show_keys;
 extern int wpa_debug_timestamp;
@@ -1827,8 +1826,7 @@
 	if (params == NULL)
 		return NULL;
 
-	wpa_debug_use_file = params->wpa_debug_use_file;
-	wpa_debug_open_file();
+	wpa_debug_open_file(params->wpa_debug_file_path);
 
 	ret = eap_peer_register_methods();
 	if (ret) {
@@ -1857,8 +1855,6 @@
 		params->wpa_debug_show_keys;
 	wpa_debug_timestamp = global->params.wpa_debug_timestamp =
 		params->wpa_debug_timestamp;
-	wpa_debug_use_file = global->params.wpa_debug_use_file =
-		params->wpa_debug_use_file;
 
 	if (eloop_init(global)) {
 		wpa_printf(MSG_ERROR, "Failed to initialize event loop");

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant_i.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant_i.h?rev=950&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant_i.h (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant_i.h Wed Dec 26 23:42:18 2007
@@ -151,9 +151,9 @@
 	int dbus_ctrl_interface;
 
 	/**
-	 * wpa_debug_use_file - Write debug to a file (instead of stdout)
-	 */
-	int wpa_debug_use_file;
+	 * wpa_debug_file_path - Path of debug file or %NULL to use stdout
+	 */
+	const char *wpa_debug_file_path;
 };
 
 /**




More information about the Pkg-wpa-devel mailing list