summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2019-10-08 01:29:24 +0100
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2019-10-08 01:38:54 +0100
commit5f4697fd7d03aad17f5b5ee79a1fbc5f9b472601 (patch)
tree6d3de410fc52cf4cf36db629b3bd28c7579bf1d7
parentc7d0d6e6c9e7a3179af67ece78505a79bd02ad5b (diff)
e - add polkit module to add an auth agent into e
new feature - polkit auth agent support partly in core (need to have the pam setuid root auth tool respond via dbus) and partly a module (the agent dbus protocol handling and setup as well as auth gui). this took me a while even with all the docs to work out how polkit works... it was really fussy and its data structs are an extra pain in the butt to craft with eldbus, but i managed it. not everything is supported but the core basics are there and this can be built on. right now the gui is really basic, but does the job.
-rw-r--r--data/config/default/e.src2
-rw-r--r--data/config/standard/e.src6
-rw-r--r--data/config/tiling/e.src7
-rw-r--r--meson_options.txt4
-rw-r--r--src/bin/e_auth.c57
-rw-r--r--src/bin/e_auth.h1
-rw-r--r--src/bin/e_ckpasswd_main.c207
-rw-r--r--src/bin/e_config.c27
-rw-r--r--src/bin/e_config.h2
-rw-r--r--src/bin/e_module.c1
-rw-r--r--src/bin/meson.build2
-rw-r--r--src/modules/meson.build1
-rw-r--r--src/modules/polkit/auth_ui.c149
-rw-r--r--src/modules/polkit/e-module-polkit.edjbin0 -> 7523 bytes
-rw-r--r--src/modules/polkit/e_mod_main.c17
-rw-r--r--src/modules/polkit/e_mod_main.h32
-rw-r--r--src/modules/polkit/meson.build6
-rw-r--r--src/modules/polkit/module.desktop6
-rw-r--r--src/modules/polkit/polkit.c523
19 files changed, 1019 insertions, 31 deletions
diff --git a/data/config/default/e.src b/data/config/default/e.src
index a2e0e3e..a017eff 100644
--- a/data/config/default/e.src
+++ b/data/config/default/e.src
@@ -1,5 +1,5 @@
1group "E_Config" struct { 1group "E_Config" struct {
2 value "config_version" int: 1000028; 2 value "config_version" int: 1000029;
3 value "config_type" uint: 0; // this profile seems to just be super minimalist 3 value "config_type" uint: 0; // this profile seems to just be super minimalist
4 value "show_splash" int: 0; 4 value "show_splash" int: 0;
5 value "desktop_default_name" string: "%i-%i"; 5 value "desktop_default_name" string: "%i-%i";
diff --git a/data/config/standard/e.src b/data/config/standard/e.src
index 4c716d8..bc9fc5d 100644
--- a/data/config/standard/e.src
+++ b/data/config/standard/e.src
@@ -1,5 +1,5 @@
1group "E_Config" struct { 1group "E_Config" struct {
2 value "config_version" int: 1000028; 2 value "config_version" int: 1000029;
3 value "config_type" uint: 3; 3 value "config_type" uint: 3;
4 value "show_splash" int: 1; 4 value "show_splash" int: 1;
5 value "desktop_default_name" string: "%i-%i"; 5 value "desktop_default_name" string: "%i-%i";
@@ -1015,6 +1015,10 @@ group "E_Config" struct {
1015 value "name" string: "bluez5"; 1015 value "name" string: "bluez5";
1016 value "enabled" uchar: 1; 1016 value "enabled" uchar: 1;
1017 } 1017 }
1018 group "E_Config_Module" struct {
1019 value "name" string: "polkit";
1020 value "enabled" uchar: 1;
1021 }
1018 } 1022 }
1019 group "xkb.used_layouts" list { 1023 group "xkb.used_layouts" list {
1020 group "E_Config_XKB_Layout" struct { 1024 group "E_Config_XKB_Layout" struct {
diff --git a/data/config/tiling/e.src b/data/config/tiling/e.src
index 431fce4..2d81e5a 100644
--- a/data/config/tiling/e.src
+++ b/data/config/tiling/e.src
@@ -1,5 +1,5 @@
1group "E_Config" struct { 1group "E_Config" struct {
2 value "config_version" int: 1000028; 2 value "config_version" int: 1000029;
3 value "config_type" uint: 3; 3 value "config_type" uint: 3;
4 value "show_splash" int: 1; 4 value "show_splash" int: 1;
5 value "desktop_default_name" string: "%i-%i"; 5 value "desktop_default_name" string: "%i-%i";
@@ -1034,10 +1034,13 @@ group "E_Config" struct {
1034 value "enabled" uchar: 1; 1034 value "enabled" uchar: 1;
1035 } 1035 }
1036 group "E_Config_Module" struct { 1036 group "E_Config_Module" struct {
1037 value "name" string: "polkit";
1038 value "enabled" uchar: 1;
1039 }
1040 group "E_Config_Module" struct {
1037 value "name" string: "tiling"; 1041 value "name" string: "tiling";
1038 value "enabled" uchar: 1; 1042 value "enabled" uchar: 1;
1039 } 1043 }
1040
1041 } 1044 }
1042 group "xkb.used_layouts" list { 1045 group "xkb.used_layouts" list {
1043 group "E_Config_XKB_Layout" struct { 1046 group "E_Config_XKB_Layout" struct {
diff --git a/meson_options.txt b/meson_options.txt
index d3457de..3a077e8 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -155,6 +155,10 @@ option('lokker',
155 type: 'boolean', 155 type: 'boolean',
156 value: true, 156 value: true,
157 description: 'enable lokker module: (default=true)') 157 description: 'enable lokker module: (default=true)')
158option('polkit',
159 type: 'boolean',
160 value: true,
161 description: 'enable polkit module: (default=true)')
158option('luncher', 162option('luncher',
159 type: 'boolean', 163 type: 'boolean',
160 value: true, 164 value: true,
diff --git a/src/bin/e_auth.c b/src/bin/e_auth.c
index 00b0e5d..92670f5 100644
--- a/src/bin/e_auth.c
+++ b/src/bin/e_auth.c
@@ -6,14 +6,17 @@ e_auth_begin(char *passwd)
6 char buf[PATH_MAX], *p; 6 char buf[PATH_MAX], *p;
7 Ecore_Exe *exe = NULL; 7 Ecore_Exe *exe = NULL;
8 int ret = 0; 8 int ret = 0;
9 size_t pwlen;
9 10
10 if (strlen(passwd) == 0) goto out; 11 pwlen = strlen(passwd);
12 if (pwlen == 0) goto out;
11 13
12 snprintf(buf, sizeof(buf), "%s/enlightenment/utils/enlightenment_ckpasswd", 14 snprintf(buf, sizeof(buf),
15 "%s/enlightenment/utils/enlightenment_ckpasswd pw",
13 e_prefix_lib_get()); 16 e_prefix_lib_get());
14
15 exe = ecore_exe_pipe_run(buf, ECORE_EXE_PIPE_WRITE, NULL); 17 exe = ecore_exe_pipe_run(buf, ECORE_EXE_PIPE_WRITE, NULL);
16 if (ecore_exe_send(exe, passwd, strlen(passwd)) != EINA_TRUE) goto out; 18 if (!exe) goto out;
19 if (ecore_exe_send(exe, passwd, pwlen) != EINA_TRUE) goto out;
17 ecore_exe_close_stdin(exe); 20 ecore_exe_close_stdin(exe);
18 21
19 ret = ecore_exe_pid_get(exe); 22 ret = ecore_exe_pid_get(exe);
@@ -24,12 +27,56 @@ e_auth_begin(char *passwd)
24 } 27 }
25 28
26 exe = NULL; 29 exe = NULL;
30
27out: 31out:
28 if (exe) ecore_exe_free(exe); 32 if (exe) ecore_exe_free(exe);
29 33
30 /* security - null out passwd string once we are done with it */ 34 /* security - null out passwd string once we are done with it */
31 for (p = passwd; *p; p++) *p = 0; 35 for (p = passwd; *p; p++) *p = 0;
32 if (passwd[0] || passwd[3]) fprintf(stderr, "ACK!\n"); 36 if (passwd[rand() % pwlen]) fprintf(stderr, "ACK!\n");
37 return ret;
38}
39
40E_API int
41e_auth_polkit_begin(char *passwd, const char *cookie, unsigned int uid)
42{
43 char buf[PATH_MAX], *p;
44 Ecore_Exe *exe = NULL;
45 int ret = 0;
46 size_t pwlen, buflen = 0;
47
48 pwlen = strlen(passwd);
49 if (pwlen == 0) goto out;
50
51 snprintf(buf, sizeof(buf),
52 "%s/enlightenment/utils/enlightenment_ckpasswd pk",
53 e_prefix_lib_get());
54 exe = ecore_exe_pipe_run(buf, ECORE_EXE_PIPE_WRITE, NULL);
55 if (!exe) goto out;
56 snprintf(buf, sizeof(buf), "%s %u %s", cookie, uid, passwd);
57 buflen = strlen(buf);
58 if (ecore_exe_send(exe, buf, buflen) != EINA_TRUE) goto out;
59 ecore_exe_close_stdin(exe);
33 60
61 ret = ecore_exe_pid_get(exe);
62 if (ret == -1)
63 {
64 ret = 0;
65 goto out;
66 }
67 exe = NULL;
68
69out:
70 if (exe) ecore_exe_free(exe);
71
72 /* security - null out passwd string once we are done with it */
73 for (p = passwd; *p; p++) *p = 0;
74 if (passwd[rand() % pwlen]) fprintf(stderr, "ACK!\n");
75 /* security - null out buf string once we are done with it */
76 if (buflen > 0)
77 {
78 for (p = buf; *p; p++) *p = 0;
79 if (buf[rand() % buflen]) fprintf(stderr, "ACK!\n");
80 }
34 return ret; 81 return ret;
35} 82}
diff --git a/src/bin/e_auth.h b/src/bin/e_auth.h
index 2ca2837..8728f29 100644
--- a/src/bin/e_auth.h
+++ b/src/bin/e_auth.h
@@ -2,6 +2,7 @@
2#define E_AUTH_H 2#define E_AUTH_H
3 3
4E_API int e_auth_begin(char *passwd); 4E_API int e_auth_begin(char *passwd);
5E_API int e_auth_polkit_begin(char *passwd, const char *cookie, unsigned int uid);
5 6
6static inline int 7static inline int
7e_auth_hash_djb2(const char *key, int len) 8e_auth_hash_djb2(const char *key, int len)
diff --git a/src/bin/e_ckpasswd_main.c b/src/bin/e_ckpasswd_main.c
index 31b04e7..173c5bd 100644
--- a/src/bin/e_ckpasswd_main.c
+++ b/src/bin/e_ckpasswd_main.c
@@ -15,6 +15,10 @@
15#include <alloca.h> 15#include <alloca.h>
16#endif 16#endif
17 17
18#include <Eina.h>
19#include <Ecore.h>
20#include <Eldbus.h>
21
18#if defined(__OpenBSD__) 22#if defined(__OpenBSD__)
19 23
20static int 24static int
@@ -162,42 +166,192 @@ _check_auth(uid_t uid, const char *pw)
162 166
163#endif 167#endif
164 168
169static int polkit_auth_ok = -1;
170
171static void
172polkit_agent_response(void *data EINA_UNUSED, const Eldbus_Message *msg,
173 Eldbus_Pending *pending EINA_UNUSED)
174{
175 const char *name, *text;
176
177 ecore_main_loop_quit();
178 if (eldbus_message_error_get(msg, &name, &text))
179 {
180 printf("Could not respond to auth.\n %s:\n %s\n", name, text);
181 return;
182 }
183 polkit_auth_ok = 0;
184 printf("Auth OK\n");
185}
186
187int
188polkit_auth(const char *cookie, unsigned int auth_uid)
189{
190 Eldbus_Connection *c;
191 Eldbus_Object *obj;
192 Eldbus_Proxy *proxy;
193 Eldbus_Message *m;
194 Eldbus_Message_Iter *iter, *subj, *array, *dict, *vari;
195 unsigned int uid;
196
197 eina_init();
198 ecore_init();
199 eldbus_init();
200 c = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
201 if (!c) return -1;
202 obj = eldbus_object_get(c, "org.freedesktop.PolicyKit1",
203 "/org/freedesktop/PolicyKit1/Authority");
204 if (!obj) return -1;
205 proxy = eldbus_proxy_get(obj, "org.freedesktop.PolicyKit1.Authority");
206 if (!proxy) return -1;
207 m = eldbus_proxy_method_call_new(proxy, "AuthenticationAgentResponse2");
208 if (!m) return -1;
209 iter = eldbus_message_iter_get(m);
210 if (!iter) return -1;
211 uid = getuid();
212 if (eldbus_message_iter_arguments_append(iter, "us", auth_uid, cookie))
213 {
214 if (eldbus_message_iter_arguments_append(iter, "(sa{sv})", &subj))
215 {
216 if (eldbus_message_iter_basic_append(subj, 's', "unix-user"))
217 {
218 if (eldbus_message_iter_arguments_append(subj, "a{sv}", &array))
219 {
220 if (eldbus_message_iter_arguments_append(array, "{sv}", &dict))
221 {
222 if (eldbus_message_iter_basic_append(dict, 's', "uid"))
223 {
224 vari = eldbus_message_iter_container_new(dict, 'v', "u");
225 if (vari)
226 {
227 if (eldbus_message_iter_basic_append(vari, 'u', auth_uid))
228 {
229 eldbus_message_iter_container_close(dict, vari);
230 } else return -1;
231 } else return -1;
232 } else return -1;
233 eldbus_message_iter_container_close(array, dict);
234 } else return -1;
235 eldbus_message_iter_container_close(subj, array);
236 } else return -1;
237 } else return -1;
238 eldbus_message_iter_container_close(iter, subj);
239 } else return -1;
240 eldbus_proxy_send(proxy, m, polkit_agent_response, NULL, -1);
241 } else return -1;
242
243 ecore_main_loop_begin();
244
245 eldbus_connection_unref(c);
246 eldbus_shutdown();
247 ecore_shutdown();
248 eina_shutdown();
249 return polkit_auth_ok;
250}
251
165int 252int
166main(int argc, char **argv) 253main(int argc, char **argv)
167{ 254{
168 ssize_t rd; 255 ssize_t rd;
169 uid_t id; 256 uid_t id;
170 char pw[4096], *p; 257 char pw[4096], *p;
258 int polkit_mode = 0;
259 char polkit_cookie[4096];
260 unsigned int polkit_uid = 0;
171 261
172 if (argc != 1) 262 if (argc < 2)
173 { 263 {
174 int i; 264 fprintf(stderr, "This is an internal tool for Enlightenment\n");
175 265 fprintf(stderr, "Options: pw | pk\n");
176 for (i = 1; i < argc; i++)
177 fprintf(stderr, "Unknown option %s\n", argv[i]);
178 fprintf(stderr,
179 "This is an internal tool for Enlightenment\n");
180 goto err; 266 goto err;
181 } 267 }
268 if (!strcmp(argv[1], "pw")) polkit_mode = 0;
269 else if (!strcmp(argv[1], "pk")) polkit_mode = 1;
182 270
183 // get uid who ran this 271 // get uid who ran this
184 id = getuid(); 272 id = getuid();
185 273
186 // read passwd from stdin 274 // read passwd from stdin
187 rd = read(0, pw, sizeof(pw) - 1); 275 if (polkit_mode == 0)
188 if (rd < 0)
189 { 276 {
190 fprintf(stderr, 277 rd = read(0, pw, sizeof(pw) - 1);
191 "Error. Can't read passwd on stdin\n"); 278 if (rd < 0)
192 goto err; 279 {
280 fprintf(stderr, "Error. Can't read passwd on stdin\n");
281 goto err;
282 }
283 pw[rd] = 0;
284 for (p = pw; *p; p++)
285 {
286 if ((*p == '\r') || (*p == '\n'))
287 {
288 *p = 0;
289 break;
290 }
291 }
193 } 292 }
194 pw[rd] = 0; 293 else if (polkit_mode == 1)
195 for (p = pw; *p; p++)
196 { 294 {
197 if ((*p == '\r') || (*p == '\n')) 295 unsigned int pos = 0;
296
297 // read "cookie-string uid-string password...[\r|\n|EOF]"
298 for (;;) // cookie
198 { 299 {
199 *p = 0; 300 rd = read(0, pw + pos, 1);
200 break; 301 if (pw[pos] == ' ')
302 {
303 memcpy(polkit_cookie, pw, pos);
304 polkit_cookie[pos] = 0;
305 printf("COOKIE: [%s]\n", polkit_cookie);
306 pos = 0;
307 break;
308 }
309 else
310 {
311 pos++;
312 if (pos > 4000)
313 {
314 fprintf(stderr, "Error. Polkit cookie too long\n");
315 return -10;
316 }
317 }
318 }
319 for (;;) // uid
320 {
321 rd = read(0, pw + pos, 1);
322 if (pw[pos] == ' ')
323 {
324 pw[pos] = 0;
325 polkit_uid = atoi(pw);
326 printf("UID: [%u]\n", polkit_uid);
327 break;
328 }
329 else
330 {
331 pos++;
332 if (pos > 4000)
333 {
334 fprintf(stderr, "Error. Polkit uid too long\n");
335 return -11;
336 }
337 }
338 }
339 // password
340 printf("READPASS...\n");
341 rd = read(0, pw, sizeof(pw) - 1);
342 if (rd < 0)
343 {
344 fprintf(stderr, "Error. Can't read passwd on stdin\n");
345 goto err;
346 }
347 pw[rd] = 0;
348 for (p = pw; *p; p++)
349 {
350 if ((*p == '\r') || (*p == '\n'))
351 {
352 *p = 0;
353 break;
354 }
201 } 355 }
202 } 356 }
203 357
@@ -209,9 +363,22 @@ main(int argc, char **argv)
209 if (setgid(0) != 0) 363 if (setgid(0) != 0)
210 fprintf(stderr, 364 fprintf(stderr,
211 "Warning. Can't become group root. If password auth requires root then this will fail\n"); 365 "Warning. Can't become group root. If password auth requires root then this will fail\n");
212 if (_check_auth(id, pw) == 0) return 0; 366 if (_check_auth(id, pw) == 0)
367 {
368 fprintf(stderr, "Password OK\n");
369 if (polkit_mode == 1)
370 {
371 if (polkit_auth(polkit_cookie, polkit_uid) == 0)
372 {
373 fprintf(stderr, "Polkit AuthenticationAgentResponse2 success\n");
374 return 0;
375 }
376 fprintf(stderr, "Polkit AuthenticationAgentResponse2 failure\n");
377 return -2;
378 }
379 return 0;
380 }
213err: 381err:
214 fprintf(stderr, 382 fprintf(stderr, "Password auth fail\n");
215 "Password auth fail\n");
216 return -1; 383 return -1;
217} 384}
diff --git a/src/bin/e_config.c b/src/bin/e_config.c
index 5195321..00fe411 100644
--- a/src/bin/e_config.c
+++ b/src/bin/e_config.c
@@ -1441,6 +1441,7 @@ e_config_load(void)
1441 e_config->window_maximize_animate = 1; 1441 e_config->window_maximize_animate = 1;
1442 e_config->window_maximize_transition = E_EFX_EFFECT_SPEED_SINUSOIDAL; 1442 e_config->window_maximize_transition = E_EFX_EFFECT_SPEED_SINUSOIDAL;
1443 e_config->window_maximize_time = 0.15; 1443 e_config->window_maximize_time = 0.15;
1444 e_config_save_queue();
1444 } 1445 }
1445 CONFIG_VERSION_CHECK(22) 1446 CONFIG_VERSION_CHECK(22)
1446 { 1447 {
@@ -1465,6 +1466,7 @@ e_config_load(void)
1465 module->enabled = 1; 1466 module->enabled = 1;
1466 e_config->modules = eina_list_append(e_config->modules, module); 1467 e_config->modules = eina_list_append(e_config->modules, module);
1467 } 1468 }
1469 e_config_save_queue();
1468 } 1470 }
1469 CONFIG_VERSION_CHECK(23) 1471 CONFIG_VERSION_CHECK(23)
1470 { 1472 {
@@ -1487,6 +1489,7 @@ e_config_load(void)
1487 module->enabled = 1; 1489 module->enabled = 1;
1488 e_config->modules = eina_list_append(e_config->modules, module); 1490 e_config->modules = eina_list_append(e_config->modules, module);
1489 } 1491 }
1492 e_config_save_queue();
1490 } 1493 }
1491 CONFIG_VERSION_CHECK(24) 1494 CONFIG_VERSION_CHECK(24)
1492 { 1495 {
@@ -1494,6 +1497,7 @@ e_config_load(void)
1494 1497
1495 if (!elm_config_profile_exists(_e_config_profile)) 1498 if (!elm_config_profile_exists(_e_config_profile))
1496 elm_config_profile_save(_e_config_profile); 1499 elm_config_profile_save(_e_config_profile);
1500 e_config_save_queue();
1497 } 1501 }
1498 CONFIG_VERSION_CHECK(25) 1502 CONFIG_VERSION_CHECK(25)
1499 { 1503 {
@@ -1574,6 +1578,29 @@ e_config_load(void)
1574 } 1578 }
1575 e_config_save_queue(); 1579 e_config_save_queue();
1576 } 1580 }
1581 CONFIG_VERSION_CHECK(29)
1582 {
1583 Eina_List *l;
1584 E_Config_Module *em, *module;
1585 Eina_Bool mod_loaded = EINA_FALSE;
1586
1587 CONFIG_VERSION_UPDATE_INFO(29);
1588
1589 EINA_LIST_FOREACH(e_config->modules, l, em)
1590 {
1591 if (!em->enabled) continue;
1592 if (eina_streq(em->name, "polkit"))
1593 mod_loaded = EINA_TRUE;
1594 }
1595 if (!mod_loaded)
1596 {
1597 module = E_NEW(E_Config_Module, 1);
1598 module->name = eina_stringshare_add("polkit");
1599 module->enabled = 1;
1600 e_config->modules = eina_list_append(e_config->modules, module);
1601 }
1602 e_config_save_queue();
1603 }
1577 } 1604 }
1578 elm_config_profile_set(_e_config_profile); 1605 elm_config_profile_set(_e_config_profile);
1579 if (!e_config->remember_internal_fm_windows) 1606 if (!e_config->remember_internal_fm_windows)
diff --git a/src/bin/e_config.h b/src/bin/e_config.h
index 0c73250..3eeb395 100644
--- a/src/bin/e_config.h
+++ b/src/bin/e_config.h
@@ -46,7 +46,7 @@ typedef enum
46/* increment this whenever a new set of config values are added but the users 46/* increment this whenever a new set of config values are added but the users
47 * config doesn't need to be wiped - simply new values need to be put in 47 * config doesn't need to be wiped - simply new values need to be put in
48 */ 48 */
49#define E_CONFIG_FILE_GENERATION 28 49#define E_CONFIG_FILE_GENERATION 29
50#define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH * 1000000) + E_CONFIG_FILE_GENERATION) 50#define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH * 1000000) + E_CONFIG_FILE_GENERATION)
51 51
52#define E_CONFIG_BINDINGS_VERSION 0 // DO NOT INCREMENT UNLESS YOU WANT TO WIPE ALL BINDINGS!!!!! 52#define E_CONFIG_BINDINGS_VERSION 0 // DO NOT INCREMENT UNLESS YOU WANT TO WIPE ALL BINDINGS!!!!!
diff --git a/src/bin/e_module.c b/src/bin/e_module.c
index bcc824e..9217662 100644
--- a/src/bin/e_module.c
+++ b/src/bin/e_module.c
@@ -753,6 +753,7 @@ _e_module_whitelist_check(void)
753 "ibox", 753 "ibox",
754 "layout", 754 "layout",
755 "lokker", 755 "lokker",
756 "polkit",
756 "luncher", 757 "luncher",
757 "mixer", 758 "mixer",
758 "msgbus", 759 "msgbus",
diff --git a/src/bin/meson.build b/src/bin/meson.build
index 138bb65..4a0878e 100644
--- a/src/bin/meson.build
+++ b/src/bin/meson.build
@@ -34,7 +34,7 @@ deps_e = [
34 dep_intl 34 dep_intl
35] 35]
36 36
37deps_ckpass = [ ] 37deps_ckpass = [ dep_eina, dep_ecore, dep_eldbus ]
38 38
39if freebsd == true 39if freebsd == true
40 deps_ckpass += dep_crypt 40 deps_ckpass += dep_crypt
diff --git a/src/modules/meson.build b/src/modules/meson.build
index 5ace236..a244bd3 100644
--- a/src/modules/meson.build
+++ b/src/modules/meson.build
@@ -65,6 +65,7 @@ mods = [
65# also standard modules with no icon or desktop file 65# also standard modules with no icon or desktop file
66 'xwayland', 66 'xwayland',
67 'lokker', 67 'lokker',
68 'polkit',
68 'wl_x11', 69 'wl_x11',
69 'wl_wl', 70 'wl_wl',
70 'wl_buffer', 71 'wl_buffer',
diff --git a/src/modules/polkit/auth_ui.c b/src/modules/polkit/auth_ui.c
new file mode 100644
index 0000000..88639eb
--- /dev/null
+++ b/src/modules/polkit/auth_ui.c
@@ -0,0 +1,149 @@
1#include "e_mod_main.h"
2
3static Eina_Bool
4_auth_cb_exit(void *data, int type EINA_UNUSED, void *event)
5{
6 Polkit_Session *ps = data;
7 Ecore_Exe_Event_Del *ev = event;
8
9 if (ev->pid != ps->auth_pid) return ECORE_CALLBACK_PASS_ON;
10 ps->auth_pid = 0;
11 if (ps->exe_exit_handler) ecore_event_handler_del(ps->exe_exit_handler);
12 ps->exe_exit_handler = NULL;
13 session_reply(ps);
14 return ECORE_CALLBACK_PASS_ON;
15}
16
17static void
18_cb_del(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj,
19 void *event_info EINA_UNUSED)
20{
21 Polkit_Session *ps = evas_object_data_get(obj, "session");
22 if (!ps) return;
23 if (ps->exe_exit_handler)
24 {
25 ecore_event_handler_del(ps->exe_exit_handler);
26 ps->exe_exit_handler = NULL;
27 }
28 if (ps->win)
29 {
30 ps->win = NULL;
31 session_reply(ps);
32 }
33}
34
35static void
36_cb_ok(void *data EINA_UNUSED, Evas_Object *obj,
37 void *event_info EINA_UNUSED)
38{
39 Polkit_Session *ps = evas_object_data_get(obj, "session");
40 const char *str = elm_object_text_get(obj);
41
42 if (!ps) return;
43 if (ps->exe_exit_handler) return;
44 ps->exe_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
45 _auth_cb_exit, ps);
46 if (str)
47 {
48 char *passwd = strdup(str);
49 if (passwd)
50 {
51 ps->auth_pid = e_auth_polkit_begin(passwd, ps->cookie, ps->target_uid);
52 free(passwd);
53 return;
54 }
55 }
56 evas_object_del(ps->win);
57}
58
59static void
60_cb_cancel(void *data EINA_UNUSED, Evas_Object *obj,
61 void *event_info EINA_UNUSED)
62{
63 Polkit_Session *ps = evas_object_data_get(obj, "session");
64 if (!ps) return;
65 if (ps->exe_exit_handler) return;
66 session_reply(ps);
67}
68
69static void
70_cb_button_ok(void *data, E_Dialog *dia EINA_UNUSED)
71{
72 _cb_ok(NULL, data, NULL);
73}
74
75static void
76_cb_button_cancel(void *data, E_Dialog *dia EINA_UNUSED)
77{
78 _cb_cancel(NULL, data, NULL);
79}
80
81void
82auth_ui(Polkit_Session *ps)
83{
84 E_Dialog *dia;
85 Evas_Object *o, *win, *box, *ent;
86
87 dia = e_dialog_new(NULL, "E", "_polkit_auth");
88 e_dialog_title_set(dia, _("Please enter password"));
89
90 win = dia->win;
91
92 if ((!ps->icon_name) || (!ps->icon_name[0]))
93 e_dialog_icon_set(dia, "enlightenment", 64);
94 else
95 e_dialog_icon_set(dia, ps->icon_name, 64);
96
97 evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _cb_del, NULL);
98 elm_win_autodel_set(win, EINA_TRUE);
99 evas_object_data_set(win, "session", ps);
100
101 box = o = elm_box_add(win);
102 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
103 evas_object_size_hint_align_set(o, -1.0, -1.0);
104 elm_box_horizontal_set(o, EINA_FALSE);
105 e_dialog_content_set(dia, o, 0, 0);
106 evas_object_show(o);
107
108/* XXX: lookup action and display something useful for it in future.
109 o = elm_label_add(win);
110 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
111 evas_object_size_hint_align_set(o, 0.0, 0.0);
112 elm_object_text_set(o, ps->action);
113 elm_box_pack_end(box, o);
114 evas_object_show(o);
115 */
116
117 o = elm_label_add(win);
118 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
119 evas_object_size_hint_align_set(o, 0.0, 0.0);
120 elm_object_text_set(o, ps->message);
121 elm_box_pack_end(box, o);
122 evas_object_show(o);
123
124 ent = o = elm_entry_add(win);
125 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
126 evas_object_size_hint_align_set(o, -1.0, 1.0);
127 elm_entry_single_line_set(ent, EINA_TRUE);
128 elm_entry_scrollable_set(ent, EINA_TRUE);
129 elm_entry_password_set(ent, EINA_TRUE);
130 elm_object_part_text_set(ent, "elm.guide", "Enter Password");
131 evas_object_data_set(ent, "session", ps);
132 evas_object_smart_callback_add(ent, "activated", _cb_ok, NULL);
133 evas_object_smart_callback_add(ent, "aborted", _cb_cancel, NULL);
134 elm_box_pack_end(box, o);
135 evas_object_show(o);
136
137 e_dialog_button_add(dia, _("OK"), NULL, _cb_button_ok, ent);
138 e_dialog_button_add(dia, _("Cancel"), NULL, _cb_button_cancel, ent);
139 e_dialog_button_focus_num(dia, 0);
140
141 elm_object_focus_set(ent, EINA_TRUE);
142
143 ps->win = win;
144 ps->entry = ent;
145
146 elm_win_center(win, 1, 1);
147 e_dialog_show(dia);
148 elm_win_activate(win);
149}
diff --git a/src/modules/polkit/e-module-polkit.edj b/src/modules/polkit/e-module-polkit.edj
new file mode 100644
index 0000000..807f83d
--- /dev/null
+++ b/src/modules/polkit/e-module-polkit.edj
Binary files differ
diff --git a/src/modules/polkit/e_mod_main.c b/src/modules/polkit/e_mod_main.c
new file mode 100644
index 0000000..c7cc07a
--- /dev/null
+++ b/src/modules/polkit/e_mod_main.c
@@ -0,0 +1,17 @@
1#include "e_mod_main.h"
2
3E_API E_Module_Api e_modapi = {E_MODULE_API_VERSION, "Polkit"};
4
5E_API void *
6e_modapi_init(E_Module *m)
7{
8 e_mod_polkit_register();
9 return m;
10}
11
12E_API int
13e_modapi_shutdown(E_Module *m EINA_UNUSED)
14{
15 e_mod_polkit_unregister();
16 return 1;
17}
diff --git a/src/modules/polkit/e_mod_main.h b/src/modules/polkit/e_mod_main.h
new file mode 100644
index 0000000..db38fa9
--- /dev/null
+++ b/src/modules/polkit/e_mod_main.h
@@ -0,0 +1,32 @@
1#ifndef E_MOD_MAIN_H
2#define E_MOD_MAIN_H
3
4#ifdef HAVE_CONFIG_H
5#include "config.h"
6#endif
7
8#include "e.h"
9
10typedef struct
11{
12 const char *cookie;
13 const char *message;
14 const char *icon_name;
15 const char *action;
16 unsigned int target_uid;
17 int auth_pid;
18 Ecore_Event_Handler *exe_exit_handler;
19 Eldbus_Message *reply;
20 Eldbus_Pending *pend_reply;
21 Evas_Object *win;
22 Evas_Object *entry;
23} Polkit_Session;
24
25void session_reply(Polkit_Session *ps);
26
27void auth_ui(Polkit_Session *ps);
28
29void e_mod_polkit_register(void);
30void e_mod_polkit_unregister(void);
31
32#endif
diff --git a/src/modules/polkit/meson.build b/src/modules/polkit/meson.build
new file mode 100644
index 0000000..f839f7a
--- /dev/null
+++ b/src/modules/polkit/meson.build
@@ -0,0 +1,6 @@
1src = files(
2 'e_mod_main.c',
3 'polkit.c',
4 'auth_ui.c',
5 'e_mod_main.h'
6 )
diff --git a/src/modules/polkit/module.desktop b/src/modules/polkit/module.desktop
new file mode 100644
index 0000000..f118928
--- /dev/null
+++ b/src/modules/polkit/module.desktop
@@ -0,0 +1,6 @@
1[Desktop Entry]
2Type=Link
3Name=Polkit
4Comment=This module provides a polkit authentication agent
5Icon=e-module-polkit
6X-Enlightenment-ModuleType=core
diff --git a/src/modules/polkit/polkit.c b/src/modules/polkit/polkit.c
new file mode 100644
index 0000000..d29b854
--- /dev/null
+++ b/src/modules/polkit/polkit.c
@@ -0,0 +1,523 @@
1#include "e_mod_main.h"
2
3static Eldbus_Connection *pk_conn = NULL;
4static Eldbus_Service_Interface *agent_iface = NULL;
5static Eldbus_Object *pk_obj = NULL;
6static Eldbus_Proxy *pk_proxy = NULL;
7
8static Eldbus_Pending *pend_call = NULL;
9
10static Eldbus_Object *ses_obj = NULL;
11static Eldbus_Object *ses_obj2 = NULL;
12static Eldbus_Proxy *ses_proxy = NULL;
13static Eldbus_Proxy *ses_proxy2 = NULL;
14
15static Eina_Bool agent_request = EINA_FALSE;
16static Eina_Bool agent_ok = EINA_FALSE;
17static const char *session_path = NULL;
18static const char *session_id = NULL;
19static unsigned int session_uid = 0;
20static const char *session_user = NULL;
21
22//////////////////////////////////////////////////////////////////////////////
23
24static Eina_Hash *sessions = NULL;
25
26static void
27_session_free(Polkit_Session *ps)
28{
29 if (ps->reply) eldbus_connection_send(pk_conn, ps->reply, NULL, NULL, -1);
30 ps->reply = NULL;
31 if (ps->pend_reply) eldbus_pending_cancel(ps->pend_reply);
32 ps->pend_reply = NULL;
33 eina_stringshare_del(ps->cookie);
34 ps->cookie = NULL;
35 eina_stringshare_del(ps->message);
36 ps->message = NULL;
37 eina_stringshare_del(ps->icon_name);
38 ps->icon_name = NULL;
39 eina_stringshare_del(ps->action);
40 ps->action = NULL;
41 if (ps->win)
42 {
43 Evas_Object *win = ps->win;
44
45 ps->win = NULL;
46 evas_object_del(win);
47 }
48 free(ps);
49}
50
51static void
52session_init(void)
53{
54 if (sessions) return;
55 sessions = eina_hash_string_superfast_new((void *)_session_free);
56}
57
58static void
59session_shutdown(void)
60{
61 if (sessions) eina_hash_free(sessions);
62 sessions = NULL;
63}
64
65static Polkit_Session *
66session_new(void)
67{
68 return calloc(1, sizeof(Polkit_Session));
69}
70
71static void
72session_free(Polkit_Session *ps)
73{
74 eina_hash_del(sessions, ps->cookie, ps);
75}
76
77static void
78session_register(Polkit_Session *ps)
79{
80 eina_hash_add(sessions, ps->cookie, ps);
81}
82
83static Polkit_Session *
84session_find(const char *cookie)
85{
86 return eina_hash_find(sessions, cookie);
87}
88
89void
90session_reply(Polkit_Session *ps)
91{
92 if (ps->reply)
93 {
94 ps->pend_reply = eldbus_connection_send(pk_conn, ps->reply, NULL, NULL, -1);
95 ps->reply = NULL;
96 }
97 session_free(ps);
98}
99
100void
101session_show(Polkit_Session *ps)
102{
103 auth_ui(ps);
104 // display some auth dialog to enter a password, show ps->message
105 // and ps->action specific ui ps->icon_name
106 // when we get the password call
107 // e_auth_polkit_begin(pass, ps->cookie, ps->target_uid);
108 // when this returns call session_reply(ps);
109}
110
111//////////////////////////////////////////////////////////////////////////////
112
113static void
114iterate_dict(void *data, const void *key, Eldbus_Message_Iter *var)
115{
116 Polkit_Session *ps = data;
117 const char *skey = key;
118
119 if (!strcmp(skey, "uid"))
120 {
121 unsigned int uid = 0;
122
123 if (eldbus_message_iter_arguments_get(var, "u", &uid))
124 ps->target_uid = uid;
125 }
126}
127
128static Eldbus_Message *
129cb_agent_begin_authentication(const Eldbus_Service_Interface *iface EINA_UNUSED,
130 const Eldbus_Message *msg)
131{
132 // sssa{ss}sa(sa{sv})
133 const char *action_id = NULL, *message = NULL, *icon_name = NULL,
134 *cookie = NULL;
135 Eldbus_Message_Iter *details = NULL, *ident = NULL, *item = NULL;
136 Polkit_Session *ps, *ps2;
137
138 ps = session_new();
139 if (!ps) goto err;
140 ps->reply = eldbus_message_method_return_new(msg);
141
142 if (!eldbus_message_arguments_get(msg, "sssa{ss}sa(sa{sv})",
143 &action_id, &message, &icon_name,
144 &details, &cookie, &ident))
145 goto err;
146 ps->cookie = eina_stringshare_add(cookie);
147 ps->message = eina_stringshare_add(message);
148 ps->icon_name = eina_stringshare_add(icon_name);
149 ps->action = eina_stringshare_add(action_id);
150 // actions in: /usr/share/polkit-1/actions
151
152/* XXX: Haven't seen details content yet - not sure what to do with it
153 while (eldbus_message_iter_get_and_next(details, 'r', &item))
154 {
155 const char *v1, *v2;
156
157 v1 = NULL;
158 v2 = NULL;
159 eldbus_message_iter_arguments_get(item, "ss", &v1, &v2);
160 }
161 */
162 while (eldbus_message_iter_get_and_next(ident, 'r', &item))
163 {
164 const char *v1;
165 Eldbus_Message_Iter *dict = NULL;
166
167 v1 = NULL;
168 eldbus_message_iter_arguments_get(item, "sa{sv}", &v1, &dict);
169 if (!strcmp(v1, "unix-user"))
170 eldbus_message_iter_dict_iterate(dict, "sv", iterate_dict, ps);
171 else
172 {
173 printf("PK: Unhandled ident type.\n");
174 }
175 }
176 ps2 = session_find(ps->cookie);
177 if (ps2) session_free(ps2);
178 session_register(ps);
179 session_show(ps);
180 return NULL;
181err:
182 return eldbus_message_method_return_new(msg);
183}
184
185static Eldbus_Message *
186cb_agent_cancel_authentication(const Eldbus_Service_Interface *iface EINA_UNUSED,
187 const Eldbus_Message *msg)
188{
189 const char *cookie;
190 Polkit_Session *ps;
191
192 // s
193 if (!eldbus_message_arguments_get(msg, "s", &cookie)) return NULL;
194 ps = session_find(cookie);
195 if (ps) session_free(ps);
196 return eldbus_message_method_return_new(msg);
197}
198
199//////////////////////////////////////////////////////////////////////////////
200
201static void
202cb_register(void *data EINA_UNUSED, const Eldbus_Message *msg,
203 Eldbus_Pending *pending EINA_UNUSED)
204{
205 const char *name, *text;
206
207 pend_call = NULL;
208 if (eldbus_message_error_get(msg, &name, &text)) return;
209 agent_request = EINA_FALSE;
210 agent_ok = EINA_TRUE;
211}
212
213static const Eldbus_Method agent_methods[] = {
214 { "BeginAuthentication",
215 ELDBUS_ARGS({ "s", "action_id" },
216 { "s", "message" },
217 { "s", "icon_name" },
218 { "a{ss}", "details" },
219 { "s", "cookie" },
220 { "a(sa{sv})", "identities" }),
221 NULL,
222 cb_agent_begin_authentication, 0
223 },
224 { "CancelAuthentication",
225 ELDBUS_ARGS({ "s", "cookie" }),
226 NULL,
227 cb_agent_cancel_authentication, 0
228 },
229 { NULL, NULL, NULL, NULL, 0 }
230};
231static const Eldbus_Service_Interface_Desc agent_desc = {
232 "org.freedesktop.PolicyKit1.AuthenticationAgent", agent_methods, NULL, NULL, NULL, NULL
233};
234
235static void
236pk_agent_register(void)
237{
238 Eldbus_Message *msg;
239 Eldbus_Message_Iter *iter, *subj, *array, *dict, *vari;
240 const char *locale = NULL;
241
242 agent_request = EINA_TRUE;
243 // set up agent interface
244 agent_iface = eldbus_service_interface_register
245 (pk_conn, "/org/enlightenment/polkit/Agent", &agent_desc);
246
247 // register agent interface with polkit
248 if (!locale) locale = getenv("LC_MESSAGES");
249 if (!locale) locale = getenv("LC_ALL");
250 if (!locale) locale = getenv("LANG");
251 if (!locale) locale = getenv("LANGUAGE");
252 if (!locale) locale = "C";
253
254 pk_obj = eldbus_object_get(pk_conn, "org.freedesktop.PolicyKit1",
255 "/org/freedesktop/PolicyKit1/Authority");
256 if (!pk_obj) return;
257 pk_proxy = eldbus_proxy_get(pk_obj, "org.freedesktop.PolicyKit1.Authority");
258 if (!pk_proxy) return;
259 msg = eldbus_proxy_method_call_new(pk_proxy, "RegisterAuthenticationAgent");
260 // (sa{sv})ss
261 iter = eldbus_message_iter_get(msg);
262 eldbus_message_iter_arguments_append(iter, "(sa{sv})", &subj);
263 eldbus_message_iter_basic_append(subj, 's', "unix-session");
264 eldbus_message_iter_arguments_append(subj, "a{sv}", &array);
265 eldbus_message_iter_arguments_append(array, "{sv}", &dict);
266 eldbus_message_iter_basic_append(dict, 's', "session-id");
267 vari = eldbus_message_iter_container_new(dict, 'v', "s");
268 eldbus_message_iter_basic_append(vari, 's', session_id);
269 eldbus_message_iter_container_close(dict, vari);
270 eldbus_message_iter_container_close(array, dict);
271 eldbus_message_iter_container_close(subj, array);
272 eldbus_message_iter_container_close(iter, subj);
273
274 eldbus_message_iter_basic_append(iter, 's', locale);
275 eldbus_message_iter_basic_append(iter, 's', "/org/enlightenment/polkit/Agent");
276 pend_call = eldbus_proxy_send(pk_proxy, msg, cb_register, NULL, -1);
277}
278
279///////////////////////////////////////////////////////////////////////////////
280
281static void
282cb_login_prop_entry(void *data EINA_UNUSED, const void *key, Eldbus_Message_Iter *var)
283{
284 const char *skey = key;
285
286 if (!strcmp(skey, "Id"))
287 {
288 const char *val = NULL;
289 if (eldbus_message_iter_arguments_get(var, "s", &val))
290 eina_stringshare_replace(&session_id, val);
291 }
292 else if (!strcmp(skey, "User"))
293 {
294 Eldbus_Message_Iter *iter = NULL;
295
296 eldbus_message_iter_arguments_get(var, "(uo)", &iter);
297 if (iter)
298 {
299 unsigned int uid = 0;
300 const char *val = NULL;
301
302 if (eldbus_message_iter_arguments_get(iter, "uo", &uid, &val))
303 {
304 session_uid = uid;
305 eina_stringshare_replace(&session_user, val);
306 }
307 }
308 }
309}
310
311static void
312cb_login_prop(void *data EINA_UNUSED, const Eldbus_Message *msg,
313 Eldbus_Pending *pending EINA_UNUSED)
314{
315 Eldbus_Message_Iter *array;
316
317 pend_call = NULL;
318 if (eldbus_message_error_get(msg, NULL, NULL)) return;
319 if (eldbus_message_arguments_get(msg, "a{sv}", &array))
320 {
321 eldbus_message_iter_dict_iterate(array, "sv",
322 cb_login_prop_entry, NULL);
323 if ((session_id) && (session_user) && (session_path))
324 pk_agent_register();
325 }
326 if (ses_proxy2) eldbus_proxy_unref(ses_proxy2);
327 ses_proxy2 = NULL;
328 if (ses_proxy) eldbus_proxy_unref(ses_proxy);
329 ses_proxy = NULL;
330 if (ses_obj) eldbus_object_unref(ses_obj);
331 ses_obj = NULL;
332 if (ses_obj2) eldbus_object_unref(ses_obj2);
333 ses_obj2 = NULL;
334}
335
336static void
337cb_login_session(void *data EINA_UNUSED, const Eldbus_Message *msg,
338 Eldbus_Pending *pending EINA_UNUSED)
339{
340 const char *name, *text;
341 const char *s;
342
343 pend_call = NULL;
344 if (eldbus_message_error_get(msg, &name, &text)) return;
345 if (!eldbus_message_arguments_get(msg, "o", &s)) return;
346 eina_stringshare_replace(&session_path, s);
347 ses_obj2 = eldbus_object_get(pk_conn, "org.freedesktop.login1", s);
348 if (!ses_obj2) return;
349 ses_proxy2 = eldbus_proxy_get(ses_obj2, "org.freedesktop.login1.Session");
350 if (!ses_proxy2) return;
351 pend_call = eldbus_proxy_property_get_all(ses_proxy2, cb_login_prop, NULL);
352}
353
354static void
355pk_session_init(void)
356{
357 ses_obj = eldbus_object_get(pk_conn, "org.freedesktop.login1",
358 "/org/freedesktop/login1");
359 if (!ses_obj) return;
360 ses_proxy = eldbus_proxy_get(ses_obj, "org.freedesktop.login1.Manager");
361 if (!ses_proxy) return;
362 pend_call = eldbus_proxy_call(ses_proxy, "GetSessionByPID",
363 cb_login_session, NULL, -1,
364 "u", (unsigned int)getpid());
365}
366
367/////////////////////////////////////////////////////////////////////////////
368
369static Ecore_Timer *owner_gain_timer = NULL;
370
371static Eina_Bool
372cb_name_owner_new(void *data EINA_UNUSED)
373{
374 owner_gain_timer = NULL;
375 pk_session_init();
376 session_init();
377 return EINA_FALSE;
378}
379
380static void
381cb_name_owner_changed(void *data EINA_UNUSED,
382 const char *bus EINA_UNUSED,
383 const char *from EINA_UNUSED,
384 const char *to)
385{
386 static Eina_Bool first = EINA_TRUE;
387
388 if (to[0])
389 {
390 if (owner_gain_timer) ecore_timer_del(owner_gain_timer);
391 // on first start try and re-init quickly because we get a name
392 // owner change even if all is good when we register to listen for it,
393 // so start fast
394 if (first)
395 owner_gain_timer = ecore_timer_add(0.1, cb_name_owner_new, NULL);
396 // but if we gegt a name owner change later it's probably because
397 // bluez was restarted or crashed. a new bz daemon will (or should)
398 // come up. so re-init more slowly here giving the daemon some time
399 // to come up before pestering it.
400 else
401 owner_gain_timer = ecore_timer_add(1.0, cb_name_owner_new, NULL);
402 first = EINA_FALSE;
403 }
404 else
405 {
406 session_shutdown();
407 if (pend_call) eldbus_pending_cancel(pend_call);
408 pend_call = NULL;
409 if (agent_iface) eldbus_service_object_unregister(agent_iface);
410 agent_iface = NULL;
411 if (owner_gain_timer) ecore_timer_del(owner_gain_timer);
412 owner_gain_timer = NULL;
413
414 if (pk_proxy) eldbus_proxy_unref(pk_proxy);
415 pk_proxy = NULL;
416 if (pk_obj) eldbus_object_unref(pk_obj);
417 pk_obj = NULL;
418
419 if (pk_proxy) eldbus_proxy_unref(pk_proxy);
420 pk_proxy = NULL;
421 if (pk_obj) eldbus_object_unref(pk_obj);
422 pk_obj = NULL;
423 if (ses_proxy2) eldbus_proxy_unref(ses_proxy2);
424 ses_proxy2 = NULL;
425 if (ses_proxy) eldbus_proxy_unref(ses_proxy);
426 ses_proxy = NULL;
427 if (ses_obj) eldbus_object_unref(ses_obj);
428 ses_obj = NULL;
429 if (ses_obj2) eldbus_object_unref(ses_obj2);
430 ses_obj2 = NULL;
431 agent_request = EINA_FALSE;
432 agent_ok = EINA_FALSE;
433 eina_stringshare_replace(&session_path, NULL);
434 eina_stringshare_replace(&session_id, NULL);
435 eina_stringshare_replace(&session_user, NULL);
436 session_uid = 0;
437 }
438}
439
440void
441e_mod_polkit_register(void)
442{
443 agent_request = EINA_FALSE;
444 agent_ok = EINA_FALSE;
445 pk_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
446 if (pk_conn)
447 {
448 eldbus_name_owner_changed_callback_add(pk_conn,
449 "org.freedesktop.PolicyKit1",
450 cb_name_owner_changed, NULL,
451 EINA_TRUE);
452 }
453}
454
455void
456e_mod_polkit_unregister(void)
457{
458 Eldbus_Message *msg;
459 Eldbus_Message_Iter *iter, *subj, *array, *dict, *vari;
460
461 if (!pk_conn) return;
462 eldbus_name_owner_changed_callback_del(pk_conn,
463 "org.freedesktop.PolicyKit1",
464 cb_name_owner_changed, NULL);
465 if (pend_call) eldbus_pending_cancel(pend_call);
466 pend_call = NULL;
467
468 if ((agent_request || agent_ok) && (session_id) && (pk_proxy))
469 {
470 msg = eldbus_proxy_method_call_new(pk_proxy,
471 "UnregisterAuthenticationAgent");
472 // (sa{sv})s
473 iter = eldbus_message_iter_get(msg);
474 eldbus_message_iter_arguments_append(iter, "(sa{sv})", &subj);
475 eldbus_message_iter_basic_append(subj, 's', "unix-session");
476 eldbus_message_iter_arguments_append(subj, "a{sv}", &array);
477 eldbus_message_iter_arguments_append(array, "{sv}", &dict);
478 eldbus_message_iter_basic_append(dict, 's', "session-id");
479 vari = eldbus_message_iter_container_new(dict, 'v', "s");
480 eldbus_message_iter_basic_append(vari, 's', session_id);
481 eldbus_message_iter_container_close(dict, vari);
482 eldbus_message_iter_container_close(array, dict);
483 eldbus_message_iter_container_close(subj, array);
484 eldbus_message_iter_container_close(iter, subj);
485 eldbus_message_iter_basic_append(iter, 's', "/org/enlightenment/polkit/Agent");
486 eldbus_proxy_send(pk_proxy, msg, NULL, NULL, -1);
487 }
488
489 session_shutdown();
490
491 if (agent_iface) eldbus_service_object_unregister(agent_iface);
492 agent_iface = NULL;
493 if (owner_gain_timer) ecore_timer_del(owner_gain_timer);
494 owner_gain_timer = NULL;
495
496 if (pk_proxy) eldbus_proxy_unref(pk_proxy);
497 pk_proxy = NULL;
498 if (pk_obj) eldbus_object_unref(pk_obj);
499 pk_obj = NULL;
500
501 if (pk_proxy) eldbus_proxy_unref(pk_proxy);
502 pk_proxy = NULL;
503 if (pk_obj) eldbus_object_unref(pk_obj);
504 pk_obj = NULL;
505 if (ses_proxy2) eldbus_proxy_unref(ses_proxy2);
506 ses_proxy2 = NULL;
507 if (ses_proxy) eldbus_proxy_unref(ses_proxy);
508 ses_proxy = NULL;
509 if (ses_obj) eldbus_object_unref(ses_obj);
510 ses_obj = NULL;
511 if (ses_obj2) eldbus_object_unref(ses_obj2);
512 ses_obj2 = NULL;
513
514 eldbus_connection_unref(pk_conn);
515 pk_conn = NULL;
516
517 agent_request = EINA_FALSE;
518 agent_ok = EINA_FALSE;
519 eina_stringshare_replace(&session_path, NULL);
520 eina_stringshare_replace(&session_id, NULL);
521 eina_stringshare_replace(&session_user, NULL);
522 session_uid = 0;
523}