Add login, sudo, user session, auth lib, etc.

This commit is contained in:
K. Lange 2018-05-10 22:33:32 +09:00
parent 554e6d10ed
commit ffa4bd7360
18 changed files with 356 additions and 11 deletions

View File

@ -158,7 +158,7 @@ endif
# Ramdisk
cdrom/ramdisk.img: ${APPS_X} ${LIBS_X} base/lib/ld.so $(shell find base) Makefile | dirs
genext2fs -B 4096 -d base -U -b 4096 -N 2048 cdrom/ramdisk.img
genext2fs -B 4096 -d base -D util/devtable -U -b 4096 -N 2048 cdrom/ramdisk.img
# CD image

View File

@ -22,10 +22,9 @@ int start_options(char * args[]) {
if (!pid) {
char * _envp[] = {
"LD_LIBRARY_PATH=/lib",
"HOME=/",
"PATH=/bin",
"USER=root",
"WM_THEME=fancy",
"HOME=/home/root",
NULL,
};
syscall_execve(args[0], args, _envp);
@ -46,7 +45,7 @@ int main(int argc, char * argv[]) {
if (argc > 1) {
if (!strcmp(argv[1], "--vga")) {
return start_options((char *[]){"/bin/terminal-vga",NULL});
return start_options((char *[]){"/bin/terminal-vga","-l",NULL});
} else if (!strcmp(argv[1], "--migrate")) {
return start_options((char *[]){"/bin/migrate",NULL});
} else {

34
apps/live-session.c Normal file
View File

@ -0,0 +1,34 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <syscall.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#include <toaru/auth.h>
int main(int argc, char * argv[]) {
if (getuid() != 0) {
return 1;
}
int _session_pid = fork();
if (!_session_pid) {
setuid(1000);
toaru_auth_set_vars();
char * args[] = {"/bin/session", NULL};
execvp(args[0], args);
return 1;
}
int pid = 0;
do {
pid = wait(NULL);
} while ((pid > 0 && pid != _session_pid) || (pid == -1 && errno == EINTR));
/* TODO Exec login manager here */
return 0;
}

132
apps/login.c Normal file
View File

@ -0,0 +1,132 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2013-2014 Kevin Lange
*
* Login Service
*
* Provides the user with a login prompt and starts their session.
*
*/
#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 <toaru/auth.h>
#define LINE_LEN 1024
uint32_t child = 0;
void sig_pass(int sig) {
/* Pass onto the shell */
if (child) {
kill(child, sig);
}
/* Else, ignore */
}
void sig_segv(int sig) {
printf("Segmentation fault.\n");
exit(127 + sig);
/* no return */
}
int main(int argc, char ** argv) {
printf("\n");
system("uname -a");
printf("\n");
signal(SIGINT, sig_pass);
signal(SIGWINCH, sig_pass);
signal(SIGSEGV, sig_segv);
while (1) {
char * username = malloc(sizeof(char) * 1024);
char * password = malloc(sizeof(char) * 1024);
/* TODO: gethostname() */
char _hostname[256];
syscall_gethostname(_hostname);
fprintf(stdout, "%s login: ", _hostname);
fflush(stdout);
char * r = fgets(username, 1024, stdin);
if (!r) {
clearerr(stdin);
fprintf(stderr, "\n");
sleep(2);
fprintf(stderr, "\nLogin failed.\n");
continue;
}
username[strlen(username)-1] = '\0';
fprintf(stdout, "password: ");
fflush(stdout);
/* Disable echo */
struct termios old, new;
tcgetattr(fileno(stdin), &old);
new = old;
new.c_lflag &= (~ECHO);
tcsetattr(fileno(stdin), TCSAFLUSH, &new);
r = fgets(password, 1024, stdin);
if (!r) {
clearerr(stdin);
tcsetattr(fileno(stdin), TCSAFLUSH, &old);
fprintf(stderr, "\n");
sleep(2);
fprintf(stderr, "\nLogin failed.\n");
continue;
}
password[strlen(password)-1] = '\0';
tcsetattr(fileno(stdin), TCSAFLUSH, &old);
fprintf(stdout, "\n");
int uid = toaru_auth_check_pass(username, password);
if (uid < 0) {
sleep(2);
fprintf(stdout, "\nLogin failed.\n");
continue;
}
system("cat /etc/motd");
pid_t pid = getpid();
pid_t f = fork();
if (getpid() != pid) {
setuid(uid);
toaru_auth_set_vars();
char * args[] = {
getenv("SHELL"),
NULL
};
int i = execvp(args[0], args);
} else {
child = f;
int result;
do {
result = waitpid(f, NULL, 0);
} while (result < 0);
}
child = 0;
free(username);
free(password);
}
return 0;
}

View File

@ -93,9 +93,9 @@ void copy_directory(char * source, char * dest, int mode) {
if (S_ISLNK(statbuf.st_mode)) {
copy_link(tmp, tmp2);
} else if (S_ISDIR(statbuf.st_mode)) {
copy_directory(tmp, tmp2, statbuf.st_mode & 0777);
copy_directory(tmp, tmp2, statbuf.st_mode & 07777);
} else if (S_ISREG(statbuf.st_mode)) {
copy_file(tmp, tmp2, statbuf.st_mode & 0777);
copy_file(tmp, tmp2, statbuf.st_mode & 07777);
} else {
fprintf(stderr, " %s is not any of the required file types?\n", tmp);
}
@ -210,7 +210,7 @@ int main(int argc, char * argv[]) {
TRACE("Launching intended startup app...");
if (!strcmp(start, "--vga")) {
execvp("/bin/terminal-vga", (char *[]){"terminal-vga",NULL});
execvp("/bin/terminal-vga", (char *[]){"terminal-vga","-l",NULL});
} else if (start) {
execvp("/bin/compositor", (char *[]){"compositor","--",start,NULL});
} else {

86
apps/sudo.c Normal file
View File

@ -0,0 +1,86 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2014 Kevin Lange
*
* 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 <toaru/auth.h>
uint32_t child = 0;
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 = toaru_auth_check_pass(username, password);
if (uid < 0) {
fails++;
if (fails == 3) {
fprintf(stderr, "%s: %d incorrect password attempts\n", argv[0], fails);
break;
}
fprintf(stderr, "Sorry, try again.\n");
continue;
}
toaru_auth_set_vars();
char ** args = &argv[1];
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;
}
return 1;
}

2
base/etc/master.passwd Normal file
View File

@ -0,0 +1,2 @@
root:toor:0:0:Administrator:/home/root:/bin/sh:fancy
local:local:1000:1000:Local User:/home/local:/bin/sh:fancy

8
base/etc/motd Normal file
View File

@ -0,0 +1,8 @@
Welcome to ToaruOS!
ToaruOS is free software, released under the terms
of the NCSA / University of Illinois License.
http://github.com/klange/toaruos

View File

@ -1 +1,2 @@
root:x:0:0:Administrator:/home/root:/bin/sh:fancy
local:x:1000:1000:Local User:/home/local:/bin/sh:fancy

1
base/home/local/hello Normal file
View File

@ -0,0 +1 @@
Hello, world!

1
base/home/root/hello Normal file
View File

@ -0,0 +1 @@
Hello, root.

View File

@ -0,0 +1,11 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2013-2018 K. Lange
*/
#pragma once
extern int toaru_auth_check_pass(char * user, char * pass);
extern void toaru_auth_set_vars(void);

View File

@ -19,6 +19,8 @@ extern int execvp(const char *file, char *const argv[]);
extern int execvpe(const char *file, char *const argv[], char *const envp[]);
extern void _exit(int status);
extern int setuid(uid_t uid);
extern uid_t getuid(void);
extern uid_t geteuid(void);
extern gid_t getgid(void);
@ -40,6 +42,7 @@ extern int chdir(const char *path);
extern int fchdir(int fd);
extern int isatty(int fd);
extern unsigned int sleep(unsigned int seconds);
extern int usleep(useconds_t usec);
extern off_t lseek(int fd, off_t offset, int whence);

View File

@ -394,9 +394,9 @@ int kmain() {
if (boot_mode == 0) {
if (_debug) {
multiboot_header.cmdline = (uintptr_t)"logtoserial=3 vid=auto,1440,900 root=/dev/ram0,nocache start=--migrate _start=session";
multiboot_header.cmdline = (uintptr_t)"logtoserial=3 vid=auto,1440,900 root=/dev/ram0,nocache start=--migrate _start=live-session";
} else {
multiboot_header.cmdline = (uintptr_t)"vid=auto,1440,900 root=/dev/ram0,nocache start=--migrate _start=session";
multiboot_header.cmdline = (uintptr_t)"vid=auto,1440,900 root=/dev/ram0,nocache start=--migrate _start=live-session";
}
} else if (boot_mode == 1) {
if (_debug) {

65
lib/auth.c Normal file
View File

@ -0,0 +1,65 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2013-2018 K. Lange
*
* Authentication methods
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#ifndef fgetpwent
extern struct passwd *fgetpwent(FILE *stream);
#endif
#define MASTER_PASSWD "/etc/master.passwd"
int toaru_auth_check_pass(char * user, char * pass) {
/* XXX DO something useful */
/* Open up /etc/master.passwd */
FILE * master = fopen(MASTER_PASSWD, "r");
struct passwd * p;
while ((p = fgetpwent(master))) {
if (!strcmp(p->pw_name, user) && !strcmp(p->pw_passwd, pass)) {
fclose(master);
return p->pw_uid;
}
}
fclose(master);
return -1;
}
void toaru_auth_set_vars(void) {
int uid = getuid();
struct passwd * p = getpwuid(uid);
if (!p) {
char tmp[10];
sprintf(tmp, "%d", uid);
setenv("USER", strdup(tmp), 1);
setenv("HOME", "/", 1);
setenv("SHELL", "/bin/sh", 1);
} else {
setenv("USER", strdup(p->pw_name), 1);
setenv("HOME", strdup(p->pw_dir), 1);
setenv("SHELL", strdup(p->pw_shell), 1);
setenv("WM_THEME", strdup(p->pw_comment), 1);
}
endpwent();
setenv("PATH", "/usr/bin:/bin", 0);
chdir(getenv("HOME"));
}

View File

@ -17,7 +17,6 @@ DEFN_SYSCALL0(getgraphicswidth, 18);
DEFN_SYSCALL0(getgraphicsheight, 19);
DEFN_SYSCALL0(getgraphicsdepth, 20);
DEFN_SYSCALL0(mkpipe, 21);
DEFN_SYSCALL1(setuid, 24, unsigned int);
DEFN_SYSCALL1(kernel_string_XXX, 25, char *);
DEFN_SYSCALL0(reboot, 26);
DEFN_SYSCALL3(readdir, 27, int, int, void *);
@ -38,7 +37,6 @@ DEFN_SYSCALL2(sleepabs, 45, unsigned long, unsigned long);
DEFN_SYSCALL3(ioctl, 47, int, int, void *);
DEFN_SYSCALL2(access, 48, char *, int);
DEFN_SYSCALL2(stat, 49, char *, void *);
DEFN_SYSCALL2(chmod, 50, char *, int);
DEFN_SYSCALL1(umask, 51, int);
DEFN_SYSCALL1(unlink, 52, char *);
DEFN_SYSCALL3(waitpid, 53, int, int *, int);

View File

@ -25,6 +25,7 @@ class Classifier(object):
'<toaru/hashmap.h>': (None, '-ltoaru_hashmap', ['<toaru/list.h>']),
'<toaru/tree.h>': (None, '-ltoaru_tree', ['<toaru/list.h>']),
'<toaru/pex.h>': (None, '-ltoaru_pex', []),
'<toaru/auth.h>': (None, '-ltoaru_auth', []),
'<toaru/graphics.h>': (None, '-ltoaru_graphics', []),
'<toaru/drawstring.h>': (None, '-ltoaru_drawstring', ['<toaru/graphics.h>']),
'<toaru/rline.h>': (None, '-ltoaru_rline', ['<toaru/kbd.h>']),

3
util/devtable Normal file
View File

@ -0,0 +1,3 @@
/bin/sudo f 4555 0 0 - - - - -
/home/local d 775 1000 1000 - - - - -
/home/local/hello f 664 1000 1000 - - - - -