#include "e.h" E_API int E_EVENT_AUTH_FPRINT_AVAILABLE = 0; E_API int E_EVENT_AUTH_FPRINT_STATUS = 0; static Eldbus_Connection *conn = NULL; ///////////////////////////////////////////////////////////////////////////// EINTERN int e_auth_init(void) { E_EVENT_AUTH_FPRINT_AVAILABLE = ecore_event_type_new(); E_EVENT_AUTH_FPRINT_STATUS = ecore_event_type_new(); conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM); return 1; } EINTERN int e_auth_shutdown(void) { if (conn) eldbus_connection_unref(conn); conn = NULL; return 1; } ///////////////////////////////////////////////////////////////////////////// E_API int e_auth_begin(char *passwd) { char buf[PATH_MAX]; Ecore_Exe *exe = NULL; int ret = 0; size_t pwlen, buflen = 0; pwlen = strlen(passwd); snprintf(buf, sizeof(buf), "%s/enlightenment/utils/enlightenment_ckpasswd pw", e_prefix_lib_get()); exe = ecore_exe_pipe_run(buf, ECORE_EXE_PIPE_WRITE, NULL); if (!exe) goto out; snprintf(buf, sizeof(buf), "pw %s", passwd); buflen = strlen(buf); if (ecore_exe_send(exe, buf, buflen) != EINA_TRUE) goto out; ecore_exe_close_stdin(exe); ret = ecore_exe_pid_get(exe); if (ret == -1) { ret = 0; goto out; } exe = NULL; out: if (exe) ecore_exe_free(exe); e_util_memclear(passwd, pwlen); e_util_memclear(buf, buflen); return ret; } E_API int e_auth_polkit_begin(char *passwd, const char *cookie, unsigned int uid) { char buf[PATH_MAX]; Ecore_Exe *exe = NULL; int ret = 0; size_t pwlen, buflen = 0; pwlen = strlen(passwd); snprintf(buf, sizeof(buf), "%s/enlightenment/utils/enlightenment_ckpasswd pk", e_prefix_lib_get()); exe = ecore_exe_pipe_run(buf, ECORE_EXE_PIPE_WRITE, NULL); if (!exe) goto out; snprintf(buf, sizeof(buf), "%s %u %s", cookie, uid, passwd); buflen = strlen(buf); if (ecore_exe_send(exe, buf, buflen) != EINA_TRUE) goto out; ecore_exe_close_stdin(exe); ret = ecore_exe_pid_get(exe); if (ret == -1) { ret = 0; goto out; } exe = NULL; out: if (exe) ecore_exe_free(exe); e_util_memclear(passwd, pwlen); e_util_memclear(buf, buflen); return ret; } ///////////////////////////////////////////////////////////////////////////// static Eldbus_Object *obj_fprint = NULL; static Eldbus_Proxy *proxy_fprint = NULL; static Eldbus_Object *obj_fprint_device = NULL; static Eldbus_Proxy *proxy_fprint_device = NULL; static E_Auth_Fprint_Type finger_type = E_AUTH_FPRINT_TYPE_UNKNOWN; static const char *finger_name = NULL; static const char *user_name = NULL; static void _cb_event_free(void *data EINA_UNUSED, void *event) { free(event); } static void _cb_verify_start(void *data EINA_UNUSED, const Eldbus_Message *m, Eldbus_Pending *p EINA_UNUSED) { const char *name = NULL, *text = NULL; printf("FP: verify start...\n"); if (eldbus_message_error_get(m, &name, &text)) { fprintf(stderr, "FP: Fprint err: %s %s\n", name, text); return; } } static void _cb_verify_stop(void *data EINA_UNUSED, const Eldbus_Message *m EINA_UNUSED, Eldbus_Pending *p EINA_UNUSED) { Eldbus_Message *m2; Eldbus_Message_Iter *iter; printf("FP: verify stop.... finger_name=%s\n", finger_name ? finger_name : "NULL"); if (!finger_name) finger_name = eina_stringshare_add("right-index-finger"); m2 = eldbus_proxy_method_call_new(proxy_fprint_device, "VerifyStart"); if (m2) { iter = eldbus_message_iter_get(m2); eldbus_message_iter_basic_append(iter, 's', "any"); eldbus_proxy_send(proxy_fprint_device, m2, _cb_verify_start, NULL, -1); } } static void _verify_begin(void) { Eldbus_Message *m2; printf("FP: verify begin...\n"); m2 = eldbus_proxy_method_call_new(proxy_fprint_device, "VerifyStop"); if (m2) { eldbus_proxy_send(proxy_fprint_device, m2, _cb_verify_stop, NULL, -1); } } static void _cb_verify(void *data EINA_UNUSED, const Eldbus_Message *m) { Eina_Bool val = EINA_FALSE; const char *txt = NULL; const char *name = NULL, *text = NULL; E_Event_Auth_Fprint_Status *ev; printf("FP: verify ...\n"); if (eldbus_message_error_get(m, &name, &text)) { fprintf(stderr, "FP: Fprint err: %s %s\n", name, text); return; } if (!eldbus_message_arguments_get(m, "sb", &txt, &val)) return; printf("FP: verify = [%s] %i\n", txt, val); if (!txt) return; ev = calloc(1, sizeof(E_Event_Auth_Fprint_Status)); if (!ev) return; if (!strcmp(txt, "verify-match")) ev->status = E_AUTH_FPRINT_STATUS_AUTH; else if (!strcmp(txt, "verify-no-match")) ev->status = E_AUTH_FPRINT_STATUS_NO_AUTH; else if (!strcmp(txt, "verify-swipe-too-short")) ev->status = E_AUTH_FPRINT_STATUS_SHORT_SWIPE; else if (!strcmp(txt, "verify-finger-not-centered")) ev->status = E_AUTH_FPRINT_STATUS_NO_CENTER; else if (!strcmp(txt, "verify-remove-and-retry")) ev->status = E_AUTH_FPRINT_STATUS_REMOVE_RETRY; else if (!strcmp(txt, "verify-retry-scan")) ev->status = E_AUTH_FPRINT_STATUS_RETRY; else if (!strcmp(txt, "verify-disconnected")) ev->status = E_AUTH_FPRINT_STATUS_DISCONNECT; else if (!strcmp(txt, "verify-unknown-error")) ev->status = E_AUTH_FPRINT_STATUS_ERROR; else ev->status = E_AUTH_FPRINT_STATUS_ERROR; ecore_event_add(E_EVENT_AUTH_FPRINT_STATUS, ev, _cb_event_free, NULL); // reset the verify and try again if verify end and NOT an auth ok if ((val) && // end of verify (ev->status != E_AUTH_FPRINT_STATUS_AUTH)) { _verify_begin(); } if (ev->status == E_AUTH_FPRINT_STATUS_AUTH) { Eldbus_Message *m2; m2 = eldbus_proxy_method_call_new(proxy_fprint_device, "Release"); eldbus_proxy_send(proxy_fprint_device, m2, NULL, NULL, -1); } } static void _cb_list_enrolled_fingers(void *data EINA_UNUSED, const Eldbus_Message *m, Eldbus_Pending *p EINA_UNUSED) { Eldbus_Message_Iter *array = NULL; const char *name = NULL, *text = NULL; printf("FP: list fingers...\n"); if (eldbus_message_error_get(m, &name, &text)) { fprintf(stderr, "FP: Fprint err: %s %s\n", name, text); return; } printf("FP: list fingers...\n"); if (eldbus_message_arguments_get(m, "as", &array)) { char *txt = NULL; printf("FP: ...\n"); while (eldbus_message_iter_get_and_next(array, 's', &txt)) { eina_stringshare_replace(&finger_name, txt); printf("FP: first finger is [%s]\n", txt); if (finger_type != E_AUTH_FPRINT_TYPE_UNKNOWN) { E_Event_Auth_Fprint_Available *ev = calloc(1, sizeof(E_Event_Auth_Fprint_Available)); if (ev) { ev->type = finger_type; ecore_event_add(E_EVENT_AUTH_FPRINT_AVAILABLE, ev, _cb_event_free, NULL); } } _verify_begin(); break; } // call VeriftyStart 'first finger found' } } static void _cb_claim(void *data EINA_UNUSED, const Eldbus_Message *m EINA_UNUSED, Eldbus_Pending *p EINA_UNUSED) { Eldbus_Proxy *proxy = proxy_fprint_device; Eldbus_Message *m2; Eldbus_Message_Iter *iter; const char *name = NULL, *text = NULL; printf("FP: claim\n"); if (eldbus_message_error_get(m, &name, &text)) { fprintf(stderr, "FP: Fprint err: %s %s\n", name, text); return; } // ListEnrolledFingrs '$USER' -> "as" printf("FP: claim ok\n"); m2 = eldbus_proxy_method_call_new(proxy, "ListEnrolledFingers"); iter = eldbus_message_iter_get(m2); eldbus_message_iter_basic_append(iter, 's', user_name); eldbus_proxy_send(proxy, m2, _cb_list_enrolled_fingers, NULL, -1); } static void _cb_prop_entry(void *data EINA_UNUSED, const void *key, Eldbus_Message_Iter *var) { const char *skey = key; if (!strcmp(skey, "scan-type")) { const char *val = NULL; if (eldbus_message_iter_arguments_get(var, "s", &val)) { if (!strcmp(val, "press")) finger_type = E_AUTH_FPRINT_TYPE_PRESS; else if (!strcmp(val, "swipe")) finger_type = E_AUTH_FPRINT_TYPE_SWIPE; printf("FP: type = %s\n", val); if (finger_name) { E_Event_Auth_Fprint_Available *ev = calloc(1, sizeof(E_Event_Auth_Fprint_Available)); if (ev) { ev->type = finger_type; ecore_event_add(E_EVENT_AUTH_FPRINT_AVAILABLE, ev, _cb_event_free, NULL); } } } } } static void _cb_props(void *data EINA_UNUSED, const Eldbus_Message *m, Eldbus_Pending *pending EINA_UNUSED) { Eldbus_Message_Iter *array = NULL; if (eldbus_message_error_get(m, NULL, NULL)) return; if (eldbus_message_arguments_get(m, "a{sv}", &array)) eldbus_message_iter_dict_iterate(array, "sv", _cb_prop_entry, NULL); } static void _cb_get_default_device(void *data EINA_UNUSED, const Eldbus_Message *m, Eldbus_Pending *p EINA_UNUSED) { Eldbus_Object *obj; Eldbus_Proxy *proxy; const char *dev = NULL; const char *name = NULL, *text = NULL; printf("FP: get default device...\n"); if (eldbus_message_error_get(m, &name, &text)) { fprintf(stderr, "FP: Fprint err: %s %s\n", name, text); return; } if (!eldbus_message_arguments_get(m, "o", &dev)) return; printf("FP: dev = %s\n", dev); obj = eldbus_object_get(conn, "net.reactivated.Fprint", dev); if (obj) { obj_fprint_device = obj; printf("FP: 22 obj = %p\n", obj); proxy = eldbus_proxy_get(obj, "net.reactivated.Fprint.Device"); if (proxy) { Eldbus_Message *m2; Eldbus_Message_Iter *iter; printf("FP: 22 proxy = %p\n", proxy); proxy_fprint_device = proxy; eldbus_proxy_property_get_all(proxy, _cb_props, NULL); eldbus_proxy_signal_handler_add(proxy, "VerifyStatus", _cb_verify, NULL); // Claim '$USER' m2 = eldbus_proxy_method_call_new(proxy, "Claim"); iter = eldbus_message_iter_get(m2); eldbus_message_iter_basic_append(iter, 's', user_name); eldbus_proxy_send(proxy, m2, _cb_claim, NULL, -1); } } } E_API void e_auth_fprint_begin(const char *user) { Eldbus_Object *obj; Eldbus_Proxy *proxy; printf("FP: e_auth_fprint_begin\n"); if (conn) { eina_stringshare_replace(&user_name, user); obj = eldbus_object_get(conn, "net.reactivated.Fprint", "/net/reactivated/Fprint/Manager"); printf("FP: obj=%p\n", obj); if (obj) { obj_fprint = obj; proxy = eldbus_proxy_get(obj, "net.reactivated.Fprint.Manager"); printf("FP: proxy=%p\n", proxy); if (proxy) { Eldbus_Message *m; proxy_fprint = proxy; m = eldbus_proxy_method_call_new(proxy, "GetDefaultDevice"); eldbus_proxy_send(proxy, m, _cb_get_default_device, NULL, -1); } } } } E_API void e_auth_fprint_end(void) { if (conn) { if (obj_fprint_device) { Eldbus_Message *m2; m2 = eldbus_proxy_method_call_new(proxy_fprint_device, "Release"); eldbus_proxy_send(proxy_fprint_device, m2, NULL, NULL, -1); if (proxy_fprint_device) { eldbus_proxy_unref(proxy_fprint_device); proxy_fprint_device = NULL; } eldbus_object_unref(obj_fprint_device); obj_fprint_device = NULL; } if (obj_fprint) { if (proxy_fprint) { eldbus_proxy_unref(proxy_fprint); proxy_fprint = NULL; } eldbus_object_unref(obj_fprint); obj_fprint = NULL; } } eina_stringshare_replace(&finger_name, NULL); eina_stringshare_replace(&user_name, NULL); finger_type = E_AUTH_FPRINT_TYPE_UNKNOWN; }