Hi.

So here's a story which I'd conjecture is not uncommon.

One installs Frugalware. She chooses to configure a wpa protected
wireless network. She enters the essid and the wpa key to the
appropriate dialogue boxes.

Later on she wants to be able to use another wpa protected wireless
network. She looks around, sees her data for the first network in
/etc/wpa_supplicant.conf. The syntax is easy to familiarize with,
she adds a new clause and types "service interface restart". And
then she will see happily that her machine finds the new network
and connects to it. Right?

Wrong! She will see that no network is connected to and the original
wpa_supplicant.conf file -- including only the network which has been
specified at install time -- has been restored. WTF, she can yell at this
point...

If she had read the fine manual, she could see that if she needs a
permanent /etc/wpa_supplicant.conf file with multiple networks then
she should abandon the wpa_psk directive and insert the appropriate
pre_up/post_down directives. So there is a solution for her problem.
Still it's contraintuitive. This scheme is a POLS violation 
(http://en.wikipedia.org/wiki/Principle_of_least_astonishment).

I can imagine two ways to get over this.

One is simply using temporary files instead of /etc/wpa_supplicant.conf
for invoking wpa_supplicant, so noone shall think that there is a
/etc/wpa_supplicant.conf which is permanent and editable. A variant of
this is adding '# WARNING! Machine generated file, do not edit" comments
to the wpa_supplicant config file.

Other is what implemented in the patch, ie. using a permanent,
user-modifiable /etc/wpa_supplicant.conf file. There is a fine summary
in the commit message. Backward compatibility is dealt with. Is this
feasible?

Regards,
Csaba



commit 5d933cb7db28589b5febe8257e0088090875d9da
Author: Csaba Henk <[email protected]>
Date:   Sun Dec 28 15:35:23 2008 +0100

    refactor wpa_supplicant usage
    
    - add a "wpa_supplicant = yes|no" network directive
    - when configuring networks via the dialogue based interface,
      netconfig sets this to "yes" if psk key is given,
      and writes essid/psk to /etc/wpa_supplicant.conf
    - when starting interfaces, if "wpa_supplicant = yes" is present,
      call wpa_supplicant using the existing /etc/wpa_supplicant.conf
      without modifying it.
    - if the old "wpa_psk" directive is present in the config file,
      fall back to old behaviour

diff --git a/doc/netconfig.txt b/doc/netconfig.txt
index 815732a..8563193 100644
--- a/doc/netconfig.txt
+++ b/doc/netconfig.txt
@@ -118,10 +118,10 @@ be used. If using DHCP, then this directive is ignored.
 
 key = <key>::
        Used to manipulate encryption or scrambling keys and security mode for
-       wireless networks. Use this for WEP only, use `wpa_psk` for WPA.
+       wireless networks. Use this for WEP only, use `wpa_supplicant` for WPA.
 
-wpa_psk = <passphrase>::
-       If this directive is specified, then wpa_supplicant will be invoked to
+wpa_supplicant = yes|no::
+       If this directive is enabled, then wpa_supplicant will be invoked to
        initialize WPA encryption before setting any other parameter (like 
ESSID).
 
 wpa_driver = <driver>::
@@ -199,11 +199,10 @@ the first, and this post_down should be the last one.
 === Using wpa_supplicant
 
 If you want to use wpa_supplicant instead of the simple encryption (using
-key = secret), then use the following pre_up and post_down lines:
+key = secret), then enable this by setting:
 
 ----
-pre_up = wpa_supplicant -Dwext -iwlan0 -c /etc/wpa_supplicant.conf -w -B
-post_down = killall wpa_supplicant
+wpa_supplicant = yes
 ----
 
 You also need to edit `/etc/wpa_supplicant.conf`. A possible correct setup is:
diff --git a/libfwnetconfig/libfwnetconfig.c b/libfwnetconfig/libfwnetconfig.c
index 4f60bde..ac0d64f 100644
--- a/libfwnetconfig/libfwnetconfig.c
+++ b/libfwnetconfig/libfwnetconfig.c
@@ -37,6 +37,8 @@
 
 #include "libfwnetconfig.h"
 
+#define WPA_CONF "/etc/wpa_supplicant.conf"
+
 extern int fwutil_dryrun;
 
 /** @defgroup libfwnetconfig Frugalware Network Configuration library
@@ -193,7 +195,12 @@ fwnet_profile_t *fwnet_parseprofile(char *fn)
                                if(!strcmp(var, "KEY") && !strlen(iface->key))
                                        strncpy(iface->key, ptr, 
FWNET_ENCODING_TOKEN_MAX);
                                if(!strcmp(var, "WPA_PSK") && 
!strlen(iface->wpa_psk))
+                               {
                                        strncpy(iface->wpa_psk, ptr, PATH_MAX);
+                                       iface->wpa_supplicant = 1;
+                               }
+                               if(!strcmp(var, "WPA_SUPPLICANT"))
+                                       iface->wpa_supplicant = (toupper(*ptr) 
== 'Y');
                                if(!strcmp(var, "WPA_DRIVER") && 
!strlen(iface->wpa_driver))
                                        strncpy(iface->wpa_driver, ptr, 
PATH_MAX);
                                if(!strcmp(var, "GATEWAY") && 
!strlen(iface->gateway))
@@ -311,7 +318,7 @@ int fwnet_ifdown(fwnet_interface_t *iface, fwnet_profile_t 
*profile)
                fwutil_system(ptr);
                FWUTIL_FREE(ptr);
        }
-       if(strlen(iface->wpa_psk))
+       if(iface->wpa_supplicant)
        {
                ptr = g_strdup("killall wpa_supplicant");
                fwutil_system(ptr);
@@ -389,15 +396,18 @@ static int update_secrets(char *path, char *user, char 
*pass)
        return(0);
 }
 
-static int update_wpa_conf(char *ssid, char *psk)
+static int update_wpa_conf(char *ssid, char *psk, int itemidx)
 {
        FILE *fp;
 
-       fp = fopen("/etc/wpa_supplicant.conf", "w");
+       if(itemidx == 0)
+               rename(WPA_CONF, WPA_CONF ".old");
+       fp = fopen(WPA_CONF, "a");
        if(!fp)
                return(1);
-       fprintf(fp, "ctrl_interface=/var/run/wpa_supplicant\n\n");
-       fprintf(fp, "network={\n\tssid=\"%s\"\n\tpsk=\"%s\"\n}\n", ssid, psk);
+       if(itemidx == 0)
+               fprintf(fp, "ctrl_interface=/var/run/wpa_supplicant\n");
+       fprintf(fp, "\nnetwork={\n\tssid=\"%s\"\n\tpsk=\"%s\"\n}\n", ssid, psk);
        fclose(fp);
        return(0);
 }
@@ -417,13 +427,17 @@ int fwnet_ifup(fwnet_interface_t *iface, fwnet_profile_t 
*profile)
 
        dhcp = fwnet_is_dhcp(iface);
        // initialize the device
-       if(strlen(iface->wpa_psk))
+       if(iface->wpa_supplicant)
        {
-               update_wpa_conf(iface->essid, iface->wpa_psk);
+               if(strlen(iface->wpa_psk))
+               {
+                       unlink(WPA_CONF);
+                       update_wpa_conf(iface->essid, iface->wpa_psk, 0);
+               }
                if(strlen(iface->wpa_driver))
-                       ptr = g_strdup_printf("wpa_supplicant -i%s -D%s -c 
/etc/wpa_supplicant.conf -w -B", iface->name, iface->wpa_driver);
+                       ptr = g_strdup_printf("wpa_supplicant -i%s -D%s -c " 
WPA_CONF " -w -B", iface->name, iface->wpa_driver);
                else
-                       ptr = g_strdup_printf("wpa_supplicant -i%s -Dwext -c 
/etc/wpa_supplicant.conf -w -B", iface->name);
+                       ptr = g_strdup_printf("wpa_supplicant -i%s -Dwext -c " 
WPA_CONF " -w -B", iface->name);
                ret += fwutil_system(ptr);
                FWUTIL_FREE(ptr);
        }
@@ -748,7 +762,10 @@ int fwnet_writeconfig(fwnet_profile_t *profile, char *host)
                if(iface->key != NULL && strlen(iface->key))
                        fprintf(fp, "key = %s\n", iface->key);
                if(iface->wpa_psk != NULL && strlen(iface->wpa_psk))
-                       fprintf(fp, "wpa_psk = %s\n", iface->wpa_psk);
+                       fprintf(fp, "wpa_supplicant = yes\n");
+               if(iface->essid != NULL && strlen(iface->essid) &&
+                  iface->wpa_psk != NULL && strlen(iface->wpa_psk))
+                       update_wpa_conf(iface->essid, iface->wpa_psk, i);
                if(iface->wpa_driver != NULL && strlen(iface->wpa_driver))
                        fprintf(fp, "wpa_driver = %s\n", iface->wpa_driver);
                if(fwnet_is_dhcp(iface))
diff --git a/libfwnetconfig/libfwnetconfig.h b/libfwnetconfig/libfwnetconfig.h
index 2144bcd..dd96ef2 100644
--- a/libfwnetconfig/libfwnetconfig.h
+++ b/libfwnetconfig/libfwnetconfig.h
@@ -50,6 +50,7 @@ typedef struct __fwnet_interface_t {
        char mode[FWNET_MODE_MAX_SIZE+1];
        char key[FWNET_ENCODING_TOKEN_MAX+1];
        char wpa_psk[PATH_MAX+1];
+       int  wpa_supplicant;
        char wpa_driver[PATH_MAX+1];
        char gateway[FWNET_GW_MAX_SIZE+1];
 } fwnet_interface_t;
_______________________________________________
Frugalware-devel mailing list
[email protected]
http://frugalware.org/mailman/listinfo/frugalware-devel

Reply via email to