wifi: handle WEP & WPA passphrases (bgo #513820) (rh #441070)

Instead of requiring applets to hash passphrases, just do it in NM instead.
This should fix confusion where people don't understand that they are seeing
their hashed passphrase.
This commit is contained in:
Dan Williams 2009-05-09 22:34:35 -04:00
parent eee3c4ceb2
commit 07cc26d5fc
15 changed files with 1259 additions and 159 deletions

View file

@ -438,6 +438,7 @@ src/named-manager/Makefile
src/vpn-manager/Makefile
src/dhcp-manager/Makefile
src/supplicant-manager/Makefile
src/supplicant-manager/tests/Makefile
src/ppp-manager/Makefile
src/dnsmasq-manager/Makefile
src/modem-manager/Makefile

View file

@ -240,6 +240,7 @@ global:
nm_setting_wireless_security_get_psk;
nm_setting_wireless_security_get_type;
nm_setting_wireless_security_get_wep_key;
nm_setting_wireless_security_get_wep_key_type;
nm_setting_wireless_security_get_wep_tx_keyidx;
nm_setting_wireless_security_new;
nm_setting_wireless_security_remove_group;

View file

@ -93,6 +93,7 @@ typedef struct {
char *wep_key3;
char *psk;
char *leap_password;
NMWepKeyType wep_key_type;
} NMSettingWirelessSecurityPrivate;
enum {
@ -110,6 +111,7 @@ enum {
PROP_WEP_KEY3,
PROP_PSK,
PROP_LEAP_PASSWORD,
PROP_WEP_KEY_TYPE,
LAST_PROP
};
@ -425,8 +427,16 @@ nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting)
return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->auth_alg;
}
NMWepKeyType
nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSecurity *setting)
{
g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0);
return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_key_type;
}
static gboolean
verify_wep_key (const char *key)
verify_wep_key (const char *key, NMWepKeyType wep_type)
{
int keylen, i;
@ -434,11 +444,24 @@ verify_wep_key (const char *key)
return FALSE;
keylen = strlen (key);
if (keylen != 10 && keylen != 26)
return FALSE;
if (wep_type == NM_WEP_KEY_TYPE_KEY || NM_WEP_KEY_TYPE_UNKNOWN) {
if (keylen == 10 || keylen == 26) {
/* Hex key */
for (i = 0; i < keylen; i++) {
if (!isxdigit (key[i]))
return FALSE;
}
} else if (keylen == 5 || keylen == 13) {
/* ASCII key */
for (i = 0; i < keylen; i++) {
if (!isascii (key[i]))
return FALSE;
}
} else
return FALSE;
for (i = 0; i < keylen; i++) {
if (!isxdigit (key[i]))
} else if (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE) {
if (!keylen || keylen > 64)
return FALSE;
}
@ -454,12 +477,15 @@ verify_wpa_psk (const char *psk)
return FALSE;
psklen = strlen (psk);
if (psklen != 64)
if (psklen < 8 || psklen > 64)
return FALSE;
for (i = 0; i < psklen; i++) {
if (!isxdigit (psk[i]))
return FALSE;
if (psklen == 64) {
/* Hex PSK */
for (i = 0; i < psklen; i++) {
if (!isxdigit (psk[i]))
return FALSE;
}
}
return TRUE;
@ -483,19 +509,19 @@ need_secrets (NMSetting *setting)
/* Static WEP */
if (strcmp (priv->key_mgmt, "none") == 0) {
if ((priv->wep_tx_keyidx == 0) && !verify_wep_key (priv->wep_key0)) {
if ((priv->wep_tx_keyidx == 0) && !verify_wep_key (priv->wep_key0, priv->wep_key_type)) {
g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
return secrets;
}
if ((priv->wep_tx_keyidx == 1) && !verify_wep_key (priv->wep_key1)) {
if ((priv->wep_tx_keyidx == 1) && !verify_wep_key (priv->wep_key1, priv->wep_key_type)) {
g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
return secrets;
}
if ((priv->wep_tx_keyidx == 2) && !verify_wep_key (priv->wep_key2)) {
if ((priv->wep_tx_keyidx == 2) && !verify_wep_key (priv->wep_key2, priv->wep_key_type)) {
g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
return secrets;
}
if ((priv->wep_tx_keyidx == 3) && !verify_wep_key (priv->wep_key3)) {
if ((priv->wep_tx_keyidx == 3) && !verify_wep_key (priv->wep_key3, priv->wep_key_type)) {
g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
return secrets;
}
@ -627,28 +653,36 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
return FALSE;
}
if (priv->wep_key0 && !strlen (priv->wep_key0)) {
if (priv->wep_key_type > NM_WEP_KEY_TYPE_LAST) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE);
return FALSE;
}
if (priv->wep_key0 && !verify_wep_key (priv->wep_key0, priv->wep_key_type)) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
return FALSE;
}
if (priv->wep_key1 && !strlen (priv->wep_key1)) {
if (priv->wep_key1 && !verify_wep_key (priv->wep_key1, priv->wep_key_type)) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
return FALSE;
}
if (priv->wep_key2 && !strlen (priv->wep_key2)) {
if (priv->wep_key2 && !verify_wep_key (priv->wep_key2, priv->wep_key_type)) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
return FALSE;
}
if (priv->wep_key3 && !strlen (priv->wep_key3)) {
if (priv->wep_key3 && !verify_wep_key (priv->wep_key3, priv->wep_key_type)) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
@ -664,7 +698,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
return FALSE;
}
if (priv->psk && !strlen (priv->psk)) {
if (priv->psk && !verify_wpa_psk (priv->psk)) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
@ -825,6 +859,9 @@ set_property (GObject *object, guint prop_id,
g_free (priv->leap_password);
priv->leap_password = g_value_dup_string (value);
break;
case PROP_WEP_KEY_TYPE:
priv->wep_key_type = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -878,6 +915,9 @@ get_property (GObject *object, guint prop_id,
case PROP_LEAP_PASSWORD:
g_value_set_string (value, priv->leap_password);
break;
case PROP_WEP_KEY_TYPE:
g_value_set_uint (value, priv->wep_key_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1004,4 +1044,14 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting
"LEAP Password",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
g_object_class_install_property
(object_class, PROP_WEP_KEY_TYPE,
g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE,
"WEP Key Type",
"WEP Key Type",
NM_WEP_KEY_TYPE_UNKNOWN,
NM_WEP_KEY_TYPE_LAST,
NM_WEP_KEY_TYPE_UNKNOWN,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
}

View file

@ -56,6 +56,14 @@ GType nm_setting_wireless_security_error_get_type (void);
#define NM_SETTING_WIRELESS_SECURITY_ERROR nm_setting_wireless_security_error_quark ()
GQuark nm_setting_wireless_security_error_quark (void);
typedef enum {
NM_WEP_KEY_TYPE_UNKNOWN = 0,
NM_WEP_KEY_TYPE_KEY = 1, /* Hex or ASCII */
NM_WEP_KEY_TYPE_PASSPHRASE = 2, /* 104/128-bit Passphrase */
NM_WEP_KEY_TYPE_LAST = NM_WEP_KEY_TYPE_PASSPHRASE
} NMWepKeyType;
#define NM_SETTING_WIRELESS_SECURITY_KEY_MGMT "key-mgmt"
#define NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX "wep-tx-keyidx"
#define NM_SETTING_WIRELESS_SECURITY_AUTH_ALG "auth-alg"
@ -69,6 +77,7 @@ GQuark nm_setting_wireless_security_error_quark (void);
#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY3 "wep-key3"
#define NM_SETTING_WIRELESS_SECURITY_PSK "psk"
#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD "leap-password"
#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE "wep-key-type"
typedef struct {
NMSetting parent;
@ -111,6 +120,7 @@ const char *nm_setting_wireless_security_get_wep_key (NMSettingWirelessSec
void nm_setting_wireless_security_set_wep_key (NMSettingWirelessSecurity *setting, guint32 idx, const char *key);
guint32 nm_setting_wireless_security_get_wep_tx_keyidx (NMSettingWirelessSecurity *setting);
const char *nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting);
NMWepKeyType nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSecurity *setting);
G_END_DECLS

View file

@ -182,61 +182,6 @@ nm_utils_ip4_prefix_to_netmask (guint32 prefix)
return (guint32) htonl (netmask);
}
/* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */
static int hex2num (char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
static int hex2byte (const char *hex)
{
int a, b;
a = hex2num(*hex++);
if (a < 0)
return -1;
b = hex2num(*hex++);
if (b < 0)
return -1;
return (a << 4) | b;
}
char *
nm_utils_hexstr2bin (const char *hex,
size_t len)
{
size_t i;
int a;
const char * ipos = hex;
char * buf = NULL;
char * opos;
/* Length must be a multiple of 2 */
if ((len % 2) != 0)
return NULL;
opos = buf = g_malloc0 ((len / 2) + 1);
for (i = 0; i < len; i += 2) {
a = hex2byte (ipos);
if (a < 0) {
g_free (buf);
return NULL;
}
*opos++ = a;
ipos += 2;
}
return buf;
}
/* End from hostap */
char *
nm_ether_ntop (const struct ether_addr *mac)
{

View file

@ -37,8 +37,6 @@ int nm_spawn_process (const char *args);
void nm_print_device_capabilities (NMDevice *dev);
char *nm_utils_hexstr2bin (const char *hex, size_t len);
char *nm_ether_ntop (const struct ether_addr *mac);
void nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting);

View file

@ -2803,10 +2803,8 @@ build_supplicant_config (NMDeviceWifi *self,
goto error;
}
} else {
/* Unencrypted, wpa_supplicant needs key_mgmt=NONE here */
if (!nm_supplicant_config_add_option (config, "key_mgmt", "NONE", -1, FALSE)) {
nm_warning ("Couldn't add 802-11-wireless (no security) setting to"
" supplicant config.");
if (!nm_supplicant_config_add_no_security (config)) {
nm_warning ("Couldn't add unsecured option to supplicant config.");
goto error;
}
}

View file

@ -1,3 +1,5 @@
SUBDIRS=. tests
INCLUDES = \
-I${top_srcdir}/src \
-I${top_srcdir}/include \
@ -16,7 +18,9 @@ libsupplicant_manager_la_SOURCES = \
nm-supplicant-interface.c \
nm-supplicant-interface.h \
nm-supplicant-settings-verify.h \
nm-supplicant-settings-verify.c
nm-supplicant-settings-verify.c \
gnome-keyring-md5.h \
gnome-keyring-md5.c
libsupplicant_manager_la_CPPFLAGS = \
$(DBUS_CFLAGS) \

View file

@ -0,0 +1,291 @@
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* GnomeKeyringMD5Context structure, pass it to gnome_keyring_md5_init, call
* gnome_keyring_md5_update as needed on buffers full of bytes, and then call
* gnome_keyring_md5_final, which will fill a supplied 32-byte array with the
* digest in ascii form.
*
*/
#include "gnome-keyring-md5.h"
#include <string.h>
static void gnome_keyring_md5_transform (guint32 buf[4],
guint32 const in[16]);
void
gnome_keyring_md5_string (const char *string, unsigned char digest[16])
{
struct GnomeKeyringMD5Context md5_context;
gnome_keyring_md5_init (&md5_context);
gnome_keyring_md5_update (&md5_context, (const unsigned char *)string, strlen (string));
gnome_keyring_md5_final (digest, &md5_context);
}
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define byteReverse(buf, len) /* Nothing */
#else
/*
* Note: this code is harmless on little-endian machines.
*/
static void
byteReverse(unsigned char *buf, unsigned longs)
{
guint32 t;
do {
t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
((unsigned) buf[1] << 8 | buf[0]);
*(guint32 *) buf = t;
buf += 4;
} while (--longs);
}
#endif
char *
gnome_keyring_md5_digest_to_ascii (unsigned char digest[16])
{
static char hex_digits[] = "0123456789abcdef";
char *res;
int i;
res = g_malloc (33);
for (i = 0; i < 16; i++) {
res[2*i] = hex_digits[digest[i] >> 4];
res[2*i+1] = hex_digits[digest[i] & 0xf];
}
res[32] = 0;
return res;
}
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void
gnome_keyring_md5_init (struct GnomeKeyringMD5Context *ctx)
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
ctx->buf[3] = 0x10325476;
ctx->bits[0] = 0;
ctx->bits[1] = 0;
}
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void
gnome_keyring_md5_update (struct GnomeKeyringMD5Context *ctx,
unsigned char const *buf,
unsigned len)
{
guint32 t;
/* Update bitcount */
t = ctx->bits[0];
if ((ctx->bits[0] = t + ((guint32) len << 3)) < t)
ctx->bits[1]++; /* Carry from low to high */
ctx->bits[1] += len >> 29;
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
/* Handle any leading odd-sized chunks */
if (t) {
unsigned char *p = (unsigned char *) ctx->in + t;
t = 64 - t;
if (len < t) {
memcpy (p, buf, len);
return;
}
memcpy (p, buf, t);
byteReverse (ctx->in, 16);
gnome_keyring_md5_transform (ctx->buf, (guint32 *) ctx->in);
buf += t;
len -= t;
}
/* Process data in 64-byte chunks */
while (len >= 64) {
memcpy (ctx->in, buf, 64);
byteReverse (ctx->in, 16);
gnome_keyring_md5_transform (ctx->buf, (guint32 *) ctx->in);
buf += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(ctx->in, buf, len);
}
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
gnome_keyring_md5_final (unsigned char digest[16], struct GnomeKeyringMD5Context *ctx)
{
unsigned count;
unsigned char *p;
/* Compute number of bytes mod 64 */
count = (ctx->bits[0] >> 3) & 0x3F;
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
p = ctx->in + count;
*p++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;
/* Pad out to 56 mod 64 */
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
memset (p, 0, count);
byteReverse (ctx->in, 16);
gnome_keyring_md5_transform (ctx->buf, (guint32 *) ctx->in);
/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
} else {
/* Pad block to 56 bytes */
memset(p, 0, count - 8);
}
byteReverse(ctx->in, 14);
/* Append length in bits and transform */
((guint32 *) ctx->in)[14] = ctx->bits[0];
((guint32 *) ctx->in)[15] = ctx->bits[1];
gnome_keyring_md5_transform (ctx->buf, (guint32 *) ctx->in);
byteReverse ((unsigned char *) ctx->buf, 4);
memcpy (digest, ctx->buf, 16);
memset (ctx, 0, sizeof(ctx)); /* In case it's sensitive */
}
/* The four core functions - F1 is optimized somewhat */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1 (z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define gnome_keyring_md5_step(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. GnomeKeyringMD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
static void
gnome_keyring_md5_transform (guint32 buf[4], guint32 const in[16])
{
register guint32 a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
gnome_keyring_md5_step(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
gnome_keyring_md5_step(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
gnome_keyring_md5_step(F1, c, d, a, b, in[2] + 0x242070db, 17);
gnome_keyring_md5_step(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
gnome_keyring_md5_step(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
gnome_keyring_md5_step(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
gnome_keyring_md5_step(F1, c, d, a, b, in[6] + 0xa8304613, 17);
gnome_keyring_md5_step(F1, b, c, d, a, in[7] + 0xfd469501, 22);
gnome_keyring_md5_step(F1, a, b, c, d, in[8] + 0x698098d8, 7);
gnome_keyring_md5_step(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
gnome_keyring_md5_step(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
gnome_keyring_md5_step(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
gnome_keyring_md5_step(F1, a, b, c, d, in[12] + 0x6b901122, 7);
gnome_keyring_md5_step(F1, d, a, b, c, in[13] + 0xfd987193, 12);
gnome_keyring_md5_step(F1, c, d, a, b, in[14] + 0xa679438e, 17);
gnome_keyring_md5_step(F1, b, c, d, a, in[15] + 0x49b40821, 22);
gnome_keyring_md5_step(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
gnome_keyring_md5_step(F2, d, a, b, c, in[6] + 0xc040b340, 9);
gnome_keyring_md5_step(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
gnome_keyring_md5_step(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
gnome_keyring_md5_step(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
gnome_keyring_md5_step(F2, d, a, b, c, in[10] + 0x02441453, 9);
gnome_keyring_md5_step(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
gnome_keyring_md5_step(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
gnome_keyring_md5_step(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
gnome_keyring_md5_step(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
gnome_keyring_md5_step(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
gnome_keyring_md5_step(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
gnome_keyring_md5_step(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
gnome_keyring_md5_step(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
gnome_keyring_md5_step(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
gnome_keyring_md5_step(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
gnome_keyring_md5_step(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
gnome_keyring_md5_step(F3, d, a, b, c, in[8] + 0x8771f681, 11);
gnome_keyring_md5_step(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
gnome_keyring_md5_step(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
gnome_keyring_md5_step(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
gnome_keyring_md5_step(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
gnome_keyring_md5_step(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
gnome_keyring_md5_step(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
gnome_keyring_md5_step(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
gnome_keyring_md5_step(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
gnome_keyring_md5_step(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
gnome_keyring_md5_step(F3, b, c, d, a, in[6] + 0x04881d05, 23);
gnome_keyring_md5_step(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
gnome_keyring_md5_step(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
gnome_keyring_md5_step(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
gnome_keyring_md5_step(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
gnome_keyring_md5_step(F4, a, b, c, d, in[0] + 0xf4292244, 6);
gnome_keyring_md5_step(F4, d, a, b, c, in[7] + 0x432aff97, 10);
gnome_keyring_md5_step(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
gnome_keyring_md5_step(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
gnome_keyring_md5_step(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
gnome_keyring_md5_step(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
gnome_keyring_md5_step(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
gnome_keyring_md5_step(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
gnome_keyring_md5_step(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
gnome_keyring_md5_step(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
gnome_keyring_md5_step(F4, c, d, a, b, in[6] + 0xa3014314, 15);
gnome_keyring_md5_step(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
gnome_keyring_md5_step(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
gnome_keyring_md5_step(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
gnome_keyring_md5_step(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
gnome_keyring_md5_step(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}

View file

@ -0,0 +1,41 @@
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* GnomeKeyringMD5Context structure, pass it to gnome_keyring_md5_init, call
* gnome_keyring_md5_update as needed on buffers full of bytes, and then call
* gnome_keyring_md5_final, which will fill a supplied 32-byte array with the
* digest in ascii form.
*
*/
#ifndef GNOME_KEYRING_MD5_H
#define GNOME_KEYRING_MD5_H
#include <glib.h>
struct GnomeKeyringMD5Context {
guint32 buf[4];
guint32 bits[2];
unsigned char in[64];
};
char *gnome_keyring_md5_digest_to_ascii (unsigned char digest[16]);
void gnome_keyring_md5_string (const char *string,
unsigned char digest[16]);
void gnome_keyring_md5_init (struct GnomeKeyringMD5Context *ctx);
void gnome_keyring_md5_update (struct GnomeKeyringMD5Context *ctx,
unsigned char const *buf,
unsigned len);
void gnome_keyring_md5_final (unsigned char digest[16],
struct GnomeKeyringMD5Context *ctx);
#endif /* GNOME_KEYRING_MD5_H */

View file

@ -35,6 +35,10 @@
#include "nm-setting.h"
#include "NetworkManagerUtils.h"
#include "gnome-keyring-md5.h"
static char *hexstr2bin (const char *hex, size_t len);
#define NM_SUPPLICANT_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SUPPLICANT_CONFIG, \
NMSupplicantConfigPrivate))
@ -44,7 +48,7 @@ G_DEFINE_TYPE (NMSupplicantConfig, nm_supplicant_config, G_TYPE_OBJECT)
typedef struct {
char *value;
guint32 len;
enum OptType type;
OptType type;
} ConfigOption;
typedef struct
@ -80,8 +84,8 @@ nm_supplicant_config_init (NMSupplicantConfig * self)
NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
priv->config = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) config_option_free);
(GDestroyNotify) g_free,
(GDestroyNotify) config_option_free);
priv->blobs = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
@ -91,12 +95,13 @@ nm_supplicant_config_init (NMSupplicantConfig * self)
priv->dispose_has_run = FALSE;
}
gboolean
nm_supplicant_config_add_option (NMSupplicantConfig *self,
const char * key,
const char * value,
gint32 len,
gboolean secret)
static gboolean
nm_supplicant_config_add_option_with_type (NMSupplicantConfig *self,
const char *key,
const char *value,
gint32 len,
OptType opt_type,
gboolean secret)
{
NMSupplicantConfigPrivate *priv;
ConfigOption *old_opt;
@ -112,13 +117,17 @@ nm_supplicant_config_add_option (NMSupplicantConfig *self,
if (len < 0)
len = strlen (value);
type = nm_supplicant_settings_verify_setting (key, value, len);
if (type == TYPE_INVALID) {
char buf[255];
memset (&buf[0], 0, sizeof (buf));
memcpy (&buf[0], value, len > 254 ? 254 : len);
nm_debug ("Key '%s' and/or value '%s' invalid.", key, buf);
return FALSE;
if (opt_type != TYPE_INVALID)
type = opt_type;
else {
type = nm_supplicant_settings_verify_setting (key, value, len);
if (type == TYPE_INVALID) {
char buf[255];
memset (&buf[0], 0, sizeof (buf));
memcpy (&buf[0], value, len > 254 ? 254 : len);
nm_debug ("Key '%s' and/or value '%s' invalid.", key, buf);
return FALSE;
}
}
old_opt = (ConfigOption *) g_hash_table_lookup (priv->config, key);
@ -155,6 +164,15 @@ nm_info ("Config: added '%s' value '%s'", key, secret ? "<omitted>" : &buf[0]);
return TRUE;
}
static gboolean
nm_supplicant_config_add_option (NMSupplicantConfig *self,
const char *key,
const char *value,
gint32 len,
gboolean secret)
{
return nm_supplicant_config_add_option_with_type (self, key, value, len, TYPE_INVALID, secret);
}
static gboolean
nm_supplicant_config_add_blob (NMSupplicantConfig *self,
@ -283,6 +301,7 @@ get_hash_cb (gpointer key, gpointer value, gpointer user_data)
g_byte_array_free (array, TRUE);
break;
case TYPE_KEYWORD:
case TYPE_STRING:
g_value_init (variant, G_TYPE_STRING);
g_value_set_string (variant, opt->value);
break;
@ -306,17 +325,17 @@ destroy_hash_value (gpointer data)
GHashTable *
nm_supplicant_config_get_hash (NMSupplicantConfig * self)
{
NMSupplicantConfigPrivate *priv;
GHashTable *hash;
g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL);
hash = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
destroy_hash_value);
g_hash_table_foreach (NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->config,
get_hash_cb, hash);
(GDestroyNotify) g_free,
destroy_hash_value);
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
g_hash_table_foreach (priv->config, get_hash_cb, hash);
return hash;
}
@ -412,23 +431,26 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
return TRUE;
}
#define ADD_STRING_VAL(field, name, ucase, unhexify, secret) \
if (field) { \
int len = -1; \
if (ucase) \
value = g_ascii_strup (field, -1); \
else if (unhexify) { \
value = nm_utils_hexstr2bin (field, strlen (field)); \
len = strlen (field) / 2; \
} else \
value = g_strdup (field); \
success = nm_supplicant_config_add_option (self, name, value, len, secret); \
g_free (value); \
if (!success) { \
nm_warning ("Error adding %s to supplicant config.", name); \
return FALSE; \
} \
}
static gboolean
add_string_val (NMSupplicantConfig *self,
const char *field,
const char *name,
gboolean ucase,
gboolean secret)
{
gboolean success;
char *value;
if (!field)
return TRUE;
value = ucase ? g_ascii_strup (field, -1) : g_strdup (field);
success = nm_supplicant_config_add_option (self, name, value, strlen (field), secret);
if (!success)
nm_warning ("Error adding %s to supplicant config.", name);
g_free (value);
return success;
}
#define ADD_STRING_LIST_VAL(setting, setting_name, field, field_plural, name, ucase, secret) \
if (nm_setting_##setting_name##_get_num_##field_plural (setting)) { \
@ -444,7 +466,7 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
} \
} \
if (ucase) \
g_string_ascii_up (str); \
g_string_ascii_up (str); \
if (str->len) \
success = nm_supplicant_config_add_option (self, name, str->str, -1, secret); \
else \
@ -479,6 +501,75 @@ get_blob_id (const char *name, const char *seed_uid)
} \
}
static unsigned char *
wep128_passphrase_hash (const char *input, size_t input_len, size_t *out_len)
{
char md5_data[65];
unsigned char *digest;
int i;
*out_len = 16;
digest = g_malloc0 (*out_len);
/* Get at least 64 bytes */
for (i = 0; i < 64; i++)
md5_data[i] = input[i % input_len];
/* Null terminate md5 seed data and hash it */
md5_data[64] = 0;
gnome_keyring_md5_string (md5_data, digest);
return digest;
}
static gboolean
add_wep_key (NMSupplicantConfig *self,
const char *key,
const char *name,
NMWepKeyType wep_type)
{
char *value;
gboolean success;
size_t key_len = key ? strlen (key) : 0;
if (!key || !key_len)
return TRUE;
if ( (wep_type == NM_WEP_KEY_TYPE_UNKNOWN)
|| (wep_type == NM_WEP_KEY_TYPE_KEY)) {
if ((key_len == 10) || (key_len == 26)) {
value = hexstr2bin (key, strlen (key));
success = nm_supplicant_config_add_option (self, name, value, key_len / 2, TRUE);
g_free (value);
if (!success) {
nm_warning ("Error adding %s to supplicant config.", name);
return FALSE;
}
} else if ((key_len == 5) || (key_len == 13)) {
if (!nm_supplicant_config_add_option (self, name, key, key_len, TRUE)) {
nm_warning ("Error adding %s to supplicant config.", name);
return FALSE;
}
} else {
nm_warning ("Invalid WEP key '%s'", name);
return FALSE;
}
} else if (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE) {
char *digest;
size_t digest_len;
digest = (char *) wep128_passphrase_hash (key, key_len, &digest_len);
success = nm_supplicant_config_add_option (self, name, digest, 13, TRUE);
g_free (digest);
if (!success) {
nm_warning ("Error adding %s to supplicant config.", name);
return FALSE;
}
}
return TRUE;
}
gboolean
nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
NMSettingWirelessSecurity *setting,
@ -489,6 +580,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
char *value;
gboolean success;
const char *key_mgmt, *auth_alg;
const char *psk;
g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
g_return_val_if_fail (setting != NULL, FALSE);
@ -497,12 +589,42 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
key_mgmt = nm_setting_wireless_security_get_key_mgmt (setting);
ADD_STRING_VAL (key_mgmt, "key_mgmt", TRUE, FALSE, FALSE);
if (!add_string_val (self, key_mgmt, "key_mgmt", TRUE, FALSE))
return FALSE;
auth_alg = nm_setting_wireless_security_get_auth_alg (setting);
ADD_STRING_VAL (auth_alg, "auth_alg", TRUE, FALSE, FALSE);
if (!add_string_val (self, auth_alg, "auth_alg", TRUE, FALSE))
return FALSE;
ADD_STRING_VAL (nm_setting_wireless_security_get_psk (setting), "psk", FALSE, TRUE, TRUE);
psk = nm_setting_wireless_security_get_psk (setting);
if (psk) {
size_t psk_len = strlen (psk);
if (psk_len == 64) {
/* Hex PSK */
value = hexstr2bin (psk, psk_len);
success = nm_supplicant_config_add_option (self, "psk", value, psk_len / 2, TRUE);
g_free (value);
if (!success) {
nm_warning ("Error adding 'psk' to supplicant config.");
return FALSE;
}
} else if (psk_len >= 8 && psk_len < 63) {
/* Use TYPE_STRING here so that it gets pushed to the
* supplicant as a string, and therefore gets quoted,
* and therefore the supplicant will interpret it as a
* passphrase and not a hex key.
*/
if (!nm_supplicant_config_add_option_with_type (self, "psk", psk, -1, TYPE_STRING, TRUE)) {
nm_warning ("Error adding 'psk' to supplicant config.");
return FALSE;
}
} else {
/* Invalid PSK */
nm_warning ("Invalid PSK length %d: not between 8 and 63 characters inclusive.", psk_len);
return FALSE;
}
}
/* Only WPA-specific things when using WPA */
if ( !strcmp (key_mgmt, "wpa-none")
@ -515,15 +637,20 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
/* WEP keys if required */
if (!strcmp (key_mgmt, "none")) {
NMWepKeyType wep_type = nm_setting_wireless_security_get_wep_key_type (setting);
const char *wep0 = nm_setting_wireless_security_get_wep_key (setting, 0);
const char *wep1 = nm_setting_wireless_security_get_wep_key (setting, 1);
const char *wep2 = nm_setting_wireless_security_get_wep_key (setting, 2);
const char *wep3 = nm_setting_wireless_security_get_wep_key (setting, 3);
ADD_STRING_VAL (wep0, "wep_key0", FALSE, TRUE, TRUE);
ADD_STRING_VAL (wep1, "wep_key1", FALSE, TRUE, TRUE);
ADD_STRING_VAL (wep2, "wep_key2", FALSE, TRUE, TRUE);
ADD_STRING_VAL (wep3, "wep_key3", FALSE, TRUE, TRUE);
if (!add_wep_key (self, wep0, "wep_key0", wep_type))
return FALSE;
if (!add_wep_key (self, wep1, "wep_key1", wep_type))
return FALSE;
if (!add_wep_key (self, wep2, "wep_key2", wep_type))
return FALSE;
if (!add_wep_key (self, wep3, "wep_key3", wep_type))
return FALSE;
if (wep0 || wep1 || wep2 || wep3) {
value = g_strdup_printf ("%d", nm_setting_wireless_security_get_wep_tx_keyidx (setting));
@ -539,9 +666,18 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
if (auth_alg && !strcmp (auth_alg, "leap")) {
/* LEAP */
if (!strcmp (key_mgmt, "ieee8021x")) {
ADD_STRING_VAL (nm_setting_wireless_security_get_leap_username (setting), "identity", FALSE, FALSE, FALSE);
ADD_STRING_VAL (nm_setting_wireless_security_get_leap_password (setting), "password", FALSE, FALSE, TRUE);
ADD_STRING_VAL ("leap", "eap", TRUE, FALSE, FALSE);
const char *tmp;
tmp = nm_setting_wireless_security_get_leap_username (setting);
if (!add_string_val (self, tmp, "identity", FALSE, FALSE))
return FALSE;
tmp = nm_setting_wireless_security_get_leap_password (setting);
if (!add_string_val (self, tmp, "password", FALSE, TRUE))
return FALSE;
if (!add_string_val (self, "leap", "eap", TRUE, FALSE))
return FALSE;
} else {
return FALSE;
}
@ -565,8 +701,8 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
gboolean wired)
{
NMSupplicantConfigPrivate *priv;
char *value, *tmp;
const char *peapver;
char *tmp;
const char *peapver, *value;
gboolean success;
GString *phase1, *phase2;
const GByteArray *array;
@ -577,13 +713,19 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
ADD_STRING_VAL (nm_setting_802_1x_get_password (setting), "password", FALSE, FALSE, TRUE);
ADD_STRING_VAL (nm_setting_802_1x_get_pin (setting), "pin", FALSE, FALSE, TRUE);
value = nm_setting_802_1x_get_password (setting);
if (!add_string_val (self, value, "password", FALSE, TRUE))
return FALSE;
value = nm_setting_802_1x_get_pin (setting);
if (!add_string_val (self, value, "pin", FALSE, TRUE))
return FALSE;
if (wired) {
ADD_STRING_VAL ("IEEE8021X", "key_mgmt", TRUE, FALSE, FALSE);
if (!add_string_val (self, "IEEE8021X", "key_mgmt", FALSE, FALSE))
return FALSE;
/* Wired 802.1x must always use eapol_flags=0 */
ADD_STRING_VAL ("0", "eapol_flags", FALSE, FALSE, FALSE);
if (!add_string_val (self, "0", "eapol_flags", FALSE, FALSE))
return FALSE;
}
ADD_STRING_LIST_VAL (setting, 802_1x, eap_method, eap_methods, "eap", TRUE, FALSE);
@ -607,8 +749,12 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
g_string_append_printf (phase1, "peaplabel=%s", nm_setting_802_1x_get_phase1_peaplabel (setting));
}
if (phase1->len)
ADD_STRING_VAL (phase1->str, "phase1", FALSE, FALSE, FALSE);
if (phase1->len) {
if (!add_string_val (self, phase1->str, "phase1", FALSE, FALSE)) {
g_string_free (phase1, TRUE);
return FALSE;
}
}
g_string_free (phase1, TRUE);
phase2 = g_string_new (NULL);
@ -626,12 +772,17 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
g_free (tmp);
}
if (phase2->len)
ADD_STRING_VAL (phase2->str, "phase2", FALSE, FALSE, FALSE);
if (phase2->len) {
if (!add_string_val (self, phase2->str, "phase2", FALSE, FALSE)) {
g_string_free (phase2, TRUE);
return FALSE;
}
}
g_string_free (phase2, TRUE);
if (nm_setting_802_1x_get_system_ca_certs (setting)) {
ADD_STRING_VAL (SYSTEM_CA_PATH, "ca_path", FALSE, FALSE, FALSE);
if (!add_string_val (self, SYSTEM_CA_PATH, "ca_path", FALSE, FALSE))
return FALSE;
} else {
ADD_BLOB_VAL (nm_setting_802_1x_get_ca_cert (setting), "ca_cert", connection_uid);
}
@ -643,7 +794,9 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
switch (nm_setting_802_1x_get_private_key_type (setting)) {
case NM_SETTING_802_1X_CK_TYPE_PKCS12:
/* Only add the private key password for PKCS#12 keys */
ADD_STRING_VAL (nm_setting_802_1x_get_private_key_password (setting), "private_key_passwd", FALSE, FALSE, TRUE);
value = nm_setting_802_1x_get_private_key_password (setting);
if (!add_string_val (self, value, "private_key_passwd", FALSE, TRUE))
return FALSE;
break;
default:
/* Only add the client cert if the private key is not PKCS#12 */
@ -653,7 +806,8 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
}
if (nm_setting_802_1x_get_system_ca_certs (setting)) {
ADD_STRING_VAL (SYSTEM_CA_PATH, "ca_path2", FALSE, FALSE, FALSE);
if (!add_string_val (self, SYSTEM_CA_PATH, "ca_path2", FALSE, FALSE))
return FALSE;
} else {
ADD_BLOB_VAL (nm_setting_802_1x_get_phase2_ca_cert (setting), "ca_cert2", connection_uid);
}
@ -665,7 +819,9 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
switch (nm_setting_802_1x_get_phase2_private_key_type (setting)) {
case NM_SETTING_802_1X_CK_TYPE_PKCS12:
/* Only add the private key password for PKCS#12 keys */
ADD_STRING_VAL (nm_setting_802_1x_get_phase2_private_key_password (setting), "private_key2_passwd", FALSE, FALSE, TRUE);
value = nm_setting_802_1x_get_phase2_private_key_password (setting);
if (!add_string_val (self, value, "private_key2_passwd", FALSE, TRUE))
return FALSE;
break;
default:
/* Only add the client cert if the private key is not PKCS#12 */
@ -674,9 +830,72 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
}
}
ADD_STRING_VAL (nm_setting_802_1x_get_identity (setting), "identity", FALSE, FALSE, FALSE);
ADD_STRING_VAL (nm_setting_802_1x_get_anonymous_identity (setting), "anonymous_identity", FALSE, FALSE, FALSE);
value = nm_setting_802_1x_get_identity (setting);
if (!add_string_val (self, value, "identity", FALSE, FALSE))
return FALSE;
value = nm_setting_802_1x_get_anonymous_identity (setting);
if (!add_string_val (self, value, "anonymous_identity", FALSE, FALSE))
return FALSE;
return TRUE;
}
gboolean
nm_supplicant_config_add_no_security (NMSupplicantConfig *self)
{
return nm_supplicant_config_add_option (self, "key_mgmt", "NONE", -1, FALSE);
}
/* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */
static int hex2num (char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
static int hex2byte (const char *hex)
{
int a, b;
a = hex2num(*hex++);
if (a < 0)
return -1;
b = hex2num(*hex++);
if (b < 0)
return -1;
return (a << 4) | b;
}
static char *
hexstr2bin (const char *hex, size_t len)
{
size_t i;
int a;
const char * ipos = hex;
char * buf = NULL;
char * opos;
/* Length must be a multiple of 2 */
if ((len % 2) != 0)
return NULL;
opos = buf = g_malloc0 ((len / 2) + 1);
for (i = 0; i < len; i += 2) {
a = hex2byte (ipos);
if (a < 0) {
g_free (buf);
return NULL;
}
*opos++ = a;
ipos += 2;
}
return buf;
}
/* End from hostap */

View file

@ -50,25 +50,19 @@ typedef struct
GType nm_supplicant_config_get_type (void);
NMSupplicantConfig * nm_supplicant_config_new (void);
NMSupplicantConfig *nm_supplicant_config_new (void);
guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self);
guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig *self);
void nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self,
void nm_supplicant_config_set_ap_scan (NMSupplicantConfig *self,
guint32 ap_scan);
gboolean nm_supplicant_config_add_option (NMSupplicantConfig *self,
const char * key,
const char * value,
gint32 len,
gboolean secret);
GHashTable *nm_supplicant_config_get_hash (NMSupplicantConfig *self);
GHashTable *nm_supplicant_config_get_hash (NMSupplicantConfig * self);
GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig *self);
GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig * self);
gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
NMSettingWireless * setting,
gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig *self,
NMSettingWireless *setting,
gboolean is_broadcast,
guint32 adhoc_freq,
gboolean has_scan_capa_ssid);
@ -78,6 +72,8 @@ gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig
NMSetting8021x *setting_8021x,
const char *connection_uid);
gboolean nm_supplicant_config_add_no_security (NMSupplicantConfig *self);
gboolean nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
NMSetting8021x *setting,
const char *connection_uid,

View file

@ -25,7 +25,8 @@ typedef enum OptType {
TYPE_INVALID = 0,
TYPE_INT,
TYPE_BYTES,
TYPE_KEYWORD
TYPE_KEYWORD,
TYPE_STRING
} OptType;
OptType nm_supplicant_settings_verify_setting (const char * key,

View file

@ -0,0 +1,27 @@
INCLUDES = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-util \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/supplicant-manager
noinst_PROGRAMS = test-supplicant-config
test_supplicant_config_SOURCES = \
test-supplicant-config.c
test_supplicant_config_CPPFLAGS = \
$(GLIB_CFLAGS) \
$(DBUS_CFLAGS)
test_supplicant_config_LDADD = \
$(DBUS_LIBS) \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/src/supplicant-manager/libsupplicant-manager.la
if WITH_TESTS
check-local: test-supplicant-config
$(abs_builddir)/test-supplicant-config
endif

View file

@ -0,0 +1,518 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 - 2009 Red Hat, Inc.
*/
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <netinet/ether.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dbus/dbus-glib.h>
#include <nm-utils.h>
#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
#include <nm-setting-wireless.h>
#include <nm-setting-wireless-security.h>
#include <nm-setting-ip4-config.h>
#include <nm-setting-8021x.h>
#include "nm-test-helpers.h"
#include "nm-supplicant-config.h"
#include "nm-supplicant-settings-verify.h"
static gboolean
validate_opt (const char *detail,
GHashTable *hash,
const char *key,
OptType val_type,
gconstpointer expected,
size_t expected_len)
{
GValue *value;
gint int_val;
GByteArray *array;
const char *s;
const unsigned char *expected_array = expected;
int result;
ASSERT (hash != NULL, detail, "hash was NULL");
value = g_hash_table_lookup (hash, key);
ASSERT (value != NULL,
detail, "option '%s' expected but not found in config hash.");
switch (val_type) {
case TYPE_INT:
ASSERT (G_VALUE_HOLDS_INT (value),
detail, "config hash item '%s' was not TYPE_INT.", key);
int_val = g_value_get_int (value);
ASSERT (int_val == GPOINTER_TO_INT (expected),
detail, "unexpected config hash item '%s' value %d (expected %d)",
key, int_val, GPOINTER_TO_INT (expected));
break;
case TYPE_BYTES:
ASSERT (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY),
detail, "config hash item '%s' was not TYPE_BYTES.", key);
array = g_value_get_boxed (value);
ASSERT (array->len == expected_len,
detail, "unexpected config hash item '%s' length %d (expected %d)",
key, array->len, expected_len);
result = memcmp (array->data, expected_array, expected_len);
ASSERT (result == 0, detail, "unexpected config hash item '%s' value", key);
break;
case TYPE_KEYWORD:
case TYPE_STRING:
ASSERT (G_VALUE_HOLDS_STRING (value),
detail, "config hash item '%s' was not TYPE_STRING or TYPE_KEYWORD.", key);
if (expected_len == -1)
expected_len = strlen ((const char *) expected);
s = g_value_get_string (value);
ASSERT (s != NULL, detail, "unexpected NULL config hash string item '%s'.", key);
ASSERT (strlen (s) == expected_len,
detail, "unexpected config hash string item '%s' length %d (expected %d)",
key, strlen (s), expected_len);
result = strcmp (s, (const char *) expected);
ASSERT (result == 0,
detail, "unexpected config hash string item '%s' value '%s' (expected '%s')",
key, s, (const char *) expected);
break;
default:
g_warning ("unknown supplicant config hash item '%s' option type %d",
key, val_type);
return FALSE;
}
return TRUE;
}
static void
test_wifi_open (void)
{
NMConnection *connection;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
NMSettingIP4Config *s_ip4;
NMSupplicantConfig *config;
GHashTable *hash;
char *uuid;
gboolean success;
GError *error = NULL;
GByteArray *ssid;
const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 };
GByteArray *bssid;
const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
const char *bssid_str = "11:22:33:44:55:66";
connection = nm_connection_new ();
ASSERT (connection != NULL,
"wifi-open", "failed to allocate new connection");
/* Connection setting */
s_con = (NMSettingConnection *) nm_setting_connection_new ();
ASSERT (s_con != NULL,
"wifi-open", "failed to allocate new %s setting",
NM_SETTING_CONNECTION_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_con));
uuid = nm_utils_uuid_generate ();
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, "Test Wifi Open",
NM_SETTING_CONNECTION_UUID, uuid,
NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
NULL);
g_free (uuid);
/* Wifi setting */
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
ASSERT (s_wifi != NULL,
"wifi-open", "failed to allocate new %s setting",
NM_SETTING_WIRELESS_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
ssid = g_byte_array_sized_new (sizeof (ssid_data));
g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
bssid = g_byte_array_sized_new (sizeof (bssid_data));
g_byte_array_append (bssid, bssid_data, sizeof (bssid_data));
g_object_set (s_wifi,
NM_SETTING_WIRELESS_SSID, ssid,
NM_SETTING_WIRELESS_BSSID, bssid,
NM_SETTING_WIRELESS_MODE, "infrastructure",
NM_SETTING_WIRELESS_BAND, "bg",
NULL);
g_byte_array_free (ssid, TRUE);
g_byte_array_free (bssid, TRUE);
/* IP4 setting */
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
ASSERT (s_ip4 != NULL,
"wifi-open", "failed to allocate new %s setting",
NM_SETTING_IP4_CONFIG_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
ASSERT (nm_connection_verify (connection, &error) == TRUE,
"wifi-open", "failed to verify connection: %s",
(error && error->message) ? error->message : "(unknown)");
config = nm_supplicant_config_new ();
ASSERT (config != NULL,
"wifi-open", "failed to create new supplicant config");
success = nm_supplicant_config_add_setting_wireless (config, s_wifi, TRUE, 0, TRUE);
ASSERT (success == TRUE,
"wifi-open", "failed to add wireless setting to supplicant config.");
success = nm_supplicant_config_add_no_security (config);
ASSERT (success == TRUE,
"wifi-open", "failed to add wireless security to supplicant config.");
hash = nm_supplicant_config_get_hash (config);
ASSERT (hash != NULL,
"wifi-open", "failed to hash supplicant config options.");
validate_opt ("wifi-open", hash, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1);
validate_opt ("wifi-open", hash, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data));
validate_opt ("wifi-open", hash, "bssid", TYPE_KEYWORD, bssid_str, -1);
validate_opt ("wifi-open", hash, "key_mgmt", TYPE_KEYWORD, "NONE", -1);
g_object_unref (connection);
}
static void
test_wifi_wep_key (const char *detail,
NMWepKeyType wep_type,
const char *key_data,
const unsigned char *expected,
size_t expected_size)
{
NMConnection *connection;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
NMSettingIP4Config *s_ip4;
NMSupplicantConfig *config;
GHashTable *hash;
char *uuid;
gboolean success;
GError *error = NULL;
GByteArray *ssid;
const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 };
GByteArray *bssid;
const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
const char *bssid_str = "11:22:33:44:55:66";
connection = nm_connection_new ();
ASSERT (connection != NULL,
detail, "failed to allocate new connection");
/* Connection setting */
s_con = (NMSettingConnection *) nm_setting_connection_new ();
ASSERT (s_con != NULL,
detail, "failed to allocate new %s setting",
NM_SETTING_CONNECTION_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_con));
uuid = nm_utils_uuid_generate ();
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, "Test Wifi WEP Key",
NM_SETTING_CONNECTION_UUID, uuid,
NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
NULL);
g_free (uuid);
/* Wifi setting */
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
ASSERT (s_wifi != NULL,
detail, "failed to allocate new %s setting",
NM_SETTING_WIRELESS_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
ssid = g_byte_array_sized_new (sizeof (ssid_data));
g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
bssid = g_byte_array_sized_new (sizeof (bssid_data));
g_byte_array_append (bssid, bssid_data, sizeof (bssid_data));
g_object_set (s_wifi,
NM_SETTING_WIRELESS_SSID, ssid,
NM_SETTING_WIRELESS_BSSID, bssid,
NM_SETTING_WIRELESS_MODE, "infrastructure",
NM_SETTING_WIRELESS_BAND, "bg",
NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
NULL);
g_byte_array_free (ssid, TRUE);
g_byte_array_free (bssid, TRUE);
/* Wifi Security setting */
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
ASSERT (s_wsec != NULL,
detail, "failed to allocate new %s setting",
NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
g_object_set (s_wsec,
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, wep_type,
NULL);
nm_setting_wireless_security_set_wep_key (s_wsec, 0, key_data);
/* IP4 setting */
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
ASSERT (s_ip4 != NULL,
detail, "failed to allocate new %s setting",
NM_SETTING_IP4_CONFIG_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
ASSERT (nm_connection_verify (connection, &error) == TRUE,
detail, "failed to verify connection: %s",
(error && error->message) ? error->message : "(unknown)");
config = nm_supplicant_config_new ();
ASSERT (config != NULL,
detail, "failed to create new supplicant config");
success = nm_supplicant_config_add_setting_wireless (config, s_wifi, TRUE, 0, TRUE);
ASSERT (success == TRUE,
detail, "failed to add wireless setting to supplicant config.");
success = nm_supplicant_config_add_setting_wireless_security (config,
s_wsec,
NULL,
"376aced7-b28c-46be-9a62-fcdf072571da");
ASSERT (success == TRUE,
detail, "failed to add wireless security to supplicant config.");
hash = nm_supplicant_config_get_hash (config);
ASSERT (hash != NULL,
detail, "failed to hash supplicant config options.");
validate_opt (detail, hash, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1);
validate_opt (detail, hash, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data));
validate_opt (detail, hash, "bssid", TYPE_KEYWORD, bssid_str, -1);
validate_opt (detail, hash, "key_mgmt", TYPE_KEYWORD, "NONE", -1);
validate_opt (detail, hash, "wep_tx_keyidx", TYPE_INT, GINT_TO_POINTER (0), -1);
validate_opt (detail, hash, "wep_key0", TYPE_BYTES, expected, expected_size);
g_object_unref (connection);
}
static void
test_wifi_wep (void)
{
const char *key1 = "12345";
const unsigned char key1_expected[] = { 0x31, 0x32, 0x33, 0x34, 0x35 };
const char *key2 = "ascii test$$$";
const unsigned char key2_expected[] = { 0x61, 0x73, 0x63, 0x69, 0x69, 0x20, 0x74, 0x65, 0x73, 0x74, 0x24, 0x24, 0x24 };
const char *key3 = "abcdef1234";
const unsigned char key3_expected[] = { 0xab, 0xcd, 0xef, 0x12, 0x34 };
const char *key4 = "96aec785c6392675f87f592972";
const unsigned char key4_expected[] = { 0x96, 0xae, 0xc7, 0x85, 0xc6, 0x39, 0x26, 0x75, 0xf8, 0x7f, 0x59, 0x29, 0x72 };
const char *key5 = "r34lly l33t w3p p4ssphr4s3 for t3st1ng";
const unsigned char key5_expected[] = { 0xce, 0x68, 0x8b, 0x35, 0xf6, 0x0a, 0x2b, 0xbf, 0xc9, 0x8f, 0xed, 0x10, 0xda };
test_wifi_wep_key ("wifi-wep-ascii-40", NM_WEP_KEY_TYPE_KEY, key1, key1_expected, sizeof (key1_expected));
test_wifi_wep_key ("wifi-wep-ascii-104", NM_WEP_KEY_TYPE_KEY, key2, key2_expected, sizeof (key2_expected));
test_wifi_wep_key ("wifi-wep-hex-40", NM_WEP_KEY_TYPE_KEY, key3, key3_expected, sizeof (key3_expected));
test_wifi_wep_key ("wifi-wep-hex-104", NM_WEP_KEY_TYPE_KEY, key4, key4_expected, sizeof (key4_expected));
test_wifi_wep_key ("wifi-wep-passphrase-104", NM_WEP_KEY_TYPE_PASSPHRASE, key5, key5_expected, sizeof (key5_expected));
test_wifi_wep_key ("wifi-wep-old-hex-104", NM_WEP_KEY_TYPE_UNKNOWN, key4, key4_expected, sizeof (key4_expected));
}
static void
test_wifi_wpa_psk (const char *detail,
OptType key_type,
const char *key_data,
const unsigned char *expected,
size_t expected_size)
{
NMConnection *connection;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
NMSettingIP4Config *s_ip4;
NMSupplicantConfig *config;
GHashTable *hash;
char *uuid;
gboolean success;
GError *error = NULL;
GByteArray *ssid;
const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 };
GByteArray *bssid;
const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
const char *bssid_str = "11:22:33:44:55:66";
connection = nm_connection_new ();
ASSERT (connection != NULL,
detail, "failed to allocate new connection");
/* Connection setting */
s_con = (NMSettingConnection *) nm_setting_connection_new ();
ASSERT (s_con != NULL,
detail, "failed to allocate new %s setting",
NM_SETTING_CONNECTION_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_con));
uuid = nm_utils_uuid_generate ();
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, "Test Wifi WEP Key",
NM_SETTING_CONNECTION_UUID, uuid,
NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
NULL);
g_free (uuid);
/* Wifi setting */
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
ASSERT (s_wifi != NULL,
detail, "failed to allocate new %s setting",
NM_SETTING_WIRELESS_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
ssid = g_byte_array_sized_new (sizeof (ssid_data));
g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
bssid = g_byte_array_sized_new (sizeof (bssid_data));
g_byte_array_append (bssid, bssid_data, sizeof (bssid_data));
g_object_set (s_wifi,
NM_SETTING_WIRELESS_SSID, ssid,
NM_SETTING_WIRELESS_BSSID, bssid,
NM_SETTING_WIRELESS_MODE, "infrastructure",
NM_SETTING_WIRELESS_BAND, "bg",
NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
NULL);
g_byte_array_free (ssid, TRUE);
g_byte_array_free (bssid, TRUE);
/* Wifi Security setting */
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
ASSERT (s_wsec != NULL,
detail, "failed to allocate new %s setting",
NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
g_object_set (s_wsec,
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
NM_SETTING_WIRELESS_SECURITY_PSK, key_data,
NULL);
nm_setting_wireless_security_add_proto (s_wsec, "wpa");
nm_setting_wireless_security_add_proto (s_wsec, "rsn");
nm_setting_wireless_security_add_pairwise (s_wsec, "tkip");
nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp");
nm_setting_wireless_security_add_group (s_wsec, "tkip");
nm_setting_wireless_security_add_group (s_wsec, "ccmp");
/* IP4 setting */
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
ASSERT (s_ip4 != NULL,
detail, "failed to allocate new %s setting",
NM_SETTING_IP4_CONFIG_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
ASSERT (nm_connection_verify (connection, &error) == TRUE,
detail, "failed to verify connection: %s",
(error && error->message) ? error->message : "(unknown)");
config = nm_supplicant_config_new ();
ASSERT (config != NULL,
detail, "failed to create new supplicant config");
success = nm_supplicant_config_add_setting_wireless (config, s_wifi, TRUE, 0, TRUE);
ASSERT (success == TRUE,
detail, "failed to add wireless setting to supplicant config.");
success = nm_supplicant_config_add_setting_wireless_security (config,
s_wsec,
NULL,
"376aced7-b28c-46be-9a62-fcdf072571da");
ASSERT (success == TRUE,
detail, "failed to add wireless security to supplicant config.");
hash = nm_supplicant_config_get_hash (config);
ASSERT (hash != NULL,
detail, "failed to hash supplicant config options.");
validate_opt (detail, hash, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1);
validate_opt (detail, hash, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data));
validate_opt (detail, hash, "bssid", TYPE_KEYWORD, bssid_str, -1);
validate_opt (detail, hash, "key_mgmt", TYPE_KEYWORD, "WPA-PSK", -1);
validate_opt (detail, hash, "proto", TYPE_KEYWORD, "WPA RSN", -1);
validate_opt (detail, hash, "pairwise", TYPE_KEYWORD, "TKIP CCMP", -1);
validate_opt (detail, hash, "group", TYPE_KEYWORD, "TKIP CCMP", -1);
validate_opt (detail, hash, "psk", key_type, expected, expected_size);
g_object_unref (connection);
}
static void
test_wifi_wpa_psk_types (void)
{
const char *key1 = "d4721e911461d3cdef9793858e977fcda091779243abb7316c2f11605a160893";
const unsigned char key1_expected[] = { 0xd4, 0x72, 0x1e, 0x91, 0x14, 0x61, 0xd3, 0xcd,
0xef, 0x97, 0x93, 0x85, 0x8e, 0x97, 0x7f, 0xcd,
0xa0, 0x91, 0x77, 0x92, 0x43, 0xab, 0xb7, 0x31,
0x6c, 0x2f, 0x11, 0x60, 0x5a, 0x16, 0x08, 0x93 };
const char *key2 = "r34lly l33t wp4 p4ssphr4s3 for t3st1ng";
test_wifi_wpa_psk ("wifi-wpa-psk-hex", TYPE_BYTES, key1, key1_expected, sizeof (key1_expected));
test_wifi_wpa_psk ("wifi-wep-psk-passphrase", TYPE_STRING, key2, (gconstpointer) key2, strlen (key2));
}
int main (int argc, char **argv)
{
GError *error = NULL;
DBusGConnection *bus;
char *base;
g_type_init ();
bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
if (!nm_utils_init (&error))
FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
/* The tests */
test_wifi_open ();
test_wifi_wep ();
test_wifi_wpa_psk_types ();
base = g_path_get_basename (argv[0]);
fprintf (stdout, "%s: SUCCESS\n", base);
g_free (base);
return 0;
}