summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Ancell <robert.ancell@canonical.com>2016-11-17 12:34:16 +1300
committerRobert Ancell <robert.ancell@canonical.com>2016-11-17 12:34:16 +1300
commit0e0d6a5eefe42533c18e59ccbb1272b7fbb9d895 (patch)
tree0b3c594e8f1422bf0aa93799de83d926b4e131ff
parent8a30eeab987fcc40851d24bd726dd36d1f7f1518 (diff)
downloadlightdm-git-0e0d6a5eefe42533c18e59ccbb1272b7fbb9d895.tar.gz
Add an API version to the greeter protocol so we can easily add new data
-rw-r--r--liblightdm-gobject/greeter.c68
-rw-r--r--src/greeter.c49
2 files changed, 89 insertions, 28 deletions
diff --git a/liblightdm-gobject/greeter.c b/liblightdm-gobject/greeter.c
index 9a74a572..38eac052 100644
--- a/liblightdm-gobject/greeter.c
+++ b/liblightdm-gobject/greeter.c
@@ -117,6 +117,9 @@ static guint signals[LAST_SIGNAL] = { 0 };
typedef struct
{
+ /* API version the daemon is using */
+ guint32 api_version;
+
/* TRUE if the daemon can reuse this greeter */
gboolean resettable;
@@ -168,6 +171,7 @@ G_DEFINE_TYPE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
#define HEADER_SIZE 8
#define MAX_MESSAGE_LENGTH 1024
+#define API_VERSION 1
/* Messages from the greeter to the server */
typedef enum
@@ -193,6 +197,7 @@ typedef enum
SERVER_MESSAGE_SHARED_DIR_RESULT,
SERVER_MESSAGE_IDLE,
SERVER_MESSAGE_RESET,
+ SERVER_MESSAGE_CONNECTED_V2,
} ServerMessage;
/* Request sent to server */
@@ -582,30 +587,57 @@ send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length, GE
}
static void
-handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
+handle_connected (LightDMGreeter *greeter, gboolean v2, guint8 *message, gsize message_length, gsize *offset)
{
LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
- gchar *version;
- GString *hint_string;
+ GString *debug_string;
int timeout;
Request *request;
- version = read_string (message, message_length, offset);
- hint_string = g_string_new ("");
- while (*offset < message_length)
+ debug_string = g_string_new ("Connected");
+ if (v2)
{
- gchar *name, *value;
+ guint32 i, n_env;
+ gchar *version;
+
+ priv->api_version = read_int (message, message_length, offset);
+ g_string_append_printf (debug_string, " api=%u", priv->api_version);
+ version = read_string (message, message_length, offset);
+ g_string_append_printf (debug_string, " version=%s", version);
+ g_free (version);
+ n_env = read_int (message, message_length, offset);
+ for (i = 0; i < n_env; i++)
+ {
+ gchar *name, *value;
- name = read_string (message, message_length, offset);
- value = read_string (message, message_length, offset);
- g_hash_table_insert (priv->hints, name, value);
- g_string_append_printf (hint_string, " %s=%s", name, value);
+ name = read_string (message, message_length, offset);
+ value = read_string (message, message_length, offset);
+ g_hash_table_insert (priv->hints, name, value);
+ g_string_append_printf (debug_string, " %s=%s", name, value);
+ }
+ }
+ else
+ {
+ gchar *version;
+
+ priv->api_version = 0;
+ version = read_string (message, message_length, offset);
+ g_string_append_printf (debug_string, " version=%s", version);
+ g_free (version);
+ while (*offset < message_length)
+ {
+ gchar *name, *value;
+
+ name = read_string (message, message_length, offset);
+ value = read_string (message, message_length, offset);
+ g_hash_table_insert (priv->hints, name, value);
+ g_string_append_printf (debug_string, " %s=%s", name, value);
+ }
}
priv->connected = TRUE;
- g_debug ("Connected version=%s%s", version, hint_string->str);
- g_free (version);
- g_string_free (hint_string, TRUE);
+ g_debug ("%s", debug_string->str);
+ g_string_free (debug_string, TRUE);
/* Set timeout for default login */
timeout = lightdm_greeter_get_autologin_timeout_hint (greeter);
@@ -821,7 +853,7 @@ handle_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
switch (id)
{
case SERVER_MESSAGE_CONNECTED:
- handle_connected (greeter, message, message_length, &offset);
+ handle_connected (greeter, FALSE, message, message_length, &offset);
break;
case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
handle_prompt_authentication (greeter, message, message_length, &offset);
@@ -841,6 +873,9 @@ handle_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
case SERVER_MESSAGE_RESET:
handle_reset (greeter, message, message_length, &offset);
break;
+ case SERVER_MESSAGE_CONNECTED_V2:
+ handle_connected (greeter, TRUE, message, message_length, &offset);
+ break;
default:
g_warning ("Unknown message from server: %d", id);
break;
@@ -957,9 +992,10 @@ send_connect (LightDMGreeter *greeter, gboolean resettable, GError **error)
gsize offset = 0;
g_debug ("Connecting to display manager...");
- return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION) + int_length (), &offset, error) &&
+ return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION) + int_length () * 2, &offset, error) &&
write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset, error) &&
write_int (message, MAX_MESSAGE_LENGTH, resettable ? 1 : 0, &offset, error) &&
+ write_int (message, MAX_MESSAGE_LENGTH, API_VERSION, &offset, error) &&
send_message (greeter, message, offset, error);
}
diff --git a/src/greeter.c b/src/greeter.c
index 1ec5bd9c..0d07762f 100644
--- a/src/greeter.c
+++ b/src/greeter.c
@@ -60,6 +60,9 @@ struct GreeterPrivate
/* PAM session being constructed by the greeter */
Session *authentication_session;
+ /* API version the client can speak */
+ guint32 api_version;
+
/* TRUE if a the greeter can handle a reset; else we will just kill it instead */
gboolean resettable;
@@ -82,6 +85,8 @@ struct GreeterPrivate
G_DEFINE_TYPE (Greeter, greeter, G_TYPE_OBJECT);
+#define API_VERSION 1
+
/* Messages from the greeter to the server */
typedef enum
{
@@ -106,6 +111,7 @@ typedef enum
SERVER_MESSAGE_SHARED_DIR_RESULT,
SERVER_MESSAGE_IDLE,
SERVER_MESSAGE_RESET,
+ SERVER_MESSAGE_CONNECTED_V2,
} ServerMessage;
static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer data);
@@ -294,30 +300,46 @@ string_length (const gchar *value)
}
static void
-handle_connect (Greeter *greeter, const gchar *version, gboolean resettable)
+handle_connect (Greeter *greeter, const gchar *version, gboolean resettable, guint32 api_version)
{
guint8 message[MAX_MESSAGE_LENGTH];
gsize offset = 0;
- guint32 length;
+ guint32 env_length = 0;
GHashTableIter iter;
gpointer key, value;
- g_debug ("Greeter connected version=%s resettable=%s", version, resettable ? "true" : "false");
+ g_debug ("Greeter connected version=%s api=%u resettable=%s", version, api_version, resettable ? "true" : "false");
+ greeter->priv->api_version = api_version;
greeter->priv->resettable = resettable;
- length = string_length (VERSION);
g_hash_table_iter_init (&iter, greeter->priv->hints);
while (g_hash_table_iter_next (&iter, &key, &value))
- length += string_length (key) + string_length (value);
+ env_length += string_length (key) + string_length (value);
- write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_CONNECTED, length, &offset);
- write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
- g_hash_table_iter_init (&iter, greeter->priv->hints);
- while (g_hash_table_iter_next (&iter, &key, &value))
+ if (api_version == 0)
{
- write_string (message, MAX_MESSAGE_LENGTH, key, &offset);
- write_string (message, MAX_MESSAGE_LENGTH, value, &offset);
+ write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_CONNECTED, string_length (VERSION) + env_length, &offset);
+ write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
+ g_hash_table_iter_init (&iter, greeter->priv->hints);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ write_string (message, MAX_MESSAGE_LENGTH, key, &offset);
+ write_string (message, MAX_MESSAGE_LENGTH, value, &offset);
+ }
+ }
+ else
+ {
+ write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_CONNECTED_V2, string_length (VERSION) + int_length () * 2 + env_length, &offset);
+ write_int (message, MAX_MESSAGE_LENGTH, api_version <= API_VERSION ? api_version : API_VERSION, &offset);
+ write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
+ write_int (message, MAX_MESSAGE_LENGTH, g_hash_table_size (greeter->priv->hints), &offset);
+ g_hash_table_iter_init (&iter, greeter->priv->hints);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ write_string (message, MAX_MESSAGE_LENGTH, key, &offset);
+ write_string (message, MAX_MESSAGE_LENGTH, value, &offset);
+ }
}
write_message (greeter, message, offset);
@@ -830,6 +852,7 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
gchar *version, *username, *session_name, *language;
gchar **secrets;
gboolean resettable = FALSE;
+ guint32 api_version = 0;
GError *error = NULL;
if (condition == G_IO_HUP)
@@ -894,7 +917,9 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
version = read_string (greeter, &offset);
if (offset < length)
resettable = read_int (greeter, &offset) != 0;
- handle_connect (greeter, version, resettable);
+ if (offset < length)
+ api_version = read_int (greeter, &offset);
+ handle_connect (greeter, version, resettable, api_version);
g_free (version);
break;
case GREETER_MESSAGE_AUTHENTICATE: