#include <stdlib.h>
#include <string.h>
+#include <gio/gio.h>
+#include <gio/gunixsocketaddress.h>
#include <security/pam_appl.h>
#include "lightdm/greeter.h"
G_DEFINE_QUARK (lightdm_greeter_error, lightdm_greeter_error)
enum {
- PROP_0,
- PROP_DEFAULT_SESSION_HINT,
+ PROP_DEFAULT_SESSION_HINT = 1,
PROP_HIDE_USERS_HINT,
PROP_SHOW_MANUAL_LOGIN_HINT,
PROP_SHOW_REMOTE_LOGIN_HINT,
/* TRUE if the daemon can reuse this greeter */
gboolean resettable;
+ /* Socket connection to daemon */
+ GSocket *socket;
+
/* Channel to write to daemon */
GIOChannel *to_server_channel;
/* Channel to read from daemon */
GIOChannel *from_server_channel;
+ guint from_server_watch;
/* Data read from the daemon */
guint8 *read_buffer;
gboolean cancelling_authentication;
} LightDMGreeterPrivate;
-G_DEFINE_TYPE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
-
-#define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeterPrivate)
+G_DEFINE_TYPE_WITH_PRIVATE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
#define HEADER_SIZE 8
#define MAX_MESSAGE_LENGTH 1024
g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
g_return_if_fail (!priv->connected);
priv->resettable = resettable;
Request *request;
request = g_object_new (request_get_type (), NULL);
- request->greeter = g_object_ref (greeter);
+ request->greeter = greeter;
if (cancellable)
request->cancellable = g_object_ref (cancellable);
request->callback = callback;
timed_login_cb (gpointer data)
{
LightDMGreeter *greeter = data;
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
priv->autologin_timeout = 0;
g_signal_emit (G_OBJECT (greeter), signals[AUTOLOGIN_TIMER_EXPIRED], 0);
static gboolean
connect_to_daemon (LightDMGreeter *greeter, GError **error)
{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
- const gchar *to_server_fd, *from_server_fd;
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
+ const gchar *to_server_fd, *from_server_fd, *pipe_path;
if (priv->to_server_channel || priv->from_server_channel)
return TRUE;
+ /* Use private connection if one exists */
to_server_fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
from_server_fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
- if (!to_server_fd || !from_server_fd)
+ pipe_path = g_getenv ("LIGHTDM_GREETER_PIPE");
+ if (to_server_fd && from_server_fd)
+ {
+ priv->to_server_channel = g_io_channel_unix_new (atoi (to_server_fd));
+ priv->from_server_channel = g_io_channel_unix_new (atoi (from_server_fd));
+ }
+ else if (pipe_path)
+ {
+ GSocketAddress *address;
+ gboolean result;
+
+ priv->socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, error);
+ if (!priv->socket)
+ return FALSE;
+
+ address = g_unix_socket_address_new (pipe_path);
+ result = g_socket_connect (priv->socket, address, NULL, error);
+ g_object_unref (address);
+ if (!result)
+ return FALSE;
+
+ priv->from_server_channel = g_io_channel_unix_new (g_socket_get_fd (priv->socket));
+ priv->to_server_channel = g_io_channel_ref (priv->from_server_channel);
+ }
+ else
{
g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_CONNECTION_FAILED,
"Unable to determine socket to daemon");
return FALSE;
}
- priv->to_server_channel = g_io_channel_unix_new (atoi (to_server_fd));
- priv->from_server_channel = g_io_channel_unix_new (atoi (from_server_fd));
- g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
+ priv->from_server_watch = g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
if (!g_io_channel_set_encoding (priv->to_server_channel, NULL, error) ||
!g_io_channel_set_encoding (priv->from_server_channel, NULL, error))
static gboolean
send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length, GError **error)
{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
gchar *data;
gsize data_length;
guint32 stated_length;
static void
handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
gchar *version;
GString *hint_string;
int timeout;
static void
handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
guint32 sequence_number, n_messages, i;
gchar *username;
static void
handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
guint32 sequence_number, return_code;
gchar *username;
static void
handle_reset (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
GString *hint_string;
g_hash_table_remove_all (priv->hints);
static void
handle_session_result (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
Request *request;
/* Notify asynchronous caller */
static void
handle_shared_dir_result (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
Request *request;
/* Notify asynchronous caller */
static gboolean
recv_message (LightDMGreeter *greeter, gboolean block, guint8 **message, gsize *length, GError **error)
{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
gsize n_to_read, n_read;
if (!connect_to_daemon (greeter, error))
g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
request = request_new (greeter, cancellable, callback, user_data);
if (send_connect (greeter, priv->resettable, &error))
Request *request = REQUEST (result);
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
-
- g_propagate_error (error, request->error);
+
+ if (request->error)
+ g_propagate_error (error, request->error);
return request->result;
}
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
/* Read until we are connected */
if (!send_connect (greeter, priv->resettable, error))
const gchar *
lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name)
{
+ LightDMGreeterPrivate *priv;
+
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
- return g_hash_table_lookup (GET_PRIVATE (greeter)->hints, name);
+
+ priv = lightdm_greeter_get_instance_private (greeter);
+
+ return g_hash_table_lookup (priv->hints, name);
}
/**
g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
if (priv->autologin_timeout)
g_source_remove (priv->autologin_timeout);
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
g_return_val_if_fail (priv->connected, FALSE);
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
g_return_val_if_fail (priv->connected, FALSE);
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
g_return_val_if_fail (priv->connected, FALSE);
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
g_return_val_if_fail (response != NULL, FALSE);
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
g_return_val_if_fail (priv->connected, FALSE);
g_return_val_if_fail (priv->n_responses_waiting > 0, FALSE);
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
g_return_val_if_fail (priv->connected, FALSE);
gboolean
lightdm_greeter_get_in_authentication (LightDMGreeter *greeter)
{
+ LightDMGreeterPrivate *priv;
+
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- return GET_PRIVATE (greeter)->in_authentication;
+
+ priv = lightdm_greeter_get_instance_private (greeter);
+
+ return priv->in_authentication;
}
/**
gboolean
lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter)
{
+ LightDMGreeterPrivate *priv;
+
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- return GET_PRIVATE (greeter)->is_authenticated;
+
+ priv = lightdm_greeter_get_instance_private (greeter);
+
+ return priv->is_authenticated;
}
/**
const gchar *
lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
{
+ LightDMGreeterPrivate *priv;
+
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
- return GET_PRIVATE (greeter)->authentication_user;
+
+ priv = lightdm_greeter_get_instance_private (greeter);
+
+ return priv->authentication_user;
}
/**
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
g_return_val_if_fail (priv->connected, FALSE);
g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
request = request_new (greeter, cancellable, callback, user_data);
priv->start_session_requests = g_list_append (priv->start_session_requests, request);
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- g_propagate_error (error, request->error);
+ if (request->error)
+ g_propagate_error (error, request->error);
return request->result;
}
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
g_return_val_if_fail (priv->connected, FALSE);
g_return_val_if_fail (priv->is_authenticated, FALSE);
g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
request = request_new (greeter, cancellable, callback, user_data);
priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, request);
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
- g_propagate_error (error, request->error);
+ if (request->error)
+ g_propagate_error (error, request->error);
return g_strdup (request->dir);
}
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
- priv = GET_PRIVATE (greeter);
+ priv = lightdm_greeter_get_instance_private (greeter);
g_return_val_if_fail (priv->connected, NULL);
static void
lightdm_greeter_init (LightDMGreeter *greeter)
{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
priv->read_buffer = g_malloc (HEADER_SIZE);
priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
lightdm_greeter_finalize (GObject *object)
{
LightDMGreeter *self = LIGHTDM_GREETER (object);
- LightDMGreeterPrivate *priv = GET_PRIVATE (self);
+ LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (self);
+ g_clear_object (&priv->socket);
if (priv->to_server_channel)
g_io_channel_unref (priv->to_server_channel);
if (priv->from_server_channel)
g_io_channel_unref (priv->from_server_channel);
- g_free (priv->authentication_user);
+ if (priv->from_server_watch)
+ g_source_remove (priv->from_server_watch);
+ priv->from_server_watch = 0;
+ g_clear_pointer (&priv->read_buffer, g_free);
+ g_list_free_full (priv->responses_received, g_free);
+ priv->responses_received = NULL;
+ g_list_free_full (priv->connect_requests, g_object_unref);
+ priv->connect_requests = NULL;
+ g_list_free_full (priv->start_session_requests, g_object_unref);
+ priv->start_session_requests = NULL;
+ g_list_free_full (priv->ensure_shared_data_dir_requests, g_object_unref);
+ priv->ensure_shared_data_dir_requests = NULL;
+ g_clear_pointer (&priv->authentication_user, g_free);
g_hash_table_unref (priv->hints);
+ priv->hints = NULL;
G_OBJECT_CLASS (lightdm_greeter_parent_class)->finalize (object);
}
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- g_type_class_add_private (klass, sizeof (LightDMGreeterPrivate));
-
object_class->set_property = lightdm_greeter_set_property;
object_class->get_property = lightdm_greeter_get_property;
object_class->finalize = lightdm_greeter_finalize;
{
Request *request = REQUEST (object);
- g_clear_object (&request->greeter);
g_clear_object (&request->cancellable);
g_free (request->dir);