loqy/main.c

357 lines
7.4 KiB
C
Raw Permalink Normal View History

2022-02-27 12:59:54 +01:00
#include <crypt.h>
#include <shadow.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include <X11/Xutil.h>
#include <X11/Xft/Xft.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/extensions/xf86vmode.h>
2022-02-27 17:55:44 +01:00
#define PASS_LEN 1024
#define PASS_BOX_LEN 20
#define FONT_SIZE 12
2022-02-27 12:59:54 +01:00
/* user and group to drop privileges to */
static const char *user = "overlord";
static const char *group = "wheel";
static const char *message = "Password";
2022-02-27 17:55:44 +01:00
typedef struct{unsigned long flags;
unsigned long functions;
unsigned long decorations;
long inputMode;
unsigned long status;
}Hints;
2022-02-27 12:59:54 +01:00
int width, height;
2022-02-27 12:59:54 +01:00
char pass_buffer[PASS_LEN], passwd[PASS_LEN];
2022-02-27 17:55:44 +01:00
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*);
2022-02-27 12:59:54 +01:00
static const char *generate_hash(void);
void window_attr(Display*, Window, int);
2022-02-27 12:59:54 +01:00
2022-02-27 17:55:44 +01:00
int main(void){
2022-02-27 12:59:54 +01:00
struct passwd *pwd;
struct group *grp;
const char *hash;
uid_t duid;
gid_t dgid;
Display *d = XOpenDisplay(NULL);
2022-02-27 17:55:44 +01:00
if(d == NULL)
2022-02-27 12:59:54 +01:00
catch_fire("Cannot open display\n", 1);
2022-02-27 17:55:44 +01:00
if(!(pwd = getpwnam(user)))
2022-02-27 12:59:54 +01:00
catch_fire("Cannot get user", 6);
duid = pwd->pw_uid;
2022-02-27 17:55:44 +01:00
if(!(grp = getgrnam(group)))
2022-02-27 12:59:54 +01:00
catch_fire("Can't get group", 7);
dgid = grp->gr_gid;
2022-02-27 17:55:44 +01:00
int s = DefaultScreen(d);
int depth = DefaultDepth(d, s);
width = DisplayWidth(d, s);
height = DisplayHeight(d, s);
2022-02-27 12:59:54 +01:00
Window w;
Visual *visual = DefaultVisual(d, s);
2022-02-27 17:55:44 +01:00
Colormap cmap = DefaultColormap(d, s);
2022-02-27 12:59:54 +01:00
// IGNORES WM RULES
XSetWindowAttributes attributes;
attributes.override_redirect = True;
2022-02-27 17:55:44 +01:00
attributes.background_pixel = BlackPixel(d, s);
2022-02-27 12:59:54 +01:00
// MAKE THE WINDOW
w = XCreateWindow(d, XRootWindow(d, s), 0, 0, width, height, 0, depth,
InputOutput, visual, CWBackPixel | CWOverrideRedirect, &attributes);
2022-02-27 17:55:44 +01:00
2022-02-27 12:59:54 +01:00
// SET WINDOW ATTRIBUTES
window_attr(d, w, s);
2022-02-27 12:59:54 +01:00
// DRAW THE RECTANGLES AND STRINGS
draw_ui(d, w, visual, cmap, s);
2022-02-27 12:59:54 +01:00
hash = generate_hash();
crypt("", hash);
2022-02-27 16:47:51 +01:00
// DROP PRIVILEGES
2022-02-27 12:59:54 +01:00
if (setgroups(0, NULL) < 0)
2022-02-27 16:47:51 +01:00
catch_fire("Can't set group", 8);
2022-02-27 12:59:54 +01:00
if (setgid(dgid) < 0)
2022-02-27 16:47:51 +01:00
catch_fire("Can't set group", 8);
2022-02-27 12:59:54 +01:00
if (setuid(duid) < 0)
2022-02-27 16:47:51 +01:00
catch_fire("Can't set group", 8);
2022-02-27 12:59:54 +01:00
2022-02-27 16:47:51 +01:00
// CHECK THE DAMNED PASSWORD
get_passwd(d, w, visual, cmap, s, hash);
2022-02-27 12:59:54 +01:00
2022-02-27 17:55:44 +01:00
2022-02-27 16:47:51 +01:00
XCloseDisplay(d);
return 0;
2022-02-27 12:59:54 +01:00
}
2022-02-27 17:55:44 +01:00
void anullate(char *str, int size){
memset(str, 0, size);
}
void catch_fire(char *string, int error){
2022-02-27 12:59:54 +01:00
fprintf(stderr, string);
exit(error);
}
void draw_ui(Display *d, Window w, Visual *visual, Colormap cmap, int s){
2022-02-27 12:59:54 +01:00
//FONT SHENANIGANS
char font_name[strlen("monospace-") +2];
sprintf(font_name, "monospace-%d", FONT_SIZE);
XftFont *font = XftFontOpenName(d, s, font_name);
// FONT COLORS
2022-02-27 17:55:44 +01:00
XftColor xft_black, xft_white;
2022-02-27 12:59:54 +01:00
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);
2022-02-27 17:55:44 +01:00
2022-02-27 12:59:54 +01:00
// PRINT PASS MESSAGE
XftDrawString8(xftdraw, &xft_black, font, white_rect_x + FONT_SIZE/2, height/2 + FONT_SIZE/2 , message, strlen(message));
2022-02-27 16:47:51 +01:00
// 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));
2022-02-27 12:59:54 +01:00
}
void window_attr(Display *d, Window w, int s){
2022-02-27 12:59:54 +01:00
int mode_count;
// VIDEO MODES
XF86VidModeModeInfo **modes, *video_mode;
XF86VidModeGetAllModeLines(d, s, &mode_count, &modes);
video_mode = modes[0];
2022-02-27 17:55:44 +01:00
// DISABLE DECORATIONS
2022-02-27 12:59:54 +01:00
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);
2022-02-27 17:55:44 +01:00
2022-02-27 12:59:54 +01:00
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){
2022-02-27 12:59:54 +01:00
int num, failure = 0, check = 1;
unsigned int len = 0;
char *input_hash;
KeySym ksym;
XEvent e;
// CHECK PASSWORD
2022-02-27 17:55:44 +01:00
while(1){
2022-02-27 12:59:54 +01:00
XNextEvent(d, &e);
2022-02-27 17:55:44 +01:00
if(e.type == KeyPress){
2022-02-27 12:59:54 +01:00
anullate(pass_buffer, sizeof(pass_buffer));
num = XLookupString(&e.xkey, pass_buffer, sizeof(pass_buffer), &ksym, 0);
2022-02-27 17:55:44 +01:00
if(IsKeypadKey(ksym)){
if(ksym == XK_KP_Enter)
ksym = XK_Return;
2022-02-27 12:59:54 +01:00
2022-02-27 17:55:44 +01:00
else if(ksym >= XK_KP_0 && ksym <= XK_KP_9)
ksym = (ksym - XK_KP_0) + XK_0;
2022-02-27 12:59:54 +01:00
}
2022-02-27 17:55:44 +01:00
if (IsFunctionKey(ksym) ||
IsKeypadKey(ksym) ||
IsMiscFunctionKey(ksym) ||
IsPFKey(ksym) ||
IsPrivateKeypadKey(ksym))
continue;
2022-02-27 12:59:54 +01:00
2022-02-27 17:55:44 +01:00
switch(ksym){
2022-02-27 12:59:54 +01:00
case XK_Return:
passwd[len] = '\0';
2022-02-27 17:55:44 +01:00
if(!(input_hash = crypt(passwd, hash))){
2022-02-27 12:59:54 +01:00
fprintf(stderr, "loqy : crypt error : %s\n", strerror(errno));
2022-02-27 17:55:44 +01:00
fprintf(stderr, "%d %d\n", errno, EINVAL);
}
2022-02-27 12:59:54 +01:00
else
2022-02-27 17:55:44 +01:00
check = !!strcmp(input_hash, hash);
2022-02-27 12:59:54 +01:00
2022-02-27 17:55:44 +01:00
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;
2022-02-27 12:59:54 +01:00
}
2022-02-27 17:55:44 +01:00
break;
2022-02-27 12:59:54 +01:00
}
draw_ui(d, w, v, cmap, screen);
2022-02-27 16:47:51 +01:00
2022-02-27 17:55:44 +01:00
if(!check)
exit(0);
2022-02-27 12:59:54 +01:00
2022-02-27 17:55:44 +01:00
}
}
2022-02-27 12:59:54 +01:00
}
static const char *generate_hash(void){
const char *hash;
struct passwd *pw;
2022-02-27 17:55:44 +01:00
if(!(pw = getpwuid(getuid())))
2022-02-27 12:59:54 +01:00
catch_fire("Cannot get password info\n", 2);
hash = pw->pw_passwd;
2022-02-27 17:55:44 +01:00
if(!strcmp(hash, "x")){
2022-02-27 12:59:54 +01:00
struct spwd *sp;
2022-02-27 17:55:44 +01:00
if(!(sp = getspnam(pw->pw_name)))
catch_fire("cannot retrieve shadow entry. ", 69);
2022-02-27 12:59:54 +01:00
hash = sp->sp_pwdp;
}
2022-02-27 17:55:44 +01:00
if(!strcmp(hash, "*"))
catch_fire("slock: getpwuid: cannot retrieve shadow entry. ", 98);
2022-02-27 12:59:54 +01:00
return hash;
}