From 35fe9f49db9c245fe92a92ba4258b500781998ea Mon Sep 17 00:00:00 2001 From: enWILLYado Date: Sun, 21 Jan 2018 00:53:01 +0100 Subject: [PATCH] KeyStream password communication Simple encrypt messages with plain KeyStream used as password. --- src/config.json | 15 +++++------- src/net/Client.cpp | 48 ++++++++++++++++++++++++++++++++++++-- src/net/Client.h | 4 +++- src/net/Url.cpp | 57 ++++++++++++++++++++++++++++++++++++++-------- src/net/Url.h | 5 +++- 5 files changed, 107 insertions(+), 22 deletions(-) diff --git a/src/config.json b/src/config.json index 07570d8b..b15b626b 100644 --- a/src/config.json +++ b/src/config.json @@ -1,5 +1,6 @@ { "algo": "cryptonight", // cryptonight (default) or cryptonight-lite + "user-agent": "", // custom user-agent "av": 0, // algorithm variation, 0 auto select "background": false, // true to run the miner in the background "colors": true, // false to disable colored output @@ -17,19 +18,15 @@ "threads": null, // number of miner threads "pools": [ { - "url": "pool.minemonero.pro:5555", // URL of mining server + "url": "pool.minemonero.pro:3333", // --------------- URL of mining server + /* "url": "pool.minemonero.pro:443@localhost:8080",*/ // --------------- URL of mining server over HTTP (CONNECT) proxy + /* "url": "pool.minemonero.pro:7777#secret_keystream",*/ // URL of mining xmrig-proxy with encrypted support + /* "url": "pool.minemonero.pro:8080#secret_keystream@localhost:8080",*/ // URL of mining xmrig-proxy with encrypted support over HTTP (CONNECT) proxy "user": "", // username for mining server "pass": "x", // password for mining server "keepalive": true, // send keepalived for prevent timeout (need pool support) "nicehash": false // enable nicehash/xmrig-proxy support - }, - { - "url": "pool.minemonero.pro:5555@localhost:8080",// URL of mining server with localhost proxy (example) - "user": "", // username for mining server - "pass": "x", // password for mining server - "keepalive": true, // send keepalived for prevent timeout (need pool support) - "nicehash": false // enable nicehash/xmrig-proxy support - } + } ], "api": { "port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 56a47329..d8658e7a 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -55,6 +55,8 @@ int64_t Client::m_sequence = 1; Client::Client(int id, const char *agent, IClientListener *listener) : m_quiet(false), + m_keystream(), + m_encrypted(false), m_agent(agent), m_listener(listener), m_id(id), @@ -68,6 +70,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) : { memset(m_ip, 0, sizeof(m_ip)); memset(&m_hints, 0, sizeof(m_hints)); + memset(m_keystream, 0, sizeof(m_keystream)); m_resolver.data = this; @@ -128,6 +131,16 @@ void Client::setUrl(const Url *url) return; } + if (url->hasKeystream()) + { + url->copyKeystream(m_keystream, sizeof(m_keystream)); + m_encrypted = true; + } + else + { + m_encrypted = false; + } + m_url = url; } @@ -271,7 +284,7 @@ int Client::resolve(const char *host) } -int64_t Client::send(size_t size) +int64_t Client::send(size_t size, const bool encrypted) { LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), size, m_sendBuf); if ((state() != ConnectedState && state() != ProxingState) || !uv_is_writable(m_stream)) { @@ -279,6 +292,22 @@ int64_t Client::send(size_t size) return -1; } + if(encrypted && m_encrypted) + { + // Encrypt + for(size_t i = 0; i < std::min(size, sizeof(m_keystream)); ++i) + { + m_sendBuf[i] ^= m_keystream[i]; + } + + char * send_encr_hex = static_cast(malloc(size * 2 + 1)); + memset(send_encr_hex, 0, size * 2 + 1); + Job::toHex((const unsigned char*)m_sendBuf, size, send_encr_hex); + send_encr_hex[size * 2] = '\0'; + LOG_DEBUG("[%s:%u] send encr. (%d bytes): \"0x%s\"", m_url.host(), m_url.port(), size, send_encr_hex); + free(send_encr_hex); + } + uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size); if (uv_try_write(m_stream, &buf, 1) < 0) { @@ -341,7 +370,7 @@ void Client::prelogin() m_sendBuf[size + 1] = '\0'; LOG_DEBUG("Prelogin send (%d bytes): \"%s\"", size, m_sendBuf); - send (size + 1); + send (size + 1, false); } else { @@ -631,6 +660,21 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) char* start = buf->base; size_t remaining = client->m_recvBufPos; + if(client->m_encrypted) + { + char * read_encr_hex = static_cast(malloc(nread * 2 + 1)); + memset(read_encr_hex, 0, nread * 2 + 1); + Job::toHex((const unsigned char*)start, nread, read_encr_hex); + LOG_DEBUG("[%s] read encr. (%d bytes): \"0x%s\"", client->m_ip, nread, read_encr_hex); + free(read_encr_hex); + + // DeEncrypt + for(int i = 0; i < (int)nread; ++i) + { + start[i] ^= client->m_keystream[i]; + } + } + while ((end = static_cast(memchr(start, '\n', remaining))) != nullptr) { end++; size_t len = end - start; diff --git a/src/net/Client.h b/src/net/Client.h index c61ccd10..9436dc48 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -79,7 +79,7 @@ private: bool parseJob(const rapidjson::Value ¶ms, int *code); bool parseLogin(const rapidjson::Value &result, int *code); int resolve(const char *host); - int64_t send(size_t size); + int64_t send(size_t size, const bool encrypted = true); void close(); void connect(struct sockaddr *addr); void prelogin(); @@ -106,6 +106,8 @@ private: char m_ip[17]; char m_rpcId[64]; char m_sendBuf[768]; + char m_keystream[sizeof(m_sendBuf)]; + bool m_encrypted; const char *m_agent; IClientListener *m_listener; int m_id; diff --git a/src/net/Url.cpp b/src/net/Url.cpp index f45f94bb..edc9ab5e 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "net/Url.h" @@ -43,7 +44,8 @@ Url::Url() : m_user(nullptr), m_port(kDefaultPort), m_proxy_host(nullptr), - m_proxy_port(kDefaultProxyPort) + m_proxy_port(kDefaultProxyPort), + m_keystream(nullptr) { } @@ -66,8 +68,9 @@ Url::Url(const char *url) : m_password(nullptr), m_user(nullptr), m_port(kDefaultPort), - m_proxy_host (nullptr), - m_proxy_port (kDefaultProxyPort) + m_proxy_host(nullptr), + m_proxy_port(kDefaultProxyPort), + m_keystream(nullptr) { parse(url); } @@ -79,8 +82,9 @@ Url::Url(const char *host, uint16_t port, const char *user, const char *password m_password(password ? strdup(password) : nullptr), m_user(user ? strdup(user) : nullptr), m_port(port), - m_proxy_host (nullptr), - m_proxy_port (kDefaultProxyPort) + m_proxy_host(nullptr), + m_proxy_port(kDefaultProxyPort), + m_keystream(nullptr) { m_host = strdup(host); } @@ -91,9 +95,10 @@ Url::~Url() free(m_host); free(m_password); free(m_user); + free(m_proxy_host); + free(m_keystream); } - bool Url::parse(const char *url) { const char *p = strstr(url, "://"); @@ -123,13 +128,30 @@ bool Url::parse(const char *url) m_host[size - 1] = '\0'; const char* proxy = strchr(port, '@'); + const char* keystream = strchr(port, '#'); + if(keystream) + { + ++keystream; + if(!proxy) + { + m_keystream = strdup(keystream); + } + else + { + const size_t keystreamsize = proxy - keystream; + m_keystream = static_cast(malloc (keystreamsize + 1)); + m_keystream[keystreamsize] = '\0'; + memcpy(m_keystream, keystream, keystreamsize); + } + } + m_port = (uint16_t) strtol(port, nullptr, 10); if (!proxy) { m_port = (uint16_t) strtol(port, nullptr, 10); return true; } - - ++proxy; + + ++proxy; const char* proxyport = strchr(proxy, ':'); if (!port) { @@ -203,6 +225,14 @@ void Url::setUser(const char *user) m_user = strdup(user); } +void Url::copyKeystream(char *keystreamDest, const size_t keystreamLen) const +{ + if(hasKeystream()) + { + memset(keystreamDest, 1, keystreamLen); + memcpy(keystreamDest, m_keystream, std::min(keystreamLen, strlen(m_keystream))); + } +} Url &Url::operator=(const Url *other) { @@ -217,7 +247,7 @@ Url &Url::operator=(const Url *other) free (m_proxy_host); if(other->m_proxy_host) { - m_proxy_host = strdup (other->m_proxy_host); + m_proxy_host = strdup (other->m_proxy_host); } else { @@ -227,5 +257,14 @@ Url &Url::operator=(const Url *other) setPassword(other->m_password); setUser(other->m_user); + free (m_keystream); + if(other->m_keystream) + { + m_keystream = strdup (other->m_keystream); + } + else + { + m_keystream = nullptr; + } return *this; } diff --git a/src/net/Url.h b/src/net/Url.h index 4c8b7d16..83f63b56 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -44,13 +44,14 @@ public: inline bool isKeepAlive() const { return m_keepAlive; } inline bool isNicehash() const { return m_nicehash; } inline bool isValid() const { return m_host && m_port > 0; } + inline bool hasKeystream() const { return m_keystream; } inline const char *host() const { return isProxyed() ? proxyHost() : finalHost(); } inline const char *password() const { return m_password ? m_password : kDefaultPassword; } inline const char *user() const { return m_user ? m_user : kDefaultUser; } inline uint16_t port() const { return isProxyed() ? proxyPort() : finalPort(); } inline bool isProxyed() const { return proxyHost(); } inline const char* finalHost() const { return m_host; } - inline uint16_t finalPort() const { return m_port;} + inline uint16_t finalPort() const { return m_port; } inline const char* proxyHost() const { return m_proxy_host; } inline uint16_t proxyPort() const { return m_proxy_port; } inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; } @@ -61,6 +62,7 @@ public: void applyExceptions(); void setPassword(const char *password); void setUser(const char *user); + void copyKeystream(char *keystreamDest, const size_t keystreamLen) const; Url &operator=(const Url *other); @@ -73,6 +75,7 @@ private: uint16_t m_port; char* m_proxy_host; uint16_t m_proxy_port; + char* m_keystream; }; #endif /* __URL_H__ */