logo

skeud

Simple and portable utilities to deal with user accounts (su, login)git clone https://anongit.hacktivis.me/git/skeud.git/
commit: a5b101daf714dfeb3cddc9ea973f6199c69d0924
parent e016382605f6cdc93afc3bd63d8df6a53225b80c
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sun, 28 Sep 2025 14:04:48 +0200

Improve error messages

Diffstat:

Mcommon.c30+++++++++++++++++++++++-------
Mcommon.h1+
Mlogin.c29++++++++++++++++-------------
Msu.c10+++++-----
4 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/common.c b/common.c @@ -16,6 +16,22 @@ #undef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +// doesn't exits to make sure cleanup is done +int +skeud_err(const char *errmsg, int err) +{ + fputs(argv0, stderr); + fputs(": error: ", stderr); + fputs(errmsg, stderr); + if(err != 0) + { + fputs(": ", stderr); + fputs(strerror(err), stderr); + } + fputs("\n", stderr); + return fflush(stderr); +} + // Needs to be constant-time bool hash_match(const char *a, size_t alen, const char *b, size_t blen) @@ -42,7 +58,7 @@ skeud_crypt_check(const char *hash, const char *password) char *chk_hash = crypt(password, hash); if(chk_hash == NULL) { - fprintf(stderr, "%s: error: Failed hashing password: %s\n", argv0, strerror(errno)); + skeud_err("Failed hashing password", errno); return false; } @@ -65,19 +81,19 @@ skeud_getpass(char **password) FILE *tty = fopen("/dev/tty", "rb+"); if(tty == NULL) { - perror("skeud_getpass: error: open(\"/dev/tty\")"); + skeud_err("Failed opening '/dev/tty'", errno); return got; } int tty_fd = fileno(tty); if(tty_fd < 0) { - perror("skeud_getpass: error: fileno(tty)"); + skeud_err("Failed getting fd from '/dev/tty' stream", errno); goto getpass_end; } if(tcgetattr(tty_fd, &t) < 0) { - perror("skeud_getpass: error: tcgetattr"); + skeud_err("Failed getting terminal attributes", errno); goto getpass_end; } @@ -86,7 +102,7 @@ skeud_getpass(char **password) t.c_lflag &= ~ECHO; if(tcsetattr(tty_fd, TCSANOW, &t) < 0) { - perror("skeud_getpass: error: tcsetattr(~ECHO)"); + skeud_err("Failed disabling terminal echo", errno); goto getpass_end; } @@ -94,7 +110,7 @@ skeud_getpass(char **password) got = getline(password, &len, tty); if(got < 0) { - if(errno != 0) perror("skeud_getpass: error: getline"); + if(errno != 0) skeud_err("Failed reading line", errno); goto getpass_clean; } fputs("\n", tty); @@ -106,7 +122,7 @@ getpass_clean: t.c_lflag ^= ECHO; if(tcsetattr(tty_fd, TCSANOW, &t) < 0) { - perror("skeud_getpass: error: tcsetattr(ECHO)"); + skeud_err("Failed re-enabling terminal echo", errno); explicit_bzero(password, got); got = -1; goto getpass_end; diff --git a/common.h b/common.h @@ -8,6 +8,7 @@ extern const char *argv0; #define strlen0(str) str ? strlen(str) : 0 +int skeud_err(const char *errmsg, int err); bool hash_match(const char *a, size_t alen, const char *b, size_t blen); bool skeud_crypt_check(const char *hash, const char *password); ssize_t skeud_getpass(char **password); diff --git a/login.c b/login.c @@ -47,17 +47,17 @@ process_pwent(struct passwd *pwent) /* considers that STDIN_FILENO is close enough to the current tty */ if(fchown(STDIN_FILENO, pwent->pw_uid, tty_gid) < 0) { - perror("login: error: fchown"); + perror("login: error: Failed setting TTY owner:group"); return 1; } if(fchmod(STDIN_FILENO, TTY_PERMS)) { - perror("login: error: fchmod"); + perror("login: error: Failed setting TTY permissions"); return 1; } if(setgid(pwent->pw_gid) < 0) { - perror("login: error: setgid"); + perror("login: error: Failed setting group-id"); return 1; } if(initgroups(pwent->pw_name, pwent->pw_gid) < 0) @@ -67,7 +67,7 @@ process_pwent(struct passwd *pwent) } if(setuid(pwent->pw_uid) < 0) { - perror("login: error: setuid"); + perror("login: error: Failed setting user-id"); return 1; } @@ -77,7 +77,10 @@ process_pwent(struct passwd *pwent) if(chdir(pwent->pw_dir) != 0) { - fprintf(stderr, "login: warning: Failed to change current directory to: %s\n", pwent->pw_dir); + fprintf(stderr, + "login: warning: Failed to change current directory to '%s': %s\n", + pwent->pw_dir, + strerror(errno)); } } @@ -96,7 +99,7 @@ main(int argc, char *argv[]) if(getuid() != 0) { - fprintf(stderr, "login: error: Not super-user\n"); + fputs("login: error: Not super-user\n", stderr); return 1; } @@ -119,7 +122,7 @@ main(int argc, char *argv[]) fprintf(stderr, "login: error: Unrecognized option: '-%c'\n", optopt); return 1; default: - fprintf(stderr, "login: error: Unknown getopt state, aborting\n"); + fputs("login: error: Unknown getopt state, aborting\n", stderr); abort(); } } @@ -158,7 +161,7 @@ main(int argc, char *argv[]) ssize_t got = getline(&username_buf, &len, stdin); if(got < 0) { - if(errno != 0) perror("login: error: getline"); + if(errno != 0) skeud_err("Failed reading line", errno); free(username_buf); return 1; } @@ -175,7 +178,7 @@ main(int argc, char *argv[]) pwent = getpwnam(username); if(errno != 0) { - perror("login: warning: getpwnam"); + perror("login: warning: Failed getting passwd entry"); } if(!opt_f) @@ -192,7 +195,7 @@ main(int argc, char *argv[]) struct spwd *swent = getspnam(username); if(errno != 0) { - perror("login: getspnam"); + perror("login: warning: Failed getting shadow passwd entry"); } else { @@ -225,7 +228,7 @@ main(int argc, char *argv[]) { free(username_buf); sleep(2); - fprintf(stderr, "login: error: Invalid username or password\n"); + fputs("login: error: Invalid username or password\n", stderr); return 1; } } @@ -278,12 +281,12 @@ main(int argc, char *argv[]) { if(errno == ENOENT) { - perror("login: error: execve"); + perror("login: error: Failed executing shell"); return 127; } else { - perror("login: error: execve"); + perror("login: error: Failed executing shell"); return 126; } } diff --git a/su.c b/su.c @@ -39,7 +39,7 @@ main(int argc, char *argv[]) if(geteuid() != 0) { - fprintf(stderr, "su: error: Not effectively super-user. Missing setuid?\n"); + fputs("su: error: Not effectively super-user. Missing setuid?\n", stderr); return 1; } @@ -57,7 +57,7 @@ main(int argc, char *argv[]) case 's': // shell if(getuid() != 0) { - fprintf(stderr, "su: error: Only the super-user can override the target shell\n"); + fputs("su: error: Only the super-user can override the target shell\n", stderr); return 1; } @@ -66,7 +66,7 @@ main(int argc, char *argv[]) case 'p': // preserve environment if(getuid() != 0) { - fprintf(stderr, "su: error: Only the super-user can preserve the environment\n"); + fputs("su: error: Only the super-user can preserve the environment\n", stderr); return 1; } @@ -79,7 +79,7 @@ main(int argc, char *argv[]) fprintf(stderr, "su: error: Unrecognized option: '-%c'\n", optopt); return 1; default: - fprintf(stderr, "su: error: Unknown getopt state, aborting\n"); + fputs("su: error: Unknown getopt state, aborting\n", stderr); abort(); } } @@ -113,7 +113,7 @@ main(int argc, char *argv[]) { if(errno != 0) { - perror("su: error: getpwnam"); + perror("su: error: Failed getting passwd entry"); } else {