Version 1.0.0

This commit is contained in:
2026-01-01 16:22:17 +01:00
parent 3dc5c04bf1
commit 1f5a0585f3
15 changed files with 187 additions and 38 deletions

View File

@@ -14,6 +14,7 @@
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <string>
#include <columnlynx/common/net/protocol_structs.hpp>
#include <columnlynx/common/net/virtual_interface.hpp>
@@ -29,6 +30,7 @@ namespace ColumnLynx::Net::TCP {
std::shared_ptr<std::array<uint8_t, 32>> aesKey,
std::shared_ptr<uint64_t> sessionIDRef,
bool insecureMode,
std::string& configPath,
std::shared_ptr<VirtualInterface> tun = nullptr)
:
mResolver(ioContext),
@@ -42,10 +44,11 @@ namespace ColumnLynx::Net::TCP {
mHeartbeatTimer(mSocket.get_executor()),
mLastHeartbeatReceived(std::chrono::steady_clock::now()),
mLastHeartbeatSent(std::chrono::steady_clock::now()),
mTun(tun)
mTun(tun),
mConfigDirPath(configPath)
{
// Preload the config map
mRawClientConfig = Utils::getConfigMap("client_config");
mRawClientConfig = Utils::getConfigMap(configPath + "client_config");
auto itPubkey = mRawClientConfig.find("CLIENT_PUBLIC_KEY");
auto itPrivkey = mRawClientConfig.find("CLIENT_PRIVATE_KEY");
@@ -54,16 +57,22 @@ namespace ColumnLynx::Net::TCP {
Utils::log("Loading keypair from config file.");
PublicKey pk;
PrivateKey sk;
PrivateSeed seed;
std::copy_n(Utils::hexStringToBytes(itPrivkey->second).begin(), sk.size(), sk.begin()); // This is extremely stupid, but the C++ compiler has forced my hand (I would've just used to_array, but fucking asio decls)
std::copy_n(Utils::hexStringToBytes(itPrivkey->second).begin(), seed.size(), seed.begin()); // This is extremely stupid, but the C++ compiler has forced my hand (I would've just used to_array, but fucking asio decls)
std::copy_n(Utils::hexStringToBytes(itPubkey->second).begin(), pk.size(), pk.begin());
mLibSodiumWrapper->setKeys(pk, sk);
if (!mLibSodiumWrapper->recomputeKeys(seed, pk)) {
throw std::runtime_error("Failed to recompute keypair from config file values!");
}
Utils::debug("Newly-Loaded Public Key: " + Utils::bytesToHexString(mLibSodiumWrapper->getPublicKey(), 32));
} else {
#if defined(DEBUG)
Utils::warn("No keypair found in config file! Using random key.");
#else
throw std::runtime_error("No keypair found in config file! Cannot start client without keys.");
#endif
}
}
@@ -109,5 +118,6 @@ namespace ColumnLynx::Net::TCP {
Protocol::TunConfig mTunConfig;
std::shared_ptr<VirtualInterface> mTun = nullptr;
std::unordered_map<std::string, std::string> mRawClientConfig;
std::string mConfigDirPath;
};
}

View File

@@ -17,6 +17,7 @@
namespace ColumnLynx {
using PublicKey = std::array<uint8_t, crypto_sign_PUBLICKEYBYTES>; // Ed25519
using PrivateKey = std::array<uint8_t, crypto_sign_SECRETKEYBYTES>; // Ed25519
using PrivateSeed = std::array<uint8_t, crypto_sign_SEEDBYTES>; // 32 bytes
using Signature = std::array<uint8_t, crypto_sign_BYTES>; // 64 bytes
using SymmetricKey = std::array<uint8_t, crypto_aead_chacha20poly1305_ietf_KEYBYTES>; // 32 bytes
using Nonce = std::array<uint8_t, crypto_aead_chacha20poly1305_ietf_NPUBBYTES>; // 12 bytes
@@ -53,6 +54,9 @@ namespace ColumnLynx::Utils {
}
}
// Recompute the keypair from a given private seed; Will return false on failure
bool recomputeKeys(PrivateSeed privateSeed, PublicKey storedPubKey);
// Helper section
// Generates a random 256-bit (32-byte) array

View File

@@ -44,7 +44,7 @@ namespace ColumnLynx::Utils {
std::string getVersion();
unsigned short serverPort();
unsigned char protocolVersion();
std::vector<std::string> getWhitelistedKeys();
std::vector<std::string> getWhitelistedKeys(std::string basePath);
// Raw byte to hex string conversion helper
std::string bytesToHexString(const uint8_t* bytes, size_t length);

View File

@@ -28,9 +28,10 @@ namespace ColumnLynx::Net::TCP {
asio::ip::tcp::socket socket,
std::shared_ptr<Utils::LibSodiumWrapper> sodiumWrapper,
std::unordered_map<std::string, std::string>* serverConfig,
std::string configDirPath,
std::function<void(pointer)> onDisconnect)
{
auto conn = pointer(new TCPConnection(std::move(socket), sodiumWrapper, serverConfig));
auto conn = pointer(new TCPConnection(std::move(socket), sodiumWrapper, serverConfig, configDirPath));
conn->mOnDisconnect = std::move(onDisconnect);
return conn;
}
@@ -50,14 +51,15 @@ namespace ColumnLynx::Net::TCP {
std::array<uint8_t, 32> getAESKey() const;
private:
TCPConnection(asio::ip::tcp::socket socket, std::shared_ptr<Utils::LibSodiumWrapper> sodiumWrapper, std::unordered_map<std::string, std::string>* serverConfig)
TCPConnection(asio::ip::tcp::socket socket, std::shared_ptr<Utils::LibSodiumWrapper> sodiumWrapper, std::unordered_map<std::string, std::string>* serverConfig, std::string configDirPath)
:
mHandler(std::make_shared<MessageHandler>(std::move(socket))),
mLibSodiumWrapper(sodiumWrapper),
mRawServerConfig(serverConfig),
mHeartbeatTimer(mHandler->socket().get_executor()),
mLastHeartbeatReceived(std::chrono::steady_clock::now()),
mLastHeartbeatSent(std::chrono::steady_clock::now())
mLastHeartbeatSent(std::chrono::steady_clock::now()),
mConfigDirPath(configDirPath)
{}
// Start the heartbeat routine
@@ -77,5 +79,6 @@ namespace ColumnLynx::Net::TCP {
std::chrono::steady_clock::time_point mLastHeartbeatSent;
int mMissedHeartbeats = 0;
std::string mRemoteIP; // Cached remote IP to avoid calling remote_endpoint() on closed sockets
std::string mConfigDirPath;
};
}

View File

@@ -25,14 +25,17 @@ namespace ColumnLynx::Net::TCP {
TCPServer(asio::io_context& ioContext,
uint16_t port,
std::shared_ptr<Utils::LibSodiumWrapper> sodiumWrapper,
std::shared_ptr<bool> hostRunning, bool ipv4Only = false)
std::shared_ptr<bool> hostRunning,
std::string& configPath,
bool ipv4Only = false)
: mIoContext(ioContext),
mAcceptor(ioContext),
mSodiumWrapper(sodiumWrapper),
mHostRunning(hostRunning)
mHostRunning(hostRunning),
mConfigDirPath(configPath)
{
// Preload the config map
mRawServerConfig = Utils::getConfigMap("server_config", {"NETWORK", "SUBNET_MASK"});
mRawServerConfig = Utils::getConfigMap(configPath + "server_config", {"NETWORK", "SUBNET_MASK"});
asio::error_code ec_open, ec_v6only, ec_bind;
@@ -84,6 +87,7 @@ namespace ColumnLynx::Net::TCP {
std::shared_ptr<Utils::LibSodiumWrapper> mSodiumWrapper;
std::shared_ptr<bool> mHostRunning;
std::unordered_map<std::string, std::string> mRawServerConfig;
std::string mConfigDirPath;
};
}