2018-01-07 06:05:16 +01:00
// Copyright (c) 2014-2018, The Monero Project
2017-02-05 23:48:03 +01:00
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
# include "rpc_args.h"
2017-10-24 15:26:05 +02:00
# include <boost/algorithm/string.hpp>
2017-02-05 23:48:03 +01:00
# include <boost/asio/ip/address.hpp>
2017-11-25 23:25:05 +01:00
# include <boost/bind.hpp>
2017-02-05 23:48:03 +01:00
# include "common/command_line.h"
# include "common/i18n.h"
namespace cryptonote
{
rpc_args : : descriptors : : descriptors ( )
2018-01-09 22:37:30 +01:00
: rpc_bind_ip ( { " rpc-bind-ip " , rpc_args : : tr ( " Specify IP to bind RPC server " ) , " 127.0.0.1 " } )
2017-02-05 23:48:03 +01:00
, rpc_login ( { " rpc-login " , rpc_args : : tr ( " Specify username[:password] required for RPC server " ) , " " , true } )
2017-02-23 22:02:15 +01:00
, confirm_external_bind ( { " confirm-external-bind " , rpc_args : : tr ( " Confirm rpc-bind-ip value is NOT a loopback (local) IP " ) } )
2017-10-24 15:26:05 +02:00
, rpc_access_control_origins ( { " rpc-access-control-origins " , rpc_args : : tr ( " Specify a comma separated list of origins to allow cross origin resource sharing " ) , " " } )
2017-02-05 23:48:03 +01:00
{ }
const char * rpc_args : : tr ( const char * str ) { return i18n_translate ( str , " cryptonote::rpc_args " ) ; }
void rpc_args : : init_options ( boost : : program_options : : options_description & desc )
{
const descriptors arg { } ;
command_line : : add_arg ( desc , arg . rpc_bind_ip ) ;
command_line : : add_arg ( desc , arg . rpc_login ) ;
command_line : : add_arg ( desc , arg . confirm_external_bind ) ;
2017-10-24 15:26:05 +02:00
command_line : : add_arg ( desc , arg . rpc_access_control_origins ) ;
2017-02-05 23:48:03 +01:00
}
boost : : optional < rpc_args > rpc_args : : process ( const boost : : program_options : : variables_map & vm )
{
const descriptors arg { } ;
rpc_args config { } ;
config . bind_ip = command_line : : get_arg ( vm , arg . rpc_bind_ip ) ;
if ( ! config . bind_ip . empty ( ) )
{
// always parse IP here for error consistency
boost : : system : : error_code ec { } ;
const auto parsed_ip = boost : : asio : : ip : : address : : from_string ( config . bind_ip , ec ) ;
if ( ec )
{
LOG_ERROR ( tr ( " Invalid IP address given for -- " ) < < arg . rpc_bind_ip . name ) ;
return boost : : none ;
}
if ( ! parsed_ip . is_loopback ( ) & & ! command_line : : get_arg ( vm , arg . confirm_external_bind ) )
{
LOG_ERROR (
" -- " < < arg . rpc_bind_ip . name < <
tr ( " permits inbound unencrypted external connections. Consider SSH tunnel or SSL proxy instead. Override with -- " ) < <
arg . confirm_external_bind . name
) ;
return boost : : none ;
}
}
if ( command_line : : has_arg ( vm , arg . rpc_login ) )
{
2017-10-28 20:13:42 +02:00
config . login = tools : : login : : parse ( command_line : : get_arg ( vm , arg . rpc_login ) , true , [ ] ( bool verify ) {
return tools : : password_container : : prompt ( verify , " RPC server password " ) ;
} ) ;
2017-02-05 23:48:03 +01:00
if ( ! config . login )
return boost : : none ;
if ( config . login - > username . empty ( ) )
{
LOG_ERROR ( tr ( " Username specified with -- " ) < < arg . rpc_login . name < < tr ( " cannot be empty " ) ) ;
return boost : : none ;
}
}
2017-10-24 15:26:05 +02:00
auto access_control_origins_input = command_line : : get_arg ( vm , arg . rpc_access_control_origins ) ;
if ( ! access_control_origins_input . empty ( ) )
{
if ( ! config . login )
{
2018-06-13 12:49:49 +02:00
LOG_ERROR ( arg . rpc_access_control_origins . name < < tr ( " requires RPC server password -- " ) < < arg . rpc_login . name < < tr ( " cannot be empty " ) ) ;
2017-10-24 15:26:05 +02:00
return boost : : none ;
}
std : : vector < std : : string > access_control_origins ;
boost : : split ( access_control_origins , access_control_origins_input , boost : : is_any_of ( " , " ) ) ;
std : : for_each ( access_control_origins . begin ( ) , access_control_origins . end ( ) , boost : : bind ( & boost : : trim < std : : string > , _1 , std : : locale : : classic ( ) ) ) ;
config . access_control_origins = std : : move ( access_control_origins ) ;
}
2017-02-05 23:48:03 +01:00
return { std : : move ( config ) } ;
}
}