diff --git a/src/chat.h b/src/chat.h deleted file mode 100644 index 4dedced..0000000 --- a/src/chat.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include "tlibc/errors.h" - -Result(void) client_run(); -Result(void) server_run(cstr server_endpoint_str); diff --git a/src/client.c b/src/client.c deleted file mode 100644 index c144c94..0000000 --- a/src/client.c +++ /dev/null @@ -1,209 +0,0 @@ -#include "chat.h" -#include -#include -#include "term.h" -#include "network/socket.h" -#include "cryptography/cryptography.h" -#include "tlibc/string/StringBuilder.h" - -static const str greeting_art = STR( - " ^,,^ ╱|\n" - " ( •·•) Meum! (o.o`7\n" - " / ` | Meum... |`˜ \\\n" - "\\(_,J J L l`,)/\n" -); - -static const str farewell_art = STR( - " ^,,^ ╱|\n" - " ( -.-) (>,<`7\n" - " / ` | Goodbye! |`˜ \\\n" - "\\(_,J J L l`,)/\n" -); - -static Result(void) commandExec(str command, bool* stop); - -typedef struct ClientCredential { - str username; - u8 passhash_lvl2[password_hash_size]; - EncryptorAES aes_enc; - DecryptorAES aes_dec; - EncryptorRSA rsa_enc; - DecryptorRSA rsa_dec; -} ClientCredential; - -typedef struct ServerConnection { - EndpointIPv4 server_end; - Socket system_socket; - Socket content_socket; - EncryptorRSA rsa_enc; - EncryptorAES session_aes_enc; - DecryptorAES session_aes_dec; -} ServerConnection; - -Result(ServerConnection*) connectToServer(EndpointIPv4 server_end, str server_key); - -Result(void) client_run() { - Deferral(32); - if(!term_init()){ - Return RESULT_ERROR("can't init terminal", false); - } - using_history(); - - fputs(greeting_art.data, stdout); - - char* command_input_prev = NULL; - char* command_input_raw = NULL; - Defer(rl_free(command_input_prev)); - str command_input = str_null; - bool stop = false; - while((command_input_raw = readline("> ")) && !stop){ - rl_free(command_input_prev); - command_input_prev = command_input_raw; - command_input = str_from_cstr(command_input_raw); - str_trim(&command_input, true); - if(command_input.size == 0) - continue; - - add_history(command_input.data); - Result(void) com_result = commandExec(command_input, &stop); - if(com_result.error){ - str e_str = Error_toStr(com_result.error); - printfe("%s\n", e_str.data); - free(e_str.data); - Error_free(com_result.error); - } - } - - Return RESULT_VOID; -} - -#define is_alias(LITERAL) str_equals(command, STR(LITERAL)) - -static ClientCredential* client_credential = NULL; - -static Result(void) commandExec(str command, bool* stop){ - Deferral(64); - char answer_buf[512]; - const u32 answer_buf_size = sizeof(answer_buf); - if(is_alias("q") || is_alias("quit") || is_alias("exit")){ - fputs(farewell_art.data, stdout); - *stop = true; - } - else if(is_alias("clear")){ - term_clear(); - } - else if(is_alias("h") || is_alias("help")){ - puts( - "COMMANDS:\n" - "q, quit, exit Close the program.\n" - "clear Clear the screen.\n" - "j, join Join a server.\n" - "c, connect Connect to a server you joined.\n" - ); - } - else if (is_alias("j") || is_alias("join")){ - puts("Enter server address (ip:port): "); - fgets(answer_buf, answer_buf_size, stdin); - EndpointIPv4 new_server_end; - try_void(EndpointIPv4_parse(answer_buf, &new_server_end)); - puts("Enter server key (): "); - fgets(answer_buf, answer_buf_size, stdin); - str new_server_key = str_from_cstr(answer_buf); - try(ServerConnection* conn, p, connectToServer(new_server_end, new_server_key)); - } - else if(is_alias("c") || is_alias("connect")){ - // TODO: read saved servers from database - } - else { - Return RESULT_ERROR_FMT("unknown kommand: '%s'\n" - "Use 'h' to see list of avaliable commands\n", - command.data); - } - - Return RESULT_VOID; -} - -void ClientCredential_free(ClientCredential* cred){ - if(cred == NULL) - return; - free(cred->username.data); - free(cred); -} - -#define __passhash_lvl_iter 1e5 - -Result(ClientCredential*) ClientCredential_create(str username, str password){ - Deferral(32); - ClientCredential* cred = (ClientCredential*)malloc(sizeof(ClientCredential)); - memset(cred, 0, sizeof(ClientCredential)); - bool success = false; - Defer( - if(!success) - ClientCredential_free(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); - - // lvl 1 hash - is being used to generate rsa keys - u8 passhash_lvl1[password_hash_size]; - hash_password(StringBuilder_getStr(&sb), passhash_lvl1, __passhash_lvl_iter); - // lvl 2 hash - is being used to authorize client on server - str _passhash_lvl1_str = str_construct((void*)passhash_lvl1, password_hash_size, false); - hash_password(_passhash_lvl1_str, cred->passhash_lvl2, __passhash_lvl_iter); - - - success = true; - return RESULT_VALUE(p, cred); -} - -void ServerConnection_close(ServerConnection* conn){ - if(conn == NULL) - return; - socket_close(conn->system_socket); - socket_close(conn->content_socket); - free(conn); -} - -Result(ServerConnection*) connectToServer(EndpointIPv4 server_end, str server_key){ - Deferral(64); - if(client_credential == NULL){ - - } - - str end_str = EndpointIPv4_toStr(server_end); - Defer(free(end_str.data)); - if(EndpointIPv4_is_invalid(server_end)){ - Return RESULT_ERROR_FMT("endpoint is invalid: %s", end_str.data); - } - - ServerConnection* conn = (ServerConnection*)malloc(sizeof(ServerConnection)); - memset(conn, 0, sizeof(ServerConnection)); - bool success = false; - Defer( - if(!success) - ServerConnection_close(conn); - ); - - printf("connecting to server %s\n", end_str.data); - try(conn->system_socket, i, socket_open_TCP()); - try_void(socket_connect(conn->system_socket, server_end)); - - // ask user name and password - // calculate key pair from password hash - // send client public key to server - // request server info - // show server info - // save server info to user's db - // hash password more times - // request log in - // if not registered, request registration and then log in - - success = true; - Return RESULT_VALUE(p, conn); -} diff --git a/src/client/ClientCredential.c b/src/client/ClientCredential.c new file mode 100644 index 0000000..8cb7330 --- /dev/null +++ b/src/client/ClientCredential.c @@ -0,0 +1,74 @@ +#include "client.h" +#include "tlibc/string/StringBuilder.h" + +void ClientCredential_free(ClientCredential* cred){ + if(cred == NULL) + return; + free(cred->username.data); + free(cred->aes_key.data); + free(cred->token.data); + RSA_destroyPrivateKey(&cred->sk); + RSA_destroyPublicKey(&cred->pk); + free(cred); +} + +#define __passhash_lvl_iter 1e5 + +Result(ClientCredential*) ClientCredential_create(str username, str password){ + Deferral(32); + ClientCredential* cred = (ClientCredential*)malloc(sizeof(ClientCredential)); + memset(cred, 0, sizeof(ClientCredential)); + bool success = false; + Defer( + if(!success) + free(cred); + ); + + cred->username = str_copy(username); + Defer( + if(!success) + free(cred->username.data); + ); + + // 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)); + // lvl 1 hash - is used to generate RSA keys + Array(u8) passhash_lvl1 = Array_alloc(u8, password_hash_size); + cred->aes_key = Array_alloc(u8, password_hash_size); + cred->token = Array_alloc(u8, password_hash_size); + Defer( + free(passhash_lvl1.data); + if(!success){ + free(cred->aes_key.data); + free(cred->token.data); + } + ); + hash_password(password_and_username, passhash_lvl1.data, __passhash_lvl_iter); + // lvl 2 hash - is used as AES key + hash_password(passhash_lvl1, cred->aes_key.data, __passhash_lvl_iter); + // lvl 3 hash - is used to authorize client on server + hash_password(cred->aes_key, cred->token.data, __passhash_lvl_iter); + + // generate client rsa keys from password hash + br_hmac_drbg_context passhash_based_rng = { .vtable = &br_hmac_drbg_vtable }; + br_hmac_drbg_init(&passhash_based_rng, &br_sha256_vtable, passhash_lvl1.data, password_hash_size); + try_void(RSA_generateKeyPair(4096, &cred->sk, &cred->pk, &passhash_based_rng.vtable)); + Defer( + if(!success){ + RSA_destroyPrivateKey(&cred->sk); + RSA_destroyPublicKey(&cred->pk); + } + ); + + DecryptorRSA_construct(&cred->rsa_dec, &cred->sk); + EncryptorRSA_construct(&cred->rsa_enc, &cred->pk); + DecryptorAES_construct(&cred->aes_dec, cred->aes_key); + EncryptorAES_construct(&cred->aes_enc, cred->aes_key); + + success = true; + Return RESULT_VALUE(p, cred); +} diff --git a/src/client/ServerConnection.c b/src/client/ServerConnection.c new file mode 100644 index 0000000..c592671 --- /dev/null +++ b/src/client/ServerConnection.c @@ -0,0 +1,44 @@ +#include "client.h" + +void ServerConnection_close(ServerConnection* conn){ + if(conn == NULL) + return; + socket_close(conn->system_socket); + socket_close(conn->content_socket); + free(conn); +} + +Result(ServerConnection*) ServerConnection_open(ClientCredential* client_credential, EndpointIPv4 server_end, str server_key){ + Deferral(64); + + str end_str = EndpointIPv4_toStr(server_end); + Defer(free(end_str.data)); + if(EndpointIPv4_is_invalid(server_end)){ + Return RESULT_ERROR_FMT("endpoint is invalid: %s", end_str.data); + } + + ServerConnection* conn = (ServerConnection*)malloc(sizeof(ServerConnection)); + memset(conn, 0, sizeof(ServerConnection)); + bool success = false; + Defer( + if(!success) + ServerConnection_close(conn); + ); + + printf("connecting to server %s\n", end_str.data); + try(conn->system_socket, i, socket_open_TCP()); + try_void(socket_connect(conn->system_socket, server_end)); + + // ask user name and password + // calculate key pair from password hash + // send client public key to server + // request server info + // show server info + // save server info to user's db + // hash password more times + // request log in + // if not registered, request registration and then log in + + success = true; + Return RESULT_VALUE(p, conn); +} diff --git a/src/client/client.c b/src/client/client.c new file mode 100644 index 0000000..1c8edf3 --- /dev/null +++ b/src/client/client.c @@ -0,0 +1,118 @@ +// readline.h doesn't include stdio.h +// This bug is older than me))) +#include "client.h" +#include +#include +#include +#include "term.h" + +static const str greeting_art = STR( + " ^,,^ ╱|\n" + " ( •·•) Meum! (o.o`7\n" + " / ` | Meum... |`˜ \\\n" + "\\(_,J J L l`,)/\n" +); + +static const str farewell_art = STR( + " ^,,^ ╱|\n" + " ( -.-) (>,<`7\n" + " / ` | Goodbye! |`˜ \\\n" + "\\(_,J J L l`,)/\n" +); + +static ClientCredential* client_credential = NULL; + +static Result(void) commandExec(str command, bool* stop); + +static Result(void) askUserNameAndPassword(ClientCredential** cred){ + Deferral(8); + char username[1024]; + char password[1024]; + scanf("username: %s", username); + scanf("password: %s", password); + try(*cred, p, ClientCredential_create(str_from_cstr(username), str_from_cstr(password))); + Return RESULT_VOID; +} + +Result(void) client_run() { + Deferral(32); + if(!term_init()){ + Return RESULT_ERROR("can't init terminal", false); + } + using_history(); + + fputs(greeting_art.data, stdout); + try_void(askUserNameAndPassword(&client_credential)); + + char* command_input_prev = NULL; + char* command_input_raw = NULL; + Defer(rl_free(command_input_prev)); + str command_input = str_null; + bool stop = false; + while((command_input_raw = readline("> ")) && !stop){ + rl_free(command_input_prev); + command_input_prev = command_input_raw; + command_input = str_from_cstr(command_input_raw); + str_trim(&command_input, true); + if(command_input.size == 0) + continue; + + add_history(command_input.data); + Result(void) com_result = commandExec(command_input, &stop); + if(com_result.error){ + str e_str = Error_toStr(com_result.error); + printfe("%s\n", e_str.data); + free(e_str.data); + Error_free(com_result.error); + } + } + + ClientCredential_free(client_credential); + Return RESULT_VOID; +} + +#define is_alias(LITERAL) str_equals(command, STR(LITERAL)) + +static Result(void) commandExec(str command, bool* stop){ + Deferral(64); + char answer_buf[512]; + const u32 answer_buf_size = sizeof(answer_buf); + if(is_alias("q") || is_alias("quit") || is_alias("exit")){ + fputs(farewell_art.data, stdout); + *stop = true; + } + else if(is_alias("clear")){ + term_clear(); + } + else if(is_alias("h") || is_alias("help")){ + puts( + "COMMANDS:\n" + "q, quit, exit Close the program.\n" + "clear Clear the screen.\n" + "j, join Join a server.\n" + "c, connect Connect to a server you joined.\n" + ); + } + else if (is_alias("j") || is_alias("join")){ + puts("Enter server address (ip:port): "); + fgets(answer_buf, answer_buf_size, stdin); + EndpointIPv4 new_server_end; + try_void(EndpointIPv4_parse(answer_buf, &new_server_end)); + puts("Enter server key (): "); + fgets(answer_buf, answer_buf_size, stdin); + str new_server_key = str_from_cstr(answer_buf); + try(ServerConnection* conn, p, ServerConnection_open(client_credential, new_server_end, new_server_key)); + // TODO: close server connection somewhere + } + else if(is_alias("c") || is_alias("connect")){ + // TODO: read saved servers from database + } + else { + Return RESULT_ERROR_FMT("unknown kommand: '%s'\n" + "Use 'h' to see list of avaliable commands\n", + command.data); + } + + Return RESULT_VOID; +} + diff --git a/src/client/client.h b/src/client/client.h new file mode 100644 index 0000000..bd93a06 --- /dev/null +++ b/src/client/client.h @@ -0,0 +1,32 @@ +#pragma once +#include "network/socket.h" +#include "cryptography/cryptography.h" + +Result(void) client_run(); + +typedef struct ClientCredential { + str username; + Array(u8) aes_key; + Array(u8) token; + br_rsa_private_key sk; + br_rsa_public_key pk; + EncryptorRSA rsa_enc; + DecryptorRSA rsa_dec; + EncryptorAES aes_enc; + DecryptorAES aes_dec; +} ClientCredential; + +Result(ClientCredential*) ClientCredential_create(str username, str password); +void ClientCredential_free(ClientCredential* cred); + +typedef struct ServerConnection { + EndpointIPv4 server_end; + Socket system_socket; + Socket content_socket; + EncryptorRSA rsa_enc; + EncryptorAES session_aes_enc; + DecryptorAES session_aes_dec; +} ServerConnection; + +Result(ServerConnection*) ServerConnection_open(ClientCredential* client_credential, EndpointIPv4 server_end, str server_key); +void ServerConnection_close(ServerConnection* conn); \ No newline at end of file diff --git a/src/cryptography/AES.c b/src/cryptography/AES.c index c6b7195..9e17890 100755 --- a/src/cryptography/AES.c +++ b/src/cryptography/AES.c @@ -3,11 +3,12 @@ //TODO: use AES CTR encryption instead of my own padding algorithm -void EncryptorAES_init(EncryptorAES* ptr, Array(u8) key){ +void EncryptorAES_construct(EncryptorAES* ptr, Array(u8) key){ assert(key.size == 16 || key.size == 24 || key.size == 32); br_aes_ct64_cbcenc_init(&ptr->enc_ctx, key.data, key.size); - rng_init_sha256_seedFromTime(&br_hmac_drbg_vtable, &ptr->rng_ctx.vtable); + ptr->rng_ctx.vtable = &br_hmac_drbg_vtable; + rng_init_sha256_seedFromTime(&ptr->rng_ctx.vtable); memset(ptr->buf, 0, __AES_BUFFER_SIZE); memset(ptr->iv, 0, sizeof(ptr->iv)); @@ -49,7 +50,7 @@ void EncryptorAES_encrypt(EncryptorAES* ptr, Array(u8) src, Array(u8) dst){ } -void DecryptorAES_init(DecryptorAES* ptr, Array(u8) key){ +void DecryptorAES_construct(DecryptorAES* ptr, Array(u8) key){ assert(key.size == 16 || key.size == 24 || key.size == 32); br_aes_ct64_cbcdec_init(&ptr->dec_ctx, key.data, key.size); diff --git a/src/cryptography/RSA.c b/src/cryptography/RSA.c index dc92e9a..9ec72d7 100644 --- a/src/cryptography/RSA.c +++ b/src/cryptography/RSA.c @@ -6,14 +6,32 @@ // https://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537 #define DEFAULT_PUBLIC_EXPONENT 65537 -bool RSA_generateKeyPair(u32 key_size, br_rsa_private_key* sk, br_rsa_public_key* pk){ - br_hmac_drbg_context rng_ctx; - const br_prng_class** rng_class_ptr = &rng_ctx.vtable; - rng_init_sha256_seedFromTime(&br_hmac_drbg_vtable, rng_class_ptr); +Result(void) RSA_generateKeyPair(u32 key_size, + br_rsa_private_key* sk, br_rsa_public_key* pk, + const br_prng_class** rng_vtable_ptr) +{ + Deferral(16); + bool success = false; + rng_init_sha256_seedFromTime(rng_vtable_ptr); + void* sk_buf = malloc(BR_RSA_KBUF_PRIV_SIZE(key_size)); + Defer( + if(!success) + free(sk_buf) + ); + void* pk_buf = malloc(BR_RSA_KBUF_PUB_SIZE(key_size)); - u32 r = br_rsa_i31_keygen(rng_class_ptr, sk, sk_buf, pk, pk_buf, key_size, DEFAULT_PUBLIC_EXPONENT); - return r; + Defer( + if(!success) + free(pk_buf) + ); + + success = br_rsa_i31_keygen(rng_vtable_ptr, sk, sk_buf, pk, pk_buf, key_size, DEFAULT_PUBLIC_EXPONENT); + if(!success){ + Return RESULT_ERROR("br_rsa_i31_keygen() failed", false); + } + + Return RESULT_VOID; } Result(void) RSA_computePublicKey(const br_rsa_private_key* sk, br_rsa_public_key* pk){ @@ -162,7 +180,8 @@ Result(void) RSA_parsePrivateKey_DER(Array(u8) _src, br_rsa_private_key* sk){ void EncryptorRSA_construct(EncryptorRSA* ptr, const br_rsa_public_key* pk){ ptr->pk = pk; - rng_init_sha256_seedFromTime(&br_hmac_drbg_vtable, &ptr->rng.vtable); + ptr->rng.vtable = &br_hmac_drbg_vtable; + rng_init_sha256_seedFromTime(&ptr->rng.vtable); } void EncryptorRSA_encrypt(EncryptorRSA* ptr, Array(u8) src, Array(u8) dst, u32* encrypted_size){ diff --git a/src/cryptography/cryptography.h b/src/cryptography/cryptography.h index 6068a34..9e53fd1 100755 --- a/src/cryptography/cryptography.h +++ b/src/cryptography/cryptography.h @@ -15,7 +15,7 @@ /// @param password some byte array /// @param out_buffer u8[password_hash_size] /// @param iterations number of iterations -void hash_password(str password, u8* out_buffer, i32 iterations); +void hash_password(Array(u8) password, u8* out_buffer, i32 iterations); #define password_hash_size 32 @@ -24,14 +24,13 @@ void hash_password(str password, u8* out_buffer, i32 iterations); ////////////////////////////////////////////////////////////////////////////// /// @brief Initialize prng context with sha256 hashing algorithm and seed from CLOCK_REALTIME. -/// @param rng_class pointer to static vtable variable -/// @param rng_ctx pointer to vtable field in prng context +/// @param rng_vtable_ptr pointer to vtable field in prng context. The field must be initialized. /// EXAMPLE: /// ``` -/// br_hmac_drbg_context rng_ctx; -/// rng_init_sha256_seedFromTime(&br_hmac_drbg_vtable, &rng_ctx.vtable); +/// br_hmac_drbg_context rng_ctx = { .vtable = &br_hmac_drbg_vtable }; +/// rng_init_sha256_seedFromTime(&rng_ctx.vtable); /// ``` -void rng_init_sha256_seedFromTime(const br_prng_class* rng_class, const br_prng_class** rng_ctx); +void rng_init_sha256_seedFromTime(const br_prng_class** rng_vtable_ptr); ////////////////////////////////////////////////////////////////////////////// @@ -57,7 +56,7 @@ typedef struct EncryptorAES { } EncryptorAES; /// @param key Array -void EncryptorAES_init(EncryptorAES* ptr, Array(u8) key); +void EncryptorAES_construct(EncryptorAES* ptr, Array(u8) key); /// @brief Encrypts `src` and writes output to `dst`. /// @param src array of any size @@ -74,7 +73,7 @@ typedef struct DecryptorAES { } DecryptorAES; /// @param key Array -void DecryptorAES_init(DecryptorAES* ptr, Array(u8) key); +void DecryptorAES_construct(DecryptorAES* ptr, Array(u8) key); /// @brief Decrypts `src` and writes output to `dst`. /// @param src array of any size @@ -91,8 +90,10 @@ void DecryptorAES_decrypt(DecryptorAES* ptr, Array(u8) src, Array(u8) dst, u32* /// @param key_size size of public key in bits (2048/3072/4096) /// @param sk key for decryption /// @param pk key for encryption -/// @return true on success -bool RSA_generateKeyPair(u32 key_size, br_rsa_private_key* sk, br_rsa_public_key* pk); +/// @param rng_vtable_ptr pointer to vtable field in prng context. The context must be initialized +Result(void) RSA_generateKeyPair(u32 key_size, + br_rsa_private_key* sk, br_rsa_public_key* pk, + const br_prng_class** rng_vtable_ptr); static inline void RSA_destroyPrivateKey(br_rsa_private_key* sk){ free(sk->p); diff --git a/src/cryptography/hash.c b/src/cryptography/hash.c index ac69578..8ce6879 100755 --- a/src/cryptography/hash.c +++ b/src/cryptography/hash.c @@ -2,7 +2,7 @@ #include "bearssl_hash.h" #include "assert.h" -void hash_password(str password, u8* out_buffer, i32 iterations){ +void hash_password(Array(u8) password, u8* out_buffer, i32 iterations){ assert(password_hash_size == br_sha256_SIZE);; memset(out_buffer, 0, br_sha256_SIZE); br_sha256_context sha256_ctx; diff --git a/src/cryptography/rng.c b/src/cryptography/rng.c index 1659c7e..7fe2031 100644 --- a/src/cryptography/rng.c +++ b/src/cryptography/rng.c @@ -1,7 +1,8 @@ #include "cryptography.h" #include "tlibc/time.h" -void rng_init_sha256_seedFromTime(const br_prng_class* rng_class, const br_prng_class** rng_ctx){ +void rng_init_sha256_seedFromTime(const br_prng_class** rng_vtable_ptr){ nsec_t time_now = getTimeNsec(); - rng_class->init(rng_ctx, &br_sha256_vtable, &time_now, sizeof(time_now)); + const br_prng_class* rng_vtable = *rng_vtable_ptr; + rng_vtable->init(rng_vtable_ptr, &br_sha256_vtable, &time_now, sizeof(time_now)); } diff --git a/src/main.c b/src/main.c index ccb8e75..7642b9d 100755 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,6 @@ #include "network/network.h" -#include "chat.h" -#include "cryptography/cryptography.h" +#include "client/client.h" +#include "server/server.h" typedef enum ProgramMode { Client, diff --git a/src/network/endpoint.h b/src/network/endpoint.h index 075e2e4..8f2d243 100755 --- a/src/network/endpoint.h +++ b/src/network/endpoint.h @@ -1,6 +1,7 @@ #pragma once #include "tlibc/std.h" #include "tlibc/string/str.h" +#include "tlibc/errors.h" #define port_INVALID ((u16)~0) #define port_is_invalid(PORT) (PORT == port_INVALID) diff --git a/src/server.c b/src/server/server.c similarity index 95% rename from src/server.c rename to src/server/server.c index 4b6f0d4..6e2ee9f 100644 --- a/src/server.c +++ b/src/server/server.c @@ -1,5 +1,4 @@ -#include "chat.h" -#include "network/socket.h" +#include "server.h" #include "db/idb.h" #include diff --git a/src/server/server.h b/src/server/server.h new file mode 100644 index 0000000..2428a33 --- /dev/null +++ b/src/server/server.h @@ -0,0 +1,5 @@ +#pragma once +#include "network/socket.h" +#include "cryptography/cryptography.h" + +Result(void) server_run(cstr server_endpoint_str);