diff options
author | Tyler Murphy <tylerm@tylerm.dev> | 2023-05-14 21:43:02 -0400 |
---|---|---|
committer | Tyler Murphy <tylerm@tylerm.dev> | 2023-05-14 21:43:02 -0400 |
commit | e735ad6710a82604a206ad29f6cbcdd7dc4b024c (patch) | |
tree | 5fe8eebbb7a2bff20bb71bd2368955356979e0a2 /lib/password.c | |
parent | sync (diff) | |
download | lazysphere-e735ad6710a82604a206ad29f6cbcdd7dc4b024c.tar.gz lazysphere-e735ad6710a82604a206ad29f6cbcdd7dc4b024c.tar.bz2 lazysphere-e735ad6710a82604a206ad29f6cbcdd7dc4b024c.zip |
refactor and add su
Diffstat (limited to 'lib/password.c')
-rw-r--r-- | lib/password.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/password.c b/lib/password.c new file mode 100644 index 0000000..7457878 --- /dev/null +++ b/lib/password.c @@ -0,0 +1,70 @@ +#include "lslib.h" + +#include <errno.h> +#include <pwd.h> +#include <shadow.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define SHADOW_BUFSIZE 256 + +static const char* get_passwd(const struct passwd* pw) { + const char *pass; + + if (!pw) + return "aa"; /* "aa" will never match */ + + pass = pw->pw_passwd; + + if ((pass[0] == 'x' || pass[0] == '*') && !pass[1]) { + struct spwd* result; + + errno = 0; + result = getspnam(pw->pw_name); + + if (errno == EACCES) { + errno = 0; + error("binary not properly installed"); + } + + pass = (result == NULL) ? "aa" : result->sp_pwdp; + } + + return pass; +} + +int check_password(const struct passwd *pw, char* plaintext) { + char* encrypted; + char* salt; + char* p; + const char *pw_pass; + int r; + + pw_pass = get_passwd(pw); + if (!pw_pass[0]) { + return PASSWORD_EMPTY; + } + + salt = strdup(pw_pass); + if (salt == NULL) die(); + p = strchr(salt + 1, '$'); + if (p == NULL) die(); + p = strchr(p + 1, '$'); + if (p == NULL) die(); + p[1] = 0; + + encrypted = crypt(plaintext, salt); + r = (strcmp(encrypted, pw_pass) == 0); + + nuke_str(plaintext); + free(salt); + + return r; +} + +int prompt_password(const struct passwd *pw, char* prompt) { + char* plaintext = getpass(prompt); + return check_password(pw, plaintext); +} |