-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFICIEPV8GyuTwyskMRAvx+AJ4412+g641eB9Yv+S/klJ4Oc8TSkQCeILhq y1Krj41Sz5kjYVLQqsV8hfg= =Xplc -----END PGP SIGNATURE-----
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 18:39:30.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 18:39:30.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 18:39:30.000000000 +0800 @@ -56,6 +56,15 @@ 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 network, WPA PSK protected network +# :sl1: +_Description: Wireless Network Type for ${iface}: + You have two choices for wireless network type. Chose Wep/Open if your + network is open or secured with wep. Chose WPA if your network is a + WPA PSK protected network. + Template: netcfg/wireless_wep Type: string # :sl1: @@ -80,6 +89,20 @@ 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 or too short. + Wpa passphrase must be no less than eight characters and no + more than 64 characters. + +Template: netcfg/wireless_wpa +Type: string +# :sl1: +_Description: WPA passphrase for wireless device ${iface}: + Please enter a WPA PSK passphrase. + Template: netcfg/invalid_essid Type: error # :sl2: @@ -126,6 +149,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. + You can either chose to use wep or ethernet. + Template: netcfg/kill_switch_enabled Type: note # A "kill switch" is a physical switch found on some network cards that @@ -159,7 +189,7 @@ Template: netcfg/wifi_progress_info Type: text # :sl1: -_Description: Searching for wireless access points... +_Description: Searching for wireless access points ... Template: netcfg/disable_dhcp Type: boolean @@ -257,7 +287,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 18:39:30.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 18:39:30.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 18:39:30.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 18:39:30.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 18:39:30.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 18:39:30.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 18:39:30.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 18:39:30.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 18:39:30.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; + } +}
Attachment:
netcfg-wpa.diff.sig
Description: Binary data