X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=i3lock.c;h=945be9fa1cc4c5a8fb794c733a5a4edb2909fe8f;hb=698204a98784a73916e3de4827ca739e88532492;hp=2110fef24c485e5aefe0fe91ea982083cd5a8a35;hpb=c1de1178254c786d9cd4fe2b36f72e6e26778f57;p=i3%2Fi3lock diff --git a/i3lock.c b/i3lock.c index 2110fef..945be9f 100644 --- a/i3lock.c +++ b/i3lock.c @@ -18,7 +18,11 @@ #include #include #include +#ifdef __OpenBSD__ +#include +#else #include +#endif #include #include #include @@ -28,6 +32,9 @@ #include #include #include +#ifdef __OpenBSD__ +#include /* explicit_bzero(3) */ +#endif #include "i3lock.h" #include "xcb.h" @@ -49,7 +56,9 @@ char color[7] = "ffffff"; uint32_t last_resolution[2]; xcb_window_t win; static xcb_cursor_t cursor; +#ifndef __OpenBSD__ static pam_handle_t *pam_handle; +#endif int input_position = 0; /* Holds the password you enter (in UTF-8). */ static char password[512]; @@ -158,6 +167,11 @@ static bool load_compose_table(const char *locale) { * */ static void clear_password_memory(void) { +#ifdef __OpenBSD__ + /* Use explicit_bzero(3) which was explicitly designed not to be + * optimized out by the compiler. */ + explicit_bzero(password, strlen(password)); +#else /* A volatile pointer to the password buffer to prevent the compiler from * optimizing this out. */ volatile char *vpassword = password; @@ -167,6 +181,7 @@ static void clear_password_memory(void) { * compiler from optimizing the calls away, since the value of 'beep' * is not known at compile-time. */ vpassword[c] = c + (int)beep; +#endif } ev_timer *start_timer(ev_timer *timer_obj, ev_tstamp timeout, ev_callback_t callback) { @@ -253,6 +268,19 @@ static void input_done(void) { unlock_state = STATE_STARTED; redraw_screen(); +#ifdef __OpenBSD__ + struct passwd *pw; + + if (!(pw = getpwuid(getuid()))) + errx(1, "unknown uid %u.", getuid()); + + if (auth_userokay(pw->pw_name, NULL, NULL, password) != 0) { + DEBUG("successfully authenticated\n"); + clear_password_memory(); + + exit(0); + } +#else if (pam_authenticate(pam_handle, 0) == PAM_SUCCESS) { DEBUG("successfully authenticated\n"); clear_password_memory(); @@ -266,6 +294,7 @@ static void input_done(void) { exit(0); } +#endif if (debug_mode) fprintf(stderr, "Authentication failure\n"); @@ -597,6 +626,7 @@ void handle_screen_resize(void) { redraw_screen(); } +#ifndef __OpenBSD__ /* * Callback function for PAM. We only react on password request callbacks. * @@ -627,6 +657,7 @@ static int conv_callback(int num_msg, const struct pam_message **msg, return 0; } +#endif /* * This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb. @@ -782,11 +813,13 @@ int main(int argc, char *argv[]) { struct passwd *pw; char *username; char *image_path = NULL; +#ifndef __OpenBSD__ int ret; struct pam_conv conv = {conv_callback, NULL}; +#endif int curs_choice = CURS_NONE; int o; - int optind = 0; + int longoptind = 0; struct option longopts[] = { {"version", no_argument, NULL, 'v'}, {"nofork", no_argument, NULL, 'n'}, @@ -810,7 +843,7 @@ int main(int argc, char *argv[]) { errx(EXIT_FAILURE, "pw->pw_name is NULL.\n"); char *optstring = "hvnbdc:p:ui:teI:f"; - while ((o = getopt_long(argc, argv, optstring, longopts, &optind)) != -1) { + while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) { switch (o) { case 'v': errx(EXIT_SUCCESS, "version " VERSION " © 2010 Michael Stapelberg"); @@ -861,7 +894,7 @@ int main(int argc, char *argv[]) { ignore_empty_password = true; break; case 0: - if (strcmp(longopts[optind].name, "debug") == 0) + if (strcmp(longopts[longoptind].name, "debug") == 0) debug_mode = true; break; case 'f': @@ -877,16 +910,20 @@ int main(int argc, char *argv[]) { * the unlock indicator upon keypresses. */ srand(time(NULL)); +#ifndef __OpenBSD__ /* Initialize PAM */ if ((ret = pam_start("i3lock", username, &conv, &pam_handle)) != PAM_SUCCESS) errx(EXIT_FAILURE, "PAM: %s", pam_strerror(pam_handle, ret)); if ((ret = pam_set_item(pam_handle, PAM_TTY, getenv("DISPLAY"))) != PAM_SUCCESS) errx(EXIT_FAILURE, "PAM: %s", pam_strerror(pam_handle, ret)); +#endif -/* Using mlock() as non-super-user seems only possible in Linux. Users of other - * operating systems should use encrypted swap/no swap (or remove the ifdef and - * run i3lock as super-user). */ +/* Using mlock() as non-super-user seems only possible in Linux. + * Users of other operating systems should use encrypted swap/no swap + * (or remove the ifdef and run i3lock as super-user). + * Alas, swap is encrypted by default on OpenBSD so swapping out + * is not necessarily an issue. */ #if defined(__linux__) /* Lock the area where we store the password in memory, we don’t want it to * be swapped to disk. Since Linux 2.6.9, this does not require any @@ -940,11 +977,11 @@ int main(int argc, char *argv[]) { errx(EXIT_FAILURE, "Could not load keymap"); const char *locale = getenv("LC_ALL"); - if (!locale) + if (!locale || !*locale) locale = getenv("LC_CTYPE"); - if (!locale) + if (!locale || !*locale) locale = getenv("LANG"); - if (!locale) { + if (!locale || !*locale) { if (debug_mode) fprintf(stderr, "Can't detect your locale, fallback to C\n"); locale = "C";