diff --git a/src/ripple/server/Port.h b/src/ripple/server/Port.h index a20bf2fc7..ab3102da8 100644 --- a/src/ripple/server/Port.h +++ b/src/ripple/server/Port.h @@ -20,6 +20,7 @@ #ifndef RIPPLE_SERVER_PORT_H_INCLUDED #define RIPPLE_SERVER_PORT_H_INCLUDED +#include #include #include #include @@ -99,6 +100,30 @@ std::ostream& operator<< (std::ostream& os, Port const& p); } // HTTP + +//------------------------------------------------------------------------------ + +struct ParsedPort +{ + std::string name; + std::set protocol; + std::string user; + std::string password; + std::string admin_user; + std::string admin_password; + std::string ssl_key; + std::string ssl_cert; + std::string ssl_chain; + + boost::optional ip; + boost::optional port; + boost::optional> admin_ip; + boost::optional> secure_gateway_ip; +}; + +void +parse_Port (ParsedPort& port, Section const& section, std::ostream& log); + } // ripple #endif diff --git a/src/ripple/server/impl/Port.cpp b/src/ripple/server/impl/Port.cpp index b1931973e..704108ed2 100644 --- a/src/ripple/server/impl/Port.cpp +++ b/src/ripple/server/impl/Port.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include namespace ripple { namespace HTTP { @@ -46,4 +47,136 @@ operator<< (std::ostream& os, Port const& p) } } // HTTP + +//------------------------------------------------------------------------------ + +static +void +populate (Section const& section, std::string const& field, std::ostream& log, + boost::optional>& ips, + bool allowAllIps, std::vector const& admin_ip) +{ + auto const result = section.find(field); + if (result.second) + { + std::stringstream ss (result.first); + std::string ip; + bool has_any (false); + + ips.emplace(); + while (std::getline (ss, ip, ',')) + { + auto const addr = beast::IP::Endpoint::from_string_checked (ip); + if (! addr.second) + { + log << "Invalid value '" << ip << "' for key '" << field << + "' in [" << section.name () << "]\n"; + Throw (); + } + + if (is_unspecified (addr.first)) + { + if (! allowAllIps) + { + log << "0.0.0.0 not allowed'" << + "' for key '" << field << "' in [" << + section.name () << "]\n"; + throw std::exception (); + } + else + { + has_any = true; + } + } + + if (has_any && ! ips->empty ()) + { + log << "IP specified along with 0.0.0.0 '" << ip << + "' for key '" << field << "' in [" << + section.name () << "]\n"; + Throw (); + } + + auto const& address = addr.first.address(); + if (std::find_if (admin_ip.begin(), admin_ip.end(), + [&address] (beast::IP::Address const& ip) + { + return address == ip; + } + ) != admin_ip.end()) + { + log << "IP specified for " << field << " is also for " << + "admin: " << ip << " in [" << section.name() << "]\n"; + throw std::exception(); + } + + ips->emplace_back (addr.first.address ()); + } + } +} + +void +parse_Port (ParsedPort& port, Section const& section, std::ostream& log) +{ + { + auto result = section.find("ip"); + if (result.second) + { + try + { + port.ip = boost::asio::ip::address::from_string(result.first); + } + catch (std::exception const&) + { + log << "Invalid value '" << result.first << + "' for key 'ip' in [" << section.name() << "]\n"; + Throw(); + } + } + } + + { + auto const result = section.find("port"); + if (result.second) + { + auto const ul = std::stoul(result.first); + if (ul > std::numeric_limits::max()) + { + log << "Value '" << result.first + << "' for key 'port' is out of range\n"; + Throw (); + } + if (ul == 0) + { + log << + "Value '0' for key 'port' is invalid\n"; + Throw (); + } + port.port = static_cast(ul); + } + } + + { + auto const result = section.find("protocol"); + if (result.second) + { + for (auto const& s : beast::rfc2616::split_commas( + result.first.begin(), result.first.end())) + port.protocol.insert(s); + } + } + + populate (section, "admin", log, port.admin_ip, true, {}); + populate (section, "secure_gateway", log, port.secure_gateway_ip, false, + port.admin_ip.get_value_or({})); + + set(port.user, "user", section); + set(port.password, "password", section); + set(port.admin_user, "admin_user", section); + set(port.admin_password, "admin_password", section); + set(port.ssl_key, "ssl_key", section); + set(port.ssl_cert, "ssl_cert", section); + set(port.ssl_chain, "ssl_chain", section); +} + } // ripple diff --git a/src/ripple/server/impl/ServerHandlerImp.cpp b/src/ripple/server/impl/ServerHandlerImp.cpp index 94a82aecb..fa88a4dc5 100644 --- a/src/ripple/server/impl/ServerHandlerImp.cpp +++ b/src/ripple/server/impl/ServerHandlerImp.cpp @@ -469,155 +469,7 @@ ServerHandler::Setup::makeContexts() } } -namespace detail { - -// Intermediate structure used for parsing -struct ParsedPort -{ - std::string name; - std::set protocol; - std::string user; - std::string password; - std::string admin_user; - std::string admin_password; - std::string ssl_key; - std::string ssl_cert; - std::string ssl_chain; - - boost::optional ip; - boost::optional port; - boost::optional> admin_ip; - boost::optional> secure_gateway_ip; -}; - -void -populate (Section const& section, std::string const& field, std::ostream& log, - boost::optional>& ips, - bool allowAllIps, std::vector const& admin_ip) -{ - auto const result = section.find(field); - if (result.second) - { - std::stringstream ss (result.first); - std::string ip; - bool has_any (false); - - ips.emplace(); - while (std::getline (ss, ip, ',')) - { - auto const addr = beast::IP::Endpoint::from_string_checked (ip); - if (! addr.second) - { - log << "Invalid value '" << ip << "' for key '" << field << - "' in [" << section.name () << "]\n"; - Throw (); - } - - if (is_unspecified (addr.first)) - { - if (! allowAllIps) - { - log << "0.0.0.0 not allowed'" << - "' for key '" << field << "' in [" << - section.name () << "]\n"; - throw std::exception (); - } - else - { - has_any = true; - } - } - - if (has_any && ! ips->empty ()) - { - log << "IP specified along with 0.0.0.0 '" << ip << - "' for key '" << field << "' in [" << - section.name () << "]\n"; - Throw (); - } - - auto const& address = addr.first.address(); - if (std::find_if (admin_ip.begin(), admin_ip.end(), - [&address] (beast::IP::Address const& ip) - { - return address == ip; - } - ) != admin_ip.end()) - { - log << "IP specified for " << field << " is also for " << - "admin: " << ip << " in [" << section.name() << "]\n"; - throw std::exception(); - } - - ips->emplace_back (addr.first.address ()); - } - } -} - -void -parse_Port (ParsedPort& port, Section const& section, std::ostream& log) -{ - { - auto result = section.find("ip"); - if (result.second) - { - try - { - port.ip = boost::asio::ip::address::from_string(result.first); - } - catch (std::exception const&) - { - log << "Invalid value '" << result.first << - "' for key 'ip' in [" << section.name() << "]\n"; - Throw(); - } - } - } - - { - auto const result = section.find("port"); - if (result.second) - { - auto const ul = std::stoul(result.first); - if (ul > std::numeric_limits::max()) - { - log << "Value '" << result.first - << "' for key 'port' is out of range\n"; - Throw (); - } - if (ul == 0) - { - log << - "Value '0' for key 'port' is invalid\n"; - Throw (); - } - port.port = static_cast(ul); - } - } - - { - auto const result = section.find("protocol"); - if (result.second) - { - for (auto const& s : beast::rfc2616::split_commas( - result.first.begin(), result.first.end())) - port.protocol.insert(s); - } - } - - populate (section, "admin", log, port.admin_ip, true, {}); - populate (section, "secure_gateway", log, port.secure_gateway_ip, false, - port.admin_ip.get_value_or({})); - - set(port.user, "user", section); - set(port.password, "password", section); - set(port.admin_user, "admin_user", section); - set(port.admin_password, "admin_password", section); - set(port.ssl_key, "ssl_key", section); - set(port.ssl_cert, "ssl_cert", section); - set(port.ssl_chain, "ssl_chain", section); -} - +static HTTP::Port to_Port(ParsedPort const& parsed, std::ostream& log) { @@ -673,6 +525,7 @@ to_Port(ParsedPort const& parsed, std::ostream& log) return p; } +static std::vector parse_Ports ( Config const& config, @@ -745,6 +598,7 @@ parse_Ports ( } // Fill out the client portion of the Setup +static void setup_Client (ServerHandler::Setup& setup) { @@ -770,6 +624,7 @@ setup_Client (ServerHandler::Setup& setup) } // Fill out the overlay portion of the Setup +static void setup_Overlay (ServerHandler::Setup& setup) { @@ -788,18 +643,16 @@ setup_Overlay (ServerHandler::Setup& setup) setup.overlay.port = iter->port; } -} - ServerHandler::Setup setup_ServerHandler( Config const& config, std::ostream& log) { ServerHandler::Setup setup; - setup.ports = detail::parse_Ports(config, log); + setup.ports = parse_Ports(config, log); - detail::setup_Client(setup); - detail::setup_Overlay(setup); + setup_Client(setup); + setup_Overlay(setup); return setup; } @@ -814,4 +667,4 @@ make_ServerHandler (Application& app, beast::Stoppable& parent, io_service, jobQueue, networkOPs, resourceManager, cm); } -} +} // ripple