aboutsummaryrefslogtreecommitdiff
path: root/client/src
diff options
context:
space:
mode:
authoralpine <[email protected]>2020-06-13 22:27:52 +0200
committeralpine <[email protected]>2020-06-13 22:27:52 +0200
commitbad7b4f2d19f95b278fdcb3056be01cae9af1dbb (patch)
tree5bef91f910a2c03d74df9693a077ee33b2fe7886 /client/src
parentInitial commit (diff)
downloadloader-bad7b4f2d19f95b278fdcb3056be01cae9af1dbb.tar.xz
loader-bad7b4f2d19f95b278fdcb3056be01cae9af1dbb.zip
Client.
Message encryption. Packet handler. Disconnect event handler.
Diffstat (limited to 'client/src')
-rw-r--r--client/src/client/client.cpp23
-rw-r--r--client/src/client/client.h29
-rw-r--r--client/src/client/packet.h65
-rw-r--r--client/src/include.h28
-rw-r--r--client/src/main.cpp17
-rw-r--r--client/src/util/xor.cpp41
-rw-r--r--client/src/util/xor.h14
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