mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-07 13:40:20 +01:00
libnm-util: verify connection's 'type' setting is actually a base type
By 'base type' I mean a hardware-related type that can actually be used to activate the connection, like wifi, wired, gsm, cdma, wimax, bluetooth, etc, but not ipv4, ipv6, 8021x, etc.
This commit is contained in:
parent
78df8c49a1
commit
74a0b1d9d1
3 changed files with 306 additions and 28 deletions
|
|
@ -98,6 +98,7 @@ nm_connection_error_get_type (void)
|
|||
static const GEnumValue values[] = {
|
||||
ENUM_ENTRY (NM_CONNECTION_ERROR_UNKNOWN, "UnknownError"),
|
||||
ENUM_ENTRY (NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, "ConnectionSettingNotFound"),
|
||||
ENUM_ENTRY (NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, "ConnectionTypeInvalid"),
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
etype = g_enum_register_static ("NMConnectionError", values);
|
||||
|
|
@ -139,6 +140,7 @@ static struct SettingInfo {
|
|||
const char *name;
|
||||
GType type;
|
||||
guint32 priority;
|
||||
gboolean base_type;
|
||||
GQuark error_quark;
|
||||
} default_map[DEFAULT_MAP_SIZE] = { { NULL } };
|
||||
|
||||
|
|
@ -170,7 +172,11 @@ setting_unregister (const char *name)
|
|||
#endif
|
||||
|
||||
static void
|
||||
register_one_setting (const char *name, GType type, GQuark error_quark, guint32 priority)
|
||||
register_one_setting (const char *name,
|
||||
GType type,
|
||||
GQuark error_quark,
|
||||
guint32 priority,
|
||||
gboolean base_type)
|
||||
{
|
||||
static guint32 i = 0;
|
||||
|
||||
|
|
@ -181,6 +187,7 @@ register_one_setting (const char *name, GType type, GQuark error_quark, guint32
|
|||
default_map[i].type = type;
|
||||
default_map[i].error_quark = error_quark;
|
||||
default_map[i].priority = priority;
|
||||
default_map[i].base_type = base_type;
|
||||
i++;
|
||||
|
||||
setting_register (name, type);
|
||||
|
|
@ -197,82 +204,82 @@ register_default_settings (void)
|
|||
register_one_setting (NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_TYPE_SETTING_CONNECTION,
|
||||
NM_SETTING_CONNECTION_ERROR,
|
||||
0);
|
||||
0, FALSE);
|
||||
|
||||
register_one_setting (NM_SETTING_WIRED_SETTING_NAME,
|
||||
NM_TYPE_SETTING_WIRED,
|
||||
NM_SETTING_WIRED_ERROR,
|
||||
1);
|
||||
1, TRUE);
|
||||
|
||||
register_one_setting (NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_TYPE_SETTING_WIRELESS,
|
||||
NM_SETTING_WIRELESS_ERROR,
|
||||
1);
|
||||
1, TRUE);
|
||||
|
||||
register_one_setting (NM_SETTING_OLPC_MESH_SETTING_NAME,
|
||||
NM_TYPE_SETTING_OLPC_MESH,
|
||||
NM_SETTING_OLPC_MESH_ERROR,
|
||||
1);
|
||||
1, TRUE);
|
||||
|
||||
register_one_setting (NM_SETTING_GSM_SETTING_NAME,
|
||||
NM_TYPE_SETTING_GSM,
|
||||
NM_SETTING_GSM_ERROR,
|
||||
1);
|
||||
1, TRUE);
|
||||
|
||||
register_one_setting (NM_SETTING_CDMA_SETTING_NAME,
|
||||
NM_TYPE_SETTING_CDMA,
|
||||
NM_SETTING_CDMA_ERROR,
|
||||
1);
|
||||
1, TRUE);
|
||||
|
||||
register_one_setting (NM_SETTING_BLUETOOTH_SETTING_NAME,
|
||||
NM_TYPE_SETTING_BLUETOOTH,
|
||||
NM_SETTING_BLUETOOTH_ERROR,
|
||||
1);
|
||||
1, TRUE);
|
||||
|
||||
register_one_setting (NM_SETTING_WIMAX_SETTING_NAME,
|
||||
NM_TYPE_SETTING_WIMAX,
|
||||
NM_SETTING_WIMAX_ERROR,
|
||||
1);
|
||||
1, TRUE);
|
||||
|
||||
register_one_setting (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
|
||||
NM_TYPE_SETTING_WIRELESS_SECURITY,
|
||||
NM_SETTING_WIRELESS_SECURITY_ERROR,
|
||||
2);
|
||||
2, FALSE);
|
||||
|
||||
register_one_setting (NM_SETTING_SERIAL_SETTING_NAME,
|
||||
NM_TYPE_SETTING_SERIAL,
|
||||
NM_SETTING_SERIAL_ERROR,
|
||||
2);
|
||||
2, FALSE);
|
||||
|
||||
register_one_setting (NM_SETTING_PPP_SETTING_NAME,
|
||||
NM_TYPE_SETTING_PPP,
|
||||
NM_SETTING_PPP_ERROR,
|
||||
3);
|
||||
3, FALSE);
|
||||
|
||||
register_one_setting (NM_SETTING_PPPOE_SETTING_NAME,
|
||||
NM_TYPE_SETTING_PPPOE,
|
||||
NM_SETTING_PPPOE_ERROR,
|
||||
3);
|
||||
3, TRUE);
|
||||
|
||||
register_one_setting (NM_SETTING_802_1X_SETTING_NAME,
|
||||
NM_TYPE_SETTING_802_1X,
|
||||
NM_SETTING_802_1X_ERROR,
|
||||
3);
|
||||
3, FALSE);
|
||||
|
||||
register_one_setting (NM_SETTING_VPN_SETTING_NAME,
|
||||
NM_TYPE_SETTING_VPN,
|
||||
NM_SETTING_VPN_ERROR,
|
||||
4);
|
||||
4, TRUE);
|
||||
|
||||
register_one_setting (NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_TYPE_SETTING_IP4_CONFIG,
|
||||
NM_SETTING_IP4_CONFIG_ERROR,
|
||||
6);
|
||||
6, FALSE);
|
||||
|
||||
register_one_setting (NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_TYPE_SETTING_IP6_CONFIG,
|
||||
NM_SETTING_IP6_CONFIG_ERROR,
|
||||
6);
|
||||
6, FALSE);
|
||||
|
||||
/* Be sure to update DEFAULT_MAP_SIZE if you add another setting!! */
|
||||
}
|
||||
|
|
@ -290,6 +297,18 @@ get_priority_for_setting_type (GType type)
|
|||
return G_MAXUINT32;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_base_type_for_setting_type (GType type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; default_map[i].name; i++) {
|
||||
if (default_map[i].type == type)
|
||||
return default_map[i].base_type;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_connection_lookup_setting_type:
|
||||
* @name: a setting name
|
||||
|
|
@ -693,15 +712,17 @@ nm_connection_verify (NMConnection *connection, GError **error)
|
|||
gpointer value;
|
||||
GSList *all_settings = NULL;
|
||||
gboolean success = TRUE;
|
||||
const char *ctype;
|
||||
GType base_type;
|
||||
|
||||
if (error)
|
||||
g_return_val_if_fail (*error == NULL, FALSE);
|
||||
|
||||
if (!NM_IS_CONNECTION (connection)) {
|
||||
g_set_error (error,
|
||||
NM_SETTING_CONNECTION_ERROR,
|
||||
NM_SETTING_CONNECTION_ERROR_UNKNOWN,
|
||||
"invalid connection; failed verification");
|
||||
g_set_error_literal (error,
|
||||
NM_SETTING_CONNECTION_ERROR,
|
||||
NM_SETTING_CONNECTION_ERROR_UNKNOWN,
|
||||
"invalid connection; failed verification");
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
|
||||
}
|
||||
|
||||
|
|
@ -710,10 +731,10 @@ nm_connection_verify (NMConnection *connection, GError **error)
|
|||
/* First, make sure there's at least 'connection' setting */
|
||||
s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
||||
if (!s_con) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND,
|
||||
"connection setting not found");
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND,
|
||||
"connection setting not found");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -726,9 +747,42 @@ nm_connection_verify (NMConnection *connection, GError **error)
|
|||
g_hash_table_iter_init (&iter, priv->settings);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value) && success)
|
||||
success = nm_setting_verify (NM_SETTING (value), all_settings, error);
|
||||
|
||||
g_slist_free (all_settings);
|
||||
return success;
|
||||
|
||||
if (success == FALSE)
|
||||
return FALSE;
|
||||
|
||||
/* Now make sure the given 'type' setting can actually be the base setting
|
||||
* of the connection. Can't have type=ppp for example.
|
||||
*/
|
||||
ctype = nm_setting_connection_get_connection_type (NM_SETTING_CONNECTION (s_con));
|
||||
if (!ctype) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID,
|
||||
"connection type missing");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
base_type = nm_connection_lookup_setting_type (ctype);
|
||||
if (base_type == 0) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID,
|
||||
"base setting GType not found");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!get_base_type_for_setting_type (base_type)) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID,
|
||||
"connection type '%s' is not a base type",
|
||||
ctype);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ G_BEGIN_DECLS
|
|||
* @NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND: the #NMConnection object
|
||||
* did not contain the required #NMSettingConnection object, which must be
|
||||
* present for all connections
|
||||
* @NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID: the 'type' property of the
|
||||
* 'connection' setting did not point to a valid connection base type; ie
|
||||
* it was not a hardware-related setting like #NMSettingWired or
|
||||
* #NMSettingWireless.
|
||||
*
|
||||
* Describes errors that may result from operations involving a #NMConnection.
|
||||
*
|
||||
|
|
@ -69,7 +73,8 @@ G_BEGIN_DECLS
|
|||
typedef enum
|
||||
{
|
||||
NM_CONNECTION_ERROR_UNKNOWN = 0,
|
||||
NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND
|
||||
NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND,
|
||||
NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID
|
||||
} NMConnectionError;
|
||||
|
||||
#define NM_TYPE_CONNECTION_ERROR (nm_connection_error_get_type ())
|
||||
|
|
|
|||
|
|
@ -29,11 +29,13 @@
|
|||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-vpn.h"
|
||||
#include "nm-setting-gsm.h"
|
||||
#include "nm-setting-cdma.h"
|
||||
#include "nm-setting-wired.h"
|
||||
#include "nm-setting-wireless-security.h"
|
||||
#include "nm-setting-ip6-config.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
#include "nm-setting-pppoe.h"
|
||||
#include "nm-setting-serial.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
|
||||
static void
|
||||
|
|
@ -900,6 +902,221 @@ test_connection_diff_no_secrets (void)
|
|||
g_object_unref (b);
|
||||
}
|
||||
|
||||
static void
|
||||
add_generic_settings (NMConnection *connection, const char *ctype)
|
||||
{
|
||||
NMSetting *setting;
|
||||
char *uuid;
|
||||
|
||||
uuid = nm_utils_uuid_generate ();
|
||||
|
||||
setting = nm_setting_connection_new ();
|
||||
g_object_set (setting,
|
||||
NM_SETTING_CONNECTION_ID, "asdfasdfadf",
|
||||
NM_SETTING_CONNECTION_TYPE, ctype,
|
||||
NM_SETTING_CONNECTION_UUID, uuid,
|
||||
NULL);
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
g_free (uuid);
|
||||
|
||||
setting = nm_setting_ip4_config_new ();
|
||||
g_object_set (setting, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
setting = nm_setting_ip6_config_new ();
|
||||
g_object_set (setting, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
|
||||
nm_connection_add_setting (connection, setting);
|
||||
}
|
||||
|
||||
static void
|
||||
test_connection_good_base_types (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSetting *setting;
|
||||
gboolean success;
|
||||
GError *error = NULL;
|
||||
GByteArray *array;
|
||||
const guint8 bdaddr[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
|
||||
|
||||
/* Try a basic wired connection */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_WIRED_SETTING_NAME);
|
||||
setting = nm_setting_wired_new ();
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
g_object_unref (connection);
|
||||
|
||||
/* Try a wired PPPoE connection */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_PPPOE_SETTING_NAME);
|
||||
setting = nm_setting_pppoe_new ();
|
||||
g_object_set (setting, NM_SETTING_PPPOE_USERNAME, "bob smith", NULL);
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
g_object_unref (connection);
|
||||
|
||||
/* Wifi connection */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_WIRELESS_SETTING_NAME);
|
||||
|
||||
setting = nm_setting_wireless_new ();
|
||||
array = g_byte_array_new ();
|
||||
g_byte_array_append (array, (const guint8 *) "1234567", 7);
|
||||
g_object_set (setting,
|
||||
NM_SETTING_WIRELESS_SSID, array,
|
||||
NM_SETTING_WIRELESS_MODE, "infrastructure",
|
||||
NULL);
|
||||
g_byte_array_free (array, TRUE);
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
g_object_unref (connection);
|
||||
|
||||
/* Bluetooth connection */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_BLUETOOTH_SETTING_NAME);
|
||||
|
||||
setting = nm_setting_bluetooth_new ();
|
||||
array = g_byte_array_new ();
|
||||
g_byte_array_append (array, bdaddr, sizeof (bdaddr));
|
||||
g_object_set (setting,
|
||||
NM_SETTING_BLUETOOTH_BDADDR, array,
|
||||
NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
|
||||
NULL);
|
||||
g_byte_array_free (array, TRUE);
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
g_object_unref (connection);
|
||||
|
||||
/* WiMAX connection */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_WIMAX_SETTING_NAME);
|
||||
setting = nm_setting_wimax_new ();
|
||||
g_object_set (setting, NM_SETTING_WIMAX_NETWORK_NAME, "CLEAR", NULL);
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
g_object_unref (connection);
|
||||
|
||||
/* GSM connection */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_GSM_SETTING_NAME);
|
||||
|
||||
setting = nm_setting_gsm_new ();
|
||||
g_object_set (setting,
|
||||
NM_SETTING_GSM_NUMBER, "*99#",
|
||||
NM_SETTING_GSM_APN, "metered.billing.sucks",
|
||||
NULL);
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
/* CDMA connection */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_CDMA_SETTING_NAME);
|
||||
|
||||
setting = nm_setting_cdma_new ();
|
||||
g_object_set (setting,
|
||||
NM_SETTING_CDMA_NUMBER, "#777",
|
||||
NM_SETTING_CDMA_USERNAME, "foobar@vzw.com",
|
||||
NULL);
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
test_connection_bad_base_types (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSetting *setting;
|
||||
gboolean success;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Test various non-base connection types to make sure they are rejected;
|
||||
* using a fake 'wired' connection so the rest of it verifies
|
||||
*/
|
||||
|
||||
/* Connection setting */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_CONNECTION_SETTING_NAME);
|
||||
setting = nm_setting_wired_new ();
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID);
|
||||
g_assert (success == FALSE);
|
||||
g_object_unref (connection);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* PPP setting */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_PPP_SETTING_NAME);
|
||||
setting = nm_setting_wired_new ();
|
||||
nm_connection_add_setting (connection, setting);
|
||||
setting = nm_setting_ppp_new ();
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID);
|
||||
g_assert (success == FALSE);
|
||||
g_object_unref (connection);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* Serial setting */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_SERIAL_SETTING_NAME);
|
||||
setting = nm_setting_wired_new ();
|
||||
nm_connection_add_setting (connection, setting);
|
||||
setting = nm_setting_serial_new ();
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID);
|
||||
g_assert (success == FALSE);
|
||||
g_object_unref (connection);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* IP4 setting */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_IP4_CONFIG_SETTING_NAME);
|
||||
setting = nm_setting_wired_new ();
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID);
|
||||
g_assert (success == FALSE);
|
||||
g_object_unref (connection);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* IP6 setting */
|
||||
connection = nm_connection_new ();
|
||||
add_generic_settings (connection, NM_SETTING_IP6_CONFIG_SETTING_NAME);
|
||||
setting = nm_setting_wired_new ();
|
||||
nm_connection_add_setting (connection, setting);
|
||||
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID);
|
||||
g_assert (success == FALSE);
|
||||
g_object_unref (connection);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
|
@ -928,6 +1145,8 @@ int main (int argc, char **argv)
|
|||
test_connection_diff_same ();
|
||||
test_connection_diff_different ();
|
||||
test_connection_diff_no_secrets ();
|
||||
test_connection_good_base_types ();
|
||||
test_connection_bad_base_types ();
|
||||
|
||||
base = g_path_get_basename (argv[0]);
|
||||
fprintf (stdout, "%s: SUCCESS\n", base);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue