3 # include <security/pam_appl.h>
7 #define E_DESKLOCK_STATE_DEFAULT 0
8 #define E_DESKLOCK_STATE_CHECKING 1
9 #define E_DESKLOCK_STATE_INVALID 2
11 #define ELOCK_POPUP_LAYER 10000
12 #define PASSWD_LEN 256
14 /**************************** private data ******************************/
15 typedef struct _E_Desklock_Data E_Desklock_Data;
16 typedef struct _E_Desklock_Popup_Data E_Desklock_Popup_Data;
18 typedef struct _E_Desklock_Auth E_Desklock_Auth;
21 typedef struct _E_Desklock_Run E_Desklock_Run;
23 struct _E_Desklock_Popup_Data
26 Evas_Object *bg_object;
27 Evas_Object *login_box;
30 struct _E_Desklock_Data
32 Eina_List *elock_wnd_list;
33 Ecore_X_Window elock_wnd;
35 Ecore_Event_Handler *move_handler;
36 Ecore_X_Window elock_grab_break_wnd;
37 char passwd[PASSWD_LEN];
39 Eina_Bool selected : 1;
42 struct _E_Desklock_Run
49 struct _E_Desklock_Auth
62 static E_Desklock_Data *edd = NULL;
63 static E_Zone *last_active_zone = NULL;
65 static Ecore_Event_Handler *_e_desklock_exit_handler = NULL;
66 static pid_t _e_desklock_child_pid = -1;
68 static Ecore_Exe *_e_custom_desklock_exe = NULL;
69 static Ecore_Event_Handler *_e_custom_desklock_exe_handler = NULL;
70 static Ecore_Poller *_e_desklock_idle_poller = NULL;
71 static int _e_desklock_user_idle = 0;
72 static double _e_desklock_autolock_time = 0.0;
73 static E_Dialog *_e_desklock_ask_presentation_dia = NULL;
74 static int _e_desklock_ask_presentation_count = 0;
76 static Ecore_Event_Handler *_e_desklock_run_handler = NULL;
77 static Ecore_Job *job = NULL;
78 static Eina_List *tasks = NULL;
81 /***********************************************************************/
83 static Eina_Bool _e_desklock_cb_key_down(void *data, int type, void *event);
84 static Eina_Bool _e_desklock_cb_mouse_move(void *data, int type, void *event);
85 static Eina_Bool _e_desklock_cb_custom_desklock_exit(void *data, int type, void *event);
86 static Eina_Bool _e_desklock_cb_idle_poller(void *data);
87 static Eina_Bool _e_desklock_cb_window_stack(void *data, int type, void *event);
88 static Eina_Bool _e_desklock_cb_zone_add(void *data, int type, void *event);
89 static Eina_Bool _e_desklock_cb_zone_del(void *data, int type, void *event);
90 static Eina_Bool _e_desklock_cb_zone_move_resize(void *data, int type, void *event);
92 static Eina_Bool _e_desklock_cb_run(void *data, int type, void *event);
94 static void _e_desklock_popup_free(E_Desklock_Popup_Data *edp);
95 static void _e_desklock_popup_add(E_Zone *zone);
96 static void _e_desklock_login_box_add(E_Desklock_Popup_Data *edp);
97 static void _e_desklock_select(void);
98 static void _e_desklock_unselect(void);
99 static void _e_desklock_null(void);
100 static void _e_desklock_passwd_update(void);
101 static void _e_desklock_backspace(void);
102 static void _e_desklock_delete(void);
103 static int _e_desklock_zone_num_get(void);
104 static int _e_desklock_check_auth(void);
105 static void _e_desklock_state_set(int state);
107 static Eina_Bool _e_desklock_state = EINA_FALSE;
109 static Eina_Bool _e_desklock_cb_exit(void *data, int type, void *event);
110 static int _desklock_auth(char *passwd);
111 static int _desklock_pam_init(E_Desklock_Auth *da);
112 static int _desklock_auth_pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr);
113 static char *_desklock_auth_get_current_user(void);
114 static char *_desklock_auth_get_current_host(void);
117 static void _e_desklock_ask_presentation_mode(void);
119 EAPI int E_EVENT_DESKLOCK = 0;
122 e_desklock_init(void)
124 /* A poller to tick every 256 ticks, watching for an idle user */
125 _e_desklock_idle_poller = ecore_poller_add(ECORE_POLLER_CORE, 256,
126 _e_desklock_cb_idle_poller, NULL);
128 if (e_config->desklock_background)
129 e_filereg_register(e_config->desklock_background);
131 E_EVENT_DESKLOCK = ecore_event_type_new();
133 _e_desklock_run_handler = ecore_event_handler_add(E_EVENT_DESKLOCK,
134 _e_desklock_cb_run, NULL);
140 e_desklock_shutdown(void)
142 Eina_Bool waslocked = EINA_FALSE;
143 E_Desklock_Run *task;
145 if (edd) waslocked = EINA_TRUE;
148 if (e_config->desklock_background)
149 e_filereg_deregister(e_config->desklock_background);
151 if (waslocked) e_util_env_set("E_DESKLOCK_LOCKED", "locked");
153 ecore_event_handler_del(_e_desklock_run_handler);
154 _e_desklock_run_handler = NULL;
156 if (job) ecore_job_del(job);
159 EINA_LIST_FREE(tasks, task)
161 e_object_del(E_OBJECT(task->desk_run));
169 _user_wallpaper_get(void)
171 const E_Config_Desktop_Background *cdbg;
174 if (e_config->desktop_default_background)
175 return e_config->desktop_default_background;
177 EINA_LIST_FOREACH(e_config->desktop_backgrounds, l, cdbg)
178 if (cdbg->file) return cdbg->file;
180 return e_theme_edje_file_get("base/theme/desklock", "e/desklock/background");
184 e_desklock_show_autolocked(void)
186 if (e_util_fullscreen_curreny_any()) return 0;
187 if (_e_desklock_autolock_time < 1.0)
188 _e_desklock_autolock_time = ecore_loop_time_get();
189 return e_desklock_show(EINA_FALSE);
193 e_desklock_show(Eina_Bool suspend)
195 Eina_List *managers, *l, *l2, *l3;
198 E_Event_Desklock *ev;
200 if (_e_custom_desklock_exe) return 0;
202 if (e_config->desklock_use_custom_desklock && e_config->desklock_custom_desklock_cmd && e_config->desklock_custom_desklock_cmd[0])
204 _e_custom_desklock_exe_handler =
205 ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
206 _e_desklock_cb_custom_desklock_exit, NULL);
207 e_util_library_path_strip();
208 _e_custom_desklock_exe =
209 ecore_exe_run(e_config->desklock_custom_desklock_cmd, NULL);
210 e_util_library_path_restore();
211 _e_desklock_state = EINA_TRUE;
216 e_util_dialog_show(_("Error - no PAM support"),
217 _("No PAM support was built into Enlightenment, so<br>"
218 "desk locking is disabled."));
225 if (e_config->desklock_auth_method == 1)
228 if (!e_config->desklock_personal_passwd)
232 zone = e_util_zone_current_get(e_manager_current_get());
234 e_configure_registry_call("screen/screen_lock", zone->container, NULL);
242 edd = E_NEW(E_Desklock_Data, 1);
244 edd->elock_wnd = ecore_x_window_input_new(e_manager_current_get()->root, 0, 0, 1, 1);
245 ecore_x_window_show(edd->elock_wnd);
246 managers = e_manager_list();
247 if (!e_grabinput_get(edd->elock_wnd, 0, edd->elock_wnd))
249 EINA_LIST_FOREACH(managers, l, man)
251 Ecore_X_Window *windows;
254 windows = ecore_x_window_children_get(man->root, &wnum);
259 for (i = 0; i < wnum; i++)
261 Ecore_X_Window_Attributes att;
263 memset(&att, 0, sizeof(Ecore_X_Window_Attributes));
264 ecore_x_window_attributes_get(windows[i], &att);
267 ecore_x_window_hide(windows[i]);
268 if (e_grabinput_get(edd->elock_wnd, 0, edd->elock_wnd))
270 edd->elock_grab_break_wnd = windows[i];
274 ecore_x_window_show(windows[i]);
280 /* everything failed - can't lock */
281 e_util_dialog_show(_("Lock Failed"),
282 _("Locking the desktop failed because some application<br>"
283 "has grabbed either the keyboard or the mouse or both<br>"
284 "and their grab is unable to be broken."));
285 ecore_x_window_free(edd->elock_wnd);
291 total_zone_num = _e_desklock_zone_num_get();
292 EINA_LIST_FOREACH(managers, l, man)
296 EINA_LIST_FOREACH(man->containers, l2, con)
299 EINA_LIST_FOREACH(con->zones, l3, zone)
300 _e_desklock_popup_add(zone);
306 eina_list_append(edd->handlers,
307 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
308 _e_desklock_cb_key_down, NULL));
310 eina_list_append(edd->handlers,
311 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK,
312 _e_desklock_cb_window_stack, NULL));
314 eina_list_append(edd->handlers,
315 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE,
316 _e_desklock_cb_window_stack, NULL));
318 eina_list_append(edd->handlers,
319 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE,
320 _e_desklock_cb_window_stack, NULL));
322 eina_list_append(edd->handlers,
323 ecore_event_handler_add(E_EVENT_ZONE_ADD,
324 _e_desklock_cb_zone_add, NULL));
326 eina_list_append(edd->handlers,
327 ecore_event_handler_add(E_EVENT_ZONE_DEL,
328 _e_desklock_cb_zone_del, NULL));
330 eina_list_append(edd->handlers,
331 ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE,
332 _e_desklock_cb_zone_move_resize, NULL));
334 if ((total_zone_num > 1) && (e_config->desklock_login_box_zone == -2))
335 edd->move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_desklock_cb_mouse_move, NULL);
337 _e_desklock_passwd_update();
339 ev = E_NEW(E_Event_Desklock, 1);
341 ev->suspend = suspend;
342 ecore_event_add(E_EVENT_DESKLOCK, ev, NULL, NULL);
344 e_util_env_set("E_DESKLOCK_LOCKED", "locked");
345 _e_desklock_state = EINA_TRUE;
350 e_desklock_hide(void)
352 E_Desklock_Popup_Data *edp;
353 E_Event_Desklock *ev;
355 if ((!edd) && (!_e_custom_desklock_exe)) return;
357 _e_desklock_state = EINA_FALSE;
358 ev = E_NEW(E_Event_Desklock, 1);
361 ecore_event_add(E_EVENT_DESKLOCK, ev, NULL, NULL);
363 if (e_config->desklock_use_custom_desklock)
365 _e_custom_desklock_exe = NULL;
370 if (edd->elock_grab_break_wnd)
371 ecore_x_window_show(edd->elock_grab_break_wnd);
373 EINA_LIST_FREE(edd->elock_wnd_list, edp)
374 _e_desklock_popup_free(edp);
376 E_FREE_LIST(edd->handlers, ecore_event_handler_del);
377 if (edd->move_handler) ecore_event_handler_del(edd->move_handler);
379 e_grabinput_release(edd->elock_wnd, edd->elock_wnd);
380 ecore_x_window_free(edd->elock_wnd);
385 if (_e_desklock_autolock_time > 0.0)
387 if ((e_config->desklock_ask_presentation) &&
388 (e_config->desklock_ask_presentation_timeout > 0.0))
392 now = ecore_loop_time_get();
393 max = _e_desklock_autolock_time + e_config->desklock_ask_presentation_timeout;
395 _e_desklock_ask_presentation_mode();
398 _e_desklock_ask_presentation_count = 0;
400 _e_desklock_autolock_time = 0.0;
402 e_util_env_set("E_DESKLOCK_LOCKED", "freefreefree");
406 _e_desklock_popup_add(E_Zone *zone)
408 E_Desklock_Popup_Data *edp;
409 E_Config_Desklock_Background *cbg;
412 cbg = eina_list_nth(e_config->desklock_backgrounds, zone->num);
413 bg = cbg ? cbg->file : NULL;
414 edp = E_NEW(E_Desklock_Popup_Data, 1);
417 CRI("DESKLOCK FAILED FOR ZONE %d!", zone->num);
421 edp->popup_wnd = e_popup_new(zone, 0, 0, zone->w, zone->h);
422 evas_event_feed_mouse_move(edp->popup_wnd->evas, -1000000, -1000000,
423 ecore_x_current_time_get(), NULL);
425 e_popup_layer_set(edp->popup_wnd, ELOCK_POPUP_LAYER);
426 ecore_evas_raise(edp->popup_wnd->ecore_evas);
428 evas_event_freeze(edp->popup_wnd->evas);
429 edp->bg_object = edje_object_add(edp->popup_wnd->evas);
431 if ((!bg) || (!strcmp(bg, "theme_desklock_background")))
433 e_theme_edje_object_set(edp->bg_object,
434 "base/theme/desklock",
435 "e/desklock/background");
437 else if (!strcmp(bg, "theme_background"))
439 e_theme_edje_object_set(edp->bg_object,
440 "base/theme/backgrounds",
441 "e/desktop/background");
447 if (!strcmp(bg, "user_background"))
448 f = _user_wallpaper_get();
452 if (e_util_edje_collection_exists(f, "e/desklock/background"))
454 edje_object_file_set(edp->bg_object, f, "e/desklock/background");
458 if (!edje_object_file_set(edp->bg_object,
459 f, "e/desktop/background"))
461 edje_object_file_set(edp->bg_object,
462 e_theme_edje_file_get("base/theme/desklock",
463 "e/desklock/background"),
464 "e/desklock/background");
469 evas_object_move(edp->bg_object, 0, 0);
470 evas_object_resize(edp->bg_object, zone->w, zone->h);
471 evas_object_show(edp->bg_object);
473 _e_desklock_login_box_add(edp);
474 e_popup_edje_bg_object_set(edp->popup_wnd, edp->bg_object);
475 evas_event_thaw(edp->popup_wnd->evas);
477 e_popup_show(edp->popup_wnd);
479 edd->elock_wnd_list = eina_list_append(edd->elock_wnd_list, edp);
483 _e_desklock_login_box_add(E_Desklock_Popup_Data *edp)
486 E_Zone *zone = edp->popup_wnd->zone;
487 E_Zone *current_zone;
490 last_active_zone = current_zone = e_zone_current_get(e_container_current_get(e_manager_current_get()));
491 total_zone_num = _e_desklock_zone_num_get();
492 if (total_zone_num > 1)
494 if ((e_config->desklock_login_box_zone == -2) && (zone != current_zone))
496 if ((e_config->desklock_login_box_zone > -1) && (e_config->desklock_login_box_zone != (int)eina_list_count(edd->elock_wnd_list)))
500 edp->login_box = edje_object_add(edp->popup_wnd->evas);
501 e_theme_edje_object_set(edp->login_box,
502 "base/theme/desklock",
503 "e/desklock/login_box");
504 edje_object_part_text_set(edp->login_box, "e.text.title",
505 _("Please enter your unlock password"));
506 edje_object_size_min_calc(edp->login_box, &mw, &mh);
507 if (edje_object_part_exists(edp->bg_object, "e.swallow.login_box"))
509 edje_extern_object_min_size_set(edp->login_box, mw, mh);
510 edje_object_part_swallow(edp->bg_object, "e.swallow.login_box", edp->login_box);
514 evas_object_resize(edp->login_box, mw, mh);
515 evas_object_move(edp->login_box,
516 ((zone->w - mw) / 2),
517 ((zone->h - mh) / 2));
519 evas_object_show(edp->login_box);
523 _e_desklock_popup_free(E_Desklock_Popup_Data *edp)
526 e_popup_hide(edp->popup_wnd);
528 evas_event_freeze(edp->popup_wnd->evas);
529 evas_object_del(edp->bg_object);
530 evas_object_del(edp->login_box);
531 evas_event_thaw(edp->popup_wnd->evas);
533 e_util_defer_object_del(E_OBJECT(edp->popup_wnd));
538 _e_desklock_cb_window_stack(void *data __UNUSED__,
542 Ecore_X_Window win, win2 = 0;
543 E_Desklock_Popup_Data *edp;
545 Eina_Bool raise_win = EINA_TRUE;
547 if (!edd) return ECORE_CALLBACK_PASS_ON;
549 if (type == ECORE_X_EVENT_WINDOW_STACK)
550 win = ((Ecore_X_Event_Window_Stack *)event)->event_win;
551 else if (type == ECORE_X_EVENT_WINDOW_CONFIGURE)
553 win = ((Ecore_X_Event_Window_Configure *)event)->event_win;
554 win2 = ((Ecore_X_Event_Window_Configure *)event)->win;
556 else if (type == ECORE_X_EVENT_WINDOW_CREATE)
557 win = ((Ecore_X_Event_Window_Create *)event)->win;
559 return ECORE_CALLBACK_PASS_ON;
561 EINA_LIST_FOREACH(edd->elock_wnd_list, l, edp)
563 if ((win == edp->popup_wnd->evas_win) ||
564 ((win2) && (win2 == edp->popup_wnd->evas_win)))
566 raise_win = EINA_FALSE;
573 EINA_LIST_FOREACH(edd->elock_wnd_list, l, edp)
574 ecore_evas_raise(edp->popup_wnd->ecore_evas);
577 return ECORE_CALLBACK_PASS_ON;
581 e_desklock_state_get(void)
583 return _e_desklock_state;
587 _e_desklock_popup_find(E_Zone *zone)
590 E_Desklock_Popup_Data *edp;
592 EINA_LIST_FOREACH(edd->elock_wnd_list, l, edp)
593 if (edp->popup_wnd->zone == zone) return l;
598 _e_desklock_cb_zone_add(void *data __UNUSED__,
602 E_Event_Zone_Add *ev = event;
603 if (!edd) return ECORE_CALLBACK_PASS_ON;
604 if ((!edd->move_handler) && (e_config->desklock_login_box_zone == -2))
605 edd->move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_desklock_cb_mouse_move, NULL);
606 if (!_e_desklock_popup_find(ev->zone)) _e_desklock_popup_add(ev->zone);
607 return ECORE_CALLBACK_PASS_ON;
611 _e_desklock_cb_zone_del(void *data __UNUSED__,
615 E_Event_Zone_Del *ev = event;
617 if (!edd) return ECORE_CALLBACK_PASS_ON;
618 if ((eina_list_count(e_container_current_get(e_manager_current_get())->zones) == 1) && (e_config->desklock_login_box_zone == -2))
619 edd->move_handler = ecore_event_handler_del(edd->move_handler);
621 l = _e_desklock_popup_find(ev->zone);
624 _e_desklock_popup_free(l->data);
625 edd->elock_wnd_list = eina_list_remove_list(edd->elock_wnd_list, l);
627 return ECORE_CALLBACK_PASS_ON;
631 _e_desklock_cb_zone_move_resize(void *data __UNUSED__,
635 E_Desklock_Popup_Data *edp;
637 E_Event_Zone_Move_Resize *ev = event;
639 if (!edd) return ECORE_CALLBACK_PASS_ON;
640 EINA_LIST_FOREACH(edd->elock_wnd_list, l, edp)
641 if (edp->popup_wnd->zone == ev->zone)
643 e_popup_move_resize(edp->popup_wnd, 0, 0, ev->zone->w, ev->zone->h);
644 evas_object_resize(edp->bg_object, ev->zone->w, ev->zone->h);
647 return ECORE_CALLBACK_PASS_ON;
651 _e_desklock_cb_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
653 Ecore_Event_Key *ev = event;
655 if ((ev->window != edd->elock_wnd) ||
656 (edd->state == E_DESKLOCK_STATE_CHECKING)) return 1;
658 if (!strcmp(ev->key, "Escape"))
662 _e_desklock_unselect();
663 return ECORE_CALLBACK_RENEW;
666 else if (!strcmp(ev->key, "KP_Enter"))
667 _e_desklock_check_auth();
668 else if (!strcmp(ev->key, "Return"))
669 _e_desklock_check_auth();
670 else if (!strcmp(ev->key, "BackSpace"))
675 _e_desklock_unselect();
676 return ECORE_CALLBACK_RENEW;
678 _e_desklock_backspace();
680 else if (!strcmp(ev->key, "Delete"))
685 _e_desklock_unselect();
686 return ECORE_CALLBACK_RENEW;
688 _e_desklock_delete();
690 else if ((!strcmp(ev->key, "u") &&
691 (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)))
693 else if ((!strcmp(ev->key, "a") &&
694 (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)))
695 _e_desklock_select();
698 /* here we have to grab a password */
704 _e_desklock_unselect();
706 if ((strlen(edd->passwd) < (PASSWD_LEN - strlen(ev->compose))))
708 strcat(edd->passwd, ev->compose);
709 _e_desklock_passwd_update();
714 return ECORE_CALLBACK_PASS_ON;
718 _e_desklock_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
720 E_Desklock_Popup_Data *edp;
721 E_Zone *current_zone;
724 current_zone = e_zone_current_get(e_container_current_get(e_manager_current_get()));
726 if (current_zone == last_active_zone)
727 return ECORE_CALLBACK_PASS_ON;
729 EINA_LIST_FOREACH(edd->elock_wnd_list, l, edp)
733 if (edp->popup_wnd->zone != current_zone)
735 if (edp->login_box) evas_object_hide(edp->login_box);
739 evas_object_show(edp->login_box);
741 _e_desklock_login_box_add(edp);
743 _e_desklock_passwd_update();
744 last_active_zone = current_zone;
745 return ECORE_CALLBACK_PASS_ON;
749 _e_desklock_passwd_update(void)
752 char passwd_hidden[PASSWD_LEN] = "", *pp;
753 E_Desklock_Popup_Data *edp;
758 len = eina_unicode_utf8_get_len(edd->passwd);
759 for (i = 0, pp = passwd_hidden; i < len; i++, pp++)
763 EINA_LIST_FOREACH(edd->elock_wnd_list, l, edp)
764 if (edp->login_box) edje_object_part_text_set(edp->login_box, "e.text.password",
769 _e_desklock_select(void)
771 E_Desklock_Popup_Data *edp;
773 EINA_LIST_FOREACH(edd->elock_wnd_list, l, edp)
775 edje_object_signal_emit(edp->login_box, "e,state,selected", "e");
776 edd->selected = EINA_TRUE;
780 _e_desklock_unselect(void)
782 E_Desklock_Popup_Data *edp;
784 EINA_LIST_FOREACH(edd->elock_wnd_list, l, edp)
786 edje_object_signal_emit(edp->login_box, "e,state,unselected", "e");
787 edd->selected = EINA_FALSE;
791 _e_desklock_null(void)
793 memset(edd->passwd, 0, sizeof(char) * PASSWD_LEN);
794 _e_desklock_passwd_update();
798 _e_desklock_backspace(void)
804 len = strlen(edd->passwd);
807 pos = evas_string_char_prev_get(edd->passwd, len, &val);
808 if ((pos < len) && (pos >= 0))
810 edd->passwd[pos] = 0;
811 _e_desklock_passwd_update();
817 _e_desklock_delete(void)
819 _e_desklock_backspace();
823 _e_desklock_zone_num_get(void)
830 EINA_LIST_FOREACH(e_manager_list(), l, man)
833 EINA_LIST_FOREACH(man->containers, l2, con)
834 num += eina_list_count(con->zones);
841 _e_desklock_check_auth(void)
845 if (e_config->desklock_auth_method == 0)
849 ret = _desklock_auth(edd->passwd);
850 // passwd off in child proc now - null out from parent
851 memset(edd->passwd, 0, sizeof(char) * PASSWD_LEN);
854 else if (e_config->desklock_auth_method == 1)
857 if ((e_config->desklock_personal_passwd) &&
858 (!strcmp(!edd->passwd ? "" : edd->passwd,
859 !e_config->desklock_personal_passwd ? "" :
860 e_config->desklock_personal_passwd)))
863 /* security - null out passwd string once we are done with it */
864 memset(edd->passwd, 0, sizeof(char) * PASSWD_LEN);
872 /* password is definitely wrong */
873 _e_desklock_state_set(E_DESKLOCK_STATE_INVALID);
879 _e_desklock_state_set(int state)
882 E_Desklock_Popup_Data *edp;
883 const char *signal_desklock, *text;
887 if (state == E_DESKLOCK_STATE_CHECKING)
889 signal_desklock = "e,state,checking";
890 text = "Authenticating...";
892 else if (state == E_DESKLOCK_STATE_INVALID)
894 signal_desklock = "e,state,invalid";
895 text = "The password you entered is invalid. Try again.";
900 EINA_LIST_FOREACH(edd->elock_wnd_list, l, edp)
902 edje_object_signal_emit(edp->login_box, signal_desklock, "e.desklock");
903 edje_object_signal_emit(edp->bg_object, signal_desklock, "e.desklock");
904 edje_object_part_text_set(edp->login_box, "e.text.title", text);
910 _e_desklock_cb_exit(void *data __UNUSED__, int type __UNUSED__, void *event)
912 Ecore_Exe_Event_Del *ev = event;
914 if (ev->pid == _e_desklock_child_pid)
916 _e_desklock_child_pid = -1;
918 if (ev->exit_code == 0)
920 /* security - null out passwd string once we are done with it */
921 memset(edd->passwd, 0, sizeof(char) * PASSWD_LEN);
925 else if (ev->exit_code < 128)
927 /* security - null out passwd string once we are done with it */
928 memset(edd->passwd, 0, sizeof(char) * PASSWD_LEN);
930 e_util_dialog_show(_("Authentication System Error"),
931 _("Authentication via PAM had errors setting up the<br>"
932 "authentication session. The error code was <hilight>%i</hilight>.<br>"
933 "This is bad and should not be happening. Please report this bug.")
939 _e_desklock_state_set(E_DESKLOCK_STATE_INVALID);
940 /* security - null out passwd string once we are done with it */
943 if (_e_desklock_exit_handler)
944 ecore_event_handler_del(_e_desklock_exit_handler);
945 _e_desklock_exit_handler = NULL;
947 return ECORE_CALLBACK_PASS_ON;
951 _desklock_auth(char *passwd)
953 _e_desklock_state_set(E_DESKLOCK_STATE_CHECKING);
954 _e_desklock_child_pid = fork();
955 if (_e_desklock_child_pid > 0)
958 _e_desklock_exit_handler =
959 ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _e_desklock_cb_exit,
962 else if (_e_desklock_child_pid == 0)
967 char *current_user, *p;
968 struct sigaction action;
970 action.sa_handler = SIG_DFL;
971 action.sa_flags = SA_ONSTACK | SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
972 sigemptyset(&action.sa_mask);
973 sigaction(SIGSEGV, &action, NULL);
974 sigaction(SIGILL, &action, NULL);
975 sigaction(SIGFPE, &action, NULL);
976 sigaction(SIGBUS, &action, NULL);
977 sigaction(SIGABRT, &action, NULL);
979 current_user = _desklock_auth_get_current_user();
980 eina_strlcpy(da.user, current_user, sizeof(da.user));
981 eina_strlcpy(da.passwd, passwd, sizeof(da.passwd));
982 /* security - null out passwd string once we are done with it */
983 for (p = passwd; *p; p++)
985 da.pam.handle = NULL;
986 da.pam.conv.conv = NULL;
987 da.pam.conv.appdata_ptr = NULL;
989 pamerr = _desklock_pam_init(&da);
990 if (pamerr != PAM_SUCCESS)
995 pamerr = pam_authenticate(da.pam.handle, 0);
996 pam_end(da.pam.handle, pamerr);
997 /* security - null out passwd string once we are done with it */
998 memset(da.passwd, 0, sizeof(da.passwd));
999 if (pamerr == PAM_SUCCESS)
1009 _e_desklock_state_set(E_DESKLOCK_STATE_INVALID);
1016 _desklock_auth_get_current_user(void)
1019 struct passwd *pwent = NULL;
1021 pwent = getpwuid(getuid());
1022 user = strdup(pwent->pw_name);
1027 _desklock_pam_init(E_Desklock_Auth *da)
1030 const char *pam_prof;
1036 da->pam.conv.conv = _desklock_auth_pam_conv;
1037 da->pam.conv.appdata_ptr = da;
1038 da->pam.handle = NULL;
1040 /* try other pam profiles - and system-auth (login for fbsd users) is a fallback */
1042 if (ecore_file_exists("/etc/pam.d/enlightenment"))
1043 pam_prof = "enlightenment";
1044 else if (ecore_file_exists("/etc/pam.d/xscreensaver"))
1045 pam_prof = "xscreensaver";
1046 else if (ecore_file_exists("/etc/pam.d/kscreensaver"))
1047 pam_prof = "kscreensaver";
1048 else if (ecore_file_exists("/etc/pam.d/system-auth"))
1049 pam_prof = "system-auth";
1050 else if (ecore_file_exists("/etc/pam.d/system"))
1051 pam_prof = "system";
1052 else if (ecore_file_exists("/etc/pam.d/xdm"))
1054 else if (ecore_file_exists("/etc/pam.d/gdm"))
1056 else if (ecore_file_exists("/etc/pam.d/kdm"))
1059 if ((pamerr = pam_start(pam_prof, da->user, &(da->pam.conv),
1060 &(da->pam.handle))) != PAM_SUCCESS)
1063 current_user = _desklock_auth_get_current_user();
1065 if ((pamerr = pam_set_item(da->pam.handle, PAM_USER, current_user)) != PAM_SUCCESS)
1071 current_host = _desklock_auth_get_current_host();
1072 if ((pamerr = pam_set_item(da->pam.handle, PAM_RHOST, current_host)) != PAM_SUCCESS)
1085 _desklock_auth_pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
1088 E_Desklock_Auth *da = (E_Desklock_Auth *)appdata_ptr;
1089 struct pam_response *reply = NULL;
1091 reply = (struct pam_response *)malloc(sizeof(struct pam_response) * num_msg);
1093 if (!reply) return PAM_CONV_ERR;
1095 for (replies = 0; replies < num_msg; replies++)
1097 switch (msg[replies]->msg_style)
1099 case PAM_PROMPT_ECHO_ON:
1100 reply[replies].resp_retcode = PAM_SUCCESS;
1101 reply[replies].resp = strdup(da->user);
1104 case PAM_PROMPT_ECHO_OFF:
1105 reply[replies].resp_retcode = PAM_SUCCESS;
1106 reply[replies].resp = strdup(da->passwd);
1111 reply[replies].resp_retcode = PAM_SUCCESS;
1112 reply[replies].resp = NULL;
1117 return PAM_CONV_ERR;
1125 _desklock_auth_get_current_host(void)
1127 return strdup("localhost");
1133 _e_desklock_cb_custom_desklock_exit(void *data __UNUSED__, int type __UNUSED__, void *event)
1135 Ecore_Exe_Event_Del *ev = event;
1137 if (ev->exe != _e_custom_desklock_exe) return ECORE_CALLBACK_PASS_ON;
1139 if (ev->exit_code != 0)
1141 /* do something profound here... like notify someone */
1146 return ECORE_CALLBACK_DONE;
1150 _e_desklock_cb_idle_poller(void *data __UNUSED__)
1152 if ((e_config->desklock_autolock_idle) && (!e_config->mode.presentation) &&
1153 (!e_util_fullscreen_curreny_any()))
1157 /* If a desklock is already up, bail */
1158 if ((_e_custom_desklock_exe) || (edd)) return ECORE_CALLBACK_RENEW;
1160 idle = ecore_x_screensaver_idle_time_get();
1161 max = e_config->desklock_autolock_idle_timeout;
1162 if (_e_desklock_ask_presentation_count > 0)
1163 max *= (1 + _e_desklock_ask_presentation_count);
1165 /* If we have exceeded our idle time... */
1169 * Unfortunately, not all "desklocks" stay up for as long as
1170 * the user is idle or until it is unlocked.
1172 * 'xscreensaver-command -lock' for example sends a command
1173 * to xscreensaver and then terminates. So, we have another
1174 * check (_e_desklock_user_idle) which lets us know that we
1175 * have locked the screen due to idleness.
1177 if (!_e_desklock_user_idle)
1179 _e_desklock_user_idle = 1;
1180 e_desklock_show_autolocked();
1184 _e_desklock_user_idle = 0;
1187 /* Make sure our poller persists. */
1188 return ECORE_CALLBACK_RENEW;
1192 _e_desklock_ask_presentation_del(void *data)
1194 if (_e_desklock_ask_presentation_dia == data)
1195 _e_desklock_ask_presentation_dia = NULL;
1199 _e_desklock_ask_presentation_yes(void *data __UNUSED__, E_Dialog *dia)
1201 e_config->mode.presentation = 1;
1202 e_config_mode_changed();
1203 e_config_save_queue();
1204 e_object_del(E_OBJECT(dia));
1205 _e_desklock_ask_presentation_count = 0;
1209 _e_desklock_ask_presentation_no(void *data __UNUSED__, E_Dialog *dia)
1211 e_object_del(E_OBJECT(dia));
1212 _e_desklock_ask_presentation_count = 0;
1216 _e_desklock_ask_presentation_no_increase(void *data __UNUSED__, E_Dialog *dia)
1218 int timeout, interval, blanking, expose;
1220 _e_desklock_ask_presentation_count++;
1221 timeout = e_config->screensaver_timeout * _e_desklock_ask_presentation_count;
1222 interval = e_config->screensaver_interval;
1223 blanking = e_config->screensaver_blanking;
1224 expose = e_config->screensaver_expose;
1226 ecore_x_screensaver_set(timeout, interval, blanking, expose);
1227 e_object_del(E_OBJECT(dia));
1231 _e_desklock_ask_presentation_no_forever(void *data __UNUSED__, E_Dialog *dia)
1233 e_config->desklock_ask_presentation = 0;
1234 e_config_save_queue();
1235 e_object_del(E_OBJECT(dia));
1236 _e_desklock_ask_presentation_count = 0;
1240 _e_desklock_ask_presentation_key_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event)
1242 Evas_Event_Key_Down *ev = event;
1243 E_Dialog *dia = data;
1245 if (strcmp(ev->keyname, "Return") == 0)
1246 _e_desklock_ask_presentation_yes(NULL, dia);
1247 else if (strcmp(ev->keyname, "Escape") == 0)
1248 _e_desklock_ask_presentation_no(NULL, dia);
1252 _e_desklock_ask_presentation_mode(void)
1258 if (_e_desklock_ask_presentation_dia) return;
1260 if (!(man = e_manager_current_get())) return;
1261 if (!(con = e_container_current_get(man))) return;
1262 if (!(dia = e_dialog_new(con, "E", "_desklock_ask_presentation"))) return;
1264 e_dialog_title_set(dia, _("Activate Presentation Mode?"));
1265 e_dialog_icon_set(dia, "dialog-ask", 64);
1266 e_dialog_text_set(dia,
1267 _("You unlocked desktop too fast.<br><br>"
1268 "Would you like to enable <b>presentation</b> mode and "
1269 "temporarily disable screen saver, lock and power saving?"));
1271 e_object_del_attach_func_set(E_OBJECT(dia),
1272 _e_desklock_ask_presentation_del);
1273 e_dialog_button_add(dia, _("Yes"), NULL,
1274 _e_desklock_ask_presentation_yes, NULL);
1275 e_dialog_button_add(dia, _("No"), NULL,
1276 _e_desklock_ask_presentation_no, NULL);
1277 e_dialog_button_add(dia, _("No, but increase timeout"), NULL,
1278 _e_desklock_ask_presentation_no_increase, NULL);
1279 e_dialog_button_add(dia, _("No, and stop asking"), NULL,
1280 _e_desklock_ask_presentation_no_forever, NULL);
1282 e_dialog_button_focus_num(dia, 0);
1283 e_widget_list_homogeneous_set(dia->box_object, 0);
1284 e_win_centered_set(dia->win, 1);
1287 evas_object_event_callback_add(dia->bg_object, EVAS_CALLBACK_KEY_DOWN,
1288 _e_desklock_ask_presentation_key_down, dia);
1290 _e_desklock_ask_presentation_dia = dia;
1294 _e_desklock_run(E_Desklock_Run *task)
1296 Efreet_Desktop *desktop;
1298 desktop = eina_list_nth(task->desk_run->desktops, task->position++);
1301 e_object_del(E_OBJECT(task->desk_run));
1306 e_exec(NULL, desktop, NULL, NULL, NULL);
1311 _e_desklock_job(void *data __UNUSED__)
1313 E_Desklock_Run *task;
1316 if (!tasks) return ;
1318 task = eina_list_data_get(tasks);
1319 if (!_e_desklock_run(task))
1320 tasks = eina_list_remove_list(tasks, tasks);
1322 if (tasks) job = ecore_job_add(_e_desklock_job, NULL);
1326 _e_desklock_cb_run(void *data __UNUSED__, int type __UNUSED__, void *event)
1328 E_Desklock_Run *task;
1329 E_Event_Desklock *ev = event;
1333 if (!ev->suspend) return ECORE_CALLBACK_PASS_ON;
1337 e_user_dir_concat_static(buf, "applications/desk-lock/.order");
1338 if (!ecore_file_exists(buf))
1339 e_prefix_data_concat_static(buf, "applications/desk-lock/.order");
1343 e_user_dir_concat_static(buf, "applications/desk-unlock/.order");
1344 if (!ecore_file_exists(buf))
1345 e_prefix_data_concat_static(buf, "applications/desk-unlock/.order");
1348 desk_run = e_order_new(buf);
1349 if (!desk_run) return ECORE_CALLBACK_PASS_ON;
1351 task = calloc(1, sizeof (E_Desklock_Run));
1354 e_object_del(E_OBJECT(desk_run));
1355 return ECORE_CALLBACK_PASS_ON;
1358 task->desk_run = desk_run;
1359 tasks = eina_list_append(tasks, task);
1361 if (!job) ecore_job_add(_e_desklock_job, NULL);
1363 return ECORE_CALLBACK_PASS_ON;