#include <stdlib.h>
#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
#include <gcrypt.h>
#include "greeter.h"
#include "shared-data-manager.h"
enum {
- PROP_0,
- PROP_ACTIVE_USERNAME,
+ PROP_ACTIVE_USERNAME = 1,
};
enum {
CONNECTED,
+ DISCONNECTED,
CREATE_SESSION,
START_SESSION,
LAST_SIGNAL
return g_object_new (GREETER_TYPE, NULL);
}
-gboolean
-greeter_start (Greeter *greeter, gboolean (*setup_child_cb)(Greeter *greeter, int input_fd, int output_fd, gpointer user_data), gpointer user_data)
+void
+greeter_set_file_descriptors (Greeter *greeter, int to_greeter_fd, int from_greeter_fd)
{
- int to_greeter_pipe[2], from_greeter_pipe[2];
- int to_greeter_output, from_greeter_input;
- gboolean result;
GError *error = NULL;
- /* Create a pipe to talk with the greeter */
- if (pipe (to_greeter_pipe) != 0 || pipe (from_greeter_pipe) != 0)
- {
- g_warning ("Failed to create pipes: %s", strerror (errno));
- return FALSE;
- }
- to_greeter_output = to_greeter_pipe[0];
- greeter->priv->to_greeter_input = to_greeter_pipe[1];
+ g_return_if_fail (greeter != NULL);
+ g_return_if_fail (greeter->priv->to_greeter_input < 0);
+ g_return_if_fail (greeter->priv->from_greeter_output < 0);
+
+ greeter->priv->to_greeter_input = to_greeter_fd;
greeter->priv->to_greeter_channel = g_io_channel_unix_new (greeter->priv->to_greeter_input);
g_io_channel_set_encoding (greeter->priv->to_greeter_channel, NULL, &error);
if (error)
g_warning ("Failed to set encoding on to greeter channel to binary: %s\n", error->message);
g_clear_error (&error);
- greeter->priv->from_greeter_output = from_greeter_pipe[0];
- from_greeter_input = from_greeter_pipe[1];
+ greeter->priv->from_greeter_output = from_greeter_fd;
greeter->priv->from_greeter_channel = g_io_channel_unix_new (greeter->priv->from_greeter_output);
g_io_channel_set_encoding (greeter->priv->from_greeter_channel, NULL, &error);
if (error)
g_clear_error (&error);
g_io_channel_set_buffered (greeter->priv->from_greeter_channel, FALSE);
greeter->priv->from_greeter_watch = g_io_add_watch (greeter->priv->from_greeter_channel, G_IO_IN | G_IO_HUP, read_cb, greeter);
-
- /* Don't allow the daemon end of the pipes to be accessed in child processes */
- fcntl (greeter->priv->to_greeter_input, F_SETFD, FD_CLOEXEC);
- fcntl (greeter->priv->from_greeter_output, F_SETFD, FD_CLOEXEC);
-
- result = setup_child_cb (greeter, from_greeter_input, to_greeter_output, user_data);
-
- /* Close the session ends of the pipe */
- close (from_greeter_input);
- close (to_greeter_output);
-
- return result;
}
void
}
static void
-handle_login (Greeter *greeter, guint32 sequence_number, const gchar *username)
+handle_authenticate (Greeter *greeter, guint32 sequence_number, const gchar *username)
{
const gchar *autologin_username, *service;
gboolean is_interactive;
}
static void
-handle_login_as_guest (Greeter *greeter, guint32 sequence_number)
+handle_authenticate_as_guest (Greeter *greeter, guint32 sequence_number)
{
g_debug ("Greeter start authentication for guest account");
}
static void
-handle_login_remote (Greeter *greeter, const gchar *session_name, const gchar *username, guint32 sequence_number)
+handle_authenticate_remote (Greeter *greeter, const gchar *session_name, const gchar *username, guint32 sequence_number)
{
gchar *service;
{
g_debug ("Greeter closed communication channel");
greeter->priv->from_greeter_watch = 0;
+ g_signal_emit (greeter, signals[DISCONNECTED], 0);
return FALSE;
}
if (error)
g_warning ("Error reading from greeter: %s", error->message);
g_clear_error (&error);
- if (status != G_IO_STATUS_NORMAL)
+ if (status == G_IO_STATUS_EOF)
+ {
+ g_debug ("Greeter closed communication channel");
+ greeter->priv->from_greeter_watch = 0;
+ g_signal_emit (greeter, signals[DISCONNECTED], 0);
+ return FALSE;
+ }
+ else if (status != G_IO_STATUS_NORMAL)
return TRUE;
greeter->priv->n_read += n_read;
case GREETER_MESSAGE_AUTHENTICATE:
sequence_number = read_int (greeter, &offset);
username = read_string (greeter, &offset);
- handle_login (greeter, sequence_number, username);
+ handle_authenticate (greeter, sequence_number, username);
g_free (username);
break;
case GREETER_MESSAGE_AUTHENTICATE_AS_GUEST:
sequence_number = read_int (greeter, &offset);
- handle_login_as_guest (greeter, sequence_number);
+ handle_authenticate_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);
+ handle_authenticate_remote (greeter, session_name, username, sequence_number);
break;
case GREETER_MESSAGE_CONTINUE_AUTHENTICATION:
n_secrets = read_int (greeter, &offset);
}
Session *
-greeter_get_authentication_session (Greeter *greeter)
+greeter_take_authentication_session (Greeter *greeter)
{
+ Session *session;
+
g_return_val_if_fail (greeter != NULL, NULL);
- return greeter->priv->authentication_session;
+
+ session = greeter->priv->authentication_session;
+ if (greeter->priv->authentication_session)
+ g_signal_handlers_disconnect_matched (greeter->priv->authentication_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, greeter);
+ greeter->priv->authentication_session = NULL;
+
+ return session;
}
gboolean
NULL,
G_TYPE_NONE, 0);
+ signals[DISCONNECTED] =
+ g_signal_new (GREETER_SIGNAL_DISCONNECTED,
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GreeterClass, disconnected),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
signals[CREATE_SESSION] =
g_signal_new (GREETER_SIGNAL_CREATE_SESSION,
G_TYPE_FROM_CLASS (klass),