[gnome-shell] Re-lock the screen if we're restarted from a previously crashed shell



commit ccfa3d3be15b3a52bfcc37feee3abb2f2d4f66cb
Author: Colin Walters <walters verbum org>
Date:   Thu Jan 17 14:39:54 2013 -0500

    Re-lock the screen if we're restarted from a previously crashed shell
    
    This way we "fail closed", which is better for security.
    
    See https://bugs.launchpad.net/ubuntu/+source/gdm/+bug/1064584
    
    https://bugzilla.gnome.org/show_bug.cgi?id=691987

 js/ui/main.js         |    3 +
 js/ui/screenShield.js |   13 ++++++
 src/shell-global.c    |  100 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/shell-global.h    |    8 ++++
 4 files changed, 124 insertions(+), 0 deletions(-)
---
diff --git a/js/ui/main.js b/js/ui/main.js
index 2657678..2dc421b 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -195,6 +195,9 @@ function _initializeUI() {
                               if (keybindingMode == Shell.KeyBindingMode.NONE) {
                                   keybindingMode = Shell.KeyBindingMode.NORMAL;
                               }
+                              if (screenShield) {
+                                  screenShield.lockIfWasLocked();
+                              }
                           });
 }
 
diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js
index 48cfaa6..185f109 100644
--- a/js/ui/screenShield.js
+++ b/js/ui/screenShield.js
@@ -30,6 +30,7 @@ const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
 const LOCK_ENABLED_KEY = 'lock-enabled';
 const LOCK_DELAY_KEY = 'lock-delay';
 
+const LOCKED_STATE_STR = 'screenShield.locked';
 // fraction of screen height the arrow must reach before completing
 // the slide up automatically
 const ARROW_DRAG_THRESHOLD = 0.1;
@@ -1175,6 +1176,7 @@ const ScreenShield = new Lang.Class({
         this._isLocked = false;
         this.emit('active-changed');
         this.emit('locked-changed');
+        global.set_runtime_state(LOCKED_STATE_STR, null);
     },
 
     activate: function(animate) {
@@ -1191,6 +1193,7 @@ const ScreenShield = new Lang.Class({
         }
 
         this._resetLockScreen(animate, animate);
+        global.set_runtime_state(LOCKED_STATE_STR, GLib.Variant.new('b', true));
 
         // We used to set isActive and emit active-changed here,
         // but now we do that from lockScreenShown, which means
@@ -1217,5 +1220,15 @@ const ScreenShield = new Lang.Class({
 
         this.emit('locked-changed');
     },
+
+    // If the previous shell crashed, and gnome-session restarted us, then re-lock
+    lockIfWasLocked: function() {
+        let wasLocked = global.get_runtime_state('b', LOCKED_STATE_STR);
+        if (wasLocked === null)
+            return;
+        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
+            this.lock(false);
+        }));
+    }
 });
 Signals.addSignalMethods(ScreenShield.prototype);
diff --git a/src/shell-global.c b/src/shell-global.c
index 9a594b7..2f96048 100644
--- a/src/shell-global.c
+++ b/src/shell-global.c
@@ -82,6 +82,8 @@ struct _ShellGlobal {
   const char *userdatadir;
   StFocusManager *focus_manager;
 
+  GFile *runtime_state_path;
+
   guint work_count;
   GSList *leisure_closures;
   guint leisure_function_id;
@@ -232,6 +234,8 @@ shell_global_init (ShellGlobal *global)
   const char *datadir = g_getenv ("GNOME_SHELL_DATADIR");
   const char *shell_js = g_getenv("GNOME_SHELL_JS");
   char *imagedir, **search_path;
+  char *path;
+  const char *byteorder_string;
 
   if (!datadir)
     datadir = GNOME_SHELL_DATADIR;
@@ -254,6 +258,20 @@ shell_global_init (ShellGlobal *global)
   global->userdatadir = g_build_filename (g_get_user_data_dir (), "gnome-shell", NULL);
   g_mkdir_with_parents (global->userdatadir, 0700);
 
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+  byteorder_string = "LE";
+#else
+  byteorder_string = "BE";
+#endif
+
+  /* And the runtime state */
+  path = g_strdup_printf ("%s/gnome-shell/runtime-state-%s.%s",
+                          g_get_user_runtime_dir (),
+                          byteorder_string,
+                          XDisplayName (NULL));
+  (void) g_mkdir_with_parents (path, 0700);
+  global->runtime_state_path = g_file_new_for_path (path);
+
   global->settings = g_settings_new ("org.gnome.shell");
   
   global->grab_notifier = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
@@ -295,6 +313,8 @@ shell_global_finalize (GObject *object)
 
   the_object = NULL;
 
+  g_clear_object (&global->runtime_state_path);
+
   G_OBJECT_CLASS(shell_global_parent_class)->finalize (object);
 }
 
@@ -1764,3 +1784,83 @@ shell_global_get_session_mode (ShellGlobal *global)
 
   return global->session_mode;
 }
+
+static GFile *
+get_runtime_state_path (ShellGlobal  *global,
+                        const char   *property_name)
+{
+  return g_file_get_child (global->runtime_state_path, property_name);
+}
+
+/**
+ * shell_global_set_runtime_state:
+ * @global: a #ShellGlobal
+ * @property_name: Name of the property
+ * @variant: (allow-none): A #GVariant, or %NULL to unset
+ *
+ * Change the value of serialized runtime state.
+ */
+void
+shell_global_set_runtime_state (ShellGlobal  *global,
+                                const char   *property_name,
+                                GVariant     *variant)
+{
+  GFile *path;
+
+  path = get_runtime_state_path (global, property_name);
+
+  if (variant == NULL)
+    (void) g_file_delete (path, NULL, NULL);
+  else
+    {
+      gsize size = g_variant_get_size (variant);
+      g_file_replace_contents (path, g_variant_get_data (variant), size,
+                               NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
+                               NULL, NULL, NULL);
+    }
+}
+
+/**
+ * shell_global_get_runtime_state:
+ * @global: a #ShellGlobal
+ * @property_type: Expected data type
+ * @property_name: Name of the property
+ *
+ * The shell maintains "runtime" state which does not persist across
+ * logout or reboot.
+ *
+ * Returns: The value of a serialized property, or %NULL if none stored
+ */
+GVariant *
+shell_global_get_runtime_state (ShellGlobal  *global,
+                                const char   *property_type,
+                                const char   *property_name)
+{
+  GVariant *res = NULL;
+  GMappedFile *mfile;
+  GFile *path;
+  char *pathstr;
+  GError *local_error = NULL;
+
+  path = get_runtime_state_path (global, property_name);
+  pathstr = g_file_get_path (path);
+  mfile = g_mapped_file_new (pathstr, FALSE, &local_error);
+  if (!mfile)
+    {
+      if (!g_error_matches (local_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+        {
+          g_warning ("Failed to open runtime state: %s", local_error->message);
+        }
+      g_clear_error (&local_error);
+    }
+  else
+    {
+      GBytes *bytes = g_mapped_file_get_bytes (mfile);
+      res = g_variant_new_from_bytes ((GVariantType*)property_type, bytes, TRUE);
+      g_bytes_unref (bytes);
+      g_mapped_file_unref (mfile);
+    }
+
+ out:
+  return res;
+}
diff --git a/src/shell-global.h b/src/shell-global.h
index 69dff85..38532b5 100644
--- a/src/shell-global.h
+++ b/src/shell-global.h
@@ -149,6 +149,14 @@ void     shell_global_reexec_self               (ShellGlobal  *global);
 
 const char *     shell_global_get_session_mode  (ShellGlobal  *global);
 
+void     shell_global_set_runtime_state      (ShellGlobal  *global,
+                                              const char   *property_name,
+                                              GVariant     *variant);
+GVariant * shell_global_get_runtime_state       (ShellGlobal  *global,
+                                                 const char   *property_type,
+                                                 const char   *property_name);
+
+
 G_END_DECLS
 
 #endif /* __SHELL_GLOBAL_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]