From 5f92f96fbe96751087db19de94b0619a0f2e2419 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 18 May 2015 08:40:12 -0400 Subject: [PATCH 1/5] Create keyring initially unencrypted This avoids a possible problem when we run gnome-initial-setup in the user session for a passwordless user - gnome-keyring will not create a keyring in this situation, and we will not ask the user to change his password, so we end up creating a keyring with the password "gis", which the user can't unlock. --- gnome-initial-setup/gis-keyring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnome-initial-setup/gis-keyring.c b/gnome-initial-setup/gis-keyring.c index 42e1a64..6459591 100644 --- a/gnome-initial-setup/gis-keyring.c +++ b/gnome-initial-setup/gis-keyring.c @@ -2,61 +2,61 @@ /* * Copyright (C) 2014 Red Hat * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Written by: * Matthias Clasen */ #include "config.h" #include #include #include "gis-keyring.h" #include -#define DUMMY_PWD "gis" +#define DUMMY_PWD "" /* We never want to see a keyring dialog, but we need to make * sure a keyring is present. * * To achieve this, install a prompter for gnome-keyring that * never shows any UI, and create a keyring, if one does not * exist yet. */ void gis_ensure_login_keyring () { GSubprocess *subprocess = NULL; GSubprocessLauncher *launcher = NULL; GError *error = NULL; g_debug ("launching gnome-keyring-daemon --login"); launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_SILENCE); subprocess = g_subprocess_launcher_spawn (launcher, &error, "gnome-keyring-daemon", "--unlock", NULL); if (subprocess == NULL) { g_warning ("Failed to spawn gnome-keyring-daemon --unlock: %s", error->message); g_error_free (error); goto out; } if (!g_subprocess_communicate_utf8 (subprocess, DUMMY_PWD, NULL, NULL, NULL, &error)) { g_warning ("Failed to communicate with gnome-keyring-daemon: %s", error->message); g_error_free (error); goto out; } -- 2.3.7 From f34f0b70ddb9bff2c439e730e69992e7209aa456 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 28 Jul 2015 14:20:38 -0400 Subject: [PATCH 2/5] keyring: don't change keyring password explicitly It will happen automatically by the pam stack --- gnome-initial-setup/gis-keyring.c | 57 ---------------------- gnome-initial-setup/gis-keyring.h | 1 - .../pages/password/gis-password-page.c | 2 - 3 files changed, 60 deletions(-) diff --git a/gnome-initial-setup/gis-keyring.c b/gnome-initial-setup/gis-keyring.c index 6459591..cbef4f2 100644 --- a/gnome-initial-setup/gis-keyring.c +++ b/gnome-initial-setup/gis-keyring.c @@ -40,87 +40,30 @@ */ void gis_ensure_login_keyring () { GSubprocess *subprocess = NULL; GSubprocessLauncher *launcher = NULL; GError *error = NULL; g_debug ("launching gnome-keyring-daemon --login"); launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_SILENCE); subprocess = g_subprocess_launcher_spawn (launcher, &error, "gnome-keyring-daemon", "--unlock", NULL); if (subprocess == NULL) { g_warning ("Failed to spawn gnome-keyring-daemon --unlock: %s", error->message); g_error_free (error); goto out; } if (!g_subprocess_communicate_utf8 (subprocess, DUMMY_PWD, NULL, NULL, NULL, &error)) { g_warning ("Failed to communicate with gnome-keyring-daemon: %s", error->message); g_error_free (error); goto out; } out: if (subprocess) g_object_unref (subprocess); if (launcher) g_object_unref (launcher); } - -void -gis_update_login_keyring_password (const gchar *new_) -{ - GDBusConnection *bus = NULL; - SecretService *service = NULL; - SecretValue *old_secret = NULL; - SecretValue *new_secret = NULL; - GError *error = NULL; - - service = secret_service_get_sync (SECRET_SERVICE_OPEN_SESSION, NULL, &error); - if (service == NULL) { - g_warning ("Failed to get secret service: %s", error->message); - g_error_free (error); - goto out; - } - - bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); - if (bus == NULL) { - g_warning ("Failed to get session bus: %s", error->message); - g_error_free (error); - goto out; - } - - old_secret = secret_value_new (DUMMY_PWD, strlen (DUMMY_PWD), "text/plain"); - new_secret = secret_value_new (new_, strlen (new_), "text/plain"); - - g_dbus_connection_call_sync (bus, - "org.gnome.keyring", - "/org/freedesktop/secrets", - "org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface", - "ChangeWithMasterPassword", - g_variant_new ("(o@(oayays)@(oayays))", - "/org/freedesktop/secrets/collection/login", - secret_service_encode_dbus_secret (service, old_secret), - secret_service_encode_dbus_secret (service, new_secret)), - NULL, - 0, - G_MAXINT, - NULL, &error); - - if (error != NULL) { - g_warning ("Failed to change keyring password: %s", error->message); - g_error_free (error); - } - -out: - - if (service) - g_object_unref (service); - if (bus) - g_object_unref (bus); - if (old_secret) - secret_value_unref (old_secret); - if (new_secret) - secret_value_unref (new_secret); -} diff --git a/gnome-initial-setup/gis-keyring.h b/gnome-initial-setup/gis-keyring.h index 764f1e6..496b153 100644 --- a/gnome-initial-setup/gis-keyring.h +++ b/gnome-initial-setup/gis-keyring.h @@ -1,35 +1,34 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* * Copyright (C) 2014 Red Hat * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Written by: * Matthias Clasen */ #ifndef __GIS_KEYRING_H__ #define __GIS_KEYRING_H__ #include G_BEGIN_DECLS void gis_ensure_login_keyring (); -void gis_update_login_keyring_password (const gchar *new_); G_END_DECLS #endif /* __GIS_KEYRING_H__ */ diff --git a/gnome-initial-setup/pages/password/gis-password-page.c b/gnome-initial-setup/pages/password/gis-password-page.c index 6d55c39..3ce3752 100644 --- a/gnome-initial-setup/pages/password/gis-password-page.c +++ b/gnome-initial-setup/pages/password/gis-password-page.c @@ -65,62 +65,60 @@ page_validate (GisPasswordPage *page) static void update_page_validation (GisPasswordPage *page) { gis_page_set_complete (GIS_PAGE (page), page_validate (page)); } static void gis_password_page_save_data (GisPage *gis_page) { GisPasswordPage *page = GIS_PASSWORD_PAGE (gis_page); GisPasswordPagePrivate *priv = gis_password_page_get_instance_private (page); ActUser *act_user; const gchar *password; if (gis_page->driver == NULL) return; gis_driver_get_user_permissions (gis_page->driver, &act_user, &password); if (act_user == NULL) /* enterprise account */ return; password = gtk_entry_get_text (GTK_ENTRY (priv->password_entry)); if (strlen (password) == 0) act_user_set_password_mode (act_user, ACT_USER_PASSWORD_MODE_NONE); else act_user_set_password (act_user, password, ""); gis_driver_set_user_permissions (gis_page->driver, act_user, password); - - gis_update_login_keyring_password (password); } static void gis_password_page_shown (GisPage *gis_page) { GisPasswordPage *page = GIS_PASSWORD_PAGE (gis_page); GisPasswordPagePrivate *priv = gis_password_page_get_instance_private (page); gtk_widget_grab_focus (priv->password_entry); } static gboolean validate (GisPasswordPage *page) { GisPasswordPagePrivate *priv = gis_password_page_get_instance_private (page); const gchar *password; const gchar *verify; gint strength_level; const gchar *hint; const gchar *long_hint; if (priv->timeout_id != 0) { g_source_remove (priv->timeout_id); priv->timeout_id = 0; } password = gtk_entry_get_text (GTK_ENTRY (priv->password_entry)); verify = gtk_entry_get_text (GTK_ENTRY (priv->confirm_entry)); pw_strength (password, NULL, priv->username, &hint, &long_hint, &strength_level); -- 2.3.7 From 82a1a59dfa1c831942491ac8c4e11703c5bfa863 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 27 Jul 2015 15:38:56 -0400 Subject: [PATCH 3/5] password: detect enterprise account by NULL username when saving Right now we detect an enterprise account by the lack of an ActUser object. That can't work going forward though, since other bits of the code need an ActUser object for enterprise accounts. This commit changes the heuristic to look for a NULL username. --- gnome-initial-setup/pages/password/gis-password-page.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-initial-setup/pages/password/gis-password-page.c b/gnome-initial-setup/pages/password/gis-password-page.c index 3ce3752..a860dc5 100644 --- a/gnome-initial-setup/pages/password/gis-password-page.c +++ b/gnome-initial-setup/pages/password/gis-password-page.c @@ -47,70 +47,73 @@ struct _GisPasswordPagePrivate GtkWidget *confirm_explanation; gboolean valid_confirm; gboolean valid_password; guint timeout_id; const gchar *username; }; typedef struct _GisPasswordPagePrivate GisPasswordPagePrivate; G_DEFINE_TYPE_WITH_PRIVATE (GisPasswordPage, gis_password_page, GIS_TYPE_PAGE); static gboolean page_validate (GisPasswordPage *page) { GisPasswordPagePrivate *priv = gis_password_page_get_instance_private (page); return priv->valid_confirm; } static void update_page_validation (GisPasswordPage *page) { gis_page_set_complete (GIS_PAGE (page), page_validate (page)); } static void gis_password_page_save_data (GisPage *gis_page) { GisPasswordPage *page = GIS_PASSWORD_PAGE (gis_page); GisPasswordPagePrivate *priv = gis_password_page_get_instance_private (page); ActUser *act_user; + const gchar *username; const gchar *password; if (gis_page->driver == NULL) return; - gis_driver_get_user_permissions (gis_page->driver, &act_user, &password); + username = gis_driver_get_username (gis_page->driver); - if (act_user == NULL) /* enterprise account */ + if (username == NULL) /* enterprise account */ return; + gis_driver_get_user_permissions (gis_page->driver, &act_user, &password); + password = gtk_entry_get_text (GTK_ENTRY (priv->password_entry)); if (strlen (password) == 0) act_user_set_password_mode (act_user, ACT_USER_PASSWORD_MODE_NONE); else act_user_set_password (act_user, password, ""); gis_driver_set_user_permissions (gis_page->driver, act_user, password); } static void gis_password_page_shown (GisPage *gis_page) { GisPasswordPage *page = GIS_PASSWORD_PAGE (gis_page); GisPasswordPagePrivate *priv = gis_password_page_get_instance_private (page); gtk_widget_grab_focus (priv->password_entry); } static gboolean validate (GisPasswordPage *page) { GisPasswordPagePrivate *priv = gis_password_page_get_instance_private (page); const gchar *password; const gchar *verify; gint strength_level; const gchar *hint; const gchar *long_hint; if (priv->timeout_id != 0) { -- 2.3.7 From 53de9c3565bbb3c007894c00008a32fa97a88ca1 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 27 Jul 2015 14:47:15 -0400 Subject: [PATCH 4/5] account: set act_user object on driver The summary page expects the act-user object to be set in the driver. That only happens at the moment for local users, not enterprise login users. This commit fixes things, so it happens for enterprise login users as well. --- .../pages/account/gis-account-page-enterprise.c | 5 +++++ gnome-initial-setup/pages/account/gis-account-page.c | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/gnome-initial-setup/pages/account/gis-account-page-enterprise.c b/gnome-initial-setup/pages/account/gis-account-page-enterprise.c index f33688c..4c9feb3 100644 --- a/gnome-initial-setup/pages/account/gis-account-page-enterprise.c +++ b/gnome-initial-setup/pages/account/gis-account-page-enterprise.c @@ -52,60 +52,61 @@ struct _GisAccountPageEnterprisePrivate GtkWidget *domain_entry; GtkTreeModel *realms_model; GtkWidget *join_dialog; GtkWidget *join_name; GtkWidget *join_password; GtkWidget *join_domain; GtkWidget *join_computer; ActUserManager *act_client; ActUser *act_user; guint realmd_watch; UmRealmManager *realm_manager; gboolean domain_chosen; /* Valid during apply */ UmRealmObject *realm; GCancellable *cancellable; gboolean join_prompted; GisPageApplyCallback apply_complete_callback; gpointer apply_complete_data; }; typedef struct _GisAccountPageEnterprisePrivate GisAccountPageEnterprisePrivate; G_DEFINE_TYPE_WITH_PRIVATE (GisAccountPageEnterprise, gis_account_page_enterprise, GTK_TYPE_BIN); enum { VALIDATION_CHANGED, + USER_CACHED, LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = { 0 }; static void validation_changed (GisAccountPageEnterprise *page) { g_signal_emit (page, signals[VALIDATION_CHANGED], 0); } static void apply_complete (GisAccountPageEnterprise *page, gboolean valid) { GisAccountPageEnterprisePrivate *priv = gis_account_page_enterprise_get_instance_private (page); priv->apply_complete_callback (NULL, valid, priv->apply_complete_data); } static void show_error_dialog (GisAccountPageEnterprise *page, const gchar *message, GError *error) { GtkWidget *dialog; if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page))), @@ -146,60 +147,61 @@ gis_account_page_enterprise_validate (GisAccountPageEnterprise *page) valid_domain = is_valid_name (name); return valid_name && valid_domain; } static void on_permit_user_login (GObject *source, GAsyncResult *result, gpointer user_data) { GisAccountPageEnterprise *page = user_data; GisAccountPageEnterprisePrivate *priv = gis_account_page_enterprise_get_instance_private (page); UmRealmCommon *common; GError *error = NULL; gchar *login; common = UM_REALM_COMMON (source); um_realm_common_call_change_login_policy_finish (common, result, &error); if (error == NULL) { /* * Now tell the account service about this user. The account service * should also lookup information about this via the realm and make * sure all that is functional. */ login = um_realm_calculate_login (common, gtk_entry_get_text (GTK_ENTRY (priv->login))); g_return_if_fail (login != NULL); g_debug ("Caching remote user: %s", login); priv->act_user = act_user_manager_cache_user (priv->act_client, login, NULL); + g_signal_emit (page, signals[USER_CACHED], 0, priv->act_user, gtk_entry_get_text (GTK_ENTRY (priv->password))); apply_complete (page, TRUE); g_free (login); } else { show_error_dialog (page, _("Failed to register account"), error); g_message ("Couldn't permit logins on account: %s", error->message); g_error_free (error); apply_complete (page, FALSE); } } static void enterprise_permit_user_login (GisAccountPageEnterprise *page, UmRealmObject *realm) { GisAccountPageEnterprisePrivate *priv = gis_account_page_enterprise_get_instance_private (page); UmRealmCommon *common; gchar *login; const gchar *add[2]; const gchar *remove[1]; GVariant *options; common = um_realm_object_get_common (realm); login = um_realm_calculate_login (common, gtk_entry_get_text (GTK_ENTRY (priv->login))); g_return_if_fail (login != NULL); add[0] = login; add[1] = NULL; remove[0] = NULL; @@ -794,45 +796,48 @@ gis_account_page_enterprise_dispose (GObject *object) } static void gis_account_page_enterprise_class_init (GisAccountPageEnterpriseClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructed = gis_account_page_enterprise_constructed; object_class->dispose = gis_account_page_enterprise_dispose; gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-account-page-enterprise.ui"); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, login); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, password); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, domain); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, domain_entry); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, realms_model); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, image); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, join_dialog); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, join_name); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, join_password); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, join_domain); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageEnterprise, join_computer); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), gis_account_page_enterprise_hierarchy_changed); signals[VALIDATION_CHANGED] = g_signal_new ("validation-changed", GIS_TYPE_ACCOUNT_PAGE_ENTERPRISE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + signals[USER_CACHED] = g_signal_new ("user-cached", GIS_TYPE_ACCOUNT_PAGE_ENTERPRISE, + G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, ACT_TYPE_USER, G_TYPE_STRING); } static void gis_account_page_enterprise_init (GisAccountPageEnterprise *page) { gtk_widget_init_template (GTK_WIDGET (page)); } void gis_account_page_enterprise_shown (GisAccountPageEnterprise *page) { GisAccountPageEnterprisePrivate *priv = gis_account_page_enterprise_get_instance_private (page); gtk_widget_grab_focus (priv->domain_entry); } diff --git a/gnome-initial-setup/pages/account/gis-account-page.c b/gnome-initial-setup/pages/account/gis-account-page.c index 9cf5231..60bb947 100644 --- a/gnome-initial-setup/pages/account/gis-account-page.c +++ b/gnome-initial-setup/pages/account/gis-account-page.c @@ -168,76 +168,93 @@ gis_account_page_shown (GisPage *gis_page) { GisAccountPage *page = GIS_ACCOUNT_PAGE (gis_page); GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page); gis_account_page_local_shown (GIS_ACCOUNT_PAGE_LOCAL (priv->page_local)); } static void on_local_user_created (GtkWidget *page_local, ActUser *user, char *password, GisAccountPage *page) { const gchar *language; language = gis_driver_get_user_language (GIS_PAGE (page)->driver); if (language) act_user_set_language (user, language); gis_driver_set_user_permissions (GIS_PAGE (page)->driver, user, password); } static void on_local_page_confirmed (GisAccountPageLocal *local, GisAccountPage *page) { gis_assistant_next_page (gis_driver_get_assistant (GIS_PAGE (page)->driver)); } static void +on_local_user_cached (GtkWidget *page_local, + ActUser *user, + char *password, + GisAccountPage *page) +{ + const gchar *language; + + language = gis_driver_get_user_language (GIS_PAGE (page)->driver); + if (language) + act_user_set_language (user, language); + + gis_driver_set_user_permissions (GIS_PAGE (page)->driver, user, password); +} + +static void gis_account_page_constructed (GObject *object) { GisAccountPage *page = GIS_ACCOUNT_PAGE (object); GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page); G_OBJECT_CLASS (gis_account_page_parent_class)->constructed (object); g_signal_connect (priv->page_local, "validation-changed", G_CALLBACK (on_validation_changed), page); g_signal_connect (priv->page_local, "user-created", G_CALLBACK (on_local_user_created), page); g_signal_connect (priv->page_local, "confirm", G_CALLBACK (on_local_page_confirmed), page); g_signal_connect (priv->page_enterprise, "validation-changed", G_CALLBACK (on_validation_changed), page); + g_signal_connect (priv->page_enterprise, "user-cached", + G_CALLBACK (on_local_user_cached), page); update_page_validation (page); g_signal_connect (priv->page_toggle, "toggled", G_CALLBACK (toggle_mode), page); g_object_bind_property (page, "applying", priv->page_toggle, "sensitive", G_BINDING_INVERT_BOOLEAN); g_object_bind_property (priv->page_enterprise, "visible", priv->page_toggle, "visible", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); /* force a refresh by setting to an invalid value */ priv->mode = NUM_MODES; set_mode (page, UM_LOCAL); gtk_widget_show (GTK_WIDGET (page)); } static void gis_account_page_locale_changed (GisPage *page) { gis_page_set_title (GIS_PAGE (page), _("About You")); } static void gis_account_page_class_init (GisAccountPageClass *klass) { GisPageClass *page_class = GIS_PAGE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-account-page.ui"); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, page_local); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, page_enterprise); -- 2.3.7 From 7a221199fe4dc5a8e5b2b451d809df2c10b7030c Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 27 Jul 2015 16:31:58 -0400 Subject: [PATCH 5/5] driver: duplicate password Otherwise it will get freed at an inopportune moment. --- gnome-initial-setup/gis-driver.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c index cbc4410..bfa35ce 100644 --- a/gnome-initial-setup/gis-driver.c +++ b/gnome-initial-setup/gis-driver.c @@ -42,79 +42,80 @@ gis_driver_mode_get_type (void) { { GIS_DRIVER_MODE_EXISTING_USER, "GIS_DRIVER_MODE_EXISTING_USER", "existing_user" }, { 0, NULL, NULL } }; enum_type_id = g_enum_register_static("GisDriverMode", values); } return enum_type_id; } enum { REBUILD_PAGES, LOCALE_CHANGED, LAST_SIGNAL, }; static guint signals[LAST_SIGNAL]; enum { PROP_0, PROP_MODE, PROP_USERNAME, PROP_LAST, }; static GParamSpec *obj_props[PROP_LAST]; struct _GisDriverPrivate { GtkWindow *main_window; GisAssistant *assistant; ActUser *user_account; - const gchar *user_password; + gchar *user_password; gchar *lang_id; gchar *username; GisDriverMode mode; }; typedef struct _GisDriverPrivate GisDriverPrivate; G_DEFINE_TYPE_WITH_PRIVATE(GisDriver, gis_driver, GTK_TYPE_APPLICATION) static void gis_driver_finalize (GObject *object) { GisDriver *driver = GIS_DRIVER (object); GisDriverPrivate *priv = gis_driver_get_instance_private (driver); g_free (priv->lang_id); g_free (priv->username); + g_free (priv->user_password); G_OBJECT_CLASS (gis_driver_parent_class)->finalize (object); } static void prepare_main_window (GisDriver *driver) { GisDriverPrivate *priv = gis_driver_get_instance_private (driver); GdkGeometry size_hints; if (gis_driver_is_small_screen (driver)) { GtkWidget *child, *sw; child = g_object_ref (gtk_bin_get_child (GTK_BIN (priv->main_window))); gtk_container_remove (GTK_CONTAINER (priv->main_window), child); sw = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (sw); gtk_container_add (GTK_CONTAINER (priv->main_window), sw); gtk_container_add (GTK_CONTAINER (sw), child); g_object_unref (child); gtk_window_maximize (priv->main_window); } else { size_hints.min_width = 1024; size_hints.min_height = 768; size_hints.win_gravity = GDK_GRAVITY_CENTER; @@ -153,61 +154,61 @@ gis_driver_set_user_language (GisDriver *driver, const gchar *lang_id) const gchar * gis_driver_get_user_language (GisDriver *driver) { GisDriverPrivate *priv = gis_driver_get_instance_private (driver); return priv->lang_id; } void gis_driver_set_username (GisDriver *driver, const gchar *username) { GisDriverPrivate *priv = gis_driver_get_instance_private (driver); g_free (priv->username); priv->username = g_strdup (username); g_object_notify (G_OBJECT (driver), "username"); } const gchar * gis_driver_get_username (GisDriver *driver) { GisDriverPrivate *priv = gis_driver_get_instance_private (driver); return priv->username; } void gis_driver_set_user_permissions (GisDriver *driver, ActUser *user, const gchar *password) { GisDriverPrivate *priv = gis_driver_get_instance_private (driver); priv->user_account = user; - priv->user_password = password; + priv->user_password = g_strdup (password); } void gis_driver_get_user_permissions (GisDriver *driver, ActUser **user, const gchar **password) { GisDriverPrivate *priv = gis_driver_get_instance_private (driver); *user = priv->user_account; *password = priv->user_password; } void gis_driver_add_page (GisDriver *driver, GisPage *page) { GisDriverPrivate *priv = gis_driver_get_instance_private (driver); gis_assistant_add_page (priv->assistant, page); } void gis_driver_hide_window (GisDriver *driver) { GisDriverPrivate *priv = gis_driver_get_instance_private (driver); gtk_widget_hide (GTK_WIDGET (priv->main_window)); } static void gis_driver_real_locale_changed (GisDriver *driver) -- 2.3.7