]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Start work on supporting remote session types
authorRobert Ancell <robert.ancell@canonical.com>
Mon, 20 Aug 2012 05:34:12 +0000 (17:34 +1200)
committerRobert Ancell <robert.ancell@canonical.com>
Mon, 20 Aug 2012 05:34:12 +0000 (17:34 +1200)
liblightdm-gobject/greeter.c
liblightdm-gobject/lightdm/greeter.h
liblightdm-gobject/lightdm/session.h
liblightdm-gobject/session.c
liblightdm-qt/QLightDM/greeter.h
liblightdm-qt/greeter.cpp
src/greeter.c

index 2d31b84cf99905fc332746d1e0d1ddc229d31e23..b6d1ba773580a1c3e02b655853c4b75c3c51a1a2 100644 (file)
@@ -80,7 +80,8 @@ typedef enum
     GREETER_MESSAGE_CONTINUE_AUTHENTICATION,
     GREETER_MESSAGE_START_SESSION,
     GREETER_MESSAGE_CANCEL_AUTHENTICATION,
-    GREETER_MESSAGE_SET_LANGUAGE
+    GREETER_MESSAGE_SET_LANGUAGE,
+    GREETER_MESSAGE_AUTHENTICATE_REMOTE
 } GreeterMessage;
 
 /* Messages from the server to the greeter */
@@ -770,7 +771,7 @@ lightdm_greeter_cancel_autologin (LightDMGreeter *greeter)
  * Starts the authentication procedure for a user.
  **/
 void
-lightdm_greeter_authenticate (LightDMGreeter *greeter, const char *username)
+lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username)
 {
     LightDMGreeterPrivate *priv;
     guint8 message[MAX_MESSAGE_LENGTH];
@@ -831,6 +832,45 @@ lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter)
     write_message (greeter, message, offset);
 }
 
+/**
+ * lightdm_greeter_authenticate_remote:
+ * @greeter: A #LightDMGreeter
+ * @session: The name of a remote session
+ * @username: (allow-none): A username of #NULL to prompt for a username.
+ *
+ * Start authentication for a remote session type.
+ **/
+void
+lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username)
+{
+    LightDMGreeterPrivate *priv;
+    guint8 message[MAX_MESSAGE_LENGTH];
+    gsize offset = 0;
+
+    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
+
+    priv = GET_PRIVATE (greeter);
+
+    g_return_if_fail (priv->connected);
+
+    priv->cancelling_authentication = FALSE;
+    priv->authenticate_sequence_number++;
+    priv->in_authentication = TRUE;
+    priv->is_authenticated = FALSE;
+    g_free (priv->authentication_user);
+    priv->authentication_user = NULL;
+
+    if (username)
+        g_debug ("Starting authentication for remote session %s as user %s...", session, username);
+    else
+        g_debug ("Starting authentication for remote session %s...", session);
+    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_REMOTE, int_length () + string_length (session) + string_length (username), &offset);
+    write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
+    write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
+    write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
+    write_message (greeter, message, offset);
+}
+
 /**
  * lightdm_greeter_respond:
  * @greeter: A #LightDMGreeter
index dc051b3e5c356b9d03b1a2b50968ef810f10d36b..cd26f772b7f8b9843a7c9efdd16b126a30b1c7fb 100644 (file)
@@ -98,10 +98,12 @@ gint lightdm_greeter_get_autologin_timeout_hint (LightDMGreeter *greeter);
 
 void lightdm_greeter_cancel_autologin (LightDMGreeter *greeter);
 
-void lightdm_greeter_authenticate (LightDMGreeter *greeter, const char *username);
+void lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username);
 
 void lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter);
 
+void lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username);
+
 void lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response);
 
 void lightdm_greeter_cancel_authentication (LightDMGreeter *greeter);
index 3b07bdcddba6ad4f01931e8fcc16c2086acec73d..910205e0a0363f9a0fac05d68199d4e020cb7154 100644 (file)
@@ -45,6 +45,8 @@ GType lightdm_session_get_type (void);
 
 GList *lightdm_get_sessions (void);
 
+GList *lightdm_get_remote_sessions (void);
+
 const gchar *lightdm_session_get_key (LightDMSession *session);
 
 const gchar *lightdm_session_get_name (LightDMSession *session);
index 603ddb7f5314e2b2049f0d681067427933fa98de..577e32742167915205118cab9917349a73b08c0e 100644 (file)
@@ -34,6 +34,7 @@ G_DEFINE_TYPE (LightDMSession, lightdm_session, G_TYPE_OBJECT);
 
 static gboolean have_sessions = FALSE;
 static GList *sessions = NULL;
+static GList *remote_sessions = NULL;
 
 static gint 
 compare_session (gconstpointer a, gconstpointer b)
@@ -208,6 +209,20 @@ lightdm_get_sessions (void)
     return sessions;
 }
 
+/**
+ * lightdm_get_remote_sessions:
+ *
+ * Get the available remote sessions.
+ *
+ * Return value: (element-type LightDMSession) (transfer none): A list of #LightDMSession
+ **/
+GList *
+lightdm_get_remote_sessions (void)
+{
+    update_sessions ();
+    return remote_sessions;
+}
+
 /**
  * lightdm_session_get_key:
  * @session: A #LightDMSession
index ab296b5e73b981ad7019063eb682f165c9faeb46..4c6799e07566cff6645ae745b31a873bb58a9ebe 100644 (file)
@@ -72,6 +72,7 @@ public slots:
     bool connectSync();
     void authenticate(const QString &username=QString());
     void authenticateAsGuest();
+    void authenticateRemote(const QString &session=QString(), const QString &username=QString());
     void respond(const QString &response);
     void cancelAuthentication();
     void setLanguage (const QString &language);
index 02e8cd8c6e9874a55fbfdcbf7679dee4c5a2e377..2df535b5211d9afd92779539585e47e784320bda 100644 (file)
@@ -117,7 +117,12 @@ void Greeter::authenticateAsGuest()
 {
     Q_D(Greeter);
     lightdm_greeter_authenticate_as_guest(d->ldmGreeter);
-    
+}
+
+void Greeter::authenticateRemote(const QString &session, const QString &username)
+{
+    Q_D(Greeter);
+    lightdm_greeter_authenticate_remote(d->ldmGreeter, session.toLocal8Bit().data(), username.toLocal8Bit().data());
 }
 
 void Greeter::respond(const QString &response)
index bcdc2ae32d6e094ede742e2be036f85060ffbea6..ad0cf557789dd26a3411bcd49c2a19c56d24622f 100644 (file)
@@ -76,7 +76,8 @@ typedef enum
     GREETER_MESSAGE_CONTINUE_AUTHENTICATION,
     GREETER_MESSAGE_START_SESSION,
     GREETER_MESSAGE_CANCEL_AUTHENTICATION,
-    GREETER_MESSAGE_SET_LANGUAGE
+    GREETER_MESSAGE_SET_LANGUAGE,
+    GREETER_MESSAGE_AUTHENTICATE_REMOTE
 } GreeterMessage;
 
 /* Messages from the server to the greeter */
@@ -350,6 +351,77 @@ handle_login_as_guest (Greeter *greeter, guint32 sequence_number)
     send_end_authentication (greeter, sequence_number, "", PAM_SUCCESS);
 }
 
+static gchar *
+get_remote_session_service (const gchar *session_name)
+{
+    GKeyFile *session_desktop_file;
+    gboolean result;
+    const gchar *c;
+    gchar *filename, *path, *service = NULL;
+    GError *error = NULL;
+
+    /* Validate session name doesn't contain directory separators */
+    for (c = session_name; *c; c++)
+    {
+        if (*c == '/')
+            return NULL;
+    }
+
+    /* Load the session file */
+    session_desktop_file = g_key_file_new ();
+    filename = g_strdup_printf ("%s.desktop", session_name);
+    path = g_build_filename (REMOTE_SESSION_DIR, filename);
+    g_free (filename);
+    result = g_key_file_load_from_file (session_desktop_file, path, G_KEY_FILE_NONE, &error);
+    g_free (path);
+    if (error)
+        g_debug ("Failed to load session file %s: %s", filename, error->message);
+    g_clear_error (&error);
+    if (result)
+        service = g_key_file_get_string (session_desktop_file, G_KEY_FILE_DESKTOP_GROUP, "X-LightDM-PAM-Service", NULL);
+    g_key_file_free (session_desktop_file);
+
+    return service;
+}
+
+static void
+handle_login_remote (Greeter *greeter, const gchar *session_name, const gchar *username, guint32 sequence_number)
+{
+    gchar *service;
+
+    if (username)
+        g_debug ("Greeter start authentication for remote session %s as user %s", session_name, username);
+    else
+        g_debug ("Greeter start authentication for remote session %s", session_name);
+
+    reset_session (greeter);
+
+    service = get_remote_session_service (session_name);
+    if (!service)
+    {
+        send_end_authentication (greeter, sequence_number, "", PAM_SYSTEM_ERR);
+        return;
+    }
+
+    g_signal_emit (greeter, signals[START_AUTHENTICATION], 0, username, &greeter->priv->authentication_session);
+    if (greeter->priv->authentication_session)
+    {
+        g_signal_connect (G_OBJECT (greeter->priv->authentication_session), "got-messages", G_CALLBACK (pam_messages_cb), greeter);
+        g_signal_connect (G_OBJECT (greeter->priv->authentication_session), "authentication-complete", G_CALLBACK (authentication_complete_cb), greeter);
+
+        /* Run the session process */
+        session_start (greeter->priv->authentication_session, service, username, TRUE, TRUE);
+    }
+
+    g_free (service);
+
+    if (!greeter->priv->authentication_session)
+    {
+        send_end_authentication (greeter, sequence_number, "", PAM_USER_UNKNOWN);
+        return;
+    }
+}
+
 static void
 handle_continue_authentication (Greeter *greeter, gchar **secrets)
 {
@@ -569,6 +641,12 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
         sequence_number = read_int (greeter, &offset);
         handle_login_as_guest (greeter, sequence_number);
         break;
+    case GREETER_MESSAGE_AUTHENTICATE_REMOTE:
+        sequence_number = read_int (greeter, &offset);
+        session_name = read_string (greeter, &offset);
+        username = read_string (greeter, &offset);
+        handle_login_remote (greeter, session_name, username, sequence_number);
+        break;
     case GREETER_MESSAGE_CONTINUE_AUTHENTICATION:
         n_secrets = read_int (greeter, &offset);
         secrets = g_malloc (sizeof (gchar *) * (n_secrets + 1));