#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define PASS_LEN 1024 #define PASS_BOX_LEN 20 #define FONT_SIZE 12 /* user and group to drop privileges to */ static const char *user = "overlord"; static const char *group = "wheel"; static const char *message = "Password"; typedef struct{unsigned long flags; unsigned long functions; unsigned long decorations; long inputMode; unsigned long status; }Hints; int width, height; char pass_buffer[PASS_LEN], passwd[PASS_LEN]; void anullate(char*, int); void catch_fire(char*, int); void draw_ui(Display*, Window, Visual*, Colormap, int); void get_passwd(Display*, Window, Visual*, Colormap, int, const char*); static const char *generate_hash(void); void window_attr(Display*, Window, int); int main(void){ struct passwd *pwd; struct group *grp; const char *hash; uid_t duid; gid_t dgid; Display *d = XOpenDisplay(NULL); if(d == NULL) catch_fire("Cannot open display\n", 1); if(!(pwd = getpwnam(user))) catch_fire("Cannot get user", 6); duid = pwd->pw_uid; if(!(grp = getgrnam(group))) catch_fire("Can't get group", 7); dgid = grp->gr_gid; int s = DefaultScreen(d); int depth = DefaultDepth(d, s); width = DisplayWidth(d, s); height = DisplayHeight(d, s); Window w; Visual *visual = DefaultVisual(d, s); Colormap cmap = DefaultColormap(d, s); // IGNORES WM RULES XSetWindowAttributes attributes; attributes.override_redirect = True; attributes.background_pixel = BlackPixel(d, s); // MAKE THE WINDOW w = XCreateWindow(d, XRootWindow(d, s), 0, 0, width, height, 0, depth, InputOutput, visual, CWBackPixel | CWOverrideRedirect, &attributes); // SET WINDOW ATTRIBUTES window_attr(d, w, s); // DRAW THE RECTANGLES AND STRINGS draw_ui(d, w, visual, cmap, s); hash = generate_hash(); crypt("", hash); // DROP PRIVILEGES if (setgroups(0, NULL) < 0) catch_fire("Can't set group", 8); if (setgid(dgid) < 0) catch_fire("Can't set group", 8); if (setuid(duid) < 0) catch_fire("Can't set group", 8); // CHECK THE DAMNED PASSWORD get_passwd(d, w, visual, cmap, s, hash); XCloseDisplay(d); return 0; } void anullate(char *str, int size){ memset(str, 0, size); } void catch_fire(char *string, int error){ fprintf(stderr, string); exit(error); } void draw_ui(Display *d, Window w, Visual *visual, Colormap cmap, int s){ //FONT SHENANIGANS char font_name[strlen("monospace-") +2]; sprintf(font_name, "monospace-%d", FONT_SIZE); XftFont *font = XftFontOpenName(d, s, font_name); // FONT COLORS XftColor xft_black, xft_white; XftColorAllocName (d, visual, cmap, "black", &xft_black); XftColorAllocName (d, visual, cmap, "white", &xft_white); XftDraw *xftdraw = XftDrawCreate(d, w, visual, cmap); //MAKE WHITE RECT int white_rect_x = width/2 - ((strlen(message) + PASS_BOX_LEN) / 2)*FONT_SIZE; int white_rect_y = height/2 - 2*FONT_SIZE; int white_rect_width = (strlen(message) + PASS_BOX_LEN)*FONT_SIZE; int white_rect_height = 4*FONT_SIZE; XftDrawRect(xftdraw, &xft_white, white_rect_x, white_rect_y, white_rect_width, white_rect_height); // MAKE BLACK RECT int black_rect_x = width/2 - ((PASS_BOX_LEN - strlen(message)) / 2)*FONT_SIZE; int black_rect_y = height/2 - 2*FONT_SIZE + FONT_SIZE/2; int black_rect_width = (PASS_BOX_LEN * FONT_SIZE) - FONT_SIZE/2; int black_rect_height = 3*FONT_SIZE; XftDrawRect(xftdraw, &xft_black, black_rect_x, black_rect_y, black_rect_width, black_rect_height); // PRINT PASS MESSAGE XftDrawString8(xftdraw, &xft_black, font, white_rect_x + FONT_SIZE/2, height/2 + FONT_SIZE/2 , message, strlen(message)); // PRINT ASTERISKS char pass_asterisks[PASS_BOX_LEN + 1]; int i = 0; for(i = 0; i < strlen(passwd) && i < PASS_BOX_LEN; ++i){ pass_asterisks[i] = '*'; } pass_asterisks[i] = '\0'; XftDrawString8(xftdraw, &xft_white, font, black_rect_x + FONT_SIZE/2, height/2 + FONT_SIZE/2 , pass_asterisks, strlen(pass_asterisks)); } void window_attr(Display *d, Window w, int s){ int mode_count; // VIDEO MODES XF86VidModeModeInfo **modes, *video_mode; XF86VidModeGetAllModeLines(d, s, &mode_count, &modes); video_mode = modes[0]; // DISABLE DECORATIONS Hints hints; hints.flags = 2; hints.decorations = 0; Atom roperty = XInternAtom(d, "_MOTIF_WM_HINTS", True); XSelectInput(d, w, ExposureMask | KeyPressMask); XMapWindow(d, w); // SETTING FULLSCREEN XF86VidModeSwitchToMode(d, s, video_mode); XF86VidModeSetViewPort(d, s, 0, 0); XMoveResizeWindow(d, w, 0, 0, width, height); XMapRaised(d, w); XGrabPointer(d, w, True, 0, GrabModeAsync, GrabModeAsync, w, 0L, CurrentTime); XGrabKeyboard(d, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); } void get_passwd(Display *d, Window w, Visual *v, Colormap cmap, int screen, const char *hash){ int num, failure = 0, check = 1; unsigned int len = 0; char *input_hash; KeySym ksym; XEvent e; // CHECK PASSWORD while(1){ XNextEvent(d, &e); if(e.type == KeyPress){ anullate(pass_buffer, sizeof(pass_buffer)); num = XLookupString(&e.xkey, pass_buffer, sizeof(pass_buffer), &ksym, 0); if(IsKeypadKey(ksym)){ if(ksym == XK_KP_Enter) ksym = XK_Return; else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; } if (IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) continue; switch(ksym){ case XK_Return: passwd[len] = '\0'; if(!(input_hash = crypt(passwd, hash))){ fprintf(stderr, "loqy : crypt error : %s\n", strerror(errno)); fprintf(stderr, "%d %d\n", errno, EINVAL); } else check = !!strcmp(input_hash, hash); if(check){ XBell(d, 100); failure = 1; } anullate(passwd, sizeof(passwd)); len = 0; break; case XK_Escape: anullate(passwd, sizeof(passwd)); len = 0; break; case XK_BackSpace: if(len) passwd[--len] = '\0'; break; default: if(num && !iscntrl((int)pass_buffer[0]) && (len + num < sizeof(passwd))){ memcpy(passwd + len, pass_buffer, num); len += num; } break; } draw_ui(d, w, v, cmap, screen); if(!check) exit(0); } } } static const char *generate_hash(void){ const char *hash; struct passwd *pw; if(!(pw = getpwuid(getuid()))) catch_fire("Cannot get password info\n", 2); hash = pw->pw_passwd; if(!strcmp(hash, "x")){ struct spwd *sp; if(!(sp = getspnam(pw->pw_name))) catch_fire("cannot retrieve shadow entry. ", 69); hash = sp->sp_pwdp; } if(!strcmp(hash, "*")) catch_fire("slock: getpwuid: cannot retrieve shadow entry. ", 98); return hash; }