From Michael Mann:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 4 Jul 2011 14:07:20 +0000 (14:07 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 4 Jul 2011 14:07:20 +0000 (14:07 +0000)
Removed "key prefix" need within GUI so it's a little more intuitive (because
that's what this bug is complaining about).  Slight backwards compatibility
issue with UAT (because key prefix was in previous keys), but all development
(including fix for BUG 1123 that created UAT) has just been on SVN and not
released.

Also adjusted AirPCap (airpcap_loader.c) to account for the lack of "key
prefix".

Addressed some memory leaks/excess string creation.

https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5985

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@37888 f5534014-38df-0310-8fa8-9805f1628bb7

airpcap_loader.c
epan/crypt/airpdcap.c
epan/crypt/airpdcap_user.h
epan/dissectors/packet-ieee80211.c

index a6ef77364d35a7744d64e4722570150bf31faee0..1887dd80e640b3e6a8362d6f0930f7a5a2a35d7f 100644 (file)
@@ -149,7 +149,8 @@ static guint num_legacy_channels = 14;
 static guint
 get_wep_key(pref_t *pref, gpointer ud)
 {
-    gchar *my_string = NULL;
+    gchar *key_string = NULL;
+    guint8 key_type = AIRPDCAP_KEY_TYPE_WEP;
     keys_cb_data_t* user_data;
 
     decryption_key_t* new_key;
@@ -159,18 +160,33 @@ get_wep_key(pref_t *pref, gpointer ud)
 
     if (g_ascii_strncasecmp(pref->name, "wep_key", 7) == 0 && pref->type == PREF_STRING)
     {
-       my_string = g_strdup(*pref->varp.string);
+        /* strip out key type */
+        if (g_ascii_strncasecmp(*pref->varp.string, STRING_KEY_TYPE_WEP ":", 4) == 0) {
+              key_string = (gchar*)(*pref->varp.string)+4;
+        }
+        else if (g_ascii_strncasecmp(*pref->varp.string, STRING_KEY_TYPE_WPA_PWD ":", 8) == 0) {
+              key_string = (gchar*)(*pref->varp.string)+8;
+          key_type = AIRPDCAP_KEY_TYPE_WPA_PWD;
+        }
+        else if (g_ascii_strncasecmp(*pref->varp.string, STRING_KEY_TYPE_WPA_PSK ":", 8) == 0) {
+              key_string = (gchar*)(*pref->varp.string)+8;
+          key_type = AIRPDCAP_KEY_TYPE_WPA_PSK;
+        }
+        else {
+          key_type = AIRPDCAP_KEY_TYPE_WEP;
+              key_string = (gchar*)*pref->varp.string;
+        }
 
            /* Here we have the string describing the key... */
-           new_key = parse_key_string(my_string);
+           new_key = parse_key_string(key_string, key_type);
 
-       if( new_key != NULL)
-       {
-           /* Key is added only if not null ... */
-           user_data->list = g_list_append(user_data->list,new_key);
-           user_data->number_of_keys++;
-           user_data->current_index++;
-       }
+           if( new_key != NULL)
+           {
+              /* Key is added only if not null ... */
+              user_data->list = g_list_append(user_data->list,new_key);
+              user_data->number_of_keys++;
+              user_data->current_index++;
+           }
     }
     return 0;
 }
index e520882cc3b45d9ad740cc5c02d8aa11bb4553b4..c96a2a2a29e3471221e09192481fbb59dcf073f2 100644 (file)
@@ -1779,12 +1779,11 @@ AirPDcapRsnaPwd2Psk(
 
 /*
  * Returns the decryption_key_t struct given a string describing the key.
- * Returns NULL if the key_string cannot be parsed.
+ * Returns NULL if the input_string cannot be parsed.
  */
 decryption_key_t*
-parse_key_string(gchar* input_string)
+parse_key_string(gchar* input_string, guint8 key_type)
 {
-    gchar *type;
     gchar *key;
     gchar *ssid;
 
@@ -1795,126 +1794,84 @@ parse_key_string(gchar* input_string)
     gchar **tokens;
     guint n = 0;
     decryption_key_t *dk;
-    gchar *first_nibble = input_string;
 
     if(input_string == NULL)
         return NULL;
 
     /*
-     * Parse the input_string. It should be in the form
-     * <key type>:<key data>[:<ssid>]
-     * XXX - For backward compatibility, the a WEP key can be just a string
-     * of hexadecimal characters (if WEP key is wrong, null will be
+     * Parse the input_string. WEP and WPA will be just a string
+     * of hexadecimal characters (if key is wrong, null will be
      * returned...).
+     * WPA-PWD should be in the form
+     * <key data>[:<ssid>]
      */
 
-    /* First, check for a WEP string */
-    /* XXX - This duplicates code in packet-ieee80211.c */
-    if (g_ascii_strncasecmp(input_string, STRING_KEY_TYPE_WEP ":", 4) == 0) {
-        first_nibble += 4;
-    }
-
-    key_ba = g_byte_array_new();
-    res = hex_str_to_bytes(first_nibble, key_ba, FALSE);
-
-    if (res && key_ba->len > 0) {
-        /* Key is correct! It was probably an 'old style' WEP key */
-        /* Create the decryption_key_t structure, fill it and return it*/
-        dk = (decryption_key_t *)g_malloc(sizeof(decryption_key_t));
-
-        dk->type = AIRPDCAP_KEY_TYPE_WEP;
-        /* XXX - The current key handling code in the GUI requires
-         * no separators and lower case */
-        dk->key  = g_string_new(bytes_to_str(key_ba->data, key_ba->len));
-        g_string_down(dk->key);
-        dk->bits = key_ba->len * 8;
-        dk->ssid = NULL;
-
-        g_byte_array_free(key_ba, TRUE);
-        return dk;
-    }
-    g_byte_array_free(key_ba, TRUE);
-
-
-    tokens = g_strsplit(input_string,":",0);
-
-    /* Tokens is a null termiated array of strings ... */
-    while(tokens[n] != NULL)
-        n++;
-
-    if(n < 2)
+    switch(key_type)
     {
-        /* Free the array of strings */
-        g_strfreev(tokens);
-        return NULL;
-    }
-
-    type = g_strdup(tokens[0]);
+    case AIRPDCAP_KEY_TYPE_WEP:
+    case AIRPDCAP_KEY_TYPE_WEP_40:
+    case AIRPDCAP_KEY_TYPE_WEP_104:
+
+       key_ba = g_byte_array_new();
+       res = hex_str_to_bytes(input_string, key_ba, FALSE);
+
+       if (res && key_ba->len > 0) {
+           /* Key is correct! It was probably an 'old style' WEP key */
+           /* Create the decryption_key_t structure, fill it and return it*/
+           dk = (decryption_key_t *)g_malloc(sizeof(decryption_key_t));
+
+           dk->type = AIRPDCAP_KEY_TYPE_WEP;
+           /* XXX - The current key handling code in the GUI requires
+            * no separators and lower case */
+           dk->key  = g_string_new(bytes_to_str(key_ba->data, key_ba->len));
+           g_string_down(dk->key);
+           dk->bits = key_ba->len * 8;
+           dk->ssid = NULL;
+
+           g_byte_array_free(key_ba, TRUE);
+           return dk;
+       }
 
-    /*
-     * The second token is the key (right now it doesn't matter
-     * if it is a passphrase[+ssid] or an hexadecimal one)
-     */
-    key = g_strdup(tokens[1]);
+       /* Key doesn't work */
+       g_byte_array_free(key_ba, TRUE);
+       return NULL;
 
-    ssid = NULL;
-    /* Maybe there is a third token (an ssid, if everything else is ok) */
-    if(n >= 3)
-    {
-        ssid = g_strdup(tokens[2]);
-    }
+    case AIRPDCAP_KEY_TYPE_WPA_PWD:
 
-    if (g_ascii_strcasecmp(type,STRING_KEY_TYPE_WPA_PSK) == 0) /* WPA key */
-    {
-        /* Create a new string */
-        key_string = g_string_new(key);
+        tokens = g_strsplit(input_string,":",0);
 
-        key_ba = g_byte_array_new();
-        res = hex_str_to_bytes(key, key_ba, FALSE);
+        /* Tokens is a null termiated array of strings ... */
+        while(tokens[n] != NULL)
+            n++;
 
-        /* Two tokens means that the user should have entered a WPA-BIN key ... */
-        if(!res || ((key_string->len) != WPA_PSK_KEY_CHAR_SIZE))
+        if(n < 1)
         {
-            g_string_free(key_string, TRUE);
-            g_byte_array_free(key_ba, TRUE);
-
-            g_free(type);
-            g_free(key);
-            /* No ssid has been created ... */
             /* Free the array of strings */
             g_strfreev(tokens);
             return NULL;
         }
 
-        /* Key was correct!!! Create the new decryption_key_t ... */
-        dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
-
-        dk->type = AIRPDCAP_KEY_TYPE_WPA_PMK;
-        dk->key  = g_string_new(key);
-        dk->bits = (guint) dk->key->len * 4;
-        dk->ssid = NULL;
+        /*
+         * The first token is the key 
+         */
+        key = g_strdup(tokens[0]);
 
-        g_string_free(key_string, TRUE);
-        g_byte_array_free(key_ba, TRUE);
-        g_free(key);
-        g_free(type);
+        ssid = NULL;
+        /* Maybe there is a second token (an ssid, if everything else is ok) */
+        if(n >= 2)
+        {
+           ssid = g_strdup(tokens[1]);
+        }
 
-        /* Free the array of strings */
-        g_strfreev(tokens);
-        return dk;
-    }
-    else if(g_ascii_strcasecmp(type,STRING_KEY_TYPE_WPA_PWD) == 0) /* WPA key *//* If the number of tokens is more than three, we accept the string... if the first three tokens are correct... */
-    {
         /* Create a new string */
         key_string = g_string_new(key);
         ssid_ba = NULL;
 
-        /* Three (or more) tokens mean that the user entered a WPA-PWD key ... */
+        /* Two (or more) tokens mean that the user entered a WPA-PWD key ... */
         if( ((key_string->len) > WPA_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WPA_KEY_MIN_CHAR_SIZE))
         {
             g_string_free(key_string, TRUE);
 
-            g_free(type);
             g_free(key);
             g_free(ssid);
 
@@ -1923,13 +1880,12 @@ parse_key_string(gchar* input_string)
             return NULL;
         }
 
-        if(ssid != NULL) /* more than three tokens found, means that the user specified the ssid */
+        if(ssid != NULL) /* more than two tokens found, means that the user specified the ssid */
         {
             ssid_ba = g_byte_array_new();
             if (! uri_str_to_bytes(ssid, ssid_ba)) {
                 g_string_free(key_string, TRUE);
                 g_byte_array_free(ssid_ba, TRUE);
-                g_free(type);
                 g_free(key);
                 g_free(ssid);
                 /* Free the array of strings */
@@ -1942,7 +1898,6 @@ parse_key_string(gchar* input_string)
                 g_string_free(key_string, TRUE);
                 g_byte_array_free(ssid_ba, TRUE);
 
-                g_free(type);
                 g_free(key);
                 g_free(ssid);
 
@@ -1964,7 +1919,6 @@ parse_key_string(gchar* input_string)
         if (ssid_ba != NULL)
             g_byte_array_free(ssid_ba, TRUE);
 
-        g_free(type);
         g_free(key);
         if(ssid != NULL)
             g_free(ssid);
@@ -1972,20 +1926,34 @@ parse_key_string(gchar* input_string)
         /* Free the array of strings */
         g_strfreev(tokens);
         return dk;
-    }
 
-    /* Something was wrong ... free everything */
+    case AIRPDCAP_KEY_TYPE_WPA_PSK:
 
-    g_free(type);
-    g_free(key);
-    if(ssid != NULL)
-        g_free(ssid); /* It is not always present */
-    if (ssid_ba != NULL)
-        g_byte_array_free(ssid_ba, TRUE);
+        key_ba = g_byte_array_new();
+        res = hex_str_to_bytes(input_string, key_ba, FALSE);
 
-    /* Free the array of strings */
-    g_strfreev(tokens);
+        /* Two tokens means that the user should have entered a WPA-BIN key ... */
+        if(!res || ((key_ba->len) != WPA_PSK_KEY_CHAR_SIZE))
+        {
+            g_byte_array_free(key_ba, TRUE);
+
+            /* No ssid has been created ... */
+            return NULL;
+        }
+
+        /* Key was correct!!! Create the new decryption_key_t ... */
+        dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
+
+        dk->type = AIRPDCAP_KEY_TYPE_WPA_PMK;
+        dk->key  = g_string_new(input_string);
+        dk->bits = (guint) dk->key->len * 4;
+        dk->ssid = NULL;
+
+        g_byte_array_free(key_ba, TRUE);
+        return dk;
+    }
 
+    /* Type not supported */
     return NULL;
 }
 
index 1d5e2663c94b850a07155dca6436ea8b0f1751d1..1b4836ea809c0ec2d4e73505e92d010dde2dcecc 100644 (file)
@@ -204,17 +204,20 @@ typedef struct _AIRPDCAP_KEYS_COLLECTION {
  * - 01:02:03:04:05 (40/64-bit WEP)
  * - 0102030405060708090a0b0c0d (104/128-bit WEP)
  * - 01:02:03:04:05:06:07:08:09:0a:0b:0c:0d (104/128-bit WEP)
- * - wep:01020304... (WEP)
- * - wep:01:02:03:04... (WEP)
- * - wpa-pwd:MyPassword (WPA + plaintext password + "wildcard" SSID)
- * - wpa-pwd:MyPassword:MySSID (WPA + plaintext password + specific SSID)
- * - wpa-psk:01020304... (WPA + 256-bit raw key)
+ * - MyPassword (WPA + plaintext password + "wildcard" SSID)
+ * - MyPassword:MySSID (WPA + plaintext password + specific SSID)
+ * - 01020304... (WPA + 256-bit raw key)
+ * @param key_type [IN] Type of key used for string. Possibilities include:
+ * - AIRPDCAP_KEY_TYPE_WEP (40/64-bit and 104/128-bit WEP)
+ * - AIRPDCAP_KEY_TYPE_WPA_PWD (WPA + plaintext password + "wildcard" SSID or 
+ * WPA + plaintext password + specific SSID)
+ * - AIRPDCAP_KEY_TYPE_WPA_PSK (WPA + 256-bit raw key)
  * @return A pointer to a freshly-g_malloc()ed decryption_key_t struct on
  *   success, or NULL on failure.
  * @see get_key_string()
  */
 decryption_key_t*
-parse_key_string(gchar* key_string);
+parse_key_string(gchar* key_string, guint8 key_type);
 
 /**
  * Returns a newly allocated string representing the given decryption_key_t
index 5b472fb9f679c40dd4e043106d1f28eee67477b3..7d1f5332559b57a3fe78d0869040a7d99eaeafe3 100644 (file)
@@ -166,22 +166,6 @@ static uat_wep_key_record_t *uat_wep_key_records = NULL;
 static uat_t * wep_uat = NULL;
 static guint num_wepkeys_uat = 0;
 
-/*
- * Convert a raw WEP key or one prefixed with "wep:" to a byte array.
- * Separators are allowed.
- */
-/* XXX This is duplicated in epan/airpdcap.c:parse_key_string() */
-static gboolean
-wep_str_to_bytes(const char *hex_str, GByteArray *bytes) {
-  char *first_nibble = (char *) hex_str;
-
-  if (g_ascii_strncasecmp(hex_str, STRING_KEY_TYPE_WEP ":", 4) == 0) {
-    first_nibble += 4;
-  }
-
-  return hex_str_to_bytes(first_nibble, bytes, FALSE);
-}
-
 static void* uat_wep_key_record_copy_cb(void* n, const void* o, size_t siz _U_) {
     uat_wep_key_record_t* new_key = (uat_wep_key_record_t *)n;
     const uat_wep_key_record_t* old_key = (uat_wep_key_record_t *)o;
@@ -198,31 +182,29 @@ static void* uat_wep_key_record_copy_cb(void* n, const void* o, size_t siz _U_)
 static void uat_wep_key_record_update_cb(void* r, const char** err) {
     uat_wep_key_record_t* rec = (uat_wep_key_record_t *)r;
     decryption_key_t* dk;
-    gchar* tmpk;
 
     if (rec->string == NULL) {
          *err = ep_strdup_printf("Key can't be blank");
     } else {
         g_strstrip(rec->string);
-        tmpk = g_strdup(rec->string);
-        dk = parse_key_string(tmpk);
+        dk = parse_key_string(rec->string, rec->key);
 
         if(dk != NULL) {
            switch(dk->type) {
               case AIRPDCAP_KEY_TYPE_WEP:
               case AIRPDCAP_KEY_TYPE_WEP_40:
               case AIRPDCAP_KEY_TYPE_WEP_104:
-                 if (rec->key != 0) {
+                 if (rec->key != AIRPDCAP_KEY_TYPE_WEP) {
                     *err = ep_strdup_printf("Invalid key format");
                  }
                  break;
               case AIRPDCAP_KEY_TYPE_WPA_PWD:
-                 if (rec->key != 1) {
+                 if (rec->key != AIRPDCAP_KEY_TYPE_WPA_PWD) {
                     *err = ep_strdup_printf("Invalid key format");
                  }
                  break;
               case AIRPDCAP_KEY_TYPE_WPA_PSK:
-                 if (rec->key != 2) {
+                 if (rec->key != AIRPDCAP_KEY_TYPE_WPA_PSK) {
                     *err = ep_strdup_printf("Invalid key format");
                  }
                  break;
@@ -12552,9 +12534,9 @@ proto_register_ieee80211 (void)
   };
 
   static const value_string wep_type_vals[] = {
-    { 0, STRING_KEY_TYPE_WEP },
-    { 1, STRING_KEY_TYPE_WPA_PWD },
-    { 2, STRING_KEY_TYPE_WPA_PSK },
+    { AIRPDCAP_KEY_TYPE_WEP, STRING_KEY_TYPE_WEP },
+    { AIRPDCAP_KEY_TYPE_WPA_PWD, STRING_KEY_TYPE_WPA_PWD },
+    { AIRPDCAP_KEY_TYPE_WPA_PSK, STRING_KEY_TYPE_WPA_PSK },
     { 0x00, NULL }
   };
 
@@ -15789,8 +15771,8 @@ proto_register_ieee80211 (void)
   prefs_register_static_text_preference(wlan_module, "info_decryption_key",
     "Key examples: 01:02:03:04:05 (40/64-bit WEP),\n"
     "010203040506070809101111213 (104/128-bit WEP),\n"
-    "wpa-pwd:MyPassword[:MyAP] (WPA + plaintext password [+ SSID]),\n"
-    "wpa-psk:0102030405...6061626364 (WPA + 256-bit key).  "
+    "MyPassword[:MyAP] (WPA + plaintext password [+ SSID]),\n"
+    "0102030405...6061626364 (WPA + 256-bit key).  "
     "Invalid keys will be ignored.",
     "Valid key formats");
 
@@ -15975,16 +15957,13 @@ void set_airpdcap_keys(void)
   decryption_key_t* dk = NULL;
   GByteArray *bytes = NULL;
   gboolean res;
-  gchar* tmpk = NULL;
 
   keys=(PAIRPDCAP_KEYS_COLLECTION)g_malloc(sizeof(AIRPDCAP_KEYS_COLLECTION));
   keys->nKeys = 0;
 
   for(i = 0; (uat_wep_key_records != NULL) && (i < num_wepkeys_uat) && (i < MAX_ENCRYPTION_KEYS); i++)
   {
-    tmpk = g_strdup(uat_wep_key_records[i].string);
-
-    dk = parse_key_string(tmpk);
+    dk = parse_key_string(uat_wep_key_records[i].string, uat_wep_key_records[i].key);
 
     if(dk != NULL)
     {
@@ -15993,7 +15972,7 @@ void set_airpdcap_keys(void)
         key.KeyType = AIRPDCAP_KEY_TYPE_WEP;
 
         bytes = g_byte_array_new();
-        res = wep_str_to_bytes(dk->key->str, bytes);
+        res = hex_str_to_bytes(dk->key->str, bytes, FALSE);
 
         if (dk->key->str && res && bytes->len > 0 && bytes->len <= AIRPDCAP_WEP_KEY_MAXLEN)
         {
@@ -16031,7 +16010,7 @@ void set_airpdcap_keys(void)
         key.KeyType = AIRPDCAP_KEY_TYPE_WPA_PMK;
 
         bytes = g_byte_array_new();
-        res = wep_str_to_bytes(dk->key->str, bytes);
+        res = hex_str_to_bytes(dk->key->str, bytes, FALSE);
 
         /* XXX - Pass the correct array of bytes... */
         if (bytes-> len <= AIRPDCAP_WPA_PMK_LEN) {
@@ -16042,7 +16021,6 @@ void set_airpdcap_keys(void)
         }
       }
     }
-    g_free(tmpk);
   }
 
   /* Now set the keys */