|
@@ -1,4 +1,4 @@
|
|
|
-// ECOin - Copyright (c) - 2014/2024 - GPLv3 - epsylon@riseup.net (https://03c8.net)
|
|
|
+// ECOin - Copyright (c) - 2014/2025 - GPLv3 - epsylon@riseup.net (https://ecoin.03c8.net)
|
|
|
|
|
|
#include "init.h"
|
|
|
#include "util.h"
|
|
@@ -9,7 +9,6 @@
|
|
|
#include "db.h"
|
|
|
|
|
|
#undef printf
|
|
|
-#include <boost/asio.hpp>
|
|
|
#include <boost/asio/ip/v6_only.hpp>
|
|
|
#include <boost/bind/bind.hpp>
|
|
|
using namespace boost::placeholders;
|
|
@@ -23,8 +22,17 @@ using namespace boost::placeholders;
|
|
|
#include <boost/asio/ssl.hpp>
|
|
|
#include <boost/filesystem/fstream.hpp>
|
|
|
#include <boost/shared_ptr.hpp>
|
|
|
+#include <boost/asio/ip/address_v4.hpp>
|
|
|
+#include <boost/asio/ip/address_v6.hpp>
|
|
|
+#include <iostream>
|
|
|
+#include <array>
|
|
|
#include <list>
|
|
|
|
|
|
+#include <boost/asio/ip/address.hpp>
|
|
|
+#include <boost/asio.hpp>
|
|
|
+#include <vector>
|
|
|
+#include <string>
|
|
|
+
|
|
|
#define printf OutputDebugStringF
|
|
|
|
|
|
using namespace std;
|
|
@@ -501,22 +509,41 @@ void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
|
|
|
|
|
|
bool ClientAllowed(const boost::asio::ip::address& address)
|
|
|
{
|
|
|
- if (address.is_v6()
|
|
|
- && (address.to_v6().is_v4_compatible()
|
|
|
- || address.to_v6().is_v4_mapped()))
|
|
|
- return ClientAllowed(address.to_v6().to_v4());
|
|
|
-
|
|
|
- if (address == asio::ip::address_v4::loopback()
|
|
|
- || address == asio::ip::address_v6::loopback()
|
|
|
- || (address.is_v4()
|
|
|
- && (address.to_v4().to_ulong() & 0xff000000) == 0x7f000000))
|
|
|
- return true;
|
|
|
-
|
|
|
- const string strAddress = address.to_string();
|
|
|
- const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
|
|
|
- BOOST_FOREACH(string strAllow, vAllow)
|
|
|
+ if (address.is_v6())
|
|
|
+ {
|
|
|
+ const boost::asio::ip::address_v6& ipv6_address = address.to_v6();
|
|
|
+ if (ipv6_address.is_v4_mapped())
|
|
|
+ {
|
|
|
+ const std::array<unsigned char, 16>& bytes = ipv6_address.to_bytes();
|
|
|
+ unsigned int ipv4_address = (bytes[12] << 24) | (bytes[13] << 16) | (bytes[14] << 8) | bytes[15];
|
|
|
+ return ClientAllowed(boost::asio::ip::address_v4(ntohl(ipv4_address)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (address == boost::asio::ip::address_v4::loopback() ||
|
|
|
+ address == boost::asio::ip::address_v6::loopback() ||
|
|
|
+ address.is_v4())
|
|
|
+ {
|
|
|
+ const boost::asio::ip::address_v4& ipv4_address = address.to_v4();
|
|
|
+ unsigned int address_int = (ipv4_address.to_bytes()[0] << 24) |
|
|
|
+ (ipv4_address.to_bytes()[1] << 16) |
|
|
|
+ (ipv4_address.to_bytes()[2] << 8) |
|
|
|
+ ipv4_address.to_bytes()[3];
|
|
|
+ if ((address_int & 0xff000000) == 0x7f000000)
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const std::string strAddress = address.to_string();
|
|
|
+ const std::vector<std::string>& vAllow = mapMultiArgs["-rpcallowip"];
|
|
|
+
|
|
|
+ for (const auto& strAllow : vAllow)
|
|
|
+ {
|
|
|
if (WildcardMatch(strAddress, strAllow))
|
|
|
+ {
|
|
|
return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -547,21 +574,24 @@ public:
|
|
|
if (fUseSSL) return asio::write(stream, asio::buffer(s, n));
|
|
|
return asio::write(stream.next_layer(), asio::buffer(s, n));
|
|
|
}
|
|
|
+
|
|
|
bool connect(const std::string& server, const std::string& port)
|
|
|
{
|
|
|
ip::tcp::resolver resolver(GetIOService(stream));
|
|
|
- ip::tcp::resolver::query query(server.c_str(), port.c_str());
|
|
|
- ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
|
|
|
- ip::tcp::resolver::iterator end;
|
|
|
- boost::system::error_code error = asio::error::host_not_found;
|
|
|
- while (error && endpoint_iterator != end)
|
|
|
+ ip::tcp::resolver::results_type endpoints = resolver.resolve(server, port);
|
|
|
+ boost::system::error_code error;
|
|
|
+
|
|
|
+ for (auto endpoint = endpoints.begin(); endpoint != endpoints.end(); ++endpoint)
|
|
|
{
|
|
|
stream.lowest_layer().close();
|
|
|
- stream.lowest_layer().connect(*endpoint_iterator++, error);
|
|
|
+ stream.lowest_layer().connect(*endpoint, error);
|
|
|
+
|
|
|
+ if (!error)
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|
|
|
- if (error)
|
|
|
- return false;
|
|
|
- return true;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
private:
|
|
@@ -585,7 +615,7 @@ class AcceptedConnectionImpl : public AcceptedConnection
|
|
|
{
|
|
|
public:
|
|
|
AcceptedConnectionImpl(
|
|
|
- asio::io_service& io_service,
|
|
|
+ asio::io_context& io_service,
|
|
|
ssl::context &context,
|
|
|
bool fUseSSL) :
|
|
|
sslStream(io_service, context),
|
|
@@ -729,9 +759,7 @@ void ThreadRPCServer2(void* parg)
|
|
|
|
|
|
const bool fUseSSL = GetBoolArg("-rpcssl");
|
|
|
|
|
|
- asio::io_service io_service;
|
|
|
-
|
|
|
- //ssl::context context(io_service, ssl::context::no_sslv2);
|
|
|
+ asio::io_context io_service;
|
|
|
ssl::context context(ssl::context::sslv23);
|
|
|
|
|
|
if (fUseSSL)
|
|
@@ -739,12 +767,12 @@ void ThreadRPCServer2(void* parg)
|
|
|
context.set_options(ssl::context::no_sslv2);
|
|
|
|
|
|
boost::filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
|
|
|
- if (!pathCertFile.is_complete()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile;
|
|
|
+ if (!pathCertFile.is_absolute()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile;
|
|
|
if (boost::filesystem::exists(pathCertFile)) context.use_certificate_chain_file(pathCertFile.string());
|
|
|
else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str());
|
|
|
|
|
|
boost::filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
|
|
|
- if (!pathPKFile.is_complete()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile;
|
|
|
+ if (!pathPKFile.is_absolute()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile;
|
|
|
if (boost::filesystem::exists(pathPKFile)) context.use_private_key_file(pathPKFile.string(), ssl::context::pem);
|
|
|
else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str());
|
|
|
|
|
@@ -770,7 +798,7 @@ void ThreadRPCServer2(void* parg)
|
|
|
acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error);
|
|
|
|
|
|
acceptor->bind(endpoint);
|
|
|
- acceptor->listen(socket_base::max_connections);
|
|
|
+ acceptor->listen(512);
|
|
|
|
|
|
RPCListen(acceptor, context, fUseSSL);
|
|
|
StopRequests.connect(signals2::slot<void ()>(
|
|
@@ -794,7 +822,7 @@ void ThreadRPCServer2(void* parg)
|
|
|
acceptor->open(endpoint.protocol());
|
|
|
acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
|
|
|
acceptor->bind(endpoint);
|
|
|
- acceptor->listen(socket_base::max_connections);
|
|
|
+ acceptor->listen(512);
|
|
|
|
|
|
RPCListen(acceptor, context, fUseSSL);
|
|
|
StopRequests.connect(signals2::slot<void ()>(
|
|
@@ -1021,8 +1049,7 @@ Object CallRPC(const string& strMethod, const Array& params)
|
|
|
GetConfigFile().string().c_str()));
|
|
|
|
|
|
bool fUseSSL = GetBoolArg("-rpcssl");
|
|
|
- asio::io_service io_service;
|
|
|
- //ssl::context context(io_service, ssl::context::sslv23);
|
|
|
+ asio::io_context io_service;
|
|
|
ssl::context context(ssl::context::sslv23);
|
|
|
context.set_options(ssl::context::no_sslv2);
|
|
|
asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
|