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
