From cd4c76bf082bc369bc2acb437594602feac4fe9a Mon Sep 17 00:00:00 2001 From: pradosh-arduino Date: Tue, 14 Jan 2025 14:48:27 +0530 Subject: [PATCH] Added a shell and login menu (username: root, password: prad) --- source/includes/algorithms/hashing.h | 2 +- source/includes/basics.h | 2 + source/includes/keyboard.h | 9 ++- source/includes/sh_util.h | 15 ++++ source/kernel/C/algorithms/hashing.c | 2 +- source/kernel/C/cc-asm.c | 6 +- source/kernel/C/kernel.c | 25 +++++-- source/kernel/C/logger.c | 9 ++- source/kernel/C/shell/commands/login.c | 52 ++++++++++++++ source/kernel/C/shell/sh.c | 96 ++++++++++++++++++++++++++ source/kernel/C/strings.c | 68 ++++++++++++++++++ source/kernel/C/user-input/keyboard.c | 44 +++++++++--- 12 files changed, 307 insertions(+), 23 deletions(-) create mode 100644 source/includes/sh_util.h create mode 100644 source/kernel/C/shell/commands/login.c create mode 100644 source/kernel/C/shell/sh.c diff --git a/source/includes/algorithms/hashing.h b/source/includes/algorithms/hashing.h index 3b4b48c..99afe73 100755 --- a/source/includes/algorithms/hashing.h +++ b/source/includes/algorithms/hashing.h @@ -22,4 +22,4 @@ void init_hashing(); * @param data The string to be hashed. * @return [int] Hashed value. */ -int hash_string(string data); \ No newline at end of file +int64 hash_string(string data); \ No newline at end of file diff --git a/source/includes/basics.h b/source/includes/basics.h index da06ffa..f8a2273 100755 --- a/source/includes/basics.h +++ b/source/includes/basics.h @@ -33,6 +33,8 @@ typedef char* string; #define Ghz *1000000000ULL #define Mhz *1000000ULL +#define EOF (-1) + #ifdef __GNUC__ #define deprecated_message(msg) attribute((deprecated(msg))) #elif defined(_MSC_VER) diff --git a/source/includes/keyboard.h b/source/includes/keyboard.h index bbbc556..bf1ca3a 100755 --- a/source/includes/keyboard.h +++ b/source/includes/keyboard.h @@ -17,4 +17,11 @@ char scancode_to_char(int scancode, bool uppercase); * @brief This is a function that is ran even when the sleep() function is called * */ -void process_keyboard(InterruptFrame* frame); \ No newline at end of file +void process_keyboard(InterruptFrame* frame); + +/** + * @brief Gets the last pressed char. + * + * @return int + */ +int getc(); \ No newline at end of file diff --git a/source/includes/sh_util.h b/source/includes/sh_util.h new file mode 100644 index 0000000..4a5c57d --- /dev/null +++ b/source/includes/sh_util.h @@ -0,0 +1,15 @@ +/** + * @file sh_util.h + * @author Pradosh (pradoshgame@gmail.com) + * @brief Utils for fw shell. + * @version 0.1 + * @date 2025-01-14 + * + * @copyright Copyright (c) 2025 + * + */ +#include +#include +#include + +#define BUFFER_SIZE 1024 diff --git a/source/kernel/C/algorithms/hashing.c b/source/kernel/C/algorithms/hashing.c index b244c8e..c3a7b46 100755 --- a/source/kernel/C/algorithms/hashing.c +++ b/source/kernel/C/algorithms/hashing.c @@ -22,7 +22,7 @@ void init_hashing(){ } } -int hash_string(string data){ +int64 hash_string(string data){ int hash = 0; while(*data){ hash += *data++; diff --git a/source/kernel/C/cc-asm.c b/source/kernel/C/cc-asm.c index cc9f9cd..9f53dba 100755 --- a/source/kernel/C/cc-asm.c +++ b/source/kernel/C/cc-asm.c @@ -17,13 +17,13 @@ void hcf() { for (;;) { #if defined (__x86_64__) - info("x86_64: Halt Initalized.", __FILE__); + // info("x86_64: Halt Initalized.", __FILE__); asm volatile ("hlt"); #elif defined (__aarch64__) || defined (__riscv) - info("aarch64 - riscv: Halt (Wait for interrupts) Initalized.", __FILE__); + // info("aarch64 - riscv: Halt (Wait for interrupts) Initalized.", __FILE__); asm volatile ("wfi"); #elif defined (__arm__) || defined (__aarch32__) - info("ARM32: Halt (Wait for interrupts) Initialized.",__FILE__); + // info("ARM32: Halt (Wait for interrupts) Initialized.",__FILE__); asm volatile ("wfi"); #endif } diff --git a/source/kernel/C/kernel.c b/source/kernel/C/kernel.c index 36a2844..4f775be 100755 --- a/source/kernel/C/kernel.c +++ b/source/kernel/C/kernel.c @@ -380,14 +380,13 @@ void main(void) { // free(data); - print("press F10 for (ACPI) Shutdown.\n"); - print("press F9 for (ACPI/Hard) Reboot/Reset.\n"); - - done("No process pending.", __FILE__); - // print("\x1b[2J"); // Clears screen // print("\x1b[H"); // Resets Cursor to 0, 0 + int failed_attempts = 0; + + printf("%x",hash_string("superuser")); + printf("%x",hash_string("frostwing")); // glCreateContext(); // glCreateContextCustom(front_buffer, framebuffer->width, framebuffer->height); @@ -406,6 +405,22 @@ void main(void) { // decode_targa_image(module_request.response->modules[3]->address, (uvec2){mousePos.x, mousePos.y}, framebuffer->width, framebuffer->height); // pit_sleep((int32)16.6666); // 60 Hz approx. + + if (failed_attempts >= 5){ + error("You tried 5 diffrent wrong attempts. You've been locked out.", __FILE__); + hcf(); + } + + char* username = login_request(); + + if(username != ""){ + int argc = 1; + char* dummy_argv[] = {username, null}; + shell_main(argc, dummy_argv); + } else { + error("Invalid credentials.", __FILE__); + failed_attempts++; + } } } diff --git a/source/kernel/C/logger.c b/source/kernel/C/logger.c index 485804e..cb47afe 100755 --- a/source/kernel/C/logger.c +++ b/source/kernel/C/logger.c @@ -113,9 +113,12 @@ void done(cstring message, cstring file) { * @deprecated Replaced with Flanterm's putchar function */ void __putc(char c) { - char _c[1]; - _c[0] = c; - print(_c); + char str[1]; + + str[0] = c; + str[1] = '\0'; + + print(str); } /** diff --git a/source/kernel/C/shell/commands/login.c b/source/kernel/C/shell/commands/login.c new file mode 100644 index 0000000..63c41a4 --- /dev/null +++ b/source/kernel/C/shell/commands/login.c @@ -0,0 +1,52 @@ +/** + * @file login.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2025-01-14 + * + * @copyright Copyright (c) 2025 + * + */ + +#include + +char* login_request(){ + char username[21]; // +1 for null terminator + char password[21]; + + char temp; + int i; + + for(int i = 0; i < 30; i++) + __putc('='); + __putc('\n'); + + warn("DON'T USE BACKSPACE!!", __FILE__); + + print("Username: "); + i = 0; + while ((temp = getc()) != 0x1c && i < 20) { + username[i++] = temp; + __putc(temp); + } + username[i] = '\0'; + + print("\nPassword: "); + i = 0; + while ((temp = getc()) != 0x1c && i < 20) { + password[i++] = temp; + __putc('*'); + } + password[i] = '\0'; + + __putc('\n'); + + if (strcmp(username, "root") == 0 && strcmp(password, "prad") == 0) { + memset(username, 0, 21); + memset(password, 0, 21); + return username; // I know this won't give the username.. need to fix! + } else { + return ""; + } +} \ No newline at end of file diff --git a/source/kernel/C/shell/sh.c b/source/kernel/C/shell/sh.c new file mode 100644 index 0000000..0f0f5e4 --- /dev/null +++ b/source/kernel/C/shell/sh.c @@ -0,0 +1,96 @@ +/** + * @file sh.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2025-01-14 + * + * @copyright Copyright (c) 2025 + * + */ + +#include + +bool running = true; + +void welcome_message(){ + print("\e[0;34m ______ _ _ _____ _ _ _ \n"); + printf("| ____| | | | |/ ____| | | | |"); + printf("| |__ _ __ ___ ___| |_ ___ __| | (___ | |__ ___| | |"); + printf("| __| '__/ _ \\/ __| __/ _ \\/ _` |\\___ \\| '_ \\ / _ \\ | |"); + printf("| | | | | (_) \\__ \\ || __/ (_| |____) | | | | __/ | |"); + print("|_| |_| \\___/|___/\\__\\___|\\__,_|_____/|_| |_|\\___|_|_|\e[0m\n\n"); + + print("\033[1;32mWelcome to frosted shell!\033[0m This is an implementation of \033[1;34msh\033[0m.\n"); + print("We as the developers try to make this shell as similar as \033[1;34msh\033[0m.\n"); + + display_time(); +} + +int shell_main(int argc, char** argv){ + char* buffer = (char*)malloc(BUFFER_SIZE * sizeof(char)); + int16 bufptr = 0; + + print("\x1b[2J\x1b[H"); + welcome_message(); + + __putc('\n'); + print(argv[0]); + __putc(' '); + __putc('%'); + __putc(' '); + int c; + + while (running) { + c = getc(); + + if (c == 0x1c) { // Enter key + buffer[bufptr] = '\0'; // Null-terminate the string + __putc('\n'); + execute(buffer); + bufptr = 0; // Reset buffer pointer + for (int i = 0; i < BUFFER_SIZE; i++) { + buffer[i] = 0; + } + + if(running){ + print(argv[0]); + __putc(' '); + __putc('%'); + __putc(' '); + } + } else if (c == 0xe) { // Backspace key + if (bufptr > 0) { + bufptr--; + buffer[bufptr] = '\0'; // Adjust null-terminator + __putc('\b'); // Move cursor back + __putc(' '); // Overwrite previous character + __putc('\b'); // Move cursor back again + } + } else { + if (bufptr < BUFFER_SIZE - 1) { + buffer[bufptr++] = (char)c; + } + } + + __putc(c); + } + + free(buffer); + return 0; +} + +void execute(const char* buffer){ + if(strcmp(buffer, "exit") == 0){ + print("\x1b[2J\x1b[H"); + running = false; + } else if(strcmp(buffer, "shutdown") == 0){ + info("Goodbye from Frosted Shell...", __FILE__); + shutdown(); + } else if(strcmp(buffer, "reboot") == 0){ + info("Goodbye from Frosted Shell...", __FILE__); + acpi_reboot(); + } else { + printf("fsh: :%s: not found (length : %d)", buffer, strlen_(buffer)); + } +} \ No newline at end of file diff --git a/source/kernel/C/strings.c b/source/kernel/C/strings.c index 7219c36..8c54aa1 100755 --- a/source/kernel/C/strings.c +++ b/source/kernel/C/strings.c @@ -299,4 +299,72 @@ bool starts_with(const char *str, const char *prefix) { prefix++; } return yes; +} + +/** + * strdup - Duplicate a string. + * + * This function creates a new string in dynamically allocated memory + * that is a duplicate of the given string. + * + * @param str The string to be duplicated. + * + * @return A pointer to the newly allocated duplicate string, + * or NULL if memory allocation fails. + */ + char* strdup(const char* str) { + if (str == NULL) { + return NULL; + } + + size_t len = strlen_(str) + 1; // Include space for null terminator + char* dup = (char*)malloc(len); + if (dup == NULL) { + return NULL; + } + + memcpy(dup, str, len); + return dup; +} + +/** + * @brief Removes the leading and trailing spaces. + * + * @param str + * @return char* + */ +char* leading_trailing_trim(const char *str) { + if (str == NULL) { + return NULL; + } + + int start = 0; + int end = strlen_(str) - 1; + + // Find the index of the first non-space character + while (start <= end && (str[start] == ' ' || str[start] == '\t')) { + start++; + } + + // Find the index of the last non-space character + while (start <= end && (str[end] == ' ' || str[end] == '\t')) { + end--; + } + + if (start > end) { + // Empty string after trimming + return strdup(""); + } + + // Allocate memory for the trimmed string + char* trimmed = (char*)malloc(end - start + 2); + if (trimmed == NULL) { + return NULL; + } + + // Copy the trimmed portion of the string + strncpy(trimmed, str + start, end - start + 1); + trimmed[end - start + 1] = '\0'; + + return trimmed; } \ No newline at end of file diff --git a/source/kernel/C/user-input/keyboard.c b/source/kernel/C/user-input/keyboard.c index f067cb3..22e7c77 100755 --- a/source/kernel/C/user-input/keyboard.c +++ b/source/kernel/C/user-input/keyboard.c @@ -75,10 +75,6 @@ void process_keyboard(InterruptFrame* frame){ goto exit_interrupt; } - if(data == 0x1C){ // Enter - print("\n"); - goto exit_interrupt; - } if(data == 0x43){ // F9 Key enable_keyboard = no; acpi_reboot(); @@ -89,10 +85,6 @@ void process_keyboard(InterruptFrame* frame){ hcf(); goto exit_interrupt; // this is not possible but for uniformity it is here. } - if(data == 0x0E){ // Backspace Key - print("\b \b"); - goto exit_interrupt; - } if(data == 0x2A || data == 0x36){ // [Left Shift || Right Shift] pressed shift = yes; @@ -104,9 +96,43 @@ void process_keyboard(InterruptFrame* frame){ c = scancode_to_char(data, shift); - if(c != '\0') print(&c); + // if(c != '\0') print(&c); exit_interrupt: c = '\0'; outb(0x20, 0x20); // End PIC Master +} + +int getc() { + int data; + + // Wait for key press + while (1) { + // Check for key press + if (inb(0x64) & 1) { + data = inb(0x60); + + if(data > 0x80) continue; + + if(data == 0x2A || data == 0x36){ // [Left Shift || Right Shift] pressed + shift = yes; + } + + if(data == 0xB6 || data == 0xAA){ + shift = no; + } + + // Send EOI to PIC + outb(0x20, 0x20); + break; + } + } + + char c = scancode_to_char(data, shift); + if(data == 0x1c) + return data; + if(data == 0xe) + return data; + + return c; } \ No newline at end of file