/** * nm_setting_vpn_get_num_secrets: * @setting: the #NMSettingVPN * * Gets number of VPN plugin specific secrets in the setting. * * Returns: the number of VPN plugin specific secrets **/ guint32 nm_setting_vpn_get_num_secrets (NMSettingVPN *setting) { g_return_val_if_fail (NM_IS_SETTING_VPN (setting), 0); return g_hash_table_size (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets); }
static gboolean clear_secrets_with_flags (NMSetting *setting, GParamSpec *pspec, NMSettingClearSecretsWithFlagsFn func, gpointer user_data) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); GHashTableIter iter; const char *secret; gboolean changed = TRUE; if (priv->secrets == NULL) return FALSE; /* Iterate through secrets hash and check each entry */ g_hash_table_iter_init (&iter, priv->secrets); while (g_hash_table_iter_next (&iter, (gpointer) &secret, NULL)) { NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; nm_setting_get_secret_flags (setting, secret, &flags, NULL); if (func (setting, pspec->name, flags, user_data) == TRUE) { g_hash_table_iter_remove (&iter); changed = TRUE; } } if (changed) g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS); return changed; }
/** * nm_setting_vpn_get_persistent: * @setting: the #NMSettingVpn * * Returns: the #NMSettingVpn:persistent property of the setting **/ gboolean nm_setting_vpn_get_persistent (NMSettingVpn *setting) { g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE); return NM_SETTING_VPN_GET_PRIVATE (setting)->persistent; }
/** * nm_setting_vpn_get_secret: * @setting: the #NMSettingVPN * @key: the name of the secret to retrieve * * Retrieves the secret of a key/value relationship previously established * by nm_setting_vpn_add_secret(). * * Returns: the secret, if any **/ const char * nm_setting_vpn_get_secret (NMSettingVPN *setting, const char *key) { g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL); return (const char *) g_hash_table_lookup (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key); }
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMSettingVPN *setting = NM_SETTING_VPN (object); NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); switch (prop_id) { case PROP_SERVICE_TYPE: g_value_set_string (value, nm_setting_vpn_get_service_type (setting)); break; case PROP_USER_NAME: g_value_set_string (value, nm_setting_vpn_get_user_name (setting)); break; case PROP_DATA: g_value_set_boxed (value, priv->data); break; case PROP_SECRETS: g_value_set_boxed (value, priv->secrets); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
/** * nm_setting_vpn_get_user_name: * @setting: the #NMSettingVpn * * Returns: the #NMSettingVpn:user-name property of the setting **/ const char * nm_setting_vpn_get_user_name (NMSettingVpn *setting) { g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL); return NM_SETTING_VPN_GET_PRIVATE (setting)->user_name; }
static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); if (!priv->service_type) { g_set_error_literal (error, NM_SETTING_VPN_ERROR, NM_SETTING_VPN_ERROR_MISSING_PROPERTY, _("property is missing")); g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE); return FALSE; } if (!strlen (priv->service_type)) { g_set_error_literal (error, NM_SETTING_VPN_ERROR, NM_SETTING_VPN_ERROR_INVALID_PROPERTY, _("property is empty")); g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE); return FALSE; } /* default username can be NULL, but can't be zero-length */ if (priv->user_name && !strlen (priv->user_name)) { g_set_error_literal (error, NM_SETTING_VPN_ERROR, NM_SETTING_VPN_ERROR_INVALID_PROPERTY, _("property is empty")); g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_USER_NAME); return FALSE; } return TRUE; }
static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (object); GHashTable *new_hash; switch (prop_id) { case PROP_SERVICE_TYPE: g_free (priv->service_type); priv->service_type = g_value_dup_string (value); break; case PROP_USER_NAME: g_free (priv->user_name); priv->user_name = g_value_dup_string (value); break; case PROP_DATA: /* Must make a deep copy of the hash table here... */ g_hash_table_remove_all (priv->data); new_hash = g_value_get_boxed (value); if (new_hash) g_hash_table_foreach (new_hash, copy_hash, priv->data); break; case PROP_SECRETS: /* Must make a deep copy of the hash table here... */ g_hash_table_remove_all (priv->secrets); new_hash = g_value_get_boxed (value); if (new_hash) g_hash_table_foreach (new_hash, copy_hash, priv->secrets); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
/** * nm_setting_vpn_get_num_data_items: * @setting: the #NMSettingVpn * * Gets number of key/value pairs of VPN configuration data. * * Returns: the number of VPN plugin specific configuration data items **/ guint32 nm_setting_vpn_get_num_data_items (NMSettingVpn *setting) { g_return_val_if_fail (NM_IS_SETTING_VPN (setting), 0); return g_hash_table_size (NM_SETTING_VPN_GET_PRIVATE (setting)->data); }
void nm_setting_vpn_remove_secret (NMSettingVPN *setting, const char *key) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key); }
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMSettingVpn *setting = NM_SETTING_VPN (object); NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); switch (prop_id) { case PROP_SERVICE_TYPE: g_value_set_string (value, nm_setting_vpn_get_service_type (setting)); break; case PROP_USER_NAME: g_value_set_string (value, nm_setting_vpn_get_user_name (setting)); break; case PROP_PERSISTENT: g_value_set_boolean (value, priv->persistent); break; case PROP_DATA: g_value_take_boxed (value, _nm_utils_copy_strdict (priv->data)); break; case PROP_SECRETS: g_value_take_boxed (value, _nm_utils_copy_strdict (priv->secrets)); break; case PROP_TIMEOUT: g_value_set_uint (value, nm_setting_vpn_get_timeout (setting)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
/** * nm_setting_vpn_get_service_type: * @setting: the #NMSettingVPN * * Returns the service name of the VPN, which identifies the specific VPN * plugin that should be used to connect to this VPN. * * Returns: the VPN plugin's service name **/ const char * nm_setting_vpn_get_service_type (NMSettingVPN *setting) { g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL); return NM_SETTING_VPN_GET_PRIVATE (setting)->service_type; }
static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (object); switch (prop_id) { case PROP_SERVICE_TYPE: g_free (priv->service_type); priv->service_type = g_value_dup_string (value); break; case PROP_USER_NAME: g_free (priv->user_name); priv->user_name = g_value_dup_string (value); break; case PROP_PERSISTENT: priv->persistent = g_value_get_boolean (value); break; case PROP_DATA: g_hash_table_unref (priv->data); priv->data = _nm_utils_copy_strdict (g_value_get_boxed (value)); break; case PROP_SECRETS: g_hash_table_unref (priv->secrets); priv->secrets = _nm_utils_copy_strdict (g_value_get_boxed (value)); break; case PROP_TIMEOUT: priv->timeout = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static gboolean get_secret_flags (NMSetting *setting, const char *secret_name, gboolean verify_secret, NMSettingSecretFlags *out_flags, GError **error) { NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); gs_free char *flags_key = NULL; gpointer val; unsigned long tmp; NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; flags_key = g_strdup_printf ("%s-flags", secret_name); if (g_hash_table_lookup_extended (priv->data, flags_key, NULL, &val)) { errno = 0; tmp = strtoul ((const char *) val, NULL, 10); if ((errno != 0) || (tmp > NM_SETTING_SECRET_FLAGS_ALL)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("failed to convert value '%s' to uint"), (const char *) val); g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, flags_key); return FALSE; } flags = (NMSettingSecretFlags) tmp; } if (out_flags) *out_flags = flags; return TRUE; }
static NMSettingUpdateSecretResult update_secret_string (NMSetting *setting, const char *key, const char *value, GError **error) { NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); g_return_val_if_fail (key != NULL, NM_SETTING_UPDATE_SECRET_ERROR); g_return_val_if_fail (value != NULL, NM_SETTING_UPDATE_SECRET_ERROR); if (!value || !strlen (value)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("secret was empty")); g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, key); return NM_SETTING_UPDATE_SECRET_ERROR; } if (g_strcmp0 (g_hash_table_lookup (priv->secrets, key), value) == 0) return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; g_hash_table_insert (priv->secrets, g_strdup (key), g_strdup (value)); return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; }
/** * nm_setting_vpn_get_timeout: * @setting: the #NMSettingVpn * * Returns: the #NMSettingVpn:timeout property of the setting * * Since: 1.2 **/ guint32 nm_setting_vpn_get_timeout (NMSettingVpn *setting) { g_return_val_if_fail (NM_IS_SETTING_VPN (setting), 0); return NM_SETTING_VPN_GET_PRIVATE (setting)->timeout; }
static void nm_setting_vpn_init (NMSettingVpn *setting) { NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); priv->data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); priv->secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_one_secret); }
/** * nm_setting_vpn_foreach_secret: * @setting: a #NMSettingVPN * @func: (scope call): an user provided function * @user_data: data to be passed to @func * * Iterates all secrets stored in this setting. It is safe to add, remove, * and modify secrets inside @func, though any additions or removals made during * iteration will not be part of the iteration. */ void nm_setting_vpn_foreach_secret (NMSettingVPN *setting, NMVPNIterFunc func, gpointer user_data) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); foreach_item_helper (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, func, user_data); }
void nm_setting_vpn_add_data_item (NMSettingVPN *setting, const char *key, const char *item) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data, g_strdup (key), g_strdup (item)); }
void nm_setting_vpn_foreach_secret (NMSettingVPN *setting, VPNIterFunc func, gpointer user_data) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); g_hash_table_foreach (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, (GHFunc) func, user_data); }
void nm_setting_vpn_add_secret (NMSettingVPN *setting, const char *key, const char *secret) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, g_strdup (key), g_strdup (secret)); }
static NMSettingUpdateSecretResult update_secret_dict (NMSetting *setting, GVariant *secrets, GError **error) { NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); GVariantIter iter; const char *name, *value; NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; g_return_val_if_fail (secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR); /* Make sure the items are valid */ g_variant_iter_init (&iter, secrets); while (g_variant_iter_next (&iter, "{&s&s}", &name, &value)) { if (!name || !strlen (name)) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, _("setting contained a secret with an empty name")); g_prefix_error (error, "%s: ", NM_SETTING_VPN_SETTING_NAME); return NM_SETTING_UPDATE_SECRET_ERROR; } if (!value || !strlen (value)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("secret value was empty")); g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, name); return NM_SETTING_UPDATE_SECRET_ERROR; } } /* Now add the items to the settings' secrets list */ g_variant_iter_init (&iter, secrets); while (g_variant_iter_next (&iter, "{&s&s}", &name, &value)) { if (value == NULL) { g_warn_if_fail (value != NULL); continue; } if (strlen (value) == 0) { g_warn_if_fail (strlen (value) > 0); continue; } if (g_strcmp0 (g_hash_table_lookup (priv->secrets, name), value) == 0) continue; g_hash_table_insert (priv->secrets, g_strdup (name), g_strdup (value)); result = NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; } return result; }
/** * nm_setting_vpn_remove_data_item: * @setting: the #NMSettingVpn * @key: the name of the data item to remove * * Deletes a key/value relationship previously established by * nm_setting_vpn_add_data_item(). * * Returns: %TRUE if the data item was found and removed from the internal list, * %FALSE if it was not. **/ gboolean nm_setting_vpn_remove_data_item (NMSettingVpn *setting, const char *key) { gboolean found; g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE); found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key); if (found) g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_DATA); return found; }
static void finalize (GObject *object) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (object); g_free (priv->service_type); g_free (priv->user_name); g_hash_table_destroy (priv->data); g_hash_table_destroy (priv->secrets); G_OBJECT_CLASS (nm_setting_vpn_parent_class)->finalize (object); }
static gboolean set_secret_flags (NMSetting *setting, const char *secret_name, gboolean verify_secret, NMSettingSecretFlags flags, GError **error) { g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data, g_strdup_printf ("%s-flags", secret_name), g_strdup_printf ("%u", flags)); return TRUE; }
/** * nm_setting_vpn_remove_secret: * @setting: the #NMSettingVPN * @key: the name of the secret to remove * * Deletes a key/value relationship previously established by * nm_setting_vpn_add_secret(). * * Returns: %TRUE if the secret was found and removed from the internal list, * %FALSE if it was not. **/ gboolean nm_setting_vpn_remove_secret (NMSettingVPN *setting, const char *key) { gboolean found; g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE); found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key); if (found) g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS); return found; }
static gboolean compare_one_secret (NMSettingVPN *a, NMSettingVPN *b, NMSettingCompareFlags flags) { GHashTable *a_secrets, *b_secrets; GHashTableIter iter; const char *key, *val; a_secrets = NM_SETTING_VPN_GET_PRIVATE (a)->secrets; b_secrets = NM_SETTING_VPN_GET_PRIVATE (b)->secrets; g_hash_table_iter_init (&iter, a_secrets); while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) { NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE; NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE; nm_setting_get_secret_flags (NM_SETTING (a), key, &a_secret_flags, NULL); nm_setting_get_secret_flags (NM_SETTING (b), key, &b_secret_flags, NULL); /* If the secret flags aren't the same, the settings aren't the same */ if (a_secret_flags != b_secret_flags) return FALSE; if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS) && (a_secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) continue; if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS) && (a_secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) continue; /* Now compare the values themselves */ if (g_strcmp0 (val, nm_setting_vpn_get_secret (b, key)) != 0) return FALSE; } return TRUE; }
static NMSettingUpdateSecretResult update_secret_hash (NMSetting *setting, GHashTable *secrets, GError **error) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); GHashTableIter iter; const char *name, *value; NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; g_return_val_if_fail (secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR); /* Make sure the items are valid */ g_hash_table_iter_init (&iter, secrets); while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) { if (!name || !strlen (name)) { g_set_error_literal (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, "Secret name was empty"); return NM_SETTING_UPDATE_SECRET_ERROR; } if (!value || !strlen (value)) { g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, "Secret %s value was empty", name); return NM_SETTING_UPDATE_SECRET_ERROR; } } /* Now add the items to the settings' secrets list */ g_hash_table_iter_init (&iter, secrets); while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) { if (value == NULL) { g_warn_if_fail (value != NULL); continue; } if (strlen (value) == 0) { g_warn_if_fail (strlen (value) > 0); continue; } if (g_strcmp0 (g_hash_table_lookup (priv->secrets, name), value) == 0) continue; g_hash_table_insert (priv->secrets, g_strdup (name), g_strdup (value)); result = NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; } return result; }
/** * nm_setting_vpn_add_secret: * @setting: the #NMSettingVPN * @key: a name that uniquely identifies the given secret @secret * @secret: the secret to be referenced by @key * * Establishes a relationship between @key and @secret internally in the * setting which may be retrieved later. **/ void nm_setting_vpn_add_secret (NMSettingVPN *setting, const char *key, const char *secret) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); g_return_if_fail (key != NULL); g_return_if_fail (strlen (key) > 0); g_return_if_fail (secret != NULL); g_return_if_fail (strlen (secret) > 0); g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, g_strdup (key), g_strdup (secret)); g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS); }
/** * nm_setting_vpn_add_data_item: * @setting: the #NMSettingVPN * @key: a name that uniquely identifies the given value @item * @item: the value to be referenced by @key * * Establishes a relationship between @key and @item internally in the * setting which may be retrieved later. Should not be used to store passwords * or other secrets, which is what nm_setting_vpn_add_secret() is for. **/ void nm_setting_vpn_add_data_item (NMSettingVPN *setting, const char *key, const char *item) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); g_return_if_fail (key != NULL); g_return_if_fail (strlen (key) > 0); g_return_if_fail (item != NULL); g_return_if_fail (strlen (item) > 0); g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data, g_strdup (key), g_strdup (item)); g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_DATA); }