Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * xtrlock.c
- *
- * X Transparent Lock
- *
- * Copyright (C)1993,1994 Ian Jackson
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #include <X11/X.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/keysym.h>
- #include <X11/Xos.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <errno.h>
- #include <pwd.h>
- #include <grp.h>
- #include <limits.h>
- #include <string.h>
- #include <crypt.h>
- #include <unistd.h>
- #include <math.h>
- #include <ctype.h>
- #include <values.h>
- /* required for custom passwd prompt --tetris11 */
- #include <unistd.h>
- #ifdef SHADOW_PWD
- #include <shadow.h>
- #endif
- #include "lock.bitmap"
- #include "mask.bitmap"
- #include "patchlevel.h"
- Display *display;
- Window window, root;
- #define TIMEOUTPERATTEMPT 30000
- #define MAXGOODWILL (TIMEOUTPERATTEMPT*5)
- #define INITIALGOODWILL MAXGOODWILL
- #define GOODWILLPORTION 0.3
- struct passwd *pw;
- int c_pass = 0; /* custom_password flag */
- int passwordok(const char *s) {
- if ( c_pass == 1 ) {
- return strcmp(s+1, pw->pw_passwd); /* skip first character to work --tetris11 */
- }
- #if 0
- char key[3];
- char *encr;
- key[0] = *(pw->pw_passwd);
- key[1] = (pw->pw_passwd)[1];
- key[2] = 0;
- encr = crypt(s, key);
- return !strcmp(encr, pw->pw_passwd);
- #else
- /* simpler, and should work with crypt() algorithms using longer
- salt strings (like the md5-based one on freebsd). --marekm */
- return !strcmp(crypt(s, pw->pw_passwd), pw->pw_passwd);
- #endif
- }
- int main(int argc, char **argv){
- XEvent ev;
- KeySym ks;
- char cbuf[10], rbuf[128]; /* shadow appears to suggest 127 a good value here */
- int clen, rlen=0;
- long goodwill= INITIALGOODWILL, timeout= 0;
- XSetWindowAttributes attrib;
- Cursor cursor;
- Pixmap csr_source,csr_mask;
- XColor csr_fg, csr_bg, dummy, black;
- int ret, screen, blank = 0;
- char *custom_passwd = 0;
- #define USAGE_EXIT \
- fprintf(stderr,"xtrlock (version %s); usage: xtrlock [-b] [-p]\n", program_version); \
- exit(1);
- #define CUSTOM_PROMPT "custom passphrase: "
- #ifdef SHADOW_PWD
- struct spwd *sp;
- #endif
- struct timeval tv;
- int tvt, gs;
- if (argc == 2){
- if (strcmp(argv[1], "-b") == 0 ) {
- blank = 1;
- }
- else if (strcmp(argv[1],"-p") == 0 ) {
- c_pass = 1;
- custom_passwd = getpass(CUSTOM_PROMPT);
- }
- else {USAGE_EXIT}
- }
- else if (argc == 3) {
- if (\
- (strcmp(argv[1], "-b") == 0 ) && (strcmp(argv[2], "-p") == 0) || \
- (strcmp(argv[1], "-p") == 0 ) && (strcmp(argv[2], "-b") == 0)\
- ) {
- blank = c_pass = 1;
- custom_passwd = getpass(CUSTOM_PROMPT);
- }
- else {USAGE_EXIT}
- }
- else if (argc > 1) {USAGE_EXIT}
- errno=0; pw= getpwuid(getuid());
- if (c_pass == 1) {
- /* custom password bypasses gid uid checks, but still requires
- a valid pw struct --tetris11 */
- pw->pw_passwd = custom_passwd;
- }
- else {
- if (!pw) { perror("password entry for uid not found"); exit(1); }
- #ifdef SHADOW_PWD
- sp = getspnam(pw->pw_name);
- if (sp)
- pw->pw_passwd = sp->sp_pwdp;
- endspent();
- #endif
- /* logically, if we need to do the following then the same
- applies to being installed setgid shadow.
- we do this first, because of a bug in linux. --jdamery */
- if (setgid(getgid())) { perror("setgid"); exit(1); }
- /* we can be installed setuid root to support shadow passwords,
- and we don't need root privileges any longer. --marekm */
- if (setuid(getuid())) { perror("setuid"); exit(1); }
- if (strlen(pw->pw_passwd) < 13) {
- fputs("password entry has no pwd\n",stderr); exit(1);
- }
- }
- display= XOpenDisplay(0);
- if (display==NULL) {
- fprintf(stderr,"xtrlock (version %s): cannot open display\n",
- program_version);
- exit(1);
- }
- attrib.override_redirect= True;
- if (blank) {
- screen = DefaultScreen(display);
- attrib.background_pixel = BlackPixel(display, screen);
- window= XCreateWindow(display,DefaultRootWindow(display),
- 0,0,DisplayWidth(display, screen),DisplayHeight(display, screen),
- 0,DefaultDepth(display, screen), CopyFromParent, DefaultVisual(display, screen),
- CWOverrideRedirect|CWBackPixel,&attrib);
- XAllocNamedColor(display, DefaultColormap(display, screen), "black", &black, &dummy);
- } else {
- window= XCreateWindow(display,DefaultRootWindow(display),
- 0,0,1,1,0,CopyFromParent,InputOnly,CopyFromParent,
- CWOverrideRedirect,&attrib);
- }
- XSelectInput(display,window,KeyPressMask|KeyReleaseMask);
- csr_source= XCreateBitmapFromData(display,window,lock_bits,lock_width,lock_height);
- csr_mask= XCreateBitmapFromData(display,window,mask_bits,mask_width,mask_height);
- ret = XAllocNamedColor(display,
- DefaultColormap(display, DefaultScreen(display)),
- "steelblue3",
- &dummy, &csr_bg);
- if (ret==0)
- XAllocNamedColor(display,
- DefaultColormap(display, DefaultScreen(display)),
- "black",
- &dummy, &csr_bg);
- ret = XAllocNamedColor(display,
- DefaultColormap(display,DefaultScreen(display)),
- "grey25",
- &dummy, &csr_fg);
- if (ret==0)
- XAllocNamedColor(display,
- DefaultColormap(display, DefaultScreen(display)),
- "white",
- &dummy, &csr_bg);
- cursor= XCreatePixmapCursor(display,csr_source,csr_mask,&csr_fg,&csr_bg,
- lock_x_hot,lock_y_hot);
- XMapWindow(display,window);
- /*Sometimes the WM doesn't ungrab the keyboard quickly enough if
- *launching xtrlock from a keystroke shortcut, meaning xtrlock fails
- *to start We deal with this by waiting (up to 100 times) for 10,000
- *microsecs and trying to grab each time. If we still fail
- *(i.e. after 1s in total), then give up, and emit an error
- */
- gs=0; /*gs==grab successful*/
- for (tvt=0 ; tvt<100; tvt++) {
- ret = XGrabKeyboard(display,window,False,GrabModeAsync,GrabModeAsync,
- CurrentTime);
- if (ret == GrabSuccess) {
- gs=1;
- break;
- }
- /*grab failed; wait .01s*/
- tv.tv_sec=0;
- tv.tv_usec=10000;
- select(1,NULL,NULL,NULL,&tv);
- }
- if (gs==0){
- fprintf(stderr,"xtrlock (version %s): cannot grab keyboard\n",
- program_version);
- exit(1);
- }
- if (XGrabPointer(display,window,False,(KeyPressMask|KeyReleaseMask)&0,
- GrabModeAsync,GrabModeAsync,None,
- cursor,CurrentTime)!=GrabSuccess) {
- XUngrabKeyboard(display,CurrentTime);
- fprintf(stderr,"xtrlock (version %s): cannot grab pointer\n",
- program_version);
- exit(1);
- }
- for (;;) {
- XNextEvent(display,&ev);
- switch (ev.type) {
- case KeyPress:
- if (ev.xkey.time < timeout) { XBell(display,0); break; }
- clen= XLookupString(&ev.xkey,cbuf,9,&ks,0);
- switch (ks) {
- case XK_Escape: case XK_Clear:
- rlen=0; break;
- case XK_Delete: case XK_BackSpace:
- if (rlen>0) rlen--;
- break;
- case XK_Linefeed: case XK_Return:
- if (rlen==0) break;
- rbuf[rlen]=0;
- if (passwordok(rbuf)) goto loop_x;
- XBell(display,0);
- rlen= 0;
- if (timeout) {
- goodwill+= ev.xkey.time - timeout;
- if (goodwill > MAXGOODWILL) {
- goodwill= MAXGOODWILL;
- }
- }
- timeout= -goodwill*GOODWILLPORTION;
- goodwill+= timeout;
- timeout+= ev.xkey.time + TIMEOUTPERATTEMPT;
- break;
- default:
- if (clen != 1) break;
- /* allow space for the trailing \0 */
- if (rlen < (sizeof(rbuf) - 1)){
- rbuf[rlen]=cbuf[0];
- rlen++;
- }
- break;
- }
- break;
- default:
- break;
- }
- }
- loop_x:
- exit(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement