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 <[email protected]> -Uploaders: Joey Hess <[EMAIL PROTECTED]>, Frans Pop <[EMAIL PROTECTED]>, Colin Watson <[EMAIL PROTECTED]> +Uploaders: David Kimdon <[EMAIL PROTECTED]>, Tollef Fog Heen <[EMAIL PROTECTED]>, Matt Kraai <[EMAIL PROTECTED]>, Joey Hess <[EMAIL PROTECTED]>, Joshua Kwan <[EMAIL PROTECTED]>, Thomas Hood <[EMAIL PROTECTED]>, Frans Pop <[EMAIL PROTECTED]>, Colin Watson <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> +* +* 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; + } +}

