core: add AddAndActivate D-Bus method

Given connection details, complete the connection as well as possible
using the given specific object and device, add it to system
settings, and activate it all in one method.
This commit is contained in:
Dan Williams 2011-01-10 23:39:12 -06:00
parent bf98469b8d
commit 215306f5a1
25 changed files with 2839 additions and 101 deletions

1
.gitignore vendored
View file

@ -94,6 +94,7 @@ libnm-util/tests/test-setting-8021x
libnm-glib/tests/test-remote-settings-client
src/tests/test-dhcp-options
src/tests/test-policy-hosts
src/tests/test-wifi-ap-utils
system-settings/plugins/keyfile/tests/test-keyfile
system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh

View file

@ -66,6 +66,55 @@
</tp:possible-errors>
</method>
<method name="AddAndActivateConnection">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_manager_add_and_activate_connection"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<tp:docstring>
Adds a new connection using the given details (if any) as a template
(automatically filling in missing settings with the capabilities of the
given device and specific object), then activate the new connection.
Cannot be used for VPN connections at this time.
</tp:docstring>
<arg name="connection" type="a{sa{sv}}" direction="in">
<tp:docstring>
Connection settings and properties; if incomplete missing settings will
be automatically completed using the given device and specific object.
</tp:docstring>
</arg>
<arg name="device" type="o" direction="in">
<tp:docstring>
The object path of device to be activated using the given connection.
</tp:docstring>
</arg>
<arg name="specific_object" type="o" direction="in">
<tp:docstring>
The path of a connection-type-specific object this activation should use.
This parameter is currently ignored for wired and mobile broadband connections,
and the value of "/" should be used (ie, no specific object). For WiFi
connections, pass the object path of a specific AP from the card's scan
list, which will be used to complete the details of the newly added
connection.
</tp:docstring>
</arg>
<arg name="path" type="o" direction="out">
<tp:docstring>
Object path of the new connection that was just added.
</tp:docstring>
</arg>
<arg name="active_connection" type="o" direction="out">
<tp:docstring>
The path of the active connection object representing this active connection.
</tp:docstring>
</arg>
<tp:possible-errors>
<tp:error name="org.freedesktop.NetworkManager.Error.UnknownConnection"/>
<tp:error name="org.freedesktop.NetworkManager.Error.UnknownDevice"/>
<tp:error name="org.freedesktop.NetworkManager.Error.ConnectionInvalid">
<tp:docstring>The connection is invalid for this device.</tp:docstring>
</tp:error>
</tp:possible-errors>
</method>
<method name="DeactivateConnection">
<tp:docstring>
Deactivate an active connection.

View file

@ -35,7 +35,10 @@ INCLUDES = -I${top_srcdir} \
# Test libraries
###########################################
noinst_LTLIBRARIES = libtest-dhcp.la libtest-policy-hosts.la
noinst_LTLIBRARIES = \
libtest-dhcp.la \
libtest-policy-hosts.la \
libtest-wifi-ap-utils.la
###########################################
# DHCP test library
@ -76,6 +79,22 @@ libtest_policy_hosts_la_LIBADD = \
$(GLIB_LIBS)
###########################################
# Wifi ap utils
###########################################
libtest_wifi_ap_utils_la_SOURCES = \
nm-wifi-ap-utils.c \
nm-wifi-ap-utils.h
libtest_wifi_ap_utils_la_CPPFLAGS = \
$(GLIB_CFLAGS)
libtest_wifi_ap_utils_la_LIBADD = \
${top_builddir}/libnm-util/libnm-util.la \
$(GLIB_LIBS)
###########################################
# NetworkManager
###########################################
@ -106,6 +125,8 @@ NetworkManager_SOURCES = \
nm-device-gsm.h \
nm-wifi-ap.c \
nm-wifi-ap.h \
nm-wifi-ap-utils.c \
nm-wifi-ap-utils.h \
nm-dbus-manager.h \
nm-dbus-manager.c \
nm-udev-manager.c \

View file

@ -15,19 +15,23 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2009 - 2010 Red Hat, Inc.
* Copyright (C) 2009 - 2011 Red Hat, Inc.
* Copyright (C) 2009 Novell, Inc.
*/
#include <string.h>
#include <glib/gi18n.h>
#include "nm-dbus-glib-types.h"
#include "nm-modem-cdma.h"
#include "nm-modem-types.h"
#include "nm-device.h"
#include "nm-device-private.h"
#include "nm-dbus-manager.h"
#include "nm-setting-connection.h"
#include "nm-setting-cdma.h"
#include "nm-setting-serial.h"
#include "nm-setting-ppp.h"
#include "NetworkManagerUtils.h"
#include "nm-logging.h"
@ -269,6 +273,47 @@ real_check_connection_compatible (NMModem *modem,
return TRUE;
}
static gboolean
real_complete_connection (NMModem *modem,
NMConnection *connection,
const GSList *existing_connections,
GError **error)
{
NMSettingCdma *s_cdma;
NMSettingSerial *s_serial;
NMSettingPPP *s_ppp;
s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
s_serial = (NMSettingSerial *) nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL);
s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP);
if (!s_cdma) {
s_cdma = (NMSettingCdma *) nm_setting_cdma_new ();
nm_connection_add_setting (connection, NM_SETTING (s_cdma));
}
if (!nm_setting_cdma_get_number (s_cdma))
g_object_set (G_OBJECT (s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL);
/* Need serial and PPP settings at least */
if (!s_serial) {
s_serial = (NMSettingSerial *) nm_setting_serial_new ();
nm_connection_add_setting (connection, NM_SETTING (s_serial));
}
if (!s_ppp) {
s_ppp = (NMSettingPPP *) nm_setting_ppp_new ();
nm_connection_add_setting (connection, NM_SETTING (s_ppp));
}
nm_device_complete_generic (connection,
NM_SETTING_CDMA_SETTING_NAME,
existing_connections,
_("CDMA connection %d"),
NULL);
return TRUE;
}
static gboolean
real_get_user_pass (NMModem *modem,
NMConnection *connection,
@ -344,6 +389,7 @@ nm_modem_cdma_class_init (NMModemCdmaClass *klass)
modem_class->get_setting_name = real_get_setting_name;
modem_class->get_best_auto_connection = real_get_best_auto_connection;
modem_class->check_connection_compatible = real_check_connection_compatible;
modem_class->complete_connection = real_complete_connection;
modem_class->act_stage1_prepare = real_act_stage1_prepare;
modem_class->deactivate_quickly = real_deactivate_quickly;

View file

@ -15,16 +15,21 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2009 - 2010 Red Hat, Inc.
* Copyright (C) 2009 - 2011 Red Hat, Inc.
* Copyright (C) 2009 Novell, Inc.
*/
#include <string.h>
#include <glib/gi18n.h>
#include "nm-dbus-glib-types.h"
#include "nm-modem-gsm.h"
#include "nm-device.h"
#include "nm-device-private.h"
#include "nm-setting-connection.h"
#include "nm-setting-gsm.h"
#include "nm-setting-serial.h"
#include "nm-setting-ppp.h"
#include "nm-modem-types.h"
#include "nm-logging.h"
#include "NetworkManagerUtils.h"
@ -467,6 +472,51 @@ real_check_connection_compatible (NMModem *modem,
return TRUE;
}
static gboolean
real_complete_connection (NMModem *modem,
NMConnection *connection,
const GSList *existing_connections,
GError **error)
{
NMSettingGsm *s_gsm;
NMSettingSerial *s_serial;
NMSettingPPP *s_ppp;
s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM);
s_serial = (NMSettingSerial *) nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL);
s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP);
if (!s_gsm || !nm_setting_gsm_get_apn (s_gsm)) {
/* Need an APN at least */
g_set_error_literal (error,
NM_SETTING_GSM_ERROR,
NM_SETTING_GSM_ERROR_MISSING_PROPERTY,
NM_SETTING_GSM_APN);
return FALSE;
}
if (!nm_setting_gsm_get_number (s_gsm))
g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL);
/* Need serial and PPP settings at least */
if (!s_serial) {
s_serial = (NMSettingSerial *) nm_setting_serial_new ();
nm_connection_add_setting (connection, NM_SETTING (s_serial));
}
if (!s_ppp) {
s_ppp = (NMSettingPPP *) nm_setting_ppp_new ();
nm_connection_add_setting (connection, NM_SETTING (s_ppp));
}
nm_device_complete_generic (connection,
NM_SETTING_GSM_SETTING_NAME,
existing_connections,
_("GSM connection %d"),
NULL);
return TRUE;
}
static gboolean
real_get_user_pass (NMModem *modem,
NMConnection *connection,
@ -545,6 +595,7 @@ nm_modem_gsm_class_init (NMModemGsmClass *klass)
modem_class->get_setting_name = real_get_setting_name;
modem_class->get_best_auto_connection = real_get_best_auto_connection;
modem_class->check_connection_compatible = real_check_connection_compatible;
modem_class->complete_connection = real_complete_connection;
modem_class->act_stage1_prepare = real_act_stage1_prepare;
modem_class->deactivate_quickly = real_deactivate_quickly;

View file

@ -619,6 +619,17 @@ nm_modem_check_connection_compatible (NMModem *self,
return FALSE;
}
gboolean
nm_modem_complete_connection (NMModem *self,
NMConnection *connection,
const GSList *existing_connections,
GError **error)
{
if (NM_MODEM_GET_CLASS (self)->complete_connection)
return NM_MODEM_GET_CLASS (self)->complete_connection (self, connection, existing_connections, error);
return FALSE;
}
static void
real_deactivate_quickly (NMModem *self, NMDevice *device)
{

View file

@ -67,6 +67,11 @@ typedef struct {
NMConnection *connection,
GError **error);
gboolean (*complete_connection) (NMModem *modem,
NMConnection *connection,
const GSList *existing_connections,
GError **error);
NMConnection * (*get_best_auto_connection) (NMModem *modem,
GSList *connections,
char **specific_object);
@ -107,6 +112,11 @@ gboolean nm_modem_check_connection_compatible (NMModem *self,
NMConnection *connection,
GError **error);
gboolean nm_modem_complete_connection (NMModem *self,
NMConnection *connection,
const GSList *existing_connections,
GError **error);
NMActStageReturn nm_modem_act_stage1_prepare (NMModem *modem,
NMActRequest *req,
NMDeviceStateReason *reason);

View file

@ -15,12 +15,15 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2009 - 2010 Red Hat, Inc.
* Copyright (C) 2009 - 2011 Red Hat, Inc.
*/
#include <stdio.h>
#include <string.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <glib/gi18n.h>
#include "nm-glib-compat.h"
#include "nm-bluez-common.h"
@ -36,6 +39,8 @@
#include "nm-setting-bluetooth.h"
#include "nm-setting-cdma.h"
#include "nm-setting-gsm.h"
#include "nm-setting-serial.h"
#include "nm-setting-ppp.h"
#include "nm-device-bt-glue.h"
#include "NetworkManagerUtils.h"
@ -250,6 +255,156 @@ real_check_connection_compatible (NMDevice *device,
return addr_match;
}
static gboolean
real_complete_connection (NMDevice *device,
NMConnection *connection,
const char *specific_object,
const GSList *existing_connections,
GError **error)
{
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
NMSettingBluetooth *s_bt;
const GByteArray *setting_bdaddr;
struct ether_addr *devaddr = ether_aton (priv->bdaddr);
const char *ctype;
gboolean is_dun = FALSE, is_pan = FALSE;
NMSettingGsm *s_gsm;
NMSettingCdma *s_cdma;
NMSettingSerial *s_serial;
NMSettingPPP *s_ppp;
const char *format = NULL, *preferred = NULL;
s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM);
s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
s_serial = (NMSettingSerial *) nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL);
s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP);
s_bt = (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
if (!s_bt) {
s_bt = (NMSettingBluetooth *) nm_setting_bluetooth_new ();
nm_connection_add_setting (connection, NM_SETTING (s_bt));
}
ctype = nm_setting_bluetooth_get_connection_type (s_bt);
if (ctype) {
if (!strcmp (ctype, NM_SETTING_BLUETOOTH_TYPE_DUN))
is_dun = TRUE;
else if (!strcmp (ctype, NM_SETTING_BLUETOOTH_TYPE_PANU))
is_pan = TRUE;
} else {
if (s_gsm || s_cdma)
is_dun = TRUE;
else if (priv->capabilities & NM_BT_CAPABILITY_NAP)
is_pan = TRUE;
}
if (is_pan) {
/* Make sure the device supports PAN */
if (!(priv->capabilities & NM_BT_CAPABILITY_NAP)) {
g_set_error_literal (error,
NM_SETTING_BLUETOOTH_ERROR,
NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
"PAN required but Bluetooth device does not support NAP");
return FALSE;
}
/* PAN can't use any DUN-related settings */
if (s_gsm || s_cdma || s_serial) {
g_set_error_literal (error,
NM_SETTING_BLUETOOTH_ERROR,
NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
"PAN incompatible with GSM, CDMA, or serial settings");
return FALSE;
}
g_object_set (G_OBJECT (s_bt),
NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
NULL);
format = _("PAN connection %d");
} else if (is_dun) {
/* Make sure the device supports PAN */
if (!(priv->capabilities & NM_BT_CAPABILITY_DUN)) {
g_set_error_literal (error,
NM_SETTING_BLUETOOTH_ERROR,
NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
"DUN required but Bluetooth device does not support DUN");
return FALSE;
}
/* Need at least a GSM or a CDMA setting */
if (!s_gsm && !s_cdma) {
g_set_error_literal (error,
NM_SETTING_BLUETOOTH_ERROR,
NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
"Setting requires DUN but no GSM or CDMA setting is present");
return FALSE;
}
g_object_set (G_OBJECT (s_bt),
NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_DUN,
NULL);
if (s_gsm) {
format = _("GSM connection %d");
if (!nm_setting_gsm_get_number (s_gsm))
g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL);
} else if (s_cdma) {
format = _("CDMA connection %d");
if (!nm_setting_cdma_get_number (s_cdma))
g_object_set (G_OBJECT (s_cdma), NM_SETTING_GSM_NUMBER, "#777", NULL);
} else
format = _("DUN connection %d");
/* Need serial and PPP settings */
if (!s_serial) {
s_serial = (NMSettingSerial *) nm_setting_serial_new ();
nm_connection_add_setting (connection, NM_SETTING (s_serial));
}
if (!s_ppp) {
s_ppp = (NMSettingPPP *) nm_setting_ppp_new ();
nm_connection_add_setting (connection, NM_SETTING (s_ppp));
}
} else {
g_set_error_literal (error,
NM_SETTING_BLUETOOTH_ERROR,
NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
"Unknown/unhandled Bluetooth connection type");
return FALSE;
}
nm_device_complete_generic (connection,
NM_SETTING_BLUETOOTH_SETTING_NAME,
existing_connections,
format,
preferred);
setting_bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt);
if (setting_bdaddr) {
/* Make sure the setting BT Address (if any) matches the device's */
if (memcmp (setting_bdaddr->data, devaddr->ether_addr_octet, ETH_ALEN)) {
g_set_error_literal (error,
NM_SETTING_BLUETOOTH_ERROR,
NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
NM_SETTING_BLUETOOTH_BDADDR);
return FALSE;
}
} else {
GByteArray *bdaddr;
const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
/* Lock the connection to this device by default */
if (memcmp (devaddr->ether_addr_octet, null_mac, ETH_ALEN)) {
bdaddr = g_byte_array_sized_new (ETH_ALEN);
g_byte_array_append (bdaddr, devaddr->ether_addr_octet, ETH_ALEN);
g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, bdaddr, NULL);
g_byte_array_free (bdaddr, TRUE);
}
}
return TRUE;
}
static guint32
real_get_generic_capabilities (NMDevice *dev)
{
@ -1000,6 +1155,7 @@ nm_device_bt_class_init (NMDeviceBtClass *klass)
device_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start;
device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
device_class->check_connection_compatible = real_check_connection_compatible;
device_class->complete_connection = real_complete_connection;
/* Properties */
g_object_class_install_property

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@ -1624,6 +1624,67 @@ real_check_connection_compatible (NMDevice *device,
return TRUE;
}
static gboolean
real_complete_connection (NMDevice *device,
NMConnection *connection,
const char *specific_object,
const GSList *existing_connections,
GError **error)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
NMSettingWired *s_wired;
NMSettingPPPOE *s_pppoe;
const GByteArray *setting_mac;
s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
/* We can't telepathically figure out the service name or username, so if
* those weren't given, we can't complete the connection.
*/
if (s_pppoe && !nm_setting_verify (NM_SETTING (s_pppoe), NULL, error))
return FALSE;
/* Default to an ethernet-only connection, but if a PPPoE setting was given
* then PPPoE should be our connection type.
*/
nm_device_complete_generic (connection,
s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_CONNECTION_SETTING_NAME,
existing_connections,
s_pppoe ? _("PPPoE connection %d") : _("Wired connection %d"),
NULL);
s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
if (!s_wired) {
s_wired = (NMSettingWired *) nm_setting_wired_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wired));
}
setting_mac = nm_setting_wired_get_mac_address (s_wired);
if (setting_mac) {
/* Make sure the setting MAC (if any) matches the device's permanent MAC */
if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) {
g_set_error_literal (error,
NM_SETTING_WIRED_ERROR,
NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRED_MAC_ADDRESS);
return FALSE;
}
} else {
GByteArray *mac;
const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
/* Lock the connection to this device by default */
if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) {
mac = g_byte_array_sized_new (ETH_ALEN);
g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN);
g_object_set (G_OBJECT (s_wired), NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
g_byte_array_free (mac, TRUE);
}
}
return TRUE;
}
static gboolean
spec_match_list (NMDevice *device, const GSList *specs)
{
@ -1933,6 +1994,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->is_available = real_is_available;
parent_class->check_connection_compatible = real_check_connection_compatible;
parent_class->complete_connection = real_complete_connection;
parent_class->act_stage1_prepare = real_act_stage1_prepare;
parent_class->act_stage2_config = real_act_stage2_config;

View file

@ -220,6 +220,18 @@ real_check_connection_compatible (NMDevice *device,
return nm_modem_check_connection_compatible (priv->modem, connection, error);
}
static gboolean
real_complete_connection (NMDevice *device,
NMConnection *connection,
const char *specific_object,
const GSList *existing_connections,
GError **error)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
return nm_modem_complete_connection (priv->modem, connection, existing_connections, error);
}
static gboolean
real_hw_is_up (NMDevice *device)
{
@ -401,6 +413,7 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
device_class->get_generic_capabilities = real_get_generic_capabilities;
device_class->get_best_auto_connection = real_get_best_auto_connection;
device_class->check_connection_compatible = real_check_connection_compatible;
device_class->complete_connection = real_complete_connection;
device_class->hw_is_up = real_hw_is_up;
device_class->hw_bring_up = real_hw_bring_up;
device_class->deactivate_quickly = real_deactivate_quickly;

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2010 Red Hat, Inc.
* Copyright (C) 2011 Red Hat, Inc.
*/
#ifndef NM_DEVICE_MODEM_H

View file

@ -19,7 +19,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2005 - 2010 Red Hat, Inc.
* (C) Copyright 2005 - 2011 Red Hat, Inc.
* (C) Copyright 2008 Collabora Ltd.
* (C) Copyright 2009 One Laptop per Child
*/
@ -381,6 +381,50 @@ real_check_connection_compatible (NMDevice *device,
return TRUE;
}
#define DEFAULT_SSID "olpc-mesh"
static gboolean
real_complete_connection (NMDevice *device,
NMConnection *connection,
const char *specific_object,
const GSList *existing_connections,
GError **error)
{
NMSettingOlpcMesh *s_mesh;
GByteArray *tmp;
s_mesh = (NMSettingOlpcMesh *) nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH);
if (!s_mesh) {
s_mesh = (NMSettingOlpcMesh *) nm_setting_olpc_mesh_new ();
nm_connection_add_setting (connection, NM_SETTING (s_mesh));
}
if (!nm_setting_olpc_mesh_get_ssid (s_mesh)) {
tmp = g_byte_array_sized_new (strlen (DEFAULT_SSID));
g_byte_array_append (tmp, (const guint8 *) DEFAULT_SSID, strlen (DEFAULT_SSID));
g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_SSID, tmp, NULL);
g_byte_array_free (tmp, TRUE);
}
if (!nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh)) {
const guint8 anycast[ETH_ALEN] = { 0xC0, 0x27, 0xC0, 0x27, 0xC0, 0x27 };
tmp = g_byte_array_sized_new (ETH_ALEN);
g_byte_array_append (tmp, anycast, sizeof (anycast));
g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, tmp, NULL);
g_byte_array_free (tmp, TRUE);
}
nm_device_complete_generic (connection,
NM_SETTING_OLPC_MESH_SETTING_NAME,
existing_connections,
_("Mesh %d"),
NULL);
return TRUE;
}
/*
* nm_device_olpc_mesh_get_address
*
@ -722,6 +766,7 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass)
parent_class->take_down = real_take_down;
parent_class->update_hw_address = real_update_hw_address;
parent_class->check_connection_compatible = real_check_connection_compatible;
parent_class->complete_connection = real_complete_connection;
parent_class->act_stage1_prepare = real_act_stage1_prepare;
parent_class->act_stage2_config = real_act_stage2_config;

View file

@ -16,7 +16,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2008 Novell, Inc.
* Copyright (C) 2007 - 2008 Red Hat, Inc.
* Copyright (C) 2007 - 2011 Red Hat, Inc.
*/
#ifndef NM_DEVICE_PRIVATE_H
@ -46,4 +46,10 @@ gboolean nm_device_get_firmware_missing (NMDevice *self);
void nm_device_set_firmware_missing (NMDevice *self, gboolean missing);
void nm_device_complete_generic (NMConnection *connection,
const char *ctype,
const GSList *existing,
const char *format,
const char *preferred);
#endif /* NM_DEVICE_PRIVATE_H */

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@ -104,15 +104,6 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
typedef enum {
NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0,
NM_WIFI_ERROR_CONNECTION_INVALID,
NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE,
} NMWifiError;
#define NM_WIFI_ERROR (nm_wifi_error_quark ())
#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ())
#define SUP_SIG_ID_LEN 5
typedef struct Supplicant {
@ -208,6 +199,18 @@ static guint32 nm_device_wifi_get_bitrate (NMDeviceWifi *self);
static void cull_scan_list (NMDeviceWifi *self);
/*****************************************************************/
typedef enum {
NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0,
NM_WIFI_ERROR_CONNECTION_INVALID,
NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE,
NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND,
} NMWifiError;
#define NM_WIFI_ERROR (nm_wifi_error_quark ())
#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ())
static GQuark
nm_wifi_error_quark (void)
{
@ -233,6 +236,8 @@ nm_wifi_error_get_type (void)
ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_INVALID, "ConnectionInvalid"),
/* Connection does not apply to this device. */
ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"),
/* Given access point was not in this device's scan list. */
ENUM_ENTRY (NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, "AccessPointNotFound"),
{ 0, 0, 0 }
};
etype = g_enum_register_static ("NMWifiError", values);
@ -240,6 +245,8 @@ nm_wifi_error_get_type (void)
return etype;
}
/*****************************************************************/
/* IPW rfkill handling (until 2.6.33) */
RfKillState
nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self)
@ -298,6 +305,8 @@ ipw_rfkill_state_work (gpointer user_data)
return TRUE;
}
/*****************************************************************/
/*
* nm_device_wifi_update_signal_strength
*
@ -732,6 +741,20 @@ supplicant_interface_release (NMDeviceWifi *self)
}
}
static NMAccessPoint *
get_ap_by_path (NMDeviceWifi *self, const char *path)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
GSList *iter;
for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
if (strcmp (path, nm_ap_get_dbus_path (NM_AP (iter->data))) == 0)
return NM_AP (iter->data);
}
return NULL;
}
static NMAccessPoint *
get_active_ap (NMDeviceWifi *self,
NMAccessPoint *ignore_ap,
@ -1222,6 +1245,174 @@ real_check_connection_compatible (NMDevice *device,
return TRUE;
}
/*
* List of manufacturer default SSIDs that are often unchanged by users.
*
* NOTE: this list should *not* contain networks that you would like to
* automatically roam to like "Starbucks" or "AT&T" or "T-Mobile HotSpot".
*/
static const char *
manf_defaults[] = {
"linksys",
"linksys-a",
"linksys-g",
"default",
"belkin54g",
"NETGEAR",
"o2DSL",
"WLAN",
"ALICE-WLAN",
};
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0]))
static gboolean
is_manf_default_ssid (const GByteArray *ssid)
{
int i;
for (i = 0; i < ARRAY_SIZE (manf_defaults); i++) {
if (ssid->len == strlen (manf_defaults[i])) {
if (memcmp (manf_defaults[i], ssid->data, ssid->len) == 0)
return TRUE;
}
}
return FALSE;
}
static gboolean
real_complete_connection (NMDevice *device,
NMConnection *connection,
const char *specific_object,
const GSList *existing_connections,
GError **error)
{
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
NMSetting8021x *s_8021x;
const GByteArray *setting_mac;
char *format, *str_ssid = NULL;
NMAccessPoint *ap = NULL;
const GByteArray *ssid = NULL;
GSList *iter;
char buf[33];
int buf_len;
s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
if (!specific_object) {
/* If not given a specific object, we need at minimum an SSID */
if (!s_wifi) {
g_set_error_literal (error,
NM_WIFI_ERROR,
NM_WIFI_ERROR_CONNECTION_INVALID,
"A 'wireless' setting is required if no AP path was given.");
return FALSE;
}
ssid = nm_setting_wireless_get_ssid (s_wifi);
if (!ssid || !ssid->len) {
g_set_error_literal (error,
NM_WIFI_ERROR,
NM_WIFI_ERROR_CONNECTION_INVALID,
"A 'wireless' setting with a valid SSID is required if no AP path was given.");
return FALSE;
}
/* Find a compatible AP in the scan list */
for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
if (nm_ap_check_compatible (NM_AP (iter->data), connection)) {
ap = NM_AP (iter->data);
break;
}
}
/* If we still don't have an AP, then the WiFI settings needs to be
* fully specified by the client. Might not be able to find an AP
* if the network isn't broadcasting the SSID for example.
*/
if (!ap) {
GSList *settings = NULL;
gboolean valid;
settings = g_slist_prepend (settings, s_wifi);
settings = g_slist_prepend (settings, s_wsec);
settings = g_slist_prepend (settings, s_8021x);
valid = nm_setting_verify (NM_SETTING (s_wifi), settings, error);
g_slist_free (settings);
if (!valid)
return FALSE;
}
} else {
ap = get_ap_by_path (self, specific_object);
if (!ap) {
g_set_error (error,
NM_WIFI_ERROR,
NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND,
"The access point %s was not in the scan list.",
specific_object);
return FALSE;
}
}
if (ap) {
ssid = nm_ap_get_ssid (ap);
/* If the SSID is a well-known SSID, lock the connection to the AP's
* specific BSSID so NM doesn't autoconnect to some random wifi net.
*/
if (!nm_ap_complete_connection (ap,
connection,
is_manf_default_ssid (ssid),
error))
return FALSE;
}
g_assert (ssid);
memset (buf, 0, sizeof (buf));
buf_len = MIN (ssid->len, sizeof (buf) - 1);
memcpy (buf, ssid->data, buf_len);
str_ssid = nm_utils_ssid_to_utf8 (buf, buf_len);
format = g_strdup_printf ("%s %%d", str_ssid);
nm_device_complete_generic (connection,
NM_SETTING_WIRELESS_SETTING_NAME,
existing_connections,
format,
str_ssid);
g_free (str_ssid);
g_free (format);
setting_mac = nm_setting_wireless_get_mac_address (s_wifi);
if (setting_mac) {
/* Make sure the setting MAC (if any) matches the device's permanent MAC */
if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) {
g_set_error (error,
NM_SETTING_WIRELESS_ERROR,
NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRELESS_MAC_ADDRESS);
return FALSE;
}
} else {
GByteArray *mac;
const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
/* Lock the connection to this device by default */
if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) {
mac = g_byte_array_sized_new (ETH_ALEN);
g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN);
g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MAC_ADDRESS, mac, NULL);
g_byte_array_free (mac, TRUE);
}
}
return TRUE;
}
static gboolean
real_is_available (NMDevice *dev)
{
@ -3449,10 +3640,8 @@ device_state_changed (NMDevice *device,
NMAccessPoint *
nm_device_wifi_get_activation_ap (NMDeviceWifi *self)
{
NMDeviceWifiPrivate *priv;
NMActRequest *req;
const char *ap_path;
GSList * elt;
g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), NULL);
@ -3461,18 +3650,8 @@ nm_device_wifi_get_activation_ap (NMDeviceWifi *self)
return NULL;
ap_path = nm_act_request_get_specific_object (req);
if (!ap_path)
return NULL;
/* Find the AP by it's object path */
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
for (elt = priv->ap_list; elt; elt = g_slist_next (elt)) {
NMAccessPoint *ap = NM_AP (elt->data);
if (!strcmp (ap_path, nm_ap_get_dbus_path (ap)))
return ap;
}
return NULL;
return ap_path ? get_ap_by_path (self, ap_path) : NULL;
}
static void
@ -3700,6 +3879,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->is_available = real_is_available;
parent_class->check_connection_compatible = real_check_connection_compatible;
parent_class->complete_connection = real_complete_connection;
parent_class->act_stage1_prepare = real_act_stage1_prepare;
parent_class->act_stage2_config = real_act_stage2_config;

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@ -572,6 +572,153 @@ nm_device_get_best_auto_connection (NMDevice *dev,
return NM_DEVICE_GET_CLASS (dev)->get_best_auto_connection (dev, connections, specific_object);
}
gboolean
nm_device_complete_connection (NMDevice *self,
NMConnection *connection,
const char *specific_object,
const GSList *existing_connections,
GError **error)
{
gboolean success = FALSE;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
if (!NM_DEVICE_GET_CLASS (self)->complete_connection) {
g_set_error (error,
NM_DEVICE_INTERFACE_ERROR,
NM_DEVICE_INTERFACE_ERROR_CONNECTION_INVALID,
"Device class %s had no complete_connection method",
G_OBJECT_TYPE_NAME (self));
return FALSE;
}
success = NM_DEVICE_GET_CLASS (self)->complete_connection (self,
connection,
specific_object,
existing_connections,
error);
if (success)
success = nm_connection_verify (connection, error);
return success;
}
static char *
nm_device_new_connection_name (const GSList *existing,
const char *format,
const char *preferred)
{
GSList *names = NULL;
const GSList *iter;
char *cname = NULL;
int i = 0;
gboolean preferred_found = FALSE;
for (iter = existing; iter; iter = g_slist_next (iter)) {
NMConnection *candidate = NM_CONNECTION (iter->data);
NMSettingConnection *s_con;
const char *id;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION));
id = nm_setting_connection_get_id (s_con);
g_assert (id);
names = g_slist_append (names, (gpointer) id);
if (preferred && !preferred_found && (strcmp (preferred, id) == 0))
preferred_found = TRUE;
}
/* Return the preferred name if it was unique */
if (preferred && !preferred_found) {
g_slist_free (names);
return g_strdup (preferred);
}
/* Otherwise find the next available unique connection name using the given
* connection name template.
*/
while (!cname && (i++ < 10000)) {
char *temp;
gboolean found = FALSE;
temp = g_strdup_printf (format, i);
for (iter = names; iter; iter = g_slist_next (iter)) {
if (!strcmp (iter->data, temp)) {
found = TRUE;
break;
}
}
if (!found)
cname = temp;
else
g_free (temp);
}
g_slist_free (names);
return cname;
}
void
nm_device_complete_generic (NMConnection *connection,
const char *ctype,
const GSList *existing,
const char *format,
const char *preferred)
{
NMSettingConnection *s_con;
NMSettingIP4Config *s_ip4;
NMSettingIP6Config *s_ip6;
const char *method;
char *id, *uuid;
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
if (!s_con) {
s_con = (NMSettingConnection *) nm_setting_connection_new ();
nm_connection_add_setting (connection, NM_SETTING (s_con));
}
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_TYPE, ctype, NULL);
if (!nm_setting_connection_get_uuid (s_con)) {
uuid = nm_utils_uuid_generate ();
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_UUID, uuid, NULL);
g_free (uuid);
}
/* Add a connection ID if absent */
if (!nm_setting_connection_get_id (s_con)) {
id = nm_device_new_connection_name (existing, format, preferred);
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_ID, id, NULL);
g_free (id);
}
/* Add an 'auto' IPv4 connection if present */
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
if (!s_ip4) {
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
}
method = nm_setting_ip4_config_get_method (s_ip4);
if (!method) {
g_object_set (G_OBJECT (s_ip4),
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
NULL);
}
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
if (!s_ip6) {
s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
nm_connection_add_setting (connection, NM_SETTING (s_ip6));
}
method = nm_setting_ip6_config_get_method (s_ip6);
if (!method) {
g_object_set (G_OBJECT (s_ip6),
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE,
NULL);
}
}
static void
dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer user_data)
{

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@ -88,6 +88,12 @@ typedef struct {
NMConnection *connection,
GError **error);
gboolean (* complete_connection) (NMDevice *self,
NMConnection *connection,
const char *specific_object,
const GSList *existing_connections,
GError **error);
NMActStageReturn (* act_stage1_prepare) (NMDevice *self,
NMDeviceStateReason *reason);
NMActStageReturn (* act_stage2_config) (NMDevice *self,
@ -157,6 +163,12 @@ NMConnection * nm_device_get_best_auto_connection (NMDevice *dev,
GSList *connections,
char **specific_object);
gboolean nm_device_complete_connection (NMDevice *device,
NMConnection *connection,
const char *specific_object,
const GSList *existing_connection,
GError **error);
void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device);
void nm_device_activate_schedule_stage2_device_config (NMDevice *device);
void nm_device_activate_schedule_stage4_ip4_config_get (NMDevice *device);

View file

@ -16,7 +16,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2009 Novell, Inc.
* Copyright (C) 2007 - 2010 Red Hat, Inc.
* Copyright (C) 2007 - 2011 Red Hat, Inc.
*/
#include <config.h>
@ -69,6 +69,12 @@ static void impl_manager_activate_connection (NMManager *manager,
const char *specific_object_path,
DBusGMethodInvocation *context);
static void impl_manager_add_and_activate_connection (NMManager *manager,
GHashTable *settings,
const char *device_path,
const char *specific_object_path,
DBusGMethodInvocation *context);
static void impl_manager_deactivate_connection (NMManager *manager,
const char *connection_path,
DBusGMethodInvocation *context);
@ -170,9 +176,8 @@ struct PendingActivation {
PendingActivationFunc callback;
NMAuthChain *chain;
gboolean authorized;
char *connection_path;
NMConnection *connection;
char *specific_object_path;
char *device_path;
};
@ -270,8 +275,10 @@ enum {
LAST_PROP
};
typedef enum
{
/************************************************************************/
typedef enum {
NM_MANAGER_ERROR_UNKNOWN_CONNECTION = 0,
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
NM_MANAGER_ERROR_UNMANAGED_DEVICE,
@ -327,6 +334,32 @@ nm_manager_error_get_type (void)
return etype;
}
/************************************************************************/
static NMDevice *
nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
{
GSList *iter;
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
if (!strcmp (nm_device_get_udi (NM_DEVICE (iter->data)), udi))
return NM_DEVICE (iter->data);
}
return NULL;
}
static NMDevice *
nm_manager_get_device_by_path (NMManager *manager, const char *path)
{
GSList *iter;
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
if (!strcmp (nm_device_get_path (NM_DEVICE (iter->data)), path))
return NM_DEVICE (iter->data);
}
return NULL;
}
static gboolean
manager_sleeping (NMManager *self)
{
@ -618,10 +651,17 @@ pending_activation_new (NMManager *manager,
DBusGMethodInvocation *context,
const char *device_path,
const char *connection_path,
GHashTable *settings,
const char *specific_object_path,
PendingActivationFunc callback)
PendingActivationFunc callback,
GError **error)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
PendingActivation *pending;
NMDevice *device;
NMConnection *connection = NULL;
GSList *all_connections = NULL;
gboolean success;
g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (authority != NULL, NULL);
@ -629,6 +669,35 @@ pending_activation_new (NMManager *manager,
g_return_val_if_fail (device_path != NULL, NULL);
g_return_val_if_fail (connection_path != NULL, NULL);
/* Create the partial connection from the given settings */
if (settings) {
device = nm_manager_get_device_by_path (manager, device_path);
if (!device) {
g_set_error_literal (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"Device not found");
return NULL;
}
connection = nm_connection_new ();
nm_connection_replace_settings (connection, settings, NULL);
/* Let each device subclass complete the connection */
all_connections = nm_settings_get_connections (priv->settings);
success = nm_device_complete_connection (device,
connection,
specific_object_path,
all_connections,
error);
g_slist_free (all_connections);
if (success == FALSE) {
g_object_unref (connection);
return NULL;
}
}
pending = g_slice_new0 (PendingActivation);
pending->manager = manager;
pending->authority = authority;
@ -637,6 +706,7 @@ pending_activation_new (NMManager *manager,
pending->device_path = g_strdup (device_path);
pending->connection_path = g_strdup (connection_path);
pending->connection = connection;
/* "/" is special-cased to NULL to get through D-Bus */
if (specific_object_path && strcmp (specific_object_path, "/"))
@ -731,14 +801,22 @@ pending_activation_destroy (PendingActivation *pending,
{
g_return_if_fail (pending != NULL);
if (error)
dbus_g_method_return_error (pending->context, error);
else if (ac_path) {
if (pending->connection) {
dbus_g_method_return (pending->context,
pending->connection_path,
ac_path);
} else
dbus_g_method_return (pending->context, ac_path);
}
g_free (pending->connection_path);
g_free (pending->specific_object_path);
g_free (pending->device_path);
if (error)
dbus_g_method_return_error (pending->context, error);
else if (ac_path)
dbus_g_method_return (pending->context, ac_path);
if (pending->connection)
g_object_unref (pending->connection);
if (pending->chain)
nm_auth_chain_unref (pending->chain);
@ -840,30 +918,6 @@ system_hostname_changed_cb (NMSettings *settings,
/* General NMManager stuff */
/*******************************************************************/
static NMDevice *
nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
{
GSList *iter;
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
if (!strcmp (nm_device_get_udi (NM_DEVICE (iter->data)), udi))
return NM_DEVICE (iter->data);
}
return NULL;
}
static NMDevice *
nm_manager_get_device_by_path (NMManager *manager, const char *path)
{
GSList *iter;
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
if (!strcmp (nm_device_get_path (NM_DEVICE (iter->data)), path))
return NM_DEVICE (iter->data);
}
return NULL;
}
/* Store value into key-file; supported types: boolean, int, string */
static gboolean
write_value_to_state_file (const char *filename,
@ -1870,7 +1924,7 @@ nm_manager_activate_connection (NMManager *manager,
* it.
*/
static void
check_pending_ready (NMManager *self, PendingActivation *pending)
pending_activate (NMManager *self, PendingActivation *pending)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMSysconfigConnection *connection;
@ -1907,14 +1961,10 @@ out:
static void
activation_auth_done (PendingActivation *pending, GError *error)
{
if (error) {
if (error)
pending_activation_destroy (pending, error, NULL);
return;
} else {
pending->authorized = TRUE;
check_pending_ready (pending->manager, pending);
}
else
pending_activate (pending->manager, pending);
}
static void
@ -1926,6 +1976,7 @@ impl_manager_activate_connection (NMManager *self,
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
PendingActivation *pending;
GError *error = NULL;
/* Need to check the caller's permissions and stuff before we can
* activate the connection.
@ -1935,10 +1986,86 @@ impl_manager_activate_connection (NMManager *self,
context,
device_path,
connection_path,
NULL,
specific_object_path,
activation_auth_done);
activation_auth_done,
&error);
if (pending)
pending_activation_check_authorized (pending, priv->dbus_mgr);
else {
g_assert (error);
dbus_g_method_return_error (context, error);
g_error_free (error);
}
}
pending_activation_check_authorized (pending, priv->dbus_mgr);
static void
activation_add_done (NMSettings *self,
NMSysconfigConnection *connection,
GError *error,
DBusGMethodInvocation *context,
gpointer user_data)
{
PendingActivation *pending = user_data;
if (error)
pending_activation_destroy (pending, error, NULL);
else {
/* Save the new connection's D-Bus path */
pending->connection_path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection)));
/* And activate it */
pending_activate (pending->manager, pending);
}
}
static void
add_and_activate_auth_done (PendingActivation *pending, GError *error)
{
if (error)
pending_activation_destroy (pending, error, NULL);
else {
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pending->manager);
/* Basic sender auth checks performed; try to add the connection */
nm_settings_add_connection (priv->settings,
pending->connection,
pending->context,
activation_add_done,
pending);
}
}
static void
impl_manager_add_and_activate_connection (NMManager *self,
GHashTable *settings,
const char *device_path,
const char *specific_object_path,
DBusGMethodInvocation *context)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
PendingActivation *pending;
GError *error = NULL;
/* Need to check the caller's permissions and stuff before we can
* activate the connection.
*/
pending = pending_activation_new (self,
priv->authority,
context,
device_path,
NULL,
settings,
specific_object_path,
add_and_activate_auth_done,
&error);
if (pending)
pending_activation_check_authorized (pending, priv->dbus_mgr);
else {
g_assert (error);
dbus_g_method_return_error (context, error);
g_error_free (error);
}
}
gboolean

699
src/nm-wifi-ap-utils.c Normal file
View file

@ -0,0 +1,699 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* (C) Copyright 2011 Red Hat, Inc.
*/
#include <string.h>
#include "nm-wifi-ap-utils.h"
static gboolean
verify_no_wep (NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error)
{
if ( nm_setting_wireless_security_get_wep_key (s_wsec, 0)
|| nm_setting_wireless_security_get_wep_key (s_wsec, 1)
|| nm_setting_wireless_security_get_wep_key (s_wsec, 2)
|| nm_setting_wireless_security_get_wep_key (s_wsec, 3)
|| nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec)
|| nm_setting_wireless_security_get_wep_key_type (s_wsec)) {
/* Dynamic WEP cannot have any WEP keys set */
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"%s is incompatible with static WEP keys", tag);
return FALSE;
}
return TRUE;
}
static gboolean
verify_leap (NMSettingWirelessSecurity *s_wsec,
NMSetting8021x *s_8021x,
gboolean adhoc,
GError **error)
{
const char *key_mgmt, *auth_alg, *leap_username;
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
leap_username = nm_setting_wireless_security_get_leap_username (s_wsec);
/* One (or both) of two things indicates we want LEAP:
* 1) auth_alg == 'leap'
* 2) valid leap_username
*
* LEAP always requires a LEAP username.
*/
if (auth_alg) {
if (!strcmp (auth_alg, "leap")) {
/* LEAP authentication requires at least a LEAP username */
if (!leap_username) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME,
"LEAP requires a LEAP username");
return FALSE;
}
} else if (leap_username) {
/* Leap username requires 'leap' auth */
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"LEAP requires 'leap' authentication");
return FALSE;
}
}
if (leap_username) {
if (key_mgmt && strcmp (key_mgmt, "ieee8021x")) {
/* LEAP requires ieee8021x key management */
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X,
"LEAP requires IEEE 802.1x key management");
return FALSE;
}
}
/* At this point if auth_alg is set it must be 'leap', and if key_mgmt
* is set it must be 'ieee8021x'.
*/
if (leap_username) {
if (auth_alg)
g_assert (strcmp (auth_alg, "leap") == 0);
if (key_mgmt)
g_assert (strcmp (key_mgmt, "ieee8021x") == 0);
if (adhoc) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"LEAP incompatible with Ad-Hoc mode");
return FALSE;
}
if (!verify_no_wep (s_wsec, "LEAP", error))
return FALSE;
if (s_8021x) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME,
"LEAP incompatible with 802.1x setting");
return FALSE;
}
}
return TRUE;
}
static gboolean
verify_no_wpa (NMSettingWirelessSecurity *s_wsec,
const char *tag,
GError **error)
{
const char *key_mgmt;
int n, i;
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
if (key_mgmt && !strncmp (key_mgmt, "wpa", 3)) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"%s incompatible with any WPA key management", tag);
return FALSE;
}
if (nm_setting_wireless_security_get_num_protos (s_wsec)) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"%s incompatible with any 'proto' setting", tag);
return FALSE;
}
n = nm_setting_wireless_security_get_num_pairwise (s_wsec);
for (i = 0; i < n; i++) {
const char *pw;
pw = nm_setting_wireless_security_get_pairwise (s_wsec, i);
if (strcmp (pw, "wep40") && strcmp (pw, "wep104")) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"%s is incompatible with WPA pairwise ciphers", tag);
return FALSE;
}
}
n = nm_setting_wireless_security_get_num_groups (s_wsec);
for (i = 0; i < n; i++) {
const char *gr;
gr = nm_setting_wireless_security_get_group (s_wsec, i);
if (strcmp (gr, "wep40") && strcmp (gr, "wep104")) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"%s is incompatible with WPA group ciphers", tag);
return FALSE;
}
}
if (nm_setting_wireless_security_get_psk (s_wsec)) {
g_set_error (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"%s is incompatible with a WPA Pre-Shared Key", tag);
return FALSE;
}
return TRUE;
}
static gboolean
verify_dynamic_wep (NMSettingWirelessSecurity *s_wsec,
NMSetting8021x *s_8021x,
gboolean adhoc,
GError **error)
{
const char *key_mgmt, *auth_alg, *leap_username;
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
leap_username = nm_setting_wireless_security_get_leap_username (s_wsec);
g_return_val_if_fail (leap_username == NULL, TRUE);
if (key_mgmt) {
if (!strcmp (key_mgmt, "ieee8021x")) {
if (!s_8021x) {
/* 802.1x key management requires an 802.1x setting */
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"Dynamic WEP requires an 802.1x setting");
return FALSE;
}
if (auth_alg && strcmp (auth_alg, "open")) {
/* 802.1x key management must use "open" authentication */
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"Dynamic WEP requires 'open' authentication");
return FALSE;
}
/* Dynamic WEP incompatible with anything static WEP related */
if (!verify_no_wep (s_wsec, "Dynamic WEP", error))
return FALSE;
} else if (!strcmp (key_mgmt, "none")) {
if (s_8021x) {
/* 802.1x setting requires 802.1x key management */
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"Dynamic WEP requires 'ieee8021x' key management");
return FALSE;
}
}
} else if (s_8021x) {
/* 802.1x setting incompatible with anything but 'open' auth */
if (auth_alg && strcmp (auth_alg, "open")) {
/* 802.1x key management must use "open" authentication */
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"Dynamic WEP requires 'open' authentication");
return FALSE;
}
/* Dynamic WEP incompatible with anything static WEP related */
if (!verify_no_wep (s_wsec, "Dynamic WEP", error))
return FALSE;
}
return TRUE;
}
static gboolean
verify_wpa_psk (NMSettingWirelessSecurity *s_wsec,
NMSetting8021x *s_8021x,
gboolean adhoc,
guint32 wpa_flags,
guint32 rsn_flags,
GError **error)
{
const char *key_mgmt, *auth_alg, *tmp;
int n;
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
if (key_mgmt) {
if (!strcmp (key_mgmt, "wpa-psk") || !strcmp (key_mgmt, "wpa-none")) {
if (s_8021x) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"WPA-PSK incompatible with 802.1x");
return FALSE;
}
if (auth_alg && strcmp (auth_alg, "open")) {
/* WPA must use "open" authentication */
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"WPA-PSK requires 'open' authentication");
return FALSE;
}
}
if (!strcmp (key_mgmt, "wpa-none")) {
if (!adhoc) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"WPA Ad-Hoc requires an Ad-Hoc mode AP");
return FALSE;
}
/* Ad-Hoc WPA requires 'wpa' proto, 'none' pairwise, and 'tkip' group */
n = nm_setting_wireless_security_get_num_protos (s_wsec);
tmp = (n > 0) ? nm_setting_wireless_security_get_proto (s_wsec, 0) : NULL;
if (n > 1 || strcmp (tmp, "wpa")) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"WPA Ad-Hoc requires 'wpa' proto");
return FALSE;
}
n = nm_setting_wireless_security_get_num_pairwise (s_wsec);
tmp = (n > 0) ? nm_setting_wireless_security_get_pairwise (s_wsec, 0) : NULL;
if (n > 1 || strcmp (tmp, "none")) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"WPA Ad-Hoc requires 'none' pairwise cipher");
return FALSE;
}
n = nm_setting_wireless_security_get_num_groups (s_wsec);
tmp = (n > 0) ? nm_setting_wireless_security_get_group (s_wsec, 0) : NULL;
if (n > 1 || strcmp (tmp, "tkip")) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"WPA Ad-Hoc requires 'tkip' group cipher");
return FALSE;
}
}
if (!strcmp (key_mgmt, "wpa-psk")) {
/* Make sure the AP's capabilities support WPA-PSK */
if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
&& !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"AP does not support PSK but setting requires it");
return FALSE;
}
}
}
return TRUE;
}
static gboolean
verify_wpa_eap (NMSettingWirelessSecurity *s_wsec,
NMSetting8021x *s_8021x,
guint32 wpa_flags,
guint32 rsn_flags,
GError **error)
{
const char *key_mgmt, *auth_alg;
gboolean is_wpa_eap = FALSE;
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
if (key_mgmt) {
if (!strcmp (key_mgmt, "wpa-eap")) {
if (!s_8021x) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"WPA-EAP requires an 802.1x setting");
return FALSE;
}
if (auth_alg && strcmp (auth_alg, "open")) {
/* WPA must use "open" authentication */
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"WPA-EAP requires 'open' authentication");
return FALSE;
}
is_wpa_eap = TRUE;
} else if (s_8021x) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"Setting requires 802.1x but does not use 'wpa-eap' key management");
return FALSE;
}
}
if (is_wpa_eap || s_8021x) {
/* Make sure the AP's capabilities support WPA-EAP */
if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
&& !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"AP does not support 802.1x but setting requires it");
return FALSE;
}
}
return TRUE;
}
static gboolean
verify_adhoc (NMSettingWirelessSecurity *s_wsec,
NMSetting8021x *s_8021x,
gboolean adhoc,
GError **error)
{
const char *key_mgmt = NULL, *leap_username = NULL, *auth_alg = NULL;
if (s_wsec) {
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
leap_username = nm_setting_wireless_security_get_leap_username (s_wsec);
}
if (adhoc) {
if (key_mgmt && strcmp (key_mgmt, "wpa-none") && strcmp (key_mgmt, "none")) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"AP mode is Ad-Hoc but setting requires Infrastructure security");
return FALSE;
}
if (s_8021x) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"Ad-Hoc mode incompatible with 802.1x security");
return FALSE;
}
if (leap_username) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"Ad-Hoc mode incompatible with LEAP security");
return FALSE;
}
if (auth_alg && strcmp (auth_alg, "open")) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"Ad-Hoc mode requires 'open' authentication");
return FALSE;
}
} else {
if (key_mgmt && !strcmp (key_mgmt, "wpa-none")) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"AP mode is Infrastructure but setting requires Ad-Hoc security");
return FALSE;
}
}
return TRUE;
}
gboolean
nm_ap_utils_complete_connection (const GByteArray *ap_ssid,
const guint8 ap_bssid[ETH_ALEN],
NM80211Mode ap_mode,
guint32 ap_flags,
guint32 ap_wpa_flags,
guint32 ap_rsn_flags,
NMConnection *connection,
gboolean lock_bssid,
GError **error)
{
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
NMSetting8021x *s_8021x;
const GByteArray *ssid;
const char *mode, *key_mgmt, *leap_username;
gboolean adhoc = FALSE;
s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
if (!s_wifi) {
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
}
/* Fill in missing SSID */
ssid = nm_setting_wireless_get_ssid (s_wifi);
if (!ssid)
g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid, NULL);
else if ( ssid->len != ap_ssid->len
|| memcmp (ssid->data, ap_ssid->data, ssid->len)) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_ERROR,
NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
"Setting SSID did not match AP SSID");
return FALSE;
}
if (lock_bssid && !nm_setting_wireless_get_bssid (s_wifi)) {
GByteArray *bssid;
bssid = g_byte_array_sized_new (ETH_ALEN);
g_byte_array_append (bssid, ap_bssid, ETH_ALEN);
g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL);
g_byte_array_free (bssid, TRUE);
}
/* And mode */
mode = nm_setting_wireless_get_mode (s_wifi);
if (mode) {
gboolean valid = FALSE;
/* Make sure the supplied mode matches the AP's */
if (!strcmp (mode, NM_SETTING_WIRELESS_MODE_INFRA)) {
if (ap_mode == NM_802_11_MODE_INFRA)
valid = TRUE;
} else if (!strcmp (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) {
if (ap_mode == NM_802_11_MODE_ADHOC)
valid = TRUE;
adhoc = TRUE;
}
if (valid == FALSE) {
g_set_error (error,
NM_SETTING_WIRELESS_ERROR,
NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRELESS_MODE);
return FALSE;
}
} else {
mode = NM_SETTING_WIRELESS_MODE_INFRA;
if (ap_mode == NM_802_11_MODE_ADHOC) {
mode = NM_SETTING_WIRELESS_MODE_ADHOC;
adhoc = TRUE;
}
g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, mode, NULL);
}
/* Security */
/* Open */
if ( !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)
&& (ap_wpa_flags == NM_802_11_AP_SEC_NONE)
&& (ap_rsn_flags == NM_802_11_AP_SEC_NONE)) {
/* Make sure the connection doesn't specify security */
if (nm_setting_wireless_get_security (s_wifi) || s_wsec || s_8021x) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"AP is unencrypted but setting specifies security");
return FALSE;
}
return TRUE;
}
/* Everything else requires security */
g_object_set (G_OBJECT (s_wifi),
NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
NULL);
if (!s_wsec) {
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
}
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
leap_username = nm_setting_wireless_security_get_leap_username (s_wsec);
/* Ad-Hoc checks */
if (!verify_adhoc (s_wsec, s_8021x, adhoc, error))
return FALSE;
/* Static WEP, Dynamic WEP, or LEAP */
if ( (ap_flags & NM_802_11_AP_FLAGS_PRIVACY)
&& (ap_wpa_flags == NM_802_11_AP_SEC_NONE)
&& (ap_rsn_flags == NM_802_11_AP_SEC_NONE)) {
const char *tag = "WEP";
gboolean is_dynamic_wep = FALSE;
if (!verify_leap (s_wsec, s_8021x, adhoc, error))
return FALSE;
if (leap_username) {
tag = "LEAP";
} else {
/* Static or Dynamic WEP */
if (!verify_dynamic_wep (s_wsec, s_8021x, adhoc, error))
return FALSE;
if (s_8021x || (key_mgmt && !strcmp (key_mgmt, "ieee8021x"))) {
is_dynamic_wep = TRUE;
tag = "Dynamic WEP";
}
}
/* Nothing WPA-related can be set */
if (!verify_no_wpa (s_wsec, tag, error))
return FALSE;
if (leap_username) {
/* LEAP */
g_object_set (s_wsec,
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x",
NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap",
NULL);
} else if (is_dynamic_wep) {
/* Dynamic WEP */
g_object_set (s_wsec,
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x",
NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open",
NULL);
nm_setting_wireless_security_add_pairwise (s_wsec, "wep40");
nm_setting_wireless_security_add_pairwise (s_wsec, "wep104");
nm_setting_wireless_security_add_group (s_wsec, "wep40");
nm_setting_wireless_security_add_group (s_wsec, "wep104");
if (s_8021x) {
/* Dynamic WEP requires a valid 802.1x setting since we can't
* autocomplete 802.1x.
*/
if (!nm_setting_verify (NM_SETTING (s_8021x), NULL, error))
return FALSE;
}
} else {
/* Static WEP */
g_object_set (s_wsec,
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
NULL);
}
return TRUE;
}
/* WPA/RSN */
g_assert (ap_wpa_flags != NM_802_11_AP_SEC_NONE);
g_assert (ap_rsn_flags != NM_802_11_AP_SEC_NONE);
if (leap_username) {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"WPA incompatible with non-EAP (original) LEAP");
return FALSE;
}
if (!verify_no_wep (s_wsec, "WPA", error))
return FALSE;
if (!verify_wpa_psk (s_wsec, s_8021x, adhoc, ap_wpa_flags, ap_rsn_flags, error))
return FALSE;
if (!adhoc && !verify_wpa_eap (s_wsec, s_8021x, ap_wpa_flags, ap_rsn_flags, error))
return FALSE;
if (adhoc) {
g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL);
/* Ad-Hoc does not support RSN/WPA2 */
nm_setting_wireless_security_add_proto (s_wsec, "wpa");
nm_setting_wireless_security_add_pairwise (s_wsec, "none");
nm_setting_wireless_security_add_group (s_wsec, "tkip");
} else if (s_8021x) {
g_object_set (s_wsec,
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap",
NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open",
NULL);
/* Leave proto/pairwise/group as client set them; if they are unset the
* supplicant will figure out the best combination at connect time.
*/
/* 802.1x also requires the client to completely fill in the 8021x
* setting. Since there's so much configuration required for it, there's
* no way it can be automatically completed.
*/
} else if ( (key_mgmt && !strcmp (key_mgmt, "wpa-psk"))
|| (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
|| (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) {
g_object_set (s_wsec,
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open",
NULL);
/* Leave proto/pairwise/group as client set them; if they are unset the
* supplicant will figure out the best combination at connect time.
*/
} else {
g_set_error_literal (error,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
"Failed to determine AP security information");
return FALSE;
}
return TRUE;
}

43
src/nm-wifi-ap-utils.h Normal file
View file

@ -0,0 +1,43 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* (C) Copyright 2011 Red Hat, Inc.
*/
#ifndef NM_WIFI_AP_UTILS_H
#define NM_WIFI_AP_UTILS_H
#include <net/ethernet.h>
#include <NetworkManager.h>
#include <nm-connection.h>
#include <nm-setting-wireless.h>
#include <nm-setting-wireless-security.h>
#include <nm-setting-8021x.h>
gboolean nm_ap_utils_complete_connection (const GByteArray *ssid,
const guint8 bssid[ETH_ALEN],
NM80211Mode mode,
guint32 flags,
guint32 wpa_flags,
guint32 rsn_flags,
NMConnection *connection,
gboolean lock_bssid,
GError **error);
#endif /* NM_WIFI_AP_UTILS_H */

View file

@ -24,6 +24,7 @@
#include <string.h>
#include "nm-wifi-ap.h"
#include "nm-wifi-ap-utils.h"
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
#include "nm-logging.h"
@ -1275,6 +1276,27 @@ nm_ap_check_compatible (NMAccessPoint *self,
nm_ap_get_mode (self));
}
gboolean
nm_ap_complete_connection (NMAccessPoint *self,
NMConnection *connection,
gboolean lock_bssid,
GError **error)
{
NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (self);
g_return_val_if_fail (connection != NULL, FALSE);
return nm_ap_utils_complete_connection (priv->ssid,
priv->address.ether_addr_octet,
priv->mode,
priv->flags,
priv->wpa_flags,
priv->rsn_flags,
connection,
lock_bssid,
error);
}
static gboolean
capabilities_compatible (guint32 a_flags, guint32 b_flags)
{

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2004 - 2010 Red Hat, Inc.
* Copyright (C) 2004 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@ -117,6 +117,11 @@ guint32 nm_ap_add_security_from_ie (guint32 flags,
gboolean nm_ap_check_compatible (NMAccessPoint *self,
NMConnection *connection);
gboolean nm_ap_complete_connection (NMAccessPoint *self,
NMConnection *connection,
gboolean lock_bssid,
GError **error);
NMAccessPoint * nm_ap_match_in_list (NMAccessPoint *find_ap,
GSList *ap_list,
gboolean strict_match);

View file

@ -776,9 +776,11 @@ pk_add_cb (NMAuthChain *chain,
NMAuthCallResult result;
GError *error = NULL, *add_error = NULL;
NMConnection *connection;
NMSysconfigConnection *added;
NMSysconfigConnection *added = NULL;
gulong caller_uid = G_MAXULONG;
char *error_desc = NULL;
NMSettingsAddCallback callback;
gpointer callback_data;
priv->auths = g_slist_remove (priv->auths, chain);
@ -830,9 +832,7 @@ pk_add_cb (NMAuthChain *chain,
}
added = add_new_connection (self, connection, &add_error);
if (added)
dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (added)));
else {
if (!added) {
error = g_error_new (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_ADD_FAILED,
"Saving connection failed: (%d) %s",
@ -842,37 +842,45 @@ pk_add_cb (NMAuthChain *chain,
}
done:
if (error)
dbus_g_method_return_error (context, error);
callback = nm_auth_chain_get_data (chain, "callback");
callback_data = nm_auth_chain_get_data (chain, "callback-data");
callback (self, added, error, context, callback_data);
g_clear_error (&error);
nm_auth_chain_unref (chain);
}
static void
impl_settings_add_connection (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context)
add_cb (NMSettings *self,
NMSysconfigConnection *connection,
GError *error,
DBusGMethodInvocation *context,
gpointer user_data)
{
if (error)
dbus_g_method_return_error (context, error);
else
dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection)));
}
void
nm_settings_add_connection (NMSettings *self,
NMConnection *connection,
DBusGMethodInvocation *context,
NMSettingsAddCallback callback,
gpointer user_data)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
NMAuthChain *chain;
NMConnection *connection;
GError *error = NULL;
connection = nm_connection_new_from_hash (settings, &error);
if (!connection) {
g_assert (error);
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
GError *error;
/* Do any of the plugins support adding? */
if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED,
"None of the registered plugins support add.");
dbus_g_method_return_error (context, error);
callback (self, NULL, error, context, user_data);
g_error_free (error);
return;
}
@ -882,7 +890,28 @@ impl_settings_add_connection (NMSettings *self,
g_assert (chain);
priv->auths = g_slist_append (priv->auths, chain);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE);
nm_auth_chain_set_data (chain, "connection", connection, g_object_unref);
nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref);
nm_auth_chain_set_data (chain, "callback", callback, NULL);
nm_auth_chain_set_data (chain, "callback-data", user_data, NULL);
}
static void
impl_settings_add_connection (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context)
{
NMConnection *connection;
GError *error = NULL;
connection = nm_connection_new_from_hash (settings, &error);
if (connection) {
nm_settings_add_connection (self, connection, context, add_cb, NULL);
g_object_unref (connection);
} else {
g_assert (error);
dbus_g_method_return_error (context, error);
g_error_free (error);
}
}
static void

View file

@ -84,6 +84,18 @@ void nm_settings_for_each_connection (NMSettings *settings,
NMSettingsForEachFunc for_each_func,
gpointer user_data);
typedef void (*NMSettingsAddCallback) (NMSettings *settings,
NMSysconfigConnection *connection,
GError *error,
DBusGMethodInvocation *context,
gpointer user_data);
void nm_settings_add_connection (NMSettings *self,
NMConnection *connection,
DBusGMethodInvocation *context,
NMSettingsAddCallback callback,
gpointer user_data);
/* Returns a list of NMSysconfigConnections. Caller must free the list with
* g_slist_free().
*/

View file

@ -6,7 +6,10 @@ INCLUDES = \
-I$(top_srcdir)/src \
-I$(top_builddir)/src
noinst_PROGRAMS = test-dhcp-options test-policy-hosts
noinst_PROGRAMS = \
test-dhcp-options \
test-policy-hosts \
test-wifi-ap-utils
####### DHCP options test #######
@ -39,6 +42,20 @@ test_policy_hosts_LDADD = \
$(top_builddir)/src/libtest-policy-hosts.la \
$(GLIB_LIBS)
####### wifi ap utils test #######
test_wifi_ap_utils_SOURCES = \
test-wifi-ap-utils.c
test_wifi_ap_utils_CPPFLAGS = \
$(GLIB_CFLAGS)
test_wifi_ap_utils_LDADD = \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/src/libtest-wifi-ap-utils.la \
$(GLIB_LIBS) \
$(DBUS_LIBS)
####### secret agent interface test #######
EXTRA_DIST = test-secret-agent.py
@ -50,6 +67,7 @@ if WITH_TESTS
check-local: test-dhcp-options test-policy-hosts
$(abs_builddir)/test-dhcp-options
$(abs_builddir)/test-policy-hosts
$(abs_builddir)/test-wifi-ap-utils
endif

View file

@ -0,0 +1,973 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* 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, 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) 2011 Red Hat, Inc.
*
*/
#include <glib.h>
#include <string.h>
#include "nm-wifi-ap-utils.h"
#include "nm-setting-connection.h"
#include "nm-setting-wireless.h"
#include "nm-setting-wireless-security.h"
#include "nm-setting-8021x.h"
#define DEBUG 1
/*******************************************/
#define COMPARE(src, expected, success, error, edomain, ecode) \
{ \
if (expected) { \
if (!success) { \
g_assert (error != NULL); \
g_warning ("Failed to complete connection: (%d) %s", error->code, error->message); \
} \
g_assert (success == TRUE); \
g_assert (error == NULL); \
\
success = nm_connection_compare (src, expected, NM_SETTING_COMPARE_FLAG_EXACT); \
if (success == FALSE && DEBUG) { \
g_message ("\n- COMPLETED ---------------------------------\n"); \
nm_connection_dump (src); \
g_message ("+ EXPECTED ++++++++++++++++++++++++++++++++++++\n"); \
nm_connection_dump (expected); \
g_message ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); \
} \
g_assert (success == TRUE); \
} else { \
if (success) { \
g_message ("\n- COMPLETED ---------------------------------\n"); \
nm_connection_dump (src); \
} \
g_assert (success == FALSE); \
g_assert_error (error, edomain, ecode); \
} \
\
g_clear_error (&error); \
}
static gboolean
complete_connection (const char *ssid,
const guint8 bssid[ETH_ALEN],
NM80211Mode mode,
guint32 flags,
guint32 wpa_flags,
guint32 rsn_flags,
gboolean lock_bssid,
NMConnection *src,
GError **error)
{
GByteArray *tmp;
gboolean success;
tmp = g_byte_array_sized_new (strlen (ssid));
g_byte_array_append (tmp, (const guint8 *) ssid, strlen (ssid));
success = nm_ap_utils_complete_connection (tmp,
bssid,
mode,
flags,
wpa_flags,
rsn_flags,
src,
lock_bssid,
error);
g_byte_array_free (tmp, TRUE);
return success;
}
static NMConnection *
create_expected (const char *ssid,
const guint8 *bssid,
NM80211Mode mode,
gboolean add_security,
gboolean add_8021x,
const char *key_mgmt,
const char *auth_alg,
NMSettingWireless **out_s_wifi,
NMSettingWirelessSecurity **out_s_wsec,
NMSetting8021x **out_s_8021x)
{
NMConnection *connection;
NMSettingWireless *s_wifi = NULL;
NMSettingWirelessSecurity *s_wsec = NULL;
NMSetting8021x *s_8021x = NULL;
GByteArray *tmp;
connection = nm_connection_new ();
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
/* SSID */
tmp = g_byte_array_sized_new (strlen (ssid));
g_byte_array_append (tmp, (const guint8 *) ssid, strlen (ssid));
g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, tmp, NULL);
g_byte_array_free (tmp, TRUE);
/* BSSID */
if (bssid) {
tmp = g_byte_array_sized_new (ETH_ALEN);
g_byte_array_append (tmp, bssid, ETH_ALEN);
g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, tmp, NULL);
g_byte_array_free (tmp, TRUE);
}
if (mode == NM_802_11_MODE_INFRA)
g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, "infrastructure", NULL);
else if (mode == NM_802_11_MODE_ADHOC)
g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, "adhoc", NULL);
else
g_assert_not_reached ();
if (add_security) {
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
g_object_set (G_OBJECT (s_wifi),
NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
NULL);
if (key_mgmt)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, NULL);
if (auth_alg)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL);
if (add_8021x) {
s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
}
}
if (out_s_wifi)
*out_s_wifi = s_wifi;
if (out_s_wsec)
*out_s_wsec = s_wsec;
if (out_s_8021x)
*out_s_8021x = s_8021x;
return connection;
}
static NMSettingWireless *
get_wifi_setting (NMConnection *connection, gboolean add_if_absent)
{
NMSettingWireless *s_wifi;
s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
if (add_if_absent) {
if (!s_wifi) {
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
}
g_object_set (G_OBJECT (s_wifi),
NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
NULL);
}
return s_wifi;
}
static void
fill_wep (NMConnection *connection,
const char *key0,
guint32 tx_keyidx,
const char *auth_alg,
gboolean set_s_wifi)
{
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
s_wifi = get_wifi_setting (connection, set_s_wifi);
s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
if (!s_wsec) {
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
}
if (key0) {
g_object_set (G_OBJECT (s_wsec),
NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, key0,
NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, tx_keyidx,
NULL);
}
if (auth_alg)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL);
}
static void
fill_leap (NMConnection *connection,
const char *leap_username,
gboolean set_auth_alg,
gboolean set_key_mgmt,
gboolean set_s_wifi)
{
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
s_wifi = get_wifi_setting (connection, set_s_wifi);
s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
if (!s_wsec) {
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
}
if (leap_username)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, NULL);
if (set_auth_alg)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", NULL);
if (set_key_mgmt)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL);
}
static void
fill_wpa_psk (NMConnection *connection,
const char *key_mgmt,
const char *psk,
const char *auth_alg,
gboolean set_s_wifi)
{
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
s_wifi = get_wifi_setting (connection, set_s_wifi);
s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
if (!s_wsec) {
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
}
if (key_mgmt)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, NULL);
if (psk)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL);
if (auth_alg)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL);
}
static void
fill_8021x (NMConnection *connection,
NMSetting8021x *s_8021x,
const char *key_mgmt,
const char *auth_alg,
gboolean set_s_wifi)
{
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
s_wifi = get_wifi_setting (connection, set_s_wifi);
s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
if (!s_wsec) {
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
}
if (key_mgmt)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, NULL);
if (auth_alg)
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL);
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
}
/*******************************************/
static void
test_lock_bssid (void)
{
NMConnection *src, *expected;
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
const char *ssid = "blahblah";
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
success = complete_connection (ssid, bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
TRUE,
src, &error);
expected = create_expected (ssid, bssid, NM_802_11_MODE_INFRA, FALSE, FALSE, NULL, NULL, NULL, NULL, NULL);
COMPARE (src, expected, success, error, 0, 0);
g_object_unref (src);
g_object_unref (expected);
}
/*******************************************/
static void
test_open_ap_empty_connection (void)
{
NMConnection *src, *expected;
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
const char *ssid = "blahblah";
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
success = complete_connection (ssid, bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
FALSE,
src, &error);
expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, FALSE, FALSE, NULL, NULL, NULL, NULL, NULL);
COMPARE (src, expected, success, error, 0, 0);
g_object_unref (src);
g_object_unref (expected);
}
/*******************************************/
static void
test_open_ap_leap_connection_1 (gboolean fill_wifi)
{
NMConnection *src;
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
s_wifi = get_wifi_setting (src, fill_wifi);
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", NULL);
nm_connection_add_setting (src, NM_SETTING (s_wsec));
success = complete_connection ("blahblah", bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
FALSE,
src, &error);
/* We expect failure */
COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
g_object_unref (src);
}
/*******************************************/
static void
test_open_ap_leap_connection_2 (void)
{
NMConnection *src;
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
s_wifi = get_wifi_setting (src, TRUE);
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL);
nm_connection_add_setting (src, NM_SETTING (s_wsec));
success = complete_connection ("blahblah", bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
FALSE,
src, &error);
/* We expect failure */
COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
g_object_unref (src);
}
/*******************************************/
static void
test_open_ap_wep_connection (gboolean fill_wifi)
{
NMConnection *src;
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
fill_wep (src, "11111111111111111111111111", 0, "open", fill_wifi);
success = complete_connection ("blahblah", bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
FALSE,
src, &error);
/* We expect failure */
COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
g_object_unref (src);
}
/*******************************************/
static void
test_ap_wpa_psk_connection_base (const char *key_mgmt,
const char *auth_alg,
guint32 flags,
guint32 wpa_flags,
guint32 rsn_flags,
gboolean fill_wifi)
{
NMConnection *src;
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
fill_wpa_psk (src, key_mgmt, "asdfasdfasdfasdfasdfafs", auth_alg, fill_wifi);
success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA,
flags, wpa_flags, rsn_flags,
FALSE, src, &error);
/* We expect failure */
COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
g_object_unref (src);
}
static void
test_open_ap_wpa_psk_connection_1 (void)
{
test_ap_wpa_psk_connection_base (NULL, NULL,
NM_802_11_AP_FLAGS_NONE,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE);
}
static void
test_open_ap_wpa_psk_connection_2 (void)
{
test_ap_wpa_psk_connection_base (NULL, NULL,
NM_802_11_AP_FLAGS_NONE,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE);
}
static void
test_open_ap_wpa_psk_connection_3 (void)
{
test_ap_wpa_psk_connection_base (NULL, "open",
NM_802_11_AP_FLAGS_NONE,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE);
}
static void
test_open_ap_wpa_psk_connection_4 (void)
{
test_ap_wpa_psk_connection_base (NULL, "shared",
NM_802_11_AP_FLAGS_NONE,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE);
}
static void
test_open_ap_wpa_psk_connection_5 (void)
{
test_ap_wpa_psk_connection_base ("wpa-psk", "open",
NM_802_11_AP_FLAGS_NONE,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE);
}
/*******************************************/
static void
test_ap_wpa_eap_connection_base (const char *key_mgmt,
const char *auth_alg,
guint32 flags,
guint32 wpa_flags,
guint32 rsn_flags,
gboolean fill_wifi,
guint error_domain,
guint error_code)
{
NMConnection *src;
NMSetting8021x *s_8021x;
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
gboolean success;
GError *error = NULL;
const char *ssid = "blahblah";
src = nm_connection_new ();
s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
fill_8021x (src, s_8021x, key_mgmt, auth_alg, fill_wifi);
success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA,
flags, wpa_flags, rsn_flags,
FALSE, src, &error);
if (!wpa_flags && !rsn_flags) {
if (!flags) {
/* Failure expected */
COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
} else if (flags & NM_802_11_AP_FLAGS_PRIVACY) {
COMPARE (src, NULL, success, error, error_domain, error_code);
}
} else
g_assert_not_reached ();
g_object_unref (src);
}
static void
test_open_ap_wpa_eap_connection_1 (void)
{
test_ap_wpa_eap_connection_base (NULL, NULL,
NM_802_11_AP_FLAGS_NONE,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE, 0, 0);
}
static void
test_open_ap_wpa_eap_connection_2 (void)
{
test_ap_wpa_eap_connection_base (NULL, NULL,
NM_802_11_AP_FLAGS_NONE,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
TRUE, 0, 0);
}
static void
test_open_ap_wpa_eap_connection_3 (void)
{
test_ap_wpa_eap_connection_base (NULL, "open",
NM_802_11_AP_FLAGS_NONE,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE, 0, 0);
}
static void
test_open_ap_wpa_eap_connection_4 (void)
{
test_ap_wpa_eap_connection_base (NULL, "shared",
NM_802_11_AP_FLAGS_NONE,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE, 0, 0);
}
static void
test_open_ap_wpa_eap_connection_5 (void)
{
test_ap_wpa_eap_connection_base ("wpa-eap", "open",
NM_802_11_AP_FLAGS_NONE,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE, 0, 0);
}
/*******************************************/
static void
test_priv_ap_empty_connection (void)
{
NMConnection *src, *expected;
NMSettingWirelessSecurity *s_wsec;
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
const char *ssid = "blahblah";
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
success = complete_connection (ssid, bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
FALSE,
src, &error);
/* Static WEP connection expected */
expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, FALSE, "none", NULL, NULL, &s_wsec, NULL);
COMPARE (src, expected, success, error, 0, 0);
g_object_unref (src);
g_object_unref (expected);
}
/*******************************************/
static void
test_priv_ap_leap_connection_1 (gboolean fill_wifi)
{
NMConnection *src, *expected;
NMSettingWirelessSecurity *s_wsec;
const char *ssid = "blahblah";
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
const char *leap_username = "Bill Smith";
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
fill_leap (src, leap_username, TRUE, FALSE, TRUE);
success = complete_connection (ssid, bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
FALSE,
src, &error);
/* We expect success here; since LEAP APs just set the 'privacy' flag
* there's no way to determine from the AP's beacon whether it's static WEP,
* dynamic WEP, or LEAP.
*/
s_wsec = NULL;
expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, FALSE, "ieee8021x", "leap", NULL, &s_wsec, NULL);
g_assert (s_wsec);
g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, NULL);
COMPARE (src, expected, success, error, 0, 0);
g_object_unref (src);
}
/*******************************************/
static void
test_priv_ap_leap_connection_2 (void)
{
NMConnection *src;
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
fill_leap (src, NULL, TRUE, TRUE, TRUE);
success = complete_connection ("blahblah", bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
FALSE,
src, &error);
/* We expect failure here, we need a LEAP username */
COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME);
g_object_unref (src);
}
/*******************************************/
static void
test_priv_ap_dynamic_wep_1 (void)
{
NMConnection *src, *expected;
const char *ssid = "blahblah";
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
NMSettingWirelessSecurity *s_wsec;
NMSetting8021x *s_8021x;
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
nm_setting_802_1x_add_eap_method (s_8021x, "peap");
g_object_set (G_OBJECT (s_8021x),
NM_SETTING_802_1X_IDENTITY, "Bill Smith",
NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2",
NULL);
fill_8021x (src, s_8021x, "ieee8021x", "open", TRUE);
success = complete_connection (ssid, bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
FALSE,
src, &error);
/* We expect a completed Dynamic WEP connection */
s_8021x = NULL;
expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, TRUE, "ieee8021x", "open", NULL, &s_wsec, &s_8021x);
nm_setting_wireless_security_add_pairwise (s_wsec, "wep40");
nm_setting_wireless_security_add_pairwise (s_wsec, "wep104");
nm_setting_wireless_security_add_group (s_wsec, "wep40");
nm_setting_wireless_security_add_group (s_wsec, "wep104");
nm_setting_802_1x_add_eap_method (s_8021x, "peap");
g_object_set (G_OBJECT (s_8021x),
NM_SETTING_802_1X_IDENTITY, "Bill Smith",
NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2",
NULL);
COMPARE (src, expected, success, error, 0, 0);
g_object_unref (src);
}
/*******************************************/
static void
test_priv_ap_dynamic_wep_2 (void)
{
NMConnection *src, *expected;
const char *ssid = "blahblah";
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
NMSettingWirelessSecurity *s_wsec;
NMSetting8021x *s_8021x;
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
nm_setting_802_1x_add_eap_method (s_8021x, "peap");
g_object_set (G_OBJECT (s_8021x),
NM_SETTING_802_1X_IDENTITY, "Bill Smith",
NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2",
NULL);
fill_8021x (src, s_8021x, NULL, "open", TRUE);
success = complete_connection (ssid, bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
FALSE,
src, &error);
/* We expect a completed Dynamic WEP connection */
s_8021x = NULL;
expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, TRUE, "ieee8021x", "open", NULL, &s_wsec, &s_8021x);
nm_setting_wireless_security_add_pairwise (s_wsec, "wep40");
nm_setting_wireless_security_add_pairwise (s_wsec, "wep104");
nm_setting_wireless_security_add_group (s_wsec, "wep40");
nm_setting_wireless_security_add_group (s_wsec, "wep104");
nm_setting_802_1x_add_eap_method (s_8021x, "peap");
g_object_set (G_OBJECT (s_8021x),
NM_SETTING_802_1X_IDENTITY, "Bill Smith",
NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2",
NULL);
COMPARE (src, expected, success, error, 0, 0);
g_object_unref (src);
}
/*******************************************/
static void
test_priv_ap_dynamic_wep_3 (void)
{
NMConnection *src;
const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
NMSetting8021x *s_8021x;
gboolean success;
GError *error = NULL;
src = nm_connection_new ();
s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
nm_setting_802_1x_add_eap_method (s_8021x, "peap");
g_object_set (G_OBJECT (s_8021x),
NM_SETTING_802_1X_IDENTITY, "Bill Smith",
NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2",
NULL);
fill_8021x (src, s_8021x, "ieee8021x", "shared", TRUE);
success = complete_connection ("blahblah", bssid,
NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE,
FALSE,
src, &error);
/* Expect failure; shared is not compatible with dynamic WEP */
COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
g_object_unref (src);
}
/*******************************************/
static void
test_priv_ap_wpa_psk_connection_1 (void)
{
test_ap_wpa_psk_connection_base (NULL, NULL,
NM_802_11_AP_FLAGS_PRIVACY,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE);
}
static void
test_priv_ap_wpa_psk_connection_2 (void)
{
test_ap_wpa_psk_connection_base (NULL, NULL,
NM_802_11_AP_FLAGS_PRIVACY,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
TRUE);
}
static void
test_priv_ap_wpa_psk_connection_3 (void)
{
test_ap_wpa_psk_connection_base (NULL, "open",
NM_802_11_AP_FLAGS_PRIVACY,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE);
}
static void
test_priv_ap_wpa_psk_connection_4 (void)
{
test_ap_wpa_psk_connection_base (NULL, "shared",
NM_802_11_AP_FLAGS_PRIVACY,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE);
}
static void
test_priv_ap_wpa_psk_connection_5 (void)
{
test_ap_wpa_psk_connection_base ("wpa-psk", "open",
NM_802_11_AP_FLAGS_PRIVACY,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE);
}
/*******************************************/
static void
test_priv_ap_wpa_eap_connection_1 (void)
{
test_ap_wpa_eap_connection_base (NULL, NULL,
NM_802_11_AP_FLAGS_PRIVACY,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE,
NM_SETTING_802_1X_ERROR,
NM_SETTING_802_1X_ERROR_MISSING_PROPERTY);
}
static void
test_priv_ap_wpa_eap_connection_2 (void)
{
test_ap_wpa_eap_connection_base (NULL, NULL,
NM_802_11_AP_FLAGS_PRIVACY,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
TRUE,
NM_SETTING_802_1X_ERROR,
NM_SETTING_802_1X_ERROR_MISSING_PROPERTY);
}
static void
test_priv_ap_wpa_eap_connection_3 (void)
{
test_ap_wpa_eap_connection_base (NULL, "open",
NM_802_11_AP_FLAGS_PRIVACY,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE,
NM_SETTING_802_1X_ERROR,
NM_SETTING_802_1X_ERROR_MISSING_PROPERTY);
}
static void
test_priv_ap_wpa_eap_connection_4 (void)
{
test_ap_wpa_eap_connection_base (NULL, "shared",
NM_802_11_AP_FLAGS_PRIVACY,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
}
static void
test_priv_ap_wpa_eap_connection_5 (void)
{
test_ap_wpa_eap_connection_base ("wpa-eap", "open",
NM_802_11_AP_FLAGS_PRIVACY,
NM_802_11_AP_SEC_NONE,
NM_802_11_AP_SEC_NONE,
FALSE,
NM_SETTING_WIRELESS_SECURITY_ERROR,
NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
}
/*******************************************/
#if GLIB_CHECK_VERSION(2,25,12)
typedef GTestFixtureFunc TCFunc;
#else
typedef void (*TCFunc)(void);
#endif
#define TESTCASE(t, d) g_test_create_case (#t, 0, (gconstpointer) d, NULL, (TCFunc) t, NULL)
int main (int argc, char **argv)
{
GTestSuite *suite;
g_type_init ();
g_test_init (&argc, &argv, NULL);
suite = g_test_get_root ();
g_test_suite_add (suite, TESTCASE (test_lock_bssid, NULL));
/* Open AP tests; make sure that connections to be completed that have
* various security-related settings already set cause the completion
* to fail.
*/
g_test_suite_add (suite, TESTCASE (test_open_ap_empty_connection, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_leap_connection_1, TRUE));
g_test_suite_add (suite, TESTCASE (test_open_ap_leap_connection_1, FALSE));
g_test_suite_add (suite, TESTCASE (test_open_ap_leap_connection_2, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_wep_connection, TRUE));
g_test_suite_add (suite, TESTCASE (test_open_ap_wep_connection, FALSE));
g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_1, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_2, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_3, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_4, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_5, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_1, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_2, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_3, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_4, NULL));
g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_5, NULL));
/* WEP AP tests */
g_test_suite_add (suite, TESTCASE (test_priv_ap_empty_connection, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_leap_connection_1, FALSE));
g_test_suite_add (suite, TESTCASE (test_priv_ap_leap_connection_2, FALSE));
g_test_suite_add (suite, TESTCASE (test_priv_ap_dynamic_wep_1, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_dynamic_wep_2, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_dynamic_wep_3, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_1, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_2, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_3, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_4, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_5, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_1, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_2, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_3, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_4, NULL));
g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_5, NULL));
return g_test_run ();
}