naive implementation of sudo and possibly insecure setuid support
This commit is contained in:
parent
095675b012
commit
f054cebdce
4
Makefile
4
Makefile
@ -220,10 +220,10 @@ $(foreach file,$(USER_CXXFILES),$(eval $(call user-cxx-rule,$(patsubst %.c++,hdd
|
||||
# Hard Disk Images #
|
||||
####################
|
||||
|
||||
toaruos-disk.img: ${USERSPACE} ${MODULES}
|
||||
toaruos-disk.img: ${USERSPACE} ${MODULES} util/devtable
|
||||
@${BEG} "hdd" "Generating a Hard Disk image..."
|
||||
@-rm -f toaruos-disk.img
|
||||
@${GENEXT} -B 4096 -d hdd -U -b ${DISK_SIZE} -N 4096 toaruos-disk.img ${ERRORS}
|
||||
@${GENEXT} -B 4096 -d hdd -D util/devtable -U -b ${DISK_SIZE} -N 4096 toaruos-disk.img ${ERRORS}
|
||||
@${END} "hdd" "Generated Hard Disk image"
|
||||
@${INFO} "--" "Hard disk image is ready!"
|
||||
|
||||
|
@ -108,7 +108,6 @@ exec(
|
||||
|
||||
/* Free the space we used for the ELF headers and files */
|
||||
free(header);
|
||||
close_fs(file);
|
||||
|
||||
for (uintptr_t stack_pointer = USER_STACK_BOTTOM; stack_pointer < USER_STACK_TOP; stack_pointer += 0x1000) {
|
||||
alloc_frame(get_page(stack_pointer, 1, current_directory), 0, 1);
|
||||
@ -173,6 +172,14 @@ exec(
|
||||
|
||||
current_process->image.start = entry;
|
||||
|
||||
/* XXX setuid */
|
||||
if (file->mask & 0x800) {
|
||||
debug_print(WARNING, "setuid binary executed [%s, uid:%d]", file->name, file->uid);
|
||||
current_process->user = file->uid;
|
||||
}
|
||||
|
||||
close_fs(file);
|
||||
|
||||
/* Go go go */
|
||||
enter_user_jmp(entry, argc, argv_, USER_STACK_TOP);
|
||||
|
||||
|
@ -133,6 +133,8 @@ void print_entry_long(const char * filename, const char * srcpath) {
|
||||
/* file permissions */
|
||||
if (S_ISLNK(statbuf.st_mode)) {
|
||||
printf("l");
|
||||
} else if (statbuf.st_mode & S_ISUID) {
|
||||
printf("s");
|
||||
} else {
|
||||
printf( (S_ISDIR(statbuf.st_mode)) ? "d" : "-");
|
||||
}
|
||||
|
120
userspace/core/sudo.c
Normal file
120
userspace/core/sudo.c
Normal file
@ -0,0 +1,120 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
*
|
||||
* sudo
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <syscall.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include "lib/sha2.h"
|
||||
|
||||
#define LINE_LEN 1024
|
||||
|
||||
uint32_t child = 0;
|
||||
|
||||
int checkUserPass(char * user, char * pass) {
|
||||
|
||||
/* Generate SHA512 */
|
||||
char hash[SHA512_DIGEST_STRING_LENGTH];
|
||||
SHA512_Data(pass, strlen(pass), hash);
|
||||
|
||||
/* Open up /etc/master.passwd */
|
||||
|
||||
FILE * passwd = fopen("/etc/master.passwd", "r");
|
||||
char line[2048];
|
||||
|
||||
while (fgets(line, 2048, passwd) != NULL) {
|
||||
|
||||
line[strlen(line)-1] = '\0';
|
||||
|
||||
char *p, *tokens[4], *last;
|
||||
int i = 0;
|
||||
for ((p = strtok_r(line, ":", &last)); p;
|
||||
(p = strtok_r(NULL, ":", &last)), i++) {
|
||||
if (i < 511) tokens[i] = p;
|
||||
}
|
||||
tokens[i] = NULL;
|
||||
|
||||
if (strcmp(tokens[0],user) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(tokens[1],hash)) {
|
||||
fclose(passwd);
|
||||
return atoi(tokens[2]);
|
||||
}
|
||||
}
|
||||
fclose(passwd);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
void usage(int argc, char * argv[]) {
|
||||
fprintf(stderr, "usage: %s [command]\n", argv[0]);
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
|
||||
int fails = 0;
|
||||
|
||||
if (argc < 2) {
|
||||
usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/*
|
||||
* This is not very secure, but I'm lazy and just want this to exist.
|
||||
* It's not like we have file system permissions or anything like
|
||||
* that sitting around anyway... So, XXX: make this not dumb.
|
||||
*/
|
||||
char * username = getenv("USER");
|
||||
char * password = malloc(sizeof(char) * 1024);
|
||||
|
||||
fprintf(stdout, "[%s] password for %s: ", argv[0], username);
|
||||
fflush(stdout);
|
||||
|
||||
/* Disable echo */
|
||||
struct termios old, new;
|
||||
tcgetattr(fileno(stdin), &old);
|
||||
new = old;
|
||||
new.c_lflag &= (~ECHO);
|
||||
tcsetattr(fileno(stdin), TCSAFLUSH, &new);
|
||||
|
||||
fgets(password, 1024, stdin);
|
||||
password[strlen(password)-1] = '\0';
|
||||
tcsetattr(fileno(stdin), TCSAFLUSH, &old);
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
int uid = checkUserPass(username, password);
|
||||
|
||||
if (uid < 0) {
|
||||
fails++;
|
||||
if (fails == 3) {
|
||||
fprintf(stderr, "%s: %d incorrect password attempts\n", argv[0]);
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "Sorry, try again.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
char ** args = &argv[1];
|
||||
int i = execvp(args[0], args);
|
||||
|
||||
/* XXX: There are other things that can cause an exec to fail. */
|
||||
fprintf(stderr, "%s: %s: command not found\n", argv[0], args[0]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
1
util/devtable
Normal file
1
util/devtable
Normal file
@ -0,0 +1 @@
|
||||
/bin/sudo f 4555 0 0 - - - - -
|
Loading…
Reference in New Issue
Block a user