Compare commits

...

150 Commits

Author SHA1 Message Date
3fa15f5ebb
changed ascii range 2024-08-31 16:25:36 +02:00
37a615cb03
got rid of the dumbass goto in read_socket_raw
and possibly created 10 new problems :))
2024-08-31 16:22:34 +02:00
981dec55db
moved is_ascii to separate fn 2024-08-31 16:11:58 +02:00
f7982d4d4a
moved removing non-ascii chars to fn 2024-08-31 16:01:04 +02:00
a9fd0596e5
creating user config on server startup
if user_pick_username is set to true
2024-08-31 14:44:08 +02:00
ada457c824
created macro for server-user config file 2024-08-31 13:20:44 +02:00
48208d0991
fixed double memory leak in init_config fn 2024-08-31 13:02:32 +02:00
b385187d39
added the why2_toml_contains fn to config header 2024-08-31 12:46:12 +02:00
446727b87c
created rust fn for checking if toml contains key 2024-08-31 12:44:15 +02:00
7be5d6ff32
added the why2_toml_write fn to config header 2024-08-31 12:36:52 +02:00
690d979124
created rust fn for writing into toml 2024-08-31 12:36:36 +02:00
f539a4bd71
displaying welcome message on client 2024-08-30 15:06:04 +02:00
329c3c9cd2
added missing why2_directory call to why2_check_version 2024-08-30 15:01:27 +02:00
c28765a4c8
sending server_name in welcome packet 2024-08-30 14:51:27 +02:00
875a1b8ac2
removed useless json syntax checks
its useless since I added check to read_socket_raw
2024-08-30 14:46:45 +02:00
184e71c899
added server_name to server config 2024-08-30 14:40:28 +02:00
972619bafa
fixed server-side pm buffer overflow 2024-08-30 14:31:14 +02:00
17f1329325
removed unused debug stuff 2024-08-30 14:30:55 +02:00
9fd9a4b233
resolving self-pm at client-side :))
haha def no easteregg
2024-08-30 14:12:15 +02:00
809d40ab2e
not sending two packets on self-pm 2024-08-30 13:57:26 +02:00
8bd3df1ae1
added json format validation to read_socket_raw 2024-08-30 13:41:01 +02:00
3fc339a9fb
fully implemented new WHY2_CONFIG_DIR
i moved it to user folder cause it causes permission problems on multi-user machine.
2024-08-30 00:54:17 +02:00
8ef39ada5f
changed WHY2_VERSIONS_NAME 2024-08-30 00:49:45 +02:00
e802f5f483
moved why2_dir from init_config to why2_directory fn 2024-08-30 00:47:52 +02:00
db1d487a2e
moved WHY2_CONFIG_DIR to core-flags 2024-08-30 00:44:38 +02:00
04d411e42a
declared why2_dir fn 2024-08-30 00:42:40 +02:00
ca97b45059
solved infinite loop in read_socket_raw
by the worst possible solution but yeahhh
2024-08-30 00:31:59 +02:00
d12936d1d0
showing pm to both users 2024-08-30 00:23:49 +02:00
2e5e9682a3
decoding pm from end-user 2024-08-30 00:21:59 +02:00
8fcddab726
sending both author and recipient in pm 2024-08-30 00:21:35 +02:00
2d5a18d667
added infinite loop todo
i mean yk, it works but its shit
2024-08-29 23:35:46 +02:00
af233c44ef
sending pm back to end user on server-side 2024-08-28 21:53:19 +02:00
2cc3cd0b78
sending pm back to end user on server-side 2024-08-28 21:52:15 +02:00
3314a82b3a
sending pm to server 2024-08-28 21:24:32 +02:00
456b523012
created WHY2_CHAT_CODE_PM_SERVER code 2024-08-28 14:00:24 +02:00
290ad5c101
moved invalid command/stuff into fn 2024-08-28 13:48:45 +02:00
854e8399fb
trimming string on command fn 2024-08-28 13:48:18 +02:00
7647be3daf
starting IDs from 1 instead of 0
atoi returns 0 in failure, meaning all typos would send PMs to first user
2024-08-28 13:38:17 +02:00
963e75da51
clearing arg on command 2024-08-28 13:21:33 +02:00
66ceb25a89
comment typo fix 2024-08-28 12:59:43 +02:00
0dfd0218e1
added version and pm cmd to help 2024-08-28 12:59:09 +02:00
64773d1f30
implemented version cmd receive half on client-side 2024-08-28 12:45:48 +02:00
41bbfc2b18
reverted the demented why2_get_version 2024-08-28 12:44:33 +02:00
6adf4a391a
removed stupid get_version
im so fucking dumb... i was sending latest why2 verison instead of current
2024-08-28 12:40:30 +02:00
1735da3807
moved why2_get_version string extraction to get_version 2024-08-28 12:21:59 +02:00
ef235e48f7
created server-side code for version command
sending the version back to client
2024-08-28 12:13:59 +02:00
e30e2dea59
created WHY2_CHAT_CODE_VERSION_SERVER code 2024-08-28 12:07:32 +02:00
e5e6460908
changed comment of get_version 2024-08-28 11:58:47 +02:00
debf90e5d2
implemented why2_get_version in why2_check_version 2024-08-28 11:55:29 +02:00
b92ed3d6a8
declared why2_get_version 2024-08-28 11:48:52 +02:00
f20550dec6
removed chat why2_check_version error todo
lol i def have clue why it works now
2024-08-28 11:46:51 +02:00
a4ec91979e
implemented send part of version cmd on client-side 2024-08-28 11:43:50 +02:00
de4b6a39bf
being correct with user pronouns 2024-08-28 11:42:13 +02:00
a5b6364c26
checking version on chat client&server startup 2024-08-28 11:39:01 +02:00
54b4ebe3e6
created version cmd and code
also added missing comments to codes
2024-08-28 11:35:09 +02:00
5442104f35
added list cmd to help 2024-08-28 11:24:13 +02:00
e18ce453be
comment typo fix 2024-08-28 11:21:08 +02:00
59ae168b15
added so pretty way of getting dynamic size of received msg
god damn it, its awesome. Also, I should get rid of the goto in there, that's stupid lol. Gonna do it tmrw ig
2024-08-27 22:42:45 +02:00
aad627b77a
created PM code 2024-04-28 15:25:43 +02:00
d539654cc3
handling LIST code sent back from server 2024-04-28 12:38:34 +02:00
e50184ad66
sedning one separator more on LIST code 2024-04-28 12:37:24 +02:00
bc14effeee
responding to LIST code from client
oh dear satan, this is possibly the worst code I have ever written. Please, if anyone has any idea how to handle strings in C in better ways, let me know.
2024-04-28 11:50:59 +02:00
cd80a640af
created LIST code but from s->c 2024-04-28 11:49:51 +02:00
c37538aa75
defined why2_list_get_size
not sure if this is correct lol

EDIT: It didn't work. I fixed it now lmao
2024-04-27 12:26:56 +02:00
c4ddb6888a
declared why2_list_get_size fn 2024-04-27 12:18:07 +02:00
97ba473143
removed INVALID_COMMAND code
it was unused atp
2024-04-27 12:01:49 +02:00
cfa9f7bcca
implemented WHY2_CHAT_COMMAND_PREFIX on server-side 2024-04-27 11:58:01 +02:00
4134f9d1b3
implemented LIST command in client
not in server yet haha
2024-04-27 11:49:00 +02:00
1b4401f944
created WHY2_CHAT_COMMAND_LIST macro 2024-04-27 11:47:04 +02:00
37b1a3a82d
changed code_998 to CODE_LIST 2024-04-27 11:43:53 +02:00
0150414d1b
optimized client command checking 2024-04-27 11:42:15 +02:00
26c5b4d831
implemented the command handler 2024-04-27 11:33:00 +02:00
e9b439884f
created command handler in client 2024-04-27 11:32:52 +02:00
f325b928eb
trimming client input text 2024-04-25 21:15:59 +02:00
f07a5fe40f
moved trim_string to header file 2024-04-25 20:52:09 +02:00
e6c570c2c7
prepared trim_string for non-why2-allocated strings 2024-04-20 11:32:18 +02:00
65135ac961
created why2_allocated fn
checks for why2-mem allocation
2024-04-20 11:22:09 +02:00
19ccc45e0a
created pm code 2024-04-19 20:09:23 +02:00
07a4eecd4e
removed the stupid exit command sending
using codes instead
2024-04-19 20:03:20 +02:00
d451030ad0
handling sigint signal
i'm really trying alex, i am

wicked game
2024-04-19 16:32:44 +02:00
e023207261
added help command 2024-04-19 16:08:54 +02:00
1fc78a2a30
sending server exit_cmd with the initial welcome message 2024-04-17 18:04:45 +02:00
c98184f1f5
created exit_cmd getter & setter 2024-04-17 18:03:40 +02:00
b2c945fe6d
implemented the exit_cmd macro 2024-04-17 17:45:21 +02:00
b2ca56e927
created WHY2_CHAT_COMMAND_EXIT macro
also the prefix
2024-04-17 17:43:25 +02:00
99c76285a2
added ID to connection node 2024-04-17 17:25:55 +02:00
f1fd7c07ea
fixed linked list linkage problems
First of all, is linkage even a word? :D Second thing, I am so fucking stupid...
2024-04-17 17:22:44 +02:00
586df77ff4
revert "added configure script source todo"
reverts commit abd8645ab06374a345f1698c313e3c6bfc363ed7.

turns out it breaks workflows
2024-04-13 17:19:07 +02:00
22e03ca06e
fixed base bug in exp_mod fn 2024-04-13 14:20:52 +02:00
6227b8eb0a
changed WHY2_CHAT_RSA_EXPONENT base to 62
so now it isn't 65537 but H33
2024-04-13 14:20:26 +02:00
d9483f02ca
fixed rsa crypto input strings & output base 2024-04-13 13:45:40 +02:00
9cf062565a
created why2_chat_rsa_pri_decrypt 2024-04-13 13:40:26 +02:00
2a9df2a4b9
moved why2_chat_rsa_pub_encrypt body into exp_mod
so in next commit, which will be decryption, I won't kms
2024-04-13 13:38:14 +02:00
b74995bbab
changed WHY2_CHAT_RSA_EXPONENT datatype to string 2024-04-13 13:37:06 +02:00
6487ea8b85
defined why2_chat_rsa_pub_encrypt
pog
2024-04-13 13:30:52 +02:00
ee3f319dd7
implemented why2_chat_deallocate_keys in client 2024-04-13 13:17:03 +02:00
62d2f10e65
declared why2_chat_rsa_pub_encrypt 2024-04-13 13:15:26 +02:00
5bd948c8a0
switched fopen for why2_fopen in crypto
whoopsie
2024-04-13 13:09:54 +02:00
60b437d4e8
implemented why2 crypto getters
bit fucked the file
2024-04-13 13:08:44 +02:00
8f3af8c7d1
defined why2_get_chat* rsa stuff fns 2024-04-13 12:32:43 +02:00
bb8436badd
added body for why2_chat_deallocate_keys 2024-04-13 12:32:19 +02:00
2755472534
declared why2_get_chat* rsa stuff fns 2024-04-13 12:28:50 +02:00
2f4c73ce09
created why2_chat_deallocate_keys fn 2024-04-13 12:26:47 +02:00
ef1f9bbf38
renamed why2_chat_generate_keys to why2_chat_init_keys
I think the name is much more self-explanatory now
2024-04-13 12:24:19 +02:00
abd8645ab0
added configure script source todo 2024-04-13 12:19:32 +02:00
274a3e1772
revert "sending ssqc on every message loop end"
this reverts commit b14c8de7105a9f570a227ce7f8608103b205eca9

it seems that I created the check for some reason
2024-02-26 15:19:41 +01:00
850ab11272
using latest toml version in rust module 2024-02-25 20:54:17 +01:00
4d6b29e4c6
implemented max_message_length in message loop 2024-02-25 20:34:18 +01:00
13d4e2f480
created max_message_length in server cfg 2024-02-25 20:25:38 +01:00
b14c8de710
sending ssqc on every message loop end 2024-02-25 14:23:53 +01:00
22282623af
implemented trim_string in message loop 2024-02-25 13:16:12 +01:00
157d56ac57
not disconnecting user on null message 2024-02-25 13:15:54 +01:00
47fd5f01b6
created trim_string fn 2024-02-25 13:15:29 +01:00
a141065189
addded null check to why2_deallocate 2024-02-25 12:25:29 +01:00
0abd38e877
fixed byte format overflowing
yippee
2024-02-24 21:56:43 +01:00
9734749c3e
implemented WHY2_OUTPUT_BYTE in decrypter
i choose literally the worst approach but YEAH...

...it doesn't work...

...it overflows...
2024-02-24 21:05:09 +01:00
226f9b3759
preventing encrypted bytes from being zero 2024-02-24 19:51:51 +01:00
23f7019883
defined why2_byte_format_length 2024-02-24 16:57:23 +01:00
bf64d848c7
declared why2_byte_format_length fn
you pass in string created using byte format and it returns the length of it
2024-02-24 16:55:10 +01:00
89d721fa9d
implemented WHY2_OUTPUT_BYTE in encrypter output 2024-02-24 12:52:06 +01:00
773591d452
implemented WHY2_OUTPUT_TEXT in encrypter 2024-02-24 12:48:38 +01:00
782e964fa2
made decrypter variables snake_case 2024-02-24 11:56:05 +01:00
58327f3046
made encrypter variables snake_case 2024-02-24 11:55:56 +01:00
21900e27cb
made encrypt & decrypt fn parameters snake_case 2024-02-24 11:51:31 +01:00
06ae819a82
added the WHY2_OUTPUT_TEXT enum to every why2_input_flags usage 2024-02-23 20:36:27 +01:00
3ef929665a
added WHY2_OUTPUT_FORMAT enum to why2_input_flags
you can basically specify if you want the "69.-420" output or you want messy string where each character is one output number iykwim
2024-02-23 20:33:37 +01:00
cb15d856de
why2_chat_generate_keys grammar fix
yessir i am an english-man fr fr
2024-02-23 20:27:00 +01:00
4564e2b63b
using base 62 for key save 2024-02-23 15:49:22 +01:00
836d3ec44a
implemented WHY2_CHAT_KEY_BASE macro 2024-02-23 11:55:29 +01:00
09a326a067
created WHY2_CHAT_KEY_BASE macro 2024-02-23 11:55:07 +01:00
4397122aaf
writing the rsa keys out 2024-02-23 11:47:33 +01:00
6ede019547
created pub & pri key location macros 2024-02-23 11:11:35 +01:00
923b9907db
renamed WHY2_CHAT_PUB_KEY_LOCATION to WHY2_CHAT_KEY_LOCATION 2024-02-23 11:08:19 +01:00
c89ae6c884
implemented WHY2_CHAT_RSA_EXPONENT in why2_chat_generate_keys 2024-02-23 11:04:21 +01:00
8599b06495
created WHY2_CHAT_RSA_EXPONENT macro
i mean it is convention AND it will make my life so much fucking easier
2024-02-23 11:03:53 +01:00
0c03ed3785
added key dir check into why2_chat_generate_keys 2024-02-23 10:59:38 +01:00
0e2da6ccb7
created WHY2_CHAT_PUB_KEY_LOCATION macro
contains path to key dir
2024-02-23 10:50:28 +01:00
1e925ec794
implemented why2_chat_generate_keys in client 2024-02-23 10:35:22 +01:00
c450adb0a8
added config init comments 2024-02-23 10:34:04 +01:00
f1a8e11ed1
using libgmp in makefile 2024-02-23 10:29:20 +01:00
55550e4ea4
defined why2_chat_generate_keys fn
and guess what! it doesn't save the keys, yet :dd
2024-02-23 10:27:00 +01:00
df4f7aae7d
created generate_prime fn
it uses gmp 😎
2024-02-23 10:25:07 +01:00
2beb4401ee
created WHY2_CHAT_PRIME_ITERS macro 2024-02-23 10:20:47 +01:00
9007dce4fd
created WHY2_CHAT_KEY_BITS macro 2024-02-23 10:14:50 +01:00
35f4b0447a
declered why2_chat_generate_keys fn 2024-02-23 10:13:47 +01:00
b1add93eca
added gmp dependency 2024-02-23 10:10:16 +01:00
07c82120dd
added unsupported distro dependency array 2024-02-23 09:52:33 +01:00
c294be679b
updated unsupported distro message formatting 2024-02-23 09:45:03 +01:00
13dff8514d
created crypto files 2024-02-23 09:40:34 +01:00
8fe73fafe9
implemented getrandom instead of rand
also made why2_generate_key's variables snake_case
2024-02-22 22:05:12 +01:00
31 changed files with 1314 additions and 308 deletions

View File

@ -59,7 +59,7 @@ TEST_LOGGER=./src/logger/lib/test/main.c
LIBS_LOGGER=$(LIB_CORE)
LIB_LOGGER=-l$(PROJECT_NAME)-logger
LIBS_LIB_CHAT=$(LIB_CORE) -lpthread
LIBS_LIB_CHAT=$(LIB_CORE) -lpthread -lgmp
LIB_CHAT=-l$(PROJECT_NAME)-chat
LIB_CHAT_CONFIG=$(LIB_CHAT)-config
LIBS_CHAT=$(LIB_CHAT) $(LIBS_LIB_CHAT) $(LIB_CHAT_CONFIG)

View File

@ -25,13 +25,13 @@ if [[ $(id -u) != "0" ]] && [[ $1 != "force" ]]; then
fi
COMMON="gcc make tmux curl"
ARCH_GENTOO_COMMON="$COMMON json-c libgit2"
ARCH_GENTOO_COMMON="$COMMON json-c libgit2 gmp"
# Get COMMAND
if [[ $DISTRO == "Arch" ]]; then
COMMAND="pacman -S --needed --noconfirm $ARCH_GENTOO_COMMON"
elif [[ $DISTRO == "Ubuntu" ]] || [[ $DISTRO == "Debian" ]]; then
COMMAND="apt install -y $COMMON libjson-c-dev libcurl4-nss-dev libgit2-dev"
COMMAND="apt install -y $COMMON libjson-c-dev libcurl4-nss-dev libgit2-dev libgmp-dev"
elif [[ $DISTRO == "Gentoo" ]]; then
COMMAND="emerge -vn $ARCH_GENTOO_COMMON"
@ -41,9 +41,18 @@ elif [[ $DISTRO == "Gentoo" ]]; then
echo "LDPATH=/usr/lib/libwhy2-chat.so" > /etc/env.d/99why2-chat
echo "LDPATH=/usr/lib/libwhy2-chat-config.so" > /etc/env.d/99why2-chat-config
env-update && source /etc/profile
else
# 'Unsupported' distro
echo "It seems you are using unsupported distribution... Don't worry, just install 'gcc', 'json-c', 'curl', 'libgit2', 'tmux' and 'make' and you'll be fine."
else # 'Unsupported' distro
IFS=' ' read -r -a dependency_array <<< "$ARCH_GENTOO_COMMON" # Split into dependency_array
echo -e "It seems you are using unsupported distribution...\nDon't worry, just install these dependencies:\n"
for dependency in "${dependency_array[@]}" # Iter
do
echo "$dependency"
done
echo -e "\nand you'll be fine."
exit
fi

View File

@ -23,17 +23,20 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
extern "C" {
#endif
#include <why2/flags.h> //damn i really hate including headers in headers
//CONFIG MACROS
#define WHY2_CONFIG_DIR "/home/{USER}/.config"
#define WHY2_CHAT_CONFIG_DIR WHY2_CONFIG_DIR "/WHY2"
#define WHY2_CHAT_CONFIG_URL "https://raw.githubusercontent.com/ENGO150/WHY2/development/src/chat/config/"
#define WHY2_CHAT_CONFIG_SERVER "server.toml"
#define WHY2_CHAT_CONFIG_CLIENT "client.toml"
#define WHY2_CHAT_CONFIG_SERVER_USERS "server_users.toml" //LOGIN INFO CONFIG
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. ...
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
why2_bool why2_toml_contains(const char *path, const char *key); //CHECK IF path CONTAINS key
void why2_toml_read_free(char* s); //DEALLOCATE THE READ VALUE
char *why2_chat_server_config(char *key); //why2_toml_read BUT YOU DO NOT HAVE TO INCLUDE path

51
include/chat/crypto.h Normal file
View File

@ -0,0 +1,51 @@
/*
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/>.
*/
#ifndef WHY2_CHAT_CRYPTO_H
#define WHY2_CHAT_CRYPTO_H
#ifdef __cplusplus
extern "C" {
#endif
#include <why2/chat/config.h>
//MACROS
#define WHY2_CHAT_KEY_BITS 4096 //BITS..
#define WHY2_CHAT_PRIME_ITERS 100 //NUMBER OF ITERATIONS WHEN CHECKING PRIME NUMBER
#define WHY2_CHAT_RSA_EXPONENT "H33" //DEFAULT e IN BASE WHY2_CHAT_KEY_BASE
#define WHY2_CHAT_KEY_LOCATION WHY2_CONFIG_DIR "/keys" //KEYS LOCATION
#define WHY2_CHAT_PUB_KEY "pub"
#define WHY2_CHAT_PRI_KEY "pri"
#define WHY2_CHAT_KEY_BASE 62 //BASE IN THE GENERATED KEYS ARE STORED IN WHY2_CHAT_KEY_LOCATION
void why2_chat_init_keys(void); //INIT (POSSIBLY GENERATE) RSA KEYS
void why2_chat_deallocate_keys(void); //DEALLOCATE :) (NO SLUR HERE)
char *why2_get_chat_modulus(void); //GET THE RSA MODULUS
char *why2_get_chat_d(void); //GET THE RSA d
char *why2_chat_rsa_pub_encrypt(char *to_encrypt); //RSA ENCRYPT USING PUBLIC KEY
char *why2_chat_rsa_pri_decrypt(char *to_decrypt); //RSA DECRYPT USING PRIVATE KEY
#ifdef __cplusplus
}
#endif
#endif

View File

@ -32,16 +32,35 @@ extern "C" {
#define WHY2_INVALID_POINTER (void*) 0xffffffffffffffff
//CODES
#define WHY2_CHAT_CODE_ACCEPT_MESSAGES "code_000"
#define WHY2_CHAT_CODE_PICK_USERNAME "code_001"
#define WHY2_CHAT_CODE_SERVER_SIDE_QUIT_COMMUNICATION "code_002"
#define WHY2_CHAT_CODE_INVALID_COMMAND "code_003"
#define WHY2_CHAT_CODE_INVALID_USERNAME "code_004"
//(SERVER -> CLIENT) CODES
#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
//(CLIENT -> SERVER) CODES
#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?
#define WHY2_CHAT_COMMAND_EXIT "exit" //QUIT THE PROGRAM CMD
#define WHY2_CHAT_COMMAND_HELP "help" //PRINT ALL COMMANDS
#define WHY2_CHAT_COMMAND_LIST "list" //LIST ALL CONNECTIONS
#define WHY2_CHAT_COMMAND_PM "pm" //PRIVATE MESSAGES
#define WHY2_CHAT_COMMAND_VERSION "version" //COMPARE CLIENT VERSION AND SERVER VERSION
//SHORTCUTS CAUSE I'M LAZY BITCH
#define WHY2_CHAT_CODE_SSQC WHY2_CHAT_CODE_SERVER_SIDE_QUIT_COMMUNICATION
char *why2_chat_client_get_server_exit_cmd(); //GETTER AND SETTER FOR !exit FROM SERVER
void why2_chat_client_set_server_exit_cmd(char *cmd);
#ifdef __cplusplus
}
#endif

View File

@ -32,6 +32,7 @@ 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_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
#ifdef __cplusplus
}

View File

@ -25,7 +25,7 @@ extern "C" {
#include <why2/flags.h>
why2_output_flags why2_decrypt_text(char *text, char *keyNew); //TEXT from WILL BE DECRYPTED WITH KEY AND RETURNED
why2_output_flags why2_decrypt_text(char *text, char *key_new); //TEXT from WILL BE DECRYPTED WITH KEY AND RETURNED
#ifdef __cplusplus
}

View File

@ -25,7 +25,7 @@ extern "C" {
#include <why2/flags.h>
why2_output_flags why2_encrypt_text(char *text, char *keyNew); //TEXT from WILL BE ENCRYPTED WITH KEY AND RETURNED
why2_output_flags why2_encrypt_text(char *text, char *key_new); //TEXT from WILL BE ENCRYPTED WITH KEY AND RETURNED
#ifdef __cplusplus
}

View File

@ -37,14 +37,21 @@ enum WHY2_EXIT_CODES //exit codes you fucking idiot
//THESE ARE 'HISTORIC' VERSION FOR GENERATING tkch, SO YOU CAN DECRYPT OLD TEXT
enum WHY2_TEXT_KEY_CHAIN_VERSIONS
{
WHY2_v1, //FIRST VERSION. Replaced on May 28th 17:45:26 2022 UTC in commit 0d64f4fa7c37f0b57914db902258e279a71c7f9a. GOOD OLD TIMES. OR NOT. IT REMINDS ME OF HER. this shit hurts, man
WHY2_v1, //FIRST VERSION. Replaced on May 28th 17:45:26 2022 UTC in commit 0d64f4fa7c37f0b57914db902258e279a71c7f9a.
WHY2_v2, //SECOND VERSION. Replaced on July 11th 17:12:41 2022 UTC in commit 0f01cde0f1e1a9210f4eef7b949e6d247072d3a6.
WHY2_v3 //THIRD VERSION. THE LATEST ONE
};
enum WHY2_OUTPUT_FORMAT
{
WHY2_OUTPUT_TEXT,
WHY2_OUTPUT_BYTE
};
#define WHY2_VERSION "v5.0" //WHY2_VERSION OF CURRENT BUILD > DO NOT TOUCH THIS <
#define WHY2_VERSIONS_URL "https://raw.githubusercontent.com/ENGO150/WHY2/release/versions.json" //URL FOR GETTING versions.json
#define WHY2_VERSIONS_NAME "/tmp/why2-versions.json" //do I have to explain this?
#define WHY2_CONFIG_DIR "/home/{USER}/.config/WHY2"
#define WHY2_VERSIONS_NAME WHY2_CONFIG_DIR "/.versions.json" //do I have to explain this?
#define WHY2_UPDATE_URL "https://github.com/ENGO150/WHY2.git" // REPOSITORY URL FOR UPDATES (YOU DON'T SAY)
#define WHY2_UPDATE_NAME "/tmp/why2-update" // fuck you
@ -71,6 +78,7 @@ typedef struct
why2_bool no_output; //BOOLEAN FOR NOT PRINTING OUTPUT WHEN ENCRYPTING/DECRYPTING
why2_bool update; //BOOLEAN FOR UPDATING YOUR WHY WHY2_VERSION IF OLD IS USED
enum WHY2_TEXT_KEY_CHAIN_VERSIONS version; //VERSION OF tkch
enum WHY2_OUTPUT_FORMAT format; //VERSION OF tkch
} why2_input_flags;
typedef struct

View File

@ -43,6 +43,7 @@ void why2_list_push(why2_list_t *list, void *value, unsigned long size); //PUSH
void why2_list_remove(why2_list_t *list, why2_node_t *node); //REMOVE ELEMENT
void why2_list_remove_back(why2_list_t *list); //REMOVE LAST ELEMENT
why2_node_t *why2_list_find(why2_list_t *list, void *value); //FIND ELEMENT IN LIST
unsigned long why2_list_get_size(why2_list_t *list); //GET SIZE
#ifdef __cplusplus
}

View File

@ -23,6 +23,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
extern "C" {
#endif
#include <why2/flags.h>
void *why2_malloc(unsigned long size);
void *why2_calloc(unsigned long element, unsigned long size);
void *why2_realloc(void *pointer, unsigned long size);
@ -37,6 +39,8 @@ void why2_deallocate(void *pointer);
void why2_clean_memory(char *identifier); //identifier SPECIFIES WHICH NODES TO DEALLOCATE | THIS IS BASICALLY GARBAGE COLLECTOR | PASS why2_get_default_memory_identifier() FOR DEALLOCATING EVERYTHING
why2_bool why2_allocated(void *pointer); //CHECKS IF pointer WAS ALLOCATED USING WHY2-MEM
#ifdef __cplusplus
}
#endif

View File

@ -30,6 +30,7 @@ extern "C" {
void why2_generate_text_key_chain(char *key, int *text_key_chain, int text_key_chain_size); //GENERATES ARRAY FOR ENCRYPTION/DECRYPTION
char *why2_generate_key(int key_length); //GENERATE ENCRYPTION KEY
void why2_deallocate_output(why2_output_flags flags); //DEALLOCATES flags
void why2_directory(void); //GENERATE WHY2_CONFIG_DIR
enum WHY2_EXIT_CODES why2_check_version(void); //THIS FUNCTION CHECKS IF LATEST WHY2_VERSION OF WHY2 IS USED
enum WHY2_EXIT_CODES why2_check_key(char *key); //CHECKS IF KEY IS VALID
enum WHY2_EXIT_CODES why2_check_text(char *text); //CHECKS IF TEXT IS VALID
@ -39,6 +40,7 @@ unsigned long why2_count_repeated_key_size(char *text, char *key); //COUNT repea
unsigned long why2_compare_time_micro(struct timeval startTime, struct timeval finishTime); //COMPARE TIMES IN MICROSECONDS
void why2_die(char *exit_message); //PRINTS exit_message ERROR AND EXITS WITH CODE 1
char *why2_replace(char *string, char *old, char *new); //REPLACES old IN string WITH new
unsigned short why2_byte_format_length(char *s); //GET LENGTH OF s OF WHY2_OUTPUT_BYTE FORMAT
#ifdef __cplusplus
}

View File

@ -44,6 +44,7 @@ extern "C" {
//CHAT
#include <why2/chat/config.h>
#include <why2/chat/crypto.h>
#include <why2/chat/flags.h>
#include <why2/chat/misc.h>

View File

@ -39,24 +39,18 @@ enum CONFIG_TYPES
void init_config(char *filename)
{
struct stat st;
char *buffer = why2_replace(WHY2_CONFIG_DIR, "{USER}", getenv("USER"));
//CREATE USER CONFIG FOLDER [THIS SHOULDN'T HAPPEN ON CLIENT, BUT IT'S NEEDED ON FRESH SERVERS]
if (stat(buffer, &st) == -1)
{
mkdir(buffer, 0700);
}
why2_directory();
//GET THE CONFIG TYPE
buffer = why2_realloc(buffer, strlen(WHY2_CHAT_CONFIG_DIR) + strlen(filename) + 2);
sprintf(buffer, "%s/%s", WHY2_CHAT_CONFIG_DIR, filename);
char *buffer = why2_malloc(strlen(WHY2_CONFIG_DIR) + strlen(filename) + 2);
sprintf(buffer, "%s/%s", WHY2_CONFIG_DIR, filename);
char *path = why2_replace(buffer, "{USER}", getenv("USER"));
if (access(path, R_OK) != 0) //CONFIG DOESN'T EXIST
{
char *config_dir = why2_replace(WHY2_CHAT_CONFIG_DIR, "{USER}", getenv("USER"));
char *config_dir = why2_replace(WHY2_CONFIG_DIR, "{USER}", getenv("USER"));
//CREATE CONFIG DIRECTORY
mkdir(config_dir, 0700);
@ -75,11 +69,13 @@ void init_config(char *filename)
//CLEANUP
curl_easy_cleanup(curl);
why2_deallocate(buffer);
why2_deallocate(path);
why2_deallocate(config_dir);
why2_deallocate(file_buffer);
}
//DEALLOCATION
why2_deallocate(path);
why2_deallocate(buffer);
}
char *config(char *key, enum CONFIG_TYPES type)
@ -89,11 +85,11 @@ char *config(char *key, enum CONFIG_TYPES type)
switch (type) //GET path
{
case CLIENT:
path = why2_replace(WHY2_CHAT_CONFIG_DIR "/" WHY2_CHAT_CONFIG_CLIENT, "{USER}", getenv("USER"));
path = why2_replace(WHY2_CONFIG_DIR "/" WHY2_CHAT_CONFIG_CLIENT, "{USER}", getenv("USER"));
break;
case SERVER:
path = why2_replace(WHY2_CHAT_CONFIG_DIR "/" WHY2_CHAT_CONFIG_SERVER, "{USER}", getenv("USER"));
path = why2_replace(WHY2_CONFIG_DIR "/" WHY2_CHAT_CONFIG_SERVER, "{USER}", getenv("USER"));
break;
default:
@ -114,6 +110,26 @@ char *config(char *key, enum CONFIG_TYPES type)
void why2_chat_init_server_config(void)
{
init_config(WHY2_CHAT_CONFIG_SERVER);
//CHECK FOR USER CONFIG
char *user_pick_username = why2_chat_server_config("user_pick_username");
char *config_path = why2_replace(WHY2_CONFIG_DIR "/" WHY2_CHAT_CONFIG_SERVER_USERS, "{USER}", getenv("USER"));
if (strcmp(user_pick_username, "true") == 0 && access(config_path, R_OK) != 0)
{
//CREATE THE CONFIG
FILE *config_file = why2_fopen(config_path, "w");
//WRITE SOMETHING POSITIVE TO THE CONFIG :) (i love you, ignore my aggressive ass)
fwrite("#haha no users registered, what a loser lol", 1, 43, config_file);
//CLEANUP
why2_deallocate(config_file);
}
//DEALLOCATION
why2_toml_read_free(user_pick_username);
why2_deallocate(config_path);
}
void why2_chat_init_client_config(void)

View File

@ -24,4 +24,4 @@ name = "why2_chat_config"
crate-type = ["cdylib"]
[dependencies]
toml = "0.8.8"
toml = "*"

View File

@ -14,7 +14,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
user_pick_username = true # User will be prompted for his username on connect or will end up with default_username
user_pick_username = true # User will be prompted for their username on connect or will end up with default_username
server_name = "WHY2 Server" # Name of the server
server_username = "server" # Username server will use
default_username = "anon" # If user_pick_username is set to false, this will be used as client username
@ -22,4 +23,6 @@ communication_time = 300 # Seconds waiting for client message before stopping co
max_username_length = 20 # Maximal username length
min_username_length = 4 # Minimal username length
max_username_tries = 3 # Times asking client for username (if client tries to use invalid username)
max_username_tries = 3 # Times asking client for username (if client tries to use invalid username)
max_message_length = 100 # Maximal message length

View File

@ -18,9 +18,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
use std::
{
fs::read_to_string,
os::raw::c_char,
fs::
{
read_to_string,
write,
},
ffi::
{
CString,
@ -28,10 +32,12 @@ use std::
},
};
use toml::Value;
#[no_mangle]
pub extern "C" fn why2_toml_read(path: *const c_char, key: *const c_char) -> *mut c_char
{
//CONVERT C STRINGS TO
//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() };
@ -61,6 +67,96 @@ pub extern "C" fn why2_toml_read(path: *const c_char, key: *const c_char) -> *mu
CString::new(value).unwrap().into_raw()
}
#[no_mangle]
pub extern "C" fn why2_toml_write(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() };
//GET FILE CONTENT
let file_raw = match read_to_string(&path_r)
{
Ok(raw) => raw,
Err(e) =>
{
eprintln!("Could not read TOML config: {}\n{}", path_r, e);
return;
},
};
//PARSE FILE
let mut data: Value = match toml::from_str(&file_raw)
{
Ok(data) => data,
Err(e) =>
{
eprintln!("Could not parse TOML config: {}\n{}", path_r, e);
return;
},
};
//INSERT VALUE (OR UPDATE)
if let Some(table) = data.as_table_mut()
{
table.insert(key_r, Value::String(value_r));
} else
{
eprintln!("Failed to get TOML table from file: {}", path_r);
return;
}
//CONVERT NEW DATA TO STRING
let updated_data = match toml::to_string(&data)
{
Ok(data) => data,
Err(e) =>
{
eprintln!("Failed to convert TOML data to string: {}\n{}", path_r, e);
return;
},
};
//WRITE NEW DATA
if let Err(e) = write(&path_r, updated_data)
{
eprintln!("Could not write to TOML config: {}\n{}", path_r, e);
}
}
#[no_mangle]
pub extern "C" fn why2_toml_contains(path: *const c_char, key: *const c_char) -> bool
{
//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() };
//GET FILE CONTENT
let file_raw = match read_to_string(&path_r)
{
Ok(raw) => raw,
Err(e) =>
{
eprintln!("Could not read TOML config: {}\n{}", path_r, e);
return false;
},
};
//PARSE FILE
let data: Value = match toml::from_str(&file_raw)
{
Ok(data) => data,
Err(e) =>
{
eprintln!("Could not parse TOML config: {}\n{}", path_r, e);
return false;
},
};
data.get(&key_r).is_some()
}
#[no_mangle]
pub extern "C" fn why2_toml_read_free(s: *mut c_char) //BECAUSE THIS IS RUST MODULE I HAVE TO CREATE A DEALLOCATING FUNCTION
{

205
src/chat/crypto.c Normal file
View File

@ -0,0 +1,205 @@
/*
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 <why2/chat/crypto.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/random.h>
#include <why2/memory.h>
#include <why2/misc.h>
#include <gmp.h>
//DO NOT TOUCH THESE PLS :3
char *rsa_modulus = NULL; //THE RSA MODULUS
char *rsa_d = NULL; //THE RSA d
//LOCAL
void generate_prime(mpz_t x)
{
//RANDOM
gmp_randstate_t state;
gmp_randinit_default(state);
unsigned long random_buffer; //SEED
do
{
if (getrandom(&random_buffer, sizeof(unsigned long), GRND_NONBLOCK) == -1) why2_die("getrandom fn failed!");
//GENERATE RANDOM PRIME USING random_buffer SEED
gmp_randseed_ui(state, random_buffer);
mpz_urandomb(x, state, WHY2_CHAT_KEY_BITS);
mpz_nextprime(x, x);
} while (mpz_probab_prime_p(x, WHY2_CHAT_PRIME_ITERS) == 0); //CHECK FOR PRIME PROBABILITY
//DEALLOCATION
gmp_randclear(state);
}
void read_file(FILE *file, char **output)
{
//VARIABLES
int buffer_size;
char *buffer;
//GET LENGTH
fseek(file, 0, SEEK_END);
buffer_size = ftell(file);
rewind(file);
//READ
buffer = why2_calloc(buffer_size + 1, sizeof(char));
if (fread(buffer, buffer_size, 1, file) != 1) why2_die("Reading keyfile failed!");
buffer[buffer_size] = '\0';
//ASSIGN OUTPUT
*output = buffer;
}
char *exp_mod(char *to_exp, char *exponent)
{
//VARIABLES
char *output;
mpz_t m, c, n, e;
mpz_init(c);
//GET ALL STUFF
mpz_init_set_str(m, to_exp, 10);
mpz_init_set_str(n, why2_get_chat_modulus(), WHY2_CHAT_KEY_BASE);
mpz_init_set_str(e, exponent, WHY2_CHAT_KEY_BASE);
//ENCRYPT MESSAGE
mpz_powm(c, m, e, n);
output = why2_malloc(mpz_sizeinbase(c, 10) + 2); //ALLOCATE OUTPUT
mpz_get_str(output, 10, c); //GET OUTPUT
//DEALLOCATION
mpz_clears(m, c, n, e, NULL);
return output;
}
//GLOBAL
void why2_chat_init_keys(void)
{
//KEY FILES
FILE *public; //TECHNICALLY, PUBLIC KEY CONTAINS ONLY THE MODULUS AND PRIVATE CONTAINS ONLY THE d
FILE *private;
//GET PATH TO KEY DIR
char *path = why2_replace(WHY2_CHAT_KEY_LOCATION, "{USER}", getenv("USER"));
//ALLOCATE THE KEY PATHS
char *public_path = why2_malloc(strlen(path) + strlen(WHY2_CHAT_PUB_KEY) + 3);
char *private_path = why2_malloc(strlen(path) + strlen(WHY2_CHAT_PRI_KEY) + 3);
//GET THE ACTUAL KEY PATHS
sprintf(public_path, "%s/%s%c", path, WHY2_CHAT_PUB_KEY, '\0');
sprintf(private_path, "%s/%s%c", path, WHY2_CHAT_PRI_KEY, '\0');
//CHECK IF KEYS EXIST
if (access(path, R_OK) != 0)
{
mkdir(path, 0700);
//SOME USER OUTPUT
printf("You are probably running WHY2-Chat for the first time now.\nGenerating RSA keys...\n");
//VARIABLES
mpz_t p, q, e, d, n, phi_n, buffer_1, buffer_2;
mpz_inits(p, q, e, d, n, phi_n, buffer_1, buffer_2, NULL);
//GENERATE PRIMES
generate_prime(p);
generate_prime(q);
//SET e
mpz_set_str(e, WHY2_CHAT_RSA_EXPONENT, 10);
//GET n
mpz_mul(n, p, q);
//GET phi
mpz_sub_ui(buffer_1, p, 1);
mpz_sub_ui(buffer_2, q, 1);
mpz_mul(phi_n, buffer_1, buffer_2);
//COUNT d
mpz_invert(d, e, phi_n);
printf("Saving keys...\n");
//WRITE THE KEYS INTO KEY-FILES
public = why2_fopen(public_path, "w+");
private = why2_fopen(private_path, "w+");
mpz_out_str(public, WHY2_CHAT_KEY_BASE, n);
mpz_out_str(private, WHY2_CHAT_KEY_BASE, d);
//KEYGEN DEALLOCATION
mpz_clears(p, q, e, d, n, phi_n, buffer_1, buffer_2, NULL);
} else
{
//OPEN FILES
public = why2_fopen(public_path, "r");
private = why2_fopen(private_path, "r");
//READ THE KEYS
read_file(public, &rsa_modulus);
read_file(private, &rsa_d);
}
//DEALLOCATION
why2_deallocate(path);
why2_deallocate(public_path);
why2_deallocate(private_path);
why2_deallocate(public);
why2_deallocate(private);
}
void why2_chat_deallocate_keys(void)
{
why2_deallocate(rsa_modulus);
why2_deallocate(rsa_d);
}
char *why2_get_chat_modulus(void)
{
return rsa_modulus;
}
char *why2_get_chat_d(void)
{
return rsa_d;
}
char *why2_chat_rsa_pub_encrypt(char *to_encrypt)
{
return exp_mod(to_encrypt, WHY2_CHAT_RSA_EXPONENT);
}
char *why2_chat_rsa_pri_decrypt(char *to_decrypt)
{
return exp_mod(to_decrypt, why2_get_chat_d());
}

View File

@ -19,6 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@ -26,23 +27,87 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#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/flags.h>
#include <why2/memory.h>
#include <why2/misc.h>
why2_bool exited = 0; //USER ALREADY REQUESTED EXIT
int listen_socket; //THE SERVER SOCKET
void exit_client(WHY2_UNUSED int i) //guess what
{
if (exited) return;
exited = 1;
why2_send_socket(WHY2_CHAT_CODE_EXIT, NULL, listen_socket);
}
why2_bool command(char *input, char *command, char **arg)
{
why2_bool returning = 0;
//GET THE COMMANDS
char *full_cmd = why2_malloc(strlen(WHY2_CHAT_COMMAND_PREFIX) + strlen(WHY2_CHAT_COMMAND_EXIT) + 2);
sprintf(full_cmd, WHY2_CHAT_COMMAND_PREFIX "%s", command);
//CLEAR arg
why2_deallocate(*arg); //DEALLOCATION (why2_deallocate fn checks for NULL, don't you worry)
*arg = NULL;
if (strncmp(input, full_cmd, strlen(full_cmd)) == 0) //COMMAND WAS EXECUTED
{
if (strlen(full_cmd) == strlen(input) - 1) //COMMAND DOESN'T HAVE ARGS
{
returning = 1;
} else if (strlen(input) - 2 > strlen(full_cmd) && input[strlen(full_cmd)] == ' ') //COMMAND CONTAINS ARGS
{
returning = 1;
//GET THE ARGS
*arg = why2_malloc(strlen(input) - strlen(full_cmd) - 1); //ALLOCATE
for (unsigned long i = strlen(full_cmd) + 1; i < strlen(input) - 1; i++)
{
(*arg)[i - (strlen(full_cmd) + 1)] = input[i];
}
(*arg)[strlen(input) - strlen(full_cmd) - 2] = '\0'; //NULL TERM
why2_trim_string(arg);
}
}
//DEALLOCATE BUFFERS
why2_deallocate(full_cmd);
return returning;
}
void invalid(char *type)
{
printf("\nInvalid %s! Use \"" WHY2_CHAT_COMMAND_PREFIX WHY2_CHAT_COMMAND_HELP "\" for list of commands.\n\n>>> ", type);
fflush(stdout);
}
int main(void)
{
why2_chat_init_client_config();
signal(SIGINT, exit_client); //HANDLE ^C
int listen_socket = socket(AF_INET, SOCK_STREAM, 0); //CREATE SERVER SOCKET
why2_check_version(); //CHECK FOR UPDATES
why2_chat_init_client_config(); //CREATE client.toml CONFIGURATION
why2_chat_init_keys(); //CREATE RSA KEYS
listen_socket = socket(AF_INET, SOCK_STREAM, 0); //CREATE SERVER SOCKET
char *line = NULL;
void *return_line = NULL;
size_t line_length = 0;
pthread_t thread_buffer;
pthread_t thread_getline;
why2_bool ssqc = 0;
char *cmd_arg = NULL;
//DEFINE SERVER ADDRESS
struct sockaddr_in server_addr;
@ -101,29 +166,115 @@ int main(void)
}
line = (char*) return_line;
why2_trim_string(&line);
if (line == NULL) line = strdup("");
printf(WHY2_CLEAR_AND_GO_UP);
//TODO: Remove accents
why2_send_socket(line, NULL, listen_socket); //NULL IS SENT BECAUSE IT IS USELESS TO SEND USER FROM CLIENT - SERVER WON'T USE IT
if (strcmp(line, "!exit\n") == 0) //USER REQUESTED PROGRAM EXIT
if (strncmp(line, WHY2_CHAT_COMMAND_PREFIX, strlen(WHY2_CHAT_COMMAND_PREFIX)) == 0) //OPTIMIZE COMMANDS
{
printf("Exiting...\n");
break;
}
//COMMANDS
if (command(line, WHY2_CHAT_COMMAND_EXIT, &cmd_arg)) //USER REQUESTED PROGRAM EXIT
{
printf("Exiting...\n");
exit_client(0);
} else if (command(line, WHY2_CHAT_COMMAND_HELP, &cmd_arg)) //HELP CMD
{
printf
(
"\nCommands:\n---------\n%s\n\n>>> ",
free(return_line);
WHY2_CHAT_COMMAND_PREFIX WHY2_CHAT_COMMAND_HELP "\t\tPrints out all the commands. :)\n"
WHY2_CHAT_COMMAND_PREFIX WHY2_CHAT_COMMAND_PM " <ID> <MSG>\tSends private message to user.\n"
WHY2_CHAT_COMMAND_PREFIX WHY2_CHAT_COMMAND_LIST "\t\tLists all users and their IDs.\n"
WHY2_CHAT_COMMAND_PREFIX WHY2_CHAT_COMMAND_VERSION "\tCheck server version.\n"
WHY2_CHAT_COMMAND_PREFIX WHY2_CHAT_COMMAND_EXIT "\t\tExits the program."
);
fflush(stdout);
} else if (command(line, WHY2_CHAT_COMMAND_PM, &cmd_arg))
{
char *id; //PM RECEIVER
WHY2_UNUSED char *msg; //something racial
//CHECK ARGS VALIDITY
why2_bool valid_param = cmd_arg != NULL && strlen(cmd_arg) >= 3;
if (valid_param)
{
valid_param = 0;
for (unsigned long i = 1; i < strlen(cmd_arg); i++)
{
if (cmd_arg[i] == ' ')
{
valid_param = 1;
//EXTRACT FIRST ARG (ID)
id = why2_malloc(i + 1);
for (unsigned long j = 0; j < i; j++)
{
id[j] = cmd_arg[j];
}
id[i] = '\0';
if (atoi(id) <= 0) //INVALID ID PASSED
{
valid_param = 0;
why2_deallocate(id);
break;
}
//EXTRACT MESSAGE
msg = cmd_arg + i + 1;
break;
}
}
}
if (!valid_param) //INVALID ARGS
{
invalid("usage");
continue;
}
//BUILD MESSAGE TO SEND TO SERVER
char *final_message = why2_malloc(strlen(WHY2_CHAT_CODE_PM) + strlen(id) + strlen(msg) + 3);
sprintf(final_message, WHY2_CHAT_CODE_PM ";%s;%s%c", id, msg, '\0');
why2_send_socket(final_message, NULL, listen_socket); //SEND
//DEALLOCATION
why2_deallocate(id);
why2_deallocate(final_message);
} else if (command(line, WHY2_CHAT_COMMAND_LIST, &cmd_arg)) //LIST CMD
{
why2_send_socket(WHY2_CHAT_CODE_LIST, NULL, listen_socket);
} else if (command(line, WHY2_CHAT_COMMAND_VERSION, &cmd_arg)) //VERSION CMD
{
why2_send_socket(WHY2_CHAT_CODE_VERSION, NULL, listen_socket);
} else
{
invalid("command");
}
} else
{
why2_send_socket(line, NULL, listen_socket); //NULL IS SENT BECAUSE IT IS USELESS TO SEND USER FROM CLIENT - SERVER WON'T USE IT
free(line);
}
}
//DEALLOCATION
if (!ssqc)
{
pthread_cancel(thread_buffer);
free(return_line);
free(line);
}
why2_deallocate(cmd_arg);
why2_chat_deallocate_keys(); //DEALLOCATE GETTERS FOR KEYS
why2_clean_memory(""); //RUN GARBAGE COLLECTOR
return 0;

View File

@ -34,7 +34,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
int main(void)
{
why2_chat_init_server_config();
why2_check_version(); //CHECK FOR UPDATES
why2_chat_init_server_config(); //CREATE server.toml CONFIGURATION
int listen_socket = socket(AF_INET, SOCK_STREAM, 0); //CREATE SERVER SOCKET
pthread_t thread;
@ -63,7 +64,7 @@ int main(void)
{
if (getline(&line_buffer, &line_length_buffer, stdin) == -1) why2_die("Reading input failed.");
if (strcmp(line_buffer, "!exit\n") == 0) //USER REQUESTED PROGRAM EXIT
if (strcmp(line_buffer, WHY2_CHAT_COMMAND_PREFIX WHY2_CHAT_COMMAND_EXIT "\n") == 0) //USER REQUESTED PROGRAM EXIT
{
printf("Exiting...\n");
break;

View File

@ -23,6 +23,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <string.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <pthread.h>
@ -44,6 +45,7 @@ typedef struct _connection_node
int connection;
pthread_t thread;
char *username;
unsigned long id;
} connection_node_t; //SINGLE LINKED LIST
why2_list_t connection_list = WHY2_LIST_EMPTY;
@ -61,8 +63,6 @@ char *get_string_from_json_string(char *json, char *string)
{
struct json_object *json_obj = json_tokener_parse(json);
if (json_obj == NULL) return NULL; //INVALID SYNTAX WAS SENT BY SOME FUCKING SCRIPT KIDDIE
char *returning = why2_strdup(get_string_from_json(json_obj, string));
//DEALLOCATION
@ -105,8 +105,6 @@ void send_to_all(char *json)
char *message = get_string_from_json(json_obj, "message");
char *username = get_string_from_json(json_obj, "username");
if (json_obj == NULL) return; //EXIT IF INVALID SYNTAX WAS SENT
while (node_buffer -> next != NULL) //SEND TO ALL CONNECTIONS
{
node_buffer = node_buffer -> next;
@ -142,6 +140,23 @@ void add_brackets(char **json)
*json = output;
}
why2_bool is_ascii(char c)
{
return 33 <= c && c <= 126;
}
void remove_non_ascii(char **text)
{
//REMOVE NON ASCII CHARS
int j = 0;
for (int i = 0; (*text)[i] != '\0'; i++)
{
if (is_ascii((*text)[i])) (*text)[i] = (*text)[j++] = (*text)[i];
}
(*text)[j] = '\0';
}
char *read_socket_raw(int socket)
{
if (socket == -1)
@ -150,32 +165,62 @@ char *read_socket_raw(int socket)
return NULL;
}
unsigned short content_size = 0;
char *content_buffer = why2_calloc(3, sizeof(char));
//GET LENGTH
if (recv(socket, content_buffer, 2, 0) != 2)
char *content_buffer = NULL;
int content_size;
char *wait_buffer = why2_malloc(2); //TEMP
//WAIT TILl RECEIVED MSG (ik it sucks but i can't think of better solution; anyways, this is way more convenient than infinite loop that makes my computer go wroom wroom)
recv(socket, wait_buffer, 1, MSG_PEEK);
why2_deallocate(wait_buffer);
do
{
fprintf(stderr, "Getting message length failed!\n");
return NULL;
}
//FIND THE SENT SIZE
content_size = 0;
if (ioctl(socket, FIONREAD, &content_size) < 0 || content_size <= 0) continue;
content_size = (unsigned short) (((unsigned) content_buffer[1] << 8) | content_buffer[0]);
//ALLOCATE
content_buffer = why2_malloc(content_size + 1);
why2_deallocate(content_buffer);
//ALLOCATE
content_buffer = why2_calloc(content_size + 1, sizeof(char));
//READ JSON MESSAGE
for (int i = 0; strncmp(content_buffer + strlen(content_buffer) - 2, "\"}", 2) != 0; i++)
{
if (recv(socket, content_buffer + i, 1, 0) != 1) //READ THE MESSAGE BY CHARACTERS
//READ JSON MESSAGE
if (recv(socket, content_buffer, content_size, MSG_PEEK) != content_size) //READ THE MESSAGE BY CHARACTERS
{
fprintf(stderr, "Socket probably read wrongly!\n");
}
why2_deallocate(content_buffer); //CLEANUP
} while (content_buffer == NULL || strncmp(content_buffer + (content_size - 2), "\"}", 2) != 0);
//ACTUALLY READ
content_buffer = why2_calloc(content_size + 1, sizeof(char)); //ALLOCATE
int i;
for (i = 0; i < content_size; i++)
{
//READ
if (recv(socket, content_buffer + i, 1, 0) != 1) //READ BY CHARS
{
fprintf(stderr, "Socket probably read wrongly!\n");
}
//REMOVE NON-ASCII
if (!is_ascii(content_buffer[i])) i--; //(REWRITE THE CURRENT CHAR)
}
content_buffer[content_size - 1] = '\0';
content_buffer[i] = '\0'; //NULL TERM
//VALIDATE JSON FORMAT
struct json_object *json = json_tokener_parse(content_buffer);
if (json == NULL)
{
//RESET content_buffer
why2_deallocate(content_buffer);
content_buffer = NULL;
} else
{
//DEALLOCATION
json_object_put(json);
}
return content_buffer;
}
@ -298,6 +343,25 @@ why2_node_t *find_connection(int connection)
return buffer;
}
why2_node_t *find_connection_by_id(unsigned long id)
{
why2_node_t *head = connection_list.head;
if (head == NULL) return NULL; //EMPTY LIST
why2_node_t *buffer = head;
while (buffer -> next != NULL)
{
if ((*(connection_node_t*) buffer -> value).id == id) return buffer;
buffer = buffer -> next;
}
if (id != (*(connection_node_t*) buffer -> value).id) buffer = NULL; //PREVENT FROM RETURNING INVALID NODE
return buffer;
}
char *read_user(int connection, void **raw_ptr)
{
//VARIABLES
@ -357,13 +421,7 @@ void send_socket(char *text, char *username, int socket, why2_bool welcome)
remove_json_syntax_characters(text_copy);
//REMOVE NON ASCII CHARS
int j = 0;
for (int i = 0; text_copy[i] != '\0'; i++)
{
if ((20 <= text_copy[i] && text_copy[i] <= 126)) text_copy[i] = text_copy[j++] = text_copy[i];
}
text_copy[j] = '\0';
remove_non_ascii(&text_copy);
//ADD OBJECTS
json_object_object_add(json, "message", json_object_new_string(text_copy));
@ -375,16 +433,19 @@ void send_socket(char *text, char *username, int socket, why2_bool welcome)
char *max_uname = why2_chat_server_config("max_username_length");
char *min_uname = why2_chat_server_config("min_username_length");
char *max_tries = why2_chat_server_config("max_username_tries");
char *server_name = why2_chat_server_config("server_name");
//ADD THE INFO OBJS
json_object_object_add(json, "max_uname", json_object_new_string(max_uname));
json_object_object_add(json, "min_uname", json_object_new_string(min_uname));
json_object_object_add(json, "max_tries", json_object_new_string(max_tries));
json_object_object_add(json, "server_name", json_object_new_string(server_name));
//DEALLOCATION
why2_toml_read_free(max_uname);
why2_toml_read_free(min_uname);
why2_toml_read_free(max_tries);
why2_toml_read_free(server_name);
}
//GENERATE JSON STRING
@ -397,23 +458,10 @@ void send_socket(char *text, char *username, int socket, why2_bool welcome)
why2_deallocate(text_copy);
json_object_put(json);
unsigned short text_length = (unsigned short) strlen(output) + 2;
char *final = why2_calloc(text_length, sizeof(char));
//SPLIT LENGTH INTO TWO CHARS
final[0] = (unsigned) text_length & 0xff;
final[1] = (unsigned) text_length >> 8;
for (int i = 2; i < text_length; i++) //APPEND
{
final[i] = output[i - 2];
}
//SEND
send(socket, final, text_length, 0);
send(socket, output, strlen(output), 0);
//DEALLOCATION
why2_deallocate(final);
why2_deallocate(output);
}
@ -429,6 +477,29 @@ void send_welcome_packet(int connection)
send_welcome_socket_deallocate(WHY2_CHAT_CODE_ACCEPT_MESSAGES, why2_chat_server_config("server_username"), connection);
}
unsigned long get_latest_id()
{
unsigned long returning = 1;
why2_node_t *buffer = connection_list.head;
connection_node_t value_buffer;
while (buffer != NULL)
{
value_buffer = *(connection_node_t*) buffer -> value;
if (value_buffer.id == returning)
{
returning++;
buffer = connection_list.head;
} else
{
buffer = buffer -> next;
}
}
return returning;
}
//GLOBAL
void why2_send_socket(char *text, char *username, int socket)
{
@ -441,7 +512,7 @@ void *why2_communicate_thread(void *arg)
printf("User connected.\t\t%d\n", connection);
send_welcome_packet(connection); //TELL USER HE ALL THE INFO HE NEEDS
send_welcome_packet(connection); //TELL USER ALL THE INFO THEY NEED
//GET USERNAME
char *config_username = why2_chat_server_config("user_pick_username");
@ -471,7 +542,7 @@ void *why2_communicate_thread(void *arg)
while (invalid_username)
{
why2_deallocate(username);
if (usernames_n++ == server_config_int("max_username_tries")) //ASKED CLIENT WAY TOO FUCKING MANY TIMES FOR USERNAME, KICK HIM
if (usernames_n++ == server_config_int("max_username_tries")) //ASKED CLIENT WAY TOO FUCKING MANY TIMES FOR USERNAME, KICK THEM
{
exiting = 1;
goto deallocation;
@ -515,7 +586,7 @@ void *why2_communicate_thread(void *arg)
if (invalid_username)
{
send_socket_deallocate(WHY2_CHAT_CODE_INVALID_USERNAME, why2_chat_server_config("server_username"), connection); //TELL THE USER HE IS DUMB AS FUCK
send_socket_deallocate(WHY2_CHAT_CODE_INVALID_USERNAME, why2_chat_server_config("server_username"), connection); //TELL THE USER THEY ARE DUMB AS FUCK
continue;
}
@ -529,7 +600,8 @@ void *why2_communicate_thread(void *arg)
{
connection,
pthread_self(),
why2_strdup(username)
why2_strdup(username),
get_latest_id()
};
why2_list_push(&connection_list, &node, sizeof(node)); //ADD TO LIST
@ -573,38 +645,149 @@ void *why2_communicate_thread(void *arg)
decoded_buffer = get_string_from_json_string(raw, "message"); //DECODE
if (decoded_buffer == NULL) //idk sometimes this happen, idk why
//TRIM MESSAGE
why2_trim_string(&decoded_buffer);
if (decoded_buffer != NULL && strlen(decoded_buffer) != 0)
{
force_exiting = 1; //force exit <3
} else
{
if (strlen(decoded_buffer) != 0)
if (strncmp(decoded_buffer, "code", 4) == 0) //CODES FROM CLIENT
{
if (decoded_buffer[0] == '!') //COMMANDS
if (strcmp(decoded_buffer, WHY2_CHAT_CODE_EXIT) == 0) //USER REQUESTED EXIT
{
if (strcmp(decoded_buffer, "!exit") == 0) //USER REQUESTED EXIT
exiting = 1;
} else if (strcmp(decoded_buffer, WHY2_CHAT_CODE_LIST) == 0) //USER REQUESTED LIST OF USERS
{
why2_node_t *head = connection_list.head;
if (head == NULL) goto deallocation; //TODO: Send no users code
//BUFFERS
why2_node_t *buffer = head;
connection_node_t value_buffer;
unsigned long alloc_size = 0;
char *append_buffer;
//COUNT REQUIRED MESSAGE ALLOCATION SIZE
do
{
exiting = 1;
} else
value_buffer = *(connection_node_t*) buffer -> value;
alloc_size += strlen(value_buffer.username) + why2_count_int_length(value_buffer.id) + 2;
buffer = buffer -> next; //ITER
} while (buffer != NULL);
char *message = why2_calloc(strlen(WHY2_CHAT_CODE_LIST_SERVER) + alloc_size + 2, sizeof(char));
buffer = head; //RESET
sprintf(message, WHY2_CHAT_CODE_LIST_SERVER); //SET CODE
//FILL THE message
do
{
send_socket_deallocate(WHY2_CHAT_CODE_INVALID_COMMAND, why2_chat_server_config("server_username"), connection); //INFORM USER THAT HE'S DUMB
value_buffer = *(connection_node_t*) buffer -> value;
append_buffer = why2_malloc(strlen(value_buffer.username) + why2_count_int_length(value_buffer.id) + 3); //ALLOCATE THE BUFFER
sprintf(append_buffer, ";%s;%ld", value_buffer.username, value_buffer.id); //FILL THE BUFFER
strcat(message, append_buffer); //JOIN THE BUFFER TO OUTPUT message
why2_deallocate(append_buffer); //DEALLOCATION
buffer = buffer -> next; //ITER
} while (buffer != NULL);
strcat(message, ";");
//SEND
send_socket_deallocate(message, why2_chat_server_config("server_username"), connection);
//DEALLOCATION
why2_deallocate(message);
} else if (strcmp(decoded_buffer, WHY2_CHAT_CODE_VERSION) == 0)
{
//GET VERSION STRING FROM THE VERSIONS JSON
char *message = why2_malloc(strlen(WHY2_CHAT_CODE_VERSION_SERVER) + strlen(WHY2_VERSION) + 2); //ALLOCATE MESSAGE FOR CLIENT
sprintf(message, WHY2_CHAT_CODE_VERSION_SERVER ";%s%c", WHY2_VERSION, '\0'); //CREATE THE MESSAGE
//SEND
send_socket_deallocate(message, why2_chat_server_config("server_username"), connection);
//DEALLOCATION
why2_deallocate(message);
} else if (strncmp(decoded_buffer, WHY2_CHAT_CODE_PM, strlen(WHY2_CHAT_CODE_PM)) == 0) //PM
{
char *input = decoded_buffer + strlen(WHY2_CHAT_CODE_PM) + 1;
char *id = NULL; //RECEIVER
char *msg;
//CHECK ARGS VALIDITY
why2_bool valid_param = strlen(input) >= 3;
if (valid_param)
{
valid_param = 0;
for (unsigned long i = 1; i < strlen(input); i++)
{
if (input[i] == ';')
{
valid_param = 1;
//EXTRACT FIRST ARG (ID)
id = why2_malloc(i + 1);
for (unsigned long j = 0; j < i; j++)
{
id[j] = input[j];
}
id[i] = '\0';
//EXTRACT MESSAGE
msg = input + i + 1;
break;
}
}
}
//IGNORE MESSAGES BEGINNING WITH '!'
} else
{
//REBUILD MESSAGE WITH USERNAME
json_object_object_add(json, "message", json_object_new_string(decoded_buffer));
json_object_object_add(json, "username", json_object_new_string(get_username(connection)));
//FIND CONNECTION
why2_node_t *pm_connection = id == NULL ? NULL : find_connection_by_id(atoi(id));
if (pm_connection == NULL) valid_param = 0;
json_object_object_foreach(json, key, value) //GENERATE JSON STRING
if (valid_param) //IGNORE INVALID ARGS
{
append(&raw_output, key, (char*) json_object_get_string(value));
}
add_brackets(&raw_output);
connection_node_t pm_connection_node = *(connection_node_t*) pm_connection -> value;
send_to_all(raw_output); //e
//ALLOCATE MESSAGE TO SEND TO RECEIVER
char *private_msg = why2_malloc(strlen(WHY2_CHAT_CODE_PM_SERVER) + strlen(node.username) + strlen(pm_connection_node.username) + strlen(msg) + 6);
//CONSTRUCT DA MESSAGE
sprintf(private_msg, WHY2_CHAT_CODE_PM_SERVER ";%s;%s;%s;%c", node.username, pm_connection_node.username, msg, '\0');
//USER IS SENDING THE MESSAGE TO HIMSELF
why2_bool self_pm = pm_connection_node.connection == connection;
//SEND YOU DUMB FUCK
send_socket_deallocate(private_msg, why2_chat_server_config("server_username"), pm_connection_node.connection); //RECIPIENT
if (!self_pm) send_socket_deallocate(private_msg, why2_chat_server_config("server_username"), connection); //AUTHOR
why2_deallocate(private_msg);
}
//DEALLOCATION
why2_deallocate(id);
}
//IGNORE INVALID CODES, THE USER JUST GOT THEIR LOBOTOMY DONE
} else if (strncmp(decoded_buffer, WHY2_CHAT_COMMAND_PREFIX, strlen(WHY2_CHAT_COMMAND_PREFIX)) != 0) //IGNORE MESSAGES BEGINNING WITH '!'
{
//REBUILD MESSAGE WITH USERNAME
json_object_object_add(json, "message", json_object_new_string(decoded_buffer));
json_object_object_add(json, "username", json_object_new_string(get_username(connection)));
json_object_object_foreach(json, key, value) //GENERATE JSON STRING
{
append(&raw_output, key, (char*) json_object_get_string(value));
}
add_brackets(&raw_output);
send_to_all(raw_output); //e
}
}
@ -707,6 +890,7 @@ void *why2_listen_server(void *socket)
int max_uname = -1;
int min_uname = -1;
int max_tries = -1;
char *server_name = NULL;
printf(">>> ");
fflush(stdout);
@ -730,7 +914,11 @@ void *why2_listen_server(void *socket)
max_uname = get_int_from_json_string(read, "max_uname");
min_uname = get_int_from_json_string(read, "min_uname");
max_tries = get_int_from_json_string(read, "max_tries");
server_name = get_string_from_json_string(read, "server_name");
printf(WHY2_CLEAR_AND_GO_UP WHY2_CLEAR_AND_GO_UP "Successfully connected to %s.\n\n\n", server_name); //WELCOME
why2_deallocate(server_name);
continuing = 1;
}
@ -753,10 +941,85 @@ void *why2_listen_server(void *socket)
printf("%s%sEnter username (a-Z, 0-9; %d-%d characters):\n", asking_username++ > 0 ? WHY2_CLEAR_AND_GO_UP : "", WHY2_CLEAR_AND_GO_UP, min_uname, max_uname);
fflush(stdout);
} else if (strcmp(message, WHY2_CHAT_CODE_INVALID_COMMAND) == 0) //INVALID CMD
} else if (strncmp(message, WHY2_CHAT_CODE_LIST_SERVER, strlen(WHY2_CHAT_CODE_LIST_SERVER)) == 0) //LIST USERS
{
printf("\nInvalid command!\n\n");
why2_bool printing_id = 0;
printf("\nList:\n-----\n");
//ITER TROUGH LIST OF USERS FROM SERVER
for (unsigned long i = strlen(WHY2_CHAT_CODE_LIST_SERVER) + 1; i < strlen(message); i++)
{
if (message[i] == ';')
{
printf((printing_id = !printing_id) ? " (" : ")\n");
continue;
}
printf("%c", message[i]);
}
printf("\n");
fflush(stdout);
} else if (strncmp(message, WHY2_CHAT_CODE_VERSION_SERVER, strlen(WHY2_CHAT_CODE_VERSION_SERVER)) == 0)
{
char *server_version = message + strlen(WHY2_CHAT_CODE_VERSION_SERVER) + 1;
//INFO
printf("\nServer Version: %s\nClient Version: %s\n\n", server_version, WHY2_VERSION);
//SERVER IS OUTDATED
if (atoi(server_version + 1) < atoi(WHY2_VERSION + 1))
{
printf("Server is outdated. Some new features may not work correctly.\n\n");
}
} else if (strncmp(message, WHY2_CHAT_CODE_PM_SERVER, strlen(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
char *received_pm = message + strlen(WHY2_CHAT_CODE_PM_SERVER) + 1;
//DECODED MESSAGE, AUTHOR AND RECIPIENT; 0 = AUTHOR, 1 = RECIPIENT, 2 = MESSAGE
char **pm_info = why2_calloc(3, sizeof(char*));
unsigned long i_buffer = 0;
unsigned long n_buffer = 0;
//DECODE
for (unsigned long i = 0; i < strlen(received_pm); i++)
{
if (received_pm[i] == ';') //FUTURE ME, THIS IS PRETTY MUCH split FUNCTION IMPLEMENTATION
{
//ALLOCATE INFO
pm_info[n_buffer] = why2_malloc((i - i_buffer) + 1);
//COPY INFO
for (unsigned long j = i_buffer; j < i; j++)
{
pm_info[n_buffer][j - i_buffer] = received_pm[j];
}
pm_info[n_buffer][i - i_buffer] = '\0';
i_buffer = i + 1;
n_buffer++;
}
}
//OUTPUT
if (strcmp(pm_info[0], pm_info[1]) != 0 || strlen(pm_info[0]) != 13)
{
printf("\n\n%s(%s -> %s): %s\n\n", WHY2_CLEAR_AND_GO_UP, pm_info[0], pm_info[1], pm_info[2]);
} else
{
printf("\n\n%s(schizophrenia): %s\n\n", WHY2_CLEAR_AND_GO_UP, pm_info[2]); //:))
}
//DEALLOCATION
for (int i = 0; i < 3; i++)
{
why2_deallocate(pm_info[i]);
}
why2_deallocate(pm_info);
}
} else if (!continuing)
{
@ -798,4 +1061,69 @@ void *why2_getline_thread(WHY2_UNUSED void* arg)
if (getline(&line, &line_length, stdin) == -1) why2_die("Reading input failed.");
return line;
}
void why2_trim_string(char **s)
{
//GET CORRECT ALLOCATION FNS
void* (*allocate)(unsigned long);
void (*deallocate)(void*);
if (why2_allocated(*s))
{
allocate = why2_malloc;
deallocate = why2_deallocate;
} else
{
allocate = malloc;
deallocate = free;
}
//BUFFERS
unsigned long start_spaces = 0;
unsigned long end_spaces = 0;
unsigned long actual_length;
//COUNT start_spaces (HOW MANY SPACES ARE IN THE START)
for (unsigned long i = 0; i < strlen(*s); i++)
{
if ((*s)[i] != ' ') break;
start_spaces++;
}
//COUNT end_spaces
for (long long i = (long long) strlen(*s) - 1; i >= 0; i--)
{
if ((*s)[i] != ' ') break;
end_spaces++;
}
//USER'S HEAD HAS FELL ON THE SPACEBAR
if (start_spaces + end_spaces > strlen(*s))
{
deallocate(*s);
*s = NULL;
return;
}
//COUNT actual_length
actual_length = strlen(*s) - (end_spaces + start_spaces);
if (actual_length == strlen(*s)) return; //NO SPACES TO REMOVE
char *st = allocate(actual_length + 2); //TRIMMED s
for (unsigned long i = start_spaces; i < (start_spaces + actual_length); i++)
{
st[i - start_spaces] = (*s)[i];
}
st[actual_length] = '\0';
//DEALLOCATE UNTRIMMED s
deallocate(*s);
//SET NEW s
*s = st;
}

View File

@ -23,7 +23,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
int main(void)
{
//SET FLAGS
why2_set_flags((why2_input_flags) { 1, 1, 0, WHY2_v3 });
why2_set_flags((why2_input_flags) { 1, 1, 0, WHY2_v3, WHY2_OUTPUT_TEXT });
//RUN ENCRYPTION WITH WHY2_TEXT_TO_ENCRYPT, GENERATE NEW KEY AND DO NOT CHECK FOR ACTIVE WHY2_VERSION & PREVENT ANY OUTPUT
why2_output_flags encryptedText = why2_encrypt_text(WHY2_TEXT_TO_ENCRYPT, NULL);

View File

@ -27,129 +27,179 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <why2/memory.h>
#include <why2/misc.h>
why2_output_flags why2_decrypt_text(char *text, char *keyNew)
why2_output_flags why2_decrypt_text(char *text, char *key_new)
{
//CHECK VARIABLE
unsigned char checkExitCode;
unsigned char check_exit_code;
//TIME VARIABLES
struct timeval startTime;
struct timeval finishTime;
gettimeofday(&startTime, NULL);
struct timeval start_time;
struct timeval finish_time;
gettimeofday(&start_time, NULL);
//CHECK FOR ACTIVE WHY2_VERSION
if ((checkExitCode = why2_check_version()) != WHY2_SUCCESS)
if ((check_exit_code = why2_check_version()) != WHY2_SUCCESS)
{
return why2_no_output(checkExitCode);
return why2_no_output(check_exit_code);
}
//CHECK FOR INVALID text
if ((checkExitCode = why2_check_text(text)) != WHY2_SUCCESS)
if ((check_exit_code = why2_check_text(text)) != WHY2_SUCCESS)
{
return why2_no_output(checkExitCode);
return why2_no_output(check_exit_code);
}
//CHECK FOR INVALID key
if ((checkExitCode = why2_check_key(keyNew)) != WHY2_SUCCESS)
if ((check_exit_code = why2_check_key(key_new)) != WHY2_SUCCESS)
{
return why2_no_output(checkExitCode);
return why2_no_output(check_exit_code);
}
//REDEFINE keyLength
why2_set_key_length(strlen(keyNew));
why2_set_key_length(strlen(key_new));
//VARIABLES
char *returningText;
int numberBuffer = 1;
int usedTextDeallocationBuffer = 0;
char *textBuffer = NULL;
int textKeyChainLength;
int *textKeyChain;
char *key = why2_strdup(keyNew); //COPY keyNew TO key
int *encryptedTextKeyChain;
char *used_text = why2_strdup(text); //COPY text TO used_text
char *returning_text;
int number_buffer = 0;
int used_text_deallocation_buffer = 0;
char *text_buffer = NULL;
int text_key_chainLength;
int *text_key_chain;
char *key = why2_strdup(key_new); //COPY key_new TO key
int *encrypted_text_key_chain;
char *used_text = NULL; //COPY text TO used_text
//GET LENGTH OF returningText AND textKeyChain
for (int i = 0; i < (int) strlen(used_text); i++)
if (why2_get_flags().format == WHY2_OUTPUT_BYTE)
{
if (used_text[i] == why2_get_encryption_separator()) numberBuffer++;
//REBUILD THE BYTE FORMAT AS TEXT FORMAT
int *encrypted_input = why2_malloc(sizeof(int) * why2_byte_format_length(text));
char *text_copy = why2_strdup(text);
//GET ENCRYPTED NUMBERS
for (unsigned short i = 0; i < why2_byte_format_length(text_copy); i++)
{
for (unsigned short j = 2 + (i * 2); j <= 3 + (i * 2); j++)
{
//ENSURE THERE IS NO \0 (REVERSED)
if (text_copy[j] == -128) text_copy[j] = 0;
}
//PUT TOGETHER
encrypted_input[i] = (text_copy[3 + (i * 2)] << 7) | text_copy[2 + (i * 2)];
//ALSO COUNT REQUIRED SIZE
number_buffer += why2_count_int_length(encrypted_input[i]);
}
number_buffer += why2_byte_format_length(text_copy); //ADD THE SEPARATORS (I didn't remove one cause 1 index will be empty at used_text end)
used_text = why2_calloc(number_buffer, sizeof(char));
for (unsigned short i = 0; i < why2_byte_format_length(text_copy); i++)
{
number_buffer = why2_count_int_length(encrypted_input[i]);
text_buffer = why2_realloc(text_buffer, number_buffer + 1);
sprintf(text_buffer, "%d", encrypted_input[i]);
strcat(used_text, text_buffer);
if (i != why2_byte_format_length(text_copy) - 1)
{
used_text[strlen(used_text)] = why2_get_encryption_separator();
}
}
//DEALLOCATION
why2_deallocate(encrypted_input);
why2_deallocate(text_buffer);
why2_deallocate(text_copy);
} else if (why2_get_flags().format == WHY2_OUTPUT_TEXT)
{
used_text = why2_strdup(text);
}
//SET LENGTH (numberBuffer)
returningText = why2_calloc(numberBuffer + 1, sizeof(char));
textKeyChain = why2_malloc(sizeof(int) * numberBuffer);
encryptedTextKeyChain = why2_malloc(sizeof(int) * numberBuffer);
textKeyChainLength = numberBuffer;
number_buffer = 1;
//LOAD textKeyChain
why2_generate_text_key_chain(key, textKeyChain, numberBuffer);
//LOAD encryptedTextKeyChain
for (int i = 0; i < textKeyChainLength; i++)
//GET LENGTH OF returning_text AND text_key_chain
for (int i = 0; i < (int) strlen(used_text); i++)
{
numberBuffer = 0;
if (used_text[i] == why2_get_encryption_separator()) number_buffer++;
}
//SET LENGTH (number_buffer)
returning_text = why2_calloc(number_buffer + 1, sizeof(char));
text_key_chain = why2_malloc(sizeof(int) * number_buffer);
encrypted_text_key_chain = why2_malloc(sizeof(int) * number_buffer);
text_key_chainLength = number_buffer;
//LOAD text_key_chain
why2_generate_text_key_chain(key, text_key_chain, number_buffer);
//LOAD encrypted_text_key_chain
for (int i = 0; i < text_key_chainLength; i++)
{
number_buffer = 0;
//GET LENGTH OF EACH CHARACTER
for (int j = 0; j < (int) strlen(used_text); j++)
{
if (used_text[j] == why2_get_encryption_separator()) break;
numberBuffer++;
number_buffer++;
}
textBuffer = why2_realloc(textBuffer, numberBuffer + 1);
text_buffer = why2_realloc(text_buffer, number_buffer + 1);
//CLEAN (POSSIBLY EXISTING) JUNK in textBuffer
for (int j = 0; j <= numberBuffer; j++)
//CLEAN (POSSIBLY EXISTING) JUNK in text_buffer
for (int j = 0; j <= number_buffer; j++)
{
textBuffer[j] = '\0';
text_buffer[j] = '\0';
}
//LOAD textBuffer
//LOAD text_buffer
for (int j = 0; j < (int) strlen(used_text); j++)
{
textBuffer[j] = used_text[j];
text_buffer[j] = used_text[j];
if (numberBuffer == j) break;
if (number_buffer == j) break;
}
encryptedTextKeyChain[i] = atoi(textBuffer);
encrypted_text_key_chain[i] = atoi(text_buffer);
used_text += numberBuffer + 1;
usedTextDeallocationBuffer += numberBuffer + 1;
used_text += number_buffer + 1;
used_text_deallocation_buffer += number_buffer + 1;
}
//DECRYPT TEXT
for (int i = 0; i < textKeyChainLength; i++)
for (int i = 0; i < text_key_chainLength; i++)
{
textKeyChain[i] = why2_get_encryption_operation()(textKeyChain[i], encryptedTextKeyChain[i]);
text_key_chain[i] = why2_get_encryption_operation()(text_key_chain[i], encrypted_text_key_chain[i]);
}
//LOAD returningText
for (int i = 0; i < textKeyChainLength; i++)
//LOAD returning_text
for (int i = 0; i < text_key_chainLength; i++)
{
returningText[i] = textKeyChain[i];
returning_text[i] = text_key_chain[i];
}
//GET FINISH TIME
gettimeofday(&finishTime, NULL);
gettimeofday(&finish_time, NULL);
//LOAD output
why2_output_flags output =
{
returningText, //DECRYPTED TEXT
returning_text, //DECRYPTED TEXT
key, //USED KEY
why2_count_unused_key_size(returningText, key), // NUMBER OF WHY2_UNUSED CHARS IN KEY
why2_count_repeated_key_size(returningText, key), //NUMBER OF REPEATED CHARS IN KEY
why2_compare_time_micro(startTime, finishTime), // ELAPSED TIME
why2_count_unused_key_size(returning_text, key), // NUMBER OF WHY2_UNUSED CHARS IN KEY
why2_count_repeated_key_size(returning_text, key), //NUMBER OF REPEATED CHARS IN KEY
why2_compare_time_micro(start_time, finish_time), // ELAPSED TIME
WHY2_SUCCESS //EXIT CODE
};
//DEALLOCATION
why2_deallocate(textKeyChain);
why2_deallocate(encryptedTextKeyChain);
why2_deallocate(textBuffer);
why2_deallocate(used_text - usedTextDeallocationBuffer);
why2_deallocate(text_key_chain);
why2_deallocate(encrypted_text_key_chain);
why2_deallocate(text_buffer);
why2_deallocate(used_text - used_text_deallocation_buffer);
return output;
}

View File

@ -26,47 +26,47 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <why2/memory.h>
#include <why2/misc.h>
why2_output_flags why2_encrypt_text(char *text, char *keyNew)
why2_output_flags why2_encrypt_text(char *text, char *key_new)
{
//CHECK VARIABLE
unsigned char checkExitCode;
unsigned char check_exit_code;
//TIME VARIABLES
struct timeval startTime;
struct timeval finishTime;
gettimeofday(&startTime, NULL);
struct timeval start_time;
struct timeval finish_time;
gettimeofday(&start_time, NULL);
//CHECK FOR ACTIVE WHY2_VERSION
if ((checkExitCode = why2_check_version()) != WHY2_SUCCESS)
if ((check_exit_code = why2_check_version()) != WHY2_SUCCESS)
{
return why2_no_output(checkExitCode);
return why2_no_output(check_exit_code);
}
//CHECK FOR INVALID text
if ((checkExitCode = why2_check_text(text)) != WHY2_SUCCESS)
if ((check_exit_code = why2_check_text(text)) != WHY2_SUCCESS)
{
return why2_no_output(checkExitCode);
return why2_no_output(check_exit_code);
}
why2_set_memory_identifier("core_decrypt");
//VARIABLES
char *key = NULL;
char *returningText;
char *textBuffer = NULL;
int *textKeyChain = why2_malloc(sizeof(int) * strlen(text));
int numberBuffer = 0;
char *returning_text = NULL;
char *text_buffer = NULL;
int *text_key_chain = why2_malloc(sizeof(int) * strlen(text));
int number_buffer = 0;
if (keyNew != NULL)
if (key_new != NULL)
{
//CHECK FOR INVALID key
if ((checkExitCode = why2_check_key(keyNew)) != WHY2_SUCCESS)
if ((check_exit_code = why2_check_key(key_new)) != WHY2_SUCCESS)
{
why2_clean_memory("core_decrypt");
return why2_no_output(checkExitCode);
return why2_no_output(check_exit_code);
}
key = why2_strdup(keyNew);
key = why2_strdup(key_new);
//REDEFINE keyLength
why2_set_key_length(strlen(key));
@ -75,58 +75,85 @@ why2_output_flags why2_encrypt_text(char *text, char *keyNew)
key = why2_generate_key(why2_get_key_length());
}
//LOAD textKeyChain
why2_generate_text_key_chain(key, textKeyChain, strlen(text));
//LOAD text_key_chain
why2_generate_text_key_chain(key, text_key_chain, strlen(text));
//ACTUALLY ENCRYPT TEXT
for (int i = 0; i < (int) strlen(text); i++)
{
textKeyChain[i] = why2_get_encryption_operation()(textKeyChain[i], (int) text[i]);
text_key_chain[i] = why2_get_encryption_operation()(text_key_chain[i], (int) text[i]);
}
//COUNT REQUIRED SIZE FOR returningText
for (int i = 0; i < (int) strlen(text); i++)
//OUTPUT FORMATS
if (why2_get_flags().format == WHY2_OUTPUT_TEXT) //NORMAL 420.-69 FORMAT
{
numberBuffer += why2_count_int_length(textKeyChain[i]);
}
//ALLOCATE returningText (WITH THE SEPARATORS)
returningText = why2_calloc(numberBuffer + strlen(text), sizeof(char));
//LOAD returningText
for (int i = 0; i < (int) strlen(text); i++)
{
numberBuffer = sizeof(int) * why2_count_int_length(textKeyChain[i]);
textBuffer = why2_realloc(textBuffer, numberBuffer);
sprintf(textBuffer, "%d", textKeyChain[i]);
strcat(returningText, textBuffer);
if (i != (int) strlen(text) - 1)
//COUNT REQUIRED SIZE FOR returning_text
for (int i = 0; i < (int) strlen(text); i++)
{
returningText[strlen(returningText)] = why2_get_encryption_separator();
number_buffer += why2_count_int_length(text_key_chain[i]);
}
//ALLOCATE returning_text (WITH THE SEPARATORS)
returning_text = why2_calloc(number_buffer + strlen(text), sizeof(char));
//LOAD returning_text
for (int i = 0; i < (int) strlen(text); i++)
{
number_buffer = sizeof(int) * why2_count_int_length(text_key_chain[i]);
text_buffer = why2_realloc(text_buffer, number_buffer);
sprintf(text_buffer, "%d", text_key_chain[i]);
strcat(returning_text, text_buffer);
if (i != (int) strlen(text) - 1)
{
returning_text[strlen(returning_text)] = why2_get_encryption_separator();
}
}
} else if (why2_get_flags().format == WHY2_OUTPUT_BYTE) //FUCKED BUT SHORT(ER) OUTPUT
{
number_buffer = (strlen(text) + 1) * 2; //EACH CHARACTER WILL BE SPLIT INTO TWO CHARS AND FIRST TWO WILL BE LENGTH OF text
returning_text = why2_calloc(number_buffer + 1, sizeof(char)); //ALLOCATE
//SET LENGTH
returning_text[0] = (strlen(text) & 0x7f) + 1; //+1 BECAUSE WE DON'T WANT \0
returning_text[1] = (strlen(text) >> 7) + 1;
//PUT THE text_key_chain INTO returning_text DIRECTLY
for (unsigned long i = 0; i < strlen(text); i++)
{
//BUILD returning_text
returning_text[2 + (i * 2)] = text_key_chain[i] & 0x7f;
returning_text[3 + (i * 2)] = (text_key_chain[i] >> 7) | ((text_key_chain[i] < 0) ? 0x80 : 0);
for (unsigned long j = 2 + (i * 2); j <= 3 + (i * 2); j++)
{
//ENSURE THERE IS NO \0
if (returning_text[j] == 0) returning_text[j] = -128;
}
}
}
//GET FINISH TIME
gettimeofday(&finishTime, NULL);
gettimeofday(&finish_time, NULL);
//LOAD output
why2_output_flags output =
{
returningText, //ENCRYPTED TEXT
returning_text, //ENCRYPTED TEXT
key, //GENERATED/USED KEY
why2_count_unused_key_size(text, key), // NUMBER OF WHY2_UNUSED CHARS IN KEY
why2_count_repeated_key_size(text, key), //NUMBER OF REPEATED CHARS IN KEY
why2_compare_time_micro(startTime, finishTime), // ELAPSED TIME
why2_compare_time_micro(start_time, finish_time), // ELAPSED TIME
WHY2_SUCCESS //EXIT CODE
};
//DEALLOCATION
why2_deallocate(textKeyChain);
why2_deallocate(textBuffer);
why2_deallocate(text_key_chain);
why2_deallocate(text_buffer);
why2_reset_memory_identifier();

View File

@ -25,7 +25,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <why2/memory.h>
//CONSTS (this is just local)
#define DEFAULT_FLAGS (why2_input_flags) { 0, 0, 0, WHY2_v3}
#define DEFAULT_FLAGS (why2_input_flags) { 0, 0, 0, WHY2_v3, WHY2_OUTPUT_TEXT }
#define DEFAULT_MEMORY_IDENTIFIER ""
int encryptionOperation(int text, int encryptedText);

View File

@ -44,7 +44,8 @@ int main(void)
0, //SKIP CHECK
0, //NO OUTPUT
0, //UPDATE
WHY2_v3 //LATEST VERSION
WHY2_v3, //LATEST VERSION
WHY2_OUTPUT_TEXT //READABLE TEXT OUTPUT
};
//SET FLAGS

View File

@ -39,11 +39,15 @@ void why2_list_push(why2_list_t *list, void *value, unsigned long size)
buffer = new_node;
} else
{
why2_node_t *buffer_2 = buffer;
while (buffer -> next != NULL) buffer = buffer -> next; //GET TO THE END OF LIST
buffer -> next = new_node; //LINK
buffer = buffer_2; //GO BACK TO THE START OF THE LLIST
}
//APPEND THE new_node TO THE END OF list
list -> head = buffer;
}
@ -129,4 +133,22 @@ why2_node_t *why2_list_find(why2_list_t *list, void *value)
if (value != buffer -> value) buffer = NULL; //PREVENT FROM RETURNING INVALID NODE
return buffer;
}
unsigned long why2_list_get_size(why2_list_t *list)
{
unsigned long n = 0; //RETURNING SIZE
why2_node_t *head = list -> head;
if (head == NULL) return n; //EMPTY LIST
why2_node_t *buffer = head;
do
{
n++;
buffer = buffer -> next; //ITER
} while (buffer != NULL);
return n;
}

View File

@ -191,6 +191,8 @@ void *why2_opendir(char *name)
void why2_deallocate(void *pointer)
{
if (pointer == NULL) return; //DEALLOCATING NULL
//VARIABLES
node_t *node = get_node(pointer);
@ -238,4 +240,9 @@ void why2_clean_memory(char *identifier)
if (buffer -> identifier == identifier || force_deallocating) why2_deallocate(buffer -> pointer); //LAST NODE
why2_reset_memory_identifier(); //THIS WILL CAUSE SEGFAULT IF YOU DIDN'T USE why2_set_memory_identifier
}
why2_bool why2_allocated(void *pointer)
{
return get_node(pointer) != NULL;
}

View File

@ -24,7 +24,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/random.h>
#include <ftw.h>
#include <curl/curl.h>
@ -34,8 +34,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <why2/flags.h>
#include <why2/memory.h>
why2_bool seedSet = 0; //DO NOT FUCKING TOUCH THIS!!!
int multiply_cb(int a, int b) { return a * b; }
int subtract_cb(int a, int b) { return a - b; }
int sum_cb(int a, int b) { return a + b; }
@ -54,22 +52,41 @@ int removeDirectory(char *path)
return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
}
enum WHY2_EXIT_CODES why2_check_version(void) //! CRASHES WHEN CALLED FROM CHAT STUFF
void why2_directory(void)
{
struct stat st;
char *buffer = why2_replace(WHY2_CONFIG_DIR, "{USER}", getenv("USER"));
//CREATE USER CONFIG FOLDER
if (stat(buffer, &st) == -1)
{
mkdir(buffer, 0700);
}
//DEALLOCATION
why2_deallocate(buffer);
}
enum WHY2_EXIT_CODES why2_check_version(void)
{
if (why2_get_flags().no_check) return WHY2_SUCCESS;
why2_set_memory_identifier("core_version_check");
why2_directory(); //MAKE SURE WHY2 DIR EXISTS
//FILE-CHECK VARIABLES
int notFoundBuffer = 0;
int not_found_buffer = 0;
//GET VERSION FILE
char *version_file = why2_replace(WHY2_VERSIONS_NAME, "{USER}", getenv("USER"));
//CURL VARIABLES
CURL *curl = curl_easy_init();
FILE *fileBuffer = why2_fopen(WHY2_VERSIONS_NAME, "w+");
FILE *file_buffer = why2_fopen(version_file, "w+");
//GET versions.json
curl_easy_setopt(curl, CURLOPT_URL, WHY2_VERSIONS_URL);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fileBuffer);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, file_buffer);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, WHY2_CURL_TIMEOUT);
//DOWNLOAD versions.json
@ -77,41 +94,41 @@ enum WHY2_EXIT_CODES why2_check_version(void) //! CRASHES WHEN CALLED FROM CHAT
//CLEANUP
curl_easy_cleanup(curl);
why2_deallocate(fileBuffer);
why2_deallocate(file_buffer);
while (access(WHY2_VERSIONS_NAME, R_OK) != 0)
while (access(version_file, R_OK) != 0)
{
notFoundBuffer++;
not_found_buffer++;
if (notFoundBuffer == WHY2_NOT_FOUND_TRIES)
if (not_found_buffer == WHY2_NOT_FOUND_TRIES)
{
if (!why2_get_flags().no_output) fprintf(stderr, "%s'%s' not found! Exiting...\n", WHY2_CLEAR_SCREEN, WHY2_VERSIONS_NAME);
if (!why2_get_flags().no_output) fprintf(stderr, "%s'%s' not found! Exiting...\n", WHY2_CLEAR_SCREEN, version_file);
why2_clean_memory("core_version_check");
return WHY2_DOWNLOAD_FAILED;
}
if (!why2_get_flags().no_output) printf("%s'%s' not found (%dx)! Trying again in a second.\n", WHY2_CLEAR_SCREEN, WHY2_VERSIONS_NAME, notFoundBuffer);
if (!why2_get_flags().no_output) printf("%s'%s' not found (%dx)! Trying again in a second.\n", WHY2_CLEAR_SCREEN, version_file, not_found_buffer);
sleep(1);
}
//JSON VARIABLES
char *buffer;
struct json_object *parsedJson;
long buffer_size;
struct json_object *parsed_json;
struct json_object *active;
int bufferSize;
//COUNT LENGTH OF buffer AND STORE IT IN bufferSize
fileBuffer = why2_fopen(WHY2_VERSIONS_NAME, "r");
fseek(fileBuffer, 0, SEEK_END);
bufferSize = ftell(fileBuffer);
rewind(fileBuffer); //REWIND fileBuffer (NO SHIT)
file_buffer = why2_fopen(version_file, "r");
fseek(file_buffer, 0, SEEK_END);
buffer_size = ftell(file_buffer);
rewind(file_buffer); //REWIND file_buffer (NO SHIT)
//SET LENGTH OF buffer
buffer = why2_calloc(bufferSize + 1, sizeof(char));
buffer = why2_calloc(buffer_size + 1, sizeof(char));
//LOAD jsonFile
if (fread(buffer, bufferSize, 1, fileBuffer) != 1)
if (fread(buffer, buffer_size, 1, file_buffer) != 1)
{
if (!why2_get_flags().no_output) fprintf(stderr, "Reading file failed!\n");
@ -120,7 +137,7 @@ enum WHY2_EXIT_CODES why2_check_version(void) //! CRASHES WHEN CALLED FROM CHAT
// return WHY2_DOWNLOAD_FAILED;
}
buffer[bufferSize] = '\0';
buffer[buffer_size] = '\0';
//CHECK FOR TEXT IN buffer
if (strcmp(buffer, "") == 0)
@ -135,11 +152,11 @@ enum WHY2_EXIT_CODES why2_check_version(void) //! CRASHES WHEN CALLED FROM CHAT
}
//CLEANUP
why2_deallocate(fileBuffer);
why2_deallocate(file_buffer);
//GET
parsedJson = json_tokener_parse(buffer); //yes, ik, i could use json_object_from_file, but I need to check for internet somehow
json_object_object_get_ex(parsedJson, "active", &active);
parsed_json = json_tokener_parse(buffer); //yes, ik, i could use json_object_from_file, but I need to check for internet somehow
json_object_object_get_ex(parsed_json, "active", &active);
if (strcmp(WHY2_VERSION, json_object_get_string(active)) != 0)
{
@ -158,8 +175,8 @@ enum WHY2_EXIT_CODES why2_check_version(void) //! CRASHES WHEN CALLED FROM CHAT
//VARIABLES
git_repository *repo = NULL;
int exit_code;
char *installCommand;
int installCode;
char *install_command;
int install_code;
//MESSAGE
if (!why2_get_flags().no_output) printf("Your WHY2 version is outdated!\nUpdating...\t[BETA]\n\n");
@ -185,18 +202,18 @@ enum WHY2_EXIT_CODES why2_check_version(void) //! CRASHES WHEN CALLED FROM CHAT
return WHY2_WHY2_UPDATE_FAILED;
}
//COUNT installCommand LENGTH & ALLOCATE IT
installCommand = why2_replace(WHY2_UPDATE_COMMAND, "{DIR}", WHY2_UPDATE_NAME);
//COUNT install_command LENGTH & ALLOCATE IT
install_command = why2_replace(WHY2_UPDATE_COMMAND, "{DIR}", WHY2_UPDATE_NAME);
installCode = system(installCommand); //INSTALL
install_code = system(install_command); //INSTALL
//REMOVE versions.json - OTHERWISE WILL CAUSE SEGFAULT IN NEXT RUN
remove(WHY2_VERSIONS_NAME);
remove(version_file);
why2_deallocate(installCommand);
why2_deallocate(install_command);
//CHECK FOR ERRORS
if (installCode != 0)
if (install_code != 0)
{
if (!why2_get_flags().no_output) fprintf(stderr, "Updating failed! (installing)\n");
@ -206,34 +223,34 @@ enum WHY2_EXIT_CODES why2_check_version(void) //! CRASHES WHEN CALLED FROM CHAT
} else
{
//COUNT WHY2_VERSIONS BEHIND
int versionsIndex = -1;
int versionsBuffer = 0;
int versions_index = -1;
int versions_buffer = 0;
struct json_object *deprecated;
json_object_object_get_ex(parsedJson, "deprecated", &deprecated);
json_object_object_get_ex(parsed_json, "deprecated", &deprecated);
//COUNT versionsIndex
//COUNT versions_index
for (int i = 0; i < (int) json_object_array_length(deprecated); i++)
{
//IT'S A MATCH, BABY :D
if (strcmp(json_object_get_string(json_object_array_get_idx(deprecated, i)), WHY2_VERSION) == 0)
{
versionsIndex = i;
versions_index = i;
break;
}
}
//versions.json DOESN'T CONTAIN WHY2_VERSION (THIS WILL NOT HAPPEN IF YOU WILL NOT EDIT IT)
if (versionsIndex == -1)
if (versions_index == -1)
{
if (!why2_get_flags().no_output) printf("Version %s not found! Check your flags.\n\n", WHY2_VERSION);
} else
{
//COUNT versionsBuffer
versionsBuffer = json_object_array_length(deprecated) - versionsIndex;
//COUNT versions_buffer
versions_buffer = json_object_array_length(deprecated) - versions_index;
if (!why2_get_flags().no_output) fprintf(stderr, "This release could be unsafe! You're %d versions behind! (%s/%s)\n\n", versionsBuffer, WHY2_VERSION, json_object_get_string(active));
if (!why2_get_flags().no_output) fprintf(stderr, "This release could be unsafe! You're %d versions behind! (%s/%s)\n\n", versions_buffer, WHY2_VERSION, json_object_get_string(active));
//WAIT FOR 5 SECONDS
sleep(5);
@ -242,8 +259,9 @@ enum WHY2_EXIT_CODES why2_check_version(void) //! CRASHES WHEN CALLED FROM CHAT
}
//DEALLOCATION
json_object_put(parsedJson); //THIS FREES EVERY json_object - AT LEAST JSON-C'S DOCUMENTATION SAYS THAT
json_object_put(parsed_json); //THIS FREES EVERY json_object - AT LEAST JSON-C'S DOCUMENTATION SAYS THAT
why2_deallocate(buffer);
why2_deallocate(version_file);
why2_reset_memory_identifier();
@ -393,54 +411,30 @@ unsigned long why2_compare_time_micro(struct timeval startTime, struct timeval f
char *why2_generate_key(int key_length)
{
int numberBuffer;
int number_buffer;
unsigned int random_buffer;
char *key;
if (!seedSet)
{
why2_set_memory_identifier("core_key_generation_random");
//TRY TO MAKE RANDOM GENERATION REALLY "RANDOM"
FILE *fileBuffer;
fileBuffer = why2_fopen("/dev/urandom", "r");
if (fread(&numberBuffer, sizeof(numberBuffer), 1, fileBuffer) != 1)
{
if (!why2_get_flags().no_output) fprintf(stderr, "Reading file failed!\n");
why2_clean_memory("core_key_generation_random");
return NULL;
}
numberBuffer = abs(numberBuffer); //MAKE numberBuffer POSITIVE
srand(numberBuffer);
why2_deallocate(fileBuffer);
seedSet = 1;
why2_reset_memory_identifier();
}
key = why2_malloc(key_length + 1);
for (int i = 0; i < key_length; i++)
{
//GET RANDOM NUMBER
if (getrandom(&random_buffer, sizeof(unsigned int), GRND_NONBLOCK) == -1) why2_die("getrandom fn failed!");
//SET numberBuffer TO RANDOM NUMBER BETWEEN 0 AND 52
numberBuffer = (rand() % 52) + 1;
number_buffer = (random_buffer % 52) + 1;
//GET CHAR FROM numberBuffer
if (numberBuffer > 26)
if (number_buffer > 26)
{
numberBuffer += 70;
}
else
number_buffer += 70;
} else
{
numberBuffer += 64;
number_buffer += 64;
}
key[i] = (char) numberBuffer;
key[i] = (char) number_buffer;
}
key[key_length] = '\0';
@ -491,4 +485,9 @@ char *why2_replace(char *string, char *old, char *new) //CODE FROM: https://www.
result[i] = '\0';
return result;
}
unsigned short why2_byte_format_length(char *s)
{
return ((s[1] - 1) << 7) | (s[0] - 1); //ADD THE FIRST TWO INDEXES TOGETHER TO GET LENGTH
}

View File

@ -16,7 +16,8 @@ int main(void)
1,
1,
0,
WHY2_v3
WHY2_v3,
WHY2_OUTPUT_TEXT
}
);

View File

@ -132,7 +132,7 @@ void why2_write_log(int loggerFile, char *logMessage)
why2_log_flags flags = why2_get_log_flags();
//SET ENCRYPTER FLAGS
if (!why2_get_flags_changed()) why2_set_flags((why2_input_flags) { 0, 1, 0, WHY2_v3 });
if (!why2_get_flags_changed()) why2_set_flags((why2_input_flags) { 0, 1, 0, WHY2_v3, WHY2_OUTPUT_TEXT });
if (flags.key != NULL) //ENCRYPT TEXT IF KEY WAS CHANGED
{