diff options
author | Ubuntu <baitinq@Peces.qluofd4gyjdubpy0ojfn3gxkic.bx.internal.cloudapp.net> | 2020-06-05 17:12:19 +0000 |
---|---|---|
committer | Ubuntu <baitinq@Peces.qluofd4gyjdubpy0ojfn3gxkic.bx.internal.cloudapp.net> | 2020-06-05 17:12:19 +0000 |
commit | c739aa0cf8fc885c8cad79d2d639d0ecd49bd5ae (patch) | |
tree | 66fb3ec1af228082fab674e9aa98ba17d6b9cb44 /utils.hpp | |
download | encrypted-chat-c739aa0cf8fc885c8cad79d2d639d0ecd49bd5ae.tar.gz encrypted-chat-c739aa0cf8fc885c8cad79d2d639d0ecd49bd5ae.tar.bz2 encrypted-chat-c739aa0cf8fc885c8cad79d2d639d0ecd49bd5ae.zip |
Diffstat (limited to 'utils.hpp')
-rw-r--r-- | utils.hpp | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/utils.hpp b/utils.hpp new file mode 100644 index 0000000..71762b2 --- /dev/null +++ b/utils.hpp @@ -0,0 +1,204 @@ +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "encryption.hpp" + +#define ERROR_LOG(msg, ...) printf("[!] "); printf(msg, ##__VA_ARGS__); fflush(stdout); +#define INFO_LOG(msg, ...) printf("[+] "); printf(msg, ##__VA_ARGS__); fflush(stdout); +#define PRINT_MSG(name, id, msg, sv) if(sv) printf("[%s]: %s", name, msg); else printf("[%s-%d]: %s", name, id, msg); fflush(stdout); + +int start_client(std::vector<int>* clients, Options* options); +int handle_incoming_packet(Packet* packet, int* clientfd, std::vector<int>* clients, Options* options); +int handle_packet_connect(PacketConnect* packet, int* clientfd, std::vector<int>* clients, Options* options); +int handle_packet_disconnect(PacketDisconnect* packet, int* clientfd, std::vector<int>* clients, Options* options); +int handle_packet_message(PacketMessage* packet, int* clientfd, std::vector<int>* clients, Options* options); +int notify_clients(Packet* packet, std::vector<int>* clients, Options* options); +int send_packet(Packet* packet, int* sockfd, Options* options, void* extra_data); +int add_client(int* clientfd, std::vector<int>* clients); +int remove_client(int* clientfd, std::vector<int>* clients); +int enable_echo(); +int disable_echo(); + +int start_client(std::vector<int>* clients, Options* options) +{ + char* stc; + size_t bytes; + while(1) + { + stc = NULL; + getline(&stc, &bytes, stdin); //need to make it so it doesnt print to terminal + //disable_echo(); + Packet packet {}; + packet.type = PacketType::packet_message; + packet.data.packet_message.server = options->server; + strncpy(packet.data.packet_message.name, options->name, sizeof(packet.data.packet_message.name)); + strncpy(packet.data.packet_message.message, stc, sizeof(packet.data.packet_message)); + if(options->server) + { + if(options->encryption) + encrypt(options, (char*)&packet, sizeof(packet)); + handle_incoming_packet(&packet, &options->sockfd, clients, options); + } + else + if(send_packet(&packet, &options->sockfd, options, NULL)) + { + free(stc); + return 0; + } + + free(stc); + } + + return 0; +} + +int handle_incoming_packet(Packet* packet, int* sockfd, std::vector<int>* clients, Options* options) +{ + int status = decrypt(options, (char*)packet, sizeof(*packet)); + if(!status) + switch(packet->type) + { + case PacketType::packet_connect: + status = handle_packet_connect(&packet->data.packet_connect, sockfd, clients, options); + break; + case PacketType::packet_disconnect: + status = handle_packet_disconnect(&packet->data.packet_disconnect, sockfd, clients, options); + break; + case PacketType::packet_message: + status = handle_packet_message(&packet->data.packet_message, sockfd, options->server ? clients : NULL, options); + break; + case PacketType::packet_ping: + status = -2; //dont notify + break; + default: + status = -1; + break; + } + + if(options->server && !status) + status = notify_clients(packet, clients, options); + + return status; +} + +int handle_packet_connect(PacketConnect* packet, int* clientfd, std::vector<int>* clients, Options* options) +{ + int status = 0; + if(options->server) + { + if(options->pass && (!packet->pass || strcmp(options->password, packet->password))) + { + status = -3; + INFO_LOG("Player tried to join with an incorrect password.\n"); + close(*clientfd); + goto end; + } + + status = add_client(clientfd, clients); + } + + INFO_LOG("%s joined the chat!\n", packet->name); + + + end: + return status; +} + +int handle_packet_disconnect(PacketDisconnect* packet, int* clientfd, std::vector<int>* clients, Options* options) +{ + int status = 0; + if(options->server) + status = remove_client(clientfd, clients); + + INFO_LOG("%s left the chat!\n", packet->name); + + return status; +} + +int handle_packet_message(PacketMessage* packet, int* clientfd, std::vector<int>* clients, Options* options) +{ + if(options->server) + { + packet->client_fd = *clientfd; + std::vector<int>::iterator pos = std::find(clients->begin(), clients->end(), *clientfd); + if(*clientfd != options->sockfd && pos == clients->end()) + return 1; + } + + packet->client_fd = *clientfd; + + if(!options->server || options->interactive) + { + PRINT_MSG(packet->name, packet->client_fd, packet->message, packet->server); + } + + return 0; +} + +int notify_clients(Packet* packet, std::vector<int>* clients, Options* options) +{ + for(int clientfd : *clients) + if(send_packet(packet, &clientfd, options, NULL)) + return 1; + + return 0; +} + +int send_packet(Packet* packet, int* sockfd, Options* options, void* extra_data) +{ + int status = encrypt(options, (char*)packet, sizeof(*packet)); + if(status) + return status; + if(send(*sockfd, (const char*)packet, sizeof(*packet), 0) < 0) + status = 1; + status = decrypt(options, (char*)packet, sizeof(*packet)); + + return status; +} + +int add_client(int* clientfd, std::vector<int>* clients) +{ + std::vector<int>::iterator pos = std::find(clients->begin(), clients->end(), *clientfd); + if(pos == clients->end()) + { + clients->push_back(*clientfd); + return 0; + } + + return 1; +} + +int remove_client(int* clientfd, std::vector<int>* clients) +{ + std::vector<int>::iterator pos = std::find(clients->begin(), clients->end(), *clientfd); + if(pos != clients->end()) + { + clients->erase(pos); + return 0; + } + + close(*clientfd); + + return 1; +} + +int enable_echo() +{ + struct termios term; + tcgetattr(0, &term); + term.c_lflag |= ECHO; + tcsetattr(0, TCSAFLUSH, &term); + + return 0; +} + +int disable_echo() +{ + struct termios term; + tcgetattr(0, &term); + term.c_lflag &= ~ECHO; + tcsetattr(0, TCSAFLUSH, &term); + + return 0; +} |