raster pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=1cf55952084b6b47c1a2bda2a3791614965f52f8

commit 1cf55952084b6b47c1a2bda2a3791614965f52f8
Author: Carsten Haitzler <ras...@rasterman.com>
Date:   Fri Jul 2 13:26:05 2021 +0100

    auth and desklock - support auth by fingerprint and show status
---
 src/bin/e_auth.c            | 339 ++++++++++++++++++++++++++++++++++++++++++++
 src/bin/e_auth.h            |  38 +++++
 src/bin/e_main.c            |   5 +
 src/bin/e_utils.c           |   9 ++
 src/bin/e_utils.h           |   2 +
 src/modules/lokker/lokker.c |  64 +++++++++
 6 files changed, 457 insertions(+)

diff --git a/src/bin/e_auth.c b/src/bin/e_auth.c
index 0ab534511..e18a868f4 100644
--- a/src/bin/e_auth.c
+++ b/src/bin/e_auth.c
@@ -1,5 +1,32 @@
 #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)
 {
@@ -72,3 +99,315 @@ out:
    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, "Fprint err: %s %s\n", name, text);
+        return;
+     }
+}
+
+static void
+_verify_begin(void)
+{
+   Eldbus_Message *m2;
+   Eldbus_Message_Iter *iter;
+
+   // brute force stop a previous verify - if its active - dont care about 
reply
+   m2 = eldbus_proxy_method_call_new(proxy_fprint_device, "VerifyStop");
+   if (m2)
+     {
+        eldbus_proxy_send(proxy_fprint_device, m2, NULL, NULL, -1);
+     }
+   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', finger_name);
+        eldbus_proxy_send(proxy_fprint_device, m2, _cb_verify_start, 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, "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, "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, "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, "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;
+}
diff --git a/src/bin/e_auth.h b/src/bin/e_auth.h
index 8728f2900..85ec13816 100644
--- a/src/bin/e_auth.h
+++ b/src/bin/e_auth.h
@@ -1,6 +1,41 @@
 #ifndef E_AUTH_H
 #define E_AUTH_H
 
+typedef enum _E_Auth_Fprint_Type
+{
+   E_AUTH_FPRINT_TYPE_UNKNOWN,
+   E_AUTH_FPRINT_TYPE_PRESS,
+   E_AUTH_FPRINT_TYPE_SWIPE
+} E_Auth_Fprint_Type;
+
+typedef enum _E_Auth_Fprint_Status
+{
+   E_AUTH_FPRINT_STATUS_AUTH,
+   E_AUTH_FPRINT_STATUS_NO_AUTH,
+   E_AUTH_FPRINT_STATUS_SHORT_SWIPE,
+   E_AUTH_FPRINT_STATUS_NO_CENTER,
+   E_AUTH_FPRINT_STATUS_REMOVE_RETRY,
+   E_AUTH_FPRINT_STATUS_RETRY,
+   E_AUTH_FPRINT_STATUS_DISCONNECT,
+   E_AUTH_FPRINT_STATUS_ERROR
+} E_Auth_Fprint_Status;
+
+typedef struct _E_Event_Auth_Fprint_Available
+{
+   E_Auth_Fprint_Type type;
+} E_Event_Auth_Fprint_Available;
+
+typedef struct _E_Event_Auth_Fprint_Status
+{
+   E_Auth_Fprint_Status status;
+} E_Event_Auth_Fprint_Status;
+
+extern E_API int E_EVENT_AUTH_FPRINT_AVAILABLE;
+extern E_API int E_EVENT_AUTH_FPRINT_STATUS;
+
+EINTERN int e_auth_init(void);
+EINTERN int e_auth_shutdown(void);
+
 E_API int e_auth_begin(char *passwd);
 E_API int e_auth_polkit_begin(char *passwd, const char *cookie, unsigned int 
uid);
 
@@ -17,4 +52,7 @@ e_auth_hash_djb2(const char *key, int len)
    return (int)hash_num;
 }
 
+E_API void e_auth_fprint_begin(const char *user);
+E_API void e_auth_fprint_end(void);
+
 #endif
diff --git a/src/bin/e_main.c b/src/bin/e_main.c
index a4a12fbaa..68ed3507a 100644
--- a/src/bin/e_main.c
+++ b/src/bin/e_main.c
@@ -859,6 +859,11 @@ main(int argc, char **argv)
    TS("E_Acpi Init Done");
    _e_main_shutdown_push(e_acpi_shutdown);
 
+   TS("E_Auth Init");
+   e_auth_init();
+   TS("E_Auth Init Done");
+   _e_main_shutdown_push(e_auth_shutdown);
+
    TS("E_Backlight Init");
    if (!e_backlight_init())
      {
diff --git a/src/bin/e_utils.c b/src/bin/e_utils.c
index 49716ebdd..637579fc9 100644
--- a/src/bin/e_utils.c
+++ b/src/bin/e_utils.c
@@ -1557,3 +1557,12 @@ e_util_key_geometry_action_get(const char *key, int *x, 
int *y, int dx, int dy)
 
    return E_UTIL_ACTION_DO;
 }
+
+E_API const char *
+e_username_get(void)
+{
+   struct passwd *pw = getpwuid(getuid());
+
+   if (pw) return pw->pw_name;
+   return "";
+}
diff --git a/src/bin/e_utils.h b/src/bin/e_utils.h
index eac3cfb6d..8884ede03 100644
--- a/src/bin/e_utils.h
+++ b/src/bin/e_utils.h
@@ -70,6 +70,8 @@ E_API Ecore_Exe *e_util_open(const char *exe, void *data);
 
 E_API Ecore_Exe *e_util_exe_safe_run(const char *cmd, void *data);
 
+E_API const char *e_username_get(void);
+
 typedef enum
 {
    E_UTIL_ACTION_NONE,
diff --git a/src/modules/lokker/lokker.c b/src/modules/lokker/lokker.c
index 36dc77597..c864810cd 100644
--- a/src/modules/lokker/lokker.c
+++ b/src/modules/lokker/lokker.c
@@ -741,6 +741,64 @@ _lokker_check_auth(void)
    return 0;
 }
 
+static Eina_Bool
+_lokker_cb_fprint_available(void *data EINA_UNUSED,
+                            int type EINA_UNUSED,
+                            void *event)
+{
+   E_Event_Auth_Fprint_Available *ev = event;
+   Lokker_Popup *lp;
+   Eina_List *l;
+   const char *sig = "";
+
+   if (!edd) return ECORE_CALLBACK_PASS_ON;
+
+   if      (ev->type == E_AUTH_FPRINT_TYPE_UNKNOWN) sig = "e,fprint,unknown";
+   else if (ev->type == E_AUTH_FPRINT_TYPE_PRESS) sig = "e,fprint,press";
+   else if (ev->type == E_AUTH_FPRINT_TYPE_SWIPE) sig = "e,fprint,swipe";
+   EINA_LIST_FOREACH(edd->elock_wnd_list, l, lp)
+     {
+        if (lp->login_box) edje_object_signal_emit(lp->login_box, sig, "e");
+        if (lp->bg_object) edje_object_signal_emit(lp->bg_object, sig, "e");
+     }
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_lokker_cb_fprint_status(void *data EINA_UNUSED,
+                         int type EINA_UNUSED,
+                         void *event)
+{
+   E_Event_Auth_Fprint_Status *ev = event;
+   Lokker_Popup *lp;
+   Eina_List *l;
+   const char *sig = "";
+
+   if (!edd) return ECORE_CALLBACK_PASS_ON;
+
+   if      (ev->status == E_AUTH_FPRINT_STATUS_AUTH) sig = 
"e,fprint,auth,succeed";
+   else if (ev->status == E_AUTH_FPRINT_STATUS_NO_AUTH) sig = 
"e,fprint,auth,fail";
+   else if (ev->status == E_AUTH_FPRINT_STATUS_SHORT_SWIPE) sig = 
"e,fprint,auth,short";
+   else if (ev->status == E_AUTH_FPRINT_STATUS_NO_CENTER) sig = 
"e,fprint,auth,nocenter";
+   else if (ev->status == E_AUTH_FPRINT_STATUS_REMOVE_RETRY) sig = 
"e,fprint,auth,removeretry";
+   else if (ev->status == E_AUTH_FPRINT_STATUS_RETRY) sig = 
"e,fprint,auth,retry";
+   else if (ev->status == E_AUTH_FPRINT_STATUS_DISCONNECT) sig = 
"e,fprint,auth,disconnect";
+   else if (ev->status == E_AUTH_FPRINT_STATUS_ERROR) sig = 
"e,fprint,auth,error";
+
+   EINA_LIST_FOREACH(edd->elock_wnd_list, l, lp)
+     {
+        if (lp->login_box) edje_object_signal_emit(lp->login_box, sig, "e");
+        if (lp->bg_object) edje_object_signal_emit(lp->bg_object, sig, "e");
+     }
+   if (ev->status == E_AUTH_FPRINT_STATUS_AUTH)
+     {
+        /* security - null out passwd string once we are done with it */
+        _lokker_null();
+        e_desklock_hide();
+     }
+   return ECORE_CALLBACK_PASS_ON;
+}
+
 EINTERN Eina_Bool
 lokker_key_up(Ecore_Event_Key *ev)
 {
@@ -875,12 +933,18 @@ lokker_lock(void)
      edd->move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, 
_lokker_cb_mouse_move, NULL);
 
    _text_passwd_update();
+
+   e_auth_fprint_begin(e_username_get());
+   E_LIST_HANDLER_APPEND(edd->handlers, E_EVENT_AUTH_FPRINT_AVAILABLE, 
_lokker_cb_fprint_available, NULL);
+   E_LIST_HANDLER_APPEND(edd->handlers, E_EVENT_AUTH_FPRINT_STATUS, 
_lokker_cb_fprint_status, NULL);
+
    return EINA_TRUE;
 }
 
 EINTERN void
 lokker_unlock(void)
 {
+   e_auth_fprint_end();
    E_FREE_LIST(edd->elock_wnd_list, _lokker_popup_free);
    e_pointer_type_pop(e_comp->pointer, e_comp->pointer, "default");
    e_pointer_type_pop(e_comp->pointer, NULL, NULL);

-- 


Reply via email to