From ece4b01f218ab4e71233580e199e830b83958c99 Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Thu, 11 Jun 2015 15:05:44 -0700 Subject: Add the wireless toolbar. Add the wireless toolbar to the Qt UI. Start adding AirPcap support to ui/80211_utils. Add FCS validation routines to ws80211_utils. Move a bunch of AirPcap routines that require epan from caputils to ui/gtk. They were required for driver key management, which we'll leave to the AirPcap Control Panel in the Qt UI. Move frequency-utils to wsutil. Change-Id: I44446758046621d183f5c2ba9f6526bf01e084f1 Reviewed-on: https://code.wireshark.org/review/8910 Petri-Dish: Gerald Combs Tested-by: Petri Dish Buildbot Reviewed-by: Gerald Combs --- ui/gtk/airpcap_dlg.c | 3 +- ui/gtk/airpcap_gui_utils.c | 1317 ++++++++++++++++++++++++++++++++++++++++- ui/gtk/airpcap_gui_utils.h | 88 +++ ui/gtk/main.c | 2 +- ui/gtk/main_airpcap_toolbar.c | 3 +- 5 files changed, 1409 insertions(+), 4 deletions(-) (limited to 'ui/gtk') diff --git a/ui/gtk/airpcap_dlg.c b/ui/gtk/airpcap_dlg.c index a079d9e006..6ea1fc26f3 100644 --- a/ui/gtk/airpcap_dlg.c +++ b/ui/gtk/airpcap_dlg.c @@ -31,8 +31,9 @@ #include #include +#include + #include -#include #include #include diff --git a/ui/gtk/airpcap_gui_utils.c b/ui/gtk/airpcap_gui_utils.c index a305bdd983..14d96d5f3f 100644 --- a/ui/gtk/airpcap_gui_utils.c +++ b/ui/gtk/airpcap_gui_utils.c @@ -34,10 +34,19 @@ #include #include +#include + +#include +#include +#include #include -#include #include +#include + +#include +#include +#include "ui/capture_ui_utils.h" #include "ui/simple_dialog.h" #include "ui/gtk/main.h" @@ -56,6 +65,9 @@ /* Controls the releay of settings back to the adapter. */ gboolean change_airpcap_settings = FALSE; +/* WLAN preferences pointer */ +module_t *wlan_prefs = NULL; + /* * Set up the airpcap toolbar for the new capture interface */ @@ -244,6 +256,1309 @@ airpcap_set_toolbar_stop_capture(airpcap_if_info_t* if_info) } } +#if 0 +/* Returs TRUE if the WEP key is valid, false otherwise */ +gboolean +wep_key_is_valid(char* key) +{ + size_t strsize, i; + + if (key == NULL) + return FALSE; + + strsize = strlen(key); + + if ( (strsize > WEP_KEY_MAX_CHAR_SIZE) || (strsize < 2)) + { + return FALSE; + } + if ((strsize % 2) != 0) + { + return FALSE; + } + for(i = 0; i < strsize; i++) + { + if (!g_ascii_isxdigit(key[i])) + { + return FALSE; + } + } + + return TRUE; +} +#endif + +/* + * Callback used by the load_wlan_keys() routine in order to read a WEP decryption key + */ +static guint +get_wep_key(pref_t *pref, gpointer ud) +{ + gchar *key_string = NULL; + guint8 key_type = AIRPDCAP_KEY_TYPE_WEP; + keys_cb_data_t* user_data; + uat_t *uat; + guint i; + char* err = NULL; + uat_wep_key_record_t* wep_keys; + decryption_key_t* new_key; + + /* Retrieve user data info */ + user_data = (keys_cb_data_t*)ud; + + if (g_ascii_strcasecmp(pref->name, "wep_key_table") == 0 && pref->type == PREF_UAT) + { + uat = pref->varp.uat; + /* This is just a sanity check. UAT should be loaded */ + if (!uat->loaded) + { + if (!uat_load(uat, &err)) + { + /* XXX - report the error */ + g_free(err); + return 1; + } + } + + for (i = 0, wep_keys = (uat_wep_key_record_t*)*uat->user_ptr; i < *uat->nrows_p; i++, wep_keys++) + { + /* strip out key type if present */ + if (g_ascii_strncasecmp(wep_keys->string, STRING_KEY_TYPE_WEP ":", 4) == 0) { + key_type = AIRPDCAP_KEY_TYPE_WEP; + key_string = (gchar*)wep_keys->string+4; + } + else if (g_ascii_strncasecmp(wep_keys->string, STRING_KEY_TYPE_WPA_PWD ":", 8) == 0) { + key_string = (gchar*)wep_keys->string+8; + key_type = AIRPDCAP_KEY_TYPE_WPA_PWD; + } + else if (g_ascii_strncasecmp(wep_keys->string, STRING_KEY_TYPE_WPA_PSK ":", 8) == 0) { + key_string = (gchar*)wep_keys->string+8; + key_type = AIRPDCAP_KEY_TYPE_WPA_PSK; + } + else { + key_type = wep_keys->key; + key_string = (gchar*)wep_keys->string; + } + + /* Here we have the string describing the key... */ + 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++; + } + } + } + return 0; +} + +/* Callback used by the save_wlan_keys() routine in order to write a decryption key */ +static guint +set_wep_key(pref_t *pref, gpointer ud _U_) +{ + keys_cb_data_t* user_data; + uat_t *uat; + gint i; + char* err = NULL; + uat_wep_key_record_t uat_key; + + decryption_key_t* new_key; + + /* Retrieve user data info */ + user_data = (keys_cb_data_t*)ud; + + if (g_ascii_strcasecmp(pref->name, "wep_key_table") == 0 && pref->type == PREF_UAT) + { + uat = pref->varp.uat; + if (!uat->loaded) + { + /* UAT will only be loaded if previous keys exist, so it may need + to be loaded now */ + if (!uat_load(uat, &err)) + { + /* XXX - report the error */ + g_free(err); + return 1; + } + uat->loaded = 1; + } + /* Free the old records */ + uat_clear(uat); + + for (i = 0; i < user_data->number_of_keys; i++) + { + new_key = (decryption_key_t*)g_list_nth_data(user_data->list,i); + + uat_key.string = get_key_string(new_key); + uat_key.key = new_key->type; + uat_add_record(uat, &uat_key, TRUE); + } + + if (!uat_save(uat, &err)) + { + /* XXX - report the error */ + g_free(err); + return 1; + } + } + + return 0; +} + +/* + * This function will tell the airpcap driver the key list to use + * This will be stored into the registry... + */ +static gboolean +write_wlan_driver_wep_keys_to_registry(GList* key_list) +{ + guint i,j,k,n,y; + GString *new_key; + gchar s[3]; + PAirpcapKeysCollection KeysCollection; + guint KeysCollectionSize; + guint8 KeyByte; + guint keys_in_list = 0; + decryption_key_t* key_item = NULL; + airpcap_if_info_t* fake_info_if = NULL; + + /* Create the fake_info_if from the first adapter of the list */ + fake_info_if = airpcap_driver_fake_if_info_new(); + + if (fake_info_if == NULL) + return FALSE; + + /* + * XXX - When WPA will be supported, change this to: keys_in_list = g_list_length(key_list); + * but right now we will have to count only the WEP keys (or we will have a malloc-mess :-) ) + */ + n = g_list_length(key_list); + for(k = 0; k < n; k++ ) + if (((decryption_key_t*)g_list_nth_data(key_list,k))->type == AIRPDCAP_KEY_TYPE_WEP) + keys_in_list++; + + /* + * Calculate the size of the keys collection + */ + KeysCollectionSize = (guint)AirpcapKeysCollectionSize(keys_in_list); + + /* + * Allocate the collection + */ + KeysCollection = (PAirpcapKeysCollection)g_malloc(KeysCollectionSize); + if (!KeysCollection) + { + return FALSE; + } + + /* + * Populate the key collection + */ + KeysCollection->nKeys = keys_in_list; + + /* + * XXX - If we have, let's say, six keys, the first three are WEP, then two are WPA, and the + * last is WEP, we have to scroll the whole list (n) but increment the array counter only + * when a WEP key is found (y) .. When WPA will be supported by the driver, I'll have to change + * this + */ + y = 0; /* Current position in the key list */ + + for(i = 0; i < n; i++) + { + /* Retrieve the Item corresponding to the i-th key */ + key_item = (decryption_key_t*)g_list_nth_data(key_list,i); + + /* + * XXX - The AIRPDCAP_KEY_TYPE_WEP is the only supported right now! + * We will have to modify the AirpcapKey structure in order to + * support the other two types! What happens now, is that simply the + * not supported keys will just be discarded (they will be saved in Wireshark though) + */ + if (key_item->type == AIRPDCAP_KEY_TYPE_WEP) + { + KeysCollection->Keys[y].KeyType = AIRPDCAP_KEY_TYPE_WEP; + + new_key = g_string_new(key_item->key->str); + + KeysCollection->Keys[y].KeyLen = (guint) new_key->len / 2; + memset(&KeysCollection->Keys[y].KeyData, 0, sizeof(KeysCollection->Keys[y].KeyData)); + + for(j = 0 ; j < new_key->len; j += 2) + { + s[0] = new_key->str[j]; + s[1] = new_key->str[j+1]; + s[2] = '\0'; + KeyByte = (guint8)strtol(s, NULL, 16); + KeysCollection->Keys[y].KeyData[j / 2] = KeyByte; + } + /* XXX - Change when WPA will be supported!!! */ + y++; + g_string_free(new_key,TRUE); + } + else if (key_item->type == AIRPDCAP_KEY_TYPE_WPA_PWD) + { + /* XXX - The driver cannot deal with this kind of key yet... */ + } + else if (key_item->type == AIRPDCAP_KEY_TYPE_WPA_PMK) + { + /* XXX - The driver cannot deal with this kind of key yet... */ + } + } + + /* + * Free the old adapter key collection! + */ + if (fake_info_if->keysCollection != NULL) + g_free(fake_info_if->keysCollection); + + /* + * Set this collection ad the new one + */ + fake_info_if->keysCollection = KeysCollection; + fake_info_if->keysCollectionSize = KeysCollectionSize; + + /* + * Configuration must be saved + */ + fake_info_if->saved = FALSE; + + /* + * Write down the changes to the registry + */ + airpcap_save_driver_if_configuration(fake_info_if); + + airpcap_if_info_free(fake_info_if); + + return TRUE; +} + +/* + * Function used to read the Decryption Keys from the preferences and store them + * properly into the airpcap adapter. + */ +static gboolean +load_wlan_driver_wep_keys(void) +{ + keys_cb_data_t* user_data; + guint i; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Allocate a structure used to keep infos between the callbacks */ + user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t)); + + /* Fill the structure */ + user_data->list = NULL; + user_data->current_index = 0; + user_data->number_of_keys= 0; /* Still unknown */ + + /* Run the callback on each 802.11 preference */ + prefs_pref_foreach(wlan_prefs, get_wep_key, (gpointer)user_data); + + /* Now the key list should be filled */ + + /* + * Signal that we've changed things, and run the 802.11 dissector's + * callback + */ + wlan_prefs->prefs_changed = TRUE; + + prefs_apply(wlan_prefs); + + write_wlan_driver_wep_keys_to_registry(user_data->list); + + /* FREE MEMORY */ + /* free the WEP key string */ + for(i=0;ilist);i++) + { + g_free(g_list_nth(user_data->list,i)->data); + } + + /* free the (empty) list */ + g_list_free(user_data->list); + + /* free the user_data structure */ + g_free(user_data); + + /* airpcap_if_info_free(fake_info_if); */ + + return TRUE; +} + +/* + * This function will tell the airpcap driver the key list to use + * This will be stored into the registry... + */ +static gboolean +write_wlan_wep_keys_to_registry(airpcap_if_info_t* info_if, GList* key_list) +{ + guint i,j; + GString *new_key; + gchar s[3]; + PAirpcapKeysCollection KeysCollection; + guint KeysCollectionSize; + guint8 KeyByte; + guint keys_in_list = 0; + decryption_key_t* key_item = NULL; + + keys_in_list = g_list_length(key_list); + + /* + * Calculate the size of the keys collection + */ + KeysCollectionSize = (guint)AirpcapKeysCollectionSize(keys_in_list); + + /* + * Allocate the collection + */ + KeysCollection = (PAirpcapKeysCollection)g_malloc(KeysCollectionSize); + if (!KeysCollection) + { + return FALSE; + } + + /* + * Populate the key collection + */ + KeysCollection->nKeys = keys_in_list; + + for(i = 0; i < keys_in_list; i++) + { + KeysCollection->Keys[i].KeyType = AIRPDCAP_KEY_TYPE_WEP; + + /* Retrieve the Item corresponding to the i-th key */ + key_item = (decryption_key_t*)g_list_nth_data(key_list,i); + new_key = g_string_new(key_item->key->str); + + KeysCollection->Keys[i].KeyLen = (guint) new_key->len / 2; + memset(&KeysCollection->Keys[i].KeyData, 0, sizeof(KeysCollection->Keys[i].KeyData)); + + for(j = 0 ; j < new_key->len; j += 2) + { + s[0] = new_key->str[j]; + s[1] = new_key->str[j+1]; + s[2] = '\0'; + KeyByte = (guint8)strtol(s, NULL, 16); + KeysCollection->Keys[i].KeyData[j / 2] = KeyByte; + } + + g_string_free(new_key,TRUE); + + } + /* + * Free the old adapter key collection! + */ + if (info_if->keysCollection != NULL) + g_free(info_if->keysCollection); + + /* + * Set this collection ad the new one + */ + info_if->keysCollection = KeysCollection; + info_if->keysCollectionSize = KeysCollectionSize; + + /* + * Configuration must be saved + */ + info_if->saved = FALSE; + + /* + * Write down the changes to the registry + */ + airpcap_save_selected_if_configuration(info_if); + + return TRUE; +} + +/* + * Returns the ASCII string of a key given the key bytes + */ +static gchar* +airpcap_get_key_string(AirpcapKey key) +{ + unsigned int j = 0; + gchar *dst,*src; + + dst = NULL; + src = NULL; + + if (key.KeyType == AIRPDCAP_KEY_TYPE_WEP) + { + if (key.KeyLen != 0) + { + /* Allocate the string used to store the ASCII representation of the WEP key */ + dst = (gchar*)g_malloc(sizeof(gchar)*WEP_KEY_MAX_CHAR_SIZE + 1); + /* Make sure that the first char is '\0' in order to make g_strlcat() work */ + dst[0]='\0'; + + for(j = 0; j < key.KeyLen; j++) + { + src = g_strdup_printf("%.2x", key.KeyData[j]); + /* + * XXX - use g_strconcat() or GStrings instead ??? + */ + g_strlcat(dst, src, WEP_KEY_MAX_CHAR_SIZE+1); + } + g_free(src); + } + } + else if (key.KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD) + { + /* XXX - Add code here */ + } + else if (key.KeyType == AIRPDCAP_KEY_TYPE_WPA_PMK) + { + /* XXX - Add code here */ + } + else + { + /* XXX - Add code here */ + } + + return dst; +} + +/* + * Function used to save to the preference file the Decryption Keys. + */ +static int +save_wlan_driver_wep_keys(void) +{ + GList* key_list = NULL; + char* tmp_key = NULL; + guint keys_in_list,i; + keys_cb_data_t* user_data; + airpcap_if_info_t* fake_info_if = NULL; + + /* Create the fake_info_if from the first adapter of the list */ + fake_info_if = airpcap_driver_fake_if_info_new(); + + if (fake_info_if == NULL) + return 0; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Allocate a structure used to keep infos between the callbacks */ + user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t)); + + /* Number of keys in key list */ + if (fake_info_if->keysCollectionSize != 0) + keys_in_list = AirpcapKeysCollectionSizeToKeyCount(fake_info_if->keysCollectionSize); + else + keys_in_list = 0; + + for(i=0; ikeysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WEP) + { + tmp_key = airpcap_get_key_string(fake_info_if->keysCollection->Keys[i]); + key_list = g_list_append(key_list,g_strdup(tmp_key)); + g_free(tmp_key); + } + } + + /* Now we know the exact number of WEP keys in the list, so store it ... */ + keys_in_list = g_list_length(key_list); + + /* Fill the structure */ + user_data->list = key_list; + user_data->current_index = 0; + user_data->number_of_keys= keys_in_list; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Run the callback on each 802.11 preference */ + prefs_pref_foreach(wlan_prefs, set_wep_key, (gpointer)user_data); + + /* Signal that we've changed things, and run the 802.11 dissector's + * callback */ + wlan_prefs->prefs_changed = TRUE; + + /* Apply changes for the specified preference */ + prefs_apply(wlan_prefs); + + /* FREE MEMORY */ + /* free the WEP key string */ + for(i=0;ilist);i++) + { + g_free(g_list_nth(user_data->list,i)->data); + } + + /* free the (empty) list */ + g_list_free(user_data->list); + + /* free the user_data structure */ + g_free(user_data); + + airpcap_if_info_free(fake_info_if); + + return keys_in_list; +} + +/* + * Function used to save to the preference file the Decryption Keys. + */ +static int +save_wlan_wireshark_wep_keys(GList* key_ls) +{ + GList* key_list = NULL; + guint keys_in_list,i; + keys_cb_data_t* user_data; + decryption_key_t* tmp_dk; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Allocate a structure used to keep infos between the callbacks */ + user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t)); + + keys_in_list = g_list_length(key_ls); + + key_list = key_ls; + + /* Fill the structure */ + user_data->list = key_list; + user_data->current_index = 0; + user_data->number_of_keys= keys_in_list; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Run the callback on each 802.11 preference */ + prefs_pref_foreach(wlan_prefs, set_wep_key, (gpointer)user_data); + + /* Signal that we've changed things, and run the 802.11 dissector's + * callback */ + wlan_prefs->prefs_changed = TRUE; + + /* Apply changes for the specified preference */ + prefs_apply(wlan_prefs); + + /* FREE MEMORY */ + /* free the WEP key string */ + for(i=0;ilist);i++) + { + tmp_dk = (decryption_key_t*)g_list_nth(user_data->list,i)->data; + g_string_free(tmp_dk->key,TRUE); + if (tmp_dk->ssid != NULL) g_byte_array_free(tmp_dk->ssid,TRUE); + } + + /* free the (empty) list */ + g_list_free(user_data->list); + + /* free the user_data structure */ + g_free(user_data); + + return keys_in_list; +} + +/* + * Returns the default airpcap interface of a list, NULL if list is empty + */ +airpcap_if_info_t* +airpcap_get_default_if(GList* airpcap_if_list_p) +{ + airpcap_if_info_t* if_info = NULL; + + if ((prefs.capture_device != NULL) && (*prefs.capture_device != '\0')) + { + if_info = get_airpcap_if_from_name(airpcap_if_list_p, + get_if_name(prefs.capture_device)); + } + return if_info; +} + +/* + * DECRYPTION KEYS FUNCTIONS + */ +#if 0 +/* + * This function is used for DEBUG POURPOSES ONLY!!! + */ +void +print_key_list(GList* key_list) +{ + gint n,i; + decryption_key_t* tmp; + + if (key_list == NULL) + { + g_print("\n\n******* KEY LIST NULL *******\n\n"); + return; + } + + n = g_list_length(key_list); + + g_print("\n\n********* KEY LIST **********\n\n"); + + g_print("NUMBER OF KEYS IN LIST : %d\n\n",n); + + for(i =0; i < n; i++) + { + g_print("[%d] :\n",i+1); + tmp = (decryption_key_t*)(g_list_nth_data(key_list,i)); + g_print("KEY : %s\n",tmp->key->str); + + g_print("BITS: %d\n",tmp->bits); + + if (tmp->type == AIRPDCAP_KEY_TYPE_WEP) + g_print("TYPE: %s\n",AIRPCAP_WEP_KEY_STRING); + else if (tmp->type == AIRPDCAP_KEY_TYPE_WPA_PWD) + g_print("TYPE: %s\n",AIRPCAP_WPA_PWD_KEY_STRING); + else if (tmp->type == AIRPDCAP_KEY_TYPE_WPA_PMK) + g_print("TYPE: %s\n",AIRPCAP_WPA_BIN_KEY_STRING); + else + g_print("TYPE: %s\n","???"); + + g_print("SSID: %s\n",(tmp->ssid != NULL) ? + format_text((guchar *)tmp->ssid->data, tmp->ssid->len) : "---"); + g_print("\n"); + } + + g_print("\n*****************************\n\n"); +} +#endif + +/* + * Retrieves a GList of decryption_key_t structures containing infos about the + * keys for the given adapter... returns NULL if no keys are found. + */ +GList * +get_airpcap_device_keys(airpcap_if_info_t* info_if) +{ + /* tmp vars */ + char* tmp_key = NULL; + guint i,keys_in_list = 0; + + /* real vars*/ + decryption_key_t *new_key = NULL; + GList *key_list = NULL; + + /* Number of keys in key list */ + if (info_if->keysCollectionSize != 0) + keys_in_list = AirpcapKeysCollectionSizeToKeyCount(info_if->keysCollectionSize); + else + keys_in_list = 0; + + for(i=0; ikeysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WEP) + { + /* allocate memory for the new key item */ + new_key = (decryption_key_t*)g_malloc(sizeof(decryption_key_t)); + + /* fill the fields */ + /* KEY */ + tmp_key = airpcap_get_key_string(info_if->keysCollection->Keys[i]); + new_key->key = g_string_new(tmp_key); + g_free(tmp_key); + + /* BITS */ + new_key->bits = (guint) new_key->key->len *4; /* every char is 4 bits in WEP keys (it is an hexadecimal number) */ + + /* SSID not used in WEP keys */ + new_key->ssid = NULL; + + /* TYPE (WEP in this case) */ + new_key->type = info_if->keysCollection->Keys[i].KeyType; + + /* Append the new element in the list */ + key_list = g_list_append(key_list,(gpointer)new_key); + } + else if (info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD) + { + /* XXX - Not supported yet */ + } + else if (info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PMK) + { + /* XXX - Not supported yet */ + } + } + + return key_list; +} + +/* + * Retrieves a GList of decryption_key_t structures containing infos about the + * keys for the global AirPcap driver... returns NULL if no keys are found. + */ +GList * +get_airpcap_driver_keys(void) +{ + /* tmp vars */ + char *tmp_key = NULL; + guint i,keys_in_list = 0; + + /* real vars*/ + decryption_key_t *new_key = NULL; + GList *key_list = NULL; + + /* + * To read the drivers general settings we need to create and use one airpcap adapter... + * The only way to do that is to instantiate a fake adapter, and then close it and delete it. + */ + airpcap_if_info_t* fake_info_if = NULL; + + /* Create the fake_info_if from the first adapter of the list */ + fake_info_if = airpcap_driver_fake_if_info_new(); + + if (fake_info_if == NULL) + return NULL; + + /* Number of keys in key list */ + if (fake_info_if->keysCollectionSize != 0) + keys_in_list = AirpcapKeysCollectionSizeToKeyCount(fake_info_if->keysCollectionSize); + else + keys_in_list = 0; + + for(i=0; ikeysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WEP) + { + /* allocate memory for the new key item */ + new_key = (decryption_key_t*)g_malloc(sizeof(decryption_key_t)); + + /* fill the fields */ + /* KEY */ + tmp_key = airpcap_get_key_string(fake_info_if->keysCollection->Keys[i]); + new_key->key = g_string_new(tmp_key); + if (tmp_key != NULL) g_free(tmp_key); + + /* BITS */ + new_key->bits = (guint) new_key->key->len *4; /* every char is 4 bits in WEP keys (it is an hexadecimal number) */ + + /* SSID not used in WEP keys */ + new_key->ssid = NULL; + + /* TYPE (WEP in this case) */ + new_key->type = fake_info_if->keysCollection->Keys[i].KeyType; + + /* Append the new element in the list */ + key_list = g_list_append(key_list,(gpointer)new_key); + } + else if (fake_info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD) + { + /* XXX - Not supported yet */ + } + else if (fake_info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PMK) + { + /* XXX - Not supported yet */ + } + } + + airpcap_if_info_free(fake_info_if); + + return key_list; +} + +/* + * Returns the list of the decryption keys specified for wireshark, NULL if + * no key is found + */ +GList * +get_wireshark_keys(void) +{ + keys_cb_data_t *wep_user_data = NULL; + + GList *final_list = NULL; + GList *wep_final_list = NULL; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Allocate a structure used to keep infos between the callbacks */ + wep_user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t)); + + /* Fill the structure */ + wep_user_data->list = NULL; + wep_user_data->current_index = 0; + wep_user_data->number_of_keys= 0; /* Still unknown */ + + /* Run the callback on each 802.11 preference */ + /* XXX - Right now, only WEP keys will be loaded */ + prefs_pref_foreach(wlan_prefs, get_wep_key, (gpointer)wep_user_data); + + /* Copy the list field in the user data structure pointer into the final_list */ + wep_final_list = wep_user_data->list; + + /* XXX - Merge the three lists!!!!! */ + final_list = wep_final_list; + + /* free the wep_user_data structure */ + g_free(wep_user_data); + + return final_list; +} + + +static guint +test_if_on(pref_t *pref, gpointer ud) +{ + gboolean *is_on; + gboolean number; + + /* Retrieve user data info */ + is_on = (gboolean*)ud; + + + if (g_ascii_strncasecmp(pref->name, "enable_decryption", 17) == 0 && pref->type == PREF_BOOL) + { + number = *pref->varp.boolp; + + if (number) *is_on = TRUE; + else *is_on = FALSE; + + return 1; + } + return 0; +} + +/* + * Merges two lists of keys and return a newly created GList. If a key is + * found multiple times, it will just appear once! + * list1 and list 2 pointer will have to be freed manually if needed!!! + * If the total number of keys exceeeds the maximum number allowed, + * exceeding keys will be discarded... + */ +GList * +merge_key_list(GList* list1, GList* list2) +{ + guint n1=0,n2=0; + guint i; + decryption_key_t *dk1=NULL, + *dk2=NULL, + *new_dk=NULL; + + GList* merged_list = NULL; + + if ( (list1 == NULL) && (list2 == NULL) ) + return NULL; + + if (list1 == NULL) + { + n2 = g_list_length(list2); + + for(i=0;ibits = dk2->bits; + new_dk->type = dk2->type; + new_dk->key = g_string_new(dk2->key->str); + new_dk->ssid = byte_array_dup(dk2->ssid); + + /* Check the total length of the merged list */ + if (g_list_length(merged_list) < MAX_ENCRYPTION_KEYS) + merged_list = g_list_append(merged_list,(gpointer)new_dk); + } + } + else if (list2 == NULL) + { + n1 = g_list_length(list1); + + for(i=0;ibits = dk1->bits; + new_dk->type = dk1->type; + new_dk->key = g_string_new(dk1->key->str); + new_dk->ssid = byte_array_dup(dk1->ssid); + + /* Check the total length of the merged list */ + if (g_list_length(merged_list) < MAX_ENCRYPTION_KEYS) + merged_list = g_list_append(merged_list,(gpointer)new_dk); + } + } + else + { + n1 = g_list_length(list1); + n2 = g_list_length(list2); + + /* Copy the whole list1 into merged_list */ + for(i=0;ibits = dk1->bits; + new_dk->type = dk1->type; + new_dk->key = g_string_new(dk1->key->str); + new_dk->ssid = byte_array_dup(dk1->ssid); + + /* Check the total length of the merged list */ + if (g_list_length(merged_list) < MAX_ENCRYPTION_KEYS) + merged_list = g_list_append(merged_list,(gpointer)new_dk); + } + + /* Look for keys that are present in list2 but aren't in list1 yet... + * Add them to merged_list + */ + for(i=0;ibits = dk2->bits; + new_dk->type = dk2->type; + new_dk->key = g_string_new(dk2->key->str); + new_dk->ssid = byte_array_dup(dk2->ssid); + + /* Check the total length of the merged list */ + if (g_list_length(merged_list) < MAX_ENCRYPTION_KEYS) + merged_list = g_list_append(merged_list,(gpointer)new_dk); + } + } + } + + return merged_list; +} + +/* + * Use this function to free a key list. + */ +void +free_key_list(GList *list) +{ + guint i,n; + decryption_key_t *curr_key; + + if (list == NULL) + return; + + n = g_list_length(list); + + for(i = 0; i < n; i++) + { + curr_key = (decryption_key_t*)g_list_nth_data(list,i); + + /* Free all the strings */ + if (curr_key->key != NULL) + g_string_free(curr_key->key, TRUE); + + if (curr_key->ssid != NULL) + g_byte_array_free(curr_key->ssid, TRUE); + + /* free the decryption_key_t structure*/ + g_free(curr_key); + curr_key = NULL; + } + + /* Free the list */ + g_list_free(list); + + return; +} + + +/* + * If the given key is contained in the list, returns TRUE. + * Returns FALSE otherwise. + */ +gboolean +key_is_in_list(decryption_key_t *dk,GList *list) +{ + guint i,n; + decryption_key_t *curr_key = NULL; + gboolean found = FALSE; + + if ( (list == NULL) || (dk == NULL) ) + return FALSE; + + n = g_list_length(list); + + if (n < 1) + return FALSE; + + for(i = 0; i < n; i++) + { + curr_key = (decryption_key_t*)g_list_nth_data(list,i); + if (keys_are_equals(dk,curr_key)) + found = TRUE; + } + + return found; +} + +/* + * Returns TRUE if keys are equals, FALSE otherwise + */ +gboolean +keys_are_equals(decryption_key_t *k1,decryption_key_t *k2) +{ + + if ((k1==NULL) || (k2==NULL)) + return FALSE; + + /* XXX - Remove this check when we will have the WPA/WPA2 decryption in the Driver! */ + /** if ( (k1->type == AIRPDCAP_KEY_TYPE_WPA_PWD) || (k2->type == AIRPDCAP_KEY_TYPE_WPA_PWD) || (k1->type == AIRPDCAP_KEY_TYPE_WPA_PMK) || (k2->type == AIRPDCAP_KEY_TYPE_WPA_PMK) ) **/ + /** return TRUE; **/ + + if (g_string_equal(k1->key,k2->key) && + (k1->bits == k2->bits) && /* If the previous is TRUE, this must be TRUE as well */ + (k1->type == k2->type)) + { + /* Check the ssid... if the key type is WEP, the two fields should be NULL */ + if ((k1->ssid == NULL) && (k2->ssid == NULL)) + return TRUE; + + /* If they are not null, they must share the same ssid */ + return byte_array_equal(k1->ssid,k2->ssid); + } + + /* Some field is not equal ... */ + return FALSE; +} + +/* + * Tests if two collection of keys are equal or not, to be considered equals, they have to + * contain the same keys in the SAME ORDER! (If both lists are NULL, which means empty will + * return TRUE) + */ +gboolean +key_lists_are_equal(GList* list1, GList* list2) +{ + guint n1 = 0,n2=0; + /* XXX - Remove */ + guint wep_n1 = 0,wep_n2=0; + GList *wep_list1 = NULL; + GList *wep_list2 = NULL; + /* XXX - END*/ + guint i/*,j*/; + decryption_key_t *dk1=NULL,*dk2=NULL; + + n1 = g_list_length(list1); + n2 = g_list_length(list2); + + /* + * XXX - START : Retrieve the aublists of WEP keys!!! This is needed only 'till Driver WPA decryption + * is implemented. + */ + for(i=0;itype == AIRPDCAP_KEY_TYPE_WEP) + { + wep_list1 = g_list_append(wep_list1,(gpointer)dk1); + wep_n1++; + } + } + for(i=0;itype == AIRPDCAP_KEY_TYPE_WEP) + { + wep_list2 = g_list_append(wep_list2,(gpointer)dk2); + wep_n2++; + } + } + + /* + * XXX - END : Remove from START to END when the WPA/WPA2 decryption will be implemented in + * the Driver + */ + + /* + * Commented, because in the new AirPcap version all the keys will be saved + * into the driver, and all the keys for every specific adapter will be + * removed. This means that this check will always fail... and the user will + * always be asked what to do... and it doesn't make much sense. + */ + /* if (n1 != n2) return FALSE; */ + if (wep_n1 != wep_n2) return FALSE; + + n2 = wep_n2; + + /*for(i=0;ikey,dk2->key)) return FALSE; + }*/ + for(i=0;iDecryptionOn == AIRPCAP_DECRYPTION_ON) + is_on = TRUE; + else if (fake_if_info->DecryptionOn == AIRPCAP_DECRYPTION_OFF) + is_on = FALSE; + } + + airpcap_if_info_free(fake_if_info); + + return is_on; +} + +static guint +set_on_off(pref_t *pref, gpointer ud) +{ + gboolean *is_on; + + /* Retrieve user data info */ + is_on = (gboolean*)ud; + + if (g_ascii_strncasecmp(pref->name, "enable_decryption", 17) == 0 && pref->type == PREF_BOOL) + { + + if (*is_on) + *pref->varp.boolp = TRUE; + else + *pref->varp.boolp = FALSE; + + return 1; + } + return 0; +} + +/* + * Enables decryption for Wireshark if on_off is TRUE, disables it otherwise. + */ +void +set_wireshark_decryption(gboolean on_off) +{ + gboolean is_on; + + is_on = on_off; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Run the callback on each 802.11 preference */ + prefs_pref_foreach(wlan_prefs, set_on_off, (gpointer)&is_on); + + /* + * Signal that we've changed things, and run the 802.11 dissector's + * callback + */ + wlan_prefs->prefs_changed = TRUE; + + prefs_apply(wlan_prefs); +} + +/* + * Enables decryption for all the adapters if on_off is TRUE, disables it otherwise. + */ +gboolean +set_airpcap_decryption(gboolean on_off) +{ + /* We need to directly access the .dll functions here... */ + gchar ebuf[AIRPCAP_ERRBUF_SIZE]; + PAirpcapHandle ad,ad_driver; + + gboolean success = TRUE; + + gint n = 0; + gint i = 0; + airpcap_if_info_t* curr_if = NULL; + airpcap_if_info_t* fake_if_info = NULL; + + fake_if_info = airpcap_driver_fake_if_info_new(); + + if (fake_if_info == NULL) + /* We apparently don't have any adapters installed. + * This isn't a failure, so return TRUE + */ + return TRUE; + + /* Set the driver decryption */ + ad_driver = airpcap_if_open(fake_if_info->name, ebuf); + if (ad_driver) + { + if (on_off) + airpcap_if_set_driver_decryption_state(ad_driver,AIRPCAP_DECRYPTION_ON); + else + airpcap_if_set_driver_decryption_state(ad_driver,AIRPCAP_DECRYPTION_OFF); + + airpcap_if_close(ad_driver); + } + + airpcap_if_info_free(fake_if_info); + + n = g_list_length(airpcap_if_list); + + /* Set to FALSE the decryption for all the adapters */ + /* Apply this change to all the adapters !!! */ + for(i = 0; i < n; i++) + { + curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i); + + if (curr_if != NULL) + { + ad = airpcap_if_open(curr_if->name, ebuf); + if (ad) + { + curr_if->DecryptionOn = AIRPCAP_DECRYPTION_OFF; + airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn); + /* Save configuration for the curr_if */ + if (!airpcap_if_store_cur_config_as_adapter_default(ad)) + { + success = FALSE; + } + airpcap_if_close(ad); + } + } + } + + return success; +} + + + /* * Add a key (string) to the given list */ diff --git a/ui/gtk/airpcap_gui_utils.h b/ui/gtk/airpcap_gui_utils.h index 3238312edf..d5cd0a0632 100644 --- a/ui/gtk/airpcap_gui_utils.h +++ b/ui/gtk/airpcap_gui_utils.h @@ -214,4 +214,92 @@ airpcap_save_decryption_keys(GList* key_list, GList* adapters_list); void airpcap_enable_toolbar_widgets(GtkWidget* w, gboolean en); +/* + * Returns the default airpcap interface of a list, NULL if list is empty + */ +airpcap_if_info_t* +airpcap_get_default_if(GList* airpcap_if_list); + +/* + * DECRYPTION KEYS FUNCTIONS + */ + +/* + * Retrieves a GList of decryption_key_t structures containing infos about the + * keys for the given adapter... returns NULL if no keys are found. + */ +GList* +get_airpcap_device_keys(airpcap_if_info_t* if_info); + +/* + * Retrieves a GList of decryption_key_t structures containing infos about the + * keys for the global AirPcap driver... returns NULL if no keys are found. + */ +GList* +get_airpcap_driver_keys(void); + +/* + * Returns the list of the decryption keys specified for wireshark, NULL if + * no key is found + */ +GList* +get_wireshark_keys(void); + +/* + * Tests if two collection of keys are equal or not, to be considered equals, they have to + * contain the same keys in the SAME ORDER! (If both lists are NULL, which means empty will + * return TRUE) + */ +gboolean +key_lists_are_equal(GList* list1, GList* list2); + +/* + * Merges two lists of keys. If a key is found multiple times, it will just appear once! + */ +GList* +merge_key_list(GList* list1, GList* list2); + +/* + * If the given key is contained in the list, returns TRUE. + * Returns FALSE otherwise. + */ +gboolean +key_is_in_list(decryption_key_t *dk,GList *list); + +/* + * Returns TRUE if keys are equals, FALSE otherwise + */ +gboolean +keys_are_equals(decryption_key_t *k1,decryption_key_t *k2); + +/* + * Use this function to free a key list. + */ +void +free_key_list(GList *list); + +/* + * Returns TRUE if the Wireshark decryption is active, FALSE otherwise + */ +gboolean +wireshark_decryption_on(void); + +/* + * Returns TRUE if the AirPcap decryption for the current adapter is active, FALSE otherwise + */ +gboolean +airpcap_decryption_on(void); + +/* + * Enables decryption for Wireshark if on_off is TRUE, disables it otherwise. + */ +void +set_wireshark_decryption(gboolean on_off); + +/* + * Enables decryption for all the adapters if on_off is TRUE, disables it otherwise. + */ +gboolean +set_airpcap_decryption(gboolean on_off); + #endif diff --git a/ui/gtk/main.c b/ui/gtk/main.c index 6b73413230..d0c3b47c9c 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c @@ -80,7 +80,6 @@ #include #include #include -#include #include #include #include @@ -96,6 +95,7 @@ #endif #include +#include #include /* general (not GTK specific) */ diff --git a/ui/gtk/main_airpcap_toolbar.c b/ui/gtk/main_airpcap_toolbar.c index 44cb20a57e..0f3f8374ee 100644 --- a/ui/gtk/main_airpcap_toolbar.c +++ b/ui/gtk/main_airpcap_toolbar.c @@ -32,7 +32,8 @@ #include "ui/gtk/old-gtk-compat.h" #include "epan/epan.h" -#include "epan/frequency-utils.h" + +#include "wsutil/frequency-utils.h" #include "ui/recent.h" #include "simple_dialog.h" -- cgit v1.2.3