From f9bfc48a9fdfd23e1c938751a1843d5432a9eade Mon Sep 17 00:00:00 2001 From: javalsai Date: Sun, 14 Jul 2024 20:21:17 +0200 Subject: [PATCH] =?UTF-8?q?spain's=20gonna=20win=20btw=20=F0=9F=87=AA?= =?UTF-8?q?=F0=9F=87=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 8 +-- README.md | 4 +- compile_commands.json | 12 +++++ include/auth.h | 11 ++++ include/sessions.h | 3 +- src/auth.c | 113 ++++++++++++++++++++++++++++++++++++++++++ src/main.c | 8 +-- src/sessions.c | 69 +++++++++++++++++++------- src/ui.c | 16 ++++-- 9 files changed, 211 insertions(+), 33 deletions(-) create mode 100644 include/auth.h create mode 100644 src/auth.c diff --git a/Makefile b/Makefile index 3e9ed7b..e734e2d 100644 --- a/Makefile +++ b/Makefile @@ -4,14 +4,14 @@ IDIR=include ODIR=dist CC=gcc -CFLAGS=-I$(IDIR) +CFLAGS=-O3 -I$(IDIR) -LIBS=-lm +LIBS=-lm -lpam -lpam_misc -_DEPS = util.h ui.h efield.h keys.h users.h sessions.h +_DEPS = util.h ui.h auth.h efield.h keys.h users.h sessions.h DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) -_OBJ = main.o util.o ui.o efield.o users.o sessions.o +_OBJ = main.o util.o ui.o auth.o efield.o users.o sessions.o OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) $(ODIR)/%.o: $(CDIR)/%.c $(DEPS) diff --git a/README.md b/README.md index c2b9f88..a28d038 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ Lidm is a really light display manager made in C, highly customizable and held t ![demo image](assets/lidm.png) > *this is shown as in a terminal emulator, actual linux console doesn't support as much color and decorations* +> *I'm open if anybody wants to contact me to record a proper demo of the program, my laptop can't handle it and idk how to config obs for hyprland* + ## Features * Builds fast af * Works everywhere you can get gcc to compile @@ -15,7 +17,7 @@ Lidm is a really light display manager made in C, highly customizable and held t * Save last selection * Show/hide passwd switch * Config parsing, it's fully customizable, but everything hardcoded for now :) -* Long sessions, strings, usernames, passwords... they will just overflow or f*ck your terminal, I know it and I don't know if I'll fix it. +* Long sessions, strings, usernames, passwords... they will just overflow or f\*ck your terminal, I know it and I don't know if I'll fix it. ## Forget it * Any kind of arguments diff --git a/compile_commands.json b/compile_commands.json index f7d5d7f..6766123 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -70,5 +70,17 @@ "-Iinclude" ], "file": "src/efield.c" + }, + { + "directory": "/home/javalsai/coding/lidm", + "arguments": [ + "gcc", + "-c", + "-o", + "dist/auth.o", + "src/auth.c", + "-Iinclude" + ], + "file": "src/auth.c" } ] diff --git a/include/auth.h b/include/auth.h new file mode 100644 index 0000000..5fa6028 --- /dev/null +++ b/include/auth.h @@ -0,0 +1,11 @@ +#ifndef _AUTHH_ +#define _AUTHH_ + +#include + +#include + +bool check_passwd(char *user, char *passwd); +bool launch(char *user, char *passwd, struct session session, void (*cb)(void)); + +#endif diff --git a/include/sessions.h b/include/sessions.h index f6b689e..e5e9a1e 100644 --- a/include/sessions.h +++ b/include/sessions.h @@ -11,7 +11,8 @@ enum session_type { struct session { char *name; - char *path; + char *exec; + char *tryexec; enum session_type type; }; diff --git a/src/auth.c b/src/auth.c new file mode 100644 index 0000000..63b5b9f --- /dev/null +++ b/src/auth.c @@ -0,0 +1,113 @@ +#include +#include +#include + +#include +#include + +int pam_conversation(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) { + struct pam_response *reply = + (struct pam_response *)malloc(sizeof(struct pam_response) * num_msg); + for (int i = 0; i < num_msg; i++) { + reply[i].resp = NULL; + reply[i].resp_retcode = 0; + if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF || + msg[i]->msg_style == PAM_PROMPT_ECHO_ON) { + char *input = (char *)appdata_ptr; + reply[i].resp = strdup(input); + } + } + *resp = reply; + return PAM_SUCCESS; +} + +bool check_passwd(char *user, char *passwd) { + pam_handle_t *pamh = NULL; + struct pam_conv pamc = {pam_conversation, (void *)passwd}; + int retval; + + retval = pam_start("login", user, &pamc, &pamh); + if (retval != PAM_SUCCESS) { + return false; + } + + retval = pam_authenticate(pamh, 0); + if (retval != PAM_SUCCESS) { + pam_end(pamh, retval); + return false; + } + + retval = pam_acct_mgmt(pamh, 0); + if (retval != PAM_SUCCESS) { + pam_end(pamh, retval); + return false; + } + + pam_end(pamh, PAM_SUCCESS); + return true; +} + +/*void run(char *user, char *passwd, char *type, char *command) {*/ +/* int pipefd[2];*/ +/* pid_t pid;*/ +/**/ +/* if (pipe(pipefd) == -1) {*/ +/* perror("pipe");*/ +/* exit(EXIT_FAILURE);*/ +/* }*/ +/**/ +/* if ((pid = fork()) == -1) {*/ +/* perror("fork");*/ +/* exit(EXIT_FAILURE);*/ +/* }*/ +/**/ +/* if (pid == 0) {*/ +/* close(pipefd[0]);*/ +/* write(pipefd[1], passwd, strlen(passwd));*/ +/* close(pipefd[1]);*/ +/* exit(EXIT_SUCCESS);*/ +/* } else {*/ +/* close(pipefd[1]);*/ +/**/ +/* if (dup2(pipefd[0], STDIN_FILENO) == -1) {*/ +/* perror("dup2");*/ +/* exit(EXIT_FAILURE);*/ +/* }*/ +/* close(pipefd[0]);*/ +/**/ +/* execlp("su", "-", user, type, command, (char *)NULL);*/ +/* perror("execlp");*/ +/* exit(EXIT_FAILURE);*/ +/* }*/ +/*}*/ + +void run(char *user, char *passwd, char *type, char *command) { + int pipefd[2]; + pipe(pipefd); + close(STDIN_FILENO); + dup2(pipefd[0], STDIN_FILENO); + write(pipefd[1], passwd, strlen(passwd)); + write(pipefd[1], "\n", 1); + char *const args[] = { "-", user, type, command, NULL }; + execvp("su", args); + exit(1); +} + +bool launch(char *user, char *passwd, struct session session, void (*cb)(void)) { + if (!check_passwd(user, passwd)) + return false; + + if (cb != NULL) + cb(); + + if (session.type == SHELL) { + system("clear"); + run(user, passwd, "-s", session.exec); + } else if (session.type == XORG || session.type == WAYLAND) { + system("clear"); + run(user, passwd, "-c", session.exec); + } + + return true; +} diff --git a/src/main.c b/src/main.c index 05bc7bf..60145c2 100644 --- a/src/main.c +++ b/src/main.c @@ -38,7 +38,6 @@ static const struct config default_config() { __theme.colors = __colors; __theme.chars = __chars; - struct functions __functions; __functions.poweroff = F1; __functions.reboot = F2; @@ -66,12 +65,15 @@ static const struct config default_config() { return __config; } -int main(int argc, char* argv[]) { +#include +#include +int main(int argc, char *argv[]) { setup(default_config()); struct users_list *users = get_human_users(); struct sessions_list *sessions = get_avaliable_sessions(); int ret = load(users, sessions); - if(ret == 0) execl(argv[0], argv[0], NULL); + if (ret == 0) + execl(argv[0], argv[0], NULL); } diff --git a/src/sessions.c b/src/sessions.c index 64080b6..1d63101 100644 --- a/src/sessions.c +++ b/src/sessions.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -11,19 +12,21 @@ struct source_dir { enum session_type type; - char* dir; + char *dir; }; static const struct source_dir sources[] = { - { XORG, "/usr/share/xsessions" }, - { WAYLAND, "/usr/share/wayland-sessions" }, + {XORG, "/usr/share/xsessions"}, + {WAYLAND, "/usr/share/wayland-sessions"}, }; static const size_t sources_size = sizeof(sources) / sizeof(sources[0]); -static struct session __new_session(enum session_type type, char *name, const char *path) { +static struct session __new_session(enum session_type type, char *name, + const char *exec, const char *tryexec) { struct session __session; __session.type = type; strcln(&__session.name, name); - strcln(&__session.path, path); + strcln(&__session.exec, exec); + strcln(&__session.tryexec, tryexec); return __session; } @@ -53,35 +56,63 @@ static int fn(const char *fpath, const struct stat *sb, int typeflag) { return 0; } - bool found = false; + u_char found = 0; size_t alloc_size = sb->st_blksize; - char *buf = malloc(sb->st_blksize); - while (true) { - buf = realloc(buf, sb->st_blksize); - ssize_t read_size = getline(&buf, &alloc_size, fd); - if (read_size == -1) - break; - uint read; - if ((read = sscanf(buf, "Name=%s\n", buf)) != 0) { - found = true; - buf = realloc(buf, read); + char *name_buf = NULL; + char *exec_buf = NULL; + char *tryexec_buf = NULL; + while (true) { + char *buf = malloc(sb->st_blksize); + ssize_t read_size = getline(&buf, &alloc_size, fd); + if (read_size == -1) { + free(buf); break; } + + uint read; + char *key = malloc(read_size); + if ((read = sscanf(buf, "%[^=]=%[^\n]\n", key, buf)) != 0) { + if (strcmp(key, "Name") == 0) { + found &= 0b001; + name_buf = realloc(buf, read); + } else if (strcmp(key, "Exec") == 0) { + found &= 0b010; + exec_buf = realloc(buf, read); + } else if (strcmp(key, "TryExec") == 0) { + found &= 0b100; + tryexec_buf = realloc(buf, read); + } else + free(buf); + } else + free(buf); + free(key); + + if (found == 0b111) + break; } // just add this to the list - if (found) { + if (name_buf != NULL && exec_buf != NULL) { if (used_size >= alloc_size) { alloc_size += bs; sessions = realloc(sessions, alloc_size * unit_size); } - sessions[used_size] = __new_session(session_type, buf, fpath); + /*printf("n %s\ne %s\nte %s\n", name_buf, exec_buf, tryexec_buf);*/ + sessions[used_size] = __new_session(session_type, name_buf, exec_buf, + tryexec_buf == NULL ? "" : tryexec_buf); + used_size++; } - free(buf); + if (name_buf != NULL) + free(name_buf); + if (exec_buf != NULL) + free(exec_buf); + if (tryexec_buf != NULL) + free(tryexec_buf); + return 0; } diff --git a/src/ui.c b/src/ui.c index 5a48d6a..0f87f0a 100644 --- a/src/ui.c +++ b/src/ui.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -231,14 +232,14 @@ struct session get_current_session() { of_session.current_opt == gsessions->length + 1) { struct session shell_session; shell_session.type = SHELL; - shell_session.path = shell_session.name = get_current_user().shell; + shell_session.exec = shell_session.name = get_current_user().shell; return shell_session; } else return gsessions->sessions[of_session.current_opt - 1]; } else { struct session custom_session; custom_session.type = SHELL; - custom_session.name = custom_session.path = of_session.efield.content; + custom_session.name = custom_session.exec = of_session.efield.content; return custom_session; } } @@ -311,7 +312,7 @@ void ffield_type(char *text) { start = get_current_user().username; if (focused_input == SESSION && of_session.current_opt != 0 && get_current_session().type == SHELL) - start = get_current_session().path; + start = get_current_session().exec; ofield_type(field, text, start); print_ffield(); @@ -389,8 +390,13 @@ int load(struct users_list *users, struct sessions_list *sessions) { } } } else { - if(len == 1 && *seq == '\n') { - printf("\x1b[HTODO: submit creds\n"); + if (len == 1 && *seq == '\n') { + if (!launch(get_current_user().username, of_passwd.efield.content, + get_current_session(), &restore_all)) { + print_passwd(box_start(), of_passwd.efield.length, true); + ffield_cursor_focus(); + continue; + } } ffield_type(seq); }