Implement authorization
Read username from user config, check existence of user and then check password.
This commit was merged in pull request #1.
This commit is contained in:
129
src/userctl.c
129
src/userctl.c
@@ -1,15 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#include <sha256.h>
|
||||
#include <dirent.h>
|
||||
#define NOH_IMPLEMENTATION
|
||||
#include "noh.h"
|
||||
|
||||
#define SV Noh_String_View
|
||||
#define sv noh_sv_from_cstr
|
||||
Noh_Arena temp;
|
||||
|
||||
#include "path.c"
|
||||
#include "users.c"
|
||||
|
||||
Noh_Arena temp;
|
||||
#define SV Noh_String_View
|
||||
#define sv noh_sv_from_cstr
|
||||
|
||||
static void show_usage(char *program_name, char *error) {
|
||||
noh_log(NOH_INFO, "Usage:");
|
||||
@@ -35,42 +35,6 @@ static void show_usage(char *program_name, char *error) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Noh_String hash_password(Noh_String_View username, Noh_String_View password) {
|
||||
// Build the sha input string.
|
||||
Noh_String input = {0};
|
||||
noh_string_append_sv(&input, username);
|
||||
noh_string_append_cstr(&input, "<><>");
|
||||
noh_string_append_sv(&input, password);
|
||||
|
||||
// Calculate the hash.
|
||||
SHA256_CTX ctx = {0};
|
||||
BYTE hash[32];
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, (BYTE*)input.elems, input.count);
|
||||
sha256_final(&ctx, hash);
|
||||
|
||||
// Build the result string.
|
||||
noh_arena_save(&temp);
|
||||
Noh_String result = {0};
|
||||
for (int i = 0; i < 32; i++) {
|
||||
noh_string_append_cstr(&result, noh_arena_sprintf(&temp, "%02x", hash[i]));
|
||||
}
|
||||
noh_arena_reset(&temp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Noh_String_View username;
|
||||
Noh_String_View hash;
|
||||
} User;
|
||||
|
||||
typedef struct {
|
||||
User *elems;
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
} Users;
|
||||
|
||||
bool remove_directory(char *path) {
|
||||
noh_arena_save(&temp);
|
||||
bool result = true;
|
||||
@@ -103,55 +67,6 @@ bool remove_directory(char *path) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool read_users_file(char *file_path, Users *users) {
|
||||
Noh_String users_file = {0};
|
||||
|
||||
noh_log(NOH_INFO, "Reading users file: %s", file_path);
|
||||
if (!noh_file_exists(file_path)) return true;
|
||||
if (!noh_string_read_file(&users_file, file_path)) return false;
|
||||
Noh_String_View users_file_sv = noh_sv_from_string(users_file);
|
||||
|
||||
Noh_String_View line = {0};
|
||||
for (size_t i = 0; users_file_sv.count > 0; i++) {
|
||||
line = noh_sv_chop_line(&users_file_sv);
|
||||
|
||||
// Ignore empty lines.
|
||||
noh_sv_trim_space(&line);
|
||||
if (line.count == 0) continue;
|
||||
|
||||
Noh_String_View un = noh_sv_chop_by_delim(&line, ':');
|
||||
|
||||
if (line.count == 0) {
|
||||
noh_log(NOH_ERROR, "%s %zu: Line not in username:hash format.", file_path, i);
|
||||
noh_string_free(&users_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
noh_da_append(users, ((User){ .username = un, .hash = line }));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool write_users_file(char *file_path, Users *users, User *user_to_skip) {
|
||||
Noh_String users_file = {0};
|
||||
|
||||
for (size_t i = 0; i < users->count; i++) {
|
||||
User *u = &users->elems[i];
|
||||
if (u == user_to_skip) continue;
|
||||
|
||||
noh_string_append_sv(&users_file, u->username);
|
||||
noh_string_append_cstr(&users_file, ":");
|
||||
noh_string_append_sv(&users_file, u->hash);
|
||||
noh_string_append_cstr(&users_file, "\n");
|
||||
}
|
||||
|
||||
bool result = noh_string_write_file(&users_file, file_path);
|
||||
noh_string_free(&users_file);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// Prompts a user with a question and returns their response.
|
||||
bool prompt_user(char *question) {
|
||||
noh_arena_save(&temp);
|
||||
@@ -168,18 +83,22 @@ bool prompt_user(char *question) {
|
||||
}
|
||||
|
||||
bool register_user(Noh_String_View library_path, Noh_String_View username, Noh_String_View password) {
|
||||
bool result = true;
|
||||
|
||||
// Read the file.
|
||||
Noh_String_View file_name = noh_sv_from_cstr("users.conf");
|
||||
Noh_String users_file_path = build_path(false, &library_path, &file_name);
|
||||
noh_string_append_null(&users_file_path);
|
||||
|
||||
// Build users map.
|
||||
Noh_String hashed = {0};
|
||||
Users users = {0};
|
||||
if (!read_users_file(users_file_path.elems, &users)) return false;
|
||||
bool result = true;
|
||||
Noh_String users_file = {0};
|
||||
Noh_String user_folder_path = {0};
|
||||
if (!read_users_file(users_file_path.elems, &users_file, &users)) noh_return_defer(false);
|
||||
|
||||
// Hash the password.
|
||||
Noh_String hashed = hash_password(username, password);
|
||||
hashed = hash_password(username, password);
|
||||
|
||||
// Find the user in the map of users.
|
||||
for (size_t i = 0; i < users.count; i++) {
|
||||
@@ -197,7 +116,7 @@ bool register_user(Noh_String_View library_path, Noh_String_View username, Noh_S
|
||||
if (!write_users_file(users_file_path.elems, &users, NULL)) noh_return_defer(false);
|
||||
|
||||
// Create user folder if needed.
|
||||
Noh_String user_folder_path = build_path(false, &library_path, &username);
|
||||
user_folder_path = build_path(false, &library_path, &username);
|
||||
noh_string_append_null(&user_folder_path);
|
||||
if (!noh_mkdir_if_needed(user_folder_path.elems)) noh_return_defer(false);
|
||||
|
||||
@@ -210,25 +129,32 @@ bool register_user(Noh_String_View library_path, Noh_String_View username, Noh_S
|
||||
if (!write_users_file(users_file_path.elems, &users, NULL)) noh_return_defer(false);
|
||||
|
||||
// Create user folder if needed.
|
||||
Noh_String user_folder_path = build_path(false, &library_path, &username);
|
||||
user_folder_path = build_path(false, &library_path, &username);
|
||||
noh_string_append_null(&user_folder_path);
|
||||
if (!noh_mkdir_if_needed(user_folder_path.elems)) noh_return_defer(false);
|
||||
|
||||
defer:
|
||||
noh_string_free(&users_file_path);
|
||||
noh_string_free(&user_folder_path);
|
||||
noh_da_free(&users);
|
||||
noh_string_free(&users_file);
|
||||
noh_string_free(&hashed);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool delete_user(Noh_String_View library_path, Noh_String_View username) {
|
||||
bool result = true;
|
||||
|
||||
// Read the file.
|
||||
Noh_String_View file_name = noh_sv_from_cstr("users.conf");
|
||||
Noh_String users_file_path = build_path(false, &library_path, &file_name);
|
||||
noh_string_append_null(&users_file_path);
|
||||
|
||||
// Build users map.
|
||||
Noh_String user_folder_path = {0};
|
||||
Users users = {0};
|
||||
if (!read_users_file(users_file_path.elems, &users)) return false;
|
||||
bool result = true;
|
||||
Noh_String users_file = {0};
|
||||
if (!read_users_file(users_file_path.elems, &users_file, &users)) noh_return_defer(false);
|
||||
|
||||
// Check if the user exists.
|
||||
User *user_to_delete = NULL;
|
||||
@@ -256,7 +182,7 @@ bool delete_user(Noh_String_View library_path, Noh_String_View username) {
|
||||
if (!write_users_file(users_file_path.elems, &users, user_to_delete)) noh_return_defer(false);
|
||||
|
||||
// Prompt to delete the user's library folder.
|
||||
Noh_String user_folder_path = build_path(false, &library_path, &username);
|
||||
user_folder_path = build_path(false, &library_path, &username);
|
||||
noh_string_append_null(&user_folder_path);
|
||||
if (!noh_file_exists(user_folder_path.elems)) noh_return_defer(true);
|
||||
|
||||
@@ -266,7 +192,10 @@ bool delete_user(Noh_String_View library_path, Noh_String_View username) {
|
||||
}
|
||||
|
||||
defer:
|
||||
noh_string_free(&user_folder_path);
|
||||
noh_string_free(&users_file_path);
|
||||
noh_da_free(&users);
|
||||
noh_string_free(&users_file);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -278,11 +207,13 @@ bool list_users(Noh_String_View library_path) {
|
||||
|
||||
// Build users map.
|
||||
Users users = {0};
|
||||
if (!read_users_file(users_file_path.elems, &users)) return false;
|
||||
Noh_String users_file = {0};
|
||||
if (!read_users_file(users_file_path.elems, &users_file, &users)) return false;
|
||||
|
||||
if (users.count == 0) {
|
||||
noh_log(NOH_INFO, "No users registered.");
|
||||
noh_da_free(&users);
|
||||
noh_string_free(&users_file);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -294,7 +225,9 @@ bool list_users(Noh_String_View library_path) {
|
||||
}
|
||||
noh_arena_reset(&temp);
|
||||
|
||||
noh_string_free(&users_file_path);
|
||||
noh_da_free(&users);
|
||||
noh_string_free(&users_file);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user