forked from osmocom/wireshark
Add uri_str_to_bytes(), byte_array_dup(), and byte_array_equal()
functions to strutil. Use GByteArrays to store SSIDs for decryption, and let the user specify arbitrary byte strings using percent-encoded strings. We should probably add percent encoding for pass phrases as well, so you can escape the ":" character. Move the key struct key conversion utilities to airpdcap.c, and remove duplicate code from packet-ieee80211.c. Fix a lot of indentation. svn path=/trunk/; revision=20388
This commit is contained in:
parent
5223c8dfa6
commit
983f496f69
2320
airpcap_loader.c
2320
airpcap_loader.c
File diff suppressed because it is too large
Load Diff
|
@ -530,17 +530,4 @@ get_compiled_airpcap_version(GString *str);
|
|||
void
|
||||
get_runtime_airpcap_version(GString *str);
|
||||
|
||||
/*
|
||||
* Returns the decryption_key_t struct given a string describing the key.
|
||||
* Returns NULL if the key_string cannot be parsed.
|
||||
*/
|
||||
decryption_key_t*
|
||||
parse_key_string(gchar* key_string);
|
||||
|
||||
/*
|
||||
* Returns a newly allocated string representing the given decryption_key_t struct
|
||||
*/
|
||||
gchar*
|
||||
get_key_string(decryption_key_t* dk);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <epan/tvbuff.h>
|
||||
#include <epan/crc32.h>
|
||||
#include <epan/strutil.h>
|
||||
|
||||
#include "airpdcap_system.h"
|
||||
#include "airpdcap_int.h"
|
||||
|
@ -12,6 +13,8 @@
|
|||
|
||||
#include "airpdcap_debug.h"
|
||||
|
||||
#include "wep-wpadefs.h"
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -1282,6 +1285,373 @@ INT AirPDcapRsnaPwd2Psk(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the decryption_key_t struct given a string describing the key.
|
||||
* Returns NULL if the key_string cannot be parsed.
|
||||
*/
|
||||
decryption_key_t*
|
||||
parse_key_string(gchar* input_string)
|
||||
{
|
||||
gchar *type;
|
||||
gchar *key;
|
||||
gchar *ssid;
|
||||
|
||||
GString *key_string = NULL;
|
||||
GByteArray *ssid_ba = NULL;
|
||||
|
||||
gchar **tokens;
|
||||
guint n = 0;
|
||||
guint i;
|
||||
|
||||
decryption_key_t *dk;
|
||||
|
||||
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
|
||||
* returned...).
|
||||
*/
|
||||
tokens = g_strsplit(input_string,":",0);
|
||||
|
||||
/* Tokens is a null termiated array of strings ... */
|
||||
while(tokens[n] != NULL)
|
||||
n++;
|
||||
|
||||
if(n == 0)
|
||||
{
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 'n' contains the number of tokens. If the key string is correct,
|
||||
* we should have 2 or 3 tokens... If we have 1 token, it can be an
|
||||
* 'old style' WEP key. Check for it.
|
||||
*/
|
||||
if(n == 1)
|
||||
{
|
||||
/* Maybe it is an 'old style' WEP key */
|
||||
key = g_strdup(tokens[0]);
|
||||
|
||||
/* Create a new string */
|
||||
key_string = g_string_new(key);
|
||||
|
||||
/* Check if it is a correct WEP key */
|
||||
if( ((key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WEP_KEY_MIN_CHAR_SIZE))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((key_string->len % 2) != 0)
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < key_string->len; i++)
|
||||
{
|
||||
if(!g_ascii_isxdigit(key_string->str[i]))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Key is correct! It was probably an 'old style' WEP key */
|
||||
/* Create the decryption_key_t structure, fill it and return it*/
|
||||
dk = g_malloc(sizeof(decryption_key_t));
|
||||
|
||||
dk->type = AIRPDCAP_KEY_TYPE_WEP;
|
||||
dk->key = g_string_new(key);
|
||||
dk->bits = dk->key->len * 4;
|
||||
dk->ssid = NULL;
|
||||
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
|
||||
return dk;
|
||||
}
|
||||
|
||||
/* There were at least 2 tokens... copy the type value */
|
||||
type = g_strdup(tokens[0]);
|
||||
|
||||
/*
|
||||
* The second token is the key (right now it doesn't matter
|
||||
* if it is a passphrase or an hexadecimal one)
|
||||
*/
|
||||
key = g_strdup(tokens[1]);
|
||||
|
||||
/* Lower case the type */
|
||||
g_strdown(type);
|
||||
|
||||
/* Maybe there is a third token (an ssid, if everything else is ok) */
|
||||
if(n >= 3)
|
||||
{
|
||||
ssid = g_strdup(tokens[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ssid = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now the initial key string has been divided in two/three tokens.
|
||||
* Let's see which kind of key it is, and if it is the correct form
|
||||
*/
|
||||
if(g_strcasecmp(type,STRING_KEY_TYPE_WEP) == 0) /* WEP key */
|
||||
{
|
||||
/* Create a new string */
|
||||
key_string = g_string_new(key);
|
||||
|
||||
/* Check if it is a correct WEP key */
|
||||
if( ((key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WEP_KEY_MIN_CHAR_SIZE))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((key_string->len % 2) != 0)
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < key_string->len; i++)
|
||||
{
|
||||
if(!g_ascii_isxdigit(key_string->str[i]))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
|
||||
|
||||
dk->type = AIRPDCAP_KEY_TYPE_WEP;
|
||||
dk->key = g_string_new(key);
|
||||
dk->bits = dk->key->len * 4;
|
||||
dk->ssid = NULL;
|
||||
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return dk;
|
||||
}
|
||||
else if(g_strcasecmp(type,STRING_KEY_TYPE_WPA_PSK) == 0) /* WPA key */
|
||||
{
|
||||
/* Create a new string */
|
||||
key_string = g_string_new(key);
|
||||
|
||||
/* Two tokens means that the user should have entered a WPA-BIN key ... */
|
||||
if( ((key_string->len) != WPA_PSK_KEY_CHAR_SIZE))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
|
||||
g_free(type);
|
||||
g_free(key);
|
||||
/* No ssid has been created ... */
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < key_string->len; i++)
|
||||
{
|
||||
if(!g_ascii_isxdigit(key_string->str[i]))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
/* No ssid_string has been created ... */
|
||||
|
||||
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 = dk->key->len * 4;
|
||||
dk->ssid = NULL;
|
||||
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
g_free(type);
|
||||
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return dk;
|
||||
}
|
||||
else if(g_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 ... */
|
||||
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);
|
||||
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ssid != NULL) /* more than three 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 */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - Maybe we need some check on the characters? I'm not sure if only standard ASCII are ok...
|
||||
*/
|
||||
if(ssid_ba->len > WPA_SSID_MAX_CHAR_SIZE)
|
||||
{
|
||||
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 */
|
||||
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_PWD;
|
||||
dk->key = g_string_new(key);
|
||||
dk->bits = 256; /* This is the lenght of the array pf bytes that will be generated using key+ssid ...*/
|
||||
if(ssid != NULL)
|
||||
dk->ssid = byte_array_dup(ssid_ba);
|
||||
|
||||
g_string_free(key_string, TRUE);
|
||||
if (ssid_ba != NULL)
|
||||
g_byte_array_free(ssid_ba, TRUE);
|
||||
|
||||
g_free(type);
|
||||
g_free(key);
|
||||
if(ssid != NULL) g_free(ssid);
|
||||
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return dk;
|
||||
}
|
||||
|
||||
/* Something was wrong ... free everything */
|
||||
|
||||
g_free(type);
|
||||
g_free(key);
|
||||
if(ssid != NULL) g_free(ssid); /* It is not always present */
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a newly allocated string representing the given decryption_key_t
|
||||
* struct, or NULL if something is wrong...
|
||||
*/
|
||||
gchar*
|
||||
get_key_string(decryption_key_t* dk)
|
||||
{
|
||||
gchar* output_string = NULL;
|
||||
|
||||
if(dk == NULL)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE_AIRPDCAP
|
||||
if(dk->type == AIRPDCAP_KEY_TYPE_WEP)
|
||||
{
|
||||
if(dk->key == NULL) /* Should NOT happen at all... */
|
||||
return NULL;
|
||||
|
||||
output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WEP,dk->key->str);
|
||||
}
|
||||
else if(dk->type == AIRPDCAP_KEY_TYPE_WPA_PWD)
|
||||
{
|
||||
if(dk->key == NULL) /* Should NOT happen at all... */
|
||||
return NULL;
|
||||
|
||||
if(dk->ssid == NULL)
|
||||
output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WPA_PWD,dk->key->str);
|
||||
else
|
||||
output_string = g_strdup_printf("%s:%s:%s",
|
||||
STRING_KEY_TYPE_WPA_PWD,dk->key->str,
|
||||
format_text((guchar *)dk->ssid->data, dk->ssid->len);
|
||||
}
|
||||
else if(dk->type == AIRPDCAP_KEY_TYPE_WPA_PMK)
|
||||
{
|
||||
if(dk->key == NULL) /* Should NOT happen at all... */
|
||||
return NULL;
|
||||
|
||||
output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WPA_PSK,dk->key->str);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#else /* not HAVE_AIRPDCAP*/
|
||||
output_string = g_strdup(dk->key->str);
|
||||
#endif
|
||||
|
||||
return output_string;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -51,10 +51,10 @@
|
|||
* Struct to store info about a specific decryption key.
|
||||
*/
|
||||
typedef struct {
|
||||
GString *key;
|
||||
GString *ssid;
|
||||
guint bits;
|
||||
guint type;
|
||||
GString *key;
|
||||
GByteArray *ssid;
|
||||
guint bits;
|
||||
guint type;
|
||||
} decryption_key_t;
|
||||
|
||||
/**
|
||||
|
@ -159,9 +159,20 @@ typedef struct _AIRPDCAP_KEYS_COLLECTION {
|
|||
|
||||
/******************************************************************************/
|
||||
/* Function prototype declarations */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
|
||||
/*
|
||||
* Returns the decryption_key_t struct given a string describing the key.
|
||||
* Returns NULL if the key_string cannot be parsed.
|
||||
*/
|
||||
decryption_key_t*
|
||||
parse_key_string(gchar* key_string);
|
||||
|
||||
/*
|
||||
* Returns a newly allocated string representing the given decryption_key_t struct
|
||||
*/
|
||||
gchar*
|
||||
get_key_string(decryption_key_t* dk);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#endif /* _AIRPDCAP_USER_H */
|
||||
|
|
|
@ -5024,9 +5024,9 @@ proto_register_ieee80211 (void)
|
|||
g_string_sprintf(key_desc,
|
||||
"Key #%d string can be:"
|
||||
" <wep hexadecimal key>;"
|
||||
" WEP:<wep hexadecimal key>;"
|
||||
" WPA-PWD:<passphrase>[:<ssid>];"
|
||||
" WPA-PSK:<wpa hexadecimal key>", i + 1);
|
||||
" wep:<wep hexadecimal key>;"
|
||||
" wpa-pwd:<passphrase>[:<ssid>];"
|
||||
" wpa-psk:<wpa hexadecimal key>", i + 1);
|
||||
#else
|
||||
g_string_sprintf(key_name, "wep_key%d", i + 1);
|
||||
g_string_sprintf(key_title, "WEP key #%d", i + 1);
|
||||
|
@ -5169,321 +5169,11 @@ static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
|
|||
return decr_tvb;
|
||||
}
|
||||
|
||||
#ifdef HAVE_AIRPDCAP
|
||||
/*
|
||||
* Returns the decryption_key_t struct given a string describing the key.
|
||||
* Returns NULL if the key_string cannot be parsed.
|
||||
*/
|
||||
static decryption_key_t*
|
||||
parse_key(gchar* input_string)
|
||||
{
|
||||
gchar *type;
|
||||
gchar *key;
|
||||
gchar *ssid;
|
||||
|
||||
GString *key_string,
|
||||
*ssid_string;
|
||||
|
||||
gchar **tokens;
|
||||
guint n = 0;
|
||||
guint i;
|
||||
|
||||
decryption_key_t *dk;
|
||||
|
||||
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 returned...).
|
||||
*/
|
||||
tokens = g_strsplit(input_string,":",0);
|
||||
|
||||
/* Tokens is a null termiated array of strings ... */
|
||||
while(tokens[n] != NULL)
|
||||
n++;
|
||||
|
||||
if(n == 0)
|
||||
{
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 'n' contains the number of tokens. If the key string is correct, we should have
|
||||
* 2 or 3 tokens... If we have 1 token, it can be an 'old style' WEP key... check for it...
|
||||
*/
|
||||
if(n == 1)
|
||||
{
|
||||
/* Maybe it is an 'old style' WEP key */
|
||||
key = g_strdup(tokens[0]);
|
||||
|
||||
/* Create a new string */
|
||||
key_string = g_string_new(key);
|
||||
|
||||
/* Check if it is a correct WEP key */
|
||||
if( ((key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WEP_KEY_MIN_CHAR_SIZE))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((key_string->len % 2) != 0)
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < key_string->len; i++)
|
||||
{
|
||||
if(!g_ascii_isxdigit(key_string->str[i]))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Key is correct! It was probably an 'old style' WEP key */
|
||||
/* Create the decryption_key_t structure, fill it and return it*/
|
||||
dk = g_malloc(sizeof(decryption_key_t));
|
||||
|
||||
dk->type = AIRPDCAP_KEY_TYPE_WEP;
|
||||
dk->key = g_string_new(key);
|
||||
dk->bits = dk->key->len * 4;
|
||||
dk->ssid = NULL;
|
||||
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
|
||||
return dk;
|
||||
}
|
||||
|
||||
/* There were at least 2 tokens... copy the type value */
|
||||
type = g_strdup(tokens[0]);
|
||||
|
||||
/*
|
||||
* The second token is the key (right now it doesn't matter
|
||||
* if it is a passphrase or an hexadecimal one)
|
||||
*/
|
||||
key = g_strdup(tokens[1]);
|
||||
|
||||
/* Lower case... */
|
||||
g_strdown(type);
|
||||
|
||||
/* Maybe there is a third token (an ssid, if everything else is ok) */
|
||||
if(n >= 3)
|
||||
{
|
||||
ssid = g_strdup(tokens[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ssid = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now the initial key string has been divided in two/three tokens... let's see
|
||||
* which kind of key it is, and if it is the correct form
|
||||
*/
|
||||
if(g_strcasecmp(type,STRING_KEY_TYPE_WEP) == 0) /* WEP key */
|
||||
{
|
||||
/* Create a new string */
|
||||
key_string = g_string_new(key);
|
||||
|
||||
/* Check if it is a correct WEP key */
|
||||
if( ((key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WEP_KEY_MIN_CHAR_SIZE))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((key_string->len % 2) != 0)
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < key_string->len; i++)
|
||||
{
|
||||
if(!g_ascii_isxdigit(key_string->str[i]))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
|
||||
|
||||
dk->type = AIRPDCAP_KEY_TYPE_WEP;
|
||||
dk->key = g_string_new(key);
|
||||
dk->bits = dk->key->len * 4;
|
||||
dk->ssid = NULL;
|
||||
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return dk;
|
||||
}
|
||||
else if(g_strcasecmp(type,STRING_KEY_TYPE_WPA_PSK) == 0) /* WPA key */
|
||||
{
|
||||
/* Create a new string */
|
||||
key_string = g_string_new(key);
|
||||
|
||||
/* Two tokens means that the user should have entered a WPA-BIN key ... */
|
||||
if( ((key_string->len) != WPA_PSK_KEY_CHAR_SIZE))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
|
||||
g_free(type);
|
||||
g_free(key);
|
||||
/* No ssid has been created ... */
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < key_string->len; i++)
|
||||
{
|
||||
if(!g_ascii_isxdigit(key_string->str[i]))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
/* No ssid_string has been created ... */
|
||||
|
||||
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 = dk->key->len * 4;
|
||||
dk->ssid = NULL;
|
||||
|
||||
g_string_free(key_string, TRUE);
|
||||
g_free(key);
|
||||
g_free(type);
|
||||
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return dk;
|
||||
}
|
||||
else if(g_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_string = NULL;
|
||||
|
||||
|
||||
/* Three (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);
|
||||
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ssid != NULL) /* more than three tokens found, means that the user specified the ssid */
|
||||
{
|
||||
ssid_string = g_string_new(ssid);
|
||||
|
||||
/*
|
||||
* XXX - Maybe we need some check on the characters? I'm not sure if only standard ASCII are ok...
|
||||
*/
|
||||
if( ((ssid_string->len) > WPA_SSID_MAX_CHAR_SIZE) || ((ssid_string->len) < WPA_SSID_MIN_CHAR_SIZE))
|
||||
{
|
||||
g_string_free(key_string, TRUE);
|
||||
g_string_free(ssid_string, TRUE);
|
||||
|
||||
g_free(type);
|
||||
g_free(key);
|
||||
g_free(ssid);
|
||||
|
||||
/* 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_PWD;
|
||||
dk->key = g_string_new(key);
|
||||
dk->bits = 256; /* This is the lenght of the array pf bytes that will be generated using key+ssid ...*/
|
||||
if(ssid != NULL)
|
||||
dk->ssid = g_string_new(ssid);
|
||||
else
|
||||
dk->ssid = NULL;
|
||||
|
||||
g_string_free(key_string, TRUE);
|
||||
if(ssid_string != NULL) g_string_free(ssid_string, TRUE);
|
||||
|
||||
g_free(type);
|
||||
g_free(key);
|
||||
if(ssid != NULL) g_free(ssid);
|
||||
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
return dk;
|
||||
}
|
||||
|
||||
/* Something was wrong ... free everything */
|
||||
|
||||
g_free(type);
|
||||
g_free(key);
|
||||
if(ssid != NULL) g_free(ssid); /* It is not always present */
|
||||
/* Free the array of strings */
|
||||
g_strfreev(tokens);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AIRPDCAP
|
||||
static
|
||||
void set_airpdcap_keys()
|
||||
{
|
||||
guint n = 0;
|
||||
guint i = 0;
|
||||
guint nKeys = 0;
|
||||
AIRPDCAP_KEY_ITEM key;
|
||||
PAIRPDCAP_KEYS_COLLECTION keys;
|
||||
decryption_key_t* dk = NULL;
|
||||
|
@ -5498,7 +5188,7 @@ void set_airpdcap_keys()
|
|||
{
|
||||
tmpk = g_strdup(wep_keystr[i]);
|
||||
|
||||
dk = parse_key(tmpk);
|
||||
dk = parse_key_string(tmpk);
|
||||
|
||||
if(dk != NULL)
|
||||
{
|
||||
|
@ -5533,7 +5223,7 @@ void set_airpdcap_keys()
|
|||
{
|
||||
if(dk->ssid->len > 0)
|
||||
{
|
||||
memcpy(key.KeyData.Wpa.UserPwd.Ssid,dk->ssid->str,dk->ssid->len+1);
|
||||
memcpy(key.KeyData.Wpa.UserPwd.Ssid,dk->ssid->data,dk->ssid->len);
|
||||
key.KeyData.Wpa.UserPwd.SsidLen = dk->ssid->len;
|
||||
}
|
||||
else /* The GString is not NULL, but the 'ssid' name is just "\0" */
|
||||
|
|
|
@ -505,6 +505,67 @@ hex_str_to_bytes(const char *hex_str, GByteArray *bytes, gboolean force_separato
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn an RFC 3986 percent-encoded string into a byte array.
|
||||
* XXX - We don't check for reserved characters.
|
||||
*/
|
||||
#define HEX_DIGIT_BUF_LEN 3
|
||||
gboolean
|
||||
uri_str_to_bytes(const char *uri_str, GByteArray *bytes) {
|
||||
guint8 val;
|
||||
const char *p;
|
||||
char hex_digit[HEX_DIGIT_BUF_LEN];
|
||||
|
||||
g_byte_array_set_size(bytes, 0);
|
||||
if (! uri_str) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
p = uri_str;
|
||||
|
||||
while (*p) {
|
||||
if (! isascii(*p) || ! isprint(*p))
|
||||
return FALSE;
|
||||
if (*p == '%') {
|
||||
p++;
|
||||
g_strlcpy(hex_digit, p, HEX_DIGIT_BUF_LEN);
|
||||
if (strlen(hex_digit) != 2)
|
||||
return FALSE;
|
||||
if (! isxdigit(hex_digit[0]) || ! isxdigit(hex_digit[1]))
|
||||
return FALSE;
|
||||
val = (guint8) strtoul(hex_digit, NULL, 16);
|
||||
g_byte_array_append(bytes, &val, 1);
|
||||
p ++;
|
||||
} else {
|
||||
g_byte_array_append(bytes, (guint8 *) p, 1);
|
||||
}
|
||||
p++;
|
||||
|
||||
}
|
||||
g_warning("ba %s len: %d", format_text(bytes->data, bytes->len), bytes->len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of a GByteArray
|
||||
*
|
||||
* @param ba The byte array to be copied.
|
||||
* @return If ba exists, a freshly allocated copy. NULL otherwise.
|
||||
*
|
||||
* XXX - Should this be in strutil.c?
|
||||
*/
|
||||
GByteArray *
|
||||
byte_array_dup(GByteArray *ba) {
|
||||
GByteArray *new_ba;
|
||||
|
||||
if (!ba)
|
||||
return NULL;
|
||||
|
||||
new_ba = g_byte_array_new();
|
||||
g_byte_array_append(new_ba, ba->data, ba->len);
|
||||
return new_ba;
|
||||
}
|
||||
|
||||
#define SUBID_BUF_LEN 5
|
||||
gboolean
|
||||
oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
|
||||
|
@ -563,6 +624,31 @@ oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the contents of two GByteArrays
|
||||
*
|
||||
* @param ba1 A byte array
|
||||
* @param ba2 A byte array
|
||||
* @return If both arrays are non-NULL and their lengths are equal and
|
||||
* their contents are equal, returns TRUE. Otherwise, returns
|
||||
* FALSE.
|
||||
*
|
||||
* XXX - Should this be in strutil.c?
|
||||
*/
|
||||
gboolean
|
||||
byte_array_equal(GByteArray *ba1, GByteArray *ba2) {
|
||||
if (!ba1 || !ba2)
|
||||
return FALSE;
|
||||
|
||||
if (ba1->len != ba2->len)
|
||||
return FALSE;
|
||||
|
||||
if (memcmp(ba1->data, ba2->data, ba1->len) != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Return a XML escaped representation of the unescaped string.
|
||||
* The returned string must be freed when no longer in use. */
|
||||
|
|
|
@ -101,6 +101,15 @@ gchar* bytes_to_str_punct(const guint8 *bd, int bd_len, gchar punct);
|
|||
gboolean hex_str_to_bytes(const char *hex_str, GByteArray *bytes,
|
||||
gboolean force_separators);
|
||||
|
||||
/** Turn an RFC 3986 percent-encoded string into a byte array.
|
||||
*
|
||||
* @param uri_str The string of hex digits.
|
||||
* @param bytes The GByteArray that will receive the bytes. This
|
||||
* must be initialized by the caller.
|
||||
* @return True if the string was converted successfully
|
||||
*/
|
||||
gboolean uri_str_to_bytes(const char *uri_str, GByteArray *bytes);
|
||||
|
||||
/** Turn a OID string representation (dot notaion) into a byte array.
|
||||
*
|
||||
* @param oid_str The OID string (dot notaion).
|
||||
|
@ -110,6 +119,30 @@ gboolean hex_str_to_bytes(const char *hex_str, GByteArray *bytes,
|
|||
*/
|
||||
gboolean oid_str_to_bytes(const char *oid_str, GByteArray *bytes);
|
||||
|
||||
/**
|
||||
* Create a copy of a GByteArray
|
||||
*
|
||||
* @param ba The byte array to be copied.
|
||||
* @return If ba exists, a freshly allocated copy. NULL otherwise.
|
||||
*
|
||||
* XXX - Should this be in strutil.c?
|
||||
*/
|
||||
GByteArray *byte_array_dup(GByteArray *ba);
|
||||
|
||||
/**
|
||||
* Compare the contents of two GByteArrays
|
||||
*
|
||||
* @param ba1 A byte array
|
||||
* @param ba2 A byte array
|
||||
* @return If both arrays are non-NULL and their lengths are equal and
|
||||
* their contents are equal, returns TRUE. Otherwise, returns
|
||||
* FALSE.
|
||||
*
|
||||
* XXX - Should this be in strutil.c?
|
||||
*/
|
||||
gboolean byte_array_equal(GByteArray *ba1, GByteArray *ba2);
|
||||
|
||||
|
||||
/** Return a XML escaped representation of the unescaped string.
|
||||
* The returned string must be freed when no longer in use.
|
||||
*
|
||||
|
@ -118,7 +151,8 @@ gboolean oid_str_to_bytes(const char *oid_str, GByteArray *bytes);
|
|||
*/
|
||||
gchar* xml_escape(const gchar *unescaped);
|
||||
|
||||
/* Return the first occurrence of needle in haystack.
|
||||
/**
|
||||
* Return the first occurrence of needle in haystack.
|
||||
* Algorithm copied from GNU's glibc 2.3.2 memcmp()
|
||||
*
|
||||
* @param haystack The data to search
|
||||
|
|
Loading…
Reference in New Issue