diff options
author | Robert Ancell <robert.ancell@canonical.com> | 2016-11-17 12:34:16 +1300 |
---|---|---|
committer | Robert Ancell <robert.ancell@canonical.com> | 2016-11-17 12:34:16 +1300 |
commit | 0e0d6a5eefe42533c18e59ccbb1272b7fbb9d895 (patch) | |
tree | 0b3c594e8f1422bf0aa93799de83d926b4e131ff | |
parent | 8a30eeab987fcc40851d24bd726dd36d1f7f1518 (diff) | |
download | lightdm-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.c | 68 | ||||
-rw-r--r-- | src/greeter.c | 49 |
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: |