[gdm-list] [RFC PATCH] Support for PAM_XDISPLAY and PAM_XAUTH_DATA
- From: Eamon Walsh <ewalsh tycho nsa gov>
- To: gdm-list gnome org
- Subject: [gdm-list] [RFC PATCH] Support for PAM_XDISPLAY and PAM_XAUTH_DATA
- Date: Thu, 17 Jan 2008 01:27:53 -0500
This patch implements support for two new pam items that are in the
Linux-PAM repo. The first item is PAM_XDISPLAY which contains the name
of the X display, and the second item is PAM_XAUTH_DATA which contains
an Xauth structure. These are intended to allow PAM session modules to
connect to the X server to set up the user's session, if the X server
supports security extensions (such as SELinux, which is my reason for
working on this).
The display name was easy, but to get the Xauth structure the name of
the display authority file must be sent through the SessionDirect object
to the SessionWorker object. The SessionWorker object looks up the
display in the authority file before calling pam_open_session(). This
last step is a little dodgy and I am considering going back to the
Linux-PAM list and asking to change PAM_XAUTH_DATA (if it's not too
late) to just take the name of an authority file instead of a raw Xauth
structure. Alternately, the lookup could be added to the
DisplayAccessFile class which already has authfile parsing code.
Comments and review are appreciated.
Makefile.am | 1
gdm-product-slave.c | 3 +
gdm-session-direct.c | 46 +++++++++++++++++++++++++++-
gdm-session-direct.h | 1
gdm-session-worker.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++--
gdm-simple-slave.c | 3 +
test-session.c | 1
7 files changed, 131 insertions(+), 5 deletions(-)
Index: daemon/gdm-product-slave.c
===================================================================
--- daemon/gdm-product-slave.c (revision 5615)
+++ daemon/gdm-product-slave.c (working copy)
@@ -671,6 +671,7 @@
char *display_name;
char *display_hostname;
char *display_device;
+ char *display_x11_authority_file;
g_debug ("GdmProductSlave: Creating new session");
@@ -678,6 +679,7 @@
"display-name", &display_name,
"display-hostname", &display_hostname,
"display-is-local", &display_is_local,
+ "display-x11-authority-file", &display_x11_authority_file,
NULL);
/* FIXME: we don't yet have a display device! */
@@ -686,6 +688,7 @@
slave->priv->session = gdm_session_direct_new (display_name,
display_hostname,
display_device,
+ display_x11_authority_file,
display_is_local);
g_free (display_name);
g_free (display_hostname);
Index: daemon/test-session.c
===================================================================
--- daemon/test-session.c (revision 5615)
+++ daemon/test-session.c (working copy)
@@ -248,6 +248,7 @@
session = gdm_session_direct_new (":0",
g_get_host_name (),
ttyname (STDIN_FILENO),
+ getenv("XAUTHORITY"),
TRUE);
g_debug ("GdmSessionDirect object created successfully");
Index: daemon/gdm-session-worker.c
===================================================================
--- daemon/gdm-session-worker.c (revision 5615)
+++ daemon/gdm-session-worker.c (working copy)
@@ -34,6 +34,9 @@
#include <security/pam_appl.h>
+#include <X11/Xauth.h>
+#include <xcb/xcb.h>
+
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
@@ -94,6 +97,7 @@
/* from Setup */
char *service;
char *x11_display_name;
+ char *x11_authority_file;
char *display_device;
char *hostname;
char *username;
@@ -801,18 +805,54 @@
return g_strdup (x11_display_name);
}
+static struct pam_xauth_data *
+_get_xauth_for_pam (const char *x11_display_name,
+ const char *x11_authority_file)
+{
+ struct pam_xauth_data *retval;
+ char *hostname, displayname[16];
+ int display;
+ Xauth *auth;
+
+ if (x11_authority_file == NULL || x11_authority_file[0] == '\0')
+ return NULL;
+ if (! xcb_parse_display (x11_display_name, &hostname, &display, NULL))
+ return NULL;
+
+ snprintf (displayname, sizeof (displayname), "%d", display);
+ g_setenv ("XAUTHORITY", x11_authority_file, TRUE);
+
+ auth = XauGetAuthByAddr(FamilyWild,
+ strlen (hostname), hostname,
+ strlen (displayname), displayname,
+ 0, NULL);
+ retval = g_malloc0 (sizeof (struct pam_xauth_data));
+
+ if (auth && retval) {
+ retval->namelen = auth->name_length;
+ retval->name = g_strndup (auth->name, auth->name_length);
+ retval->datalen = auth->data_length;
+ retval->data = g_memdup (auth->data, auth->data_length);
+ }
+ XauDisposeAuth(auth);
+ g_debug("GdmSessionWorker: finished _get_xauth_for_pam");
+ return retval;
+}
+
static gboolean
gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
const char *service,
const char *username,
const char *hostname,
const char *x11_display_name,
+ const char *x11_authority_file,
const char *display_device,
GError **error)
{
- struct pam_conv pam_conversation;
- int error_code;
- char *pam_tty;
+ struct pam_conv pam_conversation;
+ struct pam_xauth_data *pam_xauth;
+ int error_code;
+ char *pam_tty;
g_assert (worker->priv->pam_handle == NULL);
@@ -885,6 +925,34 @@
goto out;
}
+ /* set XDISPLAY */
+ error_code = pam_set_item (worker->priv->pam_handle, PAM_XDISPLAY, x11_display_name);
+
+ if (error_code != PAM_SUCCESS) {
+ g_set_error (error,
+ GDM_SESSION_WORKER_ERROR,
+ GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
+ _("error informing authentication system of display string - %s"),
+ pam_strerror (worker->priv->pam_handle, error_code));
+ goto out;
+ }
+
+ /* set XAUTHDATA */
+ pam_xauth = _get_xauth_for_pam (x11_display_name, x11_authority_file);
+ error_code = pam_set_item (worker->priv->pam_handle, PAM_XAUTHDATA, pam_xauth);
+ g_free (pam_xauth->name);
+ g_free (pam_xauth->data);
+ g_free (pam_xauth);
+
+ if (error_code != PAM_SUCCESS) {
+ g_set_error (error,
+ GDM_SESSION_WORKER_ERROR,
+ GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
+ _("error informing authentication system of display xauth credentials - %s"),
+ pam_strerror (worker->priv->pam_handle, error_code));
+ goto out;
+ }
+
g_debug ("GdmSessionWorker: state SETUP_COMPLETE");
worker->priv->state = GDM_SESSION_WORKER_STATE_SETUP_COMPLETE;
@@ -1527,6 +1595,7 @@
worker->priv->username,
worker->priv->hostname,
worker->priv->x11_display_name,
+ worker->priv->x11_authority_file,
worker->priv->display_device,
&error);
if (! res) {
@@ -1784,6 +1853,7 @@
DBusError error;
const char *service;
const char *x11_display_name;
+ const char *x11_authority_file;
const char *console;
const char *hostname;
dbus_bool_t res;
@@ -1797,10 +1867,12 @@
DBUS_TYPE_STRING, &x11_display_name,
DBUS_TYPE_STRING, &console,
DBUS_TYPE_STRING, &hostname,
+ DBUS_TYPE_STRING, &x11_authority_file,
DBUS_TYPE_INVALID);
if (res) {
worker->priv->service = g_strdup (service);
worker->priv->x11_display_name = g_strdup (x11_display_name);
+ worker->priv->x11_authority_file = g_strdup (x11_authority_file);
worker->priv->display_device = g_strdup (console);
worker->priv->hostname = g_strdup (hostname);
worker->priv->username = NULL;
@@ -1820,6 +1892,7 @@
DBusError error;
const char *service;
const char *x11_display_name;
+ const char *x11_authority_file;
const char *console;
const char *hostname;
const char *username;
@@ -1834,11 +1907,13 @@
DBUS_TYPE_STRING, &x11_display_name,
DBUS_TYPE_STRING, &console,
DBUS_TYPE_STRING, &hostname,
+ DBUS_TYPE_STRING, &x11_authority_file,
DBUS_TYPE_STRING, &username,
DBUS_TYPE_INVALID);
if (res) {
worker->priv->service = g_strdup (service);
worker->priv->x11_display_name = g_strdup (x11_display_name);
+ worker->priv->x11_authority_file = g_strdup (x11_authority_file);
worker->priv->display_device = g_strdup (console);
worker->priv->hostname = g_strdup (hostname);
worker->priv->username = g_strdup (username);
Index: daemon/gdm-session-direct.c
===================================================================
--- daemon/gdm-session-direct.c (revision 5615)
+++ daemon/gdm-session-direct.c (working copy)
@@ -82,6 +82,7 @@
char *display_name;
char *display_hostname;
char *display_device;
+ char *display_x11_authority_file;
gboolean display_is_local;
DBusServer *server;
@@ -95,6 +96,7 @@
PROP_DISPLAY_HOSTNAME,
PROP_DISPLAY_IS_LOCAL,
PROP_DISPLAY_DEVICE,
+ PROP_DISPLAY_X11_AUTHORITY_FILE,
PROP_USER_X11_AUTHORITY_FILE,
};
@@ -898,12 +900,14 @@
" <arg name=\"x11_display_name\" type=\"s\"/>\n"
" <arg name=\"display_device\" type=\"s\"/>\n"
" <arg name=\"hostname\" type=\"s\"/>\n"
+ " <arg name=\"x11_authority_file\" type=\"s\"/>\n"
" </signal>\n"
" <signal name=\"SetupForUser\">\n"
" <arg name=\"service_name\" type=\"s\"/>\n"
" <arg name=\"x11_display_name\" type=\"s\"/>\n"
" <arg name=\"display_device\" type=\"s\"/>\n"
" <arg name=\"hostname\" type=\"s\"/>\n"
+ " <arg name=\"x11_authority_file\" type=\"s\"/>\n"
" <arg name=\"username\" type=\"s\"/>\n"
" </signal>\n"
" <signal name=\"Authenticate\">\n"
@@ -1281,6 +1285,7 @@
const char *display_name;
const char *display_device;
const char *display_hostname;
+ const char *display_x11_authority_file;
if (session->priv->display_name != NULL) {
display_name = session->priv->display_name;
@@ -1297,6 +1302,11 @@
} else {
display_device = "";
}
+ if (session->priv->display_x11_authority_file != NULL) {
+ display_x11_authority_file = session->priv->display_x11_authority_file;
+ } else {
+ display_x11_authority_file = "";
+ }
g_debug ("GdmSessionDirect: Beginning setup");
@@ -1309,6 +1319,7 @@
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
if (! send_dbus_message (session->priv->worker_connection, message)) {
g_debug ("GdmSessionDirect: Could not send %s signal", "Setup");
@@ -1325,6 +1336,7 @@
const char *display_name;
const char *display_device;
const char *display_hostname;
+ const char *display_x11_authority_file;
const char *selected_user;
if (session->priv->display_name != NULL) {
@@ -1342,6 +1354,11 @@
} else {
display_device = "";
}
+ if (session->priv->display_x11_authority_file != NULL) {
+ display_x11_authority_file = session->priv->display_x11_authority_file;
+ } else {
+ display_x11_authority_file = "";
+ }
if (session->priv->selected_user != NULL) {
selected_user = session->priv->selected_user;
} else {
@@ -1359,6 +1376,7 @@
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &selected_user);
if (! send_dbus_message (session->priv->worker_connection, message)) {
@@ -1882,6 +1900,14 @@
}
static void
+_gdm_session_direct_set_display_x11_authority_file (GdmSessionDirect *session,
+ const char *name)
+{
+ g_free (session->priv->display_x11_authority_file);
+ session->priv->display_x11_authority_file = g_strdup (name);
+}
+
+static void
_gdm_session_direct_set_display_is_local (GdmSessionDirect *session,
gboolean is)
{
@@ -1911,6 +1937,9 @@
case PROP_USER_X11_AUTHORITY_FILE:
_gdm_session_direct_set_user_x11_authority_file (self, g_value_get_string (value));
break;
+ case PROP_DISPLAY_X11_AUTHORITY_FILE:
+ _gdm_session_direct_set_display_x11_authority_file (self, g_value_get_string (value));
+ break;
case PROP_DISPLAY_IS_LOCAL:
_gdm_session_direct_set_display_is_local (self, g_value_get_boolean (value));
break;
@@ -1943,6 +1972,9 @@
case PROP_USER_X11_AUTHORITY_FILE:
g_value_set_string (value, self->priv->user_x11_authority_file);
break;
+ case PROP_DISPLAY_X11_AUTHORITY_FILE:
+ g_value_set_string (value, self->priv->display_x11_authority_file);
+ break;
case PROP_DISPLAY_IS_LOCAL:
g_value_set_boolean (value, self->priv->display_is_local);
break;
@@ -1975,6 +2007,9 @@
g_free (session->priv->display_device);
session->priv->display_device = NULL;
+ g_free (session->priv->display_x11_authority_file);
+ session->priv->display_x11_authority_file = NULL;
+
g_free (session->priv->server_address);
session->priv->server_address = NULL;
@@ -2062,6 +2097,13 @@
"display is local",
TRUE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class,
+ PROP_DISPLAY_X11_AUTHORITY_FILE,
+ g_param_spec_string ("display-x11-authority-file",
+ "display x11 authority file",
+ "display x11 authority file",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/* not construct only */
g_object_class_install_property (object_class,
PROP_USER_X11_AUTHORITY_FILE,
@@ -2077,14 +2119,13 @@
"display device",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-
}
GdmSessionDirect *
gdm_session_direct_new (const char *display_name,
const char *display_hostname,
const char *display_device,
+ const char *display_x11_authority_file,
gboolean display_is_local)
{
GdmSessionDirect *session;
@@ -2093,6 +2134,7 @@
"display-name", display_name,
"display-hostname", display_hostname,
"display-device", display_device,
+ "display-x11-authority-file", display_x11_authority_file,
"display-is-local", display_is_local,
NULL);
Index: daemon/gdm-session-direct.h
===================================================================
--- daemon/gdm-session-direct.h (revision 5615)
+++ daemon/gdm-session-direct.h (working copy)
@@ -51,6 +51,7 @@
GdmSessionDirect * gdm_session_direct_new (const char *display_name,
const char *display_hostname,
const char *display_device,
+ const char *display_x11_authority_file,
gboolean display_is_local) G_GNUC_MALLOC;
char * gdm_session_direct_get_username (GdmSessionDirect *session_direct);
Index: daemon/gdm-simple-slave.c
===================================================================
--- daemon/gdm-simple-slave.c (revision 5615)
+++ daemon/gdm-simple-slave.c (working copy)
@@ -324,6 +324,7 @@
char *display_name;
char *display_hostname;
char *display_device;
+ char *display_x11_authority_file;
g_debug ("GdmSimpleSlave: Creating new session");
@@ -331,6 +332,7 @@
"display-name", &display_name,
"display-hostname", &display_hostname,
"display-is-local", &display_is_local,
+ "display-x11-authority-file", &display_x11_authority_file,
NULL);
display_device = NULL;
@@ -341,6 +343,7 @@
slave->priv->session = gdm_session_direct_new (display_name,
display_hostname,
display_device,
+ display_x11_authority_file,
display_is_local);
g_free (display_name);
g_free (display_device);
Index: daemon/Makefile.am
===================================================================
--- daemon/Makefile.am (revision 5615)
+++ daemon/Makefile.am (working copy)
@@ -209,6 +209,7 @@
$(NULL)
gdm_session_worker_LDFLAGS = \
+ $(XLIB_LIBS) \
$(PAM_LIBS) \
$(NULL)
--
Eamon Walsh <ewalsh tycho nsa gov>
National Security Agency
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]