greeter.c revision 46633cdb66707c52c31cadcfbc4ce38c68f47d2e
/*
* Copyright (C) 2010 Robert Ancell.
* Author: Robert Ancell <robert.ancell@canonical.com>
*
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2 or version 3 of the License.
* See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <security/pam_appl.h>
enum {
};
enum {
};
typedef struct
{
#define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeterPrivate)
#define HEADER_SIZE 8
#define MAX_MESSAGE_LENGTH 1024
/* Messages from the greeter to the server */
typedef enum
{
/* Messages from the server to the greeter */
typedef enum
{
/**
* lightdm_greeter_new:
*
* Create a new greeter.
*
* Return value: the new #LightDMGreeter
**/
{
}
static gboolean
{
priv->autologin_timeout = 0;
return FALSE;
}
static guint32
int_length ()
{
return 4;
}
static void
{
return;
*offset += 4;
}
static void
{
if (value)
return;
}
static guint32
{
{
return 0;
}
*offset += int_length ();
return value;
}
static gchar *
{
{
return g_strdup ("");
}
return value;
}
static guint32
{
if (value)
else
return int_length ();
}
static void
{
}
static guint32
{
}
static void
{
/* Double check that we're sending well-formed messages. If we say we're
sending more than we do, we end up DOS'ing lightdm as it waits for the
rest. If we say we're sending less than we do, we confuse the heck out
of lightdm, as it starts reading headers from the middle of our
messages. */
if (stated_length != message_length)
{
g_warning ("Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu", stated_length, message_length);
return;
}
status = g_io_channel_write_chars (priv->to_server_channel, (gchar *) message, message_length, NULL, &error);
if (error)
g_clear_error (&error);
if (status == G_IO_STATUS_NORMAL)
}
static void
{
int timeout;
while (*offset < message_length)
{
}
/* Set timeout for default login */
if (timeout)
{
}
}
static void
handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
{
{
return;
}
{
g_debug ("Ignoring prompt authentication as waiting for it to cancel");
return;
}
/* Update username */
{
}
priv->n_responses_waiting = 0;
for (i = 0; i < n_messages; i++)
{
int style;
// FIXME: Should stop on prompts?
switch (style)
{
case PAM_PROMPT_ECHO_OFF:
break;
case PAM_PROMPT_ECHO_ON:
break;
case PAM_ERROR_MSG:
break;
case PAM_TEXT_INFO:
break;
}
}
}
static void
handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
{
{
return;
}
/* Update username */
{
}
}
static guint8 *
{
/* Read the header, or the whole message if we already have that */
do
{
&n_read,
&error);
if (error)
g_clear_error (&error);
if (status != G_IO_STATUS_NORMAL)
break;
/* Stop if haven't got all the data we want */
return FALSE;
/* If have header, rerun for content */
{
if (n_to_read > 0)
{
}
}
return buffer;
}
static gboolean
{
if (!message)
return TRUE;
offset = 0;
switch (id)
{
break;
break;
default:
break;
}
return TRUE;
}
/**
* lightdm_greeter_connect_sync:
* @greeter: The greeter to connect
* @error: return location for a #GError, or %NULL
*
* Connects the greeter to the display manager. Will block until connected.
*
* Return value: #TRUE if successfully connected
**/
{
if (!fd)
{
g_warning ("No LIGHTDM_TO_SERVER_FD environment variable");
return FALSE;
}
if (!fd)
{
g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable");
return FALSE;
}
g_debug ("Connecting to display manager...");
write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION), &offset);
if (!response)
return FALSE;
offset = 0;
if (id == SERVER_MESSAGE_CONNECTED)
if (id != SERVER_MESSAGE_CONNECTED)
{
return FALSE;
}
return TRUE;
}
/**
* lightdm_greeter_get_hint:
* @greeter: A #LightDMGreeter
* @name: The hint name to query.
*
* Get a hint.
*
* Return value: The value for this hint or #NULL if not set.
**/
const gchar *
{
}
/**
* lightdm_greeter_get_default_session_hint:
* @greeter: A #LightDMGreeter
*
* Get the default session to use.
*
* Return value: The session name
**/
const gchar *
{
}
/**
* lightdm_greeter_get_hide_users_hint:
* @greeter: A #LightDMGreeter
*
* Check if user accounts should be shown. If this is TRUE then the list of
* accounts should be taken from #LightDMUserList and displayed in the greeter
* for the user to choose from. Note that this list can be empty and it is
* recommended you show a method for the user to enter a username manually.
*
* If this option is shown the greeter should only allow these users to be
* chosen for login unless the manual login hint is set.
*
* Return value: #TRUE if the available users should not be shown.
*/
{
}
/**
* lightdm_greeter_get_show_manual_login_hint:
* @greeter: A #LightDMGreeter
*
* Check if a manual login option should be shown. If set the GUI
* should provide a way for a username to be entered manually.
* Without this hint a greeter which is showing a user list can
* limit logins to only those users.
*
* Return value: #TRUE if a manual login option should be shown.
*/
{
}
/**
* lightdm_greeter_get_show_remote_login_hint:
* @greeter: A #LightDMGreeter
*
* Check if a remote login option should be shown. If set the GUI
* should provide a way for a user to log into a remote desktop server.
*
* Return value: #TRUE if a remote login option should be shown.
*/
{
}
/**
* lightdm_greeter_get_lock_hint:
* @greeter: A #LightDMGreeter
*
* Check if the greeter is acting as a lock screen.
*
* Return value: #TRUE if the greeter was triggered by locking the seat.
*/
{
}
/**
* lightdm_greeter_get_has_guest_account_hint:
* @greeter: A #LightDMGreeter
*
* Check if guest sessions are supported.
*
* Return value: #TRUE if guest sessions are supported.
*/
{
}
/**
* lightdm_greeter_get_select_user_hint:
* @greeter: A #LightDMGreeter
*
* Get the user to select by default.
*
* Return value: A username
*/
const gchar *
{
}
/**
* lightdm_greeter_get_select_guest_hint:
* @greeter: A #LightDMGreeter
*
* Check if the guest account should be selected by default.
*
* Return value: #TRUE if the guest account should be selected by default.
*/
{
}
/**
* lightdm_greeter_get_autologin_user_hint:
* @greeter: A #LightDMGreeter
*
* Get the user account to automatically logg into when the timer expires.
*
* Return value: The user account to automatically log into.
*/
const gchar *
{
}
/**
* lightdm_greeter_get_autologin_guest_hint:
* @greeter: A #LightDMGreeter
*
* Check if the guest account should be automatically logged into when the timer expires.
*
* Return value: #TRUE if the guest account should be automatically logged into.
*/
{
}
/**
* lightdm_greeter_get_autologin_timeout_hint:
* @greeter: A #LightDMGreeter
*
* Get the number of seconds to wait before automaitcally logging in.
*
* Return value: The number of seconds to wait before automatically logging in or 0 for no timeout.
*/
{
if (value)
if (timeout < 0)
timeout = 0;
return timeout;
}
/**
* lightdm_greeter_cancel_autologin:
* @greeter: A #LightDMGreeter
*
* Cancel the automatic login.
*/
void
{
if (priv->autologin_timeout)
priv->autologin_timeout = 0;
}
/**
* lightdm_greeter_authenticate:
* @greeter: A #LightDMGreeter
* @username: (allow-none): A username or #NULL to prompt for a username.
*
* Starts the authentication procedure for a user.
**/
void
{
{
}
write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset);
}
/**
* lightdm_greeter_authenticate_as_guest:
* @greeter: A #LightDMGreeter
*
* Starts the authentication procedure for the guest user.
**/
void
{
g_debug ("Starting authentication for guest account...");
write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset);
}
/**
* lightdm_greeter_authenticate_autologin:
* @greeter: A #LightDMGreeter
*
* Starts the authentication procedure for the automatic login user.
**/
void
{
else if (user)
}
/**
* 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)
{
if (username)
else
write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_REMOTE, int_length () + string_length (session) + string_length (username), &offset);
}
/**
* lightdm_greeter_respond:
* @greeter: A #LightDMGreeter
* @response: Response to a prompt
*
* Provide response to a prompt. May be one in a series.
**/
void
{
if (priv->n_responses_waiting == 0)
{
g_debug ("Providing response to display manager");
msg_length = int_length ();
{
}
write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, msg_length, &offset);
{
}
}
}
/**
* lightdm_greeter_cancel_authentication:
* @greeter: A #LightDMGreeter
*
* Cancel the current user authentication.
**/
void
{
}
/**
* lightdm_greeter_get_in_authentication:
* @greeter: A #LightDMGreeter
*
* Checks if the greeter is in the process of authenticating.
*
* Return value: #TRUE if the greeter is authenticating a user.
**/
{
}
/**
* lightdm_greeter_get_is_authenticated:
* @greeter: A #LightDMGreeter
*
* Checks if the greeter has successfully authenticated.
*
* Return value: #TRUE if the greeter is authenticated for login.
**/
{
}
/**
* lightdm_greeter_get_authentication_user:
* @greeter: A #LightDMGreeter
*
* Get the user that is being authenticated.
*
* Return value: The username of the authentication user being authenticated or #NULL if no authentication in progress.
*/
const gchar *
{
}
/**
* lightdm_greeter_set_language:
* @greeter: A #LightDMGreeter
* @language: The language to use for this user.
*
* Set the language for the currently authenticated user.
**/
void
{
write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset);
}
/**
* lightdm_greeter_start_session_sync:
* @greeter: A #LightDMGreeter
* @session: (allow-none): The session to log into or #NULL to use the default.
* @error: return location for a #GError, or %NULL
*
* Start a session for the authenticated user.
*
* Return value: TRUE if the session was started.
**/
{
if (session)
else
g_debug ("Starting default session");
write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
if (!response)
return FALSE;
offset = 0;
if (id == SERVER_MESSAGE_SESSION_RESULT)
else
return return_code == 0;
}
static void
{
}
static void
{
}
static void
{
switch (prop_id) {
break;
case PROP_HIDE_USERS_HINT:
break;
break;
break;
case PROP_LOCK_HINT:
break;
break;
case PROP_SELECT_USER_HINT:
break;
case PROP_SELECT_GUEST_HINT:
break;
case PROP_AUTOLOGIN_USER_HINT:
break;
break;
break;
case PROP_AUTHENTICATION_USER:
break;
case PROP_IN_AUTHENTICATION:
break;
case PROP_IS_AUTHENTICATED:
break;
default:
break;
}
}
static void
const GValue *param_values,
{
register GMarshalFunc_VOID__STRING_INT callback;
if (G_CCLOSURE_SWAP_DATA (closure))
{
}
else
{
}
data2);
}
static void
{
if (priv->to_server_channel)
if (priv->from_server_channel)
}
static void
{
g_param_spec_string ("default-session-hint",
"default-session-hint",
"Default session hint",
NULL,
g_param_spec_boolean ("hide-users-hint",
"hide-users-hint",
"Hide users hint",
g_param_spec_boolean ("show-manual-login-hint",
"show-manual-login-hint",
"Show manual login hint",
g_param_spec_boolean ("show-remote-login-hint",
"show-remote-login-hint",
"Show remote login hint",
g_param_spec_boolean ("lock-hint",
"lock-hint",
"Lock hint",
g_param_spec_boolean ("has-guest-account-hint",
"has-guest-account-hint",
"Has guest account hint",
g_param_spec_string ("select-user-hint",
"select-user-hint",
"Select user hint",
NULL,
g_param_spec_boolean ("select-guest-hint",
"select-guest-hint",
"Select guest account hint",
g_param_spec_string ("autologin-user-hint",
"autologin-user-hint",
"Autologin user hint",
NULL,
g_param_spec_boolean ("autologin-guest-hint",
"autologin-guest-hint",
"Autologin guest account hint",
g_param_spec_int ("autologin-timeout-hint",
"autologin-timeout-hint",
"Autologin timeout hint",
0, G_MAXINT, 0,
g_param_spec_string ("authentication-user",
"authentication-user",
"The user being authenticated",
NULL,
g_param_spec_boolean ("in-authentication",
"in-authentication",
"TRUE if a user is being authenticated",
g_param_spec_boolean ("is-authenticated",
"is-authenticated",
"TRUE if the selected user is authenticated",
/**
* LightDMGreeter::show-prompt:
* @greeter: A #LightDMGreeter
* @text: Prompt text
* @type: Prompt type
*
* The ::show-prompt signal gets emitted when the greeter should show a
* prompt to the user. The given text should be displayed and an input
* field for the user to provide a response.
*
* Call lightdm_greeter_respond() with the resultant input or
* lightdm_greeter_cancel_authentication() to abort the authentication.
**/
g_signal_new ("show-prompt",
/**
* LightDMGreeter::show-message:
* @greeter: A #LightDMGreeter
* @text: Message text
* @type: Message type
*
* The ::show-message signal gets emitted when the greeter
* should show a message to the user.
**/
g_signal_new ("show-message",
/**
* LightDMGreeter::authentication-complete:
* @greeter: A #LightDMGreeter
*
* The ::authentication-complete signal gets emitted when the greeter
* has completed authentication.
*
* Call lightdm_greeter_get_is_authenticated() to check if the authentication
* was successful.
**/
g_signal_new ("authentication-complete",
G_TYPE_NONE, 0);
/**
* LightDMGreeter::autologin-timer-expired:
* @greeter: A #LightDMGreeter
*
* The ::timed-login signal gets emitted when the automatic login timer has expired.
* The application should then call lightdm_greeter_login().
**/
g_signal_new ("autologin-timer-expired",
G_TYPE_NONE, 0);
}