/* * hlogin(1) * * Copyleft (C) 2022 ~keith * * This file is part of hlogin. * * hlogin 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, version 3. * * hlogin 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. * * You should have received a copy of the GNU General Public License * along with hlogin. If not, see . */ #include "config.h" #include #include #include #include #include #include "gettext.h" #include #include #include #include "ui.h" #define VAR_(x) #x #define VAR(x) VAR_(x) #pragma message "LOCALEDIR=" VAR(LOCALEDIR) int pam_conv_handler(int msgc, const struct pam_message *msgv[], struct pam_response **resp, void *appdata_ptr) { if (msgc <= 0) return PAM_CONV_ERR; struct pam_response *result = calloc(msgc, sizeof(struct pam_response)); if (!result) return PAM_CONV_ERR; for (int i = 0; i < msgc; i++) { int r; char *text; switch (msgv[i]->msg_style) { case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_ON: ui_setup_dialog((char *) msgv[i]->msg, msgv[i]->msg_style == PAM_PROMPT_ECHO_OFF); r = ui_run(); text = ui_get_text(); if (r != 0) { _pam_overwrite(text); free(text); text = NULL; } result[i].resp_retcode = 0; result[i].resp = text; break; case PAM_ERROR_MSG: case PAM_TEXT_INFO: goto FAILURE; // TODO implement info/error dialog default: goto FAILURE; } } *resp = result; return PAM_SUCCESS; FAILURE: if (result) { for (int i = 0; i < msgc; i++) { if (result[i].resp) { _pam_overwrite(result[i].resp); free(result[i].resp); } } free(result); result = NULL; } return PAM_CONV_ERR; } int main(int argc, char* argv[]) { setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); pam_handle_t *pam = NULL; struct pam_conv conv = { .conv = pam_conv_handler, .appdata_ptr = NULL }; if (pam_start("login", NULL, &conv, &pam) != PAM_SUCCESS) { // TODO log error & pause before exiting return EXIT_FAILURE; } ui_init(); // prompt for username ui_setup_dialog(_("Login name:"), false); int result = ui_run(); char *login_name = ui_get_text(); if (result != 0) goto END; result = pam_set_item(pam, PAM_USER, login_name); if (result != PAM_SUCCESS) { endwin(); printf("pam_set_item error: %s\n", pam_strerror(pam, result)); return EXIT_FAILURE; } result = pam_authenticate(pam, 0); if (result != PAM_SUCCESS) { endwin(); printf("pam_authenticate error: %s\n", pam_strerror(pam, result)); return EXIT_FAILURE; } END: endwin(); return EXIT_SUCCESS; }