Compare commits
17 Commits
e99f0115d6
...
35ec44ae68
Author | SHA1 | Date | |
---|---|---|---|
35ec44ae68 | |||
7b2f55e3ae | |||
8a7c389a74 | |||
481bce366c | |||
4d8f61259d | |||
4317c9fa5d | |||
f3f5533763 | |||
c1ee049f32 | |||
ca6b81943a | |||
a242fbea95 | |||
a4b8bf2f4c | |||
ee309b2cbb | |||
767f78a554 | |||
7daa9aa124 | |||
4d64d73c07 | |||
6c53169f09 | |||
2970878bce |
@ -49,7 +49,7 @@ why2_bool why2_chat_ecc_verify_signature(char *message, char *signature, EVP_PKE
|
||||
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_chat_ecc_shared_key(char *ecc_key); //ENCRYPT message WITH ECC key
|
||||
|
||||
char *why2_sha256(char *input, size_t length); //HASH input USING SHA256 AND RETURN IN STRING
|
||||
|
||||
|
@ -42,24 +42,28 @@ 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_SERVER_CLIENT_KEY_EXCHANGE "SC0" //TELL CLIENT YOU ARE SHARING YOUR PUBLIC KEY
|
||||
#define WHY2_CHAT_CODE_ACCEPT_MESSAGES "SC1" //TELL CLIENT THEY CAN SEND MESSAGES
|
||||
#define WHY2_CHAT_CODE_PICK_USERNAME "SC2" //TELL CLIENT TO PICK USERNAME
|
||||
#define WHY2_CHAT_CODE_SERVER_SIDE_QUIT_COMMUNICATION "SC3" //TELL CLIENT TO END COMMUNICATION (just so they don't get segfault on server-side disconnect)
|
||||
#define WHY2_CHAT_CODE_INVALID_USERNAME "SC4" //haha
|
||||
#define WHY2_CHAT_CODE_LIST_SERVER "SC5" //SAME AS WHY2_CHAT_CODE_LIST BUT BACK TO THE CLIENT
|
||||
#define WHY2_CHAT_CODE_VERSION_SERVER "SC6" //SAME AS WHY2_CHAT_CODE_VERSION BUT BACK TO THE CLIENT
|
||||
#define WHY2_CHAT_CODE_DM_SERVER "SC7" //SAME AS WHY2_CHAT_CODE_DM BUT BACK TO THE CLIENT
|
||||
#define WHY2_CHAT_CODE_ENTER_PASSWORD "SC8" //RECEIVE PASSWORD FROM USER
|
||||
#define WHY2_CHAT_CODE_INVALID_PASSWORD "SC9"//🌸ꗥ~ꗥ🌸 𝐢 𝐡𝐚𝐭𝐞 𝐲𝐨𝐮 🌸ꗥ~ꗥ🌸
|
||||
|
||||
//(CLIENT -> SERVER) CODES
|
||||
#define WHY2_CHAT_CODE_CLIENT_SERVER_KEY_EXCHANGE "CS0" //TELL SERVER YOU ARE SHARING YOUR PUBLIC KEY
|
||||
#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
|
||||
#define WHY2_CHAT_CODE_USERNAME "CS5" //TELL SERVER YOU ARE GIVING IT YOUR USERNAME
|
||||
#define WHY2_CHAT_CODE_PASSWORD "CS6" //TELL SERVER YOU ARE GIVING IT YOUR PASSWORD (HASHED)
|
||||
|
||||
//(AUTHORITY -> CLIENT) CODES
|
||||
#define WHY2_CHAT_CODE_KEY_EXCHANGE "AC0" //TELL CLIENT YOU ARE SENDING YOUR PUBLIC KEY
|
||||
#define WHY2_CHAT_CODE_KEY_EXCHANGE "AC0" //TELL CLIENT TO SEND CA THEIR PUBKEY
|
||||
#define WHY2_CHAT_CODE_SUCCESS "AC1" //TELL CLIENT THEY ARE GOOD TO GO
|
||||
#define WHY2_CHAT_CODE_FAILURE "AC2" //TELL CLIENT THEY FUCKED UP
|
||||
|
||||
@ -79,8 +83,15 @@ enum WHY2_CHAT_SERVER_TYPE //TYPE OF SERVER
|
||||
#define WHY2_CHAT_CODE_SSQC WHY2_CHAT_CODE_SERVER_SIDE_QUIT_COMMUNICATION
|
||||
|
||||
//FUNCTIONS
|
||||
void why2_chat_set_client_server_key(char *key); //SET KEY USED FOR ENCRYPTION BETWEEN CLIENT AND SERVER
|
||||
char *why2_chat_get_client_server_key(void);
|
||||
void why2_chat_deallocate_client_server_key(void);
|
||||
|
||||
void __why2_set_asking_password(why2_bool value); //IF HASH SHOULD BE SENT INSTEAD OF NORMAL MESSAGE
|
||||
why2_bool __why2_get_asking_password();
|
||||
why2_bool __why2_get_asking_password(void);
|
||||
|
||||
void __why2_set_asking_username(why2_bool value);
|
||||
why2_bool __why2_get_asking_username(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -259,16 +259,13 @@ EVP_PKEY* why2_chat_ecc_deserialize_public_key(char *pubkey)
|
||||
return key;
|
||||
}
|
||||
|
||||
char *why2_chat_ecc_encrypt(char *message, char *key)
|
||||
char *why2_chat_ecc_shared_key(char *ecc_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 *recipient_pubkey_decoded = base64_decode(ecc_key, &key_length); //DECODE key
|
||||
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);
|
||||
@ -279,27 +276,13 @@ char *why2_chat_ecc_encrypt(char *message, char *key)
|
||||
//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;
|
||||
return sym_key;
|
||||
}
|
||||
|
||||
void why2_chat_deallocate_keys(void)
|
||||
|
@ -21,7 +21,27 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <why2/memory.h>
|
||||
|
||||
why2_bool asking_password = 0;
|
||||
why2_bool asking_username = 0;
|
||||
char *client_server_key = NULL;
|
||||
|
||||
void why2_chat_set_client_server_key(char *key)
|
||||
{
|
||||
client_server_key = key;
|
||||
}
|
||||
|
||||
char *why2_chat_get_client_server_key(void)
|
||||
{
|
||||
return client_server_key;
|
||||
}
|
||||
|
||||
void why2_chat_deallocate_client_server_key(void)
|
||||
{
|
||||
why2_deallocate(client_server_key);
|
||||
client_server_key = NULL;
|
||||
}
|
||||
|
||||
void __why2_set_asking_password(why2_bool value)
|
||||
{
|
||||
@ -41,7 +61,17 @@ void __why2_set_asking_password(why2_bool value)
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &tty); //SET ATTRS
|
||||
}
|
||||
|
||||
why2_bool __why2_get_asking_password()
|
||||
why2_bool __why2_get_asking_password(void)
|
||||
{
|
||||
return asking_password;
|
||||
}
|
||||
|
||||
void __why2_set_asking_username(why2_bool value)
|
||||
{
|
||||
asking_username = value;
|
||||
}
|
||||
|
||||
why2_bool __why2_get_asking_username(void)
|
||||
{
|
||||
return asking_username;
|
||||
}
|
@ -101,7 +101,7 @@ int main(void)
|
||||
why2_chat_init_client_config(); //CREATE client.toml CONFIGURATION
|
||||
why2_chat_init_keys(); //CREATE ECC KEY
|
||||
|
||||
listen_socket = socket(AF_INET, SOCK_STREAM, 0); //CREATE SERVER SOCKET
|
||||
listen_socket = socket(AF_INET, SOCK_STREAM, 0); //CREATE AUTHORITY SOCKET
|
||||
char *line = NULL;
|
||||
void *return_line = NULL;
|
||||
size_t line_length = 0;
|
||||
@ -133,6 +133,7 @@ int main(void)
|
||||
why2_deallocate(ca_success);
|
||||
|
||||
//SERVER CONNECT
|
||||
listen_socket = socket(AF_INET, SOCK_STREAM, 0); //CREATE SERVER SOCKET
|
||||
server_addr.sin_port = htons(WHY2_CHAT_SERVER_PORT);
|
||||
|
||||
//GET IP
|
||||
@ -287,15 +288,23 @@ int main(void)
|
||||
|
||||
char *hash = why2_sha256(line, strlen(line)); //HASHISH
|
||||
|
||||
why2_send_socket(hash, NULL, listen_socket); //SEND BUT HASHED
|
||||
why2_send_socket_code(hash, NULL, listen_socket, WHY2_CHAT_CODE_PASSWORD); //SEND BUT HASHED
|
||||
|
||||
//DEALLOCATION
|
||||
why2_deallocate(hash);
|
||||
__why2_set_asking_password(0);
|
||||
} else
|
||||
{
|
||||
if (__why2_get_asking_username())
|
||||
{
|
||||
__why2_set_asking_username(0);
|
||||
|
||||
why2_send_socket_code(line, NULL, listen_socket, WHY2_CHAT_CODE_USERNAME);
|
||||
} 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);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ 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>
|
||||
|
||||
@ -36,6 +37,7 @@ int main(void)
|
||||
{
|
||||
why2_check_version(); //CHECK FOR UPDATES
|
||||
why2_chat_init_server_config(); //CREATE server.toml CONFIGURATION
|
||||
why2_chat_init_keys(); //CREATE ECC KEY
|
||||
|
||||
int listen_socket = socket(AF_INET, SOCK_STREAM, 0); //CREATE SERVER SOCKET
|
||||
pthread_t thread;
|
||||
|
142
src/chat/misc.c
142
src/chat/misc.c
@ -500,6 +500,82 @@ unsigned long get_latest_id()
|
||||
return returning;
|
||||
}
|
||||
|
||||
why2_bool perform_key_exchange_client(int connection)
|
||||
{
|
||||
//VARIABLES
|
||||
char *client_pubkey = why2_chat_ecc_serialize_public_key(); //GET PUBLIC KEY
|
||||
char *server_pubkey;
|
||||
char *read = NULL;
|
||||
char *read_code = NULL;
|
||||
why2_bool exiting_read = 0;
|
||||
|
||||
why2_send_socket_code(client_pubkey, NULL, connection, WHY2_CHAT_CODE_CLIENT_SERVER_KEY_EXCHANGE); //SEND pubkey TO SERVER
|
||||
|
||||
why2_deallocate(client_pubkey); //DEALLOCATE client_pubkey
|
||||
|
||||
//GET SERVER PUBKEY
|
||||
do
|
||||
{
|
||||
why2_deallocate(read);
|
||||
why2_deallocate(read_code);
|
||||
|
||||
read = read_socket_raw(connection);
|
||||
|
||||
read_code = get_string_from_json_string(read, "code");
|
||||
exiting_read = read_code != NULL && strcmp(read_code, WHY2_CHAT_CODE_SERVER_CLIENT_KEY_EXCHANGE) == 0;
|
||||
} while (!exiting_read);
|
||||
why2_deallocate(read_code);
|
||||
|
||||
server_pubkey = get_string_from_json_string(read, "message");
|
||||
|
||||
why2_chat_set_client_server_key( why2_chat_ecc_shared_key(server_pubkey)); //CALCULATE SHARED KEY
|
||||
|
||||
//DEALLOCATION
|
||||
why2_deallocate(read);
|
||||
why2_deallocate(server_pubkey);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
why2_bool perform_key_exchange_server(int connection, char **key)
|
||||
{
|
||||
//VARIABLES
|
||||
char *server_pubkey;
|
||||
char *client_pubkey;
|
||||
char *read = NULL;
|
||||
char *read_code = NULL;
|
||||
why2_bool exiting_read = 0;
|
||||
|
||||
//GET CLIENT PUBKEY
|
||||
do
|
||||
{
|
||||
why2_deallocate(read);
|
||||
why2_deallocate(read_code);
|
||||
|
||||
read = read_socket_raw(connection);
|
||||
|
||||
read_code = get_string_from_json_string(read, "code");
|
||||
exiting_read = read_code != NULL && strcmp(read_code, WHY2_CHAT_CODE_CLIENT_SERVER_KEY_EXCHANGE) == 0;
|
||||
} while (!exiting_read);
|
||||
why2_deallocate(read_code);
|
||||
|
||||
client_pubkey = get_string_from_json_string(read, "message"); //GET client_pubkey
|
||||
if (client_pubkey == NULL) return 1; //client is funi
|
||||
|
||||
//SEND CLIENT PUBKEY
|
||||
server_pubkey = why2_chat_ecc_serialize_public_key();
|
||||
why2_send_socket_code(server_pubkey, NULL, connection, WHY2_CHAT_CODE_SERVER_CLIENT_KEY_EXCHANGE);
|
||||
|
||||
*key = why2_chat_ecc_shared_key(client_pubkey);
|
||||
|
||||
//DEALLOCATION
|
||||
why2_deallocate(server_pubkey);
|
||||
why2_deallocate(client_pubkey);
|
||||
why2_deallocate(read);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//GLOBAL
|
||||
void why2_send_socket(char *text, char *username, int socket)
|
||||
{
|
||||
@ -514,6 +590,14 @@ void why2_send_socket_code(char *params, char *username, int socket, char *code)
|
||||
void *why2_communicate_thread(void *arg)
|
||||
{
|
||||
int connection = *(int*) arg;
|
||||
char *client_server_key = NULL;
|
||||
|
||||
//PERFORM KEY EXCHANGE
|
||||
if (perform_key_exchange_server(connection, &client_server_key))
|
||||
{
|
||||
close(connection);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("User connected.\t\t%d\n", connection);
|
||||
|
||||
@ -554,12 +638,27 @@ void *why2_communicate_thread(void *arg)
|
||||
goto deallocation;
|
||||
}
|
||||
|
||||
//KEEP READING UNTIL CODE ARRIVES
|
||||
char *code = NULL;
|
||||
why2_bool exiting_read = 0;
|
||||
do
|
||||
{
|
||||
//DEALLOCATE
|
||||
why2_deallocate(code);
|
||||
why2_deallocate(raw);
|
||||
|
||||
if ((raw = read_user(connection, &raw_ptr)) == NULL) //READ
|
||||
{
|
||||
force_exiting = 1; //FAILURE
|
||||
goto deallocation;
|
||||
}
|
||||
|
||||
//COMPARE CODE
|
||||
code = get_string_from_json_string(raw, "code");
|
||||
exiting_read = code != NULL && strcmp(code, WHY2_CHAT_CODE_USERNAME) == 0;
|
||||
} while (!exiting_read);
|
||||
why2_deallocate(code);
|
||||
|
||||
decoded_buffer = get_string_from_json_string(raw, "message"); //DECODE
|
||||
|
||||
invalid_username = decoded_buffer == NULL || (strlen(decoded_buffer) > (unsigned long) server_config_int("max_username_length")) || (strlen(decoded_buffer) < (unsigned long) server_config_int("min_username_length")) || (!check_username(decoded_buffer)); //CHECK FOR USERNAMES LONGER THAN 20 CHARACTERS
|
||||
@ -604,12 +703,28 @@ void *why2_communicate_thread(void *arg)
|
||||
{
|
||||
send_socket_code_deallocate(NULL, why2_chat_server_config("server_username"), connection, WHY2_CHAT_CODE_ENTER_PASSWORD);
|
||||
|
||||
//KEEP READING UNTIL CODE ARRIVES
|
||||
char *code = NULL;
|
||||
why2_bool exiting_read = 0;
|
||||
raw = NULL;
|
||||
do
|
||||
{
|
||||
//DEALLOCATE
|
||||
why2_deallocate(code);
|
||||
why2_deallocate(raw);
|
||||
|
||||
if ((raw = read_user(connection, &raw_ptr)) == NULL) //READ
|
||||
{
|
||||
force_exiting = 1; //FAILURE
|
||||
goto deallocation;
|
||||
}
|
||||
|
||||
//COMPARE CODE
|
||||
code = get_string_from_json_string(raw, "code");
|
||||
exiting_read = code != NULL && strcmp(code, WHY2_CHAT_CODE_PASSWORD) == 0;
|
||||
} while (!exiting_read);
|
||||
why2_deallocate(code);
|
||||
|
||||
password = get_string_from_json_string(raw, "message"); //DECODE
|
||||
|
||||
why2_toml_write(user_config_path, username, password); //SAVE PASSWORD
|
||||
@ -621,12 +736,28 @@ void *why2_communicate_thread(void *arg)
|
||||
|
||||
for (unsigned char i = 0; i < max_tries; i++)
|
||||
{
|
||||
//KEEP READING UNTIL CODE ARRIVES
|
||||
char *code = NULL;
|
||||
why2_bool exiting_read = 0;
|
||||
raw = NULL;
|
||||
do
|
||||
{
|
||||
//DEALLOCATE
|
||||
why2_deallocate(code);
|
||||
why2_deallocate(raw);
|
||||
|
||||
if ((raw = read_user(connection, &raw_ptr)) == NULL) //READ
|
||||
{
|
||||
force_exiting = 1; //FAILURE
|
||||
goto deallocation;
|
||||
}
|
||||
|
||||
//COMPARE CODE
|
||||
code = get_string_from_json_string(raw, "code");
|
||||
exiting_read = code != NULL && strcmp(code, WHY2_CHAT_CODE_PASSWORD) == 0;
|
||||
} while (!exiting_read);
|
||||
why2_deallocate(code);
|
||||
|
||||
password = get_string_from_json_string(raw, "message"); //DECODE
|
||||
|
||||
if (why2_toml_equals(user_config_path, decoded_buffer, password)) break;
|
||||
@ -661,7 +792,7 @@ void *why2_communicate_thread(void *arg)
|
||||
pthread_self(),
|
||||
why2_strdup(username),
|
||||
get_latest_id(),
|
||||
why2_generate_key(why2_get_key_length())
|
||||
client_server_key
|
||||
};
|
||||
|
||||
why2_list_push(&connection_list, &node, sizeof(node)); //ADD TO LIST
|
||||
@ -1033,6 +1164,11 @@ void why2_clean_threads(void)
|
||||
|
||||
void *why2_listen_server(void *socket)
|
||||
{
|
||||
int connection = *(int*) socket;
|
||||
|
||||
//PERFORM KEY EXCHANGE
|
||||
if (perform_key_exchange_client(connection)) return NULL;
|
||||
|
||||
//STUFF
|
||||
char *read = NULL;
|
||||
why2_bool exiting = 0;
|
||||
@ -1059,7 +1195,7 @@ void *why2_listen_server(void *socket)
|
||||
{
|
||||
continuing = 0;
|
||||
|
||||
read = read_socket_raw(*((int*) socket));
|
||||
read = read_socket_raw(connection);
|
||||
if (read == NULL) continue;
|
||||
|
||||
//GET CONTENT
|
||||
@ -1096,6 +1232,8 @@ void *why2_listen_server(void *socket)
|
||||
exiting = 1; //EXIT THIS THREAD
|
||||
} else if (strcmp(code, WHY2_CHAT_CODE_PICK_USERNAME) == 0 || strcmp(code, WHY2_CHAT_CODE_INVALID_USERNAME) == 0) //PICK USERNAME (COULD BE CAUSE BY INVALID USERNAME)
|
||||
{
|
||||
__why2_set_asking_username(1);
|
||||
|
||||
if (strcmp(code, WHY2_CHAT_CODE_INVALID_USERNAME) == 0) //INVALID USERNAME
|
||||
{
|
||||
printf(WHY2_CLEAR_AND_GO_UP WHY2_CLEAR_AND_GO_UP "%s\nInvalid username!\n\n\n", asking_username > 1 ? WHY2_CLEAR_AND_GO_UP : "");
|
||||
|
Loading…
x
Reference in New Issue
Block a user