Skip to content

Commit ef654aa

Browse files
authored
Merge pull request #4582 from EOSIO/release/1.0.x
Release 1.0.9
2 parents 5875549 + c6c3923 commit ef654aa

File tree

12 files changed

+91
-19
lines changed

12 files changed

+91
-19
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ set( CXX_STANDARD_REQUIRED ON)
2020

2121
set(VERSION_MAJOR 1)
2222
set(VERSION_MINOR 0)
23-
set(VERSION_PATCH 8)
23+
set(VERSION_PATCH 9)
2424

2525
set( CLI_CLIENT_EXECUTABLE_NAME cleos )
2626
set( GUI_CLIENT_EXECUTABLE_NAME eosio )

Docker/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ cd eos/Docker
2020
docker build . -t eosio/eos
2121
```
2222

23-
The above will build off the most recent commit to the master branch by default. If you would like to target a specific branch/tag, you may use a build argument. For example, if you wished to generate a docker image based off of the v1.0.8 tag, you could do the following:
23+
The above will build off the most recent commit to the master branch by default. If you would like to target a specific branch/tag, you may use a build argument. For example, if you wished to generate a docker image based off of the v1.0.9 tag, you could do the following:
2424

2525
```bash
26-
docker build -t eosio/eos:v1.0.8 --build-arg branch=v1.0.8 .
26+
docker build -t eosio/eos:v1.0.9 --build-arg branch=v1.0.9 .
2727
```
2828

2929
By default, the symbol in eosio.system is set to SYS. You can override this using the symbol argument while building the docker image.
@@ -181,7 +181,7 @@ Note: if you want to use the mongo db plugin, you have to enable it in your `dat
181181

182182
```
183183
# pull images
184-
docker pull eosio/eos:v1.0.8
184+
docker pull eosio/eos:v1.0.9
185185
186186
# create volume
187187
docker volume create --name=nodeos-data-volume

Docker/docker-compose-eosio1.0.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: "3"
22

33
services:
44
nodeosd:
5-
image: eosio/eos:v1.0.8
5+
image: eosio/eos:v1.0.9
66
command: /opt/eosio/bin/nodeosd.sh --data-dir /opt/eosio/bin/data-dir -e
77
hostname: nodeosd
88
ports:
@@ -14,7 +14,7 @@ services:
1414
- nodeos-data-volume:/opt/eosio/bin/data-dir
1515

1616
keosd:
17-
image: eosio/eos:v1.0.8
17+
image: eosio/eos:v1.0.9
1818
command: /opt/eosio/bin/keosd --wallet-dir /opt/eosio/bin/data-dir --http-server-address=127.0.0.1:8900
1919
hostname: keosd
2020
links:

libraries/testing/tester.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ namespace eosio { namespace testing {
9191
cfg.genesis.initial_timestamp = fc::time_point::from_iso_string("2020-01-01T00:00:00.000");
9292
cfg.genesis.initial_key = get_public_key( config::system_account_name, "active" );
9393

94-
abi_serializer::set_max_serialization_time(fc::microseconds(100*1000)); // 100ms for slow test machines
94+
abi_serializer::set_max_serialization_time(fc::seconds(1)); // 1s for slow test machines
9595

9696
for(int i = 0; i < boost::unit_test::framework::master_test_suite().argc; ++i) {
9797
if(boost::unit_test::framework::master_test_suite().argv[i] == std::string("--binaryen"))

plugins/bnet_plugin/bnet_plugin.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,12 +1283,24 @@ namespace eosio {
12831283

12841284
void listener::on_accept( boost::system::error_code ec ) {
12851285
if( ec ) {
1286+
if( ec == boost::system::errc::too_many_files_open )
1287+
do_accept();
12861288
return;
12871289
}
1288-
auto newsession = std::make_shared<session>( move( _socket ), _net_plugin );
1289-
_net_plugin->async_add_session( newsession );
1290-
newsession->_local_peer_id = _net_plugin->_peer_id;
1291-
newsession->run();
1290+
std::shared_ptr<session> newsession;
1291+
try {
1292+
newsession = std::make_shared<session>( move( _socket ), _net_plugin );
1293+
}
1294+
catch( std::exception& e ) {
1295+
//making a session creates an instance of std::random_device which may open /dev/urandom
1296+
// for example. Unfortuately the only defined error is a std::exception derivative
1297+
_socket.close();
1298+
}
1299+
if( newsession ) {
1300+
_net_plugin->async_add_session( newsession );
1301+
newsession->_local_peer_id = _net_plugin->_peer_id;
1302+
newsession->run();
1303+
}
12921304
do_accept();
12931305
}
12941306

plugins/http_plugin/http_plugin.cpp

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include <thread>
2525
#include <memory>
26+
#include <regex>
2627

2728
namespace eosio {
2829

@@ -31,7 +32,10 @@ namespace eosio {
3132
namespace asio = boost::asio;
3233

3334
using std::map;
35+
using std::vector;
36+
using std::set;
3437
using std::string;
38+
using std::regex;
3539
using boost::optional;
3640
using boost::asio::ip::tcp;
3741
using std::shared_ptr;
@@ -99,6 +103,28 @@ namespace eosio {
99103

100104
websocket_server_tls_type https_server;
101105

106+
bool validate_host;
107+
set<string> valid_hosts;
108+
109+
bool host_port_is_valid( const std::string& host_port ) {
110+
return !validate_host || valid_hosts.find(host_port) != valid_hosts.end();
111+
}
112+
113+
bool host_is_valid( const std::string& host, bool secure) {
114+
if (!validate_host) {
115+
return true;
116+
}
117+
118+
// normalise the incoming host so that it always has the explicit port
119+
static auto has_port_expr = regex("[^:]:[0-9]+$"); /// ends in :<number> without a preceeding colon which implies ipv6
120+
if (std::regex_search(host, has_port_expr)) {
121+
return host_port_is_valid( host );
122+
} else {
123+
// according to RFC 2732 ipv6 addresses should always be enclosed with brackets so we shouldn't need to special case here
124+
return host_port_is_valid( host + ":" + std::to_string(secure ? websocketpp::uri_default_secure_port : websocketpp::uri_default_port ));
125+
}
126+
}
127+
102128
ssl_context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
103129
ssl_context_ptr ctx = websocketpp::lib::make_shared<websocketpp::lib::asio::ssl::context>(asio::ssl::context::sslv23_server);
104130

@@ -169,6 +195,13 @@ namespace eosio {
169195
template<class T>
170196
void handle_http_request(typename websocketpp::server<detail::asio_with_stub_log<T>>::connection_ptr con) {
171197
try {
198+
auto& req = con->get_request();
199+
const auto& host_str = req.get_header("Host");
200+
if (host_str.empty() || !host_is_valid(host_str, con->get_uri()->get_secure())) {
201+
con->set_status(websocketpp::http::status_code::bad_request);
202+
return;
203+
}
204+
172205
if( !access_control_allow_origin.empty()) {
173206
con->append_header( "Access-Control-Allow-Origin", access_control_allow_origin );
174207
}
@@ -181,8 +214,7 @@ namespace eosio {
181214
if( access_control_allow_credentials ) {
182215
con->append_header( "Access-Control-Allow-Credentials", "true" );
183216
}
184-
185-
auto& req = con->get_request();
217+
186218
if(req.get_method() == "OPTIONS") {
187219
con->set_status(websocketpp::http::status_code::ok);
188220
return;
@@ -230,6 +262,7 @@ namespace eosio {
230262
elog("error thrown from http io service");
231263
}
232264
}
265+
233266
};
234267

235268
http_plugin::http_plugin():my(new http_plugin_impl()){}
@@ -275,10 +308,18 @@ namespace eosio {
275308
"Specify if Access-Control-Allow-Credentials: true should be returned on each request.")
276309
("max-body-size", bpo::value<uint32_t>()->default_value(1024*1024), "The maximum body size in bytes allowed for incoming RPC requests")
277310
("verbose-http-errors", bpo::bool_switch()->default_value(false), "Append the error log to HTTP responses")
311+
("http-validate-host", boost::program_options::value<bool>()->default_value(true), "If set to false, then any incoming \"Host\" header is considered valid")
312+
("http-alias", bpo::value<std::vector<string>>()->composing(), "Additionaly acceptable values for the \"Host\" header of incoming HTTP requests, can be specified multiple times. Includes http/s_server_address by default.")
278313
;
279314
}
280315

281316
void http_plugin::plugin_initialize(const variables_map& options) {
317+
my->validate_host = options.at("http-validate-host").as<bool>();
318+
if( options.count( "http-alias" )) {
319+
const auto& aliases = options["http-alias"].as<vector<string>>();
320+
my->valid_hosts.insert(aliases.begin(), aliases.end());
321+
}
322+
282323
tcp::resolver resolver(app().get_io_service());
283324
if(options.count("http-server-address") && options.at("http-server-address").as<string>().length()) {
284325
string lipstr = options.at("http-server-address").as<string>();
@@ -291,6 +332,8 @@ namespace eosio {
291332
} catch(const boost::system::system_error& ec) {
292333
elog("failed to configure http to listen on ${h}:${p} (${m})", ("h",host)("p",port)("m", ec.what()));
293334
}
335+
336+
my->valid_hosts.emplace(lipstr);
294337
}
295338

296339
if(options.count("https-server-address") && options.at("https-server-address").as<string>().length()) {
@@ -315,6 +358,8 @@ namespace eosio {
315358
} catch(const boost::system::system_error& ec) {
316359
elog("failed to configure https to listen on ${h}:${p} (${m})", ("h",host)("p",port)("m", ec.what()));
317360
}
361+
362+
my->valid_hosts.emplace(lipstr);
318363
}
319364

320365
my->max_body_size = options.at("max-body-size").as<uint32_t>();

plugins/net_plugin/net_plugin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2913,7 +2913,7 @@ namespace eosio {
29132913
( "p2p-listen-endpoint", bpo::value<string>()->default_value( "0.0.0.0:9876" ), "The actual host:port used to listen for incoming p2p connections.")
29142914
( "p2p-server-address", bpo::value<string>(), "An externally accessible host:port for identifying this node. Defaults to p2p-listen-endpoint.")
29152915
( "p2p-peer-address", bpo::value< vector<string> >()->composing(), "The public endpoint of a peer node to connect to. Use multiple p2p-peer-address options as needed to compose a network.")
2916-
( "p2p-max-nodes-per-host", bpo::value<int>()->default_value(def_max_nodes_per_host), "Maximum number of client0nodes from any single IP address")
2916+
( "p2p-max-nodes-per-host", bpo::value<int>()->default_value(def_max_nodes_per_host), "Maximum number of client nodes from any single IP address")
29172917
( "agent-name", bpo::value<string>()->default_value("\"EOS Test Agent\""), "The name supplied to identify this node amongst the peers.")
29182918
( "allowed-connection", bpo::value<vector<string>>()->multitoken()->default_value({"any"}, "any"), "Can be 'any' or 'producers' or 'specified' or 'none'. If 'specified', peer-key must be specified at least once. If only 'producers', peer-key is not required. 'producers' and 'specified' may be combined.")
29192919
( "peer-key", bpo::value<vector<string>>()->composing()->multitoken(), "Optional public key of peer allowed to connect. May be used multiple times.")

programs/cleos/httpc.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,18 @@ namespace eosio { namespace client { namespace http {
150150
return resolved_url(url, std::move(resolved_addresses), *resolved_port, is_loopback);
151151
}
152152

153+
string format_host_header(const resolved_url& url) {
154+
// common practice is to only make the port explicit when it is the non-default port
155+
if (
156+
(url.scheme == "https" && url.resolved_port == 443) ||
157+
(url.scheme == "http" && url.resolved_port == 80)
158+
) {
159+
return url.server;
160+
} else {
161+
return url.server + ":" + url.port;
162+
}
163+
}
164+
153165
fc::variant do_http_call( const connection_param& cp,
154166
const fc::variant& postdata,
155167
bool print_request,
@@ -163,8 +175,9 @@ namespace eosio { namespace client { namespace http {
163175

164176
boost::asio::streambuf request;
165177
std::ostream request_stream(&request);
178+
auto host_header_value = format_host_header(url);
166179
request_stream << "POST " << url.path << " HTTP/1.0\r\n";
167-
request_stream << "Host: " << url.server << "\r\n";
180+
request_stream << "Host: " << host_header_value << "\r\n";
168181
request_stream << "content-length: " << postjson.size() << "\r\n";
169182
request_stream << "Accept: */*\r\n";
170183
request_stream << "Connection: close\r\n";

programs/eosio-launcher/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,7 @@ launcher_def::write_config_file (tn_node_def &node) {
10261026
cfg << "readonly = 0\n";
10271027
cfg << "send-whole-blocks = true\n";
10281028
cfg << "http-server-address = " << host->host_name << ":" << instance.http_port << "\n";
1029+
cfg << "http-validate-host = false\n";
10291030
if (p2p == p2p_plugin::NET) {
10301031
cfg << "p2p-listen-endpoint = " << host->listen_addr << ":" << instance.p2p_port << "\n";
10311032
cfg << "p2p-server-address = " << host->public_name << ":" << instance.p2p_port << "\n";

tests/p2p_tests/pump/run_test.pl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ sub launch_nodes {
202202
my @cmdline = ($eosd,
203203
$gtsarg,
204204
"--data-dir=$data_dir[$i]",
205-
"--verbose-http-errors");
205+
"--verbose-http-errors",
206+
"--http-validate-host=false");
206207
$pid[$i] = fork;
207208
if ($pid[$i] > 0) {
208209
my $pause = $i == 0 ? $first_pause : $launch_pause;

tests/testUtils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,7 @@ def launch(self):
12321232
Utils.Print("ERROR: Wallet Manager wasn't configured to launch keosd")
12331233
return False
12341234

1235-
cmd="%s --data-dir %s --config-dir %s --http-server-address=%s:%d --verbose-http-errors" % (
1235+
cmd="%s --data-dir %s --config-dir %s --http-server-address=%s:%d --verbose-http-errors --http-validate-host=false" % (
12361236
Utils.EosWalletPath, WalletMgr.__walletDataDir, WalletMgr.__walletDataDir, self.host, self.port)
12371237
if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
12381238
with open(WalletMgr.__walletLogFile, 'w') as sout, open(WalletMgr.__walletLogFile, 'w') as serr:
@@ -1492,7 +1492,7 @@ def launch(self, pnodes=1, totalNodes=1, prodCount=1, topo="mesh", p2pPlugin="ne
14921492
if self.staging:
14931493
cmdArr.append("--nogen")
14941494

1495-
nodeosArgs="--max-transaction-time 5000 --filter-on * --p2p-max-nodes-per-host %d" % (totalNodes)
1495+
nodeosArgs="--max-transaction-time 5000 --abi-serializer-max-time-ms 5000 --filter-on * --p2p-max-nodes-per-host %d" % (totalNodes)
14961496
if not self.walletd:
14971497
nodeosArgs += " --plugin eosio::wallet_api_plugin"
14981498
if self.enableMongo:

tests/validate-dirty-db.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def errorExit(msg="", errorCode=1):
4040
def runNodeosAndGetOutput(myNodeId, myTimeout=3):
4141
"""Startup nodeos, wait for timeout (before forced shutdown) and collect output. Stdout, stderr and return code are returned in a dictionary."""
4242
Print("Launching nodeos process id: %d" % (myNodeId))
43-
cmd="programs/nodeos/nodeos --config-dir etc/eosio/node_bios --data-dir var/lib/node_bios --verbose-http-errors"
43+
cmd="programs/nodeos/nodeos --config-dir etc/eosio/node_bios --data-dir var/lib/node_bios --verbose-http-errors --http-validate-host=false"
4444
Print("cmd: %s" % (cmd))
4545
proc=subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
4646

0 commit comments

Comments
 (0)