diff options
-rw-r--r-- | docs/man/pkexec.xml | 5 | ||||
-rw-r--r-- | docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml | 20 | ||||
-rw-r--r-- | docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml | 2 | ||||
-rw-r--r-- | docs/polkit/polkit-1-sections.txt | 1 | ||||
-rw-r--r-- | src/polkit/polkitauthorizationresult.c | 29 | ||||
-rw-r--r-- | src/polkit/polkitauthorizationresult.h | 1 | ||||
-rw-r--r-- | src/polkit/polkitpermission.c | 29 | ||||
-rw-r--r-- | src/polkitbackend/polkitbackendinteractiveauthority.c | 30 | ||||
-rw-r--r-- | src/programs/pkexec.c | 17 |
9 files changed, 118 insertions, 16 deletions
diff --git a/docs/man/pkexec.xml b/docs/man/pkexec.xml index 6f5dc9c..97ab315 100644 --- a/docs/man/pkexec.xml +++ b/docs/man/pkexec.xml @@ -61,7 +61,10 @@ of <replaceable>PROGRAM</replaceable>. If the calling process is not authorized or an authorization could not be obtained through authentication or an error occured, <command>pkexec</command> - exits with a return value of 127. + exits with a return value of 127. If the authorization could not + be obtained because the user dismissed the authentication + dialog, <command>pkexec</command> exits with a return value of + 126. </para> </refsect1> diff --git a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml index 663169e..b01fceb 100644 --- a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml +++ b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml @@ -40,8 +40,24 @@ BeginAuthentication (IN String action_id, IN Array<<link linkend="eggdbus-struct-Identity">Identity</link>> identities) </programlisting> <para> -<para>Called by the PolicyKit daemon when the authentication agent needs the user to authenticate as one of the identities in <parameter>identities</parameter> for the action with the identifier <parameter>action_id</parameter>.</para><para>Upon succesful authentication, the authentication agent must invoke the <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse">AuthenticationAgentResponse()</link> method on the <link linkend="eggdbus-interface-org.freedesktop.PolicyKit1.Authority">org.freedesktop.PolicyKit1.Authority</link> interface of the PolicyKit daemon before returning.</para><para>If the user dismisses the authentication dialog, the authentication agent should return an error.</para> + <para> + Called by the PolicyKit daemon when the authentication agent + needs the user to authenticate as one of the identities in + <parameter>identities</parameter> for the action with the + identifier <parameter>action_id</parameter>.</para><para>Upon + succesful authentication, the authentication agent must invoke + the <link + linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse">AuthenticationAgentResponse()</link> + method on the <link + linkend="eggdbus-interface-org.freedesktop.PolicyKit1.Authority">org.freedesktop.PolicyKit1.Authority</link> + interface of the PolicyKit daemon before returning. + </para> + <para> + The authentication agent should not return until after authentication is complete. + If the user dismisses the authentication dialog, the authentication agent should return the <link linkend="eggdbus-constant-Error.org.freedesktop.PolicyKit1.Error.Cancelled">org.freedesktop.PolicyKit1.Error.Cancelled</link> error. + </para> </para> + <variablelist role="params"> <varlistentry> <term><literal>IN String <parameter>action_id</parameter></literal>:</term> @@ -71,7 +87,7 @@ The themed icon describing the action or the empty string if no icon is set. <term><literal>IN Dict<String,String> <parameter>details</parameter></literal>:</term> <listitem> <para> -Details about the authentication request. This is a dictionary of key/value pairs where both key and value are strings. These strings are translated into the locale passed when registering the authentication agent using <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent">RegisterAuthenticationAgent().</link>. +Details about the authentication request. This is a dictionary of key/value pairs where both key and value are strings. These strings are translated into the locale passed when registering the authentication agent using <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent">RegisterAuthenticationAgent()</link>. Keys starting with <literal>polkit.</literal> are reserved for internal use and should never be displayed in the UI. Known key/value-pairs include <literal>polkit.caller-pid</literal> (the process id of the mechanism making the authorization check) and <literal>polkit.subject-pid</literal> (the process id of the subject the check is for). </para> diff --git a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml index cb9da6b..93f8cfa 100644 --- a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml +++ b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml @@ -461,7 +461,7 @@ TRUE if the given <link linkend="eggdbus-struct-Subject">Subject</link> could be <term><literal>Dict<String,String> <structfield>details</structfield></literal></term> <listitem> <para> -Details for the result or empty if not authorized. Known key/value-pairs include <literal>polkit.temporary_authorization_id</literal> (if the authorization is temporary, this is set to the opaque temporary authorization id), <literal>polkit.retains_authorization_after_challenge</literal> (Set to a non-empty string if the authorization will be retained after authentication (if is_challenge is TRUE)). +Details for the result or empty if not authorized. Known key/value-pairs include <literal>polkit.temporary_authorization_id</literal> (if the authorization is temporary, this is set to the opaque temporary authorization id), <literal>polkit.retains_authorization_after_challenge</literal> (Set to a non-empty string if the authorization will be retained after authentication (if is_challenge is TRUE)), <literal>polkit.dismissed</literal> (Set to a non-empty string if the authentication dialog was dismissed by the user). </para> </listitem> </varlistentry> diff --git a/docs/polkit/polkit-1-sections.txt b/docs/polkit/polkit-1-sections.txt index 78248dc..12141e3 100644 --- a/docs/polkit/polkit-1-sections.txt +++ b/docs/polkit/polkit-1-sections.txt @@ -71,6 +71,7 @@ polkit_authorization_result_get_is_authorized polkit_authorization_result_get_is_challenge polkit_authorization_result_get_retains_authorization polkit_authorization_result_get_temporary_authorization_id +polkit_authorization_result_get_dismissed polkit_authorization_result_get_details <SUBSECTION Standard> PolkitAuthorizationResultClass diff --git a/src/polkit/polkitauthorizationresult.c b/src/polkit/polkitauthorizationresult.c index 7390a9d..dd3d761 100644 --- a/src/polkit/polkitauthorizationresult.c +++ b/src/polkit/polkitauthorizationresult.c @@ -238,6 +238,35 @@ polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationR return ret; } +/** + * polkit_authorization_result_get_dismissed: + * @result: A #PolkitAuthorizationResult. + * + * Gets whether the authentication request was dismissed / canceled by the user. + * + * This method simply reads the value of the key/value pair in @details with the + * key <literal>polkit.dismissed</literal>. + * + * Returns: %TRUE if the authentication request was dismissed, %FALSE otherwise. + * + * Since: 0.101 + */ +gboolean +polkit_authorization_result_get_dismissed (PolkitAuthorizationResult *result) +{ + gboolean ret; + PolkitDetails *details; + + g_return_val_if_fail (POLKIT_IS_AUTHORIZATION_RESULT (result), FALSE); + + ret = FALSE; + details = polkit_authorization_result_get_details (result); + if (details != NULL && polkit_details_lookup (details, "polkit.dismissed") != NULL) + ret = TRUE; + + return ret; +} + PolkitAuthorizationResult * polkit_authorization_result_new_for_gvariant (GVariant *value) { diff --git a/src/polkit/polkitauthorizationresult.h b/src/polkit/polkitauthorizationresult.h index ea479fe..7f93bee 100644 --- a/src/polkit/polkitauthorizationresult.h +++ b/src/polkit/polkitauthorizationresult.h @@ -52,6 +52,7 @@ gboolean polkit_authorization_result_get_is_authorized (P gboolean polkit_authorization_result_get_is_challenge (PolkitAuthorizationResult *result); gboolean polkit_authorization_result_get_retains_authorization (PolkitAuthorizationResult *result); const gchar *polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationResult *result); +gboolean polkit_authorization_result_get_dismissed (PolkitAuthorizationResult *result); /* ---------------------------------------------------------------------------------------------------- */ diff --git a/src/polkit/polkitpermission.c b/src/polkit/polkitpermission.c index 996ee11..c855f2d 100644 --- a/src/polkit/polkitpermission.c +++ b/src/polkit/polkitpermission.c @@ -552,11 +552,22 @@ acquire_cb (GObject *source_object, process_result (data->permission, result); if (!polkit_authorization_result_get_is_authorized (result)) { - g_simple_async_result_set_error (data->simple, - POLKIT_ERROR, - POLKIT_ERROR_FAILED, - "Failed to acquire permission for action-id %s", - data->permission->action_id); + if (polkit_authorization_result_get_dismissed (result)) + { + g_simple_async_result_set_error (data->simple, + G_IO_ERROR, + G_IO_ERROR_CANCELLED, + "User dismissed authentication dialog while trying to acquire permission for action-id %s", + data->permission->action_id); + } + else + { + g_simple_async_result_set_error (data->simple, + POLKIT_ERROR, + POLKIT_ERROR_FAILED, + "Failed to acquire permission for action-id %s", + data->permission->action_id); + } } g_object_unref (result); } @@ -640,6 +651,14 @@ acquire (GPermission *gpermission, { ret = TRUE; } + else if (polkit_authorization_result_get_dismissed (result)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_CANCELLED, + "User dismissed authentication dialog while trying to acquire permission for action-id %s", + permission->action_id); + } else { g_set_error (error, diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c index ae1a1bf..4107e2d 100644 --- a/src/polkitbackend/polkitbackendinteractiveauthority.c +++ b/src/polkitbackend/polkitbackendinteractiveauthority.c @@ -82,6 +82,7 @@ typedef void (*AuthenticationAgentCallback) (AuthenticationAgent *agent, const gchar *action_id, PolkitImplicitAuthorization implicit_authorization, gboolean authentication_success, + gboolean was_dismissed, PolkitIdentity *authenticated_identity, gpointer user_data); @@ -274,6 +275,10 @@ polkit_backend_interactive_authority_init (PolkitBackendInteractiveAuthority *au PolkitBackendInteractiveAuthorityPrivate *priv; GFile *directory; GError *error; + static volatile GQuark domain = 0; + + /* Force registering error domain */ + domain = POLKIT_ERROR; priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority); @@ -582,6 +587,7 @@ check_authorization_challenge_cb (AuthenticationAgent *agent, const gchar *action_id, PolkitImplicitAuthorization implicit_authorization, gboolean authentication_success, + gboolean was_dismissed, PolkitIdentity *authenticated_identity, gpointer user_data) { @@ -613,9 +619,11 @@ check_authorization_challenge_cb (AuthenticationAgent *agent, g_debug ("In check_authorization_challenge_cb\n" " subject %s\n" " action_id %s\n" + " was_dismissed %d\n" " authentication_success %d\n", subject_str, action_id, + was_dismissed, authentication_success); is_temp = FALSE; @@ -649,8 +657,15 @@ check_authorization_challenge_cb (AuthenticationAgent *agent, } else { + PolkitDetails *details; + /* TODO: maybe return set is_challenge? */ - result = polkit_authorization_result_new (FALSE, FALSE, NULL); + + details = polkit_details_new (); + if (was_dismissed) + polkit_details_insert (details, "polkit.dismissed", "true"); + result = polkit_authorization_result_new (FALSE, FALSE, details); + g_object_unref (details); } /* Log the event */ @@ -1633,16 +1648,24 @@ authentication_agent_begin_cb (GDBusProxy *proxy, { AuthenticationSession *session = user_data; gboolean gained_authorization; + gboolean was_dismissed; GError *error; + was_dismissed = FALSE; + gained_authorization = FALSE; + error = NULL; if (!g_dbus_proxy_call_finish (proxy, res, &error)) { - g_printerr ("Error performing authentication: %s\n", error->message); + g_printerr ("Error performing authentication: %s (%s %d)\n", + error->message, + g_quark_to_string (error->domain), + error->code); + if (error->domain == POLKIT_ERROR && error->code == POLKIT_ERROR_CANCELLED) + was_dismissed = TRUE; g_error_free (error); - gained_authorization = FALSE; } else { @@ -1660,6 +1683,7 @@ authentication_agent_begin_cb (GDBusProxy *proxy, session->action_id, session->implicit_authorization, gained_authorization, + was_dismissed, session->authenticated_identity, session->user_data); diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c index fbd700d..40042e4 100644 --- a/src/programs/pkexec.c +++ b/src/programs/pkexec.c @@ -714,10 +714,19 @@ main (int argc, char *argv[]) } else { - log_message (LOG_WARNING, TRUE, - "Error executing command as another user: Not authorized"); - g_printerr ("\n" - "This incident has been reported.\n"); + if (polkit_authorization_result_get_dismissed (result)) + { + log_message (LOG_WARNING, TRUE, + "Error executing command as another user: Request dismissed"); + ret = 126; + } + else + { + log_message (LOG_WARNING, TRUE, + "Error executing command as another user: Not authorized"); + g_printerr ("\n" + "This incident has been reported.\n"); + } goto out; } |