Compare commits

...

3 Commits

Author SHA1 Message Date
344b4375f9 updated to cbuild 2.3.0 2025-11-09 23:46:47 +05:00
083b247329 enabled more warnings 2025-11-09 18:39:50 +05:00
b662a85348 changed password hashing 2025-11-09 18:39:37 +05:00
10 changed files with 84 additions and 62 deletions

2
dependencies/tlibc vendored

@ -1 +1 @@
Subproject commit 2c8e6fc601a868851d8ce50f77b391e6a9b7e656
Subproject commit bb3b096262106fcc503c03b1555ca196d5b780e9

View File

@ -1,15 +1,24 @@
#!/usr/bin/env bash
CBUILD_VERSION=2.2.3
CBUILD_VERSION=2.3.0
PROJECT="tcp-chat"
CMP_C="gcc"
CMP_CPP="g++"
STD_C="c99"
STD_CPP="c++11"
WARN_C="-Wall -Wextra -Werror=return-type -Werror=pointer-arith -Wno-unused-parameter"
WARN_CPP="-Wall -Wextra -Werror=return-type -Werror=pointer-arith -Wno-unused-parameter"
WARN_C="-Wall -Wextra
-Wduplicated-branches
-Wduplicated-cond
-Wformat=2
-Wmissing-include-dirs
-Wshadow
-Werror=return-type
-Werror=pointer-arith
-Werror=init-self
-Werror=incompatible-pointer-types"
WARN_CPP="$WARN_C"
SRC_C="$(find src -name '*.c')"
#SRC_CPP="$(find src -name '*.cpp')"
SRC_CPP="$(find src -name '*.cpp')"
# Directory with dependency configs.
# See cbuild/example_dependency_configs
@ -24,7 +33,7 @@ ENABLED_DEPENDENCIES='tlibc bearssl'
# └── profile/ - gcc *.gcda profiling info files
OBJDIR="obj"
OUTDIR="bin"
STATIC_LIB_FILE="lib$PROJECT.a"
STATIC_LIB_FILE="$PROJECT.a"
INCLUDE="-Isrc -Idependencies/BearSSL/inc -Idependencies/tlibc/include"
@ -60,61 +69,61 @@ case "$TASK" in
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
POST_TASK_SCRIPT="tasks/strip.sh"
PRE_TASK_SCRIPT=""
TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh"
POST_TASK_SCRIPT="@cbuild/default_tasks/strip_exec.sh"
;;
# creates executable with debug info and no optimizations
build_exec_dbg)
C_ARGS="-O0 -g3"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
POST_TASK_SCRIPT=
PRE_TASK_SCRIPT=""
TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh"
POST_TASK_SCRIPT=""
;;
# creates shared library
build_shared_lib)
C_ARGS="-O2 -fpic -flto -shared"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE"
PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
POST_TASK_SCRIPT=
PRE_TASK_SCRIPT=""
TASK_SCRIPT="@cbuild/default_tasks/build_shared_lib.sh"
POST_TASK_SCRIPT=""
;;
# creates shared library with debug symbols and no optimizations
build_shared_lib_dbg)
C_ARGS="-O0 -g3 -fpic -shared"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE"
PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
POST_TASK_SCRIPT=
PRE_TASK_SCRIPT=""
TASK_SCRIPT="@cbuild/default_tasks/build_shared_lib.sh"
POST_TASK_SCRIPT=""
;;
# creates static library
build_static_lib)
C_ARGS="-O2 -fpic -fdata-sections -ffunction-sections"
CPP_ARGS="$C_ARGS"
PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
POST_TASK_SCRIPT=
PRE_TASK_SCRIPT=""
TASK_SCRIPT="@cbuild/default_tasks/build_static_lib.sh"
POST_TASK_SCRIPT=""
;;
# creates static library with debug symbols and no optimizations
build_static_lib_dbg)
C_ARGS="-O0 -g3"
CPP_ARGS="$C_ARGS"
PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
POST_TASK_SCRIPT=
PRE_TASK_SCRIPT=""
TASK_SCRIPT="@cbuild/default_tasks/build_static_lib.sh"
POST_TASK_SCRIPT=""
;;
# executes $EXEC_FILE
exec)
TASK_SCRIPT=cbuild/default_tasks/exec.sh
TASK_SCRIPT="@cbuild/default_tasks/exec.sh"
;;
# executes $EXEC_FILE with valgrind memory checker
valgrind)
VALGRIND_ARGS="-s --read-var-info=yes --track-origins=yes --fullpath-after=$(pwd)/ --leak-check=full --show-leak-kinds=all"
TASK_SCRIPT=cbuild/default_tasks/valgrind.sh
TASK_SCRIPT="@cbuild/default_tasks/valgrind.sh"
;;
# generates profiling info
profile)
@ -125,12 +134,13 @@ case "$TASK" in
# -pg adds code to executable, that generates file containing function call info (gmon.out)
# -fprofile-generate generates executable with profiling code
# -fprofile-prefix-path sets path where profiling info about objects will be saved
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
C_ARGS="-O2 -flto=auto -fuse-linker-plugin
-fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/profile.sh
POST_TASK_SCRIPT=
PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh"
TASK_SCRIPT="@cbuild/default_tasks/profile.sh"
POST_TASK_SCRIPT=""
;;
# compiles program with -pg and runs it with gprof
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
@ -139,12 +149,14 @@ case "$TASK" in
OUTDIR="$OUTDIR/gprof"
# arguments that emit some call counter code and disable optimizations to see function names
# https://github.com/msys2/MINGW-packages/issues/8503#issuecomment-1365475205
C_ARGS="-O0 -g -pg -no-pie -fno-omit-frame-pointer -fno-inline-functions -fno-inline-functions-called-once -fno-optimize-sibling-calls -fopenmp"
C_ARGS="-O0 -g -pg -no-pie -fno-omit-frame-pointer
-fno-inline-functions -fno-inline-functions-called-once
-fno-optimize-sibling-calls -fopenmp"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/gprof.sh
POST_TASK_SCRIPT=
PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh"
TASK_SCRIPT="@cbuild/default_tasks/gprof.sh"
POST_TASK_SCRIPT=""
;;
# compiles program and runs it with callgrind (part of valgrind)
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
@ -156,9 +168,9 @@ case "$TASK" in
C_ARGS="-O2 -flto=auto -fuse-linker-plugin"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/callgrind.sh
POST_TASK_SCRIPT=
PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh"
TASK_SCRIPT="@cbuild/default_tasks/callgrind.sh"
POST_TASK_SCRIPT=""
;;
# compiles executable with sanitizers and executes it to find errors and warnings
sanitize)
@ -166,19 +178,19 @@ case "$TASK" in
C_ARGS="-O0 -g3 -fsanitize=undefined,address"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/exec.sh
POST_TASK_SCRIPT=
PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh"
TASK_SCRIPT="@cbuild/default_tasks/exec.sh"
POST_TASK_SCRIPT=""
;;
# rebuilds specified dependencies
# EXAMPLE: `cbuild rebuild_dependencies=libexample1,fonts`
# 'all' can be specified to rebuild all dependencies
rebuild_dependencies)
TASK_SCRIPT=cbuild/default_tasks/rebuild_dependencies.sh
TASK_SCRIPT="@cbuild/default_tasks/rebuild_dependencies.sh"
;;
# deletes generated files
clean)
TASK_SCRIPT=cbuild/default_tasks/clean.sh
TASK_SCRIPT="@cbuild/default_tasks/clean.sh"
;;
# nothing to do
"" | no_task)

View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
# Project user config is ignored by git.
# Here you can add variables that users might want to change
# on their local machine, without commiting to the repository.
# Directory where you install dependencies.
# Do not confuse with DEPENDENCY_CONFIGS_DIR
# Example:
# libexample source code is at `../libexample`, and dependency config
# that specifies how to build this lib is at `dependencies/libexample.config`
DEPENDENCIES_DIR=".."

View File

@ -1,5 +1,5 @@
#include "client.h"
#include "tlibc/string/StringBuilder.h"
#include "tlibc/collections/List.h"
void ClientCredentials_destroy(ClientCredentials* cred){
if(!cred)
@ -22,18 +22,19 @@ Result(void) ClientCredentials_tryConstruct(ClientCredentials* cred,
cred->username = str_copy(username);
// concat password and username
StringBuilder sb = StringBuilder_alloc(username.size + password.size + 1);
Defer(StringBuilder_destroy(&sb));
StringBuilder_append_str(&sb, password);
StringBuilder_append_str(&sb, username);
Array(u8) password_and_username = str_castTo_Array(StringBuilder_getStr(&sb));
List(u8) data_to_hash = List_alloc_size(password.size + username.size + PASSWORD_HASH_SIZE);
Defer(free(data_to_hash.data));
List_push_size(&data_to_hash, password.data, password.size);
List_push_size(&data_to_hash, username.data, username.size);
// lvl 1 hash - is used as AES key for user data
cred->user_data_key = Array_alloc(u8, PASSWORD_HASH_SIZE);
hash_password(password_and_username, cred->user_data_key.data, __PASSWORD_HASH_LVL_ITERATIONS);
hash_password(List_castTo_Array(data_to_hash), cred->user_data_key.data, PASSWORD_HASH_LVL_ROUNDS);
// concat lvl 1 hash to data_to_hash
List_push_size(&data_to_hash, cred->user_data_key.data, cred->user_data_key.size);
// lvl 2 hash - is used for authentification
cred->token = Array_alloc(u8, PASSWORD_HASH_SIZE);
hash_password(cred->user_data_key, cred->token.data, __PASSWORD_HASH_LVL_ITERATIONS);
hash_password(List_castTo_Array(data_to_hash), cred->token.data, PASSWORD_HASH_LVL_ROUNDS);
AESBlockEncryptor_construct(&cred->user_data_aes_enc, cred->user_data_key, AESBlockEncryptor_DEFAULT_CLASS);
AESBlockDecryptor_construct(&cred->user_data_aes_dec, cred->user_data_key, AESBlockDecryptor_DEFAULT_CLASS);

View File

@ -41,7 +41,7 @@ Result(void) ServerLink_parse(cstr server_link_cstr, EndpointIPv4* server_end_ou
Return RESULT_VOID;
}
Result(ServerConnection*) ServerConnection_open(ClientCredentials* client_credentials, cstr server_link_cstr){
Result(ServerConnection*) ServerConnection_open(cstr server_link_cstr){
Deferral(16);
ServerConnection* conn = (ServerConnection*)malloc(sizeof(ServerConnection));

View File

@ -25,6 +25,8 @@ Result(void) Client_createFromConfig(cstr config_path){
bool success = false;
Defer(if(!success) Client_free(client));
(void)config_path;
success = true;
Return RESULT_VALUE(p, client);
}
@ -152,7 +154,7 @@ static Result(void) commandExec(Client* client, str command, bool* stop){
printf("connecting to server...\n");
try(client->server_connection, p,
ServerConnection_open(&client->cred, new_server_link.data));
ServerConnection_open(new_server_link.data));
printf("connection established\n");
// TODO: request server info

View File

@ -28,8 +28,7 @@ typedef struct ServerConnection {
EncryptedSocketTCP sock;
} ServerConnection;
Result(ServerConnection*) ServerConnection_open(ClientCredentials* client_credentials,
cstr server_link_cstr);
Result(ServerConnection*) ServerConnection_open(cstr server_link_cstr);
void ServerConnection_close(ServerConnection* conn);

View File

@ -12,11 +12,10 @@
/// @brief hashes password multiple times using its own hash as salt
/// @param password some byte array
/// @param out_buffer u8[PASSWORD_HASH_SIZE]
/// @param iterations number of iterations
void hash_password(Array(u8) password, u8* out_buffer, i32 iterations);
/// @param rounds number of rounds
void hash_password(Array(u8) password, u8* out_buffer, i32 rounds);
#define PASSWORD_HASH_SIZE 32
#define __PASSWORD_HASH_LVL_ITERATIONS 1e5
#define PASSWORD_HASH_LVL_ROUNDS 1e5
//////////////////////////////////////////////////////////////////////////////
// //

View File

@ -4,6 +4,8 @@ Result(char*) __sendErrorMessage(ClientConnection* conn, PacketHeader* req_head,
u32 msg_buf_size, cstr format, va_list argv)
{
Deferral(4);
(void)req_head;
//TODO: limit ErrorMessage size to fit into EncryptedSocketTCP.internal_buffer_size
Array(u8) err_buf = Array_alloc(u8, msg_buf_size);
bool err_complete = false;

View File

@ -1,4 +0,0 @@
#!/usr/bin/env bash
exe_path="$OUTDIR/$EXEC_FILE"
myprint "${BLUE}stripping symbols from ${WHITE}$exe_path"
strip -s "$exe_path"