]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Got authentication API working
authorunknown <robert.ancell@gmail.com>
Thu, 29 Apr 2010 13:09:40 +0000 (23:09 +1000)
committerunknown <robert.ancell@gmail.com>
Thu, 29 Apr 2010 13:09:40 +0000 (23:09 +1000)
.bzrignore
configure.ac
src/Makefile.am
src/display-manager.c
src/display.c
src/display.h
src/display.xml [new file with mode: 0644]

index 702e4361752268163abdc7100c579ce0fb0a15fe..b45c5b6534bc1c47822ade4b48ff34b95d0b1eeb 100644 (file)
@@ -17,3 +17,4 @@ xmldocs.make
 po/stamp-it
 po/POTFILES
 src/lightdm
+src/display-glue.h
index f842608ccd1ef69d48a84cddd9ab57adc4b2e429..9c5910d68618893d2463154095b07e6e99df267c 100644 (file)
@@ -28,6 +28,9 @@ PKG_CHECK_MODULES(LIGHTDM, [
 
 AC_CHECK_HEADERS([security/pam_appl.h],[],[AC_MSG_ERROR([PAM not found])])
 
+AC_PATH_PROG(DBUSBINDINGTOOL, dbus-binding-tool)
+AC_SUBST(DBUSBINDINGTOOL)
+
 dnl ###########################################################################
 dnl Documentation
 dnl ###########################################################################
index bc0dd633e25aa270af79bd813bf3f685522026a5..2e9eee80f182797f9740ab037b6d275a5efdb26b 100644 (file)
@@ -1,5 +1,8 @@
 bin_PROGRAMS = lightdm
 
+display-glue.h: display.xml
+       $(DBUSBINDINGTOOL) --prefix=display --mode=glib-server --output=$@ $^
+
 lightdm_SOURCES = \
        display.c \
        display.h \
@@ -7,6 +10,9 @@ lightdm_SOURCES = \
        display-manager.h \
        lightdm.c
 
+BUILT_SOURCES = \
+       display-glue.h
+
 lightdm_CFLAGS = \
        $(LIGHTDM_CFLAGS) \
        $(WARN_CFLAGS) \
@@ -20,4 +26,5 @@ lightdm_LDADD = \
        -lpam
 
 DISTCLEANFILES = \
+       $(BUILT_SOURCES) \
        Makefile.in
index 13c0c14db96979a07ea46284b68d5760e784686a..334fa9b835dc9afc4e9e1a101fa3a6ca034e2409 100644 (file)
@@ -9,10 +9,15 @@
  * license.
  */
 
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+
 #include "display-manager.h"
 
 struct DisplayManagerPrivate
 {
+    DBusGConnection *connection;
+
     GList *displays;
 };
 
@@ -40,6 +45,7 @@ display_manager_add_display (DisplayManager *manager)
 
     display = display_new ();
     g_signal_connect (G_OBJECT (display), "exited", G_CALLBACK (display_exited_cb), manager);
+    dbus_g_connection_register_g_object (manager->priv->connection, "/org/gnome/LightDisplayManager", G_OBJECT (display));
 
     return display;
 }
@@ -47,7 +53,27 @@ display_manager_add_display (DisplayManager *manager)
 static void
 display_manager_init (DisplayManager *manager)
 {
+    GError *error = NULL;
+    DBusGProxy *proxy;
+    guint result;
+
     manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, DISPLAY_MANAGER_TYPE, DisplayManagerPrivate);
+  
+    manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); // FIXME: Use system or private bus
+    if (!manager->priv->connection)
+        g_warning ("Failed to register on D-Bus: %s", error->message);
+    g_clear_error (&error);
+
+    proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
+                                       DBUS_SERVICE_DBUS,
+                                       DBUS_PATH_DBUS,
+                                       DBUS_INTERFACE_DBUS);
+    if (!org_freedesktop_DBus_request_name (proxy,
+                                            "org.gnome.LightDisplayManager",
+                                            DBUS_NAME_FLAG_DO_NOT_QUEUE, &result, &error))
+        g_warning ("Failed to register D-Bus name: %s", error->message);
+    g_object_unref (proxy);
+
     display_manager_add_display (manager);
 }
 
index b6f88fd57b084b9dd4ee04e1b025b15def9d90aa..8937d0fda5660d95754eab284d57121465282002 100644 (file)
@@ -18,6 +18,7 @@
 #include <security/pam_appl.h>
 
 #include "display.h"
+#include "display-glue.h"
 
 enum {
     EXITED,
@@ -161,22 +162,58 @@ start_greeter (Display *display)
     start_session (display, "gdm", argv);
 }
 
+// FIXME: Make a PAM GObject
+
+#define DBUS_STRUCT_INT_STRING dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID)
+
 static int
 pam_conv_cb (int num_msg, const struct pam_message **msg,
              struct pam_response **resp, void *app_data)
 {
     Display *display = app_data;
-    gpointer response;
+    GPtrArray *request;
+    gchar **secrets;
+    int i, secret_index = 0, n_secrets = 0;
 
     /* Respond to d-bus query with messages */
-    dbus_g_method_return (display->priv->dbus_context, 666); // ACTIONS
+    request = g_ptr_array_new ();
+    for (i = 0; i < num_msg; i++)
+    {
+        GValue value = { 0 };
+      
+        g_value_init (&value, DBUS_STRUCT_INT_STRING);
+        g_value_take_boxed (&value, dbus_g_type_specialized_construct (DBUS_STRUCT_INT_STRING));
+        // FIXME: Need to convert to UTF-8
+        dbus_g_type_struct_set (&value, 0, msg[i]->msg_style, 1, msg[i]->msg, G_MAXUINT);
+        g_ptr_array_add (request, g_value_get_boxed (&value));
+
+        if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF || msg[i]->msg_style == PAM_PROMPT_ECHO_ON)
+            n_secrets++;
+    }
+    dbus_g_method_return (display->priv->dbus_context, 0, request);
     display->priv->dbus_context = NULL;
 
-    /* Wait for responses */
-    response = g_async_queue_pop (display->priv->authentication_response_queue);
+    /* Wait for secrets */
+    secrets = g_async_queue_pop (display->priv->authentication_response_queue);
+    if (g_strv_length (secrets) != n_secrets)
+        return PAM_SYSTEM_ERR;
 
+    *resp = calloc (num_msg, sizeof (struct pam_response));
+    if (*resp == NULL)
+        return PAM_BUF_ERR;
+  
     /* Fill responses */
-    // ...
+    for (i = 0; i < num_msg; i++)
+    {
+        if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF || msg[i]->msg_style == PAM_PROMPT_ECHO_ON)
+        {
+            // FIXME: Need to convert from UTF-8
+            (*resp)[i].resp = g_strdup (secrets[secret_index]);
+            secret_index++;
+        }
+    }
+  
+    g_strfreev (secrets);
 
     return 0;
 }
@@ -187,18 +224,20 @@ authenticate_cb (gpointer data)
     Display *display = data;
     struct pam_conv conversation = { pam_conv_cb, display };
     int result;
+    GPtrArray *request;
 
     pam_start ("check_pass", display->priv->username, &conversation, &display->priv->pam_handle);
     result = pam_authenticate (display->priv->pam_handle, 0);
+    g_debug ("pam_authenticate -> %s", pam_strerror (display->priv->pam_handle, result));
 
     /* Thread complete */
-    g_thread_join (display->priv->authentication_thread);
     display->priv->authentication_thread = NULL;
     g_async_queue_unref (display->priv->authentication_response_queue);
     display->priv->authentication_response_queue = NULL;
 
     /* Respond to D-Bus request */
-    dbus_g_method_return (display->priv->dbus_context, 888); // FINISHED
+    request = g_ptr_array_new ();
+    dbus_g_method_return (display->priv->dbus_context, result, request);
     display->priv->dbus_context = NULL;
 
     return NULL;
@@ -211,7 +250,7 @@ display_start_authentication (Display *display, const char *username, DBusGMetho
 
     // FIXME: Only allow calls from the greeter
 
-    g_return_val_if_fail (display->priv->authentication_thread != NULL, FALSE);
+    g_return_val_if_fail (display->priv->authentication_thread == NULL, FALSE);
 
     /* Store authentication request and D-Bus request to respond to */
     g_free (display->priv->username);
@@ -219,8 +258,9 @@ display_start_authentication (Display *display, const char *username, DBusGMetho
     display->priv->dbus_context = context;
 
     /* Start thread */
+    // FIXME: Need to be able to abort the thread on error
     display->priv->authentication_response_queue = g_async_queue_new ();
-    display->priv->authentication_thread = g_thread_create (authenticate_cb, display, TRUE, &error);
+    display->priv->authentication_thread = g_thread_create (authenticate_cb, display, FALSE, &error);
     if (!display->priv->authentication_thread)
     {
         g_warning ("Failed to start authentication thread: %s", error->message);
@@ -233,16 +273,16 @@ display_start_authentication (Display *display, const char *username, DBusGMetho
 }
 
 gboolean
-display_continue_authentication (Display *display, int data, DBusGMethodInvocation *context)
+display_continue_authentication (Display *display, gchar **secrets, DBusGMethodInvocation *context)
 {
-    g_return_val_if_fail (display->priv->authentication_thread == NULL, FALSE);
-    g_return_val_if_fail (display->priv->dbus_context != NULL, FALSE);
+    g_return_val_if_fail (display->priv->authentication_thread != NULL, FALSE);
+    g_return_val_if_fail (display->priv->dbus_context == NULL, FALSE);
 
     // FIXME: Only allow calls from the greeter
 
     /* Push onto queue and store request to respond to */
     display->priv->dbus_context = context;
-    g_async_queue_push (display->priv->authentication_response_queue, GINT_TO_POINTER (data));
+    g_async_queue_push (display->priv->authentication_response_queue, g_strdupv (secrets));
 
     return TRUE;
 }
@@ -302,4 +342,6 @@ display_class_init (DisplayClass *klass)
                       NULL, NULL,
                       g_cclosure_marshal_VOID__VOID,
                       G_TYPE_NONE, 0);
+
+    dbus_g_object_type_install_info (DISPLAY_TYPE, &dbus_glib_display_object_info);
 }
index db36c5d39bb7b0b8d02f9149279bd428abe5bfc0..41331cc239fbb9f2753f46f61535f2d6f9f19aea 100644 (file)
@@ -41,7 +41,7 @@ Display *display_new (void);
 
 gboolean display_start_authentication (Display *display, const char *username, DBusGMethodInvocation *context);
 
-gboolean display_continue_authentication (Display *display, int data, DBusGMethodInvocation *context);
+gboolean display_continue_authentication (Display *display, gchar **secrets, DBusGMethodInvocation *context);
 
 G_END_DECLS
 
diff --git a/src/display.xml b/src/display.xml
new file mode 100644 (file)
index 0000000..23bd766
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+  <interface name="org.gnome.LightDisplayManager.Display">
+    <method name="StartAuthentication">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg name="username" direction="in" type="s"/>
+      <arg name="requests" direction="out" type="ia(is)"/>
+    </method>
+    <method name="ContinueAuthentication">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg name="secrets" direction="in" type="as"/>
+      <arg name="requests" direction="out" type="ia(is)"/>
+    </method>
+  </interface>
+</node>