whoever killed my chat client is going to pay
This commit is contained in:
parent
e30c56041d
commit
13df494cc1
13 changed files with 23 additions and 248 deletions
|
@ -1,46 +0,0 @@
|
|||
#include "cipher.hpp"
|
||||
|
||||
template<typename T>
|
||||
static void _swap(T& a, T& b) {
|
||||
T tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
sosc::cgc::Cipher::Cipher(const KeyExchange& key) {
|
||||
std::string key_raw
|
||||
= key.GetPrivateKey().ToRawString((uint64_t)key.key_size_bytes);
|
||||
|
||||
for(int i = 0; i < this->state_size; ++i)
|
||||
this->state[i] = (uint8_t)i;
|
||||
|
||||
int i = 0, j = 0;
|
||||
for(i = 0; i < this->state_size; ++i)
|
||||
j = (j + this->state[i] + key_raw[i % key_raw.length()]) % 256;
|
||||
|
||||
GenerateStream(1024);
|
||||
}
|
||||
|
||||
void sosc::cgc::Cipher::Parse
|
||||
(std::string* data, std::string::size_type offset)
|
||||
{
|
||||
std::string stream = this->GenerateStream(data->length() - offset);
|
||||
for(std::string::size_type i = offset; i < data->length(); ++i)
|
||||
(*data)[i] ^= stream[i];
|
||||
}
|
||||
|
||||
std::string sosc::cgc::Cipher::GenerateStream(uint64_t length) {
|
||||
std::string stream(length, 0);
|
||||
int i = 0, j = 0;
|
||||
|
||||
for(uint64_t x = 0; x < length; ++x) {
|
||||
i = (i + 1) % 256;
|
||||
j = (j + this->state[i]) % 256;
|
||||
_swap(this->state[i], this->state[j]);
|
||||
|
||||
stream[x] =
|
||||
this->state[(this->state[i] + this->state[j]) % 256];
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef SOSC_CRYPTO_CIPHER_H
|
||||
#define SOSC_CRYPTO_CIPHER_H
|
||||
|
||||
#include "utils/bigint.hpp"
|
||||
#include "keyex.hpp"
|
||||
|
||||
namespace sosc {
|
||||
namespace cgc {
|
||||
class Cipher {
|
||||
public:
|
||||
Cipher() = default;
|
||||
explicit Cipher(const KeyExchange& key);
|
||||
|
||||
void Parse(std::string* data, std::string::size_type offset = 0);
|
||||
private:
|
||||
std::string GenerateStream(uint64_t length);
|
||||
|
||||
static const int state_size = 256;
|
||||
uint8_t state[state_size];
|
||||
};
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,62 +0,0 @@
|
|||
#include "keyex.hpp"
|
||||
|
||||
sosc::BigUInt sosc::cgc::KeyExchange::secret;
|
||||
|
||||
sosc::cgc::KeyExchange::KeyExchange() {
|
||||
if(this->secret.IsZero())
|
||||
this->secret = FastRandomPrime();
|
||||
|
||||
this->modulus = FastRandomPrime();
|
||||
}
|
||||
|
||||
sosc::Packet sosc::cgc::KeyExchange::GenerateRequest() const {
|
||||
return Packet(1, {
|
||||
this->generator.ToString(),
|
||||
this->modulus.ToString(),
|
||||
BigUInt::ModPow(this->generator, this->secret, this->modulus)
|
||||
});
|
||||
}
|
||||
|
||||
bool sosc::cgc::KeyExchange::ParseRequest
|
||||
(const Packet& request, Packet* response, uint8_t id)
|
||||
{
|
||||
if(request.GetId() != 1 || request.RegionCount() != 3)
|
||||
return false;
|
||||
|
||||
BigUInt generator, modulus, public_key;
|
||||
bool check = generator.Parse(request[0]);
|
||||
check = check || modulus.Parse(request[1]);
|
||||
check = check || public_key.Parse(request[2]);
|
||||
|
||||
if(!check)
|
||||
return false;
|
||||
|
||||
this->private_key = BigUInt::ModPow(public_key, this->secret, modulus);
|
||||
public_key = BigUInt::ModPow(generator, this->secret, modulus);
|
||||
*response = Packet(id, { public_key.ToString() });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sosc::cgc::KeyExchange::ParseResponse(const Packet& response) {
|
||||
if(response.GetId() != 1 || response.RegionCount() != 1)
|
||||
return false;
|
||||
|
||||
BigUInt public_key;
|
||||
if(!public_key.Parse(response[0]))
|
||||
return false;
|
||||
|
||||
this->private_key =
|
||||
BigUInt::ModPow(public_key, this->secret, this->modulus);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
sosc::BigUInt sosc::cgc::KeyExchange::FastRandomPrime() {
|
||||
BigUInt prime;
|
||||
for(int i = 0; i < this->key_size_bytes; i += 16)
|
||||
prime += BigUInt::GenerateRandomPrime(16) << (i * 8);
|
||||
|
||||
return prime;
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef SOSC_CRYPTO_KEYEX_H
|
||||
#define SOSC_CRYPTO_KEYEX_H
|
||||
|
||||
#include "utils/bigint.hpp"
|
||||
#include "sock/packet.hpp"
|
||||
|
||||
namespace sosc {
|
||||
namespace cgc {
|
||||
class KeyExchange {
|
||||
public:
|
||||
KeyExchange();
|
||||
|
||||
Packet GenerateRequest() const;
|
||||
bool ParseRequest(const Packet& request, Packet* response, uint8_t id);
|
||||
bool ParseResponse(const Packet& response);
|
||||
|
||||
inline bool Succeeded() const {
|
||||
return !this->private_key.IsZero();
|
||||
}
|
||||
|
||||
inline const BigUInt& GetPrivateKey() const {
|
||||
return this->private_key;
|
||||
}
|
||||
|
||||
const int key_size = 512;
|
||||
const int key_size_bytes = key_size / 8;
|
||||
private:
|
||||
BigUInt FastRandomPrime();
|
||||
|
||||
const BigUInt generator = BigUInt(2u);
|
||||
static BigUInt secret;
|
||||
BigUInt modulus;
|
||||
|
||||
BigUInt private_key;
|
||||
};
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -8,7 +8,7 @@ sosc::net::IpAddress::IpAddress() {
|
|||
|
||||
void sosc::net::IpAddress::Reset() {
|
||||
for(int i = 0; i < 8; ++i)
|
||||
this->parts[i] = std::make_pair(0, 0);
|
||||
this->parts[i] = std::make_pair<uint16_t, uint8_t>(0, 0);
|
||||
}
|
||||
|
||||
bool sosc::net::IpAddress::ParseError() {
|
||||
|
@ -162,10 +162,7 @@ bool sosc::net::IpAddress::IsIPv4() const {
|
|||
if(this->parts[i] != blank)
|
||||
return false;
|
||||
|
||||
if(this->parts[5] != std::make_pair<uint16_t, uint8_t>(0xFFFF, 0))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return this->parts[5] == std::make_pair<uint16_t, uint8_t>(0xFFFF, 0);
|
||||
}
|
||||
|
||||
// END IPADDRESS CLASS
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef SOSC_UTIL_NET_H
|
||||
#define SOSC_UTIL_NET_H
|
||||
|
||||
#include <utility>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
#include "sock/scapesock.hpp"
|
||||
#include "sock/pool.hpp"
|
||||
|
||||
#include "crypto/keyex.hpp"
|
||||
#include "crypto/cipher.hpp"
|
||||
|
||||
#include "db/database.hpp"
|
||||
|
||||
#include "ctx/master.hpp"
|
||||
|
@ -22,8 +19,6 @@ public:
|
|||
|
||||
private:
|
||||
ScapeConnection sock;
|
||||
cgc::KeyExchange key;
|
||||
cgc::Cipher cipher;
|
||||
};
|
||||
|
||||
class MasterClientPool : public Pool<MasterClient, ctx::MasterClientContext> {
|
||||
|
@ -44,7 +39,7 @@ protected:
|
|||
class MasterIntra {
|
||||
public:
|
||||
explicit MasterIntra(const IntraClient& client);
|
||||
bool Process(const Pool::Queries* queries);
|
||||
bool Process(const Queries* queries);
|
||||
|
||||
bool Close();
|
||||
bool Close(const Packet& message);
|
||||
|
@ -72,8 +67,6 @@ private:
|
|||
};
|
||||
|
||||
IntraClient sock;
|
||||
cgc::KeyExchange key;
|
||||
cgc::Cipher cipher;
|
||||
|
||||
bool authed;
|
||||
int auth_attempts;
|
||||
|
@ -82,7 +75,7 @@ private:
|
|||
int32_t server_id;
|
||||
std::string license;
|
||||
|
||||
const Pool::Queries* queries;
|
||||
const Queries* queries;
|
||||
};
|
||||
|
||||
class MasterIntraPool : public Pool<MasterIntra, ctx::MasterIntraContext> {
|
||||
|
|
|
@ -83,7 +83,7 @@ sosc::MasterIntra::MasterIntra(const IntraClient& client) {
|
|||
this->auth_attempts = 0;
|
||||
}
|
||||
|
||||
bool sosc::MasterIntra::Process(const Pool::Queries* queries) {
|
||||
bool sosc::MasterIntra::Process(const Queries* queries) {
|
||||
Packet pck;
|
||||
int status = this->sock.Receive(&pck);
|
||||
if(status == PCK_ERR)
|
||||
|
@ -105,18 +105,7 @@ bool sosc::MasterIntra::Process(const Pool::Queries* queries) {
|
|||
}
|
||||
|
||||
bool sosc::MasterIntra::InitAttempt(sosc::Packet& pck) {
|
||||
if(!pck.Check(1, key.key_size_bytes))
|
||||
return this->Close(
|
||||
Packet(kEncryptionError, { net::htonv<uint16_t>(0x100) }));
|
||||
|
||||
Packet response;
|
||||
if(!this->key.ParseRequest(pck, &response, kKeyExchange))
|
||||
return this->Close(
|
||||
Packet(kEncryptionError, { net::htonv<uint16_t>(0x101) }));
|
||||
|
||||
this->cipher = cgc::Cipher(this->key);
|
||||
this->sock.Send(response);
|
||||
this->sock.SetCipher(&this->cipher);
|
||||
}
|
||||
|
||||
bool sosc::MasterIntra::Authentication(sosc::Packet& pck) {
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
|
||||
sosc::IntraClient::IntraClient() {
|
||||
this->client_open = false;
|
||||
this->cipher = nullptr;
|
||||
}
|
||||
|
||||
bool sosc::IntraClient::Open(const std::string& host, uint16_t port) {
|
||||
if(!this->client.Open(host, port))
|
||||
bool sosc::IntraClient::Open
|
||||
(const std::string& host, uint16_t port, bool secure)
|
||||
{
|
||||
if(!this->client.Open(host, port, secure))
|
||||
return false;
|
||||
|
||||
this->client_open = true;
|
||||
|
@ -22,15 +23,6 @@ void sosc::IntraClient::Open(const TcpClient& client) {
|
|||
this->client_open = true;
|
||||
}
|
||||
|
||||
bool sosc::IntraClient::IsCiphered() const {
|
||||
return this->cipher != nullptr;
|
||||
}
|
||||
|
||||
void sosc::IntraClient::SetCipher(cgc::Cipher *cipher) {
|
||||
this->cipher = cipher;
|
||||
cipher->Parse(&this->buffer);
|
||||
}
|
||||
|
||||
int sosc::IntraClient::Receive(Packet* packet, bool block) {
|
||||
if(!this->client_open)
|
||||
return PCK_ERR;
|
||||
|
@ -46,8 +38,6 @@ int sosc::IntraClient::Receive(Packet* packet, bool block) {
|
|||
std::string::size_type offset = this->buffer.size();
|
||||
status = this->client.Receive
|
||||
(&this->buffer, SOSC_TCP_APPEND | (block ? SOSC_TCP_BLOCK : 0));
|
||||
if(this->IsCiphered())
|
||||
this->cipher->Parse(&this->buffer, offset);
|
||||
|
||||
if(status == -1)
|
||||
return PCK_ERR;
|
||||
|
@ -61,12 +51,7 @@ bool sosc::IntraClient::Send(const Packet& packet) {
|
|||
if(!this->client_open)
|
||||
return false;
|
||||
|
||||
std::string packet_raw;
|
||||
packet.ToString(&packet_raw);
|
||||
if(this->IsCiphered())
|
||||
this->cipher->Parse(&packet_raw);
|
||||
|
||||
return this->client.Send(packet_raw);
|
||||
return this->client.Send(packet.ToString());
|
||||
}
|
||||
|
||||
/****************************/
|
||||
|
|
|
@ -3,16 +3,12 @@
|
|||
|
||||
#include "tcpsock.hpp"
|
||||
#include "packet.hpp"
|
||||
#include "crypto/cipher.hpp"
|
||||
|
||||
namespace sosc {
|
||||
class IntraClient {
|
||||
public:
|
||||
IntraClient();
|
||||
bool Open(const std::string& host, uint16_t port);
|
||||
|
||||
bool IsCiphered() const;
|
||||
void SetCipher(cgc::Cipher* cipher);
|
||||
bool Open(const std::string& host, uint16_t port, bool secure = false);
|
||||
|
||||
int Receive(Packet* packet, bool block = false);
|
||||
bool Send(const Packet& packet);
|
||||
|
@ -35,7 +31,6 @@ private:
|
|||
bool client_open;
|
||||
TcpClient client;
|
||||
std::string buffer;
|
||||
cgc::Cipher* cipher;
|
||||
|
||||
friend class IntraServer;
|
||||
};
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "db/database.hpp"
|
||||
|
||||
namespace sosc {
|
||||
typedef std::vector<db::Query*> Queries;
|
||||
|
||||
typedef struct {
|
||||
// amount of threads to start with (never close)
|
||||
int initial_count = 3;
|
||||
|
@ -42,8 +44,6 @@ public:
|
|||
}
|
||||
|
||||
virtual void Stop();
|
||||
|
||||
typedef std::vector<db::Query*> Queries;
|
||||
protected:
|
||||
virtual void SetupQueries(Queries* queries) {};
|
||||
virtual bool ProcessClient
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
sosc::ScapeConnection::ScapeConnection() {
|
||||
this->client_open = false;
|
||||
this->handshaked = false;
|
||||
this->cipher = nullptr;
|
||||
}
|
||||
|
||||
void sosc::ScapeConnection::Open(const TcpClient& client) {
|
||||
|
@ -15,15 +14,6 @@ void sosc::ScapeConnection::Open(const TcpClient& client) {
|
|||
this->client_open = true;
|
||||
}
|
||||
|
||||
bool sosc::ScapeConnection::IsCiphered() const {
|
||||
return this->cipher != nullptr;
|
||||
}
|
||||
|
||||
void sosc::ScapeConnection::SetCipher(cgc::Cipher* cipher) {
|
||||
this->cipher = cipher;
|
||||
cipher->Parse(&this->buffer);
|
||||
}
|
||||
|
||||
int sosc::ScapeConnection::Handshake() {
|
||||
if(this->handshaked)
|
||||
return SOSC_SHAKE_DONE;
|
||||
|
@ -98,9 +88,6 @@ int sosc::ScapeConnection::Receive(Packet* packet, bool block) {
|
|||
if(status == -1)
|
||||
return PCK_ERR;
|
||||
|
||||
if(this->IsCiphered())
|
||||
this->cipher->Parse(&this->buffer, bufferSize);
|
||||
|
||||
first_recv = false;
|
||||
}
|
||||
|
||||
|
@ -124,8 +111,6 @@ bool sosc::ScapeConnection::Send(const Packet& packet) {
|
|||
|
||||
std::string packet_raw;
|
||||
packet.ToString(&packet_raw);
|
||||
if(this->IsCiphered())
|
||||
this->cipher->Parse(&packet_raw);
|
||||
|
||||
return this->client.Send(packet_raw);
|
||||
}
|
||||
|
@ -140,12 +125,12 @@ sosc::ScapeServer::ScapeServer() {
|
|||
this->server_open = false;
|
||||
}
|
||||
|
||||
bool sosc::ScapeServer::Listen(uint16_t port) {
|
||||
bool sosc::ScapeServer::Listen(uint16_t port, bool secure) {
|
||||
if(this->server_open)
|
||||
return false;
|
||||
|
||||
this->server = TcpServer();
|
||||
this->server.Listen(port);
|
||||
this->server.Listen(port, secure);
|
||||
this->server_open = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -158,3 +143,7 @@ bool sosc::ScapeServer::Accept(ScapeConnection* client) {
|
|||
client->Open(raw_client);
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* END SCAPESERVER CODE */
|
||||
/****************************/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <queue>
|
||||
#include "crypto/sha1.hpp"
|
||||
#include "crypto/base64.hpp"
|
||||
#include "crypto/cipher.hpp"
|
||||
#include "frame.hpp"
|
||||
#include "packet.hpp"
|
||||
#include "tcpsock.hpp"
|
||||
|
@ -18,9 +17,6 @@ class ScapeConnection {
|
|||
public:
|
||||
ScapeConnection();
|
||||
|
||||
bool IsCiphered() const;
|
||||
void SetCipher(cgc::Cipher* cipher);
|
||||
|
||||
int Handshake();
|
||||
int Receive(Packet* packet, bool block = false);
|
||||
bool Send(const Packet& packet);
|
||||
|
@ -47,7 +43,6 @@ private:
|
|||
bool client_open;
|
||||
bool handshaked;
|
||||
TcpClient client;
|
||||
cgc::Cipher* cipher;
|
||||
|
||||
std::string buffer;
|
||||
std::string pck_frames;
|
||||
|
@ -59,7 +54,7 @@ class ScapeServer {
|
|||
public:
|
||||
ScapeServer();
|
||||
|
||||
bool Listen(uint16_t port);
|
||||
bool Listen(uint16_t port, bool secure = false);
|
||||
bool Accept(ScapeConnection* client);
|
||||
|
||||
inline bool IsOpen() const {
|
||||
|
|
Loading…
Reference in a new issue