Compare commits

..

No commits in common. "e99f0115d66fe95c1e9dde0f87f6d41716815950" and "07eb5961803775a55f0d9cc0fa86e78c181a5876" have entirely different histories.

16 changed files with 50 additions and 604 deletions

View File

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

View File

@ -31,17 +31,11 @@ extern "C" {
#define WHY2_CHAT_CONFIG_CLIENT "client.toml"
#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_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
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_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
@ -50,8 +44,6 @@ 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_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
}

View File

@ -37,21 +37,13 @@ extern "C" {
#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_deallocate_keys(void); //DEALLOCATE :) (NO SLUR HERE)
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);
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
char *why2_sha256(char *input); //HASH input USING SHA256 AND RETURN IN STRING
#ifdef __cplusplus
}

View File

@ -25,16 +25,9 @@ extern "C" {
#include <why2/flags.h>
//ENUMS
enum WHY2_CHAT_SERVER_TYPE //TYPE OF SERVER
{
WHY2_CHAT_SERVER, //CLASSIC COMMUNICATION SERVER
WHY2_CHAT_AUTHORITY //CA
};
//MACROS
#define WHY2_CHAT_SERVER_PORT 1204 //PORT FOR SERVER
#define WHY2_CHAT_AUTHORITY_PORT 1203 //PORT FOR CA
#define WHY2_SA struct sockaddr
#define WHY2_CHAT_SERVER_PORT 1204 //PORT
#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
@ -42,29 +35,21 @@ enum WHY2_CHAT_SERVER_TYPE //TYPE OF SERVER
#define WHY2_INVALID_POINTER (void*) 0xffffffffffffffff
//(SERVER -> CLIENT) CODES
#define WHY2_CHAT_CODE_ACCEPT_MESSAGES "SC0" //TELL CLIENT THEY CAN SEND MESSAGES
#define WHY2_CHAT_CODE_PICK_USERNAME "SC1" //TELL CLIENT TO PICK USERNAME
#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 "SC3" //haha
#define WHY2_CHAT_CODE_LIST_SERVER "SC4" //SAME AS WHY2_CHAT_CODE_LIST 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_DM_SERVER "SC6" //SAME AS WHY2_CHAT_CODE_DM BUT BACK TO THE CLIENT
#define WHY2_CHAT_CODE_ENTER_PASSWORD "SC7" //RECEIVE PASSWORD FROM USER
#define WHY2_CHAT_CODE_INVALID_PASSWORD "SC8"//🌸ꗥ~ꗥ🌸 𝐢 𝐡𝐚𝐭𝐞 𝐲𝐨𝐮 🌸ꗥ~ꗥ🌸
#define WHY2_CHAT_CODE_ACCEPT_MESSAGES "code_000" //TELL CLIENT THEY CAN SEND MESSAGES
#define WHY2_CHAT_CODE_PICK_USERNAME "code_001" //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_INVALID_USERNAME "code_003" //haha
#define WHY2_CHAT_CODE_LIST_SERVER "code_004" //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_PM_SERVER "code_006" //SAME AS WHY2_CHAT_CODE_PM BUT BACK TO THE CLIENT
#define WHY2_CHAT_CODE_ENTER_PASSWORD "code_007" //RECEIVE PASSWORD FROM USER
#define WHY2_CHAT_CODE_INVALID_PASSWORD "code_008"//🌸ꗥ~ꗥ🌸 𝐢 𝐡𝐚𝐭𝐞 𝐲𝐨𝐮 🌸ꗥ~ꗥ🌸
//(CLIENT -> SERVER) CODES
#define WHY2_CHAT_CODE_EXIT "CS1" //TELL SERVER YOU ARE ENDING COMMUNICATION
#define WHY2_CHAT_CODE_LIST "CS2" //TELL SERVER TO GIVE YOU ALL CONNECTED USERS
#define WHY2_CHAT_CODE_DM "CS3" //TELL SERVER TO SEND MESSAGE ONLY TO SPECIFIC ID
#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
#define WHY2_CHAT_CODE_EXIT "code_999" //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_PM "code_997" //TELL SERVER TO SEND MESSAGE ONLY TO SPECIFIC ID
#define WHY2_CHAT_CODE_VERSION "code_996" //TELL SERVER TO GIVE YOU ITS VERSION
//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?

View File

@ -23,27 +23,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
extern "C" {
#endif
#include <why2/flags.h>
#include <why2/flags.h> //TODO: fuck this
#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_code(char *params, char *username, int socket, char *code); //SEND SOCKET BUT WITH CODE
void *why2_communicate_thread(void *arg); //COMMUNICATION THREAD
void *why2_authority_communicate_thread(void *arg); //CA COMMUNICATION THREAD
void *why2_accept_thread(void *params); //LOOP ACCEPTING CONNECTIONS
void *why2_accept_thread(void *socket); //LOOP ACCEPTING CONNECTIONS
void why2_clean_connections(void); //CLOSE EVERY CONNECTION
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_authority(void *socket); //LISTEN TO AUTHORITY
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

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_TEXT = 4, //EXIT VALUE FOR INVALID TEXT
WHY2_DOWNLOAD_FAILED = 2, //EXIT VALUE FOR versions.json DOWNLOAD FAILED
WHY2_UPDATE_FAILED = 3 //EXIT VALUE FOR UPDATE FAILED
WHY2_WHY2_UPDATE_FAILED = 3 //EXIT VALUE FOR UPDATE FAILED
};

View File

@ -34,9 +34,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
enum CONFIG_TYPES
{
CLIENT,
SERVER,
SERVER_USERS,
AUTHORITY
SERVER
};
void init_config(char *filename)
@ -80,7 +78,7 @@ void init_config(char *filename)
why2_deallocate(buffer);
}
char *config_path(enum CONFIG_TYPES type)
char *config(char *key, enum CONFIG_TYPES type)
{
char *path = NULL;
@ -94,27 +92,11 @@ char *config_path(enum CONFIG_TYPES type)
path = why2_replace(WHY2_CONFIG_DIR "/" WHY2_CHAT_CONFIG_SERVER, "{HOME}", getenv("HOME"));
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:
why2_die("CONFIG_TYPE not implemented!");
break;
}
return path;
}
char *config(char *key, enum CONFIG_TYPES type)
{
//GET CONFIGURATION PATH
char *path = config_path(type);
//VALUE
char *value = why2_toml_read(path, key);
@ -155,19 +137,6 @@ void why2_chat_init_client_config(void)
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)
{
return config(key, SERVER);
@ -180,24 +149,5 @@ char *why2_chat_client_config(char *key)
char *why2_get_server_users_path(void)
{
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;
return why2_replace(WHY2_CONFIG_DIR "/" WHY2_CHAT_CONFIG_SERVER_USERS, "{HOME}", getenv("HOME"));
}

View File

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

View File

@ -15,6 +15,4 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
auto_connect = false # Automatic connection to 'auto_connect_ip'
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
auto_connect_ip = "109.123.243.163" # See 'auto_connect'

View File

@ -126,48 +126,6 @@ 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]
pub extern "C" fn why2_toml_contains(path: *const c_char, key: *const c_char) -> bool
{

View File

@ -24,15 +24,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <unistd.h>
#include <sys/stat.h>
#include <why2/memory.h>
#include <why2/misc.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/ec.h>
#include <why2/encrypter.h>
#include <why2/memory.h>
#include <why2/misc.h>
EVP_PKEY *keypair = NULL; //KEYPAIR
//LOCAL
@ -73,8 +72,8 @@ char *base64_decode(char *encoded_message, size_t *length)
BIO *bio;
BIO *b64;
char *separator_ptr = strrchr(encoded_message, WHY2_CHAT_BASE64_LENGTH_DELIMITER); //GET THE DELIMITER POINTER
size_t length_local = strtoull(separator_ptr + 1, NULL, 10);
char* decoded_message = why2_malloc(length_local + 1);
*length = strtoull(separator_ptr + 1, NULL, 10);
char* decoded_message = why2_malloc(*length + 1);
int decoded_length;
//INIT BIOs
@ -84,7 +83,7 @@ char *base64_decode(char *encoded_message, size_t *length)
bio = BIO_push(b64, bio);
//DECODE
decoded_length = BIO_read(bio, decoded_message, length_local);
decoded_length = BIO_read(bio, decoded_message, *length);
//NULL-TERM
decoded_message[decoded_length] = '\0';
@ -92,29 +91,9 @@ char *base64_decode(char *encoded_message, size_t *length)
//DEALLOCATION
BIO_free_all(bio);
//SET length
if (length != NULL) *length = length_local;
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
void why2_chat_init_keys(void)
{
@ -210,110 +189,18 @@ why2_bool why2_chat_ecc_verify_signature(char *message, char *signature, EVP_PKE
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)
{
//DEALLOCATE THE pkey
EVP_PKEY_free(keypair);
}
char *why2_sha256(char *input, size_t length)
char *why2_sha256(char *input)
{
unsigned char *output = why2_malloc(SHA256_DIGEST_LENGTH + 1);
char *formatted_output = why2_malloc(SHA256_DIGEST_LENGTH * 2 + 2);
SHA256((unsigned char*) input, length, output);
SHA256((unsigned char*) input, strlen(input), output);
//SAVE AS STRING IN HEX
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)

View File

@ -1,89 +0,0 @@
/*
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,7 +20,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@ -109,30 +108,10 @@ int main(void)
pthread_t thread_getline;
why2_bool ssqc = 0;
char *cmd_arg = NULL;
why2_bool *ca_success;
//DEFINE CONNECTION PROPERTIES
//DEFINE SERVER ADDRESS
struct sockaddr_in server_addr;
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);
//GET IP
@ -169,7 +148,9 @@ int main(void)
free(line); //PREVENT FROM MEMORY LEAK
if (connect(listen_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) why2_die("Connecting failed."); //CONNECT
int connectStatus = connect(listen_socket, (WHY2_SA *) &server_addr, sizeof(server_addr)); //CONNECT
if (connectStatus < 0) why2_die("Connecting failed.");
pthread_create(&thread_buffer, NULL, why2_listen_server, &listen_socket); //LISTEN TO OTHER USERS
@ -263,7 +244,7 @@ int main(void)
char *final_message = why2_malloc(strlen(id) + strlen(msg) + 2);
sprintf(final_message, "%s;%s%c", id, msg, '\0');
why2_send_socket_code(final_message, NULL, listen_socket, WHY2_CHAT_CODE_DM); //SEND
why2_send_socket_code(final_message, NULL, listen_socket, WHY2_CHAT_CODE_PM); //SEND
//DEALLOCATION
why2_deallocate(id);
@ -285,7 +266,7 @@ int main(void)
//REMOVE \n AT THE END OF line
line[strlen(line) - 1] = '\0';
char *hash = why2_sha256(line, strlen(line)); //HASHISH
char *hash = why2_sha256(line); //HASHISH
why2_send_socket(hash, NULL, listen_socket); //SEND BUT HASHED

View File

@ -51,15 +51,14 @@ int main(void)
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.");
if (bind(listen_socket, (WHY2_SA *) &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("Server enabled.\n\n");
__why2_accept_thread_params params = { listen_socket, WHY2_CHAT_SERVER };
pthread_create(&thread, NULL, why2_accept_thread, &params);
pthread_create(&thread, NULL, why2_accept_thread, &listen_socket);
for (;;)
{

View File

@ -31,7 +31,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <json-c/json.h>
#include <why2/chat/config.h>
#include <why2/chat/crypto.h>
#include <why2/chat/flags.h>
#include <why2/llist.h>
@ -766,7 +765,7 @@ void *why2_communicate_thread(void *arg)
//DEALLOCATION
why2_deallocate(message);
} else if (strcmp(decoded_code_buffer, WHY2_CHAT_CODE_DM) == 0 && decoded_buffer != NULL && strlen(decoded_buffer) != 0) //PM
} else if (strcmp(decoded_code_buffer, WHY2_CHAT_CODE_PM) == 0 && decoded_buffer != NULL && strlen(decoded_buffer) != 0) //PM
{
char *id = NULL; //RECEIVER
char *msg;
@ -815,8 +814,8 @@ void *why2_communicate_thread(void *arg)
why2_bool self_pm = pm_connection_node.connection == connection;
//SEND YOU DUMB FUCK
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_DM_SERVER); //AUTHOR
send_socket_code_deallocate(private_msg, why2_chat_server_config("server_username"), pm_connection_node.connection, WHY2_CHAT_CODE_PM_SERVER); //RECIPIENT
if (!self_pm) send_socket_code_deallocate(private_msg, why2_chat_server_config("server_username"), connection, WHY2_CHAT_CODE_PM_SERVER); //AUTHOR
why2_deallocate(private_msg);
}
@ -866,125 +865,19 @@ void *why2_communicate_thread(void *arg)
return NULL;
}
void *why2_authority_communicate_thread(void *arg)
void *why2_accept_thread(void *socket)
{
//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;
pthread_t thread;
//LOOP ACCEPT
for (;;)
{
accepted = accept(param.socket, (struct sockaddr *) NULL, NULL); //ACCEPT NEW SOCKET
accepted = accept(*((int*) socket), (WHY2_SA *) NULL, NULL); //ACCEPT NEW SOCKET
if (accepted == -1) continue;
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);
pthread_create(&thread, NULL, why2_communicate_thread, &accepted);
}
return NULL;
@ -1134,7 +1027,7 @@ void *why2_listen_server(void *socket)
{
printf("Server is outdated. Some new features may not work correctly.\n\n");
}
} else if (strcmp(code, WHY2_CHAT_CODE_DM_SERVER) == 0)
} else if (strcmp(code, WHY2_CHAT_CODE_PM_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
@ -1226,88 +1119,6 @@ void *why2_listen_server(void *socket)
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)
{
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");
why2_clean_memory("core_version_check");
return WHY2_UPDATE_FAILED;
return WHY2_WHY2_UPDATE_FAILED;
}
//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");
why2_clean_memory("core_version_check");
return WHY2_UPDATE_FAILED;
return WHY2_WHY2_UPDATE_FAILED;
}
//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");
why2_clean_memory("core_version_check");
return WHY2_UPDATE_FAILED;
return WHY2_WHY2_UPDATE_FAILED;
}
} else
{