static void save_one_secret (Request *r, NMSetting *setting, const char *key, const char *secret, const char *display_name) { GHashTable *attrs; char *alt_display_name = NULL; const char *setting_name; NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; /* Don't system-owned or always-ask secrets */ if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) return; if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) return; setting_name = nm_setting_get_name (setting); g_assert (setting_name); attrs = _create_keyring_add_attr_list (r->connection, setting_name, key, display_name ? NULL : &alt_display_name); g_assert (attrs); secret_password_storev (&network_manager_secret_schema, attrs, NULL, display_name ? display_name : alt_display_name, secret, r->cancellable, save_secret_cb, r); r->keyring_calls++; g_hash_table_unref (attrs); g_free (alt_display_name); }
static void 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; /* 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); }
static gboolean real_need_secrets (NMVpnServicePlugin *plugin, NMConnection *connection, const char **setting_name, GError **error) { NMSettingVpn *s_vpn; NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; g_return_val_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); s_vpn = nm_connection_get_setting_vpn (connection); nm_setting_get_secret_flags (NM_SETTING (s_vpn), NM_SSTP_KEY_PASSWORD, &flags, NULL); /* Don't need the password if it's not required */ if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) return FALSE; /* Don't need the password if we already have one */ if (nm_setting_vpn_get_secret (NM_SETTING_VPN (s_vpn), NM_SSTP_KEY_PASSWORD)) return FALSE; /* Otherwise we need a password */ *setting_name = NM_SETTING_VPN_SETTING_NAME; return TRUE; }
static void setup_password_widget (OpenswanPluginUiWidget *self, const char *entry_name, NMSettingVPN *s_vpn, const char *secret_name, gboolean new_connection) { OpenswanPluginUiWidgetPrivate *priv = OPENSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self); NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; GtkWidget *widget; const char *value; if (new_connection) secret_flags = NM_SETTING_SECRET_FLAG_AGENT_OWNED; widget = (GtkWidget *) gtk_builder_get_object (priv->builder, entry_name); g_assert (widget); gtk_size_group_add_widget (priv->group, widget); if (s_vpn) { value = nm_setting_vpn_get_secret (s_vpn, secret_name); gtk_entry_set_text (GTK_ENTRY (widget), value ? value : ""); nm_setting_get_secret_flags (NM_SETTING (s_vpn), secret_name, &secret_flags, NULL); } secret_flags &= ~(NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED); g_object_set_data (G_OBJECT (widget), "flags", GUINT_TO_POINTER (secret_flags)); g_signal_connect (widget, "changed", G_CALLBACK (stuff_changed_cb), self); }
/** * nma_utils_setup_password_storage: * @passwd_entry: password #GtkEntry which the icon is attached to * @initial_flags: initial secret flags to setup password menu from * @setting: #NMSetting containing the password, or NULL * @password_flags_name: name of the secret flags (like psk-flags), or NULL * @with_not_required: whether to include "Not required" menu item * @ask_mode: %TRUE if the entrie is shown in ASK mode. That means, * while prompting for a password, contrary to being inside the * editor mode. * If %TRUE, the entry should be sensivive on selected "always-ask" * icon (this is e.f. for nm-applet asking for password), otherwise * not. * If %TRUE, it shall not be possible to select a different storage, * because we only prompt for a password, we cannot change the password * location. * * Adds a secondary icon and creates a popup menu for password entry. * The active menu item is set up according to initial_flags, or * from @setting/@password_flags_name (if they are not NULL). * If the @setting/@password_flags_name are not NULL, secret flags will * be automatically updated in the setting when menu is changed. */ void nma_utils_setup_password_storage (GtkWidget *passwd_entry, NMSettingSecretFlags initial_flags, NMSetting *setting, const char *password_flags_name, gboolean with_not_required, gboolean ask_mode) { GtkWidget *popup_menu; GtkWidget *item[4]; GSList *group; MenuItem idx; NMSettingSecretFlags secret_flags; /* Whether entry should be sensitive if "always-ask" is active " */ g_object_set_data (G_OBJECT (passwd_entry), ASK_MODE_TAG, GUINT_TO_POINTER (ask_mode)); popup_menu = gtk_menu_new (); g_object_set_data (G_OBJECT (popup_menu), PASSWORD_STORAGE_MENU_TAG, GUINT_TO_POINTER (TRUE)); g_object_set_data (G_OBJECT (popup_menu), MENU_WITH_NOT_REQUIRED_TAG, GUINT_TO_POINTER (with_not_required)); group = NULL; item[0] = gtk_radio_menu_item_new_with_label (group, gettext (icon_desc_table[0])); group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item[0])); item[1] = gtk_radio_menu_item_new_with_label (group, gettext (icon_desc_table[1])); item[2] = gtk_radio_menu_item_new_with_label (group, gettext (icon_desc_table[2])); if (with_not_required) item[3] = gtk_radio_menu_item_new_with_label (group, gettext (icon_desc_table[3])); gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item[0]); gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item[1]); gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item[2]); if (with_not_required) gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item[3]); popup_menu_item_info_register (item[0], setting, password_flags_name, ITEM_STORAGE_USER, passwd_entry); popup_menu_item_info_register (item[1], setting, password_flags_name, ITEM_STORAGE_SYSTEM, passwd_entry); popup_menu_item_info_register (item[2], setting, password_flags_name, ITEM_STORAGE_ASK, passwd_entry); if (with_not_required) popup_menu_item_info_register (item[3], setting, password_flags_name, ITEM_STORAGE_UNUSED, passwd_entry); g_signal_connect (passwd_entry, "icon-release", G_CALLBACK (icon_release_cb), popup_menu); gtk_entry_set_icon_activatable (GTK_ENTRY (passwd_entry), GTK_ENTRY_ICON_SECONDARY, !ask_mode); gtk_menu_attach_to_widget (GTK_MENU (popup_menu), passwd_entry, NULL); /* Initialize active item for password-storage popup menu */ if (setting && password_flags_name) nm_setting_get_secret_flags (setting, password_flags_name, &secret_flags, NULL); else secret_flags = initial_flags; idx = secret_flags_to_menu_item (secret_flags, with_not_required); gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item[idx]), TRUE); change_password_storage_icon (passwd_entry, idx); }
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 const char * secret_flags_to_pw_type (NMSettingVpn *s_vpn, const char *key) { NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; if (nm_setting_get_secret_flags (NM_SETTING (s_vpn), key, &flags, NULL)) { if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) return NM_VPNC_PW_TYPE_UNUSED; if (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) return NM_VPNC_PW_TYPE_ASK; return NM_VPNC_PW_TYPE_SAVE; } return NULL; }
static void check_always_ask_cb (NMSetting *setting, const char *key, const GValue *value, GParamFlags flags, gpointer user_data) { gboolean *always_ask = user_data; NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; if (flags & NM_SETTING_PARAM_SECRET) { if (nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) { if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) *always_ask = TRUE; } } }
static void save_one_secret (Request *r, NMSetting *setting, const char *key, const char *secret, const char *display_name) { GnomeKeyringAttributeList *attrs; KeyringCall *call; char *alt_display_name = NULL; const char *setting_name; NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; /* Don't system-owned or always-ask secrets */ if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) return; if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) return; setting_name = nm_setting_get_name (setting); g_assert (setting_name); attrs = utils_create_keyring_add_attr_list (r->connection, NULL, NULL, setting_name, key, display_name ? NULL : &alt_display_name); g_assert (attrs); call = keyring_call_new (r); call->keyring_id = gnome_keyring_item_create (NULL, GNOME_KEYRING_ITEM_GENERIC_SECRET, display_name ? display_name : alt_display_name, attrs, secret, TRUE, save_secret_cb, call, keyring_call_free); r->keyring_calls = g_slist_append (r->keyring_calls, call); gnome_keyring_attribute_list_free (attrs); g_free (alt_display_name); }
static void write_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key, const GValue *value) { GHashTableIter iter; const char *property = NULL, *data = NULL; const char *group_name = nm_setting_get_name (setting); gboolean vpn_secrets = FALSE; /* Write VPN secrets out to a different group to keep them separate */ if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) { group_name = VPN_SECRETS_GROUP; vpn_secrets = TRUE; } g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); while (g_hash_table_iter_next (&iter, (gpointer *) &property, (gpointer *) &data)) { gboolean write_item = TRUE; /* Handle VPN secrets specially; they are nested in the property's hash; * we don't want to write them if the secret is not saved, not required, * or owned by a user's secret agent. */ if (vpn_secrets) { NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; nm_setting_get_secret_flags (setting, property, &secret_flags, NULL); if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) write_item = FALSE; } if (write_item) g_key_file_set_string (file, group_name, property, data); } }
static void fill_connection (EAPMethod *parent, NMConnection *connection) { EAPMethodSimple *method = (EAPMethodSimple *) parent; NMSetting8021x *s_8021x; GtkWidget *widget; gboolean not_saved = FALSE; const char *eap = NULL; NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x); /* If this is the main EAP method, clear any existing methods because the * user-selected on will replace it. */ if (parent->phase2 == FALSE) nm_setting_802_1x_clear_eap_methods (s_8021x); switch (method->type) { case EAP_METHOD_SIMPLE_TYPE_PAP: eap = "pap"; break; case EAP_METHOD_SIMPLE_TYPE_MSCHAP: eap = "mschap"; break; case EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2: eap = "mschapv2"; break; case EAP_METHOD_SIMPLE_TYPE_MD5: eap = "md5"; break; case EAP_METHOD_SIMPLE_TYPE_CHAP: eap = "chap"; break; case EAP_METHOD_SIMPLE_TYPE_GTC: eap = "gtc"; break; default: g_assert_not_reached (); break; } if (parent->phase2) g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, eap, NULL); else nm_setting_802_1x_add_eap_method (s_8021x, eap); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry")); g_assert (widget); g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (GTK_ENTRY (widget)), NULL); /* Save the password always ask setting */ widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_password_always_ask")); g_assert (widget); not_saved = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); nm_setting_get_secret_flags (NM_SETTING (s_8021x), NM_SETTING_802_1X_PASSWORD, &flags, NULL); flags &= ~(NM_SETTING_SECRET_FLAG_NOT_SAVED); if (not_saved) flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED; nm_setting_set_secret_flags (NM_SETTING (s_8021x), NM_SETTING_802_1X_PASSWORD, flags, NULL); /* Fill the connection's password if we're in the applet so that it'll get * back to NM. From the editor though, since the connection isn't going * back to NM in response to a GetSecrets() call, we don't save it if the * user checked "Always Ask". */ if (method->is_editor == FALSE || not_saved == FALSE) { widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry")); g_assert (widget); g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, gtk_entry_get_text (GTK_ENTRY (widget)), NULL); } /* Default to agent-owned secrets for new connections */ if (method->new_connection && (not_saved == FALSE)) { g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_802_1X_SYSTEM_CA_CERTS, TRUE, NULL); } }
EAPMethodSimple * eap_method_simple_new (WirelessSecurity *ws_parent, NMConnection *connection, EAPMethodSimpleType type, gboolean phase2, gboolean is_editor, gboolean secrets_only) { EAPMethod *parent; EAPMethodSimple *method; GtkWidget *widget; gboolean not_saved = FALSE; NMSetting8021x *s_8021x = NULL; parent = eap_method_init (sizeof (EAPMethodSimple), validate, add_to_size_group, fill_connection, update_secrets, NULL, UIDIR "/eap-method-simple.ui", "eap_simple_notebook", "eap_simple_username_entry", phase2); if (!parent) return NULL; method = (EAPMethodSimple *) parent; method->type = type; method->is_editor = is_editor; method->new_connection = secrets_only ? FALSE : TRUE; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); if (connection) { s_8021x = nm_connection_get_setting_802_1x (connection); if (s_8021x && nm_setting_802_1x_get_identity (s_8021x)) gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_identity (s_8021x)); } if (secrets_only) gtk_widget_set_sensitive (widget, FALSE); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_password_always_ask")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) wireless_security_changed_cb, ws_parent); if (is_editor) { /* We only desensitize the password entry from the editor, because * from nm-applet if the entry was desensitized, there'd be no way to * get the password back to NetworkManager when NM asked for it. Since * the editor only sets up the initial connection though, it's safe to * do there. */ g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (password_always_ask_changed), method); } if (secrets_only) gtk_widget_hide (widget); if (s_8021x) { NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; nm_setting_get_secret_flags (NM_SETTING (s_8021x), NM_SETTING_802_1X_PASSWORD, &flags, NULL); not_saved = (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED); } gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), not_saved); /* Fill secrets if there's a static (ie, not OTP) password */ if (connection && (not_saved == FALSE)) update_secrets (EAP_METHOD (method), connection); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapsimple")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) show_toggled_cb, method); return method; }
static void write_setting_value (NMSetting *setting, const char *key, const GValue *value, GParamFlags flag, gpointer user_data) { WriteInfo *info = user_data; const char *setting_name; GType type = G_VALUE_TYPE (value); KeyWriter *writer = &key_writers[0]; GParamSpec *pspec; /* Setting name gets picked up from the keyfile's section name instead */ if (!strcmp (key, NM_SETTING_NAME)) return; /* Don't write the NMSettingConnection object's 'read-only' property */ if ( NM_IS_SETTING_CONNECTION (setting) && !strcmp (key, NM_SETTING_CONNECTION_READ_ONLY)) return; setting_name = nm_setting_get_name (setting); /* If the value is the default value, remove the item from the keyfile */ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), key); if (pspec) { if (g_param_value_defaults (pspec, (GValue *) value)) { g_key_file_remove_key (info->keyfile, setting_name, key, NULL); return; } } /* Don't write secrets that are owned by user secret agents or aren't * supposed to be saved. VPN secrets are handled specially though since * the secret flags there are in a third-level hash in the 'secrets' * property. */ if (pspec->flags & NM_SETTING_PARAM_SECRET && !NM_IS_SETTING_VPN (setting)) { NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) return; } /* Look through the list of handlers for non-standard format key values */ while (writer->setting_name) { if (!strcmp (writer->setting_name, setting_name) && !strcmp (writer->key, key)) { (*writer->writer) (info->keyfile, info->keyfile_dir, info->uuid, setting, key, value); return; } writer++; } if (type == G_TYPE_STRING) { const char *str; str = g_value_get_string (value); if (str) g_key_file_set_string (info->keyfile, setting_name, key, str); } else if (type == G_TYPE_UINT) g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_uint (value)); else if (type == G_TYPE_INT) g_key_file_set_integer (info->keyfile, setting_name, key, g_value_get_int (value)); else if (type == G_TYPE_UINT64) { char *numstr; numstr = g_strdup_printf ("%" G_GUINT64_FORMAT, g_value_get_uint64 (value)); g_key_file_set_value (info->keyfile, setting_name, key, numstr); g_free (numstr); } else if (type == G_TYPE_BOOLEAN) { g_key_file_set_boolean (info->keyfile, setting_name, key, g_value_get_boolean (value)); } else if (type == G_TYPE_CHAR) { g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_char (value)); } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) { GByteArray *array; array = (GByteArray *) g_value_get_boxed (value); if (array && array->len > 0) { int *tmp_array; int i; tmp_array = g_new (gint, array->len); for (i = 0; i < array->len; i++) tmp_array[i] = (int) array->data[i]; g_key_file_set_integer_list (info->keyfile, setting_name, key, tmp_array, array->len); g_free (tmp_array); } } else if (type == DBUS_TYPE_G_LIST_OF_STRING) { GSList *list; GSList *iter; list = (GSList *) g_value_get_boxed (value); if (list) { char **array; int i = 0; array = g_new (char *, g_slist_length (list)); for (iter = list; iter; iter = iter->next) array[i++] = iter->data; g_key_file_set_string_list (info->keyfile, setting_name, key, (const gchar **const) array, i); g_free (array); } } else if (type == DBUS_TYPE_G_MAP_OF_STRING) {