summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiří Klimeš <jklimes@redhat.com>2015-11-10 14:36:20 +0100
committerJiří Klimeš <jklimes@redhat.com>2015-11-20 10:35:10 +0100
commitb41b32cb7b503ae189e53bc410748d08eb7c96ae (patch)
treec2b39768fb627fe7d4d9b934efccfe579f19563b
parentfc758cb4eaa378ecc0e48922b39c9ceee06eb02a (diff)
downloadNetworkManager-b41b32cb7b503ae189e53bc410748d08eb7c96ae.tar.gz
libnm: add nm_setting_verify_secrets() and nm_connection_verify_secrets()
for verifying the secrets, because it is not done in plain nm_setting_verify(). For simple verification of free-form string secrets, _nm_setting_verify_secret_string() helper is used.
-rw-r--r--libnm-core/nm-connection.c28
-rw-r--r--libnm-core/nm-connection.h2
-rw-r--r--libnm-core/nm-setting-adsl.c10
-rw-r--r--libnm-core/nm-setting-cdma.c10
-rw-r--r--libnm-core/nm-setting-gsm.c10
-rw-r--r--libnm-core/nm-setting-private.h5
-rw-r--r--libnm-core/nm-setting-wireless-security.c58
-rw-r--r--libnm-core/nm-setting.c47
-rw-r--r--libnm-core/nm-setting.h11
-rw-r--r--libnm/libnm.ver2
10 files changed, 182 insertions, 1 deletions
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c
index 1b5112cd60..412ca3c4a7 100644
--- a/libnm-core/nm-connection.c
+++ b/libnm-core/nm-connection.c
@@ -897,6 +897,34 @@ EXIT:
}
/**
+ * nm_connection_verify_secrets:
+ * @connection: the #NMConnection to verify in
+ * @error: location to store error, or %NULL
+ *
+ * Verifies the secrets in the connection.
+ *
+ * Returns: %TRUE if the secrets are valid, %FALSE if they are not
+ *
+ * Since: 1.2
+ **/
+gboolean
+nm_connection_verify_secrets (NMConnection *connection, GError **error)
+{
+ GHashTableIter iter;
+ NMSetting *setting;
+
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+ g_return_val_if_fail (!error || !*error, FALSE);
+
+ g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) {
+ if (!nm_setting_verify_secrets (setting, connection, error))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
* nm_connection_normalize:
* @connection: the #NMConnection to normalize
* @parameters: (allow-none) (element-type utf8 gpointer): a #GHashTable with
diff --git a/libnm-core/nm-connection.h b/libnm-core/nm-connection.h
index c76ad60768..f27ecc5bc0 100644
--- a/libnm-core/nm-connection.h
+++ b/libnm-core/nm-connection.h
@@ -145,6 +145,8 @@ gboolean nm_connection_diff (NMConnection *a,
GHashTable **out_settings);
gboolean nm_connection_verify (NMConnection *connection, GError **error);
+NM_AVAILABLE_IN_1_2
+gboolean nm_connection_verify_secrets (NMConnection *connection, GError **error);
gboolean nm_connection_normalize (NMConnection *connection,
GHashTable *parameters,
gboolean *modified,
diff --git a/libnm-core/nm-setting-adsl.c b/libnm-core/nm-setting-adsl.c
index 900e973eb7..0cf386d894 100644
--- a/libnm-core/nm-setting-adsl.c
+++ b/libnm-core/nm-setting-adsl.c
@@ -226,6 +226,15 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return TRUE;
}
+static gboolean
+verify_secrets (NMSetting *setting, NMConnection *connection, GError **error)
+{
+ return _nm_setting_verify_secret_string (NM_SETTING_ADSL_GET_PRIVATE (setting)->password,
+ NM_SETTING_ADSL_SETTING_NAME,
+ NM_SETTING_ADSL_PASSWORD,
+ error);
+}
+
static GPtrArray *
need_secrets (NMSetting *setting)
{
@@ -349,6 +358,7 @@ nm_setting_adsl_class_init (NMSettingAdslClass *setting_class)
object_class->get_property = get_property;
object_class->finalize = finalize;
parent_class->verify = verify;
+ parent_class->verify_secrets = verify_secrets;
parent_class->need_secrets = need_secrets;
/* Properties */
diff --git a/libnm-core/nm-setting-cdma.c b/libnm-core/nm-setting-cdma.c
index c09b9c9411..3c01b43f9a 100644
--- a/libnm-core/nm-setting-cdma.c
+++ b/libnm-core/nm-setting-cdma.c
@@ -162,6 +162,15 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return TRUE;
}
+static gboolean
+verify_secrets (NMSetting *setting, NMConnection *connection, GError **error)
+{
+ return _nm_setting_verify_secret_string (NM_SETTING_CDMA_GET_PRIVATE (setting)->password,
+ NM_SETTING_CDMA_SETTING_NAME,
+ NM_SETTING_CDMA_PASSWORD,
+ error);
+}
+
static GPtrArray *
need_secrets (NMSetting *setting)
{
@@ -264,6 +273,7 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class)
object_class->get_property = get_property;
object_class->finalize = finalize;
parent_class->verify = verify;
+ parent_class->verify_secrets = verify_secrets;
parent_class->need_secrets = need_secrets;
/* Properties */
diff --git a/libnm-core/nm-setting-gsm.c b/libnm-core/nm-setting-gsm.c
index 73bd6590d2..4bb5ba9fc9 100644
--- a/libnm-core/nm-setting-gsm.c
+++ b/libnm-core/nm-setting-gsm.c
@@ -414,6 +414,15 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return TRUE;
}
+static gboolean
+verify_secrets (NMSetting *setting, NMConnection *connection, GError **error)
+{
+ return _nm_setting_verify_secret_string (NM_SETTING_GSM_GET_PRIVATE (setting)->password,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_PASSWORD,
+ error);
+}
+
static GPtrArray *
need_secrets (NMSetting *setting)
{
@@ -583,6 +592,7 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class)
object_class->get_property = get_property;
object_class->finalize = finalize;
parent_class->verify = verify;
+ parent_class->verify_secrets = verify_secrets;
parent_class->need_secrets = need_secrets;
/* Properties */
diff --git a/libnm-core/nm-setting-private.h b/libnm-core/nm-setting-private.h
index 8f59e26303..cb7ca52e3d 100644
--- a/libnm-core/nm-setting-private.h
+++ b/libnm-core/nm-setting-private.h
@@ -112,6 +112,11 @@ NMSettingVerifyResult _nm_setting_verify (NMSetting *setting,
NMConnection *connection,
GError **error);
+gboolean _nm_setting_verify_secret_string (const char *str,
+ const char *setting_name,
+ const char *property,
+ GError **error);
+
gboolean _nm_setting_slave_type_is_valid (const char *slave_type, const char **out_port_type);
GVariant *_nm_setting_to_dbus (NMSetting *setting,
diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c
index df2190bc28..7c5e393243 100644
--- a/libnm-core/nm-setting-wireless-security.c
+++ b/libnm-core/nm-setting-wireless-security.c
@@ -1017,6 +1017,63 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
static gboolean
+_verify_wep_key (const char *wep_key,
+ NMWepKeyType wep_key_type,
+ const char *property,
+ GError **error)
+{
+ if (wep_key && !nm_utils_wep_key_valid (wep_key, wep_key_type)) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("property is invalid"));
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, property);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+verify_secrets (NMSetting *setting, NMConnection *connection, GError **error)
+{
+ NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (setting);
+ NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self);
+
+ /* LEAP */
+ if ( priv->auth_alg
+ && !strcmp (priv->auth_alg, "leap")
+ && !strcmp (priv->key_mgmt, "ieee8021x")) {
+ if (!_nm_setting_verify_secret_string (priv->leap_password,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD,
+ error))
+ return FALSE;
+ }
+
+ /* WEP */
+ if (!_verify_wep_key (priv->wep_key0, priv->wep_key_type, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, error))
+ return FALSE;
+ if (!_verify_wep_key (priv->wep_key1, priv->wep_key_type, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, error))
+ return FALSE;
+ if (!_verify_wep_key (priv->wep_key2, priv->wep_key_type, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, error))
+ return FALSE;
+ if (!_verify_wep_key (priv->wep_key3, priv->wep_key_type, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, error))
+ return FALSE;
+
+ /* WPA-PSK */
+ if (priv->psk && !nm_utils_wpa_psk_valid (priv->psk)) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("property is invalid"));
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PSK);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
get_secret_flags (NMSetting *setting,
const char *secret_name,
gboolean verify_secret,
@@ -1266,6 +1323,7 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting
object_class->finalize = finalize;
parent_class->verify = verify;
+ parent_class->verify_secrets = verify_secrets;
parent_class->need_secrets = need_secrets;
parent_class->get_secret_flags = get_secret_flags;
parent_class->set_secret_flags = set_secret_flags;
diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c
index 0f8347c166..b08eea108a 100644
--- a/libnm-core/nm-setting.c
+++ b/libnm-core/nm-setting.c
@@ -1010,6 +1010,53 @@ _nm_setting_verify (NMSetting *setting, NMConnection *connection, GError **error
return NM_SETTING_VERIFY_SUCCESS;
}
+/**
+ * nm_setting_verify_secrets:
+ * @setting: the #NMSetting to verify secrets in
+ * @connection: (allow-none): the #NMConnection that @setting came from, or
+ * %NULL if @setting is being verified in isolation.
+ * @error: location to store error, or %NULL
+ *
+ * Verifies the secrets in the setting.
+ * The returned #GError contains information about which secret of the setting
+ * failed validation, and in what way that secret failed validation.
+ * The secret validation is done separately from main setting validation, because
+ * in some cases connection failure is not desired just for the secrets.
+ *
+ * Returns: %TRUE if the setting secrets are valid, %FALSE if they are not
+ *
+ * Since: 1.2
+ **/
+gboolean
+nm_setting_verify_secrets (NMSetting *setting, NMConnection *connection, GError **error)
+{
+ g_return_val_if_fail (NM_IS_SETTING (setting), NM_SETTING_VERIFY_ERROR);
+ g_return_val_if_fail (!connection || NM_IS_CONNECTION (connection), NM_SETTING_VERIFY_ERROR);
+ g_return_val_if_fail (!error || *error == NULL, NM_SETTING_VERIFY_ERROR);
+
+ if (NM_SETTING_GET_CLASS (setting)->verify_secrets)
+ return NM_SETTING_GET_CLASS (setting)->verify_secrets (setting, connection, error);
+
+ return NM_SETTING_VERIFY_SUCCESS;
+}
+
+gboolean
+_nm_setting_verify_secret_string (const char *str,
+ const char *setting_name,
+ const char *property,
+ GError **error)
+{
+ if (str && !*str) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("property is empty"));
+ g_prefix_error (error, "%s.%s: ", setting_name, property);
+ return FALSE;
+ }
+ return TRUE;
+}
+
static gboolean
compare_property (NMSetting *setting,
NMSetting *other,
diff --git a/libnm-core/nm-setting.h b/libnm-core/nm-setting.h
index 7b1d87d576..3083ef6029 100644
--- a/libnm-core/nm-setting.h
+++ b/libnm-core/nm-setting.h
@@ -180,6 +180,10 @@ typedef struct {
NMConnection *connection,
GError **error);
+ gboolean (*verify_secrets) (NMSetting *setting,
+ NMConnection *connection,
+ GError **error);
+
GPtrArray *(*need_secrets) (NMSetting *setting);
int (*update_one_secret) (NMSetting *setting,
@@ -211,7 +215,7 @@ typedef struct {
NMSettingCompareFlags flags);
/*< private >*/
- gpointer padding[8];
+ gpointer padding[7];
} NMSettingClass;
/**
@@ -242,6 +246,11 @@ gboolean nm_setting_verify (NMSetting *setting,
NMConnection *connection,
GError **error);
+NM_AVAILABLE_IN_1_2
+gboolean nm_setting_verify_secrets (NMSetting *setting,
+ NMConnection *connection,
+ GError **error);
+
gboolean nm_setting_compare (NMSetting *a,
NMSetting *b,
NMSettingCompareFlags flags);
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 0a73b27233..4692f12eba 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -858,6 +858,7 @@ libnm_1_0_6 {
libnm_1_2_0 {
global:
nm_access_point_get_last_seen;
+ nm_connection_verify_secrets;
nm_device_ethernet_get_s390_subchannels;
nm_device_get_lldp_neighbors;
nm_device_get_metered;
@@ -895,6 +896,7 @@ global:
nm_setting_ip_config_remove_dns_option;
nm_setting_ip_config_remove_dns_option_by_value;
nm_setting_mac_randomization_get_type;
+ nm_setting_verify_secrets;
nm_setting_vpn_get_timeout;
nm_setting_wired_get_wake_on_lan;
nm_setting_wired_get_wake_on_lan_password;