lockscreen (with fewer bugs, I hope)

Andrea Malagoli malagoli at oddjob.uchicago.edu
Fri Oct 5 08:55:55 AEST 1990


I post here a version of lockscreen that has been modified according
to the many useful suggestions I got from readers of this newsgroup.
Thanks to all of them !  The program is still not 100% safe, but it
works fine on several Irises. 

A problem seemed to occurr when an Iris is running yellow
pages. I thought that getpwuid() and getuid() would work even on a
yp client, but apparently this is not the case. Does anyone know the
solution to this problem ?

Thanks in advance.

Andrea Malagoli
Astronomy Department
University of Chicago
e-mail: malagoli at mhd4.uchicago.edu

-------------------------------cut here--------------------------------
/*
 *     L O C K S C R E E N
 *
 *  lockscreen utiliy for the SGI machines
 *
 *  lockscreen allows a user to lock the access to the monitor
 *  without logging out. This is useful when one needs to go
 *  out of the office and does not want to leave the machine 
 *  accessible to anybody.
 *
 *  After calling lockscreen, the screen gets blank and a bouncing
 *  ball appears on a black background. To unlock, press the 
 *  RIGHT MOUSE BUTTON. When the prompt asking for the password
 *  appears, just enter the correct password.
 *
 *  Just compile with  
 *        cc -o lockscreen lockscreen.c -lgl_s -lc_s
 *
 *  This code has been written borrowing some routines available
 *  in  4Dgifts/examples/grafix.
 *
 *  WRITTEN BY:  Andrea Malagoli
 *               Astronomy Department
 *               University of Chicago
 *               malagoli at mhd.uchicago.edu
 *
 *  DATE: 15 June 1990
 * 
 *  LAST MODIFIED: 4 October 1990. 
 *				   Added capability of diplaying 
 *				   text at the center of the screen
 *				   when the ball is bouncing. You
 *			           need to compile with the -DTXT
 *				   flag. The current text is
 *				   "CLASSIFIED PROCESSING", but one
 *				   can change it to whatever.
 *
 *				   - Added an open to /dev/console
 *				    to prevent remote users to run
 *                                  lockscreen and seize the screen.
 * 				   - Added possibility for root to
 * 				    unlock the screen, by simply typing
 *  		                    the super-user password in.
 *				    To prevent this, compile with the
 *				    -DNOROOT flag.
 *                                 ( Modifications suggested by 
 *				     Dan Watts of Ki Research, Inc.).
 *
 *  (KNOWN) BUGS: A remote user can still seize the console terminal
 *                by modifing the source code, or by writing a similar
 *                application that does not open /dev/console. I am not
 *		  sure how to go around this.
 *
 */


#include <sys/types.h>
#include <gl.h>
#include <device.h>
#include <pwd.h>
#include <string.h>
#include <fcntl.h>

int fcons;     /* Console file descriptor */

/* These lines contain the color and the text of the line
 * printed when the bouncing ball is running. You can change
 * both the color and the text here.
 */
#ifdef TXT
int colortxt = GREEN;
static char myline[]="CLASSIFIED PROCESSING";
#endif TXT

Icoord maxxval;            /* width of prompt window ( in screen coords) */
char filename[20];         /* array to store standard input for the prompt */

struct passwd mypwd;       /* User information from /etc/passwd */

static char fprompt[80] = "Enter Password for ";
char *prompt, *prompt1;

int curpos, prevpos;       /* cursor current and previous positions */
long xvelocity = 0, yvelocity = 0;  /* initial ball velocity */
int iter=1;


#define XMIN  0
#define XMAX  XMAXSCREEN
#define YMIN  0
#define YMAX  YMAXSCREEN

            /* setup for the prompt box */
Screencoord mask1, mask2, mask3, mask4;  /* full window */

main()
{
        Device dev;
        short val;
        int check_pwd();

	if( (fcons = open("/dev/console", O_RDWR)) == -1 ) {
			printf("Cannot start lockscreen\n");
			exit(1);
	}

        init();
	hyde_cursor();

        mypwd = *getpwuid( getuid() ); /* Get User ID and 
					* encrypted password */

        prompt1 = strcat(fprompt,mypwd.pw_name);  /* Set the prompt */
        prompt  = strcat(prompt1,": ");

        xvelocity = (long int) (rand(0.6)/32767.*150);
        yvelocity = (long int) (rand(0.3)/32767.*150);

        /* process events forever */
        while(TRUE) {

            drawball();

            while( qtest() ){
            dev=qread(&val);
            switch(dev) {
                case RIGHTMOUSE:
                    if(val) {

			singlebuffer();
			gconfig();

			color( BLUE );
			clear();
			mktxtport();
			  if(check_pwd(filename) == 1){
			       endit(); 
			       break;
			  } else {
			       doublebuffer();
			       gconfig();
			       break;
			  }
                        }
                    break;
                default:
                    break;
            }
	    }
        } 
}


endit() {
    close( fcons );
    gexit();
    exit(0);
}


init() {                               /* do all the basic graphics setup */
    ginit();
    doublebuffer();
    gconfig();
    maxxval = 590;                   /* prompt window's width in pixels */
    qdevice(RIGHTMOUSE);
}


#ifdef TXT
write_txt()
{
	color(colortxt);
	cmov2i( (XMAX-strwidth(myline))/2, YMAX/2);
	charstr(myline);
}
#endif TXT

/* screen positionings of prompt box */
#define FILEX 340
#define FILEY 500
#define FILEYHI (30+FILEY)        /* 30 pixels hi */
#define TEXTX (FILEX+5)
#define TEXTY (FILEY+10)

/* Clear prompt, move to start of prompt box, and output requested prompt */
clearprompt(prmpt)
char *prmpt;
{ 
    color(WHITE); 
    rectfi(FILEX, FILEY, (Screencoord)(FILEX+maxxval-6), FILEYHI);
    color(BLACK);
    linewidth(2);
    recti(FILEX+2, FILEY+2, FILEX+maxxval-6, FILEYHI-3);
    linewidth(1);
    cmov2i(TEXTX, TEXTY);
    charstr(prmpt); 
}


mktxtport()                             /* get name of file */
{
    int curstrlen;
    short c; 
    char *cc = "a";
    char *str;
    Device dev;
    long maxwidth;
    size_t maxlen = sizeof(filename);
    char *prmpt;

    prmpt = prompt;
    maxwidth = (XMAXSCREEN-11) - (FILEX + strwidth(prmpt));
        
    /* display prompt */
    curstrlen = 0;
    clearprompt(prmpt);

    curpos = TEXTX + strwidth(prmpt) + 2;
    prevpos = curpos;
    draw_bar();

    qdevice(KEYBD);
    /* read until carriage return or linefeed */
    while(dev = qread(&c)) {
        if(dev != KEYBD)
            continue;            /* don't care */
        switch(c) {
            case '\027':         /* ctrl-W sets back to start of prompt */
                curstrlen = 0;
                clearprompt(prmpt);
                prevpos = curpos;
                curpos = TEXTX + strwidth(prmpt) + 2;
                draw_bar();
                break;
            case '\n':
            case '\r':
                goto done;
            case '\b':
                if(curstrlen) {
		    *cc = filename[--curstrlen];
                    filename[curstrlen] = '\0';
                    clearprompt(prmpt);
                    /* display rightmost portion */
                    for(str=filename; *str && strwidth(str) > maxwidth; str++);
                    prevpos = curpos;
		    curpos = curpos - strwidth(cc);
		    draw_bar();
                }
                break;
            default:
                if( curstrlen > 20 ) break;
                str = &filename[curstrlen];
                filename[curstrlen++] = c;
                filename[curstrlen] = '\0';
                *cc = c;
                prevpos = curpos;
		curpos = curpos + strwidth(cc);
		draw_bar();
            break;
        }
    }

done:
    unqdevice(KEYBD);
}


int check_pwd(pww)
char *pww;
{
        struct passwd rootpwd;    /* Root information from /etc/passwd */
	char salt[3];

        mypwd = *getpwuid( getuid() ); /* Get User ID and 
					* encrypted password */
	strncpy(salt, mypwd.pw_passwd, 2);
	if( strcmp(mypwd.pw_passwd,crypt(pww,salt)) == 0 ){
 			return 1;
#ifdef NOROOT
	} else return 0;
#else NOROOT
        } else  { rootpwd = *getpwnam("root"); /* Get root encrypted password */
                  strncpy(salt, rootpwd.pw_passwd, 2);
	          if( strcmp(rootpwd.pw_passwd,crypt(pww,salt)) == 0 ) {
		         return 1;  /* We can also enter root password */
		  } else return 0;
        }
#endif NOROOT
}


drawball()
{
      static xpos = 500,ypos = 500;
      long radius = 20;

      if( iter >= 200 ) {
          xvelocity = (long int) (rand(0.6)/32767.*60);
          yvelocity = (long int) (rand(0.3)/32767.*60);
          iter = 0;
      }
      iter++;

      color(BLACK);
      clear();

#ifdef TXT
      write_txt();
#endif TXT

      xpos += xvelocity;
      ypos += yvelocity;
      if (xpos > XMAX - radius ||
          xpos < XMIN + radius) {
	  xpos -= xvelocity;
          xvelocity = -xvelocity;
     }
     if (ypos > YMAX - radius ||
         ypos < YMIN + radius) {
         ypos -= yvelocity;
         yvelocity = -yvelocity;
     }
     color(YELLOW);
     circfi(xpos, ypos, radius);
     swapbuffers();
}


hyde_cursor()
{
	short index;
	static short  blank[16][16]={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                              	     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	                             {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

	curstype(C16X1);
	drawmode(CURSORDRAW);
	defcursor(1, blank);
	setcursor(1, 0, 0);
	drawmode(NORMALDRAW);
}


draw_bar()
{
	static int ydown = (FILEY + 5);
	static int yup   = (FILEYHI - 7);
	int vert[2];

        linewidth(1);
	if( prevpos != curpos ){
		color( WHITE );
		
		bgnline();
		vert[0] = prevpos; vert[1] = ydown;
		v2i(vert);
		vert[0] = prevpos; vert[1] = yup;
		v2i(vert);
		endline();

		color( BLACK );
		
		bgnline();
		vert[0] = curpos; vert[1] = ydown;
		v2i(vert);
		vert[0] = curpos; vert[1] = yup;
		v2i(vert);
		endline();
	} else {
		color( BLACK );
		
		bgnline();
		vert[0] = curpos; vert[1] = ydown;
		v2i(vert);
		vert[0] = curpos; vert[1] = yup;
		v2i(vert);
		endline();
	}
}



More information about the Comp.sys.sgi mailing list