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 /client | |
| parent | Initial commit (diff) | |
| download | loader-bad7b4f2d19f95b278fdcb3056be01cae9af1dbb.tar.xz loader-bad7b4f2d19f95b278fdcb3056be01cae9af1dbb.zip | |
Client.
Message encryption.
Packet handler.
Disconnect event handler.
Diffstat (limited to 'client')
| -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 |
7 files changed, 134 insertions, 83 deletions
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 |