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
This commit is contained in:
parent
727e4c0b37
commit
ccfa3d3be1
@ -195,6 +195,9 @@ function _initializeUI() {
|
|||||||
if (keybindingMode == Shell.KeyBindingMode.NONE) {
|
if (keybindingMode == Shell.KeyBindingMode.NONE) {
|
||||||
keybindingMode = Shell.KeyBindingMode.NORMAL;
|
keybindingMode = Shell.KeyBindingMode.NORMAL;
|
||||||
}
|
}
|
||||||
|
if (screenShield) {
|
||||||
|
screenShield.lockIfWasLocked();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
|||||||
const LOCK_ENABLED_KEY = 'lock-enabled';
|
const LOCK_ENABLED_KEY = 'lock-enabled';
|
||||||
const LOCK_DELAY_KEY = 'lock-delay';
|
const LOCK_DELAY_KEY = 'lock-delay';
|
||||||
|
|
||||||
|
const LOCKED_STATE_STR = 'screenShield.locked';
|
||||||
// fraction of screen height the arrow must reach before completing
|
// fraction of screen height the arrow must reach before completing
|
||||||
// the slide up automatically
|
// the slide up automatically
|
||||||
const ARROW_DRAG_THRESHOLD = 0.1;
|
const ARROW_DRAG_THRESHOLD = 0.1;
|
||||||
@ -1175,6 +1176,7 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._isLocked = false;
|
this._isLocked = false;
|
||||||
this.emit('active-changed');
|
this.emit('active-changed');
|
||||||
this.emit('locked-changed');
|
this.emit('locked-changed');
|
||||||
|
global.set_runtime_state(LOCKED_STATE_STR, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
activate: function(animate) {
|
activate: function(animate) {
|
||||||
@ -1191,6 +1193,7 @@ const ScreenShield = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._resetLockScreen(animate, animate);
|
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,
|
// We used to set isActive and emit active-changed here,
|
||||||
// but now we do that from lockScreenShown, which means
|
// but now we do that from lockScreenShown, which means
|
||||||
@ -1217,5 +1220,15 @@ const ScreenShield = new Lang.Class({
|
|||||||
|
|
||||||
this.emit('locked-changed');
|
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);
|
Signals.addSignalMethods(ScreenShield.prototype);
|
||||||
|
@ -82,6 +82,8 @@ struct _ShellGlobal {
|
|||||||
const char *userdatadir;
|
const char *userdatadir;
|
||||||
StFocusManager *focus_manager;
|
StFocusManager *focus_manager;
|
||||||
|
|
||||||
|
GFile *runtime_state_path;
|
||||||
|
|
||||||
guint work_count;
|
guint work_count;
|
||||||
GSList *leisure_closures;
|
GSList *leisure_closures;
|
||||||
guint leisure_function_id;
|
guint leisure_function_id;
|
||||||
@ -232,6 +234,8 @@ shell_global_init (ShellGlobal *global)
|
|||||||
const char *datadir = g_getenv ("GNOME_SHELL_DATADIR");
|
const char *datadir = g_getenv ("GNOME_SHELL_DATADIR");
|
||||||
const char *shell_js = g_getenv("GNOME_SHELL_JS");
|
const char *shell_js = g_getenv("GNOME_SHELL_JS");
|
||||||
char *imagedir, **search_path;
|
char *imagedir, **search_path;
|
||||||
|
char *path;
|
||||||
|
const char *byteorder_string;
|
||||||
|
|
||||||
if (!datadir)
|
if (!datadir)
|
||||||
datadir = GNOME_SHELL_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);
|
global->userdatadir = g_build_filename (g_get_user_data_dir (), "gnome-shell", NULL);
|
||||||
g_mkdir_with_parents (global->userdatadir, 0700);
|
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->settings = g_settings_new ("org.gnome.shell");
|
||||||
|
|
||||||
global->grab_notifier = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
|
global->grab_notifier = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
|
||||||
@ -295,6 +313,8 @@ shell_global_finalize (GObject *object)
|
|||||||
|
|
||||||
the_object = NULL;
|
the_object = NULL;
|
||||||
|
|
||||||
|
g_clear_object (&global->runtime_state_path);
|
||||||
|
|
||||||
G_OBJECT_CLASS(shell_global_parent_class)->finalize (object);
|
G_OBJECT_CLASS(shell_global_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1764,3 +1784,83 @@ shell_global_get_session_mode (ShellGlobal *global)
|
|||||||
|
|
||||||
return global->session_mode;
|
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;
|
||||||
|
}
|
||||||
|
@ -149,6 +149,14 @@ void shell_global_reexec_self (ShellGlobal *global);
|
|||||||
|
|
||||||
const char * shell_global_get_session_mode (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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __SHELL_GLOBAL_H__ */
|
#endif /* __SHELL_GLOBAL_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user