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