diff --git a/mdm/login.c b/mdm/login.c index 2092213..ae82750 100644 --- a/mdm/login.c +++ b/mdm/login.c @@ -1,14 +1,81 @@ #include "mdm.h" +#include + MwWidget root; +MwWidget window, usercombo, passentry; static void add_user(const char* name, void* user){ MwComboBoxAdd(user, -1, name); } +static int conversation(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata){ + int i; + + *resp = malloc(num_msg * sizeof(struct pam_response)); + + for(i = 0; i < num_msg; i++){ + if(msg[i]->msg_style == PAM_PROMPT_ECHO_OFF){ + const char* txt = MwGetText(passentry, MwNtext); + if(txt == NULL) txt = ""; + + resp[i]->resp_retcode = PAM_SUCCESS; + resp[i]->resp = MDEStringDuplicate(txt); + }else{ + return PAM_CONV_ERR; + } + } + + return PAM_SUCCESS; +} + +static void try_login(MwWidget handle, void* user, void* client){ + const char* username = MwComboBoxGet(usercombo, MwGetInteger(usercombo, MwNvalue)); + struct pam_conv conv = {conversation, NULL}; + pam_handle_t* pam; + int ret; + jmp_buf cleanup; + int err = 1; + + (void)handle; + (void)user; + (void)client; + + if(setjmp(cleanup)){ + pam_end(pam, 0); + + if(err){ + MwSetText(passentry, MwNtext, ""); + }else{ + MwDestroyWidget(root); + } + + return; + } + + ret = pam_start("mdm", username, &conv, &pam); + if(ret != PAM_SUCCESS){ + longjmp(cleanup, 1); + } + + ret = pam_authenticate(pam, 0); + if(ret != PAM_SUCCESS){ + longjmp(cleanup, 1); + } + + ret = pam_acct_mgmt(pam, 0); + if(ret != PAM_SUCCESS){ + longjmp(cleanup, 1); + } + + err = 0; + longjmp(cleanup, 1); +} + void login_window(void){ - MwWidget window, pic, userlabel, usercombo, passlabel, passentry, mainsep, sesslabel, sesscombo, fieldsep, shutdown, reboot, ok; + MwWidget pic, userlabel, passlabel, mainsep, sesslabel, sesscombo, fieldsep, shutdown, reboot, ok; MwLLPixmap p; + void* out; MwLibraryInit(); @@ -38,7 +105,7 @@ void login_window(void){ MwNtext, "Session Type:", NULL); sesscombo = MwCreateWidget(MwComboBoxClass, "sesscombo", window, 95, 10+16+5+18+5+16+5+18+10+16+5, 265, 18); - fieldsep = MwVaCreateWidget(MwSeparatorClass, "fieldsep", window, (366 - 362) / 2, 10+137, 362, 10, + fieldsep = MwVaCreateWidget(MwSeparatorClass, "fieldsep", window, 10, 10+137, 351, 10, MwNorientation, MwHORIZONTAL, NULL); shutdown = MwVaCreateWidget(MwButtonClass, "shutdown", window, 10, 10+137+10, 80, 18, @@ -53,6 +120,9 @@ void login_window(void){ if(p != NULL) MwVaApply(pic, MwNpixmap, p, NULL); + MwAddUserHandler(ok, MwNactivateHandler, try_login, NULL); + MwAddUserHandler(passentry, MwNactivateHandler, try_login, NULL); + MDEListUsers(add_user, usercombo); while(1){ @@ -67,4 +137,6 @@ void login_window(void){ MwTimeSleep(30); } + + pthread_join(xthread, &out); } diff --git a/mdm/main.c b/mdm/main.c index bb61394..7507601 100644 --- a/mdm/main.c +++ b/mdm/main.c @@ -25,7 +25,11 @@ int main(int argc, char** argv){ if((st = launch_x()) != 0) return st; } - if((st = init_x()) != 0) return st; + while(1){ + if((st = init_x()) != 0) return st; - login_window(); + login_window(); + + /* TODO: run session */ + } } diff --git a/mdm/mdm.h b/mdm/mdm.h index fe1d9db..60869bd 100644 --- a/mdm/mdm.h +++ b/mdm/mdm.h @@ -3,11 +3,14 @@ #include "config.h" +/* Milsko */ #include #include +/* External */ #include +/* Standard */ #include #include #include @@ -16,6 +19,7 @@ #include #include #include +#include #include /* xserver.c */ diff --git a/mdm/xserver.c b/mdm/xserver.c index e3e1fe2..21b6eed 100644 --- a/mdm/xserver.c +++ b/mdm/xserver.c @@ -51,6 +51,7 @@ static int wm_detect(Display* disp, XErrorEvent* ev){ static void* x11_thread_routine(void* arg){ x_loop(); + XCloseDisplay(xdisplay); } int init_x(void){ @@ -128,8 +129,24 @@ void x_loop(void){ MwNinverted, 0, NULL); + XSelectInput(xdisplay, w.client, StructureNotifyMask); + arrput(frames, w); pthread_mutex_unlock(&xmutex); + }else if(ev.type == UnmapNotify){ + int i; + + pthread_mutex_lock(&xmutex); + for(i = 0; i < arrlen(frames); i++){ + if(frames[i].client == ev.xunmap.window){ + MwDestroyWidget(frames[i].frame); + arrdel(frames, i); + break; + } + } + pthread_mutex_unlock(&xmutex); + + break; } } }