whoever killed my chat client is going to pay

This commit is contained in:
malloc 2018-09-26 16:46:29 -05:00
parent e30c56041d
commit 13df494cc1
13 changed files with 23 additions and 248 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -8,7 +8,7 @@ sosc::net::IpAddress::IpAddress() {
void sosc::net::IpAddress::Reset() { void sosc::net::IpAddress::Reset() {
for(int i = 0; i < 8; ++i) 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() { bool sosc::net::IpAddress::ParseError() {
@ -162,10 +162,7 @@ bool sosc::net::IpAddress::IsIPv4() const {
if(this->parts[i] != blank) if(this->parts[i] != blank)
return false; return false;
if(this->parts[5] != std::make_pair<uint16_t, uint8_t>(0xFFFF, 0)) return this->parts[5] == std::make_pair<uint16_t, uint8_t>(0xFFFF, 0);
return false;
return true;
} }
// END IPADDRESS CLASS // END IPADDRESS CLASS

View file

@ -1,6 +1,7 @@
#ifndef SOSC_UTIL_NET_H #ifndef SOSC_UTIL_NET_H
#define SOSC_UTIL_NET_H #define SOSC_UTIL_NET_H
#include <utility>
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <string> #include <string>

View file

@ -5,9 +5,6 @@
#include "sock/scapesock.hpp" #include "sock/scapesock.hpp"
#include "sock/pool.hpp" #include "sock/pool.hpp"
#include "crypto/keyex.hpp"
#include "crypto/cipher.hpp"
#include "db/database.hpp" #include "db/database.hpp"
#include "ctx/master.hpp" #include "ctx/master.hpp"
@ -22,8 +19,6 @@ public:
private: private:
ScapeConnection sock; ScapeConnection sock;
cgc::KeyExchange key;
cgc::Cipher cipher;
}; };
class MasterClientPool : public Pool<MasterClient, ctx::MasterClientContext> { class MasterClientPool : public Pool<MasterClient, ctx::MasterClientContext> {
@ -44,7 +39,7 @@ protected:
class MasterIntra { class MasterIntra {
public: public:
explicit MasterIntra(const IntraClient& client); explicit MasterIntra(const IntraClient& client);
bool Process(const Pool::Queries* queries); bool Process(const Queries* queries);
bool Close(); bool Close();
bool Close(const Packet& message); bool Close(const Packet& message);
@ -72,8 +67,6 @@ private:
}; };
IntraClient sock; IntraClient sock;
cgc::KeyExchange key;
cgc::Cipher cipher;
bool authed; bool authed;
int auth_attempts; int auth_attempts;
@ -82,7 +75,7 @@ private:
int32_t server_id; int32_t server_id;
std::string license; std::string license;
const Pool::Queries* queries; const Queries* queries;
}; };
class MasterIntraPool : public Pool<MasterIntra, ctx::MasterIntraContext> { class MasterIntraPool : public Pool<MasterIntra, ctx::MasterIntraContext> {

View file

@ -83,7 +83,7 @@ sosc::MasterIntra::MasterIntra(const IntraClient& client) {
this->auth_attempts = 0; this->auth_attempts = 0;
} }
bool sosc::MasterIntra::Process(const Pool::Queries* queries) { bool sosc::MasterIntra::Process(const Queries* queries) {
Packet pck; Packet pck;
int status = this->sock.Receive(&pck); int status = this->sock.Receive(&pck);
if(status == PCK_ERR) if(status == PCK_ERR)
@ -105,18 +105,7 @@ bool sosc::MasterIntra::Process(const Pool::Queries* queries) {
} }
bool sosc::MasterIntra::InitAttempt(sosc::Packet& pck) { 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) { bool sosc::MasterIntra::Authentication(sosc::Packet& pck) {

View file

@ -6,11 +6,12 @@
sosc::IntraClient::IntraClient() { sosc::IntraClient::IntraClient() {
this->client_open = false; this->client_open = false;
this->cipher = nullptr;
} }
bool sosc::IntraClient::Open(const std::string& host, uint16_t port) { bool sosc::IntraClient::Open
if(!this->client.Open(host, port)) (const std::string& host, uint16_t port, bool secure)
{
if(!this->client.Open(host, port, secure))
return false; return false;
this->client_open = true; this->client_open = true;
@ -22,15 +23,6 @@ void sosc::IntraClient::Open(const TcpClient& client) {
this->client_open = true; 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) { int sosc::IntraClient::Receive(Packet* packet, bool block) {
if(!this->client_open) if(!this->client_open)
return PCK_ERR; return PCK_ERR;
@ -46,8 +38,6 @@ int sosc::IntraClient::Receive(Packet* packet, bool block) {
std::string::size_type offset = this->buffer.size(); std::string::size_type offset = this->buffer.size();
status = this->client.Receive status = this->client.Receive
(&this->buffer, SOSC_TCP_APPEND | (block ? SOSC_TCP_BLOCK : 0)); (&this->buffer, SOSC_TCP_APPEND | (block ? SOSC_TCP_BLOCK : 0));
if(this->IsCiphered())
this->cipher->Parse(&this->buffer, offset);
if(status == -1) if(status == -1)
return PCK_ERR; return PCK_ERR;
@ -61,12 +51,7 @@ bool sosc::IntraClient::Send(const Packet& packet) {
if(!this->client_open) if(!this->client_open)
return false; return false;
std::string packet_raw; return this->client.Send(packet.ToString());
packet.ToString(&packet_raw);
if(this->IsCiphered())
this->cipher->Parse(&packet_raw);
return this->client.Send(packet_raw);
} }
/****************************/ /****************************/

View file

@ -3,16 +3,12 @@
#include "tcpsock.hpp" #include "tcpsock.hpp"
#include "packet.hpp" #include "packet.hpp"
#include "crypto/cipher.hpp"
namespace sosc { namespace sosc {
class IntraClient { class IntraClient {
public: public:
IntraClient(); IntraClient();
bool Open(const std::string& host, uint16_t port); bool Open(const std::string& host, uint16_t port, bool secure = false);
bool IsCiphered() const;
void SetCipher(cgc::Cipher* cipher);
int Receive(Packet* packet, bool block = false); int Receive(Packet* packet, bool block = false);
bool Send(const Packet& packet); bool Send(const Packet& packet);
@ -35,7 +31,6 @@ private:
bool client_open; bool client_open;
TcpClient client; TcpClient client;
std::string buffer; std::string buffer;
cgc::Cipher* cipher;
friend class IntraServer; friend class IntraServer;
}; };

View file

@ -8,6 +8,8 @@
#include "db/database.hpp" #include "db/database.hpp"
namespace sosc { namespace sosc {
typedef std::vector<db::Query*> Queries;
typedef struct { typedef struct {
// amount of threads to start with (never close) // amount of threads to start with (never close)
int initial_count = 3; int initial_count = 3;
@ -42,8 +44,6 @@ public:
} }
virtual void Stop(); virtual void Stop();
typedef std::vector<db::Query*> Queries;
protected: protected:
virtual void SetupQueries(Queries* queries) {}; virtual void SetupQueries(Queries* queries) {};
virtual bool ProcessClient virtual bool ProcessClient

View file

@ -7,7 +7,6 @@
sosc::ScapeConnection::ScapeConnection() { sosc::ScapeConnection::ScapeConnection() {
this->client_open = false; this->client_open = false;
this->handshaked = false; this->handshaked = false;
this->cipher = nullptr;
} }
void sosc::ScapeConnection::Open(const TcpClient& client) { void sosc::ScapeConnection::Open(const TcpClient& client) {
@ -15,15 +14,6 @@ void sosc::ScapeConnection::Open(const TcpClient& client) {
this->client_open = true; 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() { int sosc::ScapeConnection::Handshake() {
if(this->handshaked) if(this->handshaked)
return SOSC_SHAKE_DONE; return SOSC_SHAKE_DONE;
@ -98,9 +88,6 @@ int sosc::ScapeConnection::Receive(Packet* packet, bool block) {
if(status == -1) if(status == -1)
return PCK_ERR; return PCK_ERR;
if(this->IsCiphered())
this->cipher->Parse(&this->buffer, bufferSize);
first_recv = false; first_recv = false;
} }
@ -124,8 +111,6 @@ bool sosc::ScapeConnection::Send(const Packet& packet) {
std::string packet_raw; std::string packet_raw;
packet.ToString(&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_raw);
} }
@ -140,12 +125,12 @@ sosc::ScapeServer::ScapeServer() {
this->server_open = false; this->server_open = false;
} }
bool sosc::ScapeServer::Listen(uint16_t port) { bool sosc::ScapeServer::Listen(uint16_t port, bool secure) {
if(this->server_open) if(this->server_open)
return false; return false;
this->server = TcpServer(); this->server = TcpServer();
this->server.Listen(port); this->server.Listen(port, secure);
this->server_open = true; this->server_open = true;
return true; return true;
} }
@ -158,3 +143,7 @@ bool sosc::ScapeServer::Accept(ScapeConnection* client) {
client->Open(raw_client); client->Open(raw_client);
return true; return true;
} }
/****************************/
/* END SCAPESERVER CODE */
/****************************/

View file

@ -4,7 +4,6 @@
#include <queue> #include <queue>
#include "crypto/sha1.hpp" #include "crypto/sha1.hpp"
#include "crypto/base64.hpp" #include "crypto/base64.hpp"
#include "crypto/cipher.hpp"
#include "frame.hpp" #include "frame.hpp"
#include "packet.hpp" #include "packet.hpp"
#include "tcpsock.hpp" #include "tcpsock.hpp"
@ -18,9 +17,6 @@ class ScapeConnection {
public: public:
ScapeConnection(); ScapeConnection();
bool IsCiphered() const;
void SetCipher(cgc::Cipher* cipher);
int Handshake(); int Handshake();
int Receive(Packet* packet, bool block = false); int Receive(Packet* packet, bool block = false);
bool Send(const Packet& packet); bool Send(const Packet& packet);
@ -47,7 +43,6 @@ private:
bool client_open; bool client_open;
bool handshaked; bool handshaked;
TcpClient client; TcpClient client;
cgc::Cipher* cipher;
std::string buffer; std::string buffer;
std::string pck_frames; std::string pck_frames;
@ -59,7 +54,7 @@ class ScapeServer {
public: public:
ScapeServer(); ScapeServer();
bool Listen(uint16_t port); bool Listen(uint16_t port, bool secure = false);
bool Accept(ScapeConnection* client); bool Accept(ScapeConnection* client);
inline bool IsOpen() const { inline bool IsOpen() const {