Skip to content

Commit

Permalink
Merge pull request #44 from fischerling/add-shadow-file
Browse files Browse the repository at this point in the history
move passwords from /etc/passwd to /etc/shadow
  • Loading branch information
Galfurian authored Mar 6, 2024
2 parents d123c56 + e8cd897 commit 88bf849
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 3 deletions.
4 changes: 2 additions & 2 deletions files/etc/passwd
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
root:root:0:0:Root User:/root:/bin/shell
user:user:1000:1000:Normal User:/home/user:/bin/shell
root:x:0:0:Root User:/root:/bin/shell
user:x:1000:1000:Normal User:/home/user:/bin/shell
2 changes: 2 additions & 0 deletions files/etc/shadow
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
root:root:::::::
user:user:::::::
1 change: 1 addition & 0 deletions libc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# Add the library.
add_library(
libc
${CMAKE_SOURCE_DIR}/libc/src/shadow.c
${CMAKE_SOURCE_DIR}/libc/src/unistd/dup.c
${CMAKE_SOURCE_DIR}/libc/src/stdio.c
${CMAKE_SOURCE_DIR}/libc/src/ctype.c
Expand Down
22 changes: 22 additions & 0 deletions libc/inc/shadow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// @file shadow.h
/// @brief Secret password file routines
#pragma once

#include "stddef.h"

#define SHADOW "/etc/shadow"

struct spwd {
char *sp_namp;
char *sp_pwdp;
long sp_lstchg;
long sp_min;
long sp_max;
long sp_warn;
long sp_inact;
long sp_expire;
unsigned long sp_flag;
};

struct spwd *getspnam(const char *);
int getspnam_r(const char *, struct spwd *, char *, size_t, struct spwd **);
114 changes: 114 additions & 0 deletions libc/src/shadow.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/// @file shadow.c
/// @brief
/// @copyright (c) 2005-2020 Rich Felker, et al.
/// This file is based on the code from libmusl.
#include <shadow.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include <ctype.h>

static long xatol(char **s)
{
long x;
if (**s == ':' || **s == '\n') return -1;
for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
return x;
}

int __parsespent(char *s, struct spwd *sp)
{
sp->sp_namp = s;
if (!(s = strchr(s, ':'))) return -1;
*s = 0;

sp->sp_pwdp = ++s;
if (!(s = strchr(s, ':'))) return -1;
*s = 0;

s++; sp->sp_lstchg = xatol(&s);
if (*s != ':') return -1;

s++; sp->sp_min = xatol(&s);
if (*s != ':') return -1;

s++; sp->sp_max = xatol(&s);
if (*s != ':') return -1;

s++; sp->sp_warn = xatol(&s);
if (*s != ':') return -1;

s++; sp->sp_inact = xatol(&s);
if (*s != ':') return -1;

s++; sp->sp_expire = xatol(&s);
if (*s != ':') return -1;

s++; sp->sp_flag = xatol(&s);
if (*s != '\n') return -1;
return 0;
}

int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct spwd **res)
{
char path[20+NAME_MAX];
int rv = 0;
int fd;
size_t k, l = strlen(name);
int skip = 0;
int cs;
int orig_errno = errno;

*res = 0;

/* Disallow potentially-malicious user names */
if (*name=='.' || strchr(name, '/') || !l)
return errno = EINVAL;

/* Buffer size must at least be able to hold name, plus some.. */
if (size < l+100)
return errno = ERANGE;

fd = open(SHADOW, O_RDONLY, 0);
if (fd < 0) {
return errno;
}

while (fgets(buf, size, fd) && (k=strlen(buf))>0) {
if (skip || strncmp(name, buf, l) || buf[l]!=':') {
skip = buf[k-1] != '\n';
continue;
}
if (buf[k-1] != '\n') {
rv = ERANGE;
break;
}

if (__parsespent(buf, sp) < 0) continue;
*res = sp;
break;
}
errno = rv ? rv : orig_errno;
return rv;
}

#define LINE_LIM 256

struct spwd *getspnam(const char *name)
{
static struct spwd sp;
static char *line;
struct spwd *res;
int e;
int orig_errno = errno;

if (!line) line = malloc(LINE_LIM);
if (!line) return 0;
e = getspnam_r(name, &sp, line, LINE_LIM, &res);
errno = e ? e : orig_errno;
return res;
}
9 changes: 8 additions & 1 deletion programs/login.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <termios.h>
#include <bits/ioctls.h>
#include <pwd.h>
#include <shadow.h>
#include <strerror.h>
#include <stdlib.h>
#include <io/debug.h>
Expand Down Expand Up @@ -196,8 +197,14 @@ int main(int argc, char **argv)
continue;
}

struct spwd *spwd;
if ((spwd = getspnam(username)) == NULL) {
printf("Could not retrieve the secret password of %s:%s\n", username, strerror(errno));
continue;
}

// Check if the password is correct.
if (strcmp(pwd->pw_passwd, password) != 0) {
if (strcmp(spwd->sp_pwdp, password) != 0) {
printf("Wrong password.\n");
continue;
}
Expand Down

0 comments on commit 88bf849

Please sign in to comment.