Skip to content

Commit

Permalink
Merge remote-tracking branch 'gdamjan/delay-password'
Browse files Browse the repository at this point in the history
This does slightly change the semantics of gdamjan/delay-password:
* I removed '-g', I want to be careful with adding shortopts in case
  upstream Swaylock adds new shortopts with the same name
* '--indicator' shows the indicator regardless of the auth state
  ('--indicator-idle-visible' can be used to show the indicator
  only after the grace period)
* After the timeout, the state is set to IDLE, not INVALID,
  since that seems more semantically correct
* Change the names of things to be more consistent
  (preauth -> grace, require_authentication -> end_grace_period)
  • Loading branch information
mortie committed Apr 23, 2020
2 parents 152c638 + 3aeb099 commit c0f6b94
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
2 changes: 2 additions & 0 deletions include/swaylock.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum auth_state {
AUTH_STATE_BACKSPACE,
AUTH_STATE_VALIDATING,
AUTH_STATE_INVALID,
AUTH_STATE_GRACE,
};

struct swaylock_colorset {
Expand Down Expand Up @@ -72,6 +73,7 @@ struct swaylock_args {
bool clock;
char *timestr;
char *datestr;
uint32_t password_grace_period;
};

struct swaylock_password {
Expand Down
46 changes: 46 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,27 @@
#include "wlr-screencopy-unstable-v1-client-protocol.h"
#include "xdg-output-unstable-v1-client-protocol.h"

// returns a positive integer in milliseconds
static uint32_t parse_seconds(const char *seconds) {
char *endptr;
errno = 0;
float val = strtof(seconds, &endptr);
if (errno != 0) {
swaylock_log(LOG_DEBUG, "Invalid number for seconds %s, defaulting to 0", seconds);
return 0;
}
if (endptr == seconds) {
swaylock_log(LOG_DEBUG, "No digits were found in %s, defaulting to 0", seconds);
return 0;
}
if (val < 0) {
swaylock_log(LOG_DEBUG, "Negative seconds not allowed for %s, defaulting to 0", seconds);
return 0;
}

return (uint32_t)floor(val * 1000);
}

static uint32_t parse_color(const char *color) {
if (color[0] == '#') {
++color;
Expand Down Expand Up @@ -786,6 +807,7 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
LO_CLOCK,
LO_TIMESTR,
LO_DATESTR,
LO_GRACE,
};

static struct option long_options[] = {
Expand Down Expand Up @@ -853,6 +875,7 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
{"clock", no_argument, NULL, LO_CLOCK},
{"timestr", required_argument, NULL, LO_TIMESTR},
{"datestr", required_argument, NULL, LO_DATESTR},
{"grace", required_argument, NULL, LO_GRACE},
{0, 0, 0, 0}
};

Expand All @@ -871,6 +894,8 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
"Show current count of failed authentication attempts.\n"
" -f, --daemonize "
"Detach from the controlling terminal after locking.\n"
" --grace <seconds> "
"Password grace period. Don't require the password for the first N seconds.\n"
" -h, --help "
"Show help message and quit.\n"
" -i, --image [[<output>]:]<path> "
Expand Down Expand Up @@ -1358,6 +1383,11 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
state->args.datestr = strdup(optarg);
}
break;
case LO_GRACE:
if (state) {
state->args.password_grace_period = parse_seconds(optarg);
}
break;
default:
fprintf(stderr, "%s", usage);
return 1;
Expand Down Expand Up @@ -1451,6 +1481,13 @@ static void display_in(int fd, short mask, void *data) {
}
}

static void end_grace_period(void *data) {
struct swaylock_state *state = data;
if (state->auth_state == AUTH_STATE_GRACE) {
state->auth_state = AUTH_STATE_IDLE;
}
}

static void comm_in(int fd, short mask, void *data) {
if (read_comm_reply()) {
// Authentication succeeded
Expand Down Expand Up @@ -1503,6 +1540,7 @@ int main(int argc, char **argv) {
.clock = false,
.timestr = strdup("%T"),
.datestr = strdup("%a, %x"),
.password_grace_period = 0,
};
wl_list_init(&state.images);
set_default_colors(&state.args.colors);
Expand Down Expand Up @@ -1542,6 +1580,10 @@ int main(int argc, char **argv) {
state.args.colors.line = state.args.colors.ring;
}

if (state.args.password_grace_period > 0) {
state.auth_state = AUTH_STATE_GRACE;
}

#ifdef __linux__
// Most non-linux platforms require root to mlock()
if (mlock(state.password.buffer, sizeof(state.password.buffer)) != 0) {
Expand Down Expand Up @@ -1645,6 +1687,10 @@ int main(int argc, char **argv) {

loop_add_timer(state.eventloop, 1000, timer_render, &state);

if (state.args.password_grace_period > 0) {
loop_add_timer(state.eventloop, state.args.password_grace_period, end_grace_period, &state);
}

state.run_display = true;
while (state.run_display) {
errno = 0;
Expand Down
5 changes: 5 additions & 0 deletions password.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ static void submit_password(struct swaylock_state *state) {

void swaylock_handle_key(struct swaylock_state *state,
xkb_keysym_t keysym, uint32_t codepoint) {
// Authentication not needed
if (state->auth_state == AUTH_STATE_GRACE) {
state->run_display = false;
return;
}
// Ignore input events if validating
if (state->auth_state == AUTH_STATE_VALIDATING) {
return;
Expand Down
3 changes: 2 additions & 1 deletion render.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ void render_frame(struct swaylock_surface *surface) {
state->args.show_indicator && (state->auth_state != AUTH_STATE_IDLE ||
state->args.indicator_idle_visible);

if (state->args.indicator || upstream_show_indicator) {
if (state->args.indicator ||
(upstream_show_indicator && state->auth_state != AUTH_STATE_GRACE)) {
// Draw circle
cairo_set_line_width(cairo, arc_thickness);
cairo_arc(cairo, buffer_width / 2, buffer_diameter / 2, arc_radius,
Expand Down

0 comments on commit c0f6b94

Please sign in to comment.