71 lines
1.3 KiB
C
71 lines
1.3 KiB
C
|
#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);
|
||
|
}
|