diff options
| author | Mattias Andrée <m@maandree.se> | 2026-02-22 13:49:08 +0100 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-02-22 13:49:08 +0100 |
| commit | 86138fc92d6e5f92d9d3fcceb32b849e8504f619 (patch) | |
| tree | f361b9cea99dbe4d77d0dd8f9cbc00f67c105d6b /src/auth | |
| parent | Udpdate for new version of glibc (diff) | |
| download | cerberus-86138fc92d6e5f92d9d3fcceb32b849e8504f619.tar.gz cerberus-86138fc92d6e5f92d9d3fcceb32b849e8504f619.tar.bz2 cerberus-86138fc92d6e5f92d9d3fcceb32b849e8504f619.tar.xz | |
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
| -rw-r--r-- | src/auth.h | 43 | ||||
| -rw-r--r-- | src/auth/crypt.c | 101 | ||||
| -rw-r--r-- | src/auth/crypt.h | 7 | ||||
| -rw-r--r-- | src/auth/pam.c | 248 | ||||
| -rw-r--r-- | src/auth/pam.h | 7 |
5 files changed, 198 insertions, 208 deletions
@@ -1,7 +1,7 @@ /** * cerberus – Minimal login program * - * Copyright © 2013, 2014, 2015, 2016, 2020 Mattias Andrée (maandree@kth.se) + * Copyright © 2013, 2014, 2015, 2016, 2020 Mattias Andrée (m@maandree.se) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,33 +22,26 @@ #if AUTH == 0 - -#define close_login_session(...) /* do nothing */ -#define initialise_login(...) (void) hostname -#define authenticate_login(...) 1 -#define verify_account(...) /* do nothing */ -#define open_login_session(...) /* do nothing */ - +# define close_login_session(...) /* do nothing */ +# define initialise_login(...) (void) hostname +# define authenticate_login(...) 1 +# define verify_account(...) /* do nothing */ +# define open_login_session(...) /* do nothing */ #elif AUTH == 1 - -#include "auth/crypt.h" -#define close_login_session(...) /* do nothing */ -#define initialise_login initialise_crypt -#define authenticate_login authenticate_crypt -#define verify_account(...) /* do nothing */ -#define open_login_session(...) /* do nothing */ - +# include "auth/crypt.h" +# define close_login_session(...) /* do nothing */ +# define initialise_login initialise_crypt +# define authenticate_login authenticate_crypt +# define verify_account(...) /* do nothing */ +# define open_login_session(...) /* do nothing */ #elif AUTH == 2 - -#include "auth/pam.h" -#define close_login_session close_session_pam -#define initialise_login initialise_pam -#define authenticate_login authenticate_pam -#define verify_account verify_account_pam -#define open_login_session open_session_pam - +# include "auth/pam.h" +# define close_login_session close_session_pam +# define initialise_login initialise_pam +# define authenticate_login authenticate_pam +# define verify_account verify_account_pam +# define open_login_session open_session_pam #endif #endif - diff --git a/src/auth/crypt.c b/src/auth/crypt.c index 4573c5a..5012580 100644 --- a/src/auth/crypt.c +++ b/src/auth/crypt.c @@ -1,7 +1,7 @@ /** * cerberus – Minimal login program * - * Copyright © 2013, 2014, 2015, 2016, 2020 Mattias Andrée (maandree@kth.se) + * Copyright © 2013, 2014, 2015, 2016, 2020 Mattias Andrée (m@maandree.se) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,12 +46,12 @@ /** * Function that can be used to read a passphrase from the terminal */ -static char* (*passphrase_reader)(void) = NULL; +static char *(*passphrase_reader)(void) = NULL; /** * The username of the user to log in to */ -static char* login_username; +static char *login_username; @@ -62,12 +62,13 @@ static char* login_username; * @param username The username of the user to log in to * @param reader Function that can be used to read a passphrase from the terminal */ -void initialise_crypt(char* remote, char* username, char* (*reader)(void)) +void +initialise_crypt(char *remote, char *username, char *(*reader)(void)) { - (void) remote; - - login_username = username; - passphrase_reader = reader; + (void) remote; + + login_username = username; + passphrase_reader = reader; } @@ -76,54 +77,52 @@ void initialise_crypt(char* remote, char* username, char* (*reader)(void)) * * @return 0: failed, 1: success, 2: auto-authenticated */ -char authenticate_crypt(void) +char +authenticate_crypt(void) { #ifdef HAVE_SHADOW - struct spwd* shadow_entry = NULL; + struct spwd *shadow_entry = NULL; #endif - struct passwd* passwd_entry = NULL; - char* crypted; - char* entered; - struct termios stty; - + struct passwd *passwd_entry = NULL; + char *crypted; + char *entered; + struct termios stty; + #ifdef HAVE_SHADOW - shadow_entry = getspnam(login_username); - endspent(); - - if (shadow_entry) - crypted = shadow_entry->sp_pwdp; - else - { + shadow_entry = getspnam(login_username); + endspent(); + + if (shadow_entry) { + crypted = shadow_entry->sp_pwdp; + } else { #endif - passwd_entry = getpwnam(login_username); - if (passwd_entry) - crypted = passwd_entry->pw_passwd; - else - { - perror("getpwnam"); - endpwent(); - sleep(ERROR_SLEEP); - _exit(1); - } - endpwent(); + passwd_entry = getpwnam(login_username); + if (passwd_entry) { + crypted = passwd_entry->pw_passwd; + } else { + perror("getpwnam"); + endpwent(); + sleep(ERROR_SLEEP); + _exit(1); + } + endpwent(); #ifdef HAVE_SHADOW - } + } #endif - - if (!(crypted && *crypted)) /* empty means that no passphrase is required (not even Enter) */ - return 2; - - entered = crypt(passphrase_reader(), crypted /* salt argument stops parsing when encrypted begins */); - if (entered && !strcmp(entered, crypted)) - return 1; - - /* Clear ISIG (and everything else) to prevent the user - * from skipping the brute force protection sleep. */ - tcgetattr(STDIN_FILENO, &stty); - stty.c_lflag = 0; - tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty); - - printf("\nPassphrase incorrect.\nOnly perfect spellers may\nenter this system.\n"); - return 0; -} + if (!(crypted && *crypted)) /* empty means that no passphrase is required (not even Enter) */ + return 2; + + entered = crypt(passphrase_reader(), crypted /* salt argument stops parsing when encrypted begins */); + if (entered && !strcmp(entered, crypted)) + return 1; + + /* Clear ISIG (and everything else) to prevent the user + * from skipping the brute force protection sleep. */ + tcgetattr(STDIN_FILENO, &stty); + stty.c_lflag = 0; + tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty); + + printf("\nPassphrase incorrect.\nOnly perfect spellers may\nenter this system.\n"); + return 0; +} diff --git a/src/auth/crypt.h b/src/auth/crypt.h index 4478929..cfcfc4f 100644 --- a/src/auth/crypt.h +++ b/src/auth/crypt.h @@ -1,7 +1,7 @@ /** * cerberus – Minimal login program * - * Copyright © 2013, 2014, 2015, 2016, 2020 Mattias Andrée (maandree@kth.se) + * Copyright © 2013, 2014, 2015, 2016, 2020 Mattias Andrée (m@maandree.se) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,11 +23,11 @@ /** * Initialise crypt authentication module * - * @param remote The remote computer, {@code NULL} for local login + * @param remote The remote computer, `NULL` for local login * @param username The username of the user to log in to * @param reader Function that can be used to read a passphrase from the terminal */ -void initialise_crypt(char* remote, char* username, char* (*reader)(void)); +void initialise_crypt(char *remote, char *username, char *(*reader)(void)); /** * Perform token authentication @@ -38,4 +38,3 @@ char authenticate_crypt(void); #endif - diff --git a/src/auth/pam.c b/src/auth/pam.c index 106462a..7ddc874 100644 --- a/src/auth/pam.c +++ b/src/auth/pam.c @@ -1,7 +1,7 @@ /** * cerberus – Minimal login program * - * Copyright © 2013, 2014, 2015, 2016, 2020 Mattias Andrée (maandree@kth.se) + * Copyright © 2013, 2014, 2015, 2016, 2020 Mattias Andrée (m@maandree.se) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,7 +37,7 @@ __attribute__((noreturn)) #endif static void quit_pam(int sig); -static int conv_pam(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata_ptr); +static int conv_pam(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); /** @@ -73,7 +73,7 @@ static char auto_authenticated = 1; /** * Function that can be used to read a passphrase from the terminal */ -static char* (*passphrase_reader)(void) = NULL; +static char *(*passphrase_reader)(void) = NULL; #ifdef __GNUC__ @@ -85,17 +85,17 @@ static char* (*passphrase_reader)(void) = NULL; * * @param rc What the PAM instruction return */ -static void do_pam(int rc) +static void +do_pam(int rc) { - if (__failed(rc)) - { - const char* msg = pam_strerror(handle, rc); - if (msg) - fprintf(stderr, "%s\n", msg); - pam_end(handle, rc); - sleep(ERROR_SLEEP); - _exit(1); - } + if (__failed(rc)) { + const char *msg = pam_strerror(handle, rc); + if (msg) + fprintf(stderr, "%s\n", msg); + pam_end(handle, rc); + sleep(ERROR_SLEEP); + _exit(1); + } } #ifdef __GNUC__ # pragma GCC diagnostic pop @@ -109,91 +109,92 @@ static void do_pam(int rc) * @param username The username of the user to log in to * @param reader Function that can be used to read a passphrase from the terminal */ -void initialise_pam(char* remote, char* username, char* (*reader)(void)) +void +initialise_pam(char *remote, char *username, char *(*reader)(void)) { - passphrase_reader = reader; - - if (pam_start(remote ? "remote" : "local", username, &conv, &handle) != PAM_SUCCESS) - { - fprintf(stderr, "Cannot initialise PAM\n"); - sleep(ERROR_SLEEP); - _exit(1); - } - - do_pam(pam_set_item(handle, PAM_RHOST, remote ?: "localhost")); - do_pam(pam_set_item(handle, PAM_TTY, ttyname(STDIN_FILENO) ?: "(none)")); - do_pam(pam_set_item(handle, PAM_USER_PROMPT, "Username: ")); + passphrase_reader = reader; + + if (pam_start(remote ? "remote" : "local", username, &conv, &handle) != PAM_SUCCESS) { + fprintf(stderr, "Cannot initialise PAM\n"); + sleep(ERROR_SLEEP); + _exit(1); + } + + do_pam(pam_set_item(handle, PAM_RHOST, remote ?: "localhost")); + do_pam(pam_set_item(handle, PAM_TTY, ttyname(STDIN_FILENO) ?: "(none)")); + do_pam(pam_set_item(handle, PAM_USER_PROMPT, "Username: ")); } /** * Verify that the account may be used */ -void verify_account_pam(void) +void +verify_account_pam(void) { - /* FIXME pam_acct_mgmt exits the program, but freezes if PAM_USER_PROMPT has not been set. */ - /* however, if -f is used there is no problem. */ - /* - int rc = pam_acct_mgmt(handle, 0); - if (rc == PAM_NEW_AUTHTOK_REQD) - rc = pam_chauthtok(handle, PAM_CHANGE_EXPIRED_AUTHTOK); - do_pam(rc); - */ + /* FIXME pam_acct_mgmt exits the program, but freezes if PAM_USER_PROMPT has not been set. */ + /* however, if -f is used there is no problem. */ + /* + int rc = pam_acct_mgmt(handle, 0); + if (rc == PAM_NEW_AUTHTOK_REQD) + rc = pam_chauthtok(handle, PAM_CHANGE_EXPIRED_AUTHTOK); + do_pam(rc); + */ } /** * Open PAM session */ -void open_session_pam(void) +void +open_session_pam(void) { - int rc; - char** env; - struct sigaction signal_action; - - do_pam(pam_setcred(handle, PAM_ESTABLISH_CRED)); - - if (__failed(rc = pam_open_session(handle, 0))) - { - pam_setcred(handle, PAM_DELETE_CRED); - do_pam(rc); - } - - if (__failed(rc = pam_setcred(handle, PAM_REINITIALIZE_CRED))) - { - pam_close_session(handle, 0); - do_pam(rc); - } - - memset(&signal_action, 0, sizeof(signal_action)); - signal_action.sa_handler = SIG_IGN; - sigaction(SIGINT, &signal_action, NULL); - sigaction(SIGHUP, &signal_action, &signal_action_hup); - signal_action.sa_handler = quit_pam; - sigaction(SIGHUP, &signal_action, NULL); - sigaction(SIGTERM, &signal_action, &signal_action_term); - - for (env = pam_getenvlist(handle); env && *env; env++) - if (putenv(*env)) - { - pam_setcred(handle, PAM_DELETE_CRED); - pam_end(handle, pam_close_session(handle, 0)); - sleep(ERROR_SLEEP); - _exit(1); - } + int rc; + char **env; + struct sigaction signal_action; + + do_pam(pam_setcred(handle, PAM_ESTABLISH_CRED)); + + if (__failed(rc = pam_open_session(handle, 0))) { + pam_setcred(handle, PAM_DELETE_CRED); + do_pam(rc); + } + + if (__failed(rc = pam_setcred(handle, PAM_REINITIALIZE_CRED))) { + pam_close_session(handle, 0); + do_pam(rc); + } + + memset(&signal_action, 0, sizeof(signal_action)); + signal_action.sa_handler = SIG_IGN; + sigaction(SIGINT, &signal_action, NULL); + sigaction(SIGHUP, &signal_action, &signal_action_hup); + signal_action.sa_handler = quit_pam; + sigaction(SIGHUP, &signal_action, NULL); + sigaction(SIGTERM, &signal_action, &signal_action_term); + + for (env = pam_getenvlist(handle); env && *env; env++) { + if (putenv(*env)) { + pam_setcred(handle, PAM_DELETE_CRED); + pam_end(handle, pam_close_session(handle, 0)); + sleep(ERROR_SLEEP); + _exit(1); + } + } } /** * Close PAM session */ -void close_session_pam(void) +void +close_session_pam(void) { - sigaction(SIGHUP, &signal_action_hup, NULL); - sigaction(SIGTERM, &signal_action_term, NULL); - - pam_setcred(handle, PAM_DELETE_CRED); - pam_end(handle, pam_close_session(handle, 0)); + sigaction(SIGHUP, &signal_action_hup, NULL); + sigaction(SIGTERM, &signal_action_term, NULL); + + pam_setcred(handle, PAM_DELETE_CRED); + pam_end(handle, pam_close_session(handle, 0)); } @@ -202,17 +203,18 @@ void close_session_pam(void) * * @param sig The received signal */ -void quit_pam(int sig) +void +quit_pam(int sig) { - if (child_pid) - kill(-child_pid, sig); - if (sig == SIGTERM) - kill(-child_pid, SIGHUP); - - pam_setcred(handle, PAM_DELETE_CRED); - pam_end(handle, pam_close_session(handle, 0)); - - _exit(sig); + if (child_pid) + kill(-child_pid, sig); + if (sig == SIGTERM) + kill(-child_pid, SIGHUP); + + pam_setcred(handle, PAM_DELETE_CRED); + pam_end(handle, pam_close_session(handle, 0)); + + _exit(sig); } @@ -221,25 +223,25 @@ void quit_pam(int sig) * * @return 0: failed, 1: success, 2: auto-authenticated */ -char authenticate_pam(void) +char +authenticate_pam(void) { - int rc; - - if (__failed(rc = pam_authenticate(handle, 0))) - { - /* Clear ISIG (and everything else) to prevent the user - * from skipping the brute force protection sleep. */ - struct termios stty; - tcgetattr(STDIN_FILENO, &stty); - stty.c_lflag = 0; - tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty); - - printf("\nPassphrase incorrect.\nOnly perfect spellers may\nenter this system.\n"); - pam_end(handle, rc); - return 0; - } - - return auto_authenticated ? 2 : 1; + int rc; + + if (__failed(rc = pam_authenticate(handle, 0))) { + /* Clear ISIG (and everything else) to prevent the user + * from skipping the brute force protection sleep. */ + struct termios stty; + tcgetattr(STDIN_FILENO, &stty); + stty.c_lflag = 0; + tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty); + + printf("\nPassphrase incorrect.\nOnly perfect spellers may\nenter this system.\n"); + pam_end(handle, rc); + return 0; + } + + return auto_authenticated ? 2 : 1; } @@ -252,26 +254,24 @@ char authenticate_pam(void) * @param appdata_ptr (Not used) * @return `PAM_SUCCESS`, `PAM_CONV_ERR` or `PAM_BUF_ERR` */ -int conv_pam(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata_ptr) +int +conv_pam(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { - int i; - - (void) appdata_ptr; - - *resp = calloc((size_t)num_msg, sizeof(struct pam_response)); - - for (i = 0; i < num_msg; i++) - { - ((*resp) + i)->resp = NULL; - ((*resp) + i)->resp_retcode = 0; - - if ((**(msg + i)).msg_style == PAM_PROMPT_ECHO_OFF) - { - (*resp + i)->resp = passphrase_reader(); - auto_authenticated = 0; + int i; + + (void) appdata_ptr; + + *resp = calloc((size_t)num_msg, sizeof(struct pam_response)); + + for (i = 0; i < num_msg; i++) { + (*resp)[i].resp = NULL; + (*resp)[i].resp_retcode = 0; + + if ((**msg[i]).msg_style == PAM_PROMPT_ECHO_OFF) { + (*resp)[i].resp = passphrase_reader(); + auto_authenticated = 0; + } } - } - - return PAM_SUCCESS; -} + return PAM_SUCCESS; +} diff --git a/src/auth/pam.h b/src/auth/pam.h index ecfe03a..0b85631 100644 --- a/src/auth/pam.h +++ b/src/auth/pam.h @@ -1,7 +1,7 @@ /** * cerberus – Minimal login program * - * Copyright © 2013, 2014, 2015, 2016, 2020 Mattias Andrée (maandree@kth.se) + * Copyright © 2013, 2014, 2015, 2016, 2020 Mattias Andrée (m@maandree.se) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,11 +23,11 @@ /** * Initialise PAM * - * @param remote The remote computer, {@code NULL} for local login + * @param remote The remote computer, `NULL` for local login * @param username The username of the user to log in to * @param reader Function that can be used to read a passphrase from the terminal */ -void initialise_pam(char* remote, char* username, char* (*reader)(void)); +void initialise_pam(char *remote, char *username, char *(*reader)(void)); /** * Verify that the account may be used @@ -53,4 +53,3 @@ char authenticate_pam(void); #endif - |
