1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
/*
* Copyright (c) 2014 Ian Sutton <ian@kremlin.cc>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <glib/gprintf.h>
#include <glib-unix.h>
#include <polkit/polkit.h>
#include "polkit-auth.h"
static gboolean is_valid_action(GList *action_list, const gchar *action) {
PolkitActionDescription *action_descr;
const gchar *action_descr_id;
GList *cur;
gboolean ret;
ret = FALSE;
cur = g_list_first(action_list);
while(cur && (action_descr = ((PolkitActionDescription *)(cur->data))) && (action_descr_id = polkit_action_description_get_action_id(action_descr))) {
if(!g_strcmp0(action, action_descr_id)) {
ret = TRUE;
break;
}
cur = cur->next;
}
g_list_free(action_list);
return ret;
}
check_auth_result polkit_try_auth(const gchar *bus, const gchar *action, gboolean prompt) {
GList *valid_actions;
PolkitAuthority *auth;
PolkitSubject *subj;
PolkitAuthorizationResult *result;
PolkitCheckAuthorizationFlags prompt_flag;
gboolean authorized, challenge;
auth = NULL;
subj = NULL;
result = NULL;
valid_actions = NULL;
authorized = challenge = FALSE;
prompt_flag = prompt ? POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION : POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE;
auth = polkit_authority_get_sync(NULL, NULL); /* TODO timeout for this */
subj = polkit_system_bus_name_new(bus);
valid_actions = polkit_authority_enumerate_actions_sync(auth, NULL, NULL);
if(!auth || !valid_actions)
return ERROR_GENERIC; /* extremely unlikely */
else if(!subj)
return ERROR_BADBUS;
else if(!is_valid_action(valid_actions, action))
return ERROR_BADACTION;
if(!(result = polkit_authority_check_authorization_sync(auth, subj, action, NULL, prompt_flag, NULL, NULL)))
return ERROR_GENERIC; /* TODO pass, check gerror and return more relevant error */
authorized = polkit_authorization_result_get_is_authorized(result);
challenge = polkit_authorization_result_get_is_challenge(result);
/* free()'s before return */
if(auth)
g_object_unref(auth);
if(subj)
g_object_unref(subj);
if(result)
g_object_unref(result);
if(authorized) {
if(challenge)
return AUTHORIZED_BY_PROMPT;
return AUTHORIZED_NATIVELY;
} else if(challenge)
return UNAUTHORIZED_FAILED_PROMPT;
return UNAUTHORIZED_NATIVELY;
}
|