Add option to lock TTY switching

pull/183/head
Lorian Coltof 2018-04-24 18:13:29 +02:00
parent d9bcb58cc6
commit dcfcba3ed4
3 changed files with 56 additions and 2 deletions

View File

@ -56,3 +56,7 @@ EXTRA_DIST = \
LICENSE \
README.md \
I3LOCK_VERSION
# SUID the executable so it has permissions to lock TTY switching
install-exec-hook:
chmod +s $(DESTDIR)$(bindir)/i3lock$(EXEEXT)

View File

@ -28,6 +28,7 @@ i3lock \- improved screen locker
.RB [\|\-u\|]
.RB [\|\-e\|]
.RB [\|\-f\|]
.RB [\|\-l\|]
.SH DESCRIPTION
.B i3lock
@ -105,6 +106,10 @@ your computer with the enter key.
.B \-f, \-\-show-failed-attempts
Show the number of failed attempts, if any.
.TP
.B \-l, \-\-lock-console
Lock the console to disable TTY switching (Linux only).
.TP
.B \-\-debug
Enables debug logging.

View File

@ -40,6 +40,11 @@
#endif
#include <xcb/xcb_aux.h>
#include <xcb/randr.h>
#if defined(__linux__)
#include <fcntl.h>
#include <linux/vt.h>
#include <sys/ioctl.h>
#endif
#include "i3lock.h"
#include "xcb.h"
@ -866,6 +871,11 @@ int main(int argc, char *argv[]) {
int ret;
struct pam_conv conv = {conv_callback, NULL};
#endif
#if defined(__linux__)
bool lock_tty_switching = false;
int term = -1;
#endif
int curs_choice = CURS_NONE;
int o;
int longoptind = 0;
@ -884,6 +894,7 @@ int main(int argc, char *argv[]) {
{"ignore-empty-password", no_argument, NULL, 'e'},
{"inactivity-timeout", required_argument, NULL, 'I'},
{"show-failed-attempts", no_argument, NULL, 'f'},
{"lock-console", no_argument, NULL, 'l'},
{NULL, no_argument, NULL, 0}};
if ((pw = getpwuid(getuid())) == NULL)
@ -891,7 +902,7 @@ int main(int argc, char *argv[]) {
if ((username = pw->pw_name) == NULL)
errx(EXIT_FAILURE, "pw->pw_name is NULL.\n");
char *optstring = "hvnbdc:p:ui:teI:f";
char *optstring = "hvnbdc:p:ui:teI:fl";
while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) {
switch (o) {
case 'v':
@ -949,9 +960,16 @@ int main(int argc, char *argv[]) {
case 'f':
show_failed_attempts = true;
break;
case 'l':
#if defined(__linux__)
lock_tty_switching = true;
#else
errx(EXIT_FAILURE, "TTY switch locking is only supported on Linux.");
#endif
break;
default:
errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]"
" [-i image.png] [-t] [-e] [-I timeout] [-f]");
" [-i image.png] [-t] [-e] [-I timeout] [-f] [-l]");
}
}
@ -1117,6 +1135,21 @@ int main(int argc, char *argv[]) {
if (main_loop == NULL)
errx(EXIT_FAILURE, "Could not initialize libev. Bad LIBEV_FLAGS?\n");
#if defined(__linux__)
/* Lock tty switching */
if (lock_tty_switching) {
if ((term = open("/dev/console", O_RDWR)) == -1) {
perror("error locking TTY switching: opening console failed");
}
if (term != -1 && (ioctl(term, VT_LOCKSWITCH)) == -1) {
perror("error locking TTY switching: locking console failed");
}
}
#endif
/* Explicitly call the screen redraw in case "locking…" message was displayed */
auth_state = STATE_AUTH_IDLE;
redraw_screen();
@ -1144,6 +1177,18 @@ int main(int argc, char *argv[]) {
return 0;
}
#if defined(__linux__)
/* Restore tty switching */
if (lock_tty_switching) {
if (term != -1 && (ioctl(term, VT_UNLOCKSWITCH)) == -1) {
perror("error unlocking TTY switching: unlocking console failed");
}
close(term);
}
#endif
DEBUG("restoring focus to X11 window 0x%08x\n", stolen_focus);
xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
xcb_ungrab_keyboard(conn, XCB_CURRENT_TIME);