-DRUN_DIR=\"$(localstatedir)/run/lightdm\" \
-DCACHE_DIR=\"$(localstatedir)/cache/lightdm\" \
-DXSESSIONS_DIR=\"$(datadir)/xsessions\" \
+ -DREMOTE_SESSIONS_DIR=\"$(datadir)/remote-sessions\" \
-DXGREETERS_DIR=\"$(datadir)/xgreeters\"
lightdm_LDADD = \
#include "greeter.h"
#include "ldm-marshal.h"
+#include "configuration.h"
enum {
CONNECTED,
GKeyFile *session_desktop_file;
gboolean result;
const gchar *c;
- gchar *filename, *path, *service = NULL;
+ gchar *remote_sessions_dir, *filename, *path, *service = NULL;
GError *error = NULL;
/* Validate session name doesn't contain directory separators */
/* 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);
+ remote_sessions_dir = config_get_string (config_get_instance (), "LightDM", "remote-sessions-directory");
+ path = g_build_filename (remote_sessions_dir, filename, NULL);
+ g_free (remote_sessions_dir);
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_debug ("Failed to load session file %s: %s", path, error->message);
+ g_free (path);
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);
gboolean test_mode = FALSE;
gchar *pid_path = "/var/run/lightdm.pid";
gchar *xsessions_dir = NULL;
+ gchar *remote_sessions_dir = NULL;
gchar *xgreeters_dir = NULL;
gchar *config_dir;
gchar *log_dir = NULL;
{ "xsessions-dir", 0, 0, G_OPTION_ARG_STRING, &xsessions_dir,
/* Help string for command line --xsessions-dir flag */
N_("Directory to load X sessions from"), "DIRECTORY" },
+ { "remote-sessions-dir", 0, 0, G_OPTION_ARG_STRING, &remote_sessions_dir,
+ /* Help string for command line --remote-sessions-dir flag */
+ N_("Directory to load remote sessions from"), "DIRECTORY" },
{ "xgreeters-dir", 0, 0, G_OPTION_ARG_STRING, &xgreeters_dir,
/* Help string for command line --xgreeters-dir flag */
N_("Directory to load X greeters from"), "DIRECTORY" },
/* Always use absolute directories as child processes may run from different locations */
xsessions_dir = path_make_absolute (xsessions_dir);
+ remote_sessions_dir = path_make_absolute (remote_sessions_dir);
xgreeters_dir = path_make_absolute (xgreeters_dir);
/* If not running as root write output to directories we control */
g_free (default_cache_dir);
if (!config_has_key (config_get_instance (), "LightDM", "xsessions-directory"))
config_set_string (config_get_instance (), "LightDM", "xsessions-directory", XSESSIONS_DIR);
+ if (!config_has_key (config_get_instance (), "LightDM", "remote-sessions-directory"))
+ config_set_string (config_get_instance (), "LightDM", "remote-sessions-directory", REMOTE_SESSIONS_DIR);
if (!config_has_key (config_get_instance (), "LightDM", "xgreeters-directory"))
config_set_string (config_get_instance (), "LightDM", "xgreeters-directory", XGREETERS_DIR);
if (xsessions_dir)
config_set_string (config_get_instance (), "LightDM", "xsessions-directory", xsessions_dir);
g_free (xsessions_dir);
+ if (remote_sessions_dir)
+ config_set_string (config_get_instance (), "LightDM", "remote-sessions-directory", remote_sessions_dir);
+ g_free (remote_sessions_dir);
if (xgreeters_dir)
config_set_string (config_get_instance (), "LightDM", "xgreeters-directory", xgreeters_dir);
g_free (xgreeters_dir);
test-login-gobject-guest-no-setup-script \
test-login-gobject-guest-fail-setup-script \
test-login-gobject-guest-logout \
+ test-login-gobject-remote-session \
test-login-python \
test-login-python-manual \
test-login-python-manual-previous-session \
test-login-python-guest-no-setup-script \
test-login-python-guest-fail-setup-script \
test-login-python-guest-logout \
+ test-login-python-remote-session \
test-login-session-crash \
test-login-xserver-crash \
test-home-dir-on-authenticate \
test-login-qt-guest-disabled \
test-login-qt-guest-no-setup-script \
test-login-qt-guest-fail-setup-script \
- test-login-qt-guest-logout
+ test-login-qt-guest-logout \
+ test-login-qt-remote-session
endif
EXTRA_DIST = \
scripts/login-pam.conf \
scripts/login-pick-session.conf \
scripts/login-previous-session.conf \
- scripts/login-two-factor.conf \
+ scripts/login-remote-session.conf \
scripts/login-session-crash.conf \
+ scripts/login-two-factor.conf \
scripts/login-wrong-password.conf \
scripts/login-xserver-crash.conf \
scripts/no-accounts-service.conf \
--- /dev/null
+[Desktop Entry]
+Name=Test Remote Session
+Comment=LightDM remote test session
+Exec=test-remote
+X-LightDM-PAM-Service=test-remote
--- /dev/null
+#
+# Check can login without a username, and is prompted for one
+#
+
+[LightDM]
+minimum-display-number=50
+
+#?RUNNER DAEMON-START
+
+# X server starts
+#?XSERVER :50 START
+#?XSERVER :50 INDICATE-READY
+
+# LightDM connects to X server
+#?XSERVER :50 ACCEPT-CONNECT
+
+# Greeter starts
+#?GREETER :50 START
+#?XSERVER :50 ACCEPT-CONNECT
+#?GREETER :50 CONNECT-XSERVER
+#?GREETER :50 CONNECT-TO-DAEMON
+#?GREETER :50 CONNECTED-TO-DAEMON
+
+#?*GREETER :50 AUTHENTICATE-REMOTE SESSION=test-remote
+#?GREETER :50 SHOW-PROMPT TEXT="remote-login:"
+#?*GREETER :50 RESPOND TEXT="remote-user"
+#?GREETER :50 SHOW-PROMPT TEXT="remote-password:"
+#?*GREETER :50 RESPOND TEXT="password"
+#?GREETER :50 AUTHENTICATION-COMPLETE USERNAME=remote-user AUTHENTICATED=TRUE
+#?*GREETER :50 START-SESSION
+#?GREETER :50 TERMINATE SIGNAL=15
+
+# Session starts
+#?SESSION :50 START USER=remote-user
+#?XSERVER :50 ACCEPT-CONNECT
+#?SESSION :50 CONNECT-XSERVER
+
+# Cleanup
+#?*STOP-DAEMON
+# Don't know what order they will terminate
+#?(SESSION :50 TERMINATE SIGNAL=15|XSERVER :50 TERMINATE SIGNAL=15)
+#?(SESSION :50 TERMINATE SIGNAL=15|XSERVER :50 TERMINATE SIGNAL=15)
+#?RUNNER DAEMON-EXIT STATUS=0
{
char *service_name;
char *user;
+ char *ruser;
char *tty;
char **envlist;
struct pam_conv conversation;
if (pamh == NULL)
return PAM_SYSTEM_ERR;
+
+ if (strcmp (pamh->service_name, "test-remote") == 0)
+ {
+ int result;
+ struct pam_message **msg;
+ struct pam_response *resp = NULL;
+
+ msg = malloc (sizeof (struct pam_message *) * 1);
+ msg[0] = malloc (sizeof (struct pam_message));
+ msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
+ msg[0]->msg = "remote-login:";
+ result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
+ free (msg[0]);
+ free (msg);
+ if (result != PAM_SUCCESS)
+ return result;
+
+ if (resp == NULL)
+ return PAM_CONV_ERR;
+ if (resp[0].resp == NULL)
+ {
+ free (resp);
+ return PAM_CONV_ERR;
+ }
+
+ if (pamh->ruser)
+ free (pamh->ruser);
+ pamh->ruser = strdup (resp[0].resp);
+ free (resp[0].resp);
+ free (resp);
+
+ msg = malloc (sizeof (struct pam_message *) * 1);
+ msg[0] = malloc (sizeof (struct pam_message));
+ msg[0]->msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[0]->msg = "remote-password:";
+ result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
+ free (msg[0]);
+ free (msg);
+ if (result != PAM_SUCCESS)
+ return result;
+
+ if (resp == NULL)
+ return PAM_CONV_ERR;
+ if (resp[0].resp == NULL)
+ {
+ free (resp);
+ return PAM_CONV_ERR;
+ }
+
+ password_matches = strcmp (pamh->ruser, "remote-user") == 0 && strcmp (resp[0].resp, "password") == 0;
+ free (resp[0].resp);
+ free (resp);
+
+ if (password_matches)
+ return PAM_SUCCESS;
+ else
+ return PAM_AUTH_ERR;
+ }
/* Prompt for username */
if (pamh->user == NULL)
case PAM_USER:
*item = pamh->user;
return PAM_SUCCESS;
-
+
+ case PAM_RUSER:
+ *item = pamh->ruser;
+ return PAM_SUCCESS;
+
case PAM_USER_PROMPT:
*item = LOGIN_PROMPT;
return PAM_SUCCESS;
free (pamh->service_name);
if (pamh->user)
free (pamh->user);
+ if (pamh->ruser)
+ free (pamh->ruser);
if (pamh->tty)
free (pamh->tty);
free (pamh);
lightdm_greeter_authenticate_as_guest (greeter);
g_free (r);
+ r = g_strdup_printf ("GREETER %s AUTHENTICATE-REMOTE SESSION=", getenv ("DISPLAY"));
+ if (g_str_has_prefix (request, r))
+ lightdm_greeter_authenticate_remote (greeter, request + strlen (r), NULL);
+ g_free (r);
+
r = g_strdup_printf ("GREETER %s RESPOND TEXT=\"", getenv ("DISPLAY"));
if (g_str_has_prefix (request, r))
{
if request.startswith (r):
greeter.authenticate (request[len(r):])
+ r = 'GREETER %s AUTHENTICATE-REMOTE SESSION=' % os.getenv ('DISPLAY')
+ if request.startswith (r):
+ greeter.authenticate_remote (request[len(r):], None)
+
r = 'GREETER %s AUTHENTICATE-GUEST' % os.getenv ('DISPLAY')
if request == r:
greeter.authenticate_as_guest ()
greeter->authenticateAsGuest ();
g_free (r);
+ r = g_strdup_printf ("GREETER %s AUTHENTICATE-REMOTE SESSION=", getenv ("DISPLAY"));
+ if (g_str_has_prefix (request, r))
+ greeter->authenticateRemote (request + strlen (r), NULL);
+ g_free (r);
+
r = g_strdup_printf ("GREETER %s RESPOND TEXT=\"", getenv ("DISPLAY"));
if (g_str_has_prefix (request, r))
{
g_string_append (command_line, " --debug");
g_string_append_printf (command_line, " --cache-dir %s/cache", temp_dir);
g_string_append_printf (command_line, " --xsessions-dir=%s/usr/share/xsessions", temp_dir);
+ g_string_append_printf (command_line, " --remote-sessions-dir=%s/usr/share/remote-sessions", temp_dir);
g_string_append_printf (command_line, " --xgreeters-dir=%s/usr/share/xgreeters", temp_dir);
g_print ("Start daemon with command: PATH=%s LD_PRELOAD=%s LD_LIBRARY_PATH=%s LIGHTDM_TEST_ROOT=%s DBUS_SESSION_BUS_ADDRESS=%s %s\n",
/* Copy over the greeter files */
if (system (g_strdup_printf ("cp -r %s/xsessions %s/usr/share", DATADIR, temp_dir)))
perror ("Failed to copy xsessions");
+ if (system (g_strdup_printf ("cp -r %s/remote-sessions %s/usr/share", DATADIR, temp_dir)))
+ perror ("Failed to copy remote sessions");
if (system (g_strdup_printf ("cp -r %s/xgreeters %s/usr/share", DATADIR, temp_dir)))
perror ("Failed to copy xgreeters");
--- /dev/null
+#!/bin/sh
+./src/dbus-env ./src/test-runner login-remote-session test-gobject-greeter
--- /dev/null
+#!/bin/sh
+./src/dbus-env ./src/test-runner login-remote-session test-python-greeter
--- /dev/null
+#!/bin/sh
+./src/dbus-env ./src/test-runner login-remote-session test-qt-greeter