[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[RFC] [PATCH] WPA PSK support for netcfg



-----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


Reply to: