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.
This commit is contained in:
Jiří Klimeš 2015-11-10 14:36:20 +01:00
parent fc758cb4ea
commit b41b32cb7b
10 changed files with 182 additions and 1 deletions

View File

@ -896,6 +896,34 @@ EXIT:
return success;
}
/**
* 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

View File

@ -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,

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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,

View File

@ -1016,6 +1016,63 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return TRUE;
}
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,
@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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;