Browse Source

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

K. Lange 2 years ago
parent
commit
ffa4bd7360
18 changed files with 356 additions and 11 deletions
  1. 1 1
      Makefile
  2. 2 3
      apps/init.c
  3. 34 0
      apps/live-session.c
  4. 132 0
      apps/login.c
  5. 3 3
      apps/migrate.c
  6. 86 0
      apps/sudo.c
  7. 2 0
      base/etc/master.passwd
  8. 8 0
      base/etc/motd
  9. 1 0
      base/etc/passwd
  10. 1 0
      base/home/local/hello
  11. 1 0
      base/home/root/hello
  12. 11 0
      base/usr/include/toaru/auth.h
  13. 3 0
      base/usr/include/unistd.h
  14. 2 2
      boot/cstuff.c
  15. 65 0
      lib/auth.c
  16. 0 2
      libc/main.c
  17. 1 0
      util/auto-dep.py
  18. 3 0
      util/devtable

+ 1 - 1
Makefile

@@ -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
 

+ 2 - 3
apps/init.c

@@ -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 - 0
apps/live-session.c

@@ -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 - 0
apps/login.c

@@ -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;
+}

+ 3 - 3
apps/migrate.c

@@ -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 - 0
apps/sudo.c

@@ -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 - 0
base/etc/master.passwd

@@ -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 - 0
base/etc/motd

@@ -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
+

+ 1 - 0
base/etc/passwd

@@ -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 - 0
base/home/local/hello

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

+ 1 - 0
base/home/root/hello

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

+ 11 - 0
base/usr/include/toaru/auth.h

@@ -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);
+

+ 3 - 0
base/usr/include/unistd.h

@@ -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);
 

+ 2 - 2
boot/cstuff.c

@@ -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 - 0
lib/auth.c

@@ -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"));
+}
+

+ 0 - 2
libc/main.c

@@ -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);

+ 1 - 0
util/auto-dep.py

@@ -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 - 0
util/devtable

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