aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/client/blacklist.h100
-rw-r--r--server/src/client/client.h14
-rw-r--r--server/src/forum/forum.cpp47
-rw-r--r--server/src/forum/forum.h24
-rw-r--r--server/src/main.cpp57
-rw-r--r--server/src/server/packet.h4
-rw-r--r--server/src/server/server.h5
7 files changed, 194 insertions, 57 deletions
diff --git a/server/src/client/blacklist.h b/server/src/client/blacklist.h
index 397dc6c..70f5c7a 100644
--- a/server/src/client/blacklist.h
+++ b/server/src/client/blacklist.h
@@ -1,60 +1,54 @@
#pragma once
-namespace tcp {
-
struct blacklist_data {
- std::string ip;
- std::string hwid;
+ std::string ip;
+ std::string hwid;
};
class blacklist {
-
-nlohmann::json m_data;
-std::string m_name;
-
-public:
- void init(const std::string_view file = "blacklist") {
- m_name = file;
-
- std::string data;
- if(!io::read_file(file, data))
- return;
-
- if(!nlohmann::json::accept(data)) {
- io::logger->error("blacklist file isnt valid json.");
- return;
- }
-
- m_data = nlohmann::json::parse(data);
- }
-
- void add(const blacklist_data &data) {
- m_data["ips"].emplace_back(data.ip);
- m_data["hwids"].emplace_back(data.hwid);
-
- save();
- }
-
- void save() {
- std::ofstream o(m_name, std::ios::trunc);
- o << std::setw(4) << m_data;
- o.close();
- }
-
- bool find(const std::string &key) {
- for(auto &item : m_data["ips"]) {
- if(item.get<std::string>() == key) {
- return true;
- }
- }
-
- for(auto &item : m_data["hwids"]) {
- if(item.get<std::string>() == key) {
- return true;
- }
- }
- return false;
- }
+ nlohmann::json m_data;
+ std::string m_name;
+
+ public:
+ void init(const std::string_view file = "blacklist") {
+ m_name = file;
+
+ std::string data;
+ if (!io::read_file(file, data)) return;
+
+ if (!nlohmann::json::accept(data)) {
+ io::logger->error("blacklist file isnt valid json.");
+ return;
+ }
+
+ m_data = nlohmann::json::parse(data);
+ }
+
+ void add(const blacklist_data &data) {
+ m_data["ips"].emplace_back(data.ip);
+ m_data["hwids"].emplace_back(data.hwid);
+
+ save();
+ }
+
+ void save() {
+ std::ofstream o(m_name, std::ios::trunc);
+ o << std::setw(4) << m_data;
+ o.close();
+ }
+
+ bool find(const std::string &key) {
+ for (auto &item : m_data["ips"]) {
+ if (item.get<std::string>() == key) {
+ return true;
+ }
+ }
+
+ for (auto &item : m_data["hwids"]) {
+ if (item.get<std::string>() == key) {
+ return true;
+ }
+ }
+ return false;
+ }
};
-
-}; \ No newline at end of file
diff --git a/server/src/client/client.h b/server/src/client/client.h
index a3d558d..2777a0d 100644
--- a/server/src/client/client.h
+++ b/server/src/client/client.h
@@ -3,6 +3,17 @@
namespace tcp {
+enum client_state {
+ idle = 0, logged_in, waiting, injected
+};
+
+enum login_result {
+ login_fail = 15494,
+ hwid_mismatch = 11006,
+ login_success = 61539,
+ banned = 28618
+};
+
class client {
int m_socket;
SSL* m_ssl;
@@ -14,10 +25,11 @@ class client {
public:
std::string hwid;
+ int state;
client() : m_socket{-1} {};
client(const int& socket, const std::string_view ip)
- : m_socket{std::move(socket)}, m_ip{ip}, m_ssl{nullptr} {}
+ : m_socket{std::move(socket)}, m_ip{ip}, m_ssl{nullptr}, state{-1} {}
~client() = default;
bool init_ssl(SSL_CTX* server_ctx);
diff --git a/server/src/forum/forum.cpp b/server/src/forum/forum.cpp
new file mode 100644
index 0000000..57eff72
--- /dev/null
+++ b/server/src/forum/forum.cpp
@@ -0,0 +1,47 @@
+#include "../include.h"
+#include "../util/io.h"
+#include "forum.h"
+
+void xenforo_forum::init(const std::string_view link, const std::string_view key) {
+ m_link = link;
+ m_api = key;
+
+ m_header = cpr::Header{{"Content-Type", "application/x-www-form-urlencoded"},
+ {"XF-Api-Key", m_api.data()},
+ {"XF-Api-User", "1"},
+ {"api_bypass_permissions", "1"}};
+}
+
+int xenforo_forum::check_login(const std::string_view username,
+ const std::string_view password, user_data &data) {
+ auto url = fmt::format("{}{}", m_link, "/auth/");
+ auto post_data = fmt::format("login={}&password={}", username, password);
+
+ auto req = cpr::Post(cpr::Url{url}, cpr::Body{post_data}, cpr::Timeout{10000},
+ m_header);
+
+ if (req.elapsed >= 10) {
+ io::logger->warn("login request on {} timed out.", username);
+ return forum_response::api_timeout;
+ }
+
+ int status_code = req.status_code;
+ auto response = req.text;
+
+ if (!nlohmann::json::accept(response)) {
+ io::logger->error("login response on {} isnt valid json.", username);
+ return forum_response::api_fail;
+ }
+
+ if (status_code >= 400) {
+ return forum_response::api_error;
+ }
+
+ auto j = nlohmann::json::parse(response);
+
+ data.banned = j["user"]["is_banned"].get<bool>();
+ // data.active = check user group
+ data.hwid = j["user"]["custom_fields"]["hwid"].get<std::string>();
+
+ return forum_response::api_success;
+} \ No newline at end of file
diff --git a/server/src/forum/forum.h b/server/src/forum/forum.h
new file mode 100644
index 0000000..df18cb4
--- /dev/null
+++ b/server/src/forum/forum.h
@@ -0,0 +1,24 @@
+#pragma once
+#include <cpr/cpr.h>
+#include <json.hpp>
+// XenForo forum api wrapper
+
+struct user_data {
+ std::string hwid;
+ bool banned;
+ bool active;
+};
+
+enum forum_response { api_fail = 0, api_error, api_timeout, api_success };
+
+class xenforo_forum {
+ std::string m_link;
+ std::string m_api;
+
+ cpr::Header m_header;
+
+ public:
+ void init(const std::string_view link, const std::string_view key);
+ int check_login(const std::string_view username,
+ const std::string_view password, user_data &data);
+}; \ No newline at end of file
diff --git a/server/src/main.cpp b/server/src/main.cpp
index 779b610..0947b75 100644
--- a/server/src/main.cpp
+++ b/server/src/main.cpp
@@ -21,6 +21,8 @@ int main(int argc, char* argv[]) {
client.gen_session();
client.write(tcp::packet_t(version, tcp::packet_type::write, client(),
tcp::packet_id::session));
+
+ client.state = tcp::client_state::idle;
});
client_server.disconnect_event.add([&](tcp::client& client) {
@@ -76,6 +78,61 @@ int main(int argc, char* argv[]) {
}
}
+ if (id == tcp::packet_id::login_req) {
+ if (client.state != tcp::client_state::idle) {
+ return;
+ }
+
+ auto pos = message.find(",");
+ if (pos != std::string::npos) {
+ auto user = message.substr(0, pos);
+ auto pass = message.substr(pos + 1);
+
+ user_data data{};
+ //int ret = client_server.forum().check_login(user, pass, data);
+ int ret = forum_response::api_success;
+ if (ret == forum_response::api_success) {
+
+ nlohmann::json j;
+
+ if (data.banned) {
+ io::logger->warn("{} is forum banned, dropping...", user);
+
+ j["result"] = tcp::login_result::banned;
+
+ client.write(tcp::packet_t(j.dump(), tcp::packet_type::write,
+ session, tcp::packet_id::login_resp));
+
+ client_server.disconnect_event.call(client);
+ return;
+ }
+ // new user/no hwid, register the hwid on the forums
+ if (data.hwid.empty()) {
+ data.hwid = client.hwid;
+ }
+
+ // invalid hwid
+ if (data.hwid != client.hwid) {
+
+ j["result"] = tcp::login_result::hwid_mismatch;
+
+ client.write(tcp::packet_t(j.dump(), tcp::packet_type::write,
+ session, tcp::packet_id::login_resp));
+
+ client_server.disconnect_event.call(client);
+ return;
+ }
+
+ j["result"] = tcp::login_result::banned;
+
+ client.write(tcp::packet_t(j.dump(), tcp::packet_type::write,
+ session, tcp::packet_id::login_resp));
+
+ client.state = tcp::client_state::logged_in;
+ }
+ }
+ }
+
client.write(tcp::packet_t(message, tcp::packet_type::write, session));
});
diff --git a/server/src/server/packet.h b/server/src/server/packet.h
index 261109d..c0aab12 100644
--- a/server/src/server/packet.h
+++ b/server/src/server/packet.h
@@ -7,9 +7,9 @@ namespace tcp {
constexpr size_t session_id_len = 10;
constexpr size_t message_len = 512;
-enum packet_type : int { write = 0, read };
+enum packet_type { write = 0, read };
-enum packet_id : int { message = 0, hwid, session };
+enum packet_id { message = 0, hwid, session, login_req, login_resp, process_list };
struct packet_t {
std::string message;
diff --git a/server/src/server/server.h b/server/src/server/server.h
index ede0683..7fa5dc4 100644
--- a/server/src/server/server.h
+++ b/server/src/server/server.h
@@ -2,12 +2,13 @@
#include "../client/client.h"
#include "../util/events.h"
#include "../client/blacklist.h"
+#include "../forum/forum.h"
#include "ssl.h"
namespace tcp {
constexpr uint8_t server_version = 0;
-enum select_status : int { error = 0, standby, ready };
+enum select_status { error = 0, standby, ready };
class server {
int m_socket;
@@ -21,6 +22,7 @@ class server {
std::vector<tcp::client> client_stack;
blacklist m_blacklist;
+ xenforo_forum m_forum;
public:
event<client&> connect_event;
event<packet_t&, client&> receive_event;
@@ -41,6 +43,7 @@ class server {
auto &operator()() { return client_stack; }
auto &bl() { return m_blacklist; }
+ auto &forum() { return m_forum; }
static void monitor(server& srv) {
while (srv) {