From 3b7868b33033ed8dde17bb6b88ef461f4ecbb93f Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Fri, 18 May 2012 17:23:18 -0400 Subject: Make it possible for JS code to change details For example, to set the authentication message, a JS function can simply do details["polkit.message"] = "Hey dude, XYZ, I need your password"; This can also be used to pass data back to the mechanism. To make this work properly, we also introduce a slight change: the a{ss} passed back to the mechanism (part of the AuthorizationResult structure) will be initialized with the a{ss} the app passed itself in the CheckAuthorization() call. Signed-off-by: David Zeuthen --- .../polkitbackendinteractiveauthority.c | 48 ++++++++--------- .../polkitbackendinteractiveauthority.h | 6 +-- src/polkitbackend/polkitbackendjsauthority.c | 60 +++++++++++++++++++--- src/polkitbackend/polkitbackendlocalauthority.c | 12 ++--- .../polkitbackendlocalauthorizationstore.c | 12 ++--- .../polkitbackendlocalauthorizationstore.h | 3 +- 6 files changed, 87 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c index 5f6eea5..171e686 100644 --- a/src/polkitbackend/polkitbackendinteractiveauthority.c +++ b/src/polkitbackend/polkitbackendinteractiveauthority.c @@ -80,6 +80,7 @@ typedef void (*AuthenticationAgentCallback) (AuthenticationAgent *agent, PolkitSubject *caller, PolkitBackendInteractiveAuthority *authority, const gchar *action_id, + PolkitDetails *details, PolkitImplicitAuthorization implicit_authorization, gboolean authentication_success, gboolean was_dismissed, @@ -595,6 +596,7 @@ check_authorization_challenge_cb (AuthenticationAgent *agent, PolkitSubject *caller, PolkitBackendInteractiveAuthority *authority, const gchar *action_id, + PolkitDetails *details, PolkitImplicitAuthorization implicit_authorization, gboolean authentication_success, gboolean was_dismissed, @@ -610,7 +612,6 @@ check_authorization_challenge_cb (AuthenticationAgent *agent, gchar *authenticated_identity_str; gchar *subject_cmdline; gboolean is_temp; - PolkitDetails *details; priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority); @@ -637,7 +638,6 @@ check_authorization_challenge_cb (AuthenticationAgent *agent, was_dismissed, authentication_success); - details = polkit_details_new (); if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED_RETAINED || implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED_RETAINED) polkit_details_insert (details, "polkit.retains_authorization_after_challenge", "true"); @@ -715,7 +715,6 @@ check_authorization_challenge_cb (AuthenticationAgent *agent, /* log_result (authority, action_id, subject, caller, result); */ - g_object_unref (details); g_simple_async_result_set_op_res_gpointer (simple, result, g_object_unref); @@ -1047,7 +1046,6 @@ check_authorization_sync (PolkitBackendAuthority *authority, gboolean session_is_active; PolkitImplicitAuthorization implicit_authorization; const gchar *tmp_authz_id; - PolkitDetails *result_details; GList *actions; GList *l; @@ -1061,7 +1059,6 @@ check_authorization_sync (PolkitBackendAuthority *authority, groups_of_user = NULL; subject_str = NULL; session_for_subject = NULL; - result_details = NULL; session_is_local = FALSE; session_is_active = FALSE; @@ -1130,8 +1127,6 @@ check_authorization_sync (PolkitBackendAuthority *authority, implicit_authorization = polkit_action_description_get_implicit_any (action_desc); } - result_details = polkit_details_new (); - /* allow subclasses to rewrite implicit_authorization */ implicit_authorization = polkit_backend_interactive_authority_check_authorization_sync (interactive_authority, caller, @@ -1141,16 +1136,14 @@ check_authorization_sync (PolkitBackendAuthority *authority, session_is_active, action_id, details, - implicit_authorization, - result_details); - + implicit_authorization); /* first see if there's an implicit authorization for subject available */ if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED) { g_debug (" is authorized (has implicit authorization local=%d active=%d)", session_is_local, session_is_active); - result = polkit_authorization_result_new (TRUE, FALSE, result_details); + result = polkit_authorization_result_new (TRUE, FALSE, details); goto out; } @@ -1162,8 +1155,8 @@ check_authorization_sync (PolkitBackendAuthority *authority, { g_debug (" is authorized (has temporary authorization)"); - polkit_details_insert (result_details, "polkit.temporary_authorization_id", tmp_authz_id); - result = polkit_authorization_result_new (TRUE, FALSE, result_details); + polkit_details_insert (details, "polkit.temporary_authorization_id", tmp_authz_id); + result = polkit_authorization_result_new (TRUE, FALSE, details); goto out; } @@ -1210,7 +1203,6 @@ check_authorization_sync (PolkitBackendAuthority *authority, g_debug (" is authorized (implied by %s)", imply_action_id); result = implied_result; /* cleanup */ - g_object_unref (result_details); g_strfreev (tokens); goto out; } @@ -1230,10 +1222,10 @@ check_authorization_sync (PolkitBackendAuthority *authority, if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED_RETAINED || implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED_RETAINED) { - polkit_details_insert (result_details, "polkit.retains_authorization_after_challenge", "1"); + polkit_details_insert (details, "polkit.retains_authorization_after_challenge", "1"); } - result = polkit_authorization_result_new (FALSE, TRUE, result_details); + result = polkit_authorization_result_new (FALSE, TRUE, details); /* return implicit_authorization so the caller can use an authentication agent if applicable */ if (out_implicit_authorization != NULL) @@ -1244,7 +1236,7 @@ check_authorization_sync (PolkitBackendAuthority *authority, } else { - result = polkit_authorization_result_new (FALSE, FALSE, result_details); + result = polkit_authorization_result_new (FALSE, FALSE, details); g_debug (" not authorized"); } out: @@ -1265,9 +1257,6 @@ check_authorization_sync (PolkitBackendAuthority *authority, if (action_desc != NULL) g_object_unref (action_desc); - if (result_details != NULL) - g_object_unref (result_details); - g_debug (" "); return result; @@ -1332,12 +1321,10 @@ polkit_backend_interactive_authority_get_admin_identities (PolkitBackendInteract * @action_id: The action we are checking an authorization for. * @details: Details about the action. * @implicit: A #PolkitImplicitAuthorization value computed from the policy file and @subject. - * @out_details: A #PolkitDetails object that will be return to @caller. * * Checks whether @subject is authorized to perform the action - * specified by @action_id and @details. The implementation may - * append key/value pairs to @out_details to return extra information - * to @caller. + * specified by @action_id and @details. The implementation may append + * key/value pairs to @details to return extra information to @caller. * * The default implementation of this method simply returns @implicit. * @@ -1353,8 +1340,7 @@ polkit_backend_interactive_authority_check_authorization_sync (PolkitBackendInte gboolean subject_is_active, const gchar *action_id, PolkitDetails *details, - PolkitImplicitAuthorization implicit, - PolkitDetails *out_details) + PolkitImplicitAuthorization implicit) { PolkitBackendInteractiveAuthorityClass *klass; PolkitImplicitAuthorization ret; @@ -1375,8 +1361,7 @@ polkit_backend_interactive_authority_check_authorization_sync (PolkitBackendInte subject_is_active, action_id, details, - implicit, - out_details); + implicit); } return ret; @@ -1402,6 +1387,8 @@ struct AuthenticationSession gchar *action_id; + PolkitDetails *details; + gchar *initiated_by_system_bus_unique_name; PolkitImplicitAuthorization implicit_authorization; @@ -1436,6 +1423,7 @@ authentication_session_new (AuthenticationAgent *agent, PolkitBackendInteractiveAuthority *authority, GList *identities, const gchar *action_id, + PolkitDetails *details, const gchar *initiated_by_system_bus_unique_name, PolkitImplicitAuthorization implicit_authorization, GCancellable *cancellable, @@ -1454,6 +1442,7 @@ authentication_session_new (AuthenticationAgent *agent, session->identities = g_list_copy (identities); g_list_foreach (session->identities, (GFunc) g_object_ref, NULL); session->action_id = g_strdup (action_id); + session->details = g_object_ref (details); session->initiated_by_system_bus_unique_name = g_strdup (initiated_by_system_bus_unique_name); session->implicit_authorization = implicit_authorization; session->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL; @@ -1483,6 +1472,7 @@ authentication_session_free (AuthenticationSession *session) g_object_unref (session->caller); g_object_unref (session->authority); g_free (session->action_id); + g_object_unref (session->details); g_free (session->initiated_by_system_bus_unique_name); if (session->cancellable_signal_handler_id > 0) g_signal_handler_disconnect (session->cancellable, session->cancellable_signal_handler_id); @@ -1832,6 +1822,7 @@ authentication_agent_begin_cb (GDBusProxy *proxy, session->caller, session->authority, session->action_id, + session->details, session->implicit_authorization, gained_authorization, was_dismissed, @@ -2228,6 +2219,7 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent, authority, identities, action_id, + details, polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)), implicit_authorization, cancellable, diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.h b/src/polkitbackend/polkitbackendinteractiveauthority.h index 408c3e4..9820dac 100644 --- a/src/polkitbackend/polkitbackendinteractiveauthority.h +++ b/src/polkitbackend/polkitbackendinteractiveauthority.h @@ -83,8 +83,7 @@ struct _PolkitBackendInteractiveAuthorityClass gboolean subject_is_active, const gchar *action_id, PolkitDetails *details, - PolkitImplicitAuthorization implicit, - PolkitDetails *out_details); + PolkitImplicitAuthorization implicit); /*< private >*/ /* Padding for future expansion */ @@ -139,8 +138,7 @@ PolkitImplicitAuthorization polkit_backend_interactive_authority_check_authoriza gboolean subject_is_active, const gchar *action_id, PolkitDetails *details, - PolkitImplicitAuthorization implicit, - PolkitDetails *out_details); + PolkitImplicitAuthorization implicit); G_END_DECLS diff --git a/src/polkitbackend/polkitbackendjsauthority.c b/src/polkitbackend/polkitbackendjsauthority.c index b3669d5..81cccd0 100644 --- a/src/polkitbackend/polkitbackendjsauthority.c +++ b/src/polkitbackend/polkitbackendjsauthority.c @@ -100,8 +100,7 @@ static PolkitImplicitAuthorization polkit_backend_js_authority_check_authorizati gboolean subject_is_active, const gchar *action_id, PolkitDetails *details, - PolkitImplicitAuthorization implicit, - PolkitDetails *out_details); + PolkitImplicitAuthorization implicit); G_DEFINE_TYPE_WITH_CODE (PolkitBackendJsAuthority, polkit_backend_js_authority, @@ -193,7 +192,7 @@ load_scripts (PolkitBackendJsAuthority *authority) if (dir == NULL) { polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), - "Error opening rules directory: %s (%s, %d)\n", + "Error opening rules directory: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_clear_error (&error); goto out; @@ -858,8 +857,7 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu gboolean subject_is_active, const gchar *action_id, PolkitDetails *details, - PolkitImplicitAuthorization implicit, - PolkitDetails *out_details) + PolkitImplicitAuthorization implicit) { PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority); PolkitImplicitAuthorization ret = implicit; @@ -871,6 +869,9 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu const jschar *ret_utf16; gchar *ret_str = NULL; gboolean good = FALSE; + JSIdArray *ids; + JSObject *details_obj; + gint n; action_id_jstr = JS_NewStringCopyZ (authority->priv->cx, action_id); argv[0] = STRING_TO_JSVAL (action_id_jstr); @@ -931,11 +932,58 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu if (!polkit_implicit_authorization_from_string (ret_str, &ret)) { polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), - "Returned result `%s' is not valid\n", + "Returned result `%s' is not valid", ret_str); goto out; } + + /* the JS code may have modifed @details - update PolkitDetails + * object accordingly + */ + details_obj = JSVAL_TO_OBJECT (argv[2]); + ids = JS_Enumerate (authority->priv->cx, details_obj); + if (ids == NULL) + { + polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), + "Failed to enumerate properties of Details object"); + goto out; + } + for (n = 0; n < ids->length; n++) + { + jsval id_val; + jsval value_val; + char *id_s = NULL; + char *value_s = NULL; + + if (!JS_IdToValue (authority->priv->cx, ids->vector[n], &id_val)) + { + g_warning ("Error getting string for property id %d", n); + goto cont; + } + id_s = JS_EncodeString (authority->priv->cx, JSVAL_TO_STRING (id_val)); + + if (!JS_GetPropertyById (authority->priv->cx, details_obj, ids->vector[n], &value_val)) + { + g_warning ("Error getting value string for property value %s", id_s); + goto cont; + } + + /* skip e.g. functions */ + if (!JSVAL_IS_STRING (value_val) && !JSVAL_IS_NULL (value_val)) + goto cont; + + value_s = JS_EncodeString (authority->priv->cx, JSVAL_TO_STRING (value_val)); + + polkit_details_insert (details, id_s, value_s); + cont: + if (id_s != NULL) + JS_free (authority->priv->cx, id_s); + if (value_s != NULL) + JS_free (authority->priv->cx, value_s); + } + JS_DestroyIdArray (authority->priv->cx, ids); + good = TRUE; out: diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c index b53eda3..2e5e8fe 100644 --- a/src/polkitbackend/polkitbackendlocalauthority.c +++ b/src/polkitbackend/polkitbackendlocalauthority.c @@ -100,8 +100,7 @@ static PolkitImplicitAuthorization polkit_backend_local_authority_check_authoriz gboolean subject_is_active, const gchar *action_id, PolkitDetails *details, - PolkitImplicitAuthorization implicit, - PolkitDetails *out_details); + PolkitImplicitAuthorization implicit); G_DEFINE_TYPE_WITH_CODE (PolkitBackendLocalAuthority, polkit_backend_local_authority, @@ -543,8 +542,7 @@ polkit_backend_local_authority_check_authorization_sync (PolkitBackendInteractiv gboolean subject_is_active, const gchar *action_id, PolkitDetails *details, - PolkitImplicitAuthorization implicit, - PolkitDetails *out_details) + PolkitImplicitAuthorization implicit) { PolkitBackendLocalAuthority *local_authority; PolkitBackendLocalAuthorityPrivate *priv; @@ -583,8 +581,7 @@ polkit_backend_local_authority_check_authorization_sync (PolkitBackendInteractiv details, &ret_any, &ret_inactive, - &ret_active, - out_details)) + &ret_active)) { if (subject_is_local && subject_is_active) { @@ -618,8 +615,7 @@ polkit_backend_local_authority_check_authorization_sync (PolkitBackendInteractiv details, &ret_any, &ret_inactive, - &ret_active, - out_details)) + &ret_active)) { if (subject_is_local && subject_is_active) { diff --git a/src/polkitbackend/polkitbackendlocalauthorizationstore.c b/src/polkitbackend/polkitbackendlocalauthorizationstore.c index 2ddfe75..f40a943 100644 --- a/src/polkitbackend/polkitbackendlocalauthorizationstore.c +++ b/src/polkitbackend/polkitbackendlocalauthorizationstore.c @@ -669,9 +669,10 @@ polkit_backend_local_authorization_store_ensure (PolkitBackendLocalAuthorization * @out_result_any: Return location for the result for any subjects if the look up matched. * @out_result_inactive: Return location for the result for subjects in local inactive sessions if the look up matched. * @out_result_active: Return location for the result for subjects in local active sessions if the look up matched. - * @out_details: %NULL or a #PolkitDetails object to append key/value pairs to on a positive match. * - * Checks if an authorization entry from @store matches @identity, @action_id and @details. + * Checks if an authorization entry from @store matches @identity, + * @action_id and @details. May append information to @details if + * found. * * Returns: %TRUE if @store has an authorization entry that matches * @identity, @action_id and @details. Otherwise %FALSE. @@ -683,8 +684,7 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization PolkitDetails *details, PolkitImplicitAuthorization *out_result_any, PolkitImplicitAuthorization *out_result_inactive, - PolkitImplicitAuthorization *out_result_active, - PolkitDetails *out_details) + PolkitImplicitAuthorization *out_result_active) { GList *l, *ll; gboolean ret; @@ -749,7 +749,7 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization *out_result_active = authorization->result_active; ret = TRUE; - if (out_details != NULL && authorization->return_value != NULL) + if (details != NULL && authorization->return_value != NULL) { GHashTableIter iter; const gchar *key; @@ -758,7 +758,7 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization g_hash_table_iter_init (&iter, authorization->return_value); while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) { - polkit_details_insert (out_details, key, value); + polkit_details_insert (details, key, value); } } diff --git a/src/polkitbackend/polkitbackendlocalauthorizationstore.h b/src/polkitbackend/polkitbackendlocalauthorizationstore.h index c15d9a6..4f198e9 100644 --- a/src/polkitbackend/polkitbackendlocalauthorizationstore.h +++ b/src/polkitbackend/polkitbackendlocalauthorizationstore.h @@ -78,8 +78,7 @@ gboolean polkit_backend_local_authorization_store_lookup (PolkitBackendLocalA PolkitDetails *details, PolkitImplicitAuthorization *out_result_any, PolkitImplicitAuthorization *out_result_inactive, - PolkitImplicitAuthorization *out_result_active, - PolkitDetails *out_details); + PolkitImplicitAuthorization *out_result_active); G_END_DECLS -- cgit v1.2.3