1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301 USA.
18 * Copyright 2007 - 2013 Red Hat, Inc.
19 * Copyright 2007 - 2008 Novell, Inc.
22 #include "nm-default.h"
27 #include <dbus/dbus-glib.h>
29 #include "nm-setting-vpn.h"
30 #include "nm-param-spec-specialized.h"
32 #include "nm-dbus-glib-types.h"
33 #include "nm-setting-private.h"
36 * SECTION:nm-setting-vpn
37 * @short_description: Describes connection properties for Virtual Private Networks
38 * @include: nm-setting-vpn.h
40 * The #NMSettingVPN object is a #NMSetting subclass that describes properties
41 * necessary for connection to Virtual Private Networks. NetworkManager uses
42 * a plugin architecture to allow easier use of new VPN types, and this
43 * setting abstracts the configuration for those plugins. Since the configuration
44 * options are only known to the VPN plugins themselves, the VPN configuration
45 * options are stored as key/value pairs of strings rather than GObject
50 * nm_setting_vpn_error_quark:
52 * Registers an error quark for #NMSettingVPN if necessary.
54 * Returns: the error quark used for #NMSettingVPN errors.
57 nm_setting_vpn_error_quark (void)
61 if (G_UNLIKELY (!quark))
62 quark = g_quark_from_static_string ("nm-setting-vpn-error-quark");
67 G_DEFINE_TYPE_WITH_CODE (NMSettingVPN, nm_setting_vpn, NM_TYPE_SETTING,
68 _nm_register_setting (NM_SETTING_VPN_SETTING_NAME,
71 NM_SETTING_VPN_ERROR))
72 NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_VPN)
74 #define NM_SETTING_VPN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_VPN, NMSettingVPNPrivate))
79 /* username of the user requesting this connection, thus
80 * it's really only valid for user connections, and it also
81 * should never be saved out to persistent config.
85 /* Whether the VPN stays up across link changes, until the user
86 * explicitly disconnects it.
90 /* The hash table is created at setting object
91 * init time and should not be replaced. It is
92 * a char * -> char * mapping, and both the key
93 * and value are owned by the hash table, and should
94 * be allocated with functions whose value can be
95 * freed with g_free(). Should not contain secrets.
99 /* The hash table is created at setting object
100 * init time and should not be replaced. It is
101 * a char * -> char * mapping, and both the key
102 * and value are owned by the hash table, and should
103 * be allocated with functions whose value can be
104 * freed with g_free(). Should contain secrets only.
107 } NMSettingVPNPrivate;
121 * nm_setting_vpn_new:
123 * Creates a new #NMSettingVPN object with default values.
125 * Returns: (transfer full): the new empty #NMSettingVPN object
128 nm_setting_vpn_new (void)
130 return (NMSetting *) g_object_new (NM_TYPE_SETTING_VPN, NULL);
134 * nm_setting_vpn_get_service_type:
135 * @setting: the #NMSettingVPN
137 * Returns the service name of the VPN, which identifies the specific VPN
138 * plugin that should be used to connect to this VPN.
140 * Returns: the VPN plugin's service name
143 nm_setting_vpn_get_service_type (NMSettingVPN *setting)
145 g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL);
147 return NM_SETTING_VPN_GET_PRIVATE (setting)->service_type;
151 * nm_setting_vpn_get_user_name:
152 * @setting: the #NMSettingVPN
154 * Returns: the #NMSettingVPN:user-name property of the setting
157 nm_setting_vpn_get_user_name (NMSettingVPN *setting)
159 g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL);
161 return NM_SETTING_VPN_GET_PRIVATE (setting)->user_name;
165 * nm_setting_vpn_get_persistent:
166 * @setting: the #NMSettingVPN
168 * Returns: the #NMSettingVPN:persistent property of the setting
171 nm_setting_vpn_get_persistent (NMSettingVPN *setting)
173 g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE);
175 return NM_SETTING_VPN_GET_PRIVATE (setting)->persistent;
179 * nm_setting_vpn_get_num_data_items:
180 * @setting: the #NMSettingVPN
182 * Gets number of key/value pairs of VPN configuration data.
184 * Returns: the number of VPN plugin specific configuration data items
187 nm_setting_vpn_get_num_data_items (NMSettingVPN *setting)
189 g_return_val_if_fail (NM_IS_SETTING_VPN (setting), 0);
191 return g_hash_table_size (NM_SETTING_VPN_GET_PRIVATE (setting)->data);
195 * nm_setting_vpn_add_data_item:
196 * @setting: the #NMSettingVPN
197 * @key: a name that uniquely identifies the given value @item
198 * @item: the value to be referenced by @key
200 * Establishes a relationship between @key and @item internally in the
201 * setting which may be retrieved later. Should not be used to store passwords
202 * or other secrets, which is what nm_setting_vpn_add_secret() is for.
205 nm_setting_vpn_add_data_item (NMSettingVPN *setting,
209 g_return_if_fail (NM_IS_SETTING_VPN (setting));
210 g_return_if_fail (key != NULL);
211 g_return_if_fail (strlen (key) > 0);
212 g_return_if_fail (item != NULL);
213 g_return_if_fail (strlen (item) > 0);
215 g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data,
216 g_strdup (key), g_strdup (item));
217 g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_DATA);
221 * nm_setting_vpn_get_data_item:
222 * @setting: the #NMSettingVPN
223 * @key: the name of the data item to retrieve
225 * Retrieves the data item of a key/value relationship previously established
226 * by nm_setting_vpn_add_data_item().
228 * Returns: the data item, if any
231 nm_setting_vpn_get_data_item (NMSettingVPN *setting, const char *key)
233 g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL);
235 return (const char *) g_hash_table_lookup (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key);
239 * nm_setting_vpn_remove_data_item:
240 * @setting: the #NMSettingVPN
241 * @key: the name of the data item to remove
243 * Deletes a key/value relationship previously established by
244 * nm_setting_vpn_add_data_item().
246 * Returns: %TRUE if the data item was found and removed from the internal list,
247 * %FALSE if it was not.
250 nm_setting_vpn_remove_data_item (NMSettingVPN *setting, const char *key)
254 g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE);
256 found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key);
258 g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_DATA);
263 foreach_item_helper (GHashTable *hash,
268 GSList *copied = NULL, *siter;
270 g_return_if_fail (hash != NULL);
272 /* Grab keys and copy them so that the callback func can modify
273 * the hash table items if it wants to.
275 keys = g_hash_table_get_keys (hash);
276 for (liter = keys; liter; liter = g_list_next (liter))
277 copied = g_slist_prepend (copied, g_strdup (liter->data));
278 copied = g_slist_reverse (copied);
281 for (siter = copied; siter; siter = g_slist_next (siter)) {
284 value = g_hash_table_lookup (hash, siter->data);
285 func (siter->data, value, user_data);
288 g_slist_free_full (copied, g_free);
292 * nm_setting_vpn_foreach_data_item:
293 * @setting: a #NMSettingVPN
294 * @func: (scope call): an user provided function
295 * @user_data: data to be passed to @func
297 * Iterates all data items stored in this setting. It is safe to add, remove,
298 * and modify data items inside @func, though any additions or removals made
299 * during iteration will not be part of the iteration.
302 nm_setting_vpn_foreach_data_item (NMSettingVPN *setting,
306 g_return_if_fail (NM_IS_SETTING_VPN (setting));
308 foreach_item_helper (NM_SETTING_VPN_GET_PRIVATE (setting)->data, func, user_data);
312 * nm_setting_vpn_get_num_secrets:
313 * @setting: the #NMSettingVPN
315 * Gets number of VPN plugin specific secrets in the setting.
317 * Returns: the number of VPN plugin specific secrets
320 nm_setting_vpn_get_num_secrets (NMSettingVPN *setting)
322 g_return_val_if_fail (NM_IS_SETTING_VPN (setting), 0);
324 return g_hash_table_size (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets);
328 * nm_setting_vpn_add_secret:
329 * @setting: the #NMSettingVPN
330 * @key: a name that uniquely identifies the given secret @secret
331 * @secret: the secret to be referenced by @key
333 * Establishes a relationship between @key and @secret internally in the
334 * setting which may be retrieved later.
337 nm_setting_vpn_add_secret (NMSettingVPN *setting,
341 g_return_if_fail (NM_IS_SETTING_VPN (setting));
342 g_return_if_fail (key != NULL);
343 g_return_if_fail (strlen (key) > 0);
344 g_return_if_fail (secret != NULL);
345 g_return_if_fail (strlen (secret) > 0);
347 g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets,
348 g_strdup (key), g_strdup (secret));
349 g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS);
353 * nm_setting_vpn_get_secret:
354 * @setting: the #NMSettingVPN
355 * @key: the name of the secret to retrieve
357 * Retrieves the secret of a key/value relationship previously established
358 * by nm_setting_vpn_add_secret().
360 * Returns: the secret, if any
363 nm_setting_vpn_get_secret (NMSettingVPN *setting, const char *key)
365 g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL);
367 return (const char *) g_hash_table_lookup (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key);
371 * nm_setting_vpn_remove_secret:
372 * @setting: the #NMSettingVPN
373 * @key: the name of the secret to remove
375 * Deletes a key/value relationship previously established by
376 * nm_setting_vpn_add_secret().
378 * Returns: %TRUE if the secret was found and removed from the internal list,
379 * %FALSE if it was not.
382 nm_setting_vpn_remove_secret (NMSettingVPN *setting, const char *key)
386 g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE);
388 found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key);
390 g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS);
395 * nm_setting_vpn_foreach_secret:
396 * @setting: a #NMSettingVPN
397 * @func: (scope call): an user provided function
398 * @user_data: data to be passed to @func
400 * Iterates all secrets stored in this setting. It is safe to add, remove,
401 * and modify secrets inside @func, though any additions or removals made during
402 * iteration will not be part of the iteration.
405 nm_setting_vpn_foreach_secret (NMSettingVPN *setting,
409 g_return_if_fail (NM_IS_SETTING_VPN (setting));
411 foreach_item_helper (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, func, user_data);
415 verify (NMSetting *setting, GSList *all_settings, GError **error)
417 NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
419 if (!priv->service_type) {
420 g_set_error_literal (error,
421 NM_SETTING_VPN_ERROR,
422 NM_SETTING_VPN_ERROR_MISSING_PROPERTY,
423 _("property is missing"));
424 g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE);
428 if (!strlen (priv->service_type)) {
429 g_set_error_literal (error,
430 NM_SETTING_VPN_ERROR,
431 NM_SETTING_VPN_ERROR_INVALID_PROPERTY,
432 _("property is empty"));
433 g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE);
437 /* default username can be NULL, but can't be zero-length */
438 if (priv->user_name && !strlen (priv->user_name)) {
439 g_set_error_literal (error,
440 NM_SETTING_VPN_ERROR,
441 NM_SETTING_VPN_ERROR_INVALID_PROPERTY,
442 _("property is empty"));
443 g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_USER_NAME);
450 static NMSettingUpdateSecretResult
451 update_secret_string (NMSetting *setting,
456 NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
458 g_return_val_if_fail (key != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
459 g_return_val_if_fail (value != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
461 if (!value || !strlen (value)) {
462 g_set_error (error, NM_SETTING_ERROR,
463 NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
464 "Secret %s was empty", key);
465 return NM_SETTING_UPDATE_SECRET_ERROR;
468 if (g_strcmp0 (g_hash_table_lookup (priv->secrets, key), value) == 0)
469 return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
471 g_hash_table_insert (priv->secrets, g_strdup (key), g_strdup (value));
472 return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED;
475 static NMSettingUpdateSecretResult
476 update_secret_hash (NMSetting *setting,
480 NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
482 const char *name, *value;
483 NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
485 g_return_val_if_fail (secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
487 /* Make sure the items are valid */
488 g_hash_table_iter_init (&iter, secrets);
489 while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) {
490 if (!name || !strlen (name)) {
491 g_set_error_literal (error, NM_SETTING_ERROR,
492 NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
493 "Secret name was empty");
494 return NM_SETTING_UPDATE_SECRET_ERROR;
497 if (!value || !strlen (value)) {
498 g_set_error (error, NM_SETTING_ERROR,
499 NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
500 "Secret %s value was empty", name);
501 return NM_SETTING_UPDATE_SECRET_ERROR;
505 /* Now add the items to the settings' secrets list */
506 g_hash_table_iter_init (&iter, secrets);
507 while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) {
509 g_warn_if_fail (value != NULL);
512 if (strlen (value) == 0) {
513 g_warn_if_fail (strlen (value) > 0);
517 if (g_strcmp0 (g_hash_table_lookup (priv->secrets, name), value) == 0)
520 g_hash_table_insert (priv->secrets, g_strdup (name), g_strdup (value));
521 result = NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED;
528 update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error)
530 NMSettingUpdateSecretResult success = NM_SETTING_UPDATE_SECRET_ERROR;
532 g_return_val_if_fail (key != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
533 g_return_val_if_fail (value != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
535 if (G_VALUE_HOLDS_STRING (value)) {
536 /* Passing the string properties individually isn't correct, and won't
537 * produce the correct result, but for some reason that's how it used
538 * to be done. So even though it's not correct, keep the code around
539 * for compatibility's sake.
541 success = update_secret_string (setting, key, g_value_get_string (value), error);
542 } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) {
543 if (strcmp (key, NM_SETTING_VPN_SECRETS) != 0) {
544 g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_NOT_SECRET,
545 "Property %s not a secret property", key);
547 success = update_secret_hash (setting, g_value_get_boxed (value), error);
549 g_set_error_literal (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, key);
551 if (success == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED)
552 g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS);
558 get_secret_flags (NMSetting *setting,
559 const char *secret_name,
560 gboolean verify_secret,
561 NMSettingSecretFlags *out_flags,
564 NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
565 gboolean success = FALSE;
569 NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
571 flags_key = g_strdup_printf ("%s-flags", secret_name);
572 if (g_hash_table_lookup_extended (priv->data, flags_key, NULL, &val)) {
574 tmp = strtoul ((const char *) val, NULL, 10);
575 if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAGS_ALL)) {
576 flags = (NMSettingSecretFlags) tmp;
581 NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
582 _("Failed to convert '%s' value '%s' to uint"),
583 flags_key, (const char *) val);
588 NM_SETTING_ERROR_PROPERTY_NOT_FOUND,
589 _("Secret flags property '%s' not found"), flags_key);
598 set_secret_flags (NMSetting *setting,
599 const char *secret_name,
600 gboolean verify_secret,
601 NMSettingSecretFlags flags,
604 g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data,
605 g_strdup_printf ("%s-flags", secret_name),
606 g_strdup_printf ("%u", flags));
607 g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS);
612 need_secrets (NMSetting *setting)
614 /* Assume that VPN connections need secrets since they almost always will */
615 return g_ptr_array_sized_new (1);
619 compare_one_secret (NMSettingVPN *a,
621 NMSettingCompareFlags flags)
623 GHashTable *a_secrets, *b_secrets;
625 const char *key, *val;
627 a_secrets = NM_SETTING_VPN_GET_PRIVATE (a)->secrets;
628 b_secrets = NM_SETTING_VPN_GET_PRIVATE (b)->secrets;
630 g_hash_table_iter_init (&iter, a_secrets);
631 while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) {
632 NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
633 NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
635 nm_setting_get_secret_flags (NM_SETTING (a), key, &a_secret_flags, NULL);
636 nm_setting_get_secret_flags (NM_SETTING (b), key, &b_secret_flags, NULL);
638 /* If the secret flags aren't the same, the settings aren't the same */
639 if (a_secret_flags != b_secret_flags)
642 if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
643 && (a_secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED))
646 if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
647 && (a_secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED))
650 /* Now compare the values themselves */
651 if (g_strcmp0 (val, nm_setting_vpn_get_secret (b, key)) != 0)
659 compare_property (NMSetting *setting,
661 const GParamSpec *prop_spec,
662 NMSettingCompareFlags flags)
666 /* We only need to treat the 'secrets' property specially */
667 if (g_strcmp0 (prop_spec->name, NM_SETTING_VPN_SECRETS) != 0)
668 return NM_SETTING_CLASS (nm_setting_vpn_parent_class)->compare_property (setting, other, prop_spec, flags);
670 /* Compare A to B to ensure everything in A is found in B */
671 same = compare_one_secret (NM_SETTING_VPN (setting), NM_SETTING_VPN (other), flags);
673 /* And then B to A to ensure everything in B is also found in A */
674 same = compare_one_secret (NM_SETTING_VPN (other), NM_SETTING_VPN (setting), flags);
681 clear_secrets_with_flags (NMSetting *setting,
683 NMSettingClearSecretsWithFlagsFn func,
686 NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
689 gboolean changed = TRUE;
691 if (priv->secrets == NULL)
694 /* Iterate through secrets hash and check each entry */
695 g_hash_table_iter_init (&iter, priv->secrets);
696 while (g_hash_table_iter_next (&iter, (gpointer) &secret, NULL)) {
697 NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
699 nm_setting_get_secret_flags (setting, secret, &flags, NULL);
700 if (func (setting, pspec->name, flags, user_data) == TRUE) {
701 g_hash_table_iter_remove (&iter);
707 g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS);
713 destroy_one_secret (gpointer data)
715 char *secret = (char *) data;
717 /* Don't leave the secret lying around in memory */
718 memset (secret, 0, strlen (secret));
723 nm_setting_vpn_init (NMSettingVPN *setting)
725 NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
727 priv->data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
728 priv->secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_one_secret);
732 finalize (GObject *object)
734 NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (object);
736 g_free (priv->service_type);
737 g_free (priv->user_name);
738 g_hash_table_destroy (priv->data);
739 g_hash_table_destroy (priv->secrets);
741 G_OBJECT_CLASS (nm_setting_vpn_parent_class)->finalize (object);
745 copy_hash (gpointer key, gpointer value, gpointer user_data)
747 g_return_if_fail (value != NULL);
748 g_return_if_fail (strlen (value));
749 g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), g_strdup (value));
753 set_property (GObject *object, guint prop_id,
754 const GValue *value, GParamSpec *pspec)
756 NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (object);
757 GHashTable *new_hash;
760 case PROP_SERVICE_TYPE:
761 g_free (priv->service_type);
762 priv->service_type = g_value_dup_string (value);
765 g_free (priv->user_name);
766 priv->user_name = g_value_dup_string (value);
768 case PROP_PERSISTENT:
769 priv->persistent = g_value_get_boolean (value);
772 /* Must make a deep copy of the hash table here... */
773 g_hash_table_remove_all (priv->data);
774 new_hash = g_value_get_boxed (value);
776 g_hash_table_foreach (new_hash, copy_hash, priv->data);
779 /* Must make a deep copy of the hash table here... */
780 g_hash_table_remove_all (priv->secrets);
781 new_hash = g_value_get_boxed (value);
783 g_hash_table_foreach (new_hash, copy_hash, priv->secrets);
786 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
792 get_property (GObject *object, guint prop_id,
793 GValue *value, GParamSpec *pspec)
795 NMSettingVPN *setting = NM_SETTING_VPN (object);
796 NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
799 case PROP_SERVICE_TYPE:
800 g_value_set_string (value, nm_setting_vpn_get_service_type (setting));
803 g_value_set_string (value, nm_setting_vpn_get_user_name (setting));
805 case PROP_PERSISTENT:
806 g_value_set_boolean (value, priv->persistent);
809 g_value_set_boxed (value, priv->data);
812 g_value_set_boxed (value, priv->secrets);
815 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
821 nm_setting_vpn_class_init (NMSettingVPNClass *setting_class)
823 GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
824 NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
826 g_type_class_add_private (setting_class, sizeof (NMSettingVPNPrivate));
828 /* virtual methods */
829 object_class->set_property = set_property;
830 object_class->get_property = get_property;
831 object_class->finalize = finalize;
833 parent_class->verify = verify;
834 parent_class->update_one_secret = update_one_secret;
835 parent_class->get_secret_flags = get_secret_flags;
836 parent_class->set_secret_flags = set_secret_flags;
837 parent_class->need_secrets = need_secrets;
838 parent_class->compare_property = compare_property;
839 parent_class->clear_secrets_with_flags = clear_secrets_with_flags;
843 * NMSettingVPN:service-type:
845 * D-Bus service name of the VPN plugin that this setting uses to connect to
846 * its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc
849 g_object_class_install_property
850 (object_class, PROP_SERVICE_TYPE,
851 g_param_spec_string (NM_SETTING_VPN_SERVICE_TYPE, "", "",
854 G_PARAM_STATIC_STRINGS));
857 * NMSettingVPN:user-name:
859 * If the VPN connection requires a user name for authentication, that name
860 * should be provided here. If the connection is available to more than one
861 * user, and the VPN requires each user to supply a different name, then
862 * leave this property empty. If this property is empty, NetworkManager
863 * will automatically supply the username of the user which requested the
866 g_object_class_install_property
867 (object_class, PROP_USER_NAME,
868 g_param_spec_string (NM_SETTING_VPN_USER_NAME, "", "",
871 G_PARAM_STATIC_STRINGS));
874 * NMSettingVPN:persistent:
876 * If the VPN service supports persistence, and this property is %TRUE,
877 * the VPN will attempt to stay connected across link changes and outages,
878 * until explicitly disconnected.
880 g_object_class_install_property
881 (object_class, PROP_PERSISTENT,
882 g_param_spec_boolean (NM_SETTING_VPN_PERSISTENT, "", "",
885 G_PARAM_STATIC_STRINGS));
890 * Dictionary of key/value pairs of VPN plugin specific data. Both keys and
891 * values must be strings.
893 g_object_class_install_property
894 (object_class, PROP_DATA,
895 _nm_param_spec_specialized (NM_SETTING_VPN_DATA, "", "",
896 DBUS_TYPE_G_MAP_OF_STRING,
898 G_PARAM_STATIC_STRINGS));
901 * NMSettingVPN:secrets:
903 * Dictionary of key/value pairs of VPN plugin specific secrets like
904 * passwords or private keys. Both keys and values must be strings.
906 g_object_class_install_property
907 (object_class, PROP_SECRETS,
908 _nm_param_spec_specialized (NM_SETTING_VPN_SECRETS, "", "",
909 DBUS_TYPE_G_MAP_OF_STRING,
911 NM_SETTING_PARAM_SECRET |
912 G_PARAM_STATIC_STRINGS));