Fixed daemon support over HTTPS.
This commit is contained in:
parent
62012a1a50
commit
5e369a5af8
6 changed files with 90 additions and 24 deletions
|
@ -79,6 +79,7 @@ private:
|
||||||
|
|
||||||
xmrig::HttpClient::HttpClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) :
|
xmrig::HttpClient::HttpClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) :
|
||||||
HttpContext(HTTP_RESPONSE, listener),
|
HttpContext(HTTP_RESPONSE, listener),
|
||||||
|
m_quiet(false),
|
||||||
m_port(0)
|
m_port(0)
|
||||||
{
|
{
|
||||||
this->method = method;
|
this->method = method;
|
||||||
|
|
|
@ -57,10 +57,11 @@ protected:
|
||||||
virtual void read(const char *data, size_t size);
|
virtual void read(const char *data, size_t size);
|
||||||
virtual void write(const std::string &header);
|
virtual void write(const std::string &header);
|
||||||
|
|
||||||
|
bool m_quiet;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void onConnect(uv_connect_t *req, int status);
|
static void onConnect(uv_connect_t *req, int status);
|
||||||
|
|
||||||
bool m_quiet;
|
|
||||||
Dns *m_dns;
|
Dns *m_dns;
|
||||||
uint16_t m_port;
|
uint16_t m_port;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,15 +29,22 @@
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
#include "base/net/http/HttpsClient.h"
|
#include "base/net/http/HttpsClient.h"
|
||||||
#include "base/tools/String.h"
|
#include "base/tools/Buffer.h"
|
||||||
|
|
||||||
|
|
||||||
xmrig::HttpsClient::HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) :
|
#ifdef _MSC_VER
|
||||||
|
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpsClient::HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint) :
|
||||||
HttpClient(method, url, listener, data, size),
|
HttpClient(method, url, listener, data, size),
|
||||||
m_ready(false),
|
m_ready(false),
|
||||||
m_buf(),
|
m_buf(),
|
||||||
m_ssl(nullptr)
|
m_ssl(nullptr),
|
||||||
|
m_fp(fingerprint)
|
||||||
{
|
{
|
||||||
m_ctx = SSL_CTX_new(SSLv23_method());
|
m_ctx = SSL_CTX_new(SSLv23_method());
|
||||||
assert(m_ctx != nullptr);
|
assert(m_ctx != nullptr);
|
||||||
|
@ -64,6 +71,18 @@ xmrig::HttpsClient::~HttpsClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *xmrig::HttpsClient::fingerprint() const
|
||||||
|
{
|
||||||
|
return m_ready ? m_fingerprint : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *xmrig::HttpsClient::version() const
|
||||||
|
{
|
||||||
|
return m_ready ? SSL_get_version(m_ssl) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::HttpsClient::handshake()
|
void xmrig::HttpsClient::handshake()
|
||||||
{
|
{
|
||||||
m_ssl = SSL_new(m_ctx);
|
m_ssl = SSL_new(m_ctx);
|
||||||
|
@ -118,13 +137,52 @@ void xmrig::HttpsClient::read(const char *data, size_t size)
|
||||||
void xmrig::HttpsClient::write(const std::string &header)
|
void xmrig::HttpsClient::write(const std::string &header)
|
||||||
{
|
{
|
||||||
SSL_write(m_ssl, (header + body).c_str(), header.size() + body.size());
|
SSL_write(m_ssl, (header + body).c_str(), header.size() + body.size());
|
||||||
|
body.clear();
|
||||||
|
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::HttpsClient::verify(X509 *cert) const
|
bool xmrig::HttpsClient::verify(X509 *cert)
|
||||||
{
|
{
|
||||||
return cert != nullptr;
|
if (cert == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!verifyFingerprint(cert)) {
|
||||||
|
if (!m_quiet) {
|
||||||
|
LOG_ERR("[%s:%d] Failed to verify server certificate fingerprint", host().data(), port());
|
||||||
|
|
||||||
|
if (strlen(m_fingerprint) == 64 && !m_fp.isNull()) {
|
||||||
|
LOG_ERR("\"%s\" was given", m_fingerprint);
|
||||||
|
LOG_ERR("\"%s\" was configured", m_fp.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::HttpsClient::verifyFingerprint(X509 *cert)
|
||||||
|
{
|
||||||
|
const EVP_MD *digest = EVP_get_digestbyname("sha256");
|
||||||
|
if (digest == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char md[EVP_MAX_MD_SIZE];
|
||||||
|
unsigned int dlen;
|
||||||
|
|
||||||
|
if (X509_digest(cert, digest, md, &dlen) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::toHex(md, 32, m_fingerprint);
|
||||||
|
|
||||||
|
return m_fp.isNull() || strncasecmp(m_fingerprint, m_fp.data(), 64) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,7 +197,7 @@ void xmrig::HttpsClient::flush()
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (uv_is_writable(stream())) {
|
if (uv_is_writable(stream())) {
|
||||||
result = uv_try_write(stream(), &buf, 1) == buf.len;
|
result = uv_try_write(stream(), &buf, 1) == static_cast<int>(buf.len);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
close(UV_EIO);
|
close(UV_EIO);
|
||||||
|
|
|
@ -35,6 +35,7 @@ typedef struct x509_st X509;
|
||||||
|
|
||||||
|
|
||||||
#include "base/net/http/HttpClient.h"
|
#include "base/net/http/HttpClient.h"
|
||||||
|
#include "base/tools/String.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
@ -43,24 +44,30 @@ namespace xmrig {
|
||||||
class HttpsClient : public HttpClient
|
class HttpsClient : public HttpClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HttpsClient(int method, const String &url, IHttpListener *listener, const char *data = nullptr, size_t size = 0);
|
HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint);
|
||||||
~HttpsClient() override;
|
~HttpsClient() override;
|
||||||
|
|
||||||
|
const char *fingerprint() const;
|
||||||
|
const char *version() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void handshake() override;
|
void handshake() override;
|
||||||
void read(const char *data, size_t size) override;
|
void read(const char *data, size_t size) override;
|
||||||
void write(const std::string &header) override;
|
void write(const std::string &header) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool verify(X509 *cert) const;
|
bool verify(X509 *cert);
|
||||||
|
bool verifyFingerprint(X509 *cert);
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
BIO *m_readBio;
|
BIO *m_readBio;
|
||||||
BIO *m_writeBio;
|
BIO *m_writeBio;
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
char m_buf[1024 * 2];
|
char m_buf[1024 * 2];
|
||||||
|
char m_fingerprint[32 * 2 + 8];
|
||||||
SSL *m_ssl;
|
SSL *m_ssl;
|
||||||
SSL_CTX *m_ctx;
|
SSL_CTX *m_ctx;
|
||||||
|
String m_fp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -72,19 +72,11 @@ bool xmrig::DaemonClient::disconnect()
|
||||||
|
|
||||||
bool xmrig::DaemonClient::isTLS() const
|
bool xmrig::DaemonClient::isTLS() const
|
||||||
{
|
{
|
||||||
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
|
return m_pool.isTLS();
|
||||||
|
# else
|
||||||
return false;
|
return false;
|
||||||
}
|
# endif
|
||||||
|
|
||||||
|
|
||||||
const char *xmrig::DaemonClient::tlsFingerprint() const
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *xmrig::DaemonClient::tlsVersion() const
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,6 +137,11 @@ void xmrig::DaemonClient::onHttpData(const HttpData &data)
|
||||||
|
|
||||||
m_ip = static_cast<const HttpContext &>(data).ip().c_str();
|
m_ip = static_cast<const HttpContext &>(data).ip().c_str();
|
||||||
|
|
||||||
|
if (isTLS()) {
|
||||||
|
m_tlsVersion = static_cast<const HttpsClient &>(data).version();
|
||||||
|
m_tlsFingerprint = static_cast<const HttpsClient &>(data).fingerprint();
|
||||||
|
}
|
||||||
|
|
||||||
rapidjson::Document doc;
|
rapidjson::Document doc;
|
||||||
if (doc.Parse(data.body.c_str()).HasParseError()) {
|
if (doc.Parse(data.body.c_str()).HasParseError()) {
|
||||||
if (!isQuiet()) {
|
if (!isQuiet()) {
|
||||||
|
@ -294,7 +291,7 @@ void xmrig::DaemonClient::send(int method, const char *url, const char *data, si
|
||||||
HttpClient *client;
|
HttpClient *client;
|
||||||
# ifdef XMRIG_FEATURE_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
if (m_pool.isTLS()) {
|
if (m_pool.isTLS()) {
|
||||||
client = new HttpsClient(method, url, this, data, size);
|
client = new HttpsClient(method, url, this, data, size, m_pool.fingerprint());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
# endif
|
# endif
|
||||||
|
|
|
@ -44,8 +44,6 @@ public:
|
||||||
protected:
|
protected:
|
||||||
bool disconnect() override;
|
bool disconnect() override;
|
||||||
bool isTLS() const override;
|
bool isTLS() const override;
|
||||||
const char *tlsFingerprint() const override;
|
|
||||||
const char *tlsVersion() const override;
|
|
||||||
int64_t submit(const JobResult &result) override;
|
int64_t submit(const JobResult &result) override;
|
||||||
void connect() override;
|
void connect() override;
|
||||||
void connect(const Pool &pool) override;
|
void connect(const Pool &pool) override;
|
||||||
|
@ -55,6 +53,8 @@ protected:
|
||||||
|
|
||||||
inline bool hasExtension(Extension) const noexcept override { return false; }
|
inline bool hasExtension(Extension) const noexcept override { return false; }
|
||||||
inline const char *mode() const override { return "daemon"; }
|
inline const char *mode() const override { return "daemon"; }
|
||||||
|
inline const char *tlsFingerprint() const override { return m_tlsFingerprint; }
|
||||||
|
inline const char *tlsVersion() const override { return m_tlsVersion; }
|
||||||
inline void deleteLater() override { delete this; }
|
inline void deleteLater() override { delete this; }
|
||||||
inline void tick(uint64_t) override {}
|
inline void tick(uint64_t) override {}
|
||||||
|
|
||||||
|
@ -68,6 +68,8 @@ private:
|
||||||
void setState(SocketState state);
|
void setState(SocketState state);
|
||||||
|
|
||||||
String m_blocktemplate;
|
String m_blocktemplate;
|
||||||
|
String m_tlsFingerprint;
|
||||||
|
String m_tlsVersion;
|
||||||
Timer *m_timer;
|
Timer *m_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue