OpenWrt Forum Archive

Topic: wl0_key causes key to be overwritten by wl0_key4 in WhiteRussian RC2

The content of this topic has been archived on 15 Mar 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hi,

I recently converted my WRT54GS to OpenWRT. Unfortunately I could not get the WEP encryption to work. At one point I discovered that the keys shown by iwconfig for key 1 and key 4 was the same. So I took a look in the sourcecode for the wifi utility.

In the setup_wext_wep function (line 337 of wificonf.c), all the 4 keys are set, one at a time. If the code also finds a wl0_key nvram attribute, it does the following:

        wrq.u.data.flags = i | IW_ENCODE_RESTRICTED;
        IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq, "Set Encode");

The trouble is that wrq still contains the last key that was configured, so in effect the above code overwrites the key that wl0_key points to.

The following (untested, as I don't have the tool-chain setup) patch should fix the problem

--- wificonf.c  2005-07-17 14:59:44.000000000 +0200
+++ wificonf2.c 2005-07-29 14:46:10.163466731 +0200
@@ -376,13 +376,16 @@
 }
 void setup_wext_wep(int skfd, char *ifname)
 {
-       int i, keylen;
+       int i, keylen, select_key;
        struct iwreq wrq;
        char keystr[5];
        char *keyval;
        unsigned char key[IW_ENCODING_TOKEN_MAX];
 
        strcpy(keystr, "key1");
+
+       select_key = atoi(nvram_safe_get(wl_var("key")));
+
        for (i = 1; i <= 4; i++) {
                if (keyval = nvram_get(wl_var(keystr))) {
                        keylen = iw_in_key(keyval, key);
@@ -391,18 +394,13 @@
                                wrq.u.data.length = keylen;
                                wrq.u.data.pointer = (caddr_t) key;
                                wrq.u.data.flags = i;
+                               if (i == select_key)
+                                       wrq.u.data.flags |= IW_ENCODE_RESTRICTED;
                                IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq, "Set Encode");
                        }
                }
                keystr[3]++;
        }
-       
-       
-       i = atoi(nvram_safe_get(wl_var("key")));
-       if (i > 0 && i < 4) {
-               wrq.u.data.flags = i | IW_ENCODE_RESTRICTED;
-               IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq, "Set Encode");
-       }
 }

Hi Hjerne,

also have problems to get WRT54G v2 to work in client mode. It does connect to an AP no problem via a wl join <ssid> [key xxxxxxxxxx] [imode bss|ibss] [amode open|shared] command though (in my case imode bss , amode shared). But the wificonf routine seems to be making some wrong settings for simple operation using WEP from a 'station'.
Tried your suggested code change in the latest HEAD checkout but that results in iwconfig eth1 showing the fourth key, ignoring the wl0_key=1 entry in NVRAM. 'wl primary_key x' statement can temporarily override that.

So made some more changes; code below works as far as the WEP key is concerned. Needs further change though as all 4 keys need to be communicated and then the selected as last one. But ....
there are more problems; via wl have figured out that the access method does not get set properly (shared in my case) and that the interface gets set to repeater mode where I am asking via NVRAM for station mode.
On the side also noticed that several other things need reviewing, like shortslot_override that seems not to get set (noticed big bitrate improvement on long distance link by setting it via WL.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void setup_wext_wep(int skfd, char *ifname)
{
    int i, keylen;
    struct iwreq wrq;
    char keystr[5];
    char *keyval;
    unsigned char key[IW_ENCODING_TOKEN_MAX];

    i = atoi(nvram_safe_get(wl_var("key")));         /* get keynumber */
    switch (i) {
        case 2:    strcpy(keystr, "key2");     break;
        case 3: strcpy(keystr, "key3");        break;
        case 4: strcpy(keystr, "key4");        break;
        default: strcpy(keystr, "key1");    break;
    }                    
    if (i > 0 && i < 5) {                     /* check range is 1 .. 4 */
        if (keyval = nvram_get(wl_var(keystr))) {    /* fetch keycode */
            keylen = iw_in_key(keyval, key);    /* get length of key */
            if (keylen > 0) {            /* only act if finite length */
                wrq.u.data.length = keylen;    /* fill in iwreq structure */
                wrq.u.data.pointer = (caddr_t) key;
                wrq.u.data.flags = i | IW_ENCODE_RESTRICTED;                               
                IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq, "Set Encode");
            }
        }
    }
}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

rgds
doddel
Portugal

(Last edited by doddel on 1 Aug 2005, 05:06)

Ok. This patch does the correct thing for me. As I don't know the inner workings of how to configure the wifi device, I choose the fool-proof way:

diff -u -r1.2.2.13 wificonf.c
--- wificonf.c  25 Jul 2005 07:51:14 -0000      1.2.2.13
+++ wificonf.c  4 Aug 2005 14:46:24 -0000
@@ -405,8 +405,17 @@

        i = atoi(nvram_safe_get(wl_var("key")));
        if (i > 0 && i < 4) {
-               wrq.u.data.flags = i | IW_ENCODE_RESTRICTED;
-               IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq, "Set Encode");
+               keystr[3] = '0' + i;
+               if (keyval = nvram_get(wl_var(keystr))) {
+                       keylen = iw_in_key(keyval, key);
+                       
+                       if (keylen > 0) {
+                               wrq.u.data.length = keylen;
+                               wrq.u.data.pointer = (caddr_t) key;
+                               wrq.u.data.flags = i | IW_ENCODE_RESTRICTED;
+                               IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq, "Set Encode");
+                       }
+               }
        }
 }

This patch is against HEAD of whiterussian. Is this the correct place to post it, or should I send it somewhere else?

The discussion might have continued from here.