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.devs/devilhorns/output
parent
c7d0d6e6c9
commit
5f4697fd7d
19 changed files with 1019 additions and 31 deletions
@ -0,0 +1,149 @@ |
||||
#include "e_mod_main.h" |
||||
|
||||
static Eina_Bool |
||||
_auth_cb_exit(void *data, int type EINA_UNUSED, void *event) |
||||
{ |
||||
Polkit_Session *ps = data; |
||||
Ecore_Exe_Event_Del *ev = event; |
||||
|
||||
if (ev->pid != ps->auth_pid) return ECORE_CALLBACK_PASS_ON; |
||||
ps->auth_pid = 0; |
||||
if (ps->exe_exit_handler) ecore_event_handler_del(ps->exe_exit_handler); |
||||
ps->exe_exit_handler = NULL; |
||||
session_reply(ps); |
||||
return ECORE_CALLBACK_PASS_ON; |
||||
} |
||||
|
||||
static void |
||||
_cb_del(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj, |
||||
void *event_info EINA_UNUSED) |
||||
{ |
||||
Polkit_Session *ps = evas_object_data_get(obj, "session"); |
||||
if (!ps) return; |
||||
if (ps->exe_exit_handler) |
||||
{ |
||||
ecore_event_handler_del(ps->exe_exit_handler); |
||||
ps->exe_exit_handler = NULL; |
||||
} |
||||
if (ps->win) |
||||
{ |
||||
ps->win = NULL; |
||||
session_reply(ps); |
||||
} |
||||
} |
||||
|
||||
static void |
||||
_cb_ok(void *data EINA_UNUSED, Evas_Object *obj, |
||||
void *event_info EINA_UNUSED) |
||||
{ |
||||
Polkit_Session *ps = evas_object_data_get(obj, "session"); |
||||
const char *str = elm_object_text_get(obj); |
||||
|
||||
if (!ps) return; |
||||
if (ps->exe_exit_handler) return; |
||||
ps->exe_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, |
||||
_auth_cb_exit, ps); |
||||
if (str) |
||||
{ |
||||
char *passwd = strdup(str); |
||||
if (passwd) |
||||
{ |
||||
ps->auth_pid = e_auth_polkit_begin(passwd, ps->cookie, ps->target_uid); |
||||
free(passwd); |
||||
return; |
||||
} |
||||
} |
||||
evas_object_del(ps->win); |
||||
} |
||||
|
||||
static void |
||||
_cb_cancel(void *data EINA_UNUSED, Evas_Object *obj, |
||||
void *event_info EINA_UNUSED) |
||||
{ |
||||
Polkit_Session *ps = evas_object_data_get(obj, "session"); |
||||
if (!ps) return; |
||||
if (ps->exe_exit_handler) return; |
||||
session_reply(ps); |
||||
} |
||||
|
||||
static void |
||||
_cb_button_ok(void *data, E_Dialog *dia EINA_UNUSED) |
||||
{ |
||||
_cb_ok(NULL, data, NULL); |
||||
} |
||||
|
||||
static void |
||||
_cb_button_cancel(void *data, E_Dialog *dia EINA_UNUSED) |
||||
{ |
||||
_cb_cancel(NULL, data, NULL); |
||||
} |
||||
|
||||
void |
||||
auth_ui(Polkit_Session *ps) |
||||
{ |
||||
E_Dialog *dia; |
||||
Evas_Object *o, *win, *box, *ent; |
||||
|
||||
dia = e_dialog_new(NULL, "E", "_polkit_auth"); |
||||
e_dialog_title_set(dia, _("Please enter password")); |
||||
|
||||
win = dia->win; |
||||
|
||||
if ((!ps->icon_name) || (!ps->icon_name[0])) |
||||
e_dialog_icon_set(dia, "enlightenment", 64); |
||||
else |
||||
e_dialog_icon_set(dia, ps->icon_name, 64); |
||||
|
||||
evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _cb_del, NULL); |
||||
elm_win_autodel_set(win, EINA_TRUE); |
||||
evas_object_data_set(win, "session", ps); |
||||
|
||||
box = o = elm_box_add(win); |
||||
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); |
||||
evas_object_size_hint_align_set(o, -1.0, -1.0); |
||||
elm_box_horizontal_set(o, EINA_FALSE); |
||||
e_dialog_content_set(dia, o, 0, 0); |
||||
evas_object_show(o); |
||||
|
||||
/* XXX: lookup action and display something useful for it in future.
|
||||
o = elm_label_add(win); |
||||
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); |
||||
evas_object_size_hint_align_set(o, 0.0, 0.0); |
||||
elm_object_text_set(o, ps->action); |
||||
elm_box_pack_end(box, o); |
||||
evas_object_show(o); |
||||
*/ |
||||
|
||||
o = elm_label_add(win); |
||||
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); |
||||
evas_object_size_hint_align_set(o, 0.0, 0.0); |
||||
elm_object_text_set(o, ps->message); |
||||
elm_box_pack_end(box, o); |
||||
evas_object_show(o); |
||||
|
||||
ent = o = elm_entry_add(win); |
||||
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); |
||||
evas_object_size_hint_align_set(o, -1.0, 1.0); |
||||
elm_entry_single_line_set(ent, EINA_TRUE); |
||||
elm_entry_scrollable_set(ent, EINA_TRUE); |
||||
elm_entry_password_set(ent, EINA_TRUE); |
||||
elm_object_part_text_set(ent, "elm.guide", "Enter Password"); |
||||
evas_object_data_set(ent, "session", ps); |
||||
evas_object_smart_callback_add(ent, "activated", _cb_ok, NULL); |
||||
evas_object_smart_callback_add(ent, "aborted", _cb_cancel, NULL); |
||||
elm_box_pack_end(box, o); |
||||
evas_object_show(o); |
||||
|
||||
e_dialog_button_add(dia, _("OK"), NULL, _cb_button_ok, ent); |
||||
e_dialog_button_add(dia, _("Cancel"), NULL, _cb_button_cancel, ent); |
||||
e_dialog_button_focus_num(dia, 0); |
||||
|
||||
elm_object_focus_set(ent, EINA_TRUE); |
||||
|
||||
ps->win = win; |
||||
ps->entry = ent; |
||||
|
||||
elm_win_center(win, 1, 1); |
||||
e_dialog_show(dia); |
||||
elm_win_activate(win); |
||||
} |
Binary file not shown.
@ -0,0 +1,17 @@ |
||||
#include "e_mod_main.h" |
||||
|
||||
E_API E_Module_Api e_modapi = {E_MODULE_API_VERSION, "Polkit"}; |
||||
|
||||
E_API void * |
||||
e_modapi_init(E_Module *m) |
||||
{ |
||||
e_mod_polkit_register(); |
||||
return m; |
||||
} |
||||
|
||||
E_API int |
||||
e_modapi_shutdown(E_Module *m EINA_UNUSED) |
||||
{ |
||||
e_mod_polkit_unregister(); |
||||
return 1; |
||||
} |
@ -0,0 +1,32 @@ |
||||
#ifndef E_MOD_MAIN_H |
||||
#define E_MOD_MAIN_H |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
#include "config.h" |
||||
#endif |
||||
|
||||
#include "e.h" |
||||
|
||||
typedef struct |
||||
{ |
||||
const char *cookie; |
||||
const char *message; |
||||
const char *icon_name; |
||||
const char *action; |
||||
unsigned int target_uid; |
||||
int auth_pid; |
||||
Ecore_Event_Handler *exe_exit_handler; |
||||
Eldbus_Message *reply; |
||||
Eldbus_Pending *pend_reply; |
||||
Evas_Object *win; |
||||
Evas_Object *entry; |
||||
} Polkit_Session; |
||||
|
||||
void session_reply(Polkit_Session *ps); |
||||
|
||||
void auth_ui(Polkit_Session *ps); |
||||
|
||||
void e_mod_polkit_register(void); |
||||
void e_mod_polkit_unregister(void); |
||||
|
||||
#endif |
@ -0,0 +1,6 @@ |
||||
src = files( |
||||
'e_mod_main.c', |
||||
'polkit.c', |
||||
'auth_ui.c', |
||||
'e_mod_main.h' |
||||
) |
@ -0,0 +1,6 @@ |
||||
[Desktop Entry] |
||||
Type=Link |
||||
Name=Polkit |
||||
Comment=This module provides a polkit authentication agent |
||||
Icon=e-module-polkit |
||||
X-Enlightenment-ModuleType=core |
@ -0,0 +1,523 @@ |
||||
#include "e_mod_main.h" |
||||
|
||||
static Eldbus_Connection *pk_conn = NULL; |
||||
static Eldbus_Service_Interface *agent_iface = NULL; |
||||
static Eldbus_Object *pk_obj = NULL; |
||||
static Eldbus_Proxy *pk_proxy = NULL; |
||||
|
||||
static Eldbus_Pending *pend_call = NULL; |
||||
|
||||
static Eldbus_Object *ses_obj = NULL; |
||||
static Eldbus_Object *ses_obj2 = NULL; |
||||
static Eldbus_Proxy *ses_proxy = NULL; |
||||
static Eldbus_Proxy *ses_proxy2 = NULL; |
||||
|
||||
static Eina_Bool agent_request = EINA_FALSE; |
||||
static Eina_Bool agent_ok = EINA_FALSE; |
||||
static const char *session_path = NULL; |
||||
static const char *session_id = NULL; |
||||
static unsigned int session_uid = 0; |
||||
static const char *session_user = NULL; |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Eina_Hash *sessions = NULL; |
||||
|
||||
static void |
||||
_session_free(Polkit_Session *ps) |
||||
{ |
||||
if (ps->reply) eldbus_connection_send(pk_conn, ps->reply, NULL, NULL, -1); |
||||
ps->reply = NULL; |
||||
if (ps->pend_reply) eldbus_pending_cancel(ps->pend_reply); |
||||
ps->pend_reply = NULL; |
||||
eina_stringshare_del(ps->cookie); |
||||
ps->cookie = NULL; |
||||
eina_stringshare_del(ps->message); |
||||
ps->message = NULL; |
||||
eina_stringshare_del(ps->icon_name); |
||||
ps->icon_name = NULL; |
||||
eina_stringshare_del(ps->action); |
||||
ps->action = NULL; |
||||
if (ps->win) |
||||
{ |
||||
Evas_Object *win = ps->win; |
||||
|
||||
ps->win = NULL; |
||||
evas_object_del(win); |
||||
} |
||||
free(ps); |
||||
} |
||||
|
||||
static void |
||||
session_init(void) |
||||
{ |
||||
if (sessions) return; |
||||
sessions = eina_hash_string_superfast_new((void *)_session_free); |
||||
} |
||||
|
||||
static void |
||||
session_shutdown(void) |
||||
{ |
||||
if (sessions) eina_hash_free(sessions); |
||||
sessions = NULL; |
||||
} |
||||
|
||||
static Polkit_Session * |
||||
session_new(void) |
||||
{ |
||||
return calloc(1, sizeof(Polkit_Session)); |
||||
} |
||||
|
||||
static void |
||||
session_free(Polkit_Session *ps) |
||||
{ |
||||
eina_hash_del(sessions, ps->cookie, ps); |
||||
} |
||||
|
||||
static void |
||||
session_register(Polkit_Session *ps) |
||||
{ |
||||
eina_hash_add(sessions, ps->cookie, ps); |
||||
} |
||||
|
||||
static Polkit_Session * |
||||
session_find(const char *cookie) |
||||
{ |
||||
return eina_hash_find(sessions, cookie); |
||||
} |
||||
|
||||
void |
||||
session_reply(Polkit_Session *ps) |
||||
{ |
||||
if (ps->reply) |
||||
{ |
||||
ps->pend_reply = eldbus_connection_send(pk_conn, ps->reply, NULL, NULL, -1); |
||||
ps->reply = NULL; |
||||
} |
||||
session_free(ps); |
||||
} |
||||
|
||||
void |
||||
session_show(Polkit_Session *ps) |
||||
{ |
||||
auth_ui(ps); |
||||
// display some auth dialog to enter a password, show ps->message
|
||||
// and ps->action specific ui ps->icon_name
|
||||
// when we get the password call
|
||||
// e_auth_polkit_begin(pass, ps->cookie, ps->target_uid);
|
||||
// when this returns call session_reply(ps);
|
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void |
||||
iterate_dict(void *data, const void *key, Eldbus_Message_Iter *var) |
||||
{ |
||||
Polkit_Session *ps = data; |
||||
const char *skey = key; |
||||
|
||||
if (!strcmp(skey, "uid")) |
||||
{ |
||||
unsigned int uid = 0; |
||||
|
||||
if (eldbus_message_iter_arguments_get(var, "u", &uid)) |
||||
ps->target_uid = uid; |
||||
} |
||||
} |
||||
|
||||
static Eldbus_Message * |
||||
cb_agent_begin_authentication(const Eldbus_Service_Interface *iface EINA_UNUSED, |
||||
const Eldbus_Message *msg) |
||||
{ |
||||
// sssa{ss}sa(sa{sv})
|
||||
const char *action_id = NULL, *message = NULL, *icon_name = NULL, |
||||
*cookie = NULL; |
||||
Eldbus_Message_Iter *details = NULL, *ident = NULL, *item = NULL; |
||||
Polkit_Session *ps, *ps2; |
||||
|
||||
ps = session_new(); |
||||
if (!ps) goto err; |
||||
ps->reply = eldbus_message_method_return_new(msg); |
||||
|
||||
if (!eldbus_message_arguments_get(msg, "sssa{ss}sa(sa{sv})", |
||||
&action_id, &message, &icon_name, |
||||
&details, &cookie, &ident)) |
||||
goto err; |
||||
ps->cookie = eina_stringshare_add(cookie); |
||||
ps->message = eina_stringshare_add(message); |
||||
ps->icon_name = eina_stringshare_add(icon_name); |
||||
ps->action = eina_stringshare_add(action_id); |
||||
// actions in: /usr/share/polkit-1/actions
|
||||
|
||||
/* XXX: Haven't seen details content yet - not sure what to do with it
|
||||
while (eldbus_message_iter_get_and_next(details, 'r', &item)) |
||||
{ |
||||
const char *v1, *v2; |
||||
|
||||
v1 = NULL; |
||||
v2 = NULL; |
||||
eldbus_message_iter_arguments_get(item, "ss", &v1, &v2); |
||||
} |
||||
*/ |
||||
while (eldbus_message_iter_get_and_next(ident, 'r', &item)) |
||||
{ |
||||
const char *v1; |
||||
Eldbus_Message_Iter *dict = NULL; |
||||
|
||||
v1 = NULL; |
||||
eldbus_message_iter_arguments_get(item, "sa{sv}", &v1, &dict); |
||||
if (!strcmp(v1, "unix-user")) |
||||
eldbus_message_iter_dict_iterate(dict, "sv", iterate_dict, ps); |
||||
else |
||||
{ |
||||
printf("PK: Unhandled ident type.\n"); |
||||
} |
||||
} |
||||
ps2 = session_find(ps->cookie); |
||||
if (ps2) session_free(ps2); |
||||
session_register(ps); |
||||
session_show(ps); |
||||
return NULL; |
||||
err: |
||||
return eldbus_message_method_return_new(msg); |
||||
} |
||||
|
||||
static Eldbus_Message * |
||||
cb_agent_cancel_authentication(const Eldbus_Service_Interface *iface EINA_UNUSED, |
||||
const Eldbus_Message *msg) |
||||
{ |
||||
const char *cookie; |
||||
Polkit_Session *ps; |
||||
|
||||
// s
|
||||
if (!eldbus_message_arguments_get(msg, "s", &cookie)) return NULL; |
||||
ps = session_find(cookie); |
||||
if (ps) session_free(ps); |
||||
return eldbus_message_method_return_new(msg); |
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void |
||||
cb_register(void *data EINA_UNUSED, const Eldbus_Message *msg, |
||||
Eldbus_Pending *pending EINA_UNUSED) |
||||
{ |
||||
const char *name, *text; |
||||
|
||||
pend_call = NULL; |
||||
if (eldbus_message_error_get(msg, &name, &text)) return; |
||||
agent_request = EINA_FALSE; |
||||
agent_ok = EINA_TRUE; |
||||
} |
||||
|
||||
static const Eldbus_Method agent_methods[] = { |
||||
{ "BeginAuthentication", |
||||
ELDBUS_ARGS({ "s", "action_id" }, |
||||
{ "s", "message" }, |
||||
{ "s", "icon_name" }, |
||||
{ "a{ss}", "details" }, |
||||
{ "s", "cookie" }, |
||||
{ "a(sa{sv})", "identities" }), |
||||
NULL, |
||||
cb_agent_begin_authentication, 0 |
||||
}, |
||||
{ "CancelAuthentication", |
||||
ELDBUS_ARGS({ "s", "cookie" }), |
||||
NULL, |
||||
cb_agent_cancel_authentication, 0 |
||||
}, |
||||
{ NULL, NULL, NULL, NULL, 0 } |
||||
}; |
||||
static const Eldbus_Service_Interface_Desc agent_desc = { |
||||
"org.freedesktop.PolicyKit1.AuthenticationAgent", agent_methods, NULL, NULL, NULL, NULL |
||||
}; |
||||
|
||||
static void |
||||
pk_agent_register(void) |
||||
{ |
||||
Eldbus_Message *msg; |
||||
Eldbus_Message_Iter *iter, *subj, *array, *dict, *vari; |
||||
const char *locale = NULL; |
||||
|
||||
agent_request = EINA_TRUE; |
||||
// set up agent interface
|
||||
agent_iface = eldbus_service_interface_register |
||||
(pk_conn, "/org/enlightenment/polkit/Agent", &agent_desc); |
||||
|
||||
// register agent interface with polkit
|
||||
if (!locale) locale = getenv("LC_MESSAGES"); |
||||
if (!locale) locale = getenv("LC_ALL"); |
||||
if (!locale) locale = getenv("LANG"); |
||||
if (!locale) locale = getenv("LANGUAGE"); |
||||
if (!locale) locale = "C"; |
||||
|
||||
pk_obj = eldbus_object_get(pk_conn, "org.freedesktop.PolicyKit1", |
||||
"/org/freedesktop/PolicyKit1/Authority"); |
||||
if (!pk_obj) return; |
||||
pk_proxy = eldbus_proxy_get(pk_obj, "org.freedesktop.PolicyKit1.Authority"); |
||||
if (!pk_proxy) return; |
||||
msg = eldbus_proxy_method_call_new(pk_proxy, "RegisterAuthenticationAgent"); |
||||
// (sa{sv})ss
|
||||
iter = eldbus_message_iter_get(msg); |
||||
eldbus_message_iter_arguments_append(iter, "(sa{sv})", &subj); |
||||
eldbus_message_iter_basic_append(subj, 's', "unix-session"); |
||||
eldbus_message_iter_arguments_append(subj, "a{sv}", &array); |
||||
eldbus_message_iter_arguments_append(array, "{sv}", &dict); |
||||
eldbus_message_iter_basic_append(dict, 's', "session-id"); |
||||
vari = eldbus_message_iter_container_new(dict, 'v', "s"); |
||||
eldbus_message_iter_basic_append(vari, 's', session_id); |
||||
eldbus_message_iter_container_close(dict, vari); |
||||
eldbus_message_iter_container_close(array, dict); |
||||
eldbus_message_iter_container_close(subj, array); |
||||
eldbus_message_iter_container_close(iter, subj); |
||||
|
||||
eldbus_message_iter_basic_append(iter, 's', locale); |
||||
eldbus_message_iter_basic_append(iter, 's', "/org/enlightenment/polkit/Agent"); |
||||
pend_call = eldbus_proxy_send(pk_proxy, msg, cb_register, NULL, -1); |
||||
} |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void |
||||
cb_login_prop_entry(void *data EINA_UNUSED, const void *key, Eldbus_Message_Iter *var) |
||||
{ |
||||
const char *skey = key; |
||||
|
||||
if (!strcmp(skey, "Id")) |
||||
{ |
||||
const char *val = NULL; |
||||
if (eldbus_message_iter_arguments_get(var, "s", &val)) |
||||
eina_stringshare_replace(&session_id, val); |
||||
} |
||||
else if (!strcmp(skey, "User")) |
||||
{ |
||||
Eldbus_Message_Iter *iter = NULL; |
||||
|
||||
eldbus_message_iter_arguments_get(var, "(uo)", &iter); |
||||
if (iter) |
||||
{ |
||||
unsigned int uid = 0; |
||||
const char *val = NULL; |
||||
|
||||
if (eldbus_message_iter_arguments_get(iter, "uo", &uid, &val)) |
||||
{ |
||||
session_uid = uid; |
||||
eina_stringshare_replace(&session_user, val); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void |
||||
cb_login_prop(void *data EINA_UNUSED, const Eldbus_Message *msg, |
||||
Eldbus_Pending *pending EINA_UNUSED) |
||||
{ |
||||
Eldbus_Message_Iter *array; |
||||
|
||||
pend_call = NULL; |
||||
if (eldbus_message_error_get(msg, NULL, NULL)) return; |
||||
if (eldbus_message_arguments_get(msg, "a{sv}", &array)) |
||||
{ |
||||
eldbus_message_iter_dict_iterate(array, "sv", |
||||
cb_login_prop_entry, NULL); |
||||
if ((session_id) && (session_user) && (session_path)) |
||||
pk_agent_register(); |
||||
} |
||||
if (ses_proxy2) eldbus_proxy_unref(ses_proxy2); |
||||
ses_proxy2 = NULL; |
||||
if (ses_proxy) eldbus_proxy_unref(ses_proxy); |
||||
ses_proxy = NULL; |
||||
if (ses_obj) eldbus_object_unref(ses_obj); |
||||
ses_obj = NULL; |
||||
if (ses_obj2) eldbus_object_unref(ses_obj2); |
||||
ses_obj2 = NULL; |
||||
} |
||||
|
||||
static void |
||||
cb_login_session(void *data EINA_UNUSED, const Eldbus_Message *msg, |
||||
Eldbus_Pending *pending EINA_UNUSED) |
||||
{ |
||||
const char *name, *text; |
||||
const char *s; |
||||
|
||||
pend_call = NULL; |
||||
if (eldbus_message_error_get(msg, &name, &text)) return; |
||||
if (!eldbus_message_arguments_get(msg, "o", &s)) return; |
||||
eina_stringshare_replace(&session_path, s); |
||||
ses_obj2 = eldbus_object_get(pk_conn, "org.freedesktop.login1", s); |
||||
if (!ses_obj2) return; |
||||
ses_proxy2 = eldbus_proxy_get(ses_obj2, "org.freedesktop.login1.Session"); |
||||
if (!ses_proxy2) return; |
||||
pend_call = eldbus_proxy_property_get_all(ses_proxy2, cb_login_prop, NULL); |
||||
} |
||||
|
||||
static void |
||||
pk_session_init(void) |
||||
{ |
||||
ses_obj = eldbus_object_get(pk_conn, "org.freedesktop.login1", |
||||
"/org/freedesktop/login1"); |
||||
if (!ses_obj) return; |
||||
ses_proxy = eldbus_proxy_get(ses_obj, "org.freedesktop.login1.Manager"); |
||||
if (!ses_proxy) return; |
||||
pend_call = eldbus_proxy_call(ses_proxy, "GetSessionByPID", |
||||
cb_login_session, NULL, -1, |
||||
"u", (unsigned int)getpid()); |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Ecore_Timer *owner_gain_timer = NULL; |
||||
|
||||
static Eina_Bool |
||||
cb_name_owner_new(void *data EINA_UNUSED) |
||||
{ |
||||
owner_gain_timer = NULL; |
||||
pk_session_init(); |
||||
session_init(); |
||||
return EINA_FALSE; |
||||
} |
||||
|
||||
static void |
||||
cb_name_owner_changed(void *data EINA_UNUSED, |
||||
const char *bus EINA_UNUSED, |
||||
const char *from EINA_UNUSED, |
||||
const char *to) |
||||
{ |
||||
static Eina_Bool first = EINA_TRUE; |
||||
|
||||
if (to[0]) |
||||
{ |
||||
if (owner_gain_timer) ecore_timer_del(owner_gain_timer); |
||||
// on first start try and re-init quickly because we get a name
|
||||
// owner change even if all is good when we register to listen for it,
|
||||
// so start fast
|
||||
if (first) |
||||
owner_gain_timer = ecore_timer_add(0.1, cb_name_owner_new, NULL); |
||||
// but if we gegt a name owner change later it's probably because
|
||||
// bluez was restarted or crashed. a new bz daemon will (or should)
|
||||
// come up. so re-init more slowly here giving the daemon some time
|
||||
// to come up before pestering it.
|
||||
else |
||||
owner_gain_timer = ecore_timer_add(1.0, cb_name_owner_new, NULL); |
||||
first = EINA_FALSE; |
||||
} |
||||
else |
||||
{ |
||||
session_shutdown(); |
||||
if (pend_call) eldbus_pending_cancel(pend_call); |
||||
pend_call = NULL; |
||||
if (agent_iface) eldbus_service_object_unregister(agent_iface); |
||||
agent_iface = NULL; |
||||
if (owner_gain_timer) ecore_timer_del(owner_gain_timer); |
||||
owner_gain_timer = NULL; |
||||
|
||||
if (pk_proxy) eldbus_proxy_unref(pk_proxy); |
||||
pk_proxy = NULL; |
||||
if (pk_obj) eldbus_object_unref(pk_obj); |
||||
pk_obj = NULL; |
||||
|
||||
if (pk_proxy) eldbus_proxy_unref(pk_proxy); |
||||
pk_proxy = NULL; |
||||
if (pk_obj) eldbus_object_unref(pk_obj); |
||||
pk_obj = NULL; |
||||
if (ses_proxy2) eldbus_proxy_unref(ses_proxy2); |
||||
ses_proxy2 = NULL; |
||||
if (ses_proxy) eldbus_proxy_unref(ses_proxy); |
||||
ses_proxy = NULL; |
||||
if (ses_obj) eldbus_object_unref(ses_obj); |
||||
ses_obj = NULL; |
||||
if (ses_obj2) eldbus_object_unref(ses_obj2); |
||||
ses_obj2 = NULL; |
||||
agent_request = EINA_FALSE; |
||||
agent_ok = EINA_FALSE; |
||||
eina_stringshare_replace(&session_path, NULL); |
||||
eina_stringshare_replace(&session_id, NULL); |
||||
eina_stringshare_replace(&session_user, NULL); |
||||
session_uid = 0; |
||||
} |
||||
} |
||||
|
||||
void |
||||
e_mod_polkit_register(void) |
||||
{ |
||||
agent_request = EINA_FALSE; |
||||
agent_ok = EINA_FALSE; |
||||
pk_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM); |
||||
if (pk_conn) |
||||
{ |
||||
eldbus_name_owner_changed_callback_add(pk_conn, |
||||
"org.freedesktop.PolicyKit1", |
||||
cb_name_owner_changed, NULL, |
||||
EINA_TRUE); |
||||
} |
||||
} |
||||
|
||||
void |
||||
e_mod_polkit_unregister(void) |
||||
{ |
||||
Eldbus_Message *msg; |
||||
Eldbus_Message_Iter *iter, *subj, *array, *dict, *vari; |
||||
|
||||
if (!pk_conn) return; |
||||
eldbus_name_owner_changed_callback_del(pk_conn, |
||||
"org.freedesktop.PolicyKit1", |
||||
cb_name_owner_changed, NULL); |
||||
if (pend_call) eldbus_pending_cancel(pend_call); |
||||
pend_call = NULL; |
||||
|
||||
if ((agent_request || agent_ok) && (session_id) && (pk_proxy)) |
||||
{ |
||||
msg = eldbus_proxy_method_call_new(pk_proxy, |
||||
"UnregisterAuthenticationAgent"); |
||||
// (sa{sv})s
|
||||
iter = eldbus_message_iter_get(msg); |
||||
eldbus_message_iter_arguments_append(iter, "(sa{sv})", &subj); |
||||
eldbus_message_iter_basic_append(subj, 's', "unix-session"); |
||||
eldbus_message_iter_arguments_append(subj, "a{sv}", &array); |
||||
eldbus_message_iter_arguments_append(array, "{sv}", &dict); |
||||
eldbus_message_iter_basic_append(dict, 's', "session-id"); |
||||
vari = eldbus_message_iter_container_new(dict, 'v', "s"); |
||||
eldbus_message_iter_basic_append(vari, 's', session_id); |
||||
eldbus_message_iter_container_close(dict, vari); |
||||
eldbus_message_iter_container_close(array, dict); |
||||
eldbus_message_iter_container_close(subj, array); |
||||
eldbus_message_iter_container_close(iter, subj); |
||||
eldbus_message_iter_basic_append(iter, 's', "/org/enlightenment/polkit/Agent"); |
||||
eldbus_proxy_send(pk_proxy, msg, NULL, NULL, -1); |
||||
} |
||||
|
||||
session_shutdown(); |
||||
|
||||
if (agent_iface) eldbus_service_object_unregister(agent_iface); |
||||
agent_iface = NULL; |
||||
if (owner_gain_timer) ecore_timer_del(owner_gain_timer); |
||||
owner_gain_timer = NULL; |
||||
|
||||
if (pk_proxy) eldbus_proxy_unref(pk_proxy); |
||||
pk_proxy = NULL; |
||||
if (pk_obj) eldbus_object_unref(pk_obj); |
||||
pk_obj = NULL; |
||||
|
||||
if (pk_proxy) eldbus_proxy_unref(pk_proxy); |
||||
pk_proxy = NULL; |
||||
if (pk_obj) eldbus_object_unref(pk_obj); |
||||
pk_obj = NULL; |
||||
if (ses_proxy2) eldbus_proxy_unref(ses_proxy2); |
||||
ses_proxy2 = NULL; |
||||
if (ses_proxy) eldbus_proxy_unref(ses_proxy); |
||||
ses_proxy = NULL; |
||||
if (ses_obj) eldbus_object_unref(ses_obj); |
||||
ses_obj = NULL; |
||||
if (ses_obj2) eldbus_object_unref(ses_obj2); |
||||
ses_obj2 = NULL; |
||||
|
||||
eldbus_connection_unref(pk_conn); |
||||
pk_conn = NULL; |
||||
|
||||
agent_request = EINA_FALSE; |
||||
agent_ok = EINA_FALSE; |
||||
eina_stringshare_replace(&session_path, NULL); |
||||
eina_stringshare_replace(&session_id, NULL); |
||||
eina_stringshare_replace(&session_user, NULL); |
||||
session_uid = 0; |
||||
} |
Loading…
Reference in new issue