From aff9ec19a2622905c4cb36c66794db916c90ca89 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 19 Sep 2013 19:41:24 +0200 Subject: [PATCH] Implement ulock --- CMakeLists.txt | 37 +++++- FindPAM.cmake | 16 +++ config.h.in | 8 ++ data/bg.svg | 208 ++++++++++++++++++++++++++++++++ data/siegel.png | Bin 0 -> 42599 bytes data/unlock.ui | 166 +++++++++++++++++++++++++ etc/ulock.conf | 4 + po/POTFILES.in | 3 + po/de.po | 49 ++++++++ po/ulock.pot | 49 ++++++++ ulock.c | 315 ++++++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 851 insertions(+), 4 deletions(-) create mode 100644 FindPAM.cmake create mode 100644 config.h.in create mode 100644 data/bg.svg create mode 100644 data/siegel.png create mode 100644 data/unlock.ui create mode 100644 etc/ulock.conf create mode 100644 po/POTFILES.in create mode 100644 po/de.po create mode 100644 po/ulock.pot diff --git a/CMakeLists.txt b/CMakeLists.txt index 14fab01..da56d2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,41 @@ project(ULOCK C) cmake_minimum_required(VERSION 2.8) +set(CMAKE_MODULE_PATH ${ULOCK_SOURCE_DIR}) + +find_package(Gettext REQUIRED) + +find_package(PAM REQUIRED) + find_package(PkgConfig REQUIRED) pkg_check_modules(GTK3 REQUIRED gtk+-x11-3.0) +pkg_check_modules(GDK3 REQUIRED gdk-x11-3.0) +pkg_check_modules(X11 REQUIRED x11) -include_directories(${GTK3_INCLUDE_DIRS}) +set(CMAKE_THREAD_PREFER_PTHREAD TRUE) +find_package(Threads) +if(NOT CMAKE_USE_PTHREADS_INIT) + MESSAGE(FATAL_ERROR "No pthread support found.") +endif(NOT CMAKE_USE_PTHREADS_INIT) + + +set(CONFIG_DIR "/etc" CACHE STRING "Path to install ulock's configuration file to") +set(DATA_DIR "share/ulock" CACHE STRING "Path to install ulock's data files to") + + +include_directories(${ULOCK_BINARY_DIR} ${GTK3_INCLUDE_DIRS} ${GDK3_INCLUDE_DIRS} ${X11_INCLUDE_DIRS} ${PAM_INCLUDE_DIR}) + +configure_file(${ULOCK_SOURCE_DIR}/config.h.in ${ULOCK_BINARY_DIR}/config.h) add_executable(ulock ulock.c) -set_property(TARGET ulock PROPERTY COMPILE_FLAGS "-Wall ${GTK3_CFLAGS_OTHER}") -set_property(TARGET ulock PROPERTY LINK_FLAGS "${GTK3_LDFLAGS_OTHER}") -target_link_libraries(ulock ${GTK3_LIBRARIES}) +set_property(TARGET ulock PROPERTY COMPILE_FLAGS "-Wall -pthread ${GTK3_CFLAGS_OTHER} ${GDK3_CFLAGS_OTHER} ${X11_CFLAGS_OTHER}") +set_property(TARGET ulock PROPERTY LINK_FLAGS "-pthread ${GTK3_LDFLAGS_OTHER} ${GDK3_LDFLAGS_OTHER} ${X11_LDFLAGS_OTHER}") +target_link_libraries(ulock ${GTK3_LIBRARIES} ${GDK3_LIBRARIES} ${X11_LIBRARIES} ${PAM_LIBRARY}) + +GETTEXT_PROCESS_PO_FILES(de ALL PO_FILES po/de.po) + +install(TARGETS ulock RUNTIME DESTINATION bin) +install(DIRECTORY data/ DESTINATION ${DATA_DIR}) +install(FILES etc/ulock.conf DESTINATION ${CONFIG_DIR}) + +install(FILES ${ULOCK_BINARY_DIR}/de.gmo DESTINATION share/locale/de/LC_MESSAGES RENAME ulock.mo) diff --git a/FindPAM.cmake b/FindPAM.cmake new file mode 100644 index 0000000..f324670 --- /dev/null +++ b/FindPAM.cmake @@ -0,0 +1,16 @@ +FIND_PATH(PAM_INCLUDE_DIR security/pam_appl.h) +FIND_LIBRARY(PAM_LIBRARY NAMES pam) + +IF (PAM_INCLUDE_DIR AND PAM_LIBRARY) + SET(PAM_FOUND TRUE) +ENDIF (PAM_INCLUDE_DIR AND PAM_LIBRARY) + +IF (PAM_FOUND) + IF (NOT PAM_FIND_QUIETLY) + MESSAGE(STATUS "Found PAM: ${PAM_LIBRARY}; include path: ${PAM_INCLUDE_DIR}") + ENDIF (NOT PAM_FIND_QUIETLY) +ELSE (PAM_FOUND) + IF (PAM_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find PAM") + ENDIF (PAM_FIND_REQUIRED) +ENDIF (PAM_FOUND) diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..6f5e541 --- /dev/null +++ b/config.h.in @@ -0,0 +1,8 @@ +#ifndef _ULOCK_CONFIG_H_ +#define _ULOCK_CONFIG_H_ + +#define CONFIG_FILE "@CONFIG_DIR@/ulock.conf" +#define PREFIX "@CMAKE_INSTALL_PREFIX@" +#define DATA_DIR "@CMAKE_INSTALL_PREFIX@/@DATA_DIR@" + +#endif /* _ULOCK_CONFIG_H_ */ diff --git a/data/bg.svg b/data/bg.svg new file mode 100644 index 0000000..78e3972 --- /dev/null +++ b/data/bg.svg @@ -0,0 +1,208 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bei Problemen melden Sie sich bitte per E-Mail anpool-hotline@itsc.uni-luebeck.deoder telefonisch unter derinternen Nummer 5004. + + \ No newline at end of file diff --git a/data/siegel.png b/data/siegel.png new file mode 100644 index 0000000000000000000000000000000000000000..8b46a101b2811d9b32898c046af53f9aba24e188 GIT binary patch literal 42599 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 + + + + 700 + True + False + center + center + False + + + True + False + 40 + + + True + False + siegel.png + + + False + True + 0 + + + + + True + False + 12 + 12 + + + True + False + [lock] + + + True + True + 1 + + + + + False + 6 + + + False + 6 + + + True + False + Password: + + + False + True + 0 + + + + + True + True + False + + True + False + False + + + + True + True + 1 + + + + + True + True + 0 + + + + + False + 0 + [message] + + + True + True + 1 + + + + + True + False + 20 + + + Unlock + False + True + True + True + False + + + True + True + end + 1 + + + + + Logout + False + True + True + True + False + + + True + True + end + 2 + + + + + True + True + 2 + + + + + False + True + 3 + + + + + False + True + 1 + + + + + + + + + diff --git a/etc/ulock.conf b/etc/ulock.conf new file mode 100644 index 0000000..920e278 --- /dev/null +++ b/etc/ulock.conf @@ -0,0 +1,4 @@ +[ulock] +#theme=Adwaita +#logout_timeout=600 +#logout_command=xfce4-session-logout -l diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..def4168 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,3 @@ +[encoding: UTF-8] +pylock.c +[type: gettext/glade]data/unlock.ui diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..108462a --- /dev/null +++ b/po/de.po @@ -0,0 +1,49 @@ +# ulock german translation +# Copyright (C) 2013 Matthias Schiffer +# This file is distributed under the same license as the ulock package. +# Matthias Schiffer , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: pylock 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-09-19 18:53+0200\n" +"PO-Revision-Date: 2012-02-01 19:30+0100\n" +"Last-Translator: Matthias Schiffer \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: data/unlock.ui:125 +msgid "Logout" +msgstr "Ausloggen" + +#: data/unlock.ui:58 +msgid "Password:" +msgstr "Passwort:" + +#: ulock.c:88 +msgid "This computer is currently locked by the user %s." +msgstr "Dieser Computer ist zur Zeit vom Benutzer %s gesperrt." + +#: ulock.c:92 +msgid "" +"This computer is currently locked by the user %s.\n" +"The user can be logged out in %02u:%02u minutes." +msgstr "" +"Dieser Computer ist zur Zeit vom Benutzer %s gesperrt.\n" +"Der Benutzer kann in %02u:%02u Minuten ausgeloggt werden." + +#: ulock.c:98 +msgid "" +"This computer is currently locked by the user %s.\n" +"The user can be logged out now." +msgstr "" +"Dieser Computer ist zur Zeit vom Benutzer %s gesperrt.\n" +"Der Benutzer kann jetzt ausgeloggt werden." + +#: data/unlock.ui:109 +msgid "Unlock" +msgstr "Entsperren" diff --git a/po/ulock.pot b/po/ulock.pot new file mode 100644 index 0000000..697554b --- /dev/null +++ b/po/ulock.pot @@ -0,0 +1,49 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-09-19 18:53+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ulock.c:88 +#, c-format +msgid "This computer is currently locked by the user %s." +msgstr "" + +#: ulock.c:92 +#, c-format +msgid "" +"This computer is currently locked by the user %s.\n" +"The user can be logged out in %02u:%02u minutes." +msgstr "" + +#: ulock.c:98 +#, c-format +msgid "" +"This computer is currently locked by the user %s.\n" +"The user can be logged out now." +msgstr "" + +#: data/unlock.ui:58 +msgid "Password:" +msgstr "" + +#: data/unlock.ui:109 +msgid "Unlock" +msgstr "" + +#: data/unlock.ui:125 +msgid "Logout" +msgstr "" diff --git a/ulock.c b/ulock.c index e69de29..aaa1ecd 100644 --- a/ulock.c +++ b/ulock.c @@ -0,0 +1,315 @@ +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + + +#define _(s) gettext(s) +#define DEBUG(args...) syslog(LOG_NOTICE, args) + + +enum lock_state { + LOCKED, UNLOCKING, LOGOUT +}; + + +static enum lock_state state = LOCKED; + +static GtkWidget *window, *unlockWindow, *lockLabel, *promptEntry, *messageLabel, *logoutButton, *unlockButton; +static gboolean enablePromptEntry = TRUE, enableLogoutButton = FALSE, enableUnlockButton = TRUE; + +static char *username; +static char *logoutCommand = NULL; +static int logoutTime = 0; + + +static gboolean do_grab_devices(gpointer user_data) { + DEBUG("do_grab_devices"); + + gtk_window_present(GTK_WINDOW(window)); + + GdkDeviceManager *deviceManager = gdk_display_get_device_manager(gdk_display_get_default()); + GList *devices = gdk_device_manager_list_devices(deviceManager, GDK_DEVICE_TYPE_MASTER); + + gboolean error = FALSE; + + for (; devices; devices = g_list_next(devices)) { + GdkDevice *device = devices->data; + + if (gdk_device_grab(device, gtk_widget_get_window(window), GDK_OWNERSHIP_APPLICATION, TRUE, GDK_ALL_EVENTS_MASK, NULL, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS) + error = TRUE; + } + + g_list_free(devices); + + return error; +} + +static void grab_devices(void) { + if (do_grab_devices(NULL)) + g_timeout_add_seconds(1, do_grab_devices, NULL); +} + +static void update(void) { + gboolean locked = (state == LOCKED); + + gtk_widget_set_sensitive(promptEntry, enablePromptEntry && locked); + gtk_widget_set_sensitive(logoutButton, enableLogoutButton && locked); + gtk_widget_set_sensitive(unlockButton, enableUnlockButton && locked); +} + +static gboolean do_update_logout_time(gpointer user_data) { + gboolean ret = FALSE; + char *escaped_username = g_markup_escape_text(username, -1); + char *message; + + if (!logoutCommand) { + message = g_strdup_printf(_("This computer is currently locked by the user %s."), escaped_username); + enableLogoutButton = FALSE; + } + else if (logoutTime > 0) { + message = g_strdup_printf(_("This computer is currently locked by the user %s.\nThe user can be logged out in %02u:%02u minutes."), escaped_username, logoutTime/60, logoutTime%60); + enableLogoutButton = FALSE; + ret = TRUE; + logoutTime--; + } + else { + message = g_strdup_printf(_("This computer is currently locked by the user %s.\nThe user can be logged out now."), escaped_username); + enableLogoutButton = TRUE; + } + + gtk_label_set_markup(GTK_LABEL(lockLabel), message); + g_free(message); + + update(); + + return ret; +} + +static void update_logout_time() { + if (do_update_logout_time(NULL)) + g_timeout_add_seconds(1, do_update_logout_time, NULL); +} + +static void lock(void) { + if (state != LOCKED) + return; + + DEBUG("lock"); + + update(); + grab_devices(); + gtk_widget_grab_focus(promptEntry); +} + +static int ulock_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { + char *password = appdata_ptr; + + *resp = calloc(num_msg, sizeof(struct pam_response)); + int i; + for (i = 0; i < num_msg; i++) { + if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) + resp[i]->resp = strdup(password); + } + + return 0; +} + +static gboolean try_unlock_return(gpointer message) { + DEBUG("try_unlock_return"); + + if (message) { + state = LOCKED; + gtk_entry_set_text(GTK_ENTRY(promptEntry), ""); + gtk_label_set_label(GTK_LABEL(messageLabel), message); + lock(); + } + else { + gtk_main_quit(); + } + + return FALSE; +} + +/* this thread must not access any GTK resources */ +static void* try_unlock_thread(void *arg) { + const struct pam_conv conv = {.conv = ulock_conv, .appdata_ptr = arg}; + + pam_handle_t *handle = NULL; + int ret = pam_start("login", username, &conv, &handle); + + if (!ret) + ret = pam_authenticate(handle, 0); + + const char *message = NULL; + if (ret) + message = pam_strerror(handle, ret); + + pam_end(handle, ret); + + g_idle_add(try_unlock_return, (gpointer)message); + + free(arg); + return NULL; +} + +static void try_unlock(void) { + if (state != LOCKED) + return; + + DEBUG("try_unlock"); + + state = UNLOCKING; + update(); + gtk_label_set_label(GTK_LABEL(messageLabel), ""); + + pthread_t thread; + pthread_create(&thread, NULL, try_unlock_thread, strdup((char*)gtk_entry_get_text(GTK_ENTRY(promptEntry)))); + pthread_detach(thread); +} + +static void logout(void) { + if (state != LOCKED) + return; + + if (!logoutCommand) + return; + + if (logoutTime > 0) + return; + + DEBUG("logout"); + + state = LOGOUT; + update(); + + system(logoutCommand); +} + +static GdkFilterReturn xevent_filter(GdkXEvent *xevent, GdkEvent *event, gpointer data) { + XEvent *ev = xevent; + + switch (ev->xany.type) { + case MapNotify: + case ConfigureNotify: + if (ev->xany.window != gdk_x11_window_get_xid(gtk_widget_get_window(window))) + gtk_window_present(GTK_WINDOW(window)); + break; + + default: + break; + } + + return GDK_FILTER_CONTINUE; +} + + +static void create_lock_window(void) { + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_window_set_decorated(GTK_WINDOW(window), FALSE); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(window), TRUE); + gtk_window_set_skip_pager_hint(GTK_WINDOW(window), TRUE); + gtk_window_set_keep_above(GTK_WINDOW(window), TRUE); + gtk_window_fullscreen(GTK_WINDOW(window)); + + GtkWidget *overlay = gtk_overlay_new(); + gtk_container_add(GTK_CONTAINER(window), overlay); + + GtkWidget *bg = gtk_image_new_from_file(DATA_DIR "/bg.svg"); + gtk_container_add(GTK_CONTAINER(overlay), bg); + + GtkBuilder *builder = gtk_builder_new(); + + if (!gtk_builder_add_from_file(builder, DATA_DIR "/unlock.ui", NULL)) + exit(1); + + unlockWindow = GTK_WIDGET(gtk_builder_get_object(builder, "unlock_window")); + lockLabel = GTK_WIDGET(gtk_builder_get_object(builder, "lock_label")); + promptEntry = GTK_WIDGET(gtk_builder_get_object(builder, "prompt_entry")); + messageLabel = GTK_WIDGET(gtk_builder_get_object(builder, "message_label")); + logoutButton = GTK_WIDGET(gtk_builder_get_object(builder, "logout_button")); + unlockButton = GTK_WIDGET(gtk_builder_get_object(builder, "unlock_button")); + + gtk_overlay_add_overlay(GTK_OVERLAY(overlay), unlockWindow); + + gtk_widget_show_all(overlay); + + gtk_entry_set_text(GTK_ENTRY(promptEntry), ""); + gtk_label_set_label(GTK_LABEL(messageLabel), ""); + + g_signal_connect(promptEntry, "activate", G_CALLBACK(try_unlock), NULL); + g_signal_connect(unlockButton, "clicked", G_CALLBACK(try_unlock), NULL); + g_signal_connect(logoutButton, "clicked", G_CALLBACK(logout), NULL); + g_signal_connect(window, "map-event", G_CALLBACK(lock), NULL); + g_signal_connect(window, "delete-event", G_CALLBACK(gtk_true), NULL); + + XSelectInput(gdk_x11_get_default_xdisplay(), gdk_x11_get_default_root_xwindow(), SubstructureNotifyMask); + gdk_window_add_filter(NULL, (GdkFilterFunc)xevent_filter, NULL); + + update_logout_time(); +} + +static void get_username(void) { + struct passwd *passwd = getpwuid(getuid()); + if (!passwd) + exit(2); + + username = strdup(passwd->pw_name); +} + +static void load_config(void) { + GKeyFile *keyFile = g_key_file_new(); + if (!g_key_file_load_from_file(keyFile, CONFIG_FILE, G_KEY_FILE_NONE, NULL)) + return; + + gchar *theme = g_key_file_get_string(keyFile, "ulock", "theme", NULL); + if (theme) + gtk_settings_set_string_property(gtk_settings_get_default(), "gtk-theme-name", theme, "ulock"); + + logoutTime = g_key_file_get_integer(keyFile, "ulock", "logout_timeout", NULL); + + gchar *logoutCommandConfig = g_key_file_get_string(keyFile, "ulock", "logout_string", NULL); + if (logoutCommandConfig) + logoutCommand = strdup(logoutCommandConfig); + + g_key_file_free(keyFile); +} + +int main(int argc, char *argv[]) { + get_username(); + logoutCommand = strdup("echo foo"); + + setlocale(LC_ALL, ""); + bindtextdomain("ulock", PREFIX "/share/locale"); + textdomain("ulock"); + + openlog("ulock", LOG_PID, LOG_DAEMON); + + gtk_init(&argc, &argv); + load_config(); + + create_lock_window(); + gtk_widget_show(window); + + gtk_main(); + + return 0; +}