aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Magahern <james@magahern.com>2019-01-19 20:17:41 -0800
committerJames Magahern <james@magahern.com>2019-01-19 20:17:41 -0800
commit5087ea7538c32d953705f0352227648ecd8e33f0 (patch)
tree397d9b897a1eae9fb38648788c3eb49bfd68ac1b
parentAuthentication now works (diff)
Changes to get it to work with xsecurelock
Only thing left to do is to get it to read the screen dimensions, since apparently we don't get window changed events.
-rw-r--r--meson.build2
-rw-r--r--src/main.c49
-rw-r--r--src/x11_support.c40
3 files changed, 79 insertions, 12 deletions
diff --git a/meson.build b/meson.build
index fab674f..2bbb9b3 100644
--- a/meson.build
+++ b/meson.build
@@ -29,7 +29,7 @@ resources = gnome.compile_resources(
c_name: 'as'
)
-executable('buzzlocker',
+executable('auth_buzzlocker',
sources: sources + resources,
dependencies: dependencies,
install: true
diff --git a/src/main.c b/src/main.c
index 5edb881..fc00437 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,12 +8,14 @@
#include "render.h"
#include "x11_support.h"
+#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
+static const int kXSecureLockCharFD = 0;
static const size_t kMaxPasswordLength = 128;
static inline saver_state_t* saver_state(void *c)
@@ -35,6 +37,40 @@ static void window_changed_size(saver_state_t *state, XConfigureEvent *event)
cairo_xlib_surface_set_size(state->surface, event->width, event->height);
}
+static void handle_xsl_key_input(saver_state_t *state, const char c)
+{
+ char *password_buf = state->password_buffer;
+ size_t pw_len = strlen(password_buf);
+ switch (c) {
+ case '\b': // Backspace.
+ if (pw_len > 0) {
+ password_buf[pw_len - 1] = '\0';
+ }
+ break;
+ case '\177': // Delete
+ break;
+ case '\001': // Ctrl-A.
+ // TODO: cursor movement
+ break;
+ case '\025': // Ctrl-U.
+ // TODO: clear line
+ break;
+ case 0: // Shouldn't happen.
+ case '\033': // Escape.
+ break;
+ case '\r': // Return.
+ case '\n': // Return.
+ accept_password(state);
+ break;
+ default:
+ if (pw_len + 1 < state->password_buffer_len) {
+ password_buf[pw_len] = c;
+ password_buf[pw_len + 1] = '\0';
+ }
+ break;
+ }
+}
+
static void handle_key_event(saver_state_t *state, XKeyEvent *event)
{
if (!state->input_allowed) return;
@@ -65,6 +101,13 @@ static int poll_events(saver_state_t *state)
XEvent e;
const bool block_for_next_event = false;
+ // Via xsecurelock, take this route
+ char buf;
+ ssize_t read_res = read(kXSecureLockCharFD, &buf, 1);
+ if (read_res > 0) {
+ handle_xsl_key_input(state, buf);
+ }
+
// Temp: this should be handled by x11_support
Display *display = cairo_xlib_surface_get_display(state->surface);
for (;;) {
@@ -208,6 +251,8 @@ static int runloop(cairo_surface_t *surface)
state.input_allowed = false;
state.password_prompt = "";
state.is_authenticated = false;
+ state.canvas_width = 800;
+ state.canvas_height = 600;
auth_callbacks_t callbacks = {
.info_handler = callback_show_info,
@@ -257,6 +302,10 @@ int main(int argc, char **argv)
exit(1);
}
+ // Make it so reading from the xsecurelock file descriptor doesn't block
+ int flags = fcntl(kXSecureLockCharFD, F_GETFL, 0);
+ fcntl(kXSecureLockCharFD, F_SETFL, flags | O_NONBLOCK);
+
// Docs say this must be called whenever the size of the window changes
cairo_xlib_surface_set_size(surface, default_width, default_height);
diff --git a/src/x11_support.c b/src/x11_support.c
index 87dd1ac..8ab05c1 100644
--- a/src/x11_support.c
+++ b/src/x11_support.c
@@ -12,6 +12,33 @@
static Window __window = { 0 };
static Display *__display = NULL;
+static Window get_window_from_environment_or_make_one(Display *display, int width, int height)
+{
+ Window window;
+
+ const char *env_window = getenv("XSCREENSAVER_WINDOW");
+ if (env_window != NULL && env_window[0] != 0) {
+ char *endptr = NULL;
+ unsigned long long number = strtoull(env_window, &endptr, 0);
+ window = (Window)number;
+ } else {
+ // Presumably this is for debugging
+ Window root_window = DefaultRootWindow(__display);
+ window = XCreateSimpleWindow(
+ display, // display
+ root_window, // parent window
+ 0, 0, // x, y
+ width, // width
+ height, // height
+ 0, // border_width
+ 0, // border
+ 0 // background
+ );
+ }
+
+ return window;
+}
+
cairo_surface_t* x11_helper_acquire_cairo_surface(int width, int height)
{
__display = XOpenDisplay(NULL);
@@ -20,17 +47,8 @@ cairo_surface_t* x11_helper_acquire_cairo_surface(int width, int height)
return NULL;
}
- Window root_window = DefaultRootWindow(__display);
- __window = XCreateSimpleWindow(
- __display, // display
- root_window, // parent window
- 0, 0, // x, y
- width, // width
- height, // height
- 0, // border_width
- 0, // border
- 0 // background
- );
+ // Create (or get) window
+ __window = get_window_from_environment_or_make_one(__display, width, height);
// Enable key events
XSelectInput(__display, __window, ButtonPressMask | KeyPressMask | StructureNotifyMask);