implemented config persist

master
Alessandro Mauri 3 years ago
parent 391353cea6
commit f489885e3e
  1. 76
      us.c

76
us.c

@ -39,6 +39,8 @@
#include <stdarg.h>
#include <ctype.h>
#include <signal.h>
#include <time.h>
#include <fcntl.h>
#if !defined(_XOPEN_CRYPT) || _XOPEN_CRYPT == -1
#include <crypt.h>
@ -55,6 +57,8 @@
#define FLAG_PERSIST 0x1
#define FLAG_NOPASS 0x2
#define FLAG_NOLOG 0x4
#define SESSION_FILE_DIR "/var/run"
#define SESSION_TIMEOUT (60*5)
struct env_elem {
char *name;
@ -84,7 +88,7 @@ void *erealloc(void *, size_t);
static void usage(void);
static void die(const char *, ...);
static int perm_set(struct passwd *, struct group *);
static int authenticate(uid_t, char);
static int authenticate(uid_t, int, int);
static struct passwd* user_to_passwd(const char *, struct user_info *);
static struct group* group_to_grp(const char *, struct user_info *);
static int get_config(struct config **, int *);
@ -159,6 +163,8 @@ int main(int argc, char *argv[])
/* From now on most actions require root */
if (setuid(0) == -1)
die("setuid:");
if (setgid(0) == -1)
die("setgid:");
/* get info from the config file and check if the action we want to
* do is permitted */
@ -236,7 +242,7 @@ int main(int argc, char *argv[])
/* Authenticate, we will be root from now on */
if (!(conf_flags & FLAG_NOPASS))
if (authenticate(my_pw->pw_uid, askpass))
if (authenticate(my_pw->pw_uid, askpass, conf_flags & FLAG_PERSIST))
exit(EXIT_FAILURE);
/* Get target user's shell */
@ -394,9 +400,57 @@ static int perm_set(struct passwd *pw, struct group *gr)
return 0;
}
static int authenticate(uid_t uid, char ask)
static int authenticate(uid_t uid, int ask, int persist)
{
// TODO: implement u2f compat
// TODO: check root access, maybe
/* try to check if a valid saved session exists */
char tmp_file[512] = {0};
if (persist) {
pid_t sid = getsid(0);
if (sid == (pid_t)-1)
die("getsid:");
if (snprintf(tmp_file, 512, SESSION_FILE_DIR "/us.%d", sid) >= 512)
die("snprintf: output truncated");
int session_file = open(tmp_file, O_RDONLY | O_CLOEXEC);
int valid_session = 1;
struct timespec now_t[2] = {0}, old_t[2] = {0};
if (session_file != -1) {
struct stat st;
if (fstat(session_file, &st) == -1) {
valid_session = 0;
} else if (st.st_uid != 0 || st.st_gid != 0) {
valid_session = 0;
} else if (!S_ISREG(st.st_mode)) {
valid_session = 0;
} else if (st.st_mode & S_IRWXO ||
st.st_mode & S_IROTH ||
st.st_mode & S_IWOTH || st.st_mode & S_IXOTH) {
valid_session = 0;
} else {
int r = read(session_file, old_t, sizeof(struct timespec)*2);
if (r != sizeof(struct timespec)*2)
valid_session = 0;
close(session_file);
}
} else {
valid_session = 0;
}
if (valid_session && session_file != -1) {
if (clock_gettime(CLOCK_MONOTONIC, &(now_t[0])) == -1)
die("clock_gettime:");
if (clock_gettime(CLOCK_REALTIME, &(now_t[1])) == -1)
die("clock_gettime:");
if (now_t[0].tv_sec <= old_t[0].tv_sec ||
old_t[0].tv_sec < now_t[0].tv_sec - SESSION_TIMEOUT ||
now_t[1].tv_sec <= old_t[1].tv_sec ||
old_t[1].tv_sec < now_t[1].tv_sec - SESSION_TIMEOUT)
valid_session = 0;
}
if (valid_session)
return 0;
}
/* get the encrypted password */
struct passwd *pw = getpwuid(uid);
char *hash_p, hash[MAX_HASH];
@ -511,6 +565,22 @@ static int authenticate(uid_t uid, char ask)
return -1;
}
printf("\n");
if (persist) {
if (!tmp_file[0])
return 0;
int session_file = creat(tmp_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (session_file == -1)
return 0;
chown(tmp_file, 0, 0);
struct timespec t[2] = {0};
if (clock_gettime(CLOCK_MONOTONIC, &(t[0])) == -1)
die("clock_gettime:");
if (clock_gettime(CLOCK_REALTIME, &(t[1])) == -1)
die("clock_gettime:");
write(session_file, t, sizeof(struct timespec)*2);
close(session_file);
}
return 0;
}

Loading…
Cancel
Save