locktty 1.1 -- lock terminal (1 of 1)
Juergen Nickelsen
nickel at kokos.cs.tu-berlin.de
Mon May 6 22:32:56 AEST 1991
>From README:
locktty 1.1
A long time I was looking for a utility to lock the screen of an ASCII
terminal, something like lockscreen or xlock on Sunview resp. X Windows,
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.
Changes to 1.0:
- crypt() and getenv() predeclared (for ANSI compilers)
- errno declared (isn't declared in every errno.h)
- inserted fflush() after every (f)puts()
- unlock prompt is really erased now
- the number of failed unlock attempts is displayed after unlock
- username and hostname are displayed in the unlock prompt
These changes were inspired or suggested by the following people:
David A. Berson, Tim Dawson, Greg Miller, Chris Phillips, Randy Hall.
The program is without any changes successfully tested on
- SunOS 4.1 on sun3, sun4, with cc, gcc, but on a sun3 with cc and -O it
throws core sometimes,
- Interactive ix/386 2.0.2,
- Ultrix Worksystem V2.1 (Rev. 14),
- HP-UX 7.00,
- IRIX System V Release 3.2.1,
- Nixdorf TOS 4.0.12,
- IBM AIX 1.2 (PS/2),
- ConvexOS Release V9.0.
To compile it under Interactive UNIX, type "make isc", otherwise just
type "make" to build locktty.
Please send corrections, improvements, and flames to
nickel at cs.tu-berlin.de (Juergen Nickelsen)
#!/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 05/06/1991 12:23 UTC by a0528 at gray3
# Source directory /usr/a0528/src/locktty
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 243 -rw-r--r-- Makefile
# 1495 -rw-r--r-- README
# 1439 -rw-r--r-- locktty.1
# 7014 -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
isc :
X make LIBS="$(LIBS) -linet"
X
clean :
X rm -f *.o core *~ $(TARGET)
SHAR_EOF
chmod 0644 Makefile ||
echo 'restore of Makefile failed'
Wc_c="`wc -c < 'Makefile'`"
test 243 -eq "$Wc_c" ||
echo 'Makefile: original size 243, 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' &&
locktty 1.1
X
A long time I was looking for a utility to lock the screen of an ASCII
terminal, something like lockscreen or xlock on Sunview resp. X Windows,
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
Changes to 1.0:
X - crypt() and getenv() predeclared (for ANSI compilers)
X - errno declared (isn't declared in every errno.h)
X - inserted fflush() after every (f)puts()
X - unlock prompt is really erased now
X - the number of failed unlock attempts is displayed after unlock
X - username and hostname are displayed in the unlock prompt
X
These changes were inspired or suggested by the following people:
David A. Berson, Tim Dawson, Greg Miller, Chris Phillips, Randy Hall.
X
The program is without any changes successfully tested on
X - SunOS 4.1 on sun3, sun4, with cc, gcc, but on a sun3 with cc and -O it
X throws core sometimes,
X - Interactive ix/386 2.0.2,
X - Ultrix Worksystem V2.1 (Rev. 14),
X - HP-UX 7.00,
X - IRIX System V Release 3.2.1,
X - Nixdorf TOS 4.0.12,
X - IBM AIX 1.2 (PS/2),
X - ConvexOS Release V9.0.
X
To compile it under Interactive UNIX, type "make isc", otherwise just
type "make" to build locktty.
X
Please send corrections, improvements, and flames to
X
X nickel at cs.tu-berlin.de (Juergen Nickelsen)
SHAR_EOF
chmod 0644 README ||
echo 'restore of README failed'
Wc_c="`wc -c < 'README'`"
test 1495 -eq "$Wc_c" ||
echo 'README: original size 1495, 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.1" ""
.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 OPTIONS
.TP
.B -p
ask for new password in ~/.lockpasswd
.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.
.br
.I Locktty
pretends to check the validity of ~/.lockpasswd, but checks only the
length and the character set.
.br
Only the first 8 characters of the password are significant.
.SH AUTHOR
Juergen Nickelsen, Technische Universitaet Berlin, Germany
.br
nickel at cs.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 1439 -eq "$Wc_c" ||
echo 'locktty.1: original size 1439, 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 * version 1.1
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 at cs.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>
#include <pwd.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 SALTC \
X "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"
X /* characters that may appear in the salt */
X
int
X uid, /* userid */
X fail_count = -1; /* number of failed unlock attempts */
X
struct passwd
X *pw_entry; /* passwd file entry */
X
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 hostname[20], /* hostname */
X prompt[40] ; /* unlock prompt */
X
extern int errno ;
extern char *getenv(), *crypt() ;
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 /* get host and user names */
X
X if (gethostname(hostname, 19) == -1) {
X hostname[0] = '\0' ;
X }
X uid = getuid() ;
X pw_entry = getpwuid(uid) ;
X
X /* note that pw_entry->pw_dir is the user's home dir */
X if (pw_entry != NULL) {
X if (hostname[0] != '\0') {
X sprintf(prompt, "Unlock %s@%s: ", pw_entry->pw_name, hostname) ;
X } else {
X sprintf(prompt, "Unlock user %s: ", pw_entry->pw_name) ;
X }
X } else if (hostname[0] != '\0') {
X sprintf(prompt, "Unlock host %s ", hostname) ;
X } else {
X sprintf(prompt, "Unlock: " ) ;
X }
X
X /* build name of password file */
X
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 fflush(stdout) ;
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 fflush(stdout) ;
X reset() ;
X exit(3) ;
X }
X
X /* clear screen and read password */
X do {
X fail_count++;
X clear() ;
X refresh() ;
X fputs(prompt, stdout) ;
X fflush(stdout) ;
X
X readpass(tmpl, false) ;
X strcpy(newc, crypt(tmpl, oldc)) ;
X } while (strcmp(newc, oldc) &&
X (puts("\r\nNo way.\r"), fflush(stdout), sleep(3), 1)) ;
X /* this is not nice, I know */
X
X /* ready */
X reset() ;
X if (fail_count) {
X printf("Failed attemps: %d\nPress return to exit ", fail_count) ;
X fflush(stdout) ;
X gets(oldc);
X }
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 = ' ' ; /* to have a value which is neither */
X /* '\n' nor '\r' */
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 int i ;
X
X /* reset modes */
X clear() ;
X noraw() ;
X echo() ;
X /* end curses */
X endwin() ;
X
X /* delete prompt */
X for (i = 0; i < strlen(prompt); i++) {
X putchar('\b');
X putchar(' ');
X putchar('\b');
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 fflush(stdout) ;
X readpass(tmpl, true) ;
X strcpy(oldc, crypt(tmpl, salt)) ;
X fputs("\r\nRetype password: ", stdout) ;
X fflush(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 fflush(stdout) ;
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 7014 -eq "$Wc_c" ||
echo 'locktty.c: original size 7014, current size' "$Wc_c"
fi
exit 0
--
Juergen Nickelsen nickel at cs.tu-berlin.de
More information about the Alt.sources
mailing list