Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
home:jberkman
gnome-screensaver
gnome-screensaver-2.16.0-better-pam-integration...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gnome-screensaver-2.16.0-better-pam-integration.patch of Package gnome-screensaver
--- gnome-screensaver-2.16.0/data/lock-dialog-default.glade.better-pam-integration 2006-08-25 10:40:48.000000000 -0400 +++ gnome-screensaver-2.16.0/data/lock-dialog-default.glade 2006-10-15 14:41:06.000000000 -0400 @@ -145,8 +145,7 @@ <child> <widget class="GtkLabel" id="auth-prompt-label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Password:</property> + <property name="label" translatable="yes"></property> <property name="use_underline">False</property> <property name="use_markup">False</property> <property name="justify">GTK_JUSTIFY_LEFT</property> @@ -173,7 +172,6 @@ <child> <widget class="GtkEntry" id="auth-prompt-entry"> - <property name="visible">True</property> <property name="can_focus">True</property> <property name="editable">True</property> <property name="visibility">False</property> --- gnome-screensaver-2.16.0/src/gs-window-x11.c.better-pam-integration 2006-08-04 15:20:11.000000000 -0400 +++ gnome-screensaver-2.16.0/src/gs-window-x11.c 2006-10-15 14:41:06.000000000 -0400 @@ -1373,6 +1373,22 @@ g_signal_emit (window, signals [DIALOG_UP], 0); } +void +gs_window_cancel_unlock_request (GSWindow *window) +{ + /* FIXME: This is a bit of a hammer approach... + * Maybe we should send a delete-event to + * the plug? + */ + g_return_if_fail (GS_IS_WINDOW (window)); + + if (window->priv->lock_socket == NULL) + return; + + if (window->priv->lock_pid > 0) + kill (window->priv->lock_pid, SIGTERM); +} + void gs_window_set_lock_enabled (GSWindow *window, gboolean lock_enabled) --- gnome-screensaver-2.16.0/src/gs-window.h.better-pam-integration 2006-07-31 13:54:48.000000000 -0400 +++ gnome-screensaver-2.16.0/src/gs-window.h 2006-10-15 14:41:06.000000000 -0400 @@ -81,6 +81,7 @@ const char *command); void gs_window_request_unlock (GSWindow *window); +void gs_window_cancel_unlock_request (GSWindow *window); GSWindow * gs_window_new (GdkScreen *screen, int monitor, --- gnome-screensaver-2.16.0/src/gs-auth-pam.c.better-pam-integration 2006-06-08 16:23:40.000000000 -0400 +++ gnome-screensaver-2.16.0/src/gs-auth-pam.c 2006-10-15 14:42:55.000000000 -0400 @@ -28,6 +28,7 @@ # include <unistd.h> #endif +#include <fcntl.h> #include <stdio.h> #include <string.h> #include <sys/types.h> @@ -40,6 +41,7 @@ #include <glib.h> #include <glib/gstdio.h> #include <glib/gi18n.h> +#include <gtk/gtk.h> #include "gs-auth.h" @@ -81,8 +83,20 @@ const char *username; GSAuthMessageFunc cb_func; gpointer cb_data; + int signal_fd; + int result; }; +typedef struct { + struct pam_closure *closure; + GSAuthMessageStyle style; + const char *msg; + char **resp; + gboolean should_interrupt_stack; +} GsAuthMessageHandlerData; +static GCond *message_handled_condition; +static GMutex *message_handler_mutex; + GQuark gs_auth_error_quark (void) { @@ -162,6 +176,48 @@ return ret; } +static gboolean +gs_auth_queued_message_handler (GsAuthMessageHandlerData *data) +{ + g_mutex_lock (message_handler_mutex); + data->should_interrupt_stack = + data->closure->cb_func (data->style, + data->msg, data->resp, + data->closure->cb_data) == FALSE; + g_cond_signal (message_handled_condition); + g_mutex_unlock (message_handler_mutex); + return FALSE; +} + +static gboolean +gs_auth_run_message_handler (struct pam_closure *c, + GSAuthMessageStyle style, + const char *msg, + char **resp) +{ + GsAuthMessageHandlerData data; + + data.closure = c; + data.style = style; + data.msg = msg; + data.resp = resp; + data.should_interrupt_stack = TRUE; + + g_mutex_lock (message_handler_mutex); + + /* Queue the callback in the gui (the main) thread + */ + g_idle_add ((GSourceFunc) gs_auth_queued_message_handler, &data); + + /* Wait for the response + */ + g_cond_wait (message_handled_condition, + message_handler_mutex); + g_mutex_unlock (message_handler_mutex); + + return data.should_interrupt_stack == FALSE; +} + static int pam_conversation (int nmsgs, const struct pam_message **msg, @@ -195,11 +251,12 @@ NULL); if (c->cb_func != NULL) { - res = c->cb_func (style, - msg [replies]->msg, - &reply [replies].resp, - c->cb_data); - + /* blocks until the gui responds + */ + res = gs_auth_run_message_handler (c, style, + msg [replies]->msg, + &reply [replies].resp); + /* If the handler returns FALSE - interrupt the PAM stack */ if (res) { reply [replies].resp_retcode = PAM_SUCCESS; @@ -231,6 +288,16 @@ } } + if (message_handled_condition != NULL) { + g_cond_free (message_handled_condition); + message_handled_condition = NULL; + } + + if (message_handler_mutex != NULL) { + g_mutex_free (message_handler_mutex); + message_handler_mutex = NULL; + } + return TRUE; } @@ -296,6 +363,8 @@ } ret = TRUE; + message_handled_condition = g_cond_new (); + message_handler_mutex = g_mutex_new (); out: if (status_code != NULL) { @@ -342,6 +411,114 @@ } +static int +gs_auth_thread_func (int auth_operation_fd) +{ + static const int flags = 0; + int status; + + status = pam_authenticate (pam_handle, flags); + + /* we're done, close the fd and wake up the main + * loop + */ + close (auth_operation_fd); + + return status; +} + +static gboolean +gs_auth_loop_quit (GIOChannel *source, + GIOCondition condition, + gboolean *thread_done) +{ + *thread_done = TRUE; + gtk_main_quit (); + return FALSE; +} + +static gboolean +gs_auth_identify_user (pam_handle_t *handle, + int *status) +{ + GThread *auth_thread; + GIOChannel *channel; + guint watch_id; + int auth_operation_fds[2]; + int auth_status; + gboolean thread_done; + + channel = NULL; + watch_id = 0; + auth_status = PAM_INCOMPLETE; + + /* This pipe gives us a set of fds we can hook into + * the event loop to be notified when our helper thread + * is ready to be reaped. + */ + if (pipe (auth_operation_fds) < 0) { + goto out; + } + + if (fcntl (auth_operation_fds[0], F_SETFD, FD_CLOEXEC) < 0) { + close (auth_operation_fds[0]); + close (auth_operation_fds[1]); + goto out; + } + + if (fcntl (auth_operation_fds[1], F_SETFD, FD_CLOEXEC) < 0) { + close (auth_operation_fds[0]); + close (auth_operation_fds[1]); + goto out; + } + + channel = g_io_channel_unix_new (auth_operation_fds[0]); + + /* we use a recursive main loop to process ui events + * while we wait on a thread to handle the blocking parts + * of pam authentication. + */ + thread_done = FALSE; + watch_id = g_io_add_watch (channel, G_IO_ERR | G_IO_HUP, + (GIOFunc) gs_auth_loop_quit, &thread_done); + + auth_thread = g_thread_create ((GThreadFunc) gs_auth_thread_func, + GINT_TO_POINTER (auth_operation_fds[1]), + TRUE, NULL); + + if (auth_thread == NULL) { + goto out; + } + + gtk_main (); + + /* if the event loop was quit before the thread is done then we can't + * reap the thread without blocking on it finishing. The + * thread may not ever finish though if the pam module is blocking. + * + * The only time the event loop is going to stop when the thread isn't + * done, however, is if the dialog quits early (from, e.g., "cancel"), + * so we can just exit. An alternative option would be to switch to + * using pthreads directly and calling pthread_cancel. + */ + if (!thread_done) + raise (SIGTERM); + + auth_status = GPOINTER_TO_INT (g_thread_join (auth_thread)); + +out: + if (watch_id != 0) + g_source_remove (watch_id); + + if (channel != NULL) + g_io_channel_unref (channel); + + if (status) + *status = auth_status; + + return auth_status == PAM_SUCCESS; +} + gboolean gs_auth_verify_user (const char *username, const char *display, @@ -356,7 +533,6 @@ sigset_t set; struct timespec timeout; struct passwd *pwent; - int null_tok = 0; const void *p; pwent = getpwnam (username); @@ -364,6 +540,7 @@ return FALSE; } + c.username = username; c.cb_func = func; c.cb_data = data; @@ -386,8 +563,6 @@ set = block_sigchld (); did_we_ask_for_password = FALSE; - status = pam_authenticate (pam_handle, null_tok); - sigtimedwait (&set, NULL, &timeout); unblock_sigchld (); @@ -397,9 +572,9 @@ PAM_STRERROR (pam_handle, status)); } - if (status != PAM_SUCCESS) { - goto DONE; - } + if (!gs_auth_identify_user (pam_handle, &status)) { + goto DONE; + } if ((status = pam_get_item (pam_handle, PAM_USER, &p)) != PAM_SUCCESS) { /* is not really an auth problem, but it will @@ -412,7 +587,7 @@ * but we need to run them anyway because certain pam modules * depend on side effects of the account modules getting run. */ - status2 = pam_acct_mgmt (pam_handle, null_tok); + status2 = pam_acct_mgmt (pam_handle, 0); if (gs_auth_get_verbose ()) { g_message ("pam_acct_mgmt (...) ==> %d (%s)\n", --- gnome-screensaver-2.16.0/src/gnome-screensaver-dialog.c.better-pam-integration 2006-07-18 14:18:23.000000000 -0400 +++ gnome-screensaver-2.16.0/src/gnome-screensaver-dialog.c 2006-10-15 14:41:06.000000000 -0400 @@ -147,6 +147,7 @@ if (response == GS_LOCK_PLUG_RESPONSE_OK) { gs_lock_plug_get_text (plug, &text); } + gs_lock_plug_hide_prompt (plug); return text; } @@ -214,6 +215,9 @@ gs_profile_start (NULL); gs_debug ("Got message style %d: '%s'", style, msg); + gtk_widget_show (GTK_WIDGET (plug)); + gs_lock_plug_set_ready (plug); + ret = TRUE; *response = NULL; message = maybe_translate_message (msg); @@ -256,6 +260,7 @@ gtk_main_iteration (); } + gs_lock_plug_set_busy (plug); gs_profile_end (NULL); return ret; @@ -278,6 +283,8 @@ error = NULL; + gs_lock_plug_hide_prompt (plug); + gs_lock_plug_set_busy (plug); res = gs_auth_verify_user (g_get_user_name (), g_getenv ("DISPLAY"), auth_message_handler, plug, &error); gs_debug ("Verify user returned: %s", res ? "TRUE" : "FALSE"); @@ -306,7 +313,8 @@ response_cb (GSLockPlug *plug, gint response_id) { - if (response_id == GS_LOCK_PLUG_RESPONSE_CANCEL) { + if ((response_id == GS_LOCK_PLUG_RESPONSE_CANCEL) || + (response_id == GTK_RESPONSE_DELETE_EVENT)) { quit_response_cancel (); } } @@ -348,7 +356,7 @@ g_signal_connect (GS_LOCK_PLUG (widget), "response", G_CALLBACK (response_cb), NULL); - gtk_widget_show (widget); + gtk_widget_realize (widget); print_id (widget); --- gnome-screensaver-2.16.0/src/gs-manager.c.better-pam-integration 2006-08-29 15:54:12.000000000 -0400 +++ gnome-screensaver-2.16.0/src/gs-manager.c 2006-10-15 14:41:06.000000000 -0400 @@ -1564,3 +1564,12 @@ return TRUE; } + +void +gs_manager_cancel_unlock_request (GSManager *manager) +{ + GSList *l; + for (l = manager->priv->windows; l; l = l->next) { + gs_window_cancel_unlock_request (l->data); + } +} --- gnome-screensaver-2.16.0/src/gs-lock-plug.h.better-pam-integration 2006-07-18 13:49:24.000000000 -0400 +++ gnome-screensaver-2.16.0/src/gs-lock-plug.h 2006-10-15 14:41:06.000000000 -0400 @@ -68,6 +68,10 @@ void gs_lock_plug_show_prompt (GSLockPlug *plug, const char *message, gboolean visible); +void gs_lock_plug_hide_prompt (GSLockPlug *plug); +void gs_lock_plug_set_busy (GSLockPlug *plug); +void gs_lock_plug_set_ready (GSLockPlug *plug); + void gs_lock_plug_get_text (GSLockPlug *plug, char **text); void gs_lock_plug_show_message (GSLockPlug *plug, --- gnome-screensaver-2.16.0/src/gs-manager.h.better-pam-integration 2006-08-04 15:36:03.000000000 -0400 +++ gnome-screensaver-2.16.0/src/gs-manager.h 2006-10-15 14:41:06.000000000 -0400 @@ -94,6 +94,7 @@ void gs_manager_set_mode (GSManager *manager, GSSaverMode mode); gboolean gs_manager_request_unlock (GSManager *manager); +void gs_manager_cancel_unlock_request (GSManager *manager); G_END_DECLS --- gnome-screensaver-2.16.0/src/gs-lock-plug.c.better-pam-integration 2006-08-25 10:40:49.000000000 -0400 +++ gnome-screensaver-2.16.0/src/gs-lock-plug.c 2006-10-15 14:41:06.000000000 -0400 @@ -102,6 +102,7 @@ guint response_idle_id; GTimeVal start_time; + GList *key_events; }; typedef struct _ResponseData ResponseData; @@ -233,6 +234,11 @@ const char *text) { if (plug->priv->auth_message_label != NULL) { + if (strcmp (text, "") == 0) + gtk_widget_hide (plug->priv->auth_message_label); + else + gtk_widget_show (plug->priv->auth_message_label); + gtk_label_set_text (GTK_LABEL (plug->priv->auth_message_label), text); } } @@ -581,6 +587,32 @@ } } +static void +queue_key_event (GSLockPlug *plug, + GdkEventKey *event) +{ + GdkEvent *saved_event; + + saved_event = gdk_event_copy ((GdkEvent *)event); + plug->priv->key_events = g_list_prepend (plug->priv->key_events, + saved_event); +} + +static void +forward_key_events (GSLockPlug *plug) +{ + plug->priv->key_events = g_list_reverse (plug->priv->key_events); + while (plug->priv->key_events) { + GdkEventKey *event = plug->priv->key_events->data; + + gtk_window_propagate_key_event (GTK_WINDOW (plug), event); + + gdk_event_free ((GdkEvent *)event); + + plug->priv->key_events = g_list_delete_link (plug->priv->key_events, + plug->priv->key_events); + } +} static void gs_lock_plug_size_request (GtkWidget *widget, @@ -861,6 +893,32 @@ } void +gs_lock_plug_set_busy (GSLockPlug *plug) +{ + GdkCursor *cursor; + GtkWidget *top_level; + + top_level = gtk_widget_get_toplevel (GTK_WIDGET (plug)); + + cursor = gdk_cursor_new (GDK_WATCH); + gdk_window_set_cursor (top_level->window, cursor); + gdk_cursor_unref (cursor); +} + +void +gs_lock_plug_set_ready (GSLockPlug *plug) +{ + GdkCursor *cursor; + GtkWidget *top_level; + + top_level = gtk_widget_get_toplevel (GTK_WIDGET (plug)); + + cursor = gdk_cursor_new (GDK_LEFT_PTR); + gdk_window_set_cursor (top_level->window, cursor); + gdk_cursor_unref (cursor); +} + +void gs_lock_plug_show_prompt (GSLockPlug *plug, const char *message, gboolean visible) @@ -869,17 +927,40 @@ gs_debug ("Setting prompt to: %s", message); + gtk_widget_set_sensitive (plug->priv->auth_unlock_button, TRUE); + gtk_widget_show (plug->priv->auth_unlock_button); + gtk_widget_grab_default (plug->priv->auth_unlock_button); gtk_label_set_text (GTK_LABEL (plug->priv->auth_prompt_label), message); + gtk_widget_show (plug->priv->auth_prompt_label); gtk_entry_set_visibility (GTK_ENTRY (plug->priv->auth_prompt_entry), visible); - + gtk_widget_show (plug->priv->auth_prompt_entry); + if (! GTK_WIDGET_HAS_FOCUS (plug->priv->auth_prompt_entry)) { gtk_widget_grab_focus (plug->priv->auth_prompt_entry); } + /* were there any key events sent to the plug while the entry wasnt + * ready? If so, forward them along + */ + forward_key_events (plug); + restart_monitor_progress (plug); } void +gs_lock_plug_hide_prompt (GSLockPlug *plug) +{ + g_return_if_fail (GS_IS_LOCK_PLUG (plug)); + + gtk_widget_hide (plug->priv->auth_prompt_entry); + gtk_widget_hide (plug->priv->auth_prompt_label); + gtk_widget_set_sensitive (plug->priv->auth_unlock_button, FALSE); + gtk_widget_hide (plug->priv->auth_unlock_button); + + gtk_widget_grab_default (plug->priv->auth_cancel_button); +} + +void gs_lock_plug_show_message (GSLockPlug *plug, const char *message) { @@ -915,7 +996,19 @@ capslock_update (plug, capslock_on); } - return FALSE; + /* if the input widget is visible and ready for input + * then just carry on as usual + */ + if (GTK_WIDGET_VISIBLE (plug->priv->auth_prompt_entry) && + GTK_WIDGET_IS_SENSITIVE (plug->priv->auth_prompt_entry)) + return FALSE; + + if (strcmp (event->string, "") == 0) + return FALSE; + + queue_key_event (plug, event); + + return TRUE; } /* adapted from gtk_dialog_add_button */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor