diff options
Diffstat (limited to 'src/polkitbackend/polkitbackendinteractiveauthority.c')
-rw-r--r-- | src/polkitbackend/polkitbackendinteractiveauthority.c | 99 |
1 files changed, 80 insertions, 19 deletions
diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c index 3f339e9..15adc6a 100644 --- a/src/polkitbackend/polkitbackendinteractiveauthority.c +++ b/src/polkitbackend/polkitbackendinteractiveauthority.c @@ -214,6 +214,8 @@ typedef struct GDBusConnection *system_bus_connection; guint name_owner_changed_signal_id; + + guint64 agent_serial; } PolkitBackendInteractiveAuthorityPrivate; /* ---------------------------------------------------------------------------------------------------- */ @@ -439,11 +441,15 @@ struct AuthenticationAgent volatile gint ref_count; PolkitSubject *scope; + guint64 serial; gchar *locale; GVariant *registration_options; gchar *object_path; gchar *unique_system_bus_name; + GRand *cookie_pool; + gchar *cookie_prefix; + guint64 cookie_serial; GDBusProxy *proxy; @@ -1427,9 +1433,54 @@ authentication_session_cancelled_cb (GCancellable *cancellable, authentication_session_cancel (session); } +/* We're not calling this a UUID, but it's basically + * the same thing, just not formatted that way because: + * + * - I'm too lazy to do it + * - If we did, people might think it was actually + * generated from /dev/random, which we're not doing + * because this value doesn't actually need to be + * globally unique. + */ +static void +append_rand_u128_str (GString *buf, + GRand *pool) +{ + g_string_append_printf (buf, "%08x%08x%08x%08x", + g_rand_int (pool), + g_rand_int (pool), + g_rand_int (pool), + g_rand_int (pool)); +} + +/* A value that should be unique to the (AuthenticationAgent, AuthenticationSession) + * pair, and not guessable by other agents. + * + * <agent serial> - <agent uuid> - <session serial> - <session uuid> + * + * See http://lists.freedesktop.org/archives/polkit-devel/2015-June/000425.html + * + */ +static gchar * +authentication_agent_generate_cookie (AuthenticationAgent *agent) +{ + GString *buf = g_string_new (""); + + g_string_append (buf, agent->cookie_prefix); + + g_string_append_c (buf, '-'); + agent->cookie_serial++; + g_string_append_printf (buf, "%" G_GUINT64_FORMAT, + agent->cookie_serial); + g_string_append_c (buf, '-'); + append_rand_u128_str (buf, agent->cookie_pool); + + return g_string_free (buf, FALSE); +} + + static AuthenticationSession * authentication_session_new (AuthenticationAgent *agent, - const gchar *cookie, PolkitSubject *subject, PolkitIdentity *user_of_subject, PolkitSubject *caller, @@ -1447,7 +1498,7 @@ authentication_session_new (AuthenticationAgent *agent, session = g_new0 (AuthenticationSession, 1); session->agent = authentication_agent_ref (agent); - session->cookie = g_strdup (cookie); + session->cookie = authentication_agent_generate_cookie (agent); session->subject = g_object_ref (subject); session->user_of_subject = g_object_ref (user_of_subject); session->caller = g_object_ref (caller); @@ -1496,16 +1547,6 @@ authentication_session_free (AuthenticationSession *session) g_free (session); } -static gchar * -authentication_agent_new_cookie (AuthenticationAgent *agent) -{ - static gint counter = 0; - - /* TODO: use a more random-looking cookie */ - - return g_strdup_printf ("cookie%d", counter++); -} - static PolkitSubject * authentication_agent_get_scope (AuthenticationAgent *agent) { @@ -1553,12 +1594,15 @@ authentication_agent_unref (AuthenticationAgent *agent) g_free (agent->unique_system_bus_name); if (agent->registration_options != NULL) g_variant_unref (agent->registration_options); + g_rand_free (agent->cookie_pool); + g_free (agent->cookie_prefix); g_free (agent); } } static AuthenticationAgent * -authentication_agent_new (PolkitSubject *scope, +authentication_agent_new (guint64 serial, + PolkitSubject *scope, const gchar *unique_system_bus_name, const gchar *locale, const gchar *object_path, @@ -1592,6 +1636,7 @@ authentication_agent_new (PolkitSubject *scope, agent = g_new0 (AuthenticationAgent, 1); agent->ref_count = 1; + agent->serial = serial; agent->scope = g_object_ref (scope); agent->object_path = g_strdup (object_path); agent->unique_system_bus_name = g_strdup (unique_system_bus_name); @@ -1599,6 +1644,25 @@ authentication_agent_new (PolkitSubject *scope, agent->registration_options = registration_options != NULL ? g_variant_ref (registration_options) : NULL; agent->proxy = proxy; + { + GString *cookie_prefix = g_string_new (""); + GRand *agent_private_rand = g_rand_new (); + + g_string_append_printf (cookie_prefix, "%" G_GUINT64_FORMAT "-", agent->serial); + + /* Use a uniquely seeded PRNG to get a prefix cookie for this agent, + * whose sequence will not correlate with the per-authentication session + * cookies. + */ + append_rand_u128_str (cookie_prefix, agent_private_rand); + g_rand_free (agent_private_rand); + + agent->cookie_prefix = g_string_free (cookie_prefix, FALSE); + + /* And a newly seeded pool for per-session cookies */ + agent->cookie_pool = g_rand_new (); + } + return agent; } @@ -2193,7 +2257,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent, { PolkitBackendInteractiveAuthorityPrivate *priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority); AuthenticationSession *session; - gchar *cookie; GList *l; GList *identities; gchar *localized_message; @@ -2215,8 +2278,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent, &localized_icon_name, &localized_details); - cookie = authentication_agent_new_cookie (agent); - identities = NULL; /* select admin user if required by the implicit authorization */ @@ -2279,7 +2340,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent, user_identities = g_list_prepend (NULL, polkit_unix_user_new (0)); session = authentication_session_new (agent, - cookie, subject, user_of_subject, caller, @@ -2335,7 +2395,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent, g_list_free_full (user_identities, g_object_unref); g_list_foreach (identities, (GFunc) g_object_unref, NULL); g_list_free (identities); - g_free (cookie); g_free (localized_message); g_free (localized_icon_name); @@ -2482,7 +2541,9 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken goto out; } - agent = authentication_agent_new (subject, + priv->agent_serial++; + agent = authentication_agent_new (priv->agent_serial, + subject, polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)), locale, object_path, |