[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: sreensaver for the console



Package: console-tools
Severity: wishlist

On Apr 13, John Haggerty <haggerjo@sophist.cs.slcc.edu> wrote:

 >This will only lock the current vt or telnet session from casual attack. 
 >The absolute best program that I have seen for console
 >locking/authentication besides some of the graphical stuff is a program
 >that is included in the debian distribution called vlock.
I wrote a similar thing. Being it such a small program I asked the
console-tools maintainer to merge it, but I never received a reply.
I'll open a wishlist bug.

/*
 * lockvt.c - Copyright 2000 by Marco d'Itri <md@linux.it>
 * You can use this software under the terms of the GPL. If we meet some day,
 * and you think this stuff is worth it, you can buy me a beer in return.
 */

/* #define _XOPEN_SOURCE */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/vt.h>
#include <pwd.h>
#include <shadow.h>

extern char *crypt(const char *, const char *);

void err_sys(const char *,...);
void sigterm(int);
int fd;

int main(void)
{
    int n = 1;
    struct spwd *sp;
    struct passwd *pw;
    char *rootpass;
    sigset_t mask;
    struct sigaction sterm;

    if ((sp = getspnam("root")) == NULL)
	err_sys("getspnam");
    if ((rootpass = malloc(strlen(sp->sp_pwdp) + 1)) == NULL)
	err_sys("malloc");
    strcpy(rootpass, sp->sp_pwdp);
    if ((pw = getpwuid(getuid())) == NULL)
	err_sys("getpwuid");
    if ((sp = getspnam(pw->pw_name)) == NULL)
	err_sys("getspnam");

    /* Don't let the user stop the program from the keyboard */
    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigaddset(&mask, SIGQUIT);
    sigaddset(&mask, SIGTSTP);
    if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
	err_sys("sigprocmask");

    sterm.sa_handler = sigterm;
    sigemptyset(&sterm.sa_mask);
    sterm.sa_flags = SA_RESTART;
    if (sigaction(SIGTERM, &sterm, NULL) < 0)
	err_sys("sigaction");

    if ((fd = open("/dev/console", O_WRONLY, 0)) < 0)
	err_sys("open(\"/dev/console\")");
    if ((ioctl(fd, VT_LOCKSWITCH) < 0))
	err_sys("ioctl(VT_LOCKSWITCH)");

    printf("Console locked by user %s.\n"
	   "(The root password will unblock too.)\n", pw->pw_name);
    while (1) {
	char *p = getpass("Password: ");
	if (strcmp(crypt(p, sp->sp_pwdp), sp->sp_pwdp) == 0 ||
	    strcmp(crypt(p, rootpass), rootpass) == 0)
	    break;
	for (; *p != '\0'; *p++ = '\0'); /* clobber the cleartext password */
	printf("Wrong password (failure #%d)!\n", n++);
    }

    for (; *p != '\0'; *p++ = '\0');	/* clobber the cleartext password */
    if ((ioctl(fd, VT_UNLOCKSWITCH) < 0))
	err_sys("ioctl(VT_UNLOCKSWITCH)");

    close(fd);
    exit(0);
}

void sigterm(int dummy)
{
    if ((ioctl(fd, VT_UNLOCKSWITCH) < 0))
	err_sys("ioctl(VT_UNLOCKSWITCH)");
    close(fd);
    exit(0);
}

void err_sys(const char *fmt,...)
{
    va_list ap;

    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    fprintf(stderr, ": %s\n", strerror(errno));
    va_end(ap);
    exit(1);
}


-- 
ciao,
Marco


Reply to: