Re: [RFC] [PATCH] WPA PSK support for netcfg
Glenn Saberton wrote:
> Hello,
> Attached is a patch for adding support for installing over a wpa
> psk protected wifi network. Its still a work in progress, but I am
> happy enough with the basic functionality to want to push it out and
> get some feedback on what the d-i team may think in regard to
> implementation or whether its worthwhile pursuing at all. Apologies
> for some noise in the patch as I had run indent on my copy, so there
> is a bit of redundant cruft in there. A basic udeb for wpasupplicant
> is needed but the clients it supplies and various drivers could be cut
> out in the udeb if the team thinks its worthwile pursuing. Thus the
> size of the udeb could be a bit smaller than the default build for
> wpasupp (ie no eap support, no clients or dbus support) Basically, it
> writes out a supplicant config during configuration of wireless device
> and starts wpasupp with that file. This appeared to me to be the
> simplist way of getting support into netcfg. I have copied the
> killall.sh script to kill wpasupp when required, though I am not
> really happy with that and will be looking to remove that in the
> future. My attempts at using kill() or such functions weren't very
> successfull and any pointers here would be appreciated. I have also
> set debconf priority to high when configuring wireless, as otherwise
> netcfg will try and associate to a random AP and this is not really
> desirable leading to the need to reconfigure wifi and manually enter
> the essid. I would like to add a scan function to netcfg in the future
> to allow people to chose their AP from a list but I am not sure on how
> to get cdebconf to chose the selected AP. Any pointers on this would
> also be appreciated. I have only tested this on my eeepc, but I dont
> see why it wouldn't work on other chipsets. Let the comments flow and
> please CC me as I am not subscribed to the list. Patch is attached or
> you can dget foomagic.org/eeepc/netcfg/netcfg_1.43.dsc
>
> Cheers
>
> Glenn
New patch attached regarding Christian Perrier's comments. Please keep
them coming and don't forget to CC me :)
Cheers
Glenn
diff -Nurb ../netcfg-1.43/base-installer netcfg-1.43/base-installer
--- ../netcfg-1.43/base-installer 2008-01-14 10:29:16.000000000 +0900
+++ netcfg-1.43/base-installer 2008-04-18 22:14:33.000000000 +0800
@@ -1,7 +1,7 @@
#!/bin/sh -e
# Copy all relevant networking-related files to /target.
-for file in /etc/network/interfaces /etc/networks /etc/hostname /etc/resolv.conf /etc/hosts; do
+for file in /etc/network/interfaces /etc/networks /etc/hostname /etc/resolv.conf /etc/hosts /etc/wpa_supplicant/wpa_supplicant.conf; do
if [ -f "$file" ]; then
mkdir /target/$(dirname $file) -p
cp $file /target/$file
diff -Nurb ../netcfg-1.43/debian/control netcfg-1.43/debian/control
--- ../netcfg-1.43/debian/control 2008-04-08 19:40:33.000000000 +0800
+++ netcfg-1.43/debian/control 2008-04-18 22:14:33.000000000 +0800
@@ -2,7 +2,7 @@
Section: debian-installer
Priority: optional
Maintainer: Debian Install System Team <debian-boot@lists.debian.org>
-Uploaders: Joey Hess <joeyh@debian.org>, Frans Pop <fjp@debian.org>, Colin Watson <cjwatson@debian.org>
+Uploaders: David Kimdon <dwhedon@debian.org>, Tollef Fog Heen <tfheen@debian.org>, Matt Kraai <kraai@debian.org>, Joey Hess <joeyh@debian.org>, Joshua Kwan <joshk@triplehelix.org>, Thomas Hood <jdthood@yahoo.co.uk>, Frans Pop <fjp@debian.org>, Colin Watson <cjwatson@debian.org>
Build-Depends: debhelper (>= 5.0.22), dpkg-dev (>= 1.9.0), libdebconfclient0-dev (>= 0.46), libdebian-installer4-dev (>= 0.41), po-debconf (>= 0.5.0), libiw-dev (>= 27+28pre9-1)
Vcs-Svn: svn://svn.debian.org/d-i/trunk/packages/netcfg
diff -Nurb ../netcfg-1.43/debian/netcfg-common.templates netcfg-1.43/debian/netcfg-common.templates
--- ../netcfg-1.43/debian/netcfg-common.templates 2008-03-08 05:00:20.000000000 +0900
+++ netcfg-1.43/debian/netcfg-common.templates 2008-04-18 22:14:33.000000000 +0800
@@ -56,6 +56,14 @@
of the wireless network you would like ${iface} to use. To skip wireless
configuration and continue, leave this field blank.
+Template: netcfg/wireless_security_type
+Type: select
+__Choices: Wep/Open, WPA PSK
+# :sl2:
+_Description: Wireless Network Type for ${iface}:
+ Chose Wep/Open if the network is open or secured with wep.
+ Chose WPA if the network is a WPA PSK protected network.
+
Template: netcfg/wireless_wep
Type: string
# :sl1:
@@ -80,6 +88,19 @@
the next screen carefully on how to enter your WEP key correctly, and try
again.
+Template: netcfg/invalid_pass
+Type: error
+# :sl2:
+_Description: Invalid passphrase
+ The WPA PSK passphrase was either too long (more than 64 characters)
+ or too short (less than 8 characters)
+
+Template: netcfg/wireless_wpa
+Type: string
+# :sl1:
+_Description: WPA passphrase for wireless device ${iface}:
+ Enter a WPA PSK passphrase.
+
Template: netcfg/invalid_essid
Type: error
# :sl2:
@@ -126,6 +147,13 @@
You may need to load a specific module for your network card, if you have
one. For this, go back to the network hardware detection step.
+Template: netcfg/no_wpa_supplicant
+Type: error
+# :sl2:
+_Description: Wpasupplicant not found
+ The wpa_supplicant binary was not found on the system.
+ Chose WEP/Open wireless network, otherwise chose wired network.
+
Template: netcfg/kill_switch_enabled
Type: note
# A "kill switch" is a physical switch found on some network cards that
@@ -257,7 +285,7 @@
Type: text
# base-installer progress bar item
# :sl1:
-_Description: Storing network settings...
+_Description: Storing network settings ...
Template: debian-installer/netcfg/title
Type: text
diff -Nurb ../netcfg-1.43/debian/rules netcfg-1.43/debian/rules
--- ../netcfg-1.43/debian/rules 2008-02-09 22:12:23.000000000 +0900
+++ netcfg-1.43/debian/rules 2008-04-18 22:14:33.000000000 +0800
@@ -26,7 +26,7 @@
dh_testdir
dh_testroot
dh_clean -k
- dh_installdirs -A usr/lib/base-installer.d etc/network bin
+ dh_installdirs -A usr/lib/base-installer.d etc/network etc/wpa_supplicant bin
# Install files that are the same in all packages
$(foreach PACKAGE, $(PACKAGES), \
install -m 755 $(PACKAGE) debian/$(PACKAGE)/bin/netcfg; \
@@ -36,7 +36,8 @@
$(foreach PACKAGE, $(DHCP_PACKAGES), \
mkdir -p debian/$(PACKAGE)/etc/dhcp debian/$(PACKAGE)/etc/dhcp3; \
mkdir -p debian/$(PACKAGE)/var/dhcp ; \
- install -m 755 killall.sh debian/$(PACKAGE)/bin/killall.sh)
+ install -m 755 killall.sh debian/$(PACKAGE)/bin/killall.sh; \
+ install -m 755 killwpa.sh debian/$(PACKAGE)/bin/killwpa.sh)
# Build architecture-independent files here.
diff -Nurb ../netcfg-1.43/dhcp.c netcfg-1.43/dhcp.c
--- ../netcfg-1.43/dhcp.c 2008-01-18 20:20:02.000000000 +0900
+++ netcfg-1.43/dhcp.c 2008-04-18 22:14:33.000000000 +0800
@@ -50,6 +50,9 @@
fprintf(fp, "\thostname %s\n", dhostname);
}
if (is_wireless_iface(iface)) {
+ if (requested_wpa_supplicant)
+ fprintf(fp, "\twpa-conf /etc/wpa_supplicant/wpa_supplicant.conf\n");
+ else {
fprintf(fp, "\t# wireless-* options are implemented by the wireless-tools package\n");
fprintf(fp, "\twireless-mode %s\n",
(mode == MANAGED) ? "managed" : "ad-hoc");
@@ -58,6 +61,7 @@
if (wepkey != NULL)
fprintf(fp, "\twireless-key1 %s\n", wepkey);
}
+ }
fclose(fp);
}
@@ -184,6 +188,7 @@
return 1;
else {
/* dhcp_pid contains the child's PID */
+
signal(SIGCHLD, &dhcp_client_sigchld);
return 0;
}
@@ -196,6 +201,11 @@
return 0;
}
+static int kill_wpa_supplicant(void) /* I would much rather kill wpasupp by pid, but my attempts at using kill() proved buggy */
+{
+ system("killwpa.sh");
+ return 0;
+}
/*
* Poll the started DHCP client for netcfg/dhcp_timeout seconds (def. 15)
@@ -302,7 +312,48 @@
return REPLY_DONT_CONFIGURE;
}
+int reconfigure_wifi(struct debconfclient *client)
+{
+ enum { ABORT, ESSID, SECURITY, WEP, WPA, DONE } wifistate = ESSID;
+
+ kill_wpa_supplicant();
+ kill_dhcp_client();
+ for (;;) {
+ switch (wifistate) {
+ case ESSID:
+ wifistate = ( netcfg_wireless_set_essid (client, interface, "high") == GO_BACK ) ?
+ ABORT : SECURITY;
+ break;
+ case SECURITY:
+ {
+ int ret;
+ ret = netcfg_wireless_set_security (client, interface);
+ if (ret == GO_BACK)
+ wifistate = ESSID;
+ else if (ret == WPAG)
+ wifistate = WPA;
+ else
+ wifistate = WEP;
+ break;
+ }
+ case WEP:
+ wifistate = (netcfg_wireless_set_wep (client, interface) == GO_BACK) ?
+ SECURITY : DONE;
+ break;
+ case WPA:
+ wifistate = (netcfg_set_passphrase (client, interface) == GO_BACK) ?
+ SECURITY : DONE;
+ break;
+ case DONE:
+ return 0;
+ break;
+ case ABORT:
+ return 1;
+ break;
+ }
+ }
+}
/* Here comes another Satan machine. */
int netcfg_activate_dhcp (struct debconfclient *client)
{
@@ -472,35 +523,10 @@
}
break;
case REPLY_RECONFIGURE_WIFI:
- {
- /* oh god - a NESTED satan machine */
- enum { ABORT, DONE, ESSID, WEP } wifistate = ESSID;
- for (;;) {
- switch (wifistate) {
- case ESSID:
- wifistate = ( netcfg_wireless_set_essid(client, interface, "high") == GO_BACK ) ?
- ABORT : WEP;
- break;
- case WEP:
- wifistate = ( netcfg_wireless_set_wep (client, interface) == GO_BACK ) ?
- ESSID : DONE;
- break;
- case ABORT:
- state = ASK_OPTIONS;
- break;
- case DONE:
- if (dhcp_pid > 0)
- state = POLL;
- else {
- kill_dhcp_client();
+ if (!reconfigure_wifi(client))
state = START;
- }
- break;
- }
- if (wifistate == DONE || wifistate == ABORT)
- break;
- }
- }
+ else
+ state = ASK_OPTIONS;
break;
}
break;
diff -Nurb ../netcfg-1.43/killwpa.sh netcfg-1.43/killwpa.sh
--- ../netcfg-1.43/killwpa.sh 1970-01-01 08:00:00.000000000 +0800
+++ netcfg-1.43/killwpa.sh 2008-04-18 22:14:33.000000000 +0800
@@ -0,0 +1,16 @@
+#!/bin/sh
+# Killall for dhcp clients.
+
+# Use [] in sed /address/ to avoid matching sed command itself in ps output
+pids=$(ps ax | sed -n '/[w]pa/s/^[ ]*\([0-9]*\).*/\1/p')
+
+for pid in $pids; do
+ if kill -0 $pid 2>/dev/null; then
+ kill -TERM $pid
+ sleep 1
+ # Still alive? Die!
+ if kill -0 $pid 2>/dev/null; then
+ kill -KILL $pid
+ fi
+ fi
+done
diff -Nurb ../netcfg-1.43/Makefile netcfg-1.43/Makefile
--- ../netcfg-1.43/Makefile 2008-01-14 10:48:18.000000000 +0900
+++ netcfg-1.43/Makefile 2008-04-18 22:14:33.000000000 +0800
@@ -17,8 +17,8 @@
all: $(TARGETS)
-netcfg-static: netcfg-static.o static.o
-netcfg: netcfg.o dhcp.o static.o ethtool-lite.o
+netcfg-static: netcfg-static.o static.o wpa.o
+netcfg: netcfg.o dhcp.o static.o ethtool-lite.o wpa.o
$(TARGETS): $(COMMON_OBJS)
$(CC) -o $@ $^ $(LDOPTS)
diff -Nurb ../netcfg-1.43/netcfg.c netcfg-1.43/netcfg.c
--- ../netcfg-1.43/netcfg.c 2006-09-23 21:24:37.000000000 +0800
+++ netcfg-1.43/netcfg.c 2008-04-18 22:14:33.000000000 +0800
@@ -33,6 +33,7 @@
#endif
#include "netcfg.h"
+int requested_wpa_supplicant = 0;
static method_t netcfg_method = DHCP;
response_t netcfg_get_method(struct debconfclient *client)
@@ -61,7 +62,21 @@
int main(int argc, char *argv[])
{
int num_interfaces = 0;
- enum { BACKUP, GET_INTERFACE, GET_HOSTNAME_ONLY, GET_METHOD, GET_DHCP, GET_STATIC, WCONFIG, WCONFIG_ESSID, WCONFIG_WEP, QUIT } state = GET_INTERFACE;
+ enum { BACKUP, \
+ GET_INTERFACE, \
+ GET_HOSTNAME_ONLY, \
+ GET_METHOD, \
+ GET_DHCP, \
+ GET_STATIC, \
+ WCONFIG, \
+ WCONFIG_ESSID, \
+ WCONFIG_SECURITY, \
+ WCONFIG_WEP, \
+ WCONFIG_WPA, \
+ QUIT }
+
+ state = GET_INTERFACE;
+
static struct debconfclient *client;
static int requested_wireless_tools = 0;
char **ifaces;
@@ -239,15 +254,40 @@
break;
case WCONFIG_ESSID:
- if (netcfg_wireless_set_essid (client, interface, NULL) == GO_BACK)
+ if (netcfg_wireless_set_essid(client, interface, "high") == GO_BACK)
state = BACKUP;
else
+ state = WCONFIG_SECURITY;
+ break;
+
+ case WCONFIG_SECURITY:
+ {
+ int ret;
+ ret = netcfg_wireless_set_security(client, interface);
+ if (ret == GO_BACK)
+ state = WCONFIG_ESSID;
+ else if (ret == WPAG)
+ state = WCONFIG_WPA;
+ else
state = WCONFIG_WEP;
break;
+ }
case WCONFIG_WEP:
- if (netcfg_wireless_set_wep (client, interface) == GO_BACK)
- state = WCONFIG_ESSID;
+ if (netcfg_wireless_set_wep(client, interface) == GO_BACK)
+ state = WCONFIG_SECURITY;
+ else
+ state = GET_METHOD;
+ break;
+
+ case WCONFIG_WPA:
+ if (requested_wpa_supplicant == 0) {
+ di_exec_shell_log("apt-install wpasupplicant");
+ requested_wpa_supplicant = 1;
+ }
+
+ if (netcfg_set_passphrase(client, interface) == GO_BACK)
+ state = WCONFIG_SECURITY;
else
state = GET_METHOD;
break;
diff -Nurb ../netcfg-1.43/netcfg.h netcfg-1.43/netcfg.h
--- ../netcfg-1.43/netcfg.h 2008-01-18 20:20:02.000000000 +0900
+++ netcfg-1.43/netcfg.h 2008-04-18 22:14:33.000000000 +0800
@@ -10,11 +10,15 @@
#define DHCLIENT3_CONF "/etc/dhcp3/dhclient.conf"
#define DOMAIN_FILE "/tmp/domain_name"
#define NTP_SERVER_FILE "/tmp/dhcp-ntp-servers"
+#define WPASUPP_FILE "/etc/wpa_supplicant/wpa_supplicant.conf"
#define DEVNAMES "/etc/network/devnames"
#define DEVHOTPLUG "/etc/network/devhotplug"
#define STAB "/var/run/stab"
+#define WPA_MIN 8
+#define WPA_MAX 64
+
#define _GNU_SOURCE
#include <sys/types.h>
@@ -41,7 +45,7 @@
"ff02::2 ip6-allrouters\n" \
"ff02::3 ip6-allhosts\n"
-typedef enum { NOT_ASKED = 30, GO_BACK } response_t;
+typedef enum { NOT_ASKED = 30, GO_BACK, WEPG, WPAG } response_t;
typedef enum { DHCP, STATIC, DUNNO } method_t;
typedef enum { ADHOC = 1, MANAGED = 2 } wifimode_t;
@@ -49,6 +53,7 @@
extern int wfd, skfd;
extern int input_result;
extern int have_domain;
+extern int requested_wpa_supplicant;
/* network config */
extern char *interface;
@@ -64,7 +69,7 @@
extern struct in_addr pointopoint;
/* wireless */
-extern char *essid, *wepkey;
+extern char *essid, *wepkey, *passphrase;
extern wifimode_t mode;
/* common functions */
@@ -111,7 +116,12 @@
extern int netcfg_wireless_set_essid (struct debconfclient *client, char* iface, char* priority);
extern int netcfg_wireless_set_wep (struct debconfclient *client, char* iface);
+extern int netcfg_wireless_set_security (struct debconfclient *client, char* iface);
+extern int netcfg_set_passphrase (struct debconfclient *client, char* iface);
+extern int netcfg_write_wpa (char *essid, char *passphrase);
+extern int start_wpa_supplicant (struct debconfclient *client);
+/*extern int kill_wpa_supplicant (void);*/
extern int iface_is_hotpluggable(const char *iface);
extern short find_in_stab (const char *iface);
extern void deconfigure_network(void);
diff -Nurb ../netcfg-1.43/netcfg-static.c netcfg-1.43/netcfg-static.c
--- ../netcfg-1.43/netcfg-static.c 2006-09-23 21:24:37.000000000 +0800
+++ netcfg-1.43/netcfg-static.c 2008-04-18 22:14:33.000000000 +0800
@@ -32,8 +32,19 @@
int num_interfaces = 0;
static struct debconfclient *client;
static int requested_wireless_tools = 0;
+ static int requested_wpa_supplicant = 0;
- enum { BACKUP, GET_INTERFACE, GET_HOSTNAME_ONLY, GET_STATIC, WCONFIG, WCONFIG_ESSID, WCONFIG_WEP, QUIT} state = GET_INTERFACE;
+ enum { BACKUP, \
+ GET_INTERFACE, \
+ GET_HOSTNAME_ONLY, \
+ GET_STATIC, \
+ WCONFIG, \
+ WCONFIG_ESSID, \
+ WCONFIG_SECURITY, \
+ WCONFIG_WEP, \
+ WCONFIG_WPA, \
+ QUIT}
+ state = GET_INTERFACE;
/* initialize libd-i */
di_system_init("netcfg-static");
@@ -91,6 +102,16 @@
if (netcfg_wireless_set_essid (client, interface, NULL))
state = BACKUP;
else
+ state = WCONFIG_SECURITY;
+ break;
+
+ case WCONFIG_SECURITY:
+ if (netcfg_wireless_set_security (client, interface) == GO_BACK)
+ state = WCONFIG_ESSID;
+ else
+ if (netcfg_wireless_set_security (client, interface) == WPAG)
+ state = WCONFIG_WPA;
+ else
state = WCONFIG_WEP;
break;
@@ -101,6 +122,18 @@
state = GET_STATIC;
break;
+ case WCONFIG_WPA:
+ if (requested_wpa_supplicant == 0) {
+ di_exec_shell_log("apt-install wpasupplicant");
+ requested_wpa_supplicant = 1;
+ }
+
+ if (netcfg_set_passphrase(client, interface) == GO_BACK)
+ state = WCONFIG_ESSID;
+ else
+ state = GET_STATIC;
+ break;
+
case QUIT:
return 0;
}
diff -Nurb ../netcfg-1.43/wireless.c netcfg-1.43/wireless.c
--- ../netcfg-1.43/wireless.c 2007-04-10 06:27:06.000000000 +0800
+++ netcfg-1.43/wireless.c 2008-04-18 22:14:33.000000000 +0800
@@ -17,53 +17,54 @@
wifimode_t mode = MANAGED;
/* wireless config */
-char* wepkey = NULL;
-char* essid = NULL;
+char *wepkey = NULL;
+char *essid = NULL;
+char *passphrase = NULL;
#ifdef WIRELESS
int is_wireless_iface (const char* iface)
{
wireless_config wc;
- return (iw_get_basic_config (wfd, (char*)iface, &wc) == 0);
+ return (iw_get_basic_config (wfd, (char*) iface, &wc) == 0);
}
-int netcfg_wireless_set_essid (struct debconfclient * client, char *iface, char* priority)
+int netcfg_wireless_set_essid (struct debconfclient *client, char *iface, char *priority)
{
int ret, couldnt_associate = 0;
wireless_config wconf;
- char* tf = NULL, *user_essid = NULL, *ptr = wconf.essid;
+ char *tf = NULL, *user_essid = NULL, *ptr = wconf.essid;
iw_get_basic_config (wfd, iface, &wconf);
- debconf_subst(client, "netcfg/wireless_essid", "iface", iface);
- debconf_subst(client, "netcfg/wireless_essid_again", "iface", iface);
- debconf_subst(client, "netcfg/wireless_adhoc_managed", "iface", iface);
+ debconf_subst (client, "netcfg/wireless_essid", "iface", iface);
+ debconf_subst (client, "netcfg/wireless_essid_again", "iface", iface);
+ debconf_subst (client, "netcfg/wireless_adhoc_managed", "iface", iface);
- debconf_input(client, priority ? priority : "low", "netcfg/wireless_adhoc_managed");
+ debconf_input (client, priority ? priority : "low", "netcfg/wireless_adhoc_managed");
- if (debconf_go(client) == 30)
+ if (debconf_go (client) == 30)
return GO_BACK;
- debconf_get(client, "netcfg/wireless_adhoc_managed");
+ debconf_get (client, "netcfg/wireless_adhoc_managed");
- if (!strcmp(client->value, "Ad-hoc network (Peer to peer)"))
+ if (!strcmp (client->value, "Ad-hoc network (Peer to peer)"))
mode = ADHOC;
wconf.has_mode = 1;
wconf.mode = mode;
- debconf_input(client, priority ? priority : "low", "netcfg/wireless_essid");
+ debconf_input (client, priority ? priority : "low", "netcfg/wireless_essid");
- if (debconf_go(client) == 30)
+ if (debconf_go (client) == 30)
return GO_BACK;
- debconf_get(client, "netcfg/wireless_essid");
- tf = strdup(client->value);
+ debconf_get (client, "netcfg/wireless_essid");
+ tf = strdup (client->value);
automatic:
/* question not asked or user doesn't care or we're successfully associated */
- if (!empty_str(wconf.essid) || empty_str(client->value))
+ if (!empty_str (wconf.essid) || empty_str (client->value))
{
int i, success = 0;
@@ -73,39 +74,39 @@
iw_set_basic_config (wfd, iface, &wconf);
- /* Wait for association.. (MAX_SECS seconds)*/
-#define MAX_SECS 3
+ /* Wait for association.. (MAX_SECS seconds) */
+#define MAX_SECS 5
- debconf_capb(client, "backup progresscancel");
- debconf_progress_start(client, 0, MAX_SECS, "netcfg/wifi_progress_title");
- if (debconf_progress_info(client, "netcfg/wifi_progress_info") == 30)
+ debconf_capb (client, "backup progresscancel");
+ debconf_progress_start (client, 0, MAX_SECS, "netcfg/wifi_progress_title");
+ if (debconf_progress_info (client, "netcfg/wifi_progress_info") == 30)
goto stop;
netcfg_progress_displayed = 1;
for (i = 0; i <= MAX_SECS; i++) {
int progress_ret;
- interface_up(iface);
+ interface_up (iface);
sleep (1);
iw_get_basic_config (wfd, iface, &wconf);
- if (!empty_str(wconf.essid)) {
+ if (!empty_str (wconf.essid)) {
/* Save for later */
- debconf_set(client, "netcfg/wireless_essid", wconf.essid);
- debconf_progress_set(client, MAX_SECS);
+ debconf_set (client, "netcfg/wireless_essid", wconf.essid);
+ debconf_progress_set (client, MAX_SECS);
success = 1;
break;
}
- progress_ret = debconf_progress_step(client, 1);
- interface_down(iface);
+ progress_ret = debconf_progress_step (client, 1);
+ interface_down (iface);
if (progress_ret == 30)
break;
}
stop:
- debconf_progress_stop(client);
- debconf_capb(client, "backup");
+ debconf_progress_stop (client);
+ debconf_capb (client, "backup");
netcfg_progress_displayed = 0;
if (success)
@@ -115,39 +116,42 @@
}
/* yes, wants to set an essid by himself */
- if (strlen(tf) <= IW_ESSID_MAX_SIZE) /* looks ok, let's use it */
+ if (strlen (tf) <= IW_ESSID_MAX_SIZE) /* looks ok, let's use it */
user_essid = tf;
- while (!user_essid || empty_str(user_essid) ||
- strlen(user_essid) > IW_ESSID_MAX_SIZE) {
+ while (!user_essid || empty_str (user_essid) ||
+ strlen (user_essid) > IW_ESSID_MAX_SIZE)
+ {
/* Misnomer of a check. Basically, if we went through autodetection,
* we want to enter this loop, but we want to suppress anything that
* relied on the checking of tf/user_essid (i.e. "", in most cases.) */
- if (!couldnt_associate) {
- debconf_subst(client, "netcfg/invalid_essid", "essid", user_essid);
- debconf_input(client, "high", "netcfg/invalid_essid");
- debconf_go(client);
+ if (!couldnt_associate)
+ {
+ debconf_subst (client, "netcfg/invalid_essid", "essid", user_essid);
+ debconf_input (client, "high", "netcfg/invalid_essid");
+ debconf_go (client);
}
if (couldnt_associate)
- ret = debconf_input(client, "critical", "netcfg/wireless_essid_again");
+ ret = debconf_input (client, "critical", "netcfg/wireless_essid_again");
else
- ret = debconf_input(client, "low", "netcfg/wireless_essid");
+ ret = debconf_input (client, "low", "netcfg/wireless_essid");
/* we asked the question once, why can't we ask it again? */
if (ret == 30)
/* maybe netcfg/wireless_essid was preseeded; if so, give up */
break;
- if (debconf_go(client) == 30) /* well, we did, but he wants to go back */
+ if (debconf_go (client) == 30) /* well, we did, but he wants to go back */
return GO_BACK;
if (couldnt_associate)
- debconf_get(client, "netcfg/wireless_essid_again");
+ debconf_get (client, "netcfg/wireless_essid_again");
else
- debconf_get(client, "netcfg/wireless_essid");
+ debconf_get (client, "netcfg/wireless_essid");
- if (empty_str(client->value)) {
+ if (empty_str (client->value))
+ {
if (couldnt_associate)
/* we've already tried the empty string here, so give up */
break;
@@ -158,14 +162,14 @@
/* But now we'd not like to suppress any MORE errors */
couldnt_associate = 0;
- free(user_essid);
- user_essid = strdup(client->value);
+ free (user_essid);
+ user_essid = strdup (client->value);
}
essid = user_essid;
- memset(ptr, 0, IW_ESSID_MAX_SIZE + 1);
- snprintf(wconf.essid, IW_ESSID_MAX_SIZE + 1, "%s", essid);
+ memset (ptr, 0, IW_ESSID_MAX_SIZE + 1);
+ snprintf (wconf.essid, IW_ESSID_MAX_SIZE + 1, "%s", essid);
wconf.has_essid = 1;
wconf.essid_on = 1;
@@ -174,12 +178,12 @@
return 0;
}
-static void unset_wep_key (char* iface)
+static void unset_wep_key (char *iface)
{
wireless_config wconf;
int ret;
- iw_get_basic_config(wfd, iface, &wconf);
+ iw_get_basic_config (wfd, iface, &wconf);
wconf.has_key = 1;
wconf.key[0] = '\0';
@@ -189,31 +193,52 @@
ret = iw_set_basic_config (wfd, iface, &wconf);
}
-int netcfg_wireless_set_wep (struct debconfclient * client, char* iface)
+int netcfg_wireless_set_security (struct debconfclient *client, char *iface)
+{
+ int ret = 0 ;
+ debconf_subst (client, "netcfg/wireless_security_type", "iface", iface);
+ debconf_input (client, "high", "netcfg/wireless_security_type");
+ ret = debconf_go(client);
+ di_info("ret = %d", ret);
+
+ if (ret == 30)
+ return GO_BACK;
+
+ debconf_get (client, "netcfg/wireless_security_type");
+ di_info ("client->value = %s", client->value);
+
+ if (client->value[1] == 'e')
+ return WEPG;
+ else
+ return WPAG;
+
+}
+
+int netcfg_wireless_set_wep (struct debconfclient *client, char *iface)
{
wireless_config wconf;
- char* rv = NULL;
+ char *rv = NULL;
int ret, keylen, err = 0;
- unsigned char buf [IW_ENCODING_TOKEN_MAX + 1];
+ unsigned char buf[IW_ENCODING_TOKEN_MAX + 1];
struct iwreq wrq;
iw_get_basic_config (wfd, iface, &wconf);
- debconf_subst(client, "netcfg/wireless_wep", "iface", iface);
+ debconf_subst (client, "netcfg/wireless_wep", "iface", iface);
debconf_input (client, "high", "netcfg/wireless_wep");
- ret = debconf_go(client);
+ ret = debconf_go (client);
if (ret == 30)
return GO_BACK;
- debconf_get(client, "netcfg/wireless_wep");
+ debconf_get (client, "netcfg/wireless_wep");
rv = client->value;
- if (empty_str(rv)) {
+ if (empty_str (rv)) {
unset_wep_key (iface);
if (wepkey != NULL) {
- free(wepkey);
+ free (wepkey);
wepkey = NULL;
}
@@ -221,35 +246,86 @@
}
while ((keylen = iw_in_key (rv, buf)) == -1) {
- debconf_subst(client, "netcfg/invalid_wep", "wepkey", rv);
- debconf_input(client, "critical", "netcfg/invalid_wep");
- debconf_go(client);
+ debconf_subst (client, "netcfg/invalid_wep", "wepkey", rv);
+ debconf_input (client, "critical", "netcfg/invalid_wep");
+ debconf_go (client);
debconf_input (client, "high", "netcfg/wireless_wep");
- ret = debconf_go(client);
+ ret = debconf_go (client);
if (ret == 30)
return GO_BACK;
- debconf_get(client, "netcfg/wireless_wep");
+ debconf_get (client, "netcfg/wireless_wep");
rv = client->value;
}
/* Now rv is safe to store since it parsed fine */
- wepkey = strdup(rv);
+ wepkey = strdup (rv);
wrq.u.data.pointer = buf;
wrq.u.data.flags = 0;
wrq.u.data.length = keylen;
- if ((err = iw_set_ext(skfd, iface, SIOCSIWENCODE, &wrq)) < 0) {
- di_warning("setting WEP key on %s failed with code %d", iface, err);
+ if ((err = iw_set_ext (skfd, iface, SIOCSIWENCODE, &wrq)) < 0) {
+ di_warning ("setting WEP key on %s failed with code %d", iface, err);
return -1;
}
return 0;
}
+int netcfg_set_passphrase (struct debconfclient *client, char *iface)
+{
+ wireless_config wconf;
+ char *pass = NULL;
+ int ret, start;
+ di_info ("set pass");
+ iw_get_basic_config (wfd, iface, &wconf);
+
+ unset_wep_key (iface);
+
+ debconf_subst (client, "netcfg/wireless_wpa", "iface", iface);
+ debconf_input (client, "high", "netcfg/wireless_wpa");
+ ret = debconf_go (client);
+
+ if (ret == 30)
+ return GO_BACK;
+
+ debconf_get (client, "netcfg/wireless_wpa");
+ pass = client->value;
+
+ while (strlen (pass) < WPA_MIN || strlen (pass) > WPA_MAX) {
+ debconf_subst (client, "netcfg/invalid_pass", "passphrase", pass);
+ debconf_input (client, "critical", "netcfg/invalid_pass");
+ debconf_go (client);
+
+ debconf_input (client, "high", "netcfg/wireless_wpa");
+ ret = debconf_go (client);
+
+
+ if (ret == 30)
+ return GO_BACK;
+
+ debconf_get (client, "netcfg/wireless_wpa");
+ pass = client->value;
+ }
+
+ passphrase = pass;
+ di_info ("passphrase == pass %s", passphrase);
+ start = netcfg_write_wpa (essid, passphrase);
+ if (start != 0)
+ return -1;
+ di_info ("netcfg_write_wpa");
+ start = start_wpa_supplicant (client);
+
+ if (start != 0)
+ return -1;
+ di_info ("start wpa");
+ return 0;
+}
+
+
#else
int is_wireless_iface (const char *iface)
@@ -273,4 +349,18 @@
return 0;
}
+int netcfg_wireless_set_security (struct debconfclient *client, char *iface)
+{
+ (void) client;
+ (void) iface;
+ return 0;
+}
+
+int netcfg_set_passphrase (struct debconfclient *client, char *iface)
+{
+ (void) client;
+ (void) iface;
+ return 0;
+}
+
#endif
diff -Nurb ../netcfg-1.43/wpa.c netcfg-1.43/wpa.c
--- ../netcfg-1.43/wpa.c 1970-01-01 08:00:00.000000000 +0800
+++ netcfg-1.43/wpa.c 2008-04-18 22:14:33.000000000 +0800
@@ -0,0 +1,93 @@
+/*
+* WPA module for netcfg
+*
+* Copyright (C) 2008 Glenn Saberton <gsaberton@foomagic.org>
+*
+* Licensed under the terms of the GNU General Public License version 2
+*
+* Functions shamelessly copied from dhcp.c, if you are looking for comments
+* look in that file.
+*/
+
+#include "netcfg.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <debian-installer.h>
+
+
+static int wpa_supplicant_exit_status = 1;
+pid_t wpa_supplicant_pid = -1;
+pid_t wpa_pid;
+pid_t wpa;
+/*
+* Build an /etc/wpa_supplicant.conf
+* file.
+*/
+
+int
+netcfg_write_wpa (char *essid, char *passphrase)
+{
+ FILE *fp;
+
+ if ((fp = file_open (WPASUPP_FILE, "w")))
+ {
+ fprintf (fp, "\n# wpa_supplicant.conf generated during install\n"
+ "ctrl_interface=/var/run/wpa_supplicant\n"
+ "ctrl_interface_group=0\n"
+ "eapol_version=1\n"
+ "ap_scan=1\n\n" /* So we can associate to hidden ssid's */
+ "network={\n");
+ fprintf (fp, "\t\tssid=\"%s\"\n", essid);
+ fprintf (fp, "\t\tpsk=\"%s\"\n", passphrase);
+ fprintf (fp, "\t\tscan_ssid=1\n" "}\n");
+ }
+ fclose (fp);
+ return 0;
+}
+
+static void
+wpa_supplicant_sigchild (int sig __attribute__ ((unused)))
+{
+ if (wpa_supplicant_pid <= 0)
+ return;
+
+ waitpid (wpa_supplicant_pid, &wpa_supplicant_exit_status, 0);
+ wpa_supplicant_pid = -1;
+}
+
+int
+start_wpa_supplicant (struct debconfclient *client)
+{
+
+ if (access ("/sbin/wpa_supplicant", F_OK) == 0);
+
+ else
+ {
+ debconf_input (client, "critical", "netcfg/no_wpa_supplicant");
+ debconf_go (client);
+ exit (1);
+ }
+
+wpa_supplicant_pid = fork();
+
+ if (wpa_supplicant_pid == 0)
+ {
+ fclose(client->out);
+ wpa = (getpid() + 6); /* I *know* this is horrendous, but I am too stupid to work it out */
+
+ if (execlp ("wpa_supplicant", "wpa_supplicant", "-i", interface, "-c",
+ "/etc/wpa_supplicant/wpa_supplicant.conf", "-B", NULL) == -1)
+ {
+ di_error("could not exec wpasupplicant: %s", strerror(errno));
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ signal(SIGCHLD, &wpa_supplicant_sigchild);
+ return 0;
+ }
+}
Reply to: