Compare commits

...

47 Commits

Author SHA1 Message Date
e99f0115d6
disconnecting user on ca auth end
Some checks failed
Codacy Scan / Codacy Security Scan (push) Successful in 1m16s
Test WHY2-core / test-why2 (why2, ./configure.sh, gdb -ex "run" -ex "quit" --batch, ubuntu-latest, ./out/why2-core-test, valgrind --leak-check=full --show-leak-kinds=reachable --track-origins=yes -s) (push) Failing after 1m54s
Test WHY2-logger / test-why2 (why2-logger, ./configure.sh, gdb -ex "run" -ex "quit" --batch, ubuntu-latest, ./out/why2-logger-test, valgrind --leak-check=full --show-leak-kinds=reachable --track-origins=yes -s) (push) Failing after 1m54s
Build WHY2-chat / test-why2 (./out/why2-chat-client, ./configure.sh, ubuntu-latest, ./out/why2-chat-server) (push) Failing after 2m20s
Test Project / test-project (./configure.sh, gdb -ex "run" -ex "quit" --batch, ubuntu-latest, ./test) (push) Failing after 2m29s
2025-02-01 19:23:24 +01:00
a0bb314010
implemented CA code in client 2025-02-01 18:07:33 +01:00
7377b672bf
returing code from why2_listen_authority 2025-02-01 18:07:13 +01:00
bd986f5327
saving user certificate 2025-02-01 17:32:27 +01:00
d799ff1e0c
allocating correct size in why2_get_authority_cert_path 2025-02-01 17:32:06 +01:00
a42764f6d6
created WHY2_CHAT_CODE_SUCCESS and WHY2_CHAT_CODE_FAILURE macros 2025-02-01 16:32:58 +01:00
61c06dc25a
created why2_get_authority_cert_path fn 2025-02-01 16:26:32 +01:00
43f4d31023
created WHY2_CHAT_AUTHORITY_CERTS_EXTENSION macro 2025-02-01 16:23:33 +01:00
9099192c8a
sending ca pubkey unencrypted to client 2025-02-01 16:12:46 +01:00
cb9ec62b94
sending authority_username from client during ca 2025-02-01 16:05:29 +01:00
82a572bda1
created why2_toml_write_preserve rust fn
same as why2_toml_write but does not remove comments
2025-02-01 16:04:04 +01:00
3227814edf
created why2_get_client_config_path fn 2025-02-01 15:24:23 +01:00
99ae6a7106
simplified config using config_path fn 2025-02-01 15:23:04 +01:00
44ddd6b3d1
sending server client's public key 2025-02-01 15:11:26 +01:00
56bd7c664d
fixed double read from authority 2025-02-01 15:09:44 +01:00
89c0f87678
created WHY2_CHAT_CODE_CLIENT_KEY_EXCHANGE macro 2025-02-01 14:58:39 +01:00
e51a6bf4e8
created why2_chat_ecc_encrypt fn 2025-02-01 14:54:11 +01:00
bf583fd495
created calculate_ecdh_secret fn
calculates shared secret (ECDH)
2025-02-01 14:53:46 +01:00
145f8d790f
created WHY2_CHAT_PADDING macro
how much padding should be used in chat encryption
2025-02-01 14:53:05 +01:00
be15fcd2f6
implemented new why2_sha256 in client 2025-02-01 14:38:14 +01:00
ea1bb6789e
added length parameter to why2_sha256 2025-02-01 14:37:53 +01:00
f404da5e2d
sending ca pubkey to client 2025-02-01 14:00:59 +01:00
9d40603741
added missing crypto include to authority 2025-02-01 14:00:04 +01:00
b9651a6749
connecting to CA on client startup 2025-02-01 13:44:29 +01:00
c10677c29c
added plain why2_listen_authority fn 2025-02-01 13:41:59 +01:00
22bf36481a
removed unused connectStatus variable from client 2025-02-01 13:34:05 +01:00
103d5d5385
added authority_ip to client config 2025-02-01 13:27:52 +01:00
7eaee3a89c
created WHY2_CHAT_CODE_KEY_EXCHANGE macro 2025-02-01 13:21:48 +01:00
bf354372ff
created why2_chat_ecc_deserialize_public_key fn 2025-02-01 13:03:21 +01:00
313c2930e9
allowing NULL length in base64_decode 2025-02-01 13:00:21 +01:00
7bb6e38a99
created why2_chat_ecc_serialize_public_key fn 2025-02-01 12:55:39 +01:00
7eb7940701
generating ecc keys on authority startup 2025-01-31 17:15:13 +01:00
aa037bce74
WHY2_UPDATE_FAILED identifier fix 2025-01-31 17:12:04 +01:00
86c804b6c0
changed __WHY2_ACCEPT_THREAD_PARAMS identifier to lowercase
i forgot it isn't macro
2025-01-31 17:10:30 +01:00
2e53e63345
changed codes to shorter forms
also rename PM codes to DM codes but I already staged it and i am too lazy to redo it
2025-01-31 17:04:53 +01:00
f7e71324f4
implemented _WHY2_ACCEPT_THREAD_PARAMS in servers 2025-01-31 16:57:57 +01:00
4b6ca483c8
using _WHY2_ACCEPT_THREAD_PARAMS in why2_accept_thread 2025-01-31 16:57:33 +01:00
316bdcc778
created _WHY2_ACCEPT_THREAD_PARAMS struct 2025-01-31 16:52:25 +01:00
1928519757
created WHY2_CHAT_SERVER_TYPE enum 2025-01-31 16:32:20 +01:00
8c80d3b815
added plain why2_authority_communicate_thread fn 2025-01-31 16:29:06 +01:00
7f76a43ea4
added make rules for ca server 2025-01-31 16:24:56 +01:00
1d0dc26f87
created ca server file
it is slightly modified server file - gonna change stuff in future commits
2025-01-31 16:21:17 +01:00
d01ba3e141
defined why2_chat_init_authority 2025-01-31 16:20:28 +01:00
78fc77cd69
created WHY2_CHAT_AUTHORITY_DIR macro 2025-01-31 15:59:14 +01:00
ee1c784b84
removed WHY_SA macro
first of all, its stupid. second thing - sa? seriously?
2025-01-31 15:56:17 +01:00
0994558a39
created WHY2_CHAT_AUTHORITY_PORT macro 2025-01-31 15:53:42 +01:00
2768280e7f
declared why2_chat_init_authority 2025-01-31 15:52:00 +01:00
16 changed files with 604 additions and 50 deletions

View File

@ -34,6 +34,7 @@ OUTPUT_APP_LOGGER=$(OUTPUT)/$(PROJECT_NAME)-logger-app
OUTPUT_CHAT_CLIENT=$(OUTPUT)/$(PROJECT_NAME)-chat-client OUTPUT_CHAT_CLIENT=$(OUTPUT)/$(PROJECT_NAME)-chat-client
OUTPUT_CHAT_SERVER=$(OUTPUT)/$(PROJECT_NAME)-chat-server OUTPUT_CHAT_SERVER=$(OUTPUT)/$(PROJECT_NAME)-chat-server
OUTPUT_CHAT_AUTHORITY=$(OUTPUT)/$(PROJECT_NAME)-chat-authority
LIB_CHAT_CONFIG_OUT=./src/chat/config/target/release LIB_CHAT_CONFIG_OUT=./src/chat/config/target/release
@ -44,6 +45,7 @@ SRC_LOGGER=./src/logger/lib/*.c
SRC_LOGGER_APP=./src/logger/app/*.c SRC_LOGGER_APP=./src/logger/app/*.c
SRC_CHAT_CLIENT=./src/chat/main/client.c SRC_CHAT_CLIENT=./src/chat/main/client.c
SRC_CHAT_SERVER=./src/chat/main/server.c SRC_CHAT_SERVER=./src/chat/main/server.c
SRC_CHAT_AUTHORITY=./src/chat/main/authority.c
SRC_CHAT_MISC=./src/chat/*.c SRC_CHAT_MISC=./src/chat/*.c
INCLUDE_DIR=./include INCLUDE_DIR=./include
@ -110,6 +112,9 @@ build_chat_client:
build_chat_server: build_chat_server:
$(CC) $(CFLAGS) $(SRC_CHAT_SERVER) -o $(OUTPUT_CHAT_SERVER) $(LIBS_CHAT) $(CC) $(CFLAGS) $(SRC_CHAT_SERVER) -o $(OUTPUT_CHAT_SERVER) $(LIBS_CHAT)
build_chat_authority:
$(CC) $(CFLAGS) $(SRC_CHAT_AUTHORITY) -o $(OUTPUT_CHAT_AUTHORITY) $(LIBS_CHAT)
build_lib_chat: build_lib_chat:
$(MAKE) clean $(MAKE) clean
$(CC) $(CFLAGS) -fPIC -c $(SRC_CHAT_MISC) $(CC) $(CFLAGS) -fPIC -c $(SRC_CHAT_MISC)
@ -148,7 +153,7 @@ clean:
$(RC) clean $(RFLAGS) $(RC) clean $(RFLAGS)
rm -rf $(OUTPUT)/* $(LOGS)/* *.o *.so vgcore.* rm -rf $(OUTPUT)/* $(LOGS)/* *.o *.so vgcore.*
build_chat: build_chat_server build_chat_client build_chat: build_chat_server build_chat_client build_chat_authority
install_header: install_header_core install_header_logger install_header_chat install_header: install_header_core install_header_logger install_header_chat
install_libs: install_lib_core install_lib_logger install_lib_chat install_libs: install_lib_core install_lib_logger install_lib_chat

View File

@ -31,11 +31,17 @@ extern "C" {
#define WHY2_CHAT_CONFIG_CLIENT "client.toml" #define WHY2_CHAT_CONFIG_CLIENT "client.toml"
#define WHY2_CHAT_CONFIG_SERVER_USERS "server_users.toml" //LOGIN INFO CONFIG #define WHY2_CHAT_CONFIG_SERVER_USERS "server_users.toml" //LOGIN INFO CONFIG
#define WHY2_CHAT_AUTHORITY_DIR "certs" //AUTHORITY DIRECTORY
#define WHY2_CHAT_AUTHORITY_CERTS_EXTENSION ".cert"
void why2_chat_init_server_config(void); //CHECK IF SERVER CONFIG EXISTS, CREATE IT void why2_chat_init_server_config(void); //CHECK IF SERVER CONFIG EXISTS, CREATE IT
void why2_chat_init_client_config(void); //Dementia is a term used to describe a group of symptoms affecting memory, thinking and social abilities. In people who have dementia, the symptoms interfere with their daily lives. Dementia isn't one specific disease. Several diseases can cause dementia. ... void why2_chat_init_client_config(void); //Dementia is a term used to describe a group of symptoms affecting memory, thinking and social abilities. In people who have dementia, the symptoms interfere with their daily lives. Dementia isn't one specific disease. Several diseases can cause dementia. ...
void why2_chat_init_authority(void); //CREATE WHY2_CHAT_AUTHORITY_DIR
char *why2_toml_read(const char* path, const char* key); //READ key FROM path TOML FILE char *why2_toml_read(const char* path, const char* key); //READ key FROM path TOML FILE
void why2_toml_write(const char *path, const char *key, const char *value); //WRITE value AS key INTO path TOML FILE void why2_toml_write(const char *path, const char *key, const char *value); //WRITE value AS key INTO path TOML FILE
void why2_toml_write_preserve(const char *path, const char *key, const char *value); //WRITE value AS key INTO path TOML FILE WITHOUT REMOVING COMMENTS
why2_bool why2_toml_contains(const char *path, const char *key); //CHECK IF path CONTAINS key why2_bool why2_toml_contains(const char *path, const char *key); //CHECK IF path CONTAINS key
why2_bool why2_toml_equals(const char *path, const char *key, const char *value); //CHECK IF key IN path IS EQUAL TO value why2_bool why2_toml_equals(const char *path, const char *key, const char *value); //CHECK IF key IN path IS EQUAL TO value
void why2_toml_read_free(char* s); //DEALLOCATE THE READ VALUE void why2_toml_read_free(char* s); //DEALLOCATE THE READ VALUE
@ -44,6 +50,8 @@ char *why2_chat_server_config(char *key); //why2_toml_read BUT YOU DO NOT HAVE T
char *why2_chat_client_config(char *key); //hihi, *grabs shotgun quietly* char *why2_chat_client_config(char *key); //hihi, *grabs shotgun quietly*
char *why2_get_server_users_path(void); //RETURNS WHY2_CHAT_CONFIG_SERVER_USERS LOCATION char *why2_get_server_users_path(void); //RETURNS WHY2_CHAT_CONFIG_SERVER_USERS LOCATION
char *why2_get_client_config_path(void); //RETURNS WHY2_CHAT_CONFIG_CLIENT LOCATION
char *why2_get_authority_cert_path(char *username); //RETURNS PATH TO CA CERTS
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -37,13 +37,21 @@ extern "C" {
#define WHY2_CHAT_BASE64_LENGTH_DELIMITER ':' //SEPARATES BASE64 FROM LENGTH (YnJhbWJvcmFrCg==:9) #define WHY2_CHAT_BASE64_LENGTH_DELIMITER ':' //SEPARATES BASE64 FROM LENGTH (YnJhbWJvcmFrCg==:9)
#define WHY2_CHAT_PADDING(input_len) ((unsigned long) input_len / 2)
//FUNCTIONS
void why2_chat_init_keys(void); //INIT (POSSIBLY GENERATE) ECC KEYS void why2_chat_init_keys(void); //INIT (POSSIBLY GENERATE) ECC KEYS
void why2_chat_deallocate_keys(void); //DEALLOCATE :) (NO SLUR HERE) void why2_chat_deallocate_keys(void); //DEALLOCATE :) (NO SLUR HERE)
char *why2_chat_ecc_sign(char *message); //SIGN message WITH ECC KEY char *why2_chat_ecc_sign(char *message); //SIGN message WITH ECC KEY
why2_bool why2_chat_ecc_verify_signature(char *message, char *signature, EVP_PKEY *key); why2_bool why2_chat_ecc_verify_signature(char *message, char *signature, EVP_PKEY *key);
char *why2_sha256(char *input); //HASH input USING SHA256 AND RETURN IN STRING char *why2_chat_ecc_serialize_public_key(); //GET PUBLIC ECC KEY IN BASE64
EVP_PKEY* why2_chat_ecc_deserialize_public_key(char *pubkey); //GET EVP_PKEY FROM BASE64 PUBLIC ECC KEY
char *why2_chat_ecc_encrypt(char *message, char *key); //ENCRYPT message WITH ECC key
char *why2_sha256(char *input, size_t length); //HASH input USING SHA256 AND RETURN IN STRING
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -25,9 +25,16 @@ extern "C" {
#include <why2/flags.h> #include <why2/flags.h>
//ENUMS
enum WHY2_CHAT_SERVER_TYPE //TYPE OF SERVER
{
WHY2_CHAT_SERVER, //CLASSIC COMMUNICATION SERVER
WHY2_CHAT_AUTHORITY //CA
};
//MACROS //MACROS
#define WHY2_SA struct sockaddr #define WHY2_CHAT_SERVER_PORT 1204 //PORT FOR SERVER
#define WHY2_CHAT_SERVER_PORT 1204 //PORT #define WHY2_CHAT_AUTHORITY_PORT 1203 //PORT FOR CA
#define WHY2_MAX_CONNECTIONS 1000 //MAX USERS CONNECTED AT ONE TIME #define WHY2_MAX_CONNECTIONS 1000 //MAX USERS CONNECTED AT ONE TIME
#define WHY2_CLEAR_AND_GO_UP "\33[2K\r\033[A" //i mean read the name #define WHY2_CLEAR_AND_GO_UP "\33[2K\r\033[A" //i mean read the name
@ -35,21 +42,29 @@ extern "C" {
#define WHY2_INVALID_POINTER (void*) 0xffffffffffffffff #define WHY2_INVALID_POINTER (void*) 0xffffffffffffffff
//(SERVER -> CLIENT) CODES //(SERVER -> CLIENT) CODES
#define WHY2_CHAT_CODE_ACCEPT_MESSAGES "code_000" //TELL CLIENT THEY CAN SEND MESSAGES #define WHY2_CHAT_CODE_ACCEPT_MESSAGES "SC0" //TELL CLIENT THEY CAN SEND MESSAGES
#define WHY2_CHAT_CODE_PICK_USERNAME "code_001" //TELL CLIENT TO PICK USERNAME #define WHY2_CHAT_CODE_PICK_USERNAME "SC1" //TELL CLIENT TO PICK USERNAME
#define WHY2_CHAT_CODE_SERVER_SIDE_QUIT_COMMUNICATION "code_002" //TELL CLIENT TO END COMMUNICATION (just so they don't get segfault on server-side disconnect) #define WHY2_CHAT_CODE_SERVER_SIDE_QUIT_COMMUNICATION "SC2" //TELL CLIENT TO END COMMUNICATION (just so they don't get segfault on server-side disconnect)
#define WHY2_CHAT_CODE_INVALID_USERNAME "code_003" //haha #define WHY2_CHAT_CODE_INVALID_USERNAME "SC3" //haha
#define WHY2_CHAT_CODE_LIST_SERVER "code_004" //SAME AS WHY2_CHAT_CODE_LIST BUT BACK TO THE CLIENT #define WHY2_CHAT_CODE_LIST_SERVER "SC4" //SAME AS WHY2_CHAT_CODE_LIST BUT BACK TO THE CLIENT
#define WHY2_CHAT_CODE_VERSION_SERVER "code_005" //SAME AS WHY2_CHAT_CODE_VERSION BUT BACK TO THE CLIENT #define WHY2_CHAT_CODE_VERSION_SERVER "SC5" //SAME AS WHY2_CHAT_CODE_VERSION BUT BACK TO THE CLIENT
#define WHY2_CHAT_CODE_PM_SERVER "code_006" //SAME AS WHY2_CHAT_CODE_PM BUT BACK TO THE CLIENT #define WHY2_CHAT_CODE_DM_SERVER "SC6" //SAME AS WHY2_CHAT_CODE_DM BUT BACK TO THE CLIENT
#define WHY2_CHAT_CODE_ENTER_PASSWORD "code_007" //RECEIVE PASSWORD FROM USER #define WHY2_CHAT_CODE_ENTER_PASSWORD "SC7" //RECEIVE PASSWORD FROM USER
#define WHY2_CHAT_CODE_INVALID_PASSWORD "code_008"//🌸ꗥ~ꗥ🌸 𝐢 𝐡𝐚𝐭𝐞 𝐲𝐨𝐮 🌸ꗥ~ꗥ🌸 #define WHY2_CHAT_CODE_INVALID_PASSWORD "SC8"//🌸ꗥ~ꗥ🌸 𝐢 𝐡𝐚𝐭𝐞 𝐲𝐨𝐮 🌸ꗥ~ꗥ🌸
//(CLIENT -> SERVER) CODES //(CLIENT -> SERVER) CODES
#define WHY2_CHAT_CODE_EXIT "code_999" //TELL SERVER YOU ARE ENDING COMMUNICATION #define WHY2_CHAT_CODE_EXIT "CS1" //TELL SERVER YOU ARE ENDING COMMUNICATION
#define WHY2_CHAT_CODE_LIST "code_998" //TELL SERVER TO GIVE YOU ALL CONNECTED USERS #define WHY2_CHAT_CODE_LIST "CS2" //TELL SERVER TO GIVE YOU ALL CONNECTED USERS
#define WHY2_CHAT_CODE_PM "code_997" //TELL SERVER TO SEND MESSAGE ONLY TO SPECIFIC ID #define WHY2_CHAT_CODE_DM "CS3" //TELL SERVER TO SEND MESSAGE ONLY TO SPECIFIC ID
#define WHY2_CHAT_CODE_VERSION "code_996" //TELL SERVER TO GIVE YOU ITS VERSION #define WHY2_CHAT_CODE_VERSION "CS4" //TELL SERVER TO GIVE YOU ITS VERSION
//(AUTHORITY -> CLIENT) CODES
#define WHY2_CHAT_CODE_KEY_EXCHANGE "AC0" //TELL CLIENT YOU ARE SENDING YOUR PUBLIC KEY
#define WHY2_CHAT_CODE_SUCCESS "AC1" //TELL CLIENT THEY ARE GOOD TO GO
#define WHY2_CHAT_CODE_FAILURE "AC2" //TELL CLIENT THEY FUCKED UP
//(CLIENT -> AUTHORITY) CODES
#define WHY2_CHAT_CODE_CLIENT_KEY_EXCHANGE "CA0" //TELL AUTHORITY YOU ARE SENDING YOUR PUBLIC KEY
//COMMANDS //COMMANDS
#define WHY2_CHAT_COMMAND_PREFIX "!" //the little thingy you write before the command names to make the program recognise them boy. You know? Like in minecraft you use /kill... Also, are you dumb? #define WHY2_CHAT_COMMAND_PREFIX "!" //the little thingy you write before the command names to make the program recognise them boy. You know? Like in minecraft you use /kill... Also, are you dumb?

View File

@ -23,15 +23,27 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
extern "C" { extern "C" {
#endif #endif
#include <why2/flags.h> //TODO: fuck this #include <why2/flags.h>
#include <why2/chat/flags.h>
//STRUCTS
typedef struct
{
int socket; //SOCKET POINTER
enum WHY2_CHAT_SERVER_TYPE type; //TYPE OF SERVER
} __why2_accept_thread_params;
//FUNCTIONS
void why2_send_socket(char *text, char *username, int socket); //send socket.... wtf did you expect void why2_send_socket(char *text, char *username, int socket); //send socket.... wtf did you expect
void why2_send_socket_code(char *params, char *username, int socket, char *code); //SEND SOCKET BUT WITH CODE void why2_send_socket_code(char *params, char *username, int socket, char *code); //SEND SOCKET BUT WITH CODE
void *why2_communicate_thread(void *arg); //COMMUNICATION THREAD void *why2_communicate_thread(void *arg); //COMMUNICATION THREAD
void *why2_accept_thread(void *socket); //LOOP ACCEPTING CONNECTIONS void *why2_authority_communicate_thread(void *arg); //CA COMMUNICATION THREAD
void *why2_accept_thread(void *params); //LOOP ACCEPTING CONNECTIONS
void why2_clean_connections(void); //CLOSE EVERY CONNECTION void why2_clean_connections(void); //CLOSE EVERY CONNECTION
void why2_clean_threads(void); //CLOSE EVERY RUNNING MESSAGE THREAD void why2_clean_threads(void); //CLOSE EVERY RUNNING MESSAGE THREAD
void *why2_listen_server(void *socket); //LISTEN FOR OTHER's USERS MESSAGES void *why2_listen_server(void *socket); //LISTEN FOR OTHER's USERS MESSAGES
void *why2_listen_authority(void *socket); //LISTEN TO AUTHORITY
void *why2_getline_thread(WHY2_UNUSED void* arg); //START getline IN SEPARATE THREAD void *why2_getline_thread(WHY2_UNUSED void* arg); //START getline IN SEPARATE THREAD
void why2_trim_string(char **s); //REMOVES SPACES FROM END AND START OF *s void why2_trim_string(char **s); //REMOVES SPACES FROM END AND START OF *s

View File

@ -30,7 +30,7 @@ enum WHY2_EXIT_CODES //exit codes you fucking idiot
WHY2_INVALID_KEY = 1, //EXIT VALUE FOR INVALID KEY WHY2_INVALID_KEY = 1, //EXIT VALUE FOR INVALID KEY
WHY2_INVALID_TEXT = 4, //EXIT VALUE FOR INVALID TEXT WHY2_INVALID_TEXT = 4, //EXIT VALUE FOR INVALID TEXT
WHY2_DOWNLOAD_FAILED = 2, //EXIT VALUE FOR versions.json DOWNLOAD FAILED WHY2_DOWNLOAD_FAILED = 2, //EXIT VALUE FOR versions.json DOWNLOAD FAILED
WHY2_WHY2_UPDATE_FAILED = 3 //EXIT VALUE FOR UPDATE FAILED WHY2_UPDATE_FAILED = 3 //EXIT VALUE FOR UPDATE FAILED
}; };

View File

@ -34,7 +34,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
enum CONFIG_TYPES enum CONFIG_TYPES
{ {
CLIENT, CLIENT,
SERVER SERVER,
SERVER_USERS,
AUTHORITY
}; };
void init_config(char *filename) void init_config(char *filename)
@ -78,7 +80,7 @@ void init_config(char *filename)
why2_deallocate(buffer); why2_deallocate(buffer);
} }
char *config(char *key, enum CONFIG_TYPES type) char *config_path(enum CONFIG_TYPES type)
{ {
char *path = NULL; char *path = NULL;
@ -92,11 +94,27 @@ char *config(char *key, enum CONFIG_TYPES type)
path = why2_replace(WHY2_CONFIG_DIR "/" WHY2_CHAT_CONFIG_SERVER, "{HOME}", getenv("HOME")); path = why2_replace(WHY2_CONFIG_DIR "/" WHY2_CHAT_CONFIG_SERVER, "{HOME}", getenv("HOME"));
break; break;
case SERVER_USERS:
path = why2_replace(WHY2_CONFIG_DIR "/" WHY2_CHAT_CONFIG_SERVER_USERS, "{HOME}", getenv("HOME"));
break;
case AUTHORITY:
path = why2_replace(WHY2_CONFIG_DIR "/" WHY2_CHAT_AUTHORITY_DIR, "{HOME}", getenv("HOME"));
break;
default: default:
why2_die("CONFIG_TYPE not implemented!"); why2_die("CONFIG_TYPE not implemented!");
break; break;
} }
return path;
}
char *config(char *key, enum CONFIG_TYPES type)
{
//GET CONFIGURATION PATH
char *path = config_path(type);
//VALUE //VALUE
char *value = why2_toml_read(path, key); char *value = why2_toml_read(path, key);
@ -137,6 +155,19 @@ void why2_chat_init_client_config(void)
init_config(WHY2_CHAT_CONFIG_CLIENT); init_config(WHY2_CHAT_CONFIG_CLIENT);
} }
void why2_chat_init_authority(void)
{
//CREATE USER CONFIG FOLDER [THIS SHOULDN'T HAPPEN ON CLIENT, BUT IT'S NEEDED ON FRESH SERVERS]
why2_directory();
//GET THE CONFIG TYPE
char *path = config_path(AUTHORITY);
if (access(path, R_OK) != 0) mkdir(path, 0700); //DIRECTORY DOESN'T EXIST; CREATE IT
//DEALLOCATION
why2_deallocate(path);
}
char *why2_chat_server_config(char *key) char *why2_chat_server_config(char *key)
{ {
return config(key, SERVER); return config(key, SERVER);
@ -149,5 +180,24 @@ char *why2_chat_client_config(char *key)
char *why2_get_server_users_path(void) char *why2_get_server_users_path(void)
{ {
return why2_replace(WHY2_CONFIG_DIR "/" WHY2_CHAT_CONFIG_SERVER_USERS, "{HOME}", getenv("HOME")); return config_path(SERVER_USERS);
}
char *why2_get_client_config_path(void)
{
return config_path(CLIENT);
}
char *why2_get_authority_cert_path(char *username)
{
char *buffer = config_path(AUTHORITY);
char *path = why2_malloc(strlen(buffer) + strlen(username) + strlen(WHY2_CHAT_AUTHORITY_CERTS_EXTENSION) + 3);
//GET THE FILE
sprintf(path, "%s/%s%s%c", buffer, username, WHY2_CHAT_AUTHORITY_CERTS_EXTENSION, '\0');
//DEALLOCATION
why2_deallocate(buffer);
return path;
} }

View File

@ -25,3 +25,4 @@ crate-type = ["cdylib"]
[dependencies] [dependencies]
toml = "*" toml = "*"
toml_edit = "*"

View File

@ -16,3 +16,5 @@
auto_connect = false # Automatic connection to 'auto_connect_ip' auto_connect = false # Automatic connection to 'auto_connect_ip'
auto_connect_ip = "109.123.243.163" # See 'auto_connect' auto_connect_ip = "109.123.243.163" # See 'auto_connect'
authority_ip = "109.123.243.163" # CA Address; Feel free to change if you don't trust the developer, but be aware that both client and server must use the same CA

View File

@ -126,6 +126,48 @@ pub extern "C" fn why2_toml_write(path: *const c_char, key: *const c_char, value
} }
} }
#[no_mangle]
pub extern "C" fn why2_toml_write_preserve(path: *const c_char, key: *const c_char, value: *const c_char)
{
//CONVERT C STRINGS TO RUST STRINGS
let path_r = unsafe { CStr::from_ptr(path).to_string_lossy().into_owned() };
let key_r = unsafe { CStr::from_ptr(key).to_string_lossy().into_owned() };
let value_r = unsafe { CStr::from_ptr(value).to_string_lossy().into_owned() };
//READ FILE
let file_raw = match read_to_string(&path_r)
{
Ok(raw) => raw,
Err(e) =>
{
eprintln!("Could not read TOML config '{}': {}", path_r, e);
return;
}
};
//PARSE TO A toml_edit Document
let mut doc: toml_edit::Document = match file_raw.parse()
{
Ok(doc) => doc,
Err(e) =>
{
eprintln!("Could not parse TOML config '{}': {}", path_r, e);
return;
}
};
doc[&key_r] = toml_edit::value(value_r);
//CONVERT DOCUMENT TO STRING
let updated_data = doc.to_string();
//WRITE
if let Err(e) = write(&path_r, updated_data)
{
eprintln!("Could not write to TOML config '{}': {}", path_r, e);
}
}
#[no_mangle] #[no_mangle]
pub extern "C" fn why2_toml_contains(path: *const c_char, key: *const c_char) -> bool pub extern "C" fn why2_toml_contains(path: *const c_char, key: *const c_char) -> bool
{ {

View File

@ -24,14 +24,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <why2/memory.h>
#include <why2/misc.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/ec.h> #include <openssl/ec.h>
#include <why2/encrypter.h>
#include <why2/memory.h>
#include <why2/misc.h>
EVP_PKEY *keypair = NULL; //KEYPAIR EVP_PKEY *keypair = NULL; //KEYPAIR
//LOCAL //LOCAL
@ -72,8 +73,8 @@ char *base64_decode(char *encoded_message, size_t *length)
BIO *bio; BIO *bio;
BIO *b64; BIO *b64;
char *separator_ptr = strrchr(encoded_message, WHY2_CHAT_BASE64_LENGTH_DELIMITER); //GET THE DELIMITER POINTER char *separator_ptr = strrchr(encoded_message, WHY2_CHAT_BASE64_LENGTH_DELIMITER); //GET THE DELIMITER POINTER
*length = strtoull(separator_ptr + 1, NULL, 10); size_t length_local = strtoull(separator_ptr + 1, NULL, 10);
char* decoded_message = why2_malloc(*length + 1); char* decoded_message = why2_malloc(length_local + 1);
int decoded_length; int decoded_length;
//INIT BIOs //INIT BIOs
@ -83,7 +84,7 @@ char *base64_decode(char *encoded_message, size_t *length)
bio = BIO_push(b64, bio); bio = BIO_push(b64, bio);
//DECODE //DECODE
decoded_length = BIO_read(bio, decoded_message, *length); decoded_length = BIO_read(bio, decoded_message, length_local);
//NULL-TERM //NULL-TERM
decoded_message[decoded_length] = '\0'; decoded_message[decoded_length] = '\0';
@ -91,9 +92,29 @@ char *base64_decode(char *encoded_message, size_t *length)
//DEALLOCATION //DEALLOCATION
BIO_free_all(bio); BIO_free_all(bio);
//SET length
if (length != NULL) *length = length_local;
return decoded_message; return decoded_message;
} }
void calculate_ecdh_secret(EVP_PKEY *pri, EVP_PKEY *pub, char **secret, size_t *len)
{
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pri, NULL);
EVP_PKEY_derive_init(ctx); //INIT DERIVE CONTEXT
EVP_PKEY_derive_set_peer(ctx, pub); //CONFIG
//ALLOCATE
EVP_PKEY_derive(ctx, NULL, len); //CALCULATE LENGTH
*secret = why2_malloc(*len);
EVP_PKEY_derive(ctx, (unsigned char*) *secret, len); //GET SHARED SECRET
//DEALLOCATION
EVP_PKEY_CTX_free(ctx);
}
//GLOBAL //GLOBAL
void why2_chat_init_keys(void) void why2_chat_init_keys(void)
{ {
@ -189,18 +210,110 @@ why2_bool why2_chat_ecc_verify_signature(char *message, char *signature, EVP_PKE
return returning; return returning;
} }
//TODO: Remove PEM
char *why2_chat_ecc_serialize_public_key()
{
//VARIABLES
BIO *bio = BIO_new(BIO_s_mem());
char *data;
size_t length;
char *pubkey;
char *base64_encoded;
//SEPARATE PUBKEY
PEM_write_bio_PUBKEY(bio, keypair);
//ALLOCATE
length = BIO_get_mem_data(bio, &data);
pubkey = why2_malloc(length + 1);
//COPY
memcpy(pubkey, data, length);
pubkey[length] = '\0';
//ENCODE
base64_encoded = base64_encode(pubkey, length);
//DEALLOCATION
BIO_free(bio);
why2_deallocate(pubkey);
return base64_encoded;
}
//TODO: Remove PEM
EVP_PKEY* why2_chat_ecc_deserialize_public_key(char *pubkey)
{
//VARIABLES
BIO *bio;
EVP_PKEY *key;
char *base64_decoded = base64_decode(pubkey, NULL);
//EXTRACT KEY
bio = BIO_new_mem_buf(base64_decoded, -1);
key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
//DEALLOCATION
BIO_free(bio);
return key;
}
char *why2_chat_ecc_encrypt(char *message, char *key)
{
//VARIABLES
size_t key_length;
char *secret = NULL;
size_t secret_len;
char *recipient_pubkey_decoded = base64_decode(key, &key_length); //DECODE key
why2_output_flags encrypted;
char *encrypted_text;
char *returning;
char *sym_key;
BIO *bio = BIO_new_mem_buf(recipient_pubkey_decoded, -1);
EVP_PKEY *recipient_pubkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
//CALCULATE SHARED SECRET
calculate_ecdh_secret(keypair, recipient_pubkey, &secret, &secret_len);
//DERIVE WHY2 KEY (SHA256)
sym_key = why2_sha256(secret, secret_len);
//ENCRYPTION SETTINGS
if (why2_get_key_length() < strlen(sym_key)) why2_set_key_length(strlen(sym_key)); //ALLOW sym_key'S LENGTH
why2_set_flags((why2_input_flags) { 0, 0, 0, WHY2_v4, WHY2_OUTPUT_TEXT, WHY2_CHAT_PADDING(strlen(sym_key)) });
//ENCRYPT MESSAGE
encrypted = why2_encrypt_text(message, sym_key);
encrypted_text = why2_strdup(encrypted.output_text);
//CONVERT TO BASE64
returning = base64_encode(encrypted_text, strlen(encrypted_text));
//DEALLOCATION
BIO_free(bio);
EVP_PKEY_free(recipient_pubkey);
why2_deallocate(secret);
why2_deallocate(sym_key);
why2_deallocate(recipient_pubkey_decoded);
why2_deallocate(encrypted_text);
why2_deallocate_output(encrypted);
return returning;
}
void why2_chat_deallocate_keys(void) void why2_chat_deallocate_keys(void)
{ {
//DEALLOCATE THE pkey //DEALLOCATE THE pkey
EVP_PKEY_free(keypair); EVP_PKEY_free(keypair);
} }
char *why2_sha256(char *input) char *why2_sha256(char *input, size_t length)
{ {
unsigned char *output = why2_malloc(SHA256_DIGEST_LENGTH + 1); unsigned char *output = why2_malloc(SHA256_DIGEST_LENGTH + 1);
char *formatted_output = why2_malloc(SHA256_DIGEST_LENGTH * 2 + 2); char *formatted_output = why2_malloc(SHA256_DIGEST_LENGTH * 2 + 2);
SHA256((unsigned char*) input, strlen(input), output); SHA256((unsigned char*) input, length, output);
//SAVE AS STRING IN HEX //SAVE AS STRING IN HEX
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)

89
src/chat/main/authority.c Normal file
View File

@ -0,0 +1,89 @@
/*
This is part of WHY2
Copyright (C) 2022 Václav Šmejkal
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include <why2/chat/config.h>
#include <why2/chat/crypto.h>
#include <why2/chat/flags.h>
#include <why2/chat/misc.h>
#include <why2/memory.h>
#include <why2/misc.h>
int main(void)
{
why2_check_version(); //CHECK FOR UPDATES
why2_chat_init_authority(); //CREATE AUTHORITY DIRECTORY
why2_chat_init_keys(); //CREATE ECC KEY
int listen_socket = socket(AF_INET, SOCK_STREAM, 0); //CREATE CA SERVER SOCKET
pthread_t thread;
size_t line_length_buffer = 0;
char *line_buffer = NULL;
if (listen_socket < 0) why2_die("Failed creating socket.");
//DEFINE CA SERVER ADDRESS
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(WHY2_CHAT_AUTHORITY_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
//BIND SOCKET
if (bind(listen_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) why2_die("Failed binding socket.");
//LISTEN
if (listen(listen_socket, WHY2_MAX_CONNECTIONS) < 0) why2_die("Binding failed.");
printf("CA server enabled.\n\n");
__why2_accept_thread_params params = { listen_socket, WHY2_CHAT_AUTHORITY };
pthread_create(&thread, NULL, why2_accept_thread, &params);
for (;;)
{
if (getline(&line_buffer, &line_length_buffer, stdin) == -1) why2_die("Reading input failed.");
if (strcmp(line_buffer, WHY2_CHAT_COMMAND_PREFIX WHY2_CHAT_COMMAND_EXIT "\n") == 0) //USER REQUESTED PROGRAM EXIT
{
printf("Exiting...\n");
break;
}
}
//QUIT COMMUNICATION
why2_clean_connections(); //STOP LISTENING; DISCONNECT ALL USERS
why2_clean_threads(); //STOP WAITING FOR MESSAGES
//DEALLOCATION
free(line_buffer);
close(listen_socket);
pthread_cancel(thread);
why2_clean_memory(""); //RUN GARBAGE COLLECTOR
return 0;
}

View File

@ -20,6 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@ -108,10 +109,30 @@ int main(void)
pthread_t thread_getline; pthread_t thread_getline;
why2_bool ssqc = 0; why2_bool ssqc = 0;
char *cmd_arg = NULL; char *cmd_arg = NULL;
why2_bool *ca_success;
//DEFINE SERVER ADDRESS //DEFINE CONNECTION PROPERTIES
struct sockaddr_in server_addr; struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET; server_addr.sin_family = AF_INET;
//CA CONNECT
line = why2_chat_client_config("authority_ip"); //GET ADDRESS OF CA
server_addr.sin_port = htons(WHY2_CHAT_AUTHORITY_PORT); //CA PORT
server_addr.sin_addr.s_addr = inet_addr(line); //IP ADDRESS OF CA
if (connect(listen_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) why2_die("Connecting to CA failed."); //CONNECT TO CA
pthread_create(&thread_buffer, NULL, why2_listen_authority, &listen_socket); //LISTEN TO AUTHORITY (only in why2, fuck authorities irl [hi fbi, this is just a joke haha])
why2_deallocate(line); //DEALLOCATE ADDRESS
pthread_join(thread_buffer, (void**) &ca_success); //WAIT UNTIL CA AUTH IS COMPLETED
close(listen_socket); //CLOSE CONNECTION
if (!*ca_success) why2_die("CA Authentication failed!");
why2_deallocate(ca_success);
//SERVER CONNECT
server_addr.sin_port = htons(WHY2_CHAT_SERVER_PORT); server_addr.sin_port = htons(WHY2_CHAT_SERVER_PORT);
//GET IP //GET IP
@ -148,9 +169,7 @@ int main(void)
free(line); //PREVENT FROM MEMORY LEAK free(line); //PREVENT FROM MEMORY LEAK
int connectStatus = connect(listen_socket, (WHY2_SA *) &server_addr, sizeof(server_addr)); //CONNECT if (connect(listen_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) why2_die("Connecting failed."); //CONNECT
if (connectStatus < 0) why2_die("Connecting failed.");
pthread_create(&thread_buffer, NULL, why2_listen_server, &listen_socket); //LISTEN TO OTHER USERS pthread_create(&thread_buffer, NULL, why2_listen_server, &listen_socket); //LISTEN TO OTHER USERS
@ -244,7 +263,7 @@ int main(void)
char *final_message = why2_malloc(strlen(id) + strlen(msg) + 2); char *final_message = why2_malloc(strlen(id) + strlen(msg) + 2);
sprintf(final_message, "%s;%s%c", id, msg, '\0'); sprintf(final_message, "%s;%s%c", id, msg, '\0');
why2_send_socket_code(final_message, NULL, listen_socket, WHY2_CHAT_CODE_PM); //SEND why2_send_socket_code(final_message, NULL, listen_socket, WHY2_CHAT_CODE_DM); //SEND
//DEALLOCATION //DEALLOCATION
why2_deallocate(id); why2_deallocate(id);
@ -266,7 +285,7 @@ int main(void)
//REMOVE \n AT THE END OF line //REMOVE \n AT THE END OF line
line[strlen(line) - 1] = '\0'; line[strlen(line) - 1] = '\0';
char *hash = why2_sha256(line); //HASHISH char *hash = why2_sha256(line, strlen(line)); //HASHISH
why2_send_socket(hash, NULL, listen_socket); //SEND BUT HASHED why2_send_socket(hash, NULL, listen_socket); //SEND BUT HASHED

View File

@ -51,14 +51,15 @@ int main(void)
server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_addr.s_addr = INADDR_ANY;
//BIND SOCKET //BIND SOCKET
if (bind(listen_socket, (WHY2_SA *) &server_addr, sizeof(server_addr)) < 0) why2_die("Failed binding socket."); if (bind(listen_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) why2_die("Failed binding socket.");
//LISTEN //LISTEN
if (listen(listen_socket, WHY2_MAX_CONNECTIONS) < 0) why2_die("Binding failed."); if (listen(listen_socket, WHY2_MAX_CONNECTIONS) < 0) why2_die("Binding failed.");
printf("Server enabled.\n\n"); printf("Server enabled.\n\n");
pthread_create(&thread, NULL, why2_accept_thread, &listen_socket); __why2_accept_thread_params params = { listen_socket, WHY2_CHAT_SERVER };
pthread_create(&thread, NULL, why2_accept_thread, &params);
for (;;) for (;;)
{ {

View File

@ -31,6 +31,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <json-c/json.h> #include <json-c/json.h>
#include <why2/chat/config.h> #include <why2/chat/config.h>
#include <why2/chat/crypto.h>
#include <why2/chat/flags.h> #include <why2/chat/flags.h>
#include <why2/llist.h> #include <why2/llist.h>
@ -765,7 +766,7 @@ void *why2_communicate_thread(void *arg)
//DEALLOCATION //DEALLOCATION
why2_deallocate(message); why2_deallocate(message);
} else if (strcmp(decoded_code_buffer, WHY2_CHAT_CODE_PM) == 0 && decoded_buffer != NULL && strlen(decoded_buffer) != 0) //PM } else if (strcmp(decoded_code_buffer, WHY2_CHAT_CODE_DM) == 0 && decoded_buffer != NULL && strlen(decoded_buffer) != 0) //PM
{ {
char *id = NULL; //RECEIVER char *id = NULL; //RECEIVER
char *msg; char *msg;
@ -814,8 +815,8 @@ void *why2_communicate_thread(void *arg)
why2_bool self_pm = pm_connection_node.connection == connection; why2_bool self_pm = pm_connection_node.connection == connection;
//SEND YOU DUMB FUCK //SEND YOU DUMB FUCK
send_socket_code_deallocate(private_msg, why2_chat_server_config("server_username"), pm_connection_node.connection, WHY2_CHAT_CODE_PM_SERVER); //RECIPIENT send_socket_code_deallocate(private_msg, why2_chat_server_config("server_username"), pm_connection_node.connection, WHY2_CHAT_CODE_DM_SERVER); //RECIPIENT
if (!self_pm) send_socket_code_deallocate(private_msg, why2_chat_server_config("server_username"), connection, WHY2_CHAT_CODE_PM_SERVER); //AUTHOR if (!self_pm) send_socket_code_deallocate(private_msg, why2_chat_server_config("server_username"), connection, WHY2_CHAT_CODE_DM_SERVER); //AUTHOR
why2_deallocate(private_msg); why2_deallocate(private_msg);
} }
@ -865,19 +866,125 @@ void *why2_communicate_thread(void *arg)
return NULL; return NULL;
} }
void *why2_accept_thread(void *socket) void *why2_authority_communicate_thread(void *arg)
{ {
//VARIABLES
int connection = *(int*) arg;
why2_bool exiting = 0;
char *raw;
void *raw_ptr;
char *message;
char *username;
char *code;
printf("User connected.\t\t%d\n", connection);
//SEND USER KEY EXCHANGE CODE
why2_send_socket_code(NULL, NULL, connection, WHY2_CHAT_CODE_KEY_EXCHANGE);
do
{
//READ PACKET
if ((raw = read_user(connection, &raw_ptr)) == NULL) break; //READ
//GET DATA
message = get_string_from_json_string(raw, "message");
username = get_string_from_json_string(raw, "username");
code = get_string_from_json_string(raw, "code");
if (code != NULL && message != NULL && username != NULL)
{
if (strcmp(code, WHY2_CHAT_CODE_CLIENT_KEY_EXCHANGE) == 0)
{
//GET PATH OF USER CERT
char *path = why2_get_authority_cert_path(username);
FILE *cert;
if (access(path, F_OK) == 0) //ALREADY EXISTS
{
//VARIABLES
char *buffer;
long buffer_size;
cert = why2_fopen(path, "r"); //OPEN FILE
//COUNT LENGTH OF buffer AND STORE IT IN buffer_size
fseek(cert, 0, SEEK_END);
buffer_size = ftell(cert);
rewind(cert); //REWIND file_buffer (NO SHIT)
//ALLOCATE
buffer = why2_calloc(buffer_size + 1, sizeof(char));
fread(buffer, buffer_size, 1, cert); //READ
//SEND STATUS
why2_send_socket_code(NULL, NULL, connection, strcmp(buffer, message) == 0 ? WHY2_CHAT_CODE_SUCCESS : WHY2_CHAT_CODE_FAILURE);
//DEALLOCATION
why2_deallocate(buffer);
} else
{
//CREATE CERT
cert = why2_fopen(path, "w+"); //CREATE FILE
fwrite(message, 1, strlen(message), cert); //WRITE PUBKEY
//CONFIRM SUCCESS
why2_send_socket_code(NULL, NULL, connection, WHY2_CHAT_CODE_SUCCESS);
}
//DEALLOCATION
why2_deallocate(path);
why2_deallocate(cert);
exiting = 1;
}
} else exiting = 1;
//DEALLOCATION
why2_deallocate(raw);
why2_deallocate(raw_ptr);
why2_deallocate(message);
why2_deallocate(username);
why2_deallocate(code);
} while (!exiting);
printf("User disconnected.\t%d\n", connection);
return NULL;
}
void *why2_accept_thread(void *params)
{
__why2_accept_thread_params param = *(__why2_accept_thread_params*) params; //GET PARAMETERS
//VARIABLES
int accepted; int accepted;
pthread_t thread; pthread_t thread;
//LOOP ACCEPT //LOOP ACCEPT
for (;;) for (;;)
{ {
accepted = accept(*((int*) socket), (WHY2_SA *) NULL, NULL); //ACCEPT NEW SOCKET accepted = accept(param.socket, (struct sockaddr *) NULL, NULL); //ACCEPT NEW SOCKET
if (accepted == -1) continue; if (accepted == -1) continue;
pthread_create(&thread, NULL, why2_communicate_thread, &accepted); void *(*communication_thread)(void*) = NULL;
switch (param.type) //GET communication_thread
{
case WHY2_CHAT_SERVER:
communication_thread = why2_communicate_thread;
break;
case WHY2_CHAT_AUTHORITY:
communication_thread = why2_authority_communicate_thread;
break;
default:
why2_die("WHY2_CHAT_SERVER_TYPE not implemented!");
break;
}
pthread_create(&thread, NULL, communication_thread, &accepted);
} }
return NULL; return NULL;
@ -1027,7 +1134,7 @@ void *why2_listen_server(void *socket)
{ {
printf("Server is outdated. Some new features may not work correctly.\n\n"); printf("Server is outdated. Some new features may not work correctly.\n\n");
} }
} else if (strcmp(code, WHY2_CHAT_CODE_PM_SERVER) == 0) } else if (strcmp(code, WHY2_CHAT_CODE_DM_SERVER) == 0)
{ {
printf(WHY2_CLEAR_AND_GO_UP WHY2_CLEAR_AND_GO_UP); //do not fucking ask me how the fucking formatting fucking works, i dont fucking know printf(WHY2_CLEAR_AND_GO_UP WHY2_CLEAR_AND_GO_UP); //do not fucking ask me how the fucking formatting fucking works, i dont fucking know
@ -1119,6 +1226,88 @@ void *why2_listen_server(void *socket)
return NULL; return NULL;
} }
void *why2_listen_authority(void *socket)
{
//VARIABLES
int socket_ptr = *(int*) socket;
char *read;
why2_bool exiting = 0;
why2_bool *success = why2_malloc(sizeof(why2_bool));
char *code;
*success = 0;
do
{
//READ PACKET
read = read_socket_raw(socket_ptr);
if (read == NULL) continue; //INVALID PACKET RECEIVED
//GET DATA
code = get_string_from_json_string(read, "code");
if (code != NULL)
{
if (strcmp(code, WHY2_CHAT_CODE_KEY_EXCHANGE) == 0)
{
//VARIABLES
char *user_config_path = why2_get_client_config_path();
char *username;
why2_bool asked_username = 0; //FOR CORRECT DEALLOCATION FN
if (!why2_toml_contains(user_config_path, "authority_username"))
{
//GET USERNAME FOR CA
pthread_t thread_getline;
printf("Enter username for CA server.\nIn order to be authenticated, you will need to use this username on server too.\n>>> ");
//GET INPUT
pthread_create(&thread_getline, NULL, why2_getline_thread, NULL);
pthread_join(thread_getline, (void**) &username);
//REMOVE \n
username[strlen(username) - 1] = '\0';
//SAVE
why2_toml_write_preserve(user_config_path, "authority_username", username);
asked_username = 1;
printf("\n");
} else username = why2_chat_client_config("authority_username");
//SEND CA CLIENT'S ENCRYPTED PUBKEY
char *key = why2_chat_ecc_serialize_public_key();
why2_send_socket_code(key, username, socket_ptr, WHY2_CHAT_CODE_CLIENT_KEY_EXCHANGE); //SEND
//DEALLOCATION
why2_deallocate(user_config_path);
why2_deallocate(key);
if (asked_username)
{
free(username);
} else
{
why2_toml_read_free(username);
}
} else
{
//EXIT
*success = strcmp(code, WHY2_CHAT_CODE_SUCCESS) == 0;
exiting = 1;
}
}
//DEALLOCATION
why2_deallocate(read);
why2_deallocate(code);
} while (!exiting);
return success;
}
void *why2_getline_thread(WHY2_UNUSED void* arg) void *why2_getline_thread(WHY2_UNUSED void* arg)
{ {
getline_thread = pthread_self(); getline_thread = pthread_self();

View File

@ -185,7 +185,7 @@ enum WHY2_EXIT_CODES why2_check_version(void)
if (!why2_get_flags().no_output) fprintf(stderr, "You need to be root to update!\t[I DO NOT RECOMMEND USING THIS]\n"); if (!why2_get_flags().no_output) fprintf(stderr, "You need to be root to update!\t[I DO NOT RECOMMEND USING THIS]\n");
why2_clean_memory("core_version_check"); why2_clean_memory("core_version_check");
return WHY2_WHY2_UPDATE_FAILED; return WHY2_UPDATE_FAILED;
} }
//VARIABLES //VARIABLES
@ -215,7 +215,7 @@ enum WHY2_EXIT_CODES why2_check_version(void)
if (!why2_get_flags().no_output) fprintf(stderr, "Updating failed! (cloning)\n"); if (!why2_get_flags().no_output) fprintf(stderr, "Updating failed! (cloning)\n");
why2_clean_memory("core_version_check"); why2_clean_memory("core_version_check");
return WHY2_WHY2_UPDATE_FAILED; return WHY2_UPDATE_FAILED;
} }
//COUNT install_command LENGTH & ALLOCATE IT //COUNT install_command LENGTH & ALLOCATE IT
@ -234,7 +234,7 @@ enum WHY2_EXIT_CODES why2_check_version(void)
if (!why2_get_flags().no_output) fprintf(stderr, "Updating failed! (installing)\n"); if (!why2_get_flags().no_output) fprintf(stderr, "Updating failed! (installing)\n");
why2_clean_memory("core_version_check"); why2_clean_memory("core_version_check");
return WHY2_WHY2_UPDATE_FAILED; return WHY2_UPDATE_FAILED;
} }
} else } else
{ {