uff67@granat.cs.tu-berlin.de (Auer u. Nickelsen) (04/15/91)
from README: A long time I was looking for a utility to lock the screen of an ASCII terminal, something like lockscreen or xlock, but didn't find anything. OK, here is "locktty". To keep it portable even for systems with a shadow password file, I keep the crypted password in a file in the user's home directory. If the file does not exist, the user is prompted for a password. The password file can be changed by using the -p option. The program is without any changes successfully tested on - SunOS 4.1, - Interactive ix/386 2.0.2, - Ultrix Worksystem V2.1 (Rev. 14), - HP-UX 7.00. Just type "make". Please send corrections, improvements, and flames to nickel@w104zrz.zrz.tu-berlin.de #!/bin/sh # This is a shell archive (produced by shar 3.49) # To extract the files from this archive, save it to a file, remove # everything above the "!/bin/sh" line above, and type "sh file_name". # # made 04/15/1991 16:15 UTC by a0528@gray3 # Source directory /usr/a0528/gaga # # existing files will NOT be overwritten unless -c is specified # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 209 -rw-r--r-- Makefile # 690 -rw-r--r-- README # 1371 -rw-r--r-- locktty.1 # 5663 -rw-r--r-- locktty.c # # ============= Makefile ============== if test -f 'Makefile' -a X"$1" != X"-c"; then echo 'x - skipping Makefile (File already exists)' else echo 'x - extracting Makefile (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile' && CC = cc LIBS = -lcurses -ltermcap SHELL = /bin/sh CFLAGS = -O SOURCE = locktty.c TARGET = locktty X $(TARGET) : $(SOURCE) X $(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(LIBS) X clean : X rm -f *.o core *~ $(TARGET) X SHAR_EOF chmod 0644 Makefile || echo 'restore of Makefile failed' Wc_c="`wc -c < 'Makefile'`" test 209 -eq "$Wc_c" || echo 'Makefile: original size 209, current size' "$Wc_c" fi # ============= README ============== if test -f 'README' -a X"$1" != X"-c"; then echo 'x - skipping README (File already exists)' else echo 'x - extracting README (Text)' sed 's/^X//' << 'SHAR_EOF' > 'README' && A long time I was looking for a utility to lock the screen of an ASCII terminal, something like lockscreen or xlock, but didn't find anything. X OK, here is "locktty". To keep it portable even for systems with a shadow password file, I keep the crypted password in a file in the user's home directory. If the file does not exist, the user is prompted for a password. X The password file can be changed by using the -p option. X The program is without any changes successfully tested on X - SunOS 4.1, X - Interactive ix/386 2.0.2, X - Ultrix Worksystem V2.1 (Rev. 14), X - HP-UX 7.00. X Just type "make". X Please send corrections, improvements, and flames to X nickel@w104zrz.zrz.tu-berlin.de SHAR_EOF chmod 0644 README || echo 'restore of README failed' Wc_c="`wc -c < 'README'`" test 690 -eq "$Wc_c" || echo 'README: original size 690, current size' "$Wc_c" fi # ============= locktty.1 ============== if test -f 'locktty.1' -a X"$1" != X"-c"; then echo 'x - skipping locktty.1 (File already exists)' else echo 'x - extracting locktty.1 (Text)' sed 's/^X//' << 'SHAR_EOF' > 'locktty.1' && .TH LOCKTTY 1L "LOCKTTY 1.0" "" .SH NAME locktty - lock terminal .SH SYNOPSIS .B locktty [ .B -p ] .PP .SH DESCRIPTION .I Locktty\^ puts the terminal into raw mode, clears the screen, and prompts the user for a password. Entered passwords are crypted and checked against a crypted password in a file in the users' home directory (~/.lockpasswd). If the correct password is given, the terminal is set into normal state again. If not, a message is given, and after some time a new password is read. .PP If the file ~/.lockpasswd does not exist, the user is prompted for a password twice before the screen is locked. This password is crypted and stored in ~/.lockpasswd. .PP The encrypted password in ~/.lockpasswd can be changed by invoking .I locktty with the .B -p option. .SH DIAGNOSTICS .TP ~/.lockpasswd in wrong format ~/.lockpasswd does not appear to be a valid password crypt. .SH FILES $HOME/.lockpasswd encrypted password .SH BUGS I haven't found a portable way to flush input before reading a new password. .br The executable is huge compared to the source, but I couldn't resist using the curses library. .br .I Locktty pretends to check the validity of ~/.lockpasswd, but checks only the length and the character set. .SH AUTHOR Juergen Nickelsen, Technische Universitaet Berlin, Germany .br nickel@w104zrz.zrz.tu-berlin.de .SH COPYRIGHTS None. SHAR_EOF chmod 0644 locktty.1 || echo 'restore of locktty.1 failed' Wc_c="`wc -c < 'locktty.1'`" test 1371 -eq "$Wc_c" || echo 'locktty.1: original size 1371, current size' "$Wc_c" fi # ============= locktty.c ============== if test -f 'locktty.c' -a X"$1" != X"-c"; then echo 'x - skipping locktty.c (File already exists)' else echo 'x - extracting locktty.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'locktty.c' && /* locktty - lock terminal X * X * compile with cc -o locktty locktty.c -lcurses -ltermcap X * Usage: locktty [ -p ] X * X * locktty puts the terminal into raw mode, clears the screen, and X * prompts the user for a password. Entered passwords are crypted and X * checked against a crypted password in a file in the users' home X * directory (~/.lockpasswd). If the correct password is given, the X * terminal is set into normal state again. If not, a messgae is X * given, and after some time a new password is read. X * If the file ~/.lockpasswd does not exist, the user is prompted for X * a password twice before the screen is locked. This password is X * crypted and stored in ~/.lockpasswd. X * The encrypted password in ~/.lockpasswd can be changed by invoking X * locktty with the -p option. X * X * Please send corrections, improvements, and flames to X * nickel@w104zrz.zrz.tu-berlin.de (Juergen Nickelsen) X */ X #include <curses.h> #include <signal.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <string.h> X #define true 1 #define false 0 X #define SIZE 1024 /* maximum size for password */ #define PFILE ".lockpasswd" /* name of password file */ #define MAXPATHLEN 4096 /* this should exceed the real value X * on nearly all machines */ #define CLEN 14 /* enough for the crypted pwd's */ #define LOCKP "Unlock: " /* prompt in "lock" mode */ #define SALTC \ X "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./" X /* characters that may appear in the salt */ char X *progname, /* the name of the game */ X newc[CLEN + 1], /* entered pwd (crypted) */ X oldc[CLEN + 1], /* old pwd (crypted) */ X pfilnam[MAXPATHLEN] ; /* name of password file */ X X main(argc, argv) int argc ; char **argv ; { X char X tmpl[SIZE+1], /* space for reading from terminal */ X *slp ; /* pointer to slash in progname */ X int pwdfile ; /* read handle for password file */ X X /* determine name of program */ X progname = *argv ; X if (slp = strrchr(progname, '/')) { X progname = slp + 1 ; X } X X /* build name of password file */ X strcpy(pfilnam, getenv("HOME")) ; X strcat(pfilnam, "/") ; X strcat(pfilnam, PFILE) ; X X prepterm() ; /* prepare terminal */ X X if (argc > 1) { /* check arguments */ X if (strcmp(argv[1], "-p") || argc != 2) { X reset() ; X usage() ; X exit(1) ; X } else { X newpwdfile() ; /* -p: new password */ X } X } X X /* Open password file. If it does not exist, create it first. */ X do { X if ((pwdfile = open(pfilnam, O_RDONLY)) == -1) { X if (errno == ENOENT) { X puts("No password file.\r") ; X newpwdfile() ; X } else { X perror(pfilnam) ; X reset() ; X exit(errno) ; X } X } X } while (pwdfile == -1) ; X X /* read and check old crypt */ X if (read(pwdfile, oldc, CLEN) != CLEN || checkoldc()) { X fputs("~/", stdout) ; X fputs(PFILE, stdout) ; X puts(" in wrong format\r") ; X reset() ; X exit(3) ; X } X X /* clear screen and read password */ X do { X clear() ; X refresh() ; X fputs(LOCKP, stdout) ; X X readpass(tmpl, false) ; X strcpy(newc, crypt(tmpl, oldc)) ; X } while (strcmp(newc, oldc) && (puts("\r\nNo way.\r"), sleep(3), 1)) ; X X /* ready */ X reset() ; X exit(0) ; } X X /* read a line in raw mode, terminated by newline or carriage return X * or exceeding SIZE. Can get interrupted by Ctrl-C if intr != 0. */ readpass(p, intr) char *p ; int intr ; { X int n ; X char c = ' ' ; X X for (n = 0; n < SIZE && c != '\r' && c != '\n'; n++) { X c = p[n] = getchar() ; X if (intr && c == '\003') { X reset() ; X exit(1) ; X } X } X p[n] = '\0' ; } X X /* prepare terminal: open stdin and stdout to /dev/tty, don't echo */ /* characters and make sure we get no signal (raw mode + some help). */ prepterm() { X int in ; X X /* we want to read the password ONLY from a terminal */ X if ((in = open("/dev/tty", O_RDWR)) == -1) { X perror("/dev/tty") ; X exit(1) ; X } X close(0) ; X dup(in) ; X close(1) ; X dup(in) ; X close(2) ; X dup(in) ; X X /* make sure we won't get interrupted */ X initscr() ; X raw() ; X /* the break key on ISC's at386 console generates a SIGINT even in X * raw mode */ X signal(SIGINT, SIG_IGN) ; X X /* don't echo keystrokes */ X noecho() ; } X X /* put terminal into a state the user is supposed to want after the */ /* termination of the program. */ reset() { X clear() ; X noraw() ; X echo() ; X endwin() ; X putchar('\r') ; X } X X /* create a new password file */ newpwdfile() { X char tmpl[SIZE+1], salt[3] ; X int out ; X X /* make salt for crypt */ X srand(time(NULL)) ; X salt[0] = SALTC[rand() % strlen(SALTC)] ; X salt[1] = SALTC[rand() % strlen(SALTC)] ; X salt[3] = '\0' ; X X /* read and verify password */ X fputs("Enter password: ", stdout) ; X readpass(tmpl, true) ; X strcpy(oldc, crypt(tmpl, salt)) ; X fputs("\r\nRetype password: ", stdout) ; X readpass(tmpl, true) ; X strcpy(newc, crypt(tmpl, salt)) ; X newc[CLEN] = '\0' ; X X if (strcmp(oldc, newc)) { X puts("\r\nNo match.\r") ; X reset() ; X exit(2) ; X } X X /* create password file */ X if ((out = open(pfilnam, O_WRONLY | O_CREAT, 0600)) == -1) { X reset() ; X perror(pfilnam) ; X exit(errno) ; X } X X /* write crypt */ X write(out, newc, CLEN) ; X close(out) ; } X X usage() { X fputs("Usage: ", stdout) ; X fputs(progname, stdout) ; X puts(" [ -p ]\r") ; } X X /* returns true if oldc does not look like a valid crypt */ checkoldc() { X int i ; X X /* check for illegal characters */ X for (i = 0; i < CLEN - 1; i++) { X if (!strchr(SALTC, oldc[i])) { X return true ; X } X } X X /* check for terminating null character */ X return oldc[i] ; } SHAR_EOF chmod 0644 locktty.c || echo 'restore of locktty.c failed' Wc_c="`wc -c < 'locktty.c'`" test 5663 -eq "$Wc_c" || echo 'locktty.c: original size 5663, current size' "$Wc_c" fi exit 0