2 * Copyright (c) 2014 Ian Sutton <ian@kremlin.cc>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include <glib/gprintf.h>
22 #include <glib-unix.h>
23 #include <polkit/polkit.h>
27 const gint MAX_TOKENS
= 20;
29 /* return must be g_free()'d */
30 gchar
*get_file_sha256(const gchar
*path
) {
37 file
= g_mapped_file_new(path
, FALSE
, &err
);
41 data
= g_mapped_file_get_bytes(file
);
42 g_mapped_file_unref(file
);
43 checksum
= g_compute_checksum_for_bytes(G_CHECKSUM_SHA256
, data
);
49 /* return must be g_free()'d */
50 gchar
*config_get(const gchar
*path
, gchar
*key
) {
52 gchar
*content
, **split_content
, *cur
, **cur_split
, *ret
;
55 gboolean breaker
= TRUE
;
57 ret
= (gchar
*) g_malloc0(4096);
59 if(!g_file_get_contents(path
, &content
, NULL
, &err
))
62 split_content
= g_strsplit(content
, "\n", MAX_TOKENS
);
64 while(breaker
&& (cur
= split_content
[incr
]) && (cur_split
= g_strsplit(cur
, "=", 2))) {
66 if(!g_strcmp0(key
, cur_split
[0])) {
68 g_strlcpy(ret
, cur_split
[1], 2048);
73 g_strfreev(cur_split
);
77 g_strfreev(split_content
);
81 return (ret
? ret
: NULL
);
84 gboolean
config_set(const gchar
*path
, gchar
*key
, gchar
*value
) {
86 gchar
*content
, **split_content
, *cur
, **cur_split
, *rewrite
;
87 GError
*err_set
, *err_get
;
90 gboolean breaker
= TRUE
;
92 err_get
= err_set
= NULL
;
94 if(!g_file_get_contents(path
, &content
, NULL
, &err_get
))
97 split_content
= g_strsplit(content
, "\n", MAX_TOKENS
);
99 while(breaker
&& (cur
= split_content
[incr
]) && (cur_split
= g_strsplit(cur
, "=", 2))) {
101 if(!g_strcmp0(key
, cur_split
[0])) {
103 cur_split
[1] = value
;
104 split_content
[incr
] = g_strjoinv("=", cur_split
);
114 rewrite
= g_strjoinv("\n", split_content
);
115 ret
= g_file_set_contents(path
, rewrite
, -1, &err_set
);
120 g_strfreev(cur_split
);
122 g_strfreev(split_content
);
129 static gboolean
is_valid_action(GList
*action_list
, const gchar
*action
) {
131 PolkitActionDescription
*action_descr
;
132 const gchar
*action_descr_id
;
137 cur
= g_list_first(action_list
);
139 while(cur
&& (action_descr
= ((PolkitActionDescription
*)(cur
->data
))) && (action_descr_id
= polkit_action_description_get_action_id(action_descr
))) {
141 if(!g_strcmp0(action
, action_descr_id
)) {
149 g_list_free(action_list
);
154 check_auth_result
polkit_try_auth(const gchar
*bus
, const gchar
*action
, gboolean prompt
) {
156 GList
*valid_actions
;
157 PolkitAuthority
*auth
;
159 PolkitAuthorizationResult
*result
;
160 PolkitCheckAuthorizationFlags prompt_flag
;
161 gboolean authorized
, challenge
;
166 valid_actions
= NULL
;
167 authorized
= challenge
= FALSE
;
168 prompt_flag
= prompt
? POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION
: POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE
;
170 auth
= polkit_authority_get_sync(NULL
, NULL
); /* TODO timeout for this */
171 subj
= polkit_system_bus_name_new(bus
);
172 valid_actions
= polkit_authority_enumerate_actions_sync(auth
, NULL
, NULL
);
174 if(!auth
|| !valid_actions
)
175 return ERROR_GENERIC
; /* extremely unlikely */
178 else if(!is_valid_action(valid_actions
, action
))
179 return ERROR_BADACTION
;
181 if(!(result
= polkit_authority_check_authorization_sync(auth
, subj
, action
, NULL
, prompt_flag
, NULL
, NULL
)))
182 return ERROR_GENERIC
; /* TODO pass, check gerror and return more relevant error */
184 authorized
= polkit_authorization_result_get_is_authorized(result
);
185 challenge
= polkit_authorization_result_get_is_challenge(result
);
187 /* free()'s before return */
189 g_object_unref(auth
);
191 g_object_unref(subj
);
193 g_object_unref(result
);
198 return AUTHORIZED_BY_PROMPT
;
200 return AUTHORIZED_NATIVELY
;
203 return UNAUTHORIZED_FAILED_PROMPT
;
205 return UNAUTHORIZED_NATIVELY
;