diff options
-rw-r--r-- | airpcap_loader.c | 36 | ||||
-rw-r--r-- | epan/crypt/airpdcap.c | 182 | ||||
-rw-r--r-- | epan/crypt/airpdcap_user.h | 15 | ||||
-rw-r--r-- | epan/dissectors/packet-ieee80211.c | 46 |
4 files changed, 122 insertions, 157 deletions
diff --git a/airpcap_loader.c b/airpcap_loader.c index a6ef77364d..1887dd80e6 100644 --- a/airpcap_loader.c +++ b/airpcap_loader.c @@ -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; } diff --git a/epan/crypt/airpdcap.c b/epan/crypt/airpdcap.c index e520882cc3..c96a2a2a29 100644 --- a/epan/crypt/airpdcap.c +++ b/epan/crypt/airpdcap.c @@ -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; } diff --git a/epan/crypt/airpdcap_user.h b/epan/crypt/airpdcap_user.h index 1d5e2663c9..1b4836ea80 100644 --- a/epan/crypt/airpdcap_user.h +++ b/epan/crypt/airpdcap_user.h @@ -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 diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c index 5b472fb9f6..7d1f533255 100644 --- a/epan/dissectors/packet-ieee80211.c +++ b/epan/dissectors/packet-ieee80211.c @@ -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 */ |