diff options
| author | alpine <[email protected]> | 2020-06-13 22:27:52 +0200 |
|---|---|---|
| committer | alpine <[email protected]> | 2020-06-13 22:27:52 +0200 |
| commit | bad7b4f2d19f95b278fdcb3056be01cae9af1dbb (patch) | |
| tree | 5bef91f910a2c03d74df9693a077ee33b2fe7886 | |
| parent | Initial commit (diff) | |
| download | loader-bad7b4f2d19f95b278fdcb3056be01cae9af1dbb.tar.xz loader-bad7b4f2d19f95b278fdcb3056be01cae9af1dbb.zip | |
Client.
Message encryption.
Packet handler.
Disconnect event handler.
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | client/src/client/client.cpp | 23 | ||||
| -rw-r--r-- | client/src/client/client.h | 29 | ||||
| -rw-r--r-- | client/src/client/packet.h | 65 | ||||
| -rw-r--r-- | client/src/include.h | 28 | ||||
| -rw-r--r-- | client/src/main.cpp | 17 | ||||
| -rw-r--r-- | client/src/util/xor.cpp | 41 | ||||
| -rw-r--r-- | client/src/util/xor.h | 14 | ||||
| -rw-r--r-- | server/src/client/client.cpp | 27 | ||||
| -rw-r--r-- | server/src/client/client.h | 57 | ||||
| -rw-r--r-- | server/src/main.cpp | 34 | ||||
| -rw-r--r-- | server/src/server/packet.h | 42 | ||||
| -rw-r--r-- | server/src/server/server.cpp | 106 | ||||
| -rw-r--r-- | server/src/server/server.h | 46 | ||||
| -rw-r--r-- | server/src/server/ssl.h | 59 | ||||
| -rw-r--r-- | server/src/util/xor.cpp | 39 | ||||
| -rw-r--r-- | server/src/util/xor.h | 12 |
17 files changed, 539 insertions, 104 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index facc157..95ff2a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,5 +27,5 @@ add_subdirectory(client) target_include_directories(server PRIVATE ${PROJECT_SOURCE_DIR}/shared ${OPENSSL_INCLUDE_DIR} ${CPR_INCLUDE_DIRS}) target_link_libraries(server PRIVATE spdlog ${OPENSSL_LIBRARIES} ${CPR_LIBRARIES}) -target_include_directories(client PRIVATE ${PROJECT_SOURCE_DIR}/shared) -target_link_libraries(client PRIVATE spdlog) +target_include_directories(client PRIVATE ${PROJECT_SOURCE_DIR}/shared ${OPENSSL_INCLUDE_DIR}) +target_link_libraries(client PRIVATE spdlog ${OPENSSL_LIBRARIES} ) diff --git a/client/src/client/client.cpp b/client/src/client/client.cpp index 9fe2e36..71c9e11 100644 --- a/client/src/client/client.cpp +++ b/client/src/client/client.cpp @@ -2,15 +2,10 @@ #include "client.h" bool tcp::client::start(const std::string_view server_ip, - const uint16_t &port) { -#ifdef WINDOWS - WSADATA data; - int res = WSAStartup(MAKEWORD(2, 2), &data); - if (res != 0) { - io::logger->error("failed to initialize WSA."); - return false; - } -#endif + const uint16_t port) { + SSL_library_init(); + + m_ssl_ctx = SSL_CTX_new(TLS_client_method()); m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_socket == -1) { @@ -31,5 +26,15 @@ bool tcp::client::start(const std::string_view server_ip, return false; } + m_server_ssl = SSL_new(m_ssl_ctx); + SSL_set_fd(m_server_ssl, m_socket); + + ret = SSL_connect(m_server_ssl); + if(ret != 1) { + ret = SSL_get_error(m_server_ssl, ret); + io::logger->error("failed to connect to server ssl. {}", ret); + return false; + } + return true; } diff --git a/client/src/client/client.h b/client/src/client/client.h index 8f14071..7c1b8a7 100644 --- a/client/src/client/client.h +++ b/client/src/client/client.h @@ -1,6 +1,7 @@ #pragma once #include "../util/io.h" #include "../util/events.h" +#include "packet.h" namespace tcp { @@ -14,33 +15,39 @@ class client { int m_socket; std::atomic<uint8_t> m_state; - event<std::string> receive_event; + SSL *m_server_ssl; + SSL_CTX *m_ssl_ctx; public: + event<packet_t &> receive_event; + client() : m_socket{-1}, m_state{0} {} - bool start(const std::string_view server_ip, const uint16_t &port); + bool start(const std::string_view server_ip, const uint16_t port); + + int write(void *data, size_t size) { + return SSL_write(m_server_ssl, data, size); + } - bool send_message(const std::string_view msg) { - int ret = send(m_socket, msg.data(), msg.size(), 0); - return ret == msg.size(); + int read(void *data, size_t size) { + return SSL_read(m_server_ssl, data, size); } int get_socket() { return m_socket; } bool is_active() { return m_state == client_state::active; } void set_state(const uint8_t &state) { m_state = state; } - auto &on_recv() { return receive_event; } - static void read(client &client) { - std::array<char, 256> buf; + static void monitor(client &client) { + std::array<char, 4096> buf; while (client.is_active()) { - int ret = recv(client.get_socket(), &buf[0], buf.size(), 0); + int ret = client.read(&buf[0], buf.size()); if (ret <= 0) { io::logger->error("connection lost."); break; } - std::string msg(buf.data(), ret); - client.on_recv().call(msg); + packet_t packet(msg, packet_type::read); + + client.receive_event.call(packet); } } }; diff --git a/client/src/client/packet.h b/client/src/client/packet.h index b61c4e2..3930243 100644 --- a/client/src/client/packet.h +++ b/client/src/client/packet.h @@ -1,45 +1,42 @@ #pragma once +#include "../util/xor.h" namespace tcp { - constexpr size_t uid_len = 10; - struct packet_t { - std::string message; - char action; - std::array<char, uid_len> uid; - - // parse packet from server message after decryption - bool parse(const std::string msg) { - // first 10 bytes is the uid - bool res = set_uid(msg.substr(0, uid_len)); - if(!res) { - return false; +constexpr size_t uid_len = 10; + +enum packet_type : int { write = 0, read }; + +struct packet_t { + std::string message; + char action; + std::string uid; + + packet_t() {} + packet_t(const std::string msg, const packet_type &type, std::string userid = "") { + if (type == read) { + std::string decrypted{msg}; + enc::decrypt_message(decrypted); + + if (decrypted.size() < uid_len) { + io::logger->error("client packet message invalid!"); + return; } - action = msg[uid_len]; - const bool stream = static_cast<bool>(msg[uid_len + 1]); - if(stream) { - const size_t size = std::stoll(msg.substr(uid_len + 2)); + uid = decrypted.substr(0, uid_len); - // receive stream + action = decrypted[uid_len]; + message = decrypted.substr(uid_len); + } else { + uid = userid; - return true; - } + message = fmt::format("{}{}", uid, msg); - message = msg.substr(uid_len + 2); - return true; + enc::encrypt_message(message); } - bool set_uid(const std::string_view uid_str) { - const size_t uid_str_len = uid_str_len.size(); - if(uid_str_len != uid_len) { - io::logger->error("packet uid len mismatch!"); - return false; - } + } - for(size_t i = 0; i < uid_len; ++i) { - uid[i] = uid_str[i]; - } - - return true; - } - }; + operator bool() const { + return !message.empty() && !uid.empty(); + } }; +}; // namespace tcp diff --git a/client/src/include.h b/client/src/include.h index e2c647b..fe46e5a 100644 --- a/client/src/include.h +++ b/client/src/include.h @@ -1,24 +1,5 @@ #pragma once -#if defined(_WIN32) || defined(_WIN64) -#define WINDOWS -#endif - -#ifdef WINDOWS -#define _CRT_SECURE_NO_WARNINGS -#define _WINSOCK_DEPRECATED_NO_WARNINGS -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX - -#include <windows.h> -#include <stdio.h> -#include <winsock2.h> -#include <ws2tcpip.h> -#include <iphlpapi.h> - -#pragma comment( lib, "ws2_32.lib" ) -#endif - #include <stdio.h> #include <algorithm> #include <array> @@ -45,19 +26,16 @@ #include <future> #include <any> -#ifndef WINDOWS - -#define closesocket(socket) close(socket) - #include <arpa/inet.h> #include <netdb.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> -#endif #include <spdlog/fmt/fmt.h> #include <spdlog/spdlog.h> #include <spdlog/sinks/basic_file_sink.h> -#include <spdlog/sinks/stdout_color_sinks.h>
\ No newline at end of file +#include <spdlog/sinks/stdout_color_sinks.h> + +#include <openssl/ssl.h>
\ No newline at end of file diff --git a/client/src/main.cpp b/client/src/main.cpp index 1dc9db2..13da109 100644 --- a/client/src/main.cpp +++ b/client/src/main.cpp @@ -3,23 +3,32 @@ #include "client/client.h" int main(int argc, char *argv[]) { + io::init(); + tcp::client client; + if (client.start("127.0.0.1", 6666)) { io::logger->info("connected."); client.set_state(tcp::client_state::active); } - client.on_recv().add([&](std::string msg) { - io::logger->info(msg); + client.receive_event.add([&](tcp::packet_t &packet) { + if(!packet) + return; + + io::logger->info(packet.message); + io::logger->info(packet.uid.data()); }); - std::thread t{tcp::client::read, std::ref(client)}; + std::thread t{tcp::client::monitor, std::ref(client)}; while (client.is_active()) { std::string p; getline(std::cin, p); - bool ret = client.send_message(p); + tcp::packet_t packet(p, tcp::packet_type::write, "1234567890"); + + bool ret = client.write(packet.message.data(), packet.message.size()); if (!ret) { break; } diff --git a/client/src/util/xor.cpp b/client/src/util/xor.cpp new file mode 100644 index 0000000..483c161 --- /dev/null +++ b/client/src/util/xor.cpp @@ -0,0 +1,41 @@ +#include "../include.h" +#include "xor.h" + +char enc::gen_key() { + std::random_device r; + + std::default_random_engine e1(r()); + std::uniform_real_distribution<> uniform_dist(0, 255); + return static_cast<char>(uniform_dist(e1)); +} + +// XOR keys at the beginning of the message for clients +void enc::encrypt_message(std::string &str) { + std::array<char, key_num> keys; + for (size_t i = 0; i < key_num; i++) { + char key = gen_key(); + keys[i] = key; + str.insert(str.begin(), key); + } + + for (auto &key : keys) { + for (size_t i = key_num; i < str.size(); i++) { + str[i] ^= key; + } + } +} + +// XOR keys at the end of the message for server messages +void enc::decrypt_message(std::string &str) { + if (str.size() <= 50) return; + + std::string keys = str.substr(str.size() - key_num); + + for (auto &key : keys) { + for (size_t i = 0; i < str.size() - key_num; i++) { + str[i] ^= key; + } + } + + str.erase(str.end() - key_num, str.end()); +}
\ No newline at end of file diff --git a/client/src/util/xor.h b/client/src/util/xor.h new file mode 100644 index 0000000..1ae1ce2 --- /dev/null +++ b/client/src/util/xor.h @@ -0,0 +1,14 @@ +#pragma once + +namespace enc { +constexpr size_t key_num = 50; + +char gen_key(); + +// XOR keys at the beginning of the message for clients +void encrypt_message(std::string &str); + +// XOR keys at the end of the message for server messages +void decrypt_message(std::string &str); + +} // namespace enc
\ No newline at end of file diff --git a/server/src/client/client.cpp b/server/src/client/client.cpp new file mode 100644 index 0000000..4c458c8 --- /dev/null +++ b/server/src/client/client.cpp @@ -0,0 +1,27 @@ +#include "../include.h" +#include "../util/io.h" +#include "client.h" + +bool tcp::client::init_ssl(SSL_CTX *server_ctx) { + m_ssl = SSL_new(server_ctx); + if (!m_ssl) { + io::logger->error("failed to create ssl on client {}.", m_ip); + return false; + } + + int ret = SSL_set_fd(m_ssl, m_socket); + if (ret <= 0) { + io::logger->error("failed to set descriptor on client {}.", m_ip); + return false; + } + + ret = SSL_accept(m_ssl); + if (ret <= 0) { + int err = SSL_get_error(m_ssl, ret); + io::logger->error("client {} failed to accept ssl, return code {}", m_ip, + err); + return false; + } + + return true; +}
\ No newline at end of file diff --git a/server/src/client/client.h b/server/src/client/client.h new file mode 100644 index 0000000..5242ae7 --- /dev/null +++ b/server/src/client/client.h @@ -0,0 +1,57 @@ +#pragma once +#include "../server/packet.h" + +namespace tcp { +constexpr uint8_t client_version = 0; + +class client { + int m_socket; + SSL *m_ssl; + + time_t m_time; + + std::string m_ip; + std::array<char, tcp::uid_len> m_uid; + public: + client() : m_socket{-1} {}; + client(const int &socket, const std::string_view ip) + : m_socket{std::move(socket)}, m_ip{ip}, m_ssl{nullptr} { + + } + ~client() = default; + + bool init_ssl(SSL_CTX *server_ctx); + + void cleanup() { + close(m_socket); + SSL_shutdown(m_ssl); + SSL_free(m_ssl); + } + + int write(void *data, size_t size) { + return SSL_write(m_ssl, data, size); + } + + int read(void *data, size_t size) { + return SSL_read(m_ssl, data, size); + } + + bool set_uid(const std::string_view uid_str) { + const size_t uid_str_len = uid_str.size(); + if (uid_str_len != tcp::uid_len) { + io::logger->error("packet uid len mismatch!"); + return false; + } + + for (size_t i = 0; i < uid_len; ++i) { + m_uid[i] = uid_str[i]; + } + + return true; + } + + int &get_socket() { return m_socket; } + auto &get_ip() { return m_ip; } + auto &get_uid() { return m_uid; } +}; +}; // namespace tcp
\ No newline at end of file diff --git a/server/src/main.cpp b/server/src/main.cpp index f34c433..9db266f 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -2,13 +2,39 @@ #include "util/io.h" #include "util/commands.h" #include "server/server.h" +#include "util/xor.h" int main(int argc, char *argv[]) { io::init(false); - tcp::server server; - server.start("6666"); - server.start("8981"); + tcp::server server("6666"); - std::cin.get(); + server.start(); + + server.connect_event.add([&](tcp::client &client) { + io::logger->info("{} connected.", client.get_ip()); + }); + + server.disconnect_event.add([&](tcp::client &client) { + auto it = std::find_if(server.client_stack.begin(), server.client_stack.end(), [&](tcp::client &c) { + return client.get_socket() == client.get_socket(); + }); + + server.client_stack.erase(it); + client.cleanup(); + + io::logger->info("{} disconnected.", client.get_ip()); + }); + + server.receive_event.add([&](tcp::packet_t &packet, tcp::client &client) { + if (!packet) return; + + io::logger->info("{} : {}", packet.uid.data(), packet.message); + + tcp::packet_t resp("hello nigga", tcp::packet_type::write, "1234567890"); + client.write(resp.message.data(), resp.message.size()); + }); + + std::thread t{tcp::server::monitor, std::ref(server)}; + t.join(); } diff --git a/server/src/server/packet.h b/server/src/server/packet.h index 02d90d1..3930243 100644 --- a/server/src/server/packet.h +++ b/server/src/server/packet.h @@ -1,10 +1,42 @@ #pragma once +#include "../util/xor.h" namespace tcp { - constexpr uint8_t uid_len = 10; +constexpr size_t uid_len = 10; - struct packet_t { - std::string message; - std::array<char, uid_len> uid; +enum packet_type : int { write = 0, read }; + +struct packet_t { + std::string message; + char action; + std::string uid; + + packet_t() {} + packet_t(const std::string msg, const packet_type &type, std::string userid = "") { + if (type == read) { + std::string decrypted{msg}; + enc::decrypt_message(decrypted); + + if (decrypted.size() < uid_len) { + io::logger->error("client packet message invalid!"); + return; + } + + uid = decrypted.substr(0, uid_len); + + action = decrypted[uid_len]; + message = decrypted.substr(uid_len); + } else { + uid = userid; + + message = fmt::format("{}{}", uid, msg); + + enc::encrypt_message(message); + } + } + + operator bool() const { + return !message.empty() && !uid.empty(); } -} +}; +}; // namespace tcp diff --git a/server/src/server/server.cpp b/server/src/server/server.cpp index 2f684e1..b140665 100644 --- a/server/src/server/server.cpp +++ b/server/src/server/server.cpp @@ -2,8 +2,13 @@ #include "../util/io.h" #include "server.h" -bool tcp::server::start(const std::string_view port) { - io::logger->info("starting server on port {}...", port.data()); +bool tcp::server::start() { + io::logger->info("starting server on port {}...", m_port.data()); + + ssl ctx("ssl/server.crt", "ssl/server.key", "ssl/rootCA.crt"); + if (!ctx.init()) return false; + + m_ctx = std::move(ctx.get_context()); m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_socket < 0) { @@ -19,7 +24,7 @@ bool tcp::server::start(const std::string_view port) { hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; - int ret = getaddrinfo(nullptr, port.data(), &hints, &addrinfo); + int ret = getaddrinfo(nullptr, m_port.data(), &hints, &addrinfo); if (ret != 0) { io::logger->critical("failed to get address info."); close(m_socket); @@ -37,16 +42,103 @@ bool tcp::server::start(const std::string_view port) { ret = listen(m_socket, SOMAXCONN); if (ret < 0) { - io::logger->critical("failed to listen on port {}.", port.data()); + io::logger->critical("failed to listen on port {}.", m_port.data()); close(m_socket); return false; } - io::logger->info("listening on {}.", port.data()); + io::logger->info("listening on {}.", m_port.data()); + + m_status = true; return true; } +tcp::select_status tcp::server::peek() { + FD_ZERO(&m_server_set); + FD_SET(m_socket, &m_server_set); + + int maxfd = m_socket; + + for (auto &c : client_stack) { + const int s = c.get_socket(); + FD_SET(s, &m_server_set); + + maxfd = std::max(maxfd, s); + } + + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + + const int ret = select(maxfd + 1, &m_server_set, nullptr, nullptr, &tv); + if (ret < 0) { + io::logger->error("select error : {}", strerror(errno)); + return tcp::select_status::error; + } + + if (ret == 0) { + return tcp::select_status::standby; + } + + return tcp::select_status::ready; +} + +void tcp::server::accept_client() { + if (!FD_ISSET(m_socket, &m_server_set)) return; + + struct sockaddr_in addr; + socklen_t len = sizeof(addr); + const int client_socket = + accept(m_socket, reinterpret_cast<sockaddr *>(&addr), &len); + + const auto ip = inet_ntoa(addr.sin_addr); + if (client_socket < 0) { + io::logger->warn("{} failed to accept.", ip); + close(client_socket); + } else { + client cli(client_socket, ip); + if (!cli.init_ssl(m_ctx)) { + cli.cleanup(); + return; + } + + // check for an existing connection + auto it = std::find_if(client_stack.begin(), client_stack.end(), + [&](client &c) { return c.get_ip() == ip; }); + if (it != client_stack.end()) { + io::logger->info("{} is already connected, dropping...", ip); + cli.cleanup(); + return; + } + + connect_event.call(cli); + client_stack.emplace_back(cli); + } +} + +void tcp::server::receive() { + std::array<char, 4096> buf; + for (auto &c : client_stack) { + const int socket = c.get_socket(); + + if (!FD_ISSET(socket, &m_server_set)) continue; + + buf.fill(0); + + const int read = c.read(&buf[0], buf.size()); + if (read > 0) { + std::string msg(buf.data(), read); + + tcp::packet_t packet(msg, tcp::packet_type::read); + + receive_event.call(packet, c); + } else { + disconnect_event.call(c); + } + } +} + void tcp::server::stop() { - io::logger->info("stopping server on port {}.", m_port); - close(m_socket); + io::logger->info("stopping server on port {}.", m_port); + close(m_socket); }
\ No newline at end of file diff --git a/server/src/server/server.h b/server/src/server/server.h index f848ae2..39b9580 100644 --- a/server/src/server/server.h +++ b/server/src/server/server.h @@ -1,12 +1,54 @@ #pragma once +#include "../client/client.h" +#include "../util/events.h" +#include "ssl.h" namespace tcp { +constexpr uint8_t server_version = 0; + +enum select_status : int { error = 0, standby, ready }; + class server { int m_socket; - + std::string_view m_port; + + fd_set m_server_set; + SSL_CTX *m_ctx; + + std::atomic<bool> m_status = false; + public: + std::vector<tcp::client> client_stack; + - bool start(const std::string_view port); + event<client &> connect_event; + event<packet_t &, client &> receive_event; + event<client &> disconnect_event; + + server(const std::string_view port) : m_port{port} {} + ~server() = default; + + bool start(); + select_status peek(); + void accept_client(); + void receive(); void stop(); + + bool running() { return m_status; } + + static void monitor(server &srv) { + while (srv.running()) { + auto ret = srv.peek(); + if (ret == select_status::ready) { + srv.accept_client(); + srv.receive(); + } else if (ret == select_status::standby) { + // check for timeout + } else { + break; + } + } + } }; + }; // namespace tcp diff --git a/server/src/server/ssl.h b/server/src/server/ssl.h index 7b9637e..06826be 100644 --- a/server/src/server/ssl.h +++ b/server/src/server/ssl.h @@ -1 +1,58 @@ -#pragma once
\ No newline at end of file +#pragma once + +class ssl { + std::string_view m_cert, m_key, m_ca; + std::string m_passphrase; + SSL_CTX* m_ctx; + + public: + ssl(const std::string_view cert, const std::string_view key, + const std::string_view ca = "") + : m_cert{cert}, m_key{key}, m_ca{ca}, m_ctx{nullptr} { + SSL_library_init(); + } + ~ssl() = default; + + bool init() { + m_ctx = SSL_CTX_new(TLS_server_method()); + if (!m_ctx) { + io::logger->error("failed to create ssl context."); + return false; + } + + int res = + SSL_CTX_use_certificate_file(m_ctx, m_cert.data(), SSL_FILETYPE_PEM); + if (res != 1) { + io::logger->error("failed to load certificate."); + return false; + } + + if (!m_passphrase.empty()) + SSL_CTX_set_default_passwd_cb_userdata(m_ctx, m_passphrase.data()); + + res = SSL_CTX_use_PrivateKey_file(m_ctx, m_key.data(), SSL_FILETYPE_PEM); + if (res != 1) { + io::logger->error("failed to load private key."); + return false; + } + + res = SSL_CTX_check_private_key(m_ctx); + if (res != 1) { + io::logger->error("failed to verify private key."); + return false; + } + + res = SSL_CTX_load_verify_locations(m_ctx, m_ca.data(), nullptr); + if (res != 1) { + io::logger->error("failed to load root ca."); + return false; + } + + SSL_CTX_set_verify(m_ctx, SSL_VERIFY_PEER, 0); + + return true; + } + + void set_passphrase(const std::string_view phrase) { m_passphrase = phrase; } + auto &get_context() { return m_ctx; } +}; diff --git a/server/src/util/xor.cpp b/server/src/util/xor.cpp new file mode 100644 index 0000000..a00ecc9 --- /dev/null +++ b/server/src/util/xor.cpp @@ -0,0 +1,39 @@ +#include "../include.h" +#include "xor.h" + +char enc::gen_key() { + std::random_device r; + + std::default_random_engine e1(r()); + std::uniform_real_distribution<> uniform_dist(0, 255); + return static_cast<char>(uniform_dist(e1)); +} + +void enc::encrypt_message(std::string &str) { + std::array<char, key_len> keys; + for (size_t i = 0; i < key_len; i++) { + keys[i] = gen_key(); + str.insert(str.end(), keys[i]); + } + + for (auto &key : keys) { + for (size_t i = 0; i < str.size() - key_len; i++) { + str[i] ^= key; + } + } +} + +void enc::decrypt_message(std::string &str) { + if (str.size() <= key_len) return; + + std::string keys = str.substr(0, key_len); + std::reverse(keys.begin(), keys.end()); + + for (auto &key : keys) { + for (size_t i = key_len; i < str.size(); i++) { + str[i] ^= key; + } + } + + str.erase(str.begin(), str.begin() + key_len); +}
\ No newline at end of file diff --git a/server/src/util/xor.h b/server/src/util/xor.h new file mode 100644 index 0000000..7180945 --- /dev/null +++ b/server/src/util/xor.h @@ -0,0 +1,12 @@ +#pragma once + +namespace enc { +constexpr size_t key_len = 50; + +char gen_key(); + +void encrypt_message(std::string &str); + +void decrypt_message(std::string &str); + +} // namespace enc
\ No newline at end of file |