mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-11-05 19:03:31 +00:00
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:
parent
bf98469b8d
commit
215306f5a1
25 changed files with 2839 additions and 101 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
149
src/nm-device.c
149
src/nm-device.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
217
src/nm-manager.c
217
src/nm-manager.c
|
@ -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
699
src/nm-wifi-ap-utils.c
Normal 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
43
src/nm-wifi-ap-utils.h
Normal 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 */
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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().
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
973
src/tests/test-wifi-ap-utils.c
Normal file
973
src/tests/test-wifi-ap-utils.c
Normal 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 ();
|
||||
}
|
||||
|
Loading…
Reference in a new issue