diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/date/date.c | 51 | ||||
-rw-r--r-- | usr.bin/fetch/fetch.c | 9 | ||||
-rw-r--r-- | usr.bin/getconf/getconf.c | 5 | ||||
-rw-r--r-- | usr.bin/login/login.c | 103 | ||||
-rw-r--r-- | usr.bin/osh/osh.c | 4 | ||||
-rw-r--r-- | usr.bin/sleep/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/sleep/sleep.c | 55 |
8 files changed, 200 insertions, 34 deletions
diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 4c17ddf..e84831a 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -19,3 +19,4 @@ all: make -C echo/ $(ARGS) make -C readcore/ $(ARGS) make -C login/ $(ARGS) + make -C sleep/ $(ARGS) diff --git a/usr.bin/date/date.c b/usr.bin/date/date.c index a47e3eb..ab26c4c 100644 --- a/usr.bin/date/date.c +++ b/usr.bin/date/date.c @@ -32,6 +32,7 @@ #include <stdio.h> #include <fcntl.h> #include <unistd.h> +#include <string.h> #define MONTHS_PER_YEAR 12 #define DAYS_PER_WEEK 7 @@ -51,19 +52,63 @@ static const char *daytab[] = { "Fri" }; +static int +set_time(int clock_fd, struct date *dp, char *timestr) +{ + uint32_t hour, min, sec; + char *p; + + /* Hour */ + p = strtok(timestr, ":"); + if (p == NULL) + return -1; + hour = atoi(p); + + /* Minute */ + p = strtok(NULL, ":"); + if (p == NULL) + return -1; + min = atoi(p); + + /* Second */ + p = strtok(NULL, ":"); + if (p == NULL) + return -1; + sec = atoi(p); + + /* Set the time */ + dp->hour = hour; + dp->min = min; + dp->sec = sec; + write(clock_fd, dp, sizeof(*dp)); + return 0; +} + int -main(void) +main(int argc, char **argv) { const char *day, *month; char date_str[32]; struct date d; - int rtc_fd; + int rtc_fd, error = 0; - if ((rtc_fd = open("/dev/rtc", O_RDONLY)) < 0) { + if ((rtc_fd = open("/dev/rtc", O_RDWR)) < 0) { return rtc_fd; } + read(rtc_fd, &d, sizeof(d)); + + /* + * If a time was specified to be set in the + * 'hh:mm:ss' format, attempt to write it. + */ + if (argc > 1) { + error = set_time(rtc_fd, &d, argv[1]); + if (error < 0) + printf("bad time specified, not set\n"); + } + close(rtc_fd); /* This should not happen */ diff --git a/usr.bin/fetch/fetch.c b/usr.bin/fetch/fetch.c index 42c2825..175cd0e 100644 --- a/usr.bin/fetch/fetch.c +++ b/usr.bin/fetch/fetch.c @@ -32,18 +32,19 @@ #include <string.h> #include <stdio.h> +static const char *user = "unknown"; + #define ASCII_ART \ " ____ \n" \ " | \\__\\ \n" \ - " | /\\ \\ user: root\n" \ + " | /\\ \\ user: %s\n" \ " |/ \\ \\ OS: Hyra/amd64 v"_OSVER"\n" \ " \\ R. \\ \\ arch: "_OSARCH"\n" \ - " \\ I. \\ \\" - + " \\ I. \\ \\\n" int main(void) { - puts(ASCII_ART); + printf(ASCII_ART, getlogin()); return 0; } diff --git a/usr.bin/getconf/getconf.c b/usr.bin/getconf/getconf.c index c60bf5d..f028e76 100644 --- a/usr.bin/getconf/getconf.c +++ b/usr.bin/getconf/getconf.c @@ -37,12 +37,15 @@ struct sysvar { const char *var; uint8_t auxv : 1; - uint8_t val; + uint32_t val; }; static struct sysvar vartab[] = { { "PAGESIZE", 1, AT_PAGESIZE }, { "CHAR_BIT", 0, CHAR_BIT }, + { "NAME_MAX", 0, NAME_MAX }, + { "PATH_MAX", 0, PATH_MAX }, + { "SSIZE_MAX", 0, SSIZE_MAX }, { NULL, 0, 0 } }; diff --git a/usr.bin/login/login.c b/usr.bin/login/login.c index c5af6c0..e9b5e88 100644 --- a/usr.bin/login/login.c +++ b/usr.bin/login/login.c @@ -30,6 +30,7 @@ #include <sys/spawn.h> #include <sys/types.h> #include <sys/errno.h> +#include <crypto/sha256.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -46,11 +47,11 @@ #define is_ascii(C) ((C) >= 0 && (C) <= 128) #define is_digit(C) ((C >= '0' && C <= '9')) -#define USERNAME "root" #define DEFAULT_SHELL "/usr/bin/osh" static char buf[64]; static uint8_t buf_i; +static short echo_chars = 1; /* * Verify a UID is valid @@ -83,20 +84,25 @@ check_uid(const char *uid) * (username) * * @alias: Alias to lookup + * @hash: Password hash * @entry: /etc/passwd entry * * Returns -1 on failure * Returns 0 if the entry matches */ static int -check_user(char *alias, char *entry) +check_user(char *alias, char *hash, char *entry) { - const char *p, *shell; + const char *p; + char shell_path[256]; char *shell_argv[] = { DEFAULT_SHELL, NULL }; char *envp[] = { NULL }; - size_t row = 0; - short retval = -1; + size_t len, row = 0; size_t line = 1; + short have_user = 0; + short have_pw = 0; + short have_uid = 0; + short have_shell = 0; uid_t uid = -1; if (alias == NULL || entry == NULL) { @@ -115,9 +121,14 @@ check_user(char *alias, char *entry) switch (row) { case ROW_USERNAME: if (strcmp(p, alias) == 0) { - retval = 0; + have_user = 1; } break; /* UNREACHABLE */ + case ROW_HASH: + if (strcmp(p, hash) == 0) { + have_pw = 1; + } + break; case ROW_USERID: if (check_uid(p) != 0) { printf("bad uid @ line %d\n", line); @@ -125,9 +136,18 @@ check_user(char *alias, char *entry) } uid = atoi(p); + have_uid = 1; break; case ROW_SHELL: - /* TODO */ + len = strlen(p) - 1; + if (len >= sizeof(shell_path) - 1) { + printf("bad shell path @ line %d\n", line); + return -1; + } + + memcpy(shell_path, p, len); + shell_path[len] = '\0'; + have_shell = 1; break; } @@ -136,31 +156,34 @@ check_user(char *alias, char *entry) ++line; } - if (uid < 0) { - printf("failed to set uid\n"); + /* + * We need to have found the password hash, + * the username, AND the UID. If we have not, + * then this has failed. + */ + if (!have_pw || !have_user || !have_uid) { return -1; } - if (shell == NULL) { - printf("failed to read shell path\n"); + + /* Do we have the shell path? */ + if (!have_shell) { return -1; } - if (retval == 0) { - setuid(uid); - spawn(shell_argv[0], shell_argv, envp, SPAWN_WAIT); - } - return retval; + setuid(uid); + shell_argv[0] = shell_path; + spawn(shell_argv[0], shell_argv, envp, SPAWN_WAIT); + return 0; } static char * getstr(void) { - char c; + char c, printc; int input; buf_i = 0; - for (;;) { if ((input = getchar()) < 0) { continue; @@ -171,6 +194,13 @@ getstr(void) continue; } + /* + * If we want to echo characters, 'printc' becomes + * exactly the character we got. Otherwise, just + * print little stars to redact it. + */ + printc = echo_chars ? c : '*'; + /* return on newline */ if (c == '\n') { buf[buf_i] = '\0'; @@ -187,7 +217,7 @@ getstr(void) } else if (is_ascii(c) && buf_i < sizeof(buf) - 1) { /* write to fd and add to buffer */ buf[buf_i++] = c; - putchar(c); + putchar(printc); } } } @@ -195,24 +225,50 @@ getstr(void) static int getuser(FILE *fp) { - char *alias; + char *pwtmp, *alias, *p; char entry[256]; + char pwhash[SHA256_HEX_SIZE]; int retval; printf("username: "); - alias = getstr(); + p = getstr(); + alias = strdup(p); + + /* Grab the password now */ + echo_chars = 0; + printf("password: "); + p = getstr(); + pwtmp = strdup(p); + sha256_hex(pwtmp, strlen(pwtmp), pwhash); + + /* Paranoia */ + memset(pwtmp, 0, strlen(pwtmp)); + buf_i = 0; + memset(buf, 0, sizeof(buf)); + + /* Clean up */ + free(pwtmp); + pwtmp = NULL; + + /* See if anything matches */ while (fgets(entry, sizeof(entry), fp) != NULL) { - retval = check_user(alias, entry); + retval = check_user(alias, pwhash, entry); if (retval == 0) { printf("login: successful\n"); + free(alias); return 0; } } - printf("bad username \"%s\"\n", alias); + /* If we reach this point, bad creds */ + free(alias); + alias = NULL; + + printf("bad username or password\n"); fseek(fp, 0, SEEK_SET); memset(buf, 0, sizeof(buf)); buf_i = 0; + echo_chars = 1; return -1; } @@ -228,7 +284,6 @@ main(void) } printf("- Please authenticate yourself -\n"); - printf("Default user 'root'\n"); for (;;) { if (getuser(fp) == 0) { break; diff --git a/usr.bin/osh/osh.c b/usr.bin/osh/osh.c index 0bce357..5bcd2e2 100644 --- a/usr.bin/osh/osh.c +++ b/usr.bin/osh/osh.c @@ -60,7 +60,7 @@ "clear - Clear the screen\n" \ "exit - Exit the shell" -#define PROMPT "[root::osmora]~ " +#define PROMPT "[%s::osmora]~ " static char buf[64]; static uint8_t buf_i; @@ -394,7 +394,7 @@ main(int argc, char **argv) puts(WELCOME); while (running) { memset(prog_argv, 0, sizeof(prog_argv)); - fputs(PROMPT, stdout); + printf(PROMPT, getlogin()); input = getstr(); if (input[0] == '\0') { diff --git a/usr.bin/sleep/Makefile b/usr.bin/sleep/Makefile new file mode 100644 index 0000000..5bfd04f --- /dev/null +++ b/usr.bin/sleep/Makefile @@ -0,0 +1,6 @@ +include user.mk + +CFILES = $(shell find . -name "*.c") + +$(ROOT)/base/usr/bin/sleep: + gcc $(CFILES) -o $@ $(INTERNAL_CFLAGS) diff --git a/usr.bin/sleep/sleep.c b/usr.bin/sleep/sleep.c new file mode 100644 index 0000000..f7d07f8 --- /dev/null +++ b/usr.bin/sleep/sleep.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <time.h> +#include <string.h> +#include <stdio.h> + +int +main(int argc, char **argv) +{ + struct timespec ts; + uint16_t nsec = 0; + + if (argc < 2) { + printf("sleep: usage: sleep <seconds>\n"); + return -1; + } + + nsec = atoi(argv[1]); + if (nsec == 0) { + printf("sleep: bad argument\n"); + return -1; + } + + ts.tv_nsec = 0; + ts.tv_sec = nsec; + sleep(&ts, &ts); + return 0; +} |