rippled
TrustedPublisherServer.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright 2017 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 #ifndef RIPPLE_TEST_TRUSTED_PUBLISHER_SERVER_H_INCLUDED
20 #define RIPPLE_TEST_TRUSTED_PUBLISHER_SERVER_H_INCLUDED
21 
22 #include <ripple/protocol/PublicKey.h>
23 #include <ripple/protocol/SecretKey.h>
24 #include <ripple/protocol/Sign.h>
25 #include <ripple/basics/base64.h>
26 #include <ripple/basics/random.h>
27 #include <ripple/basics/strHex.h>
28 #include <test/jtx/envconfig.h>
29 #include <boost/algorithm/string/predicate.hpp>
30 #include <boost/asio.hpp>
31 #include <boost/asio/ip/tcp.hpp>
32 #include <boost/asio/ssl/stream.hpp>
33 #include <boost/beast/http.hpp>
34 #include <boost/beast/ssl.hpp>
35 #include <boost/beast/version.hpp>
36 #include <boost/lexical_cast.hpp>
37 #include <thread>
38 
39 namespace ripple {
40 namespace test {
41 
43 {
44  using endpoint_type = boost::asio::ip::tcp::endpoint;
45  using address_type = boost::asio::ip::address;
46  using socket_type = boost::asio::ip::tcp::socket;
47 
48  using req_type = boost::beast::http::request<boost::beast::http::string_body>;
49  using resp_type = boost::beast::http::response<boost::beast::http::string_body>;
50  using error_code = boost::system::error_code;
51 
54  boost::asio::ip::tcp::acceptor acceptor_;
56 
57  // The SSL context is required, and holds certificates
58  bool useSSL_;
59  boost::asio::ssl::context sslCtx_{boost::asio::ssl::context::tlsv12};
60 
63 
64  // Load a signed certificate into the ssl context, and configure
65  // the context for use with a server.
66  inline
67  void
69  {
70  sslCtx_.set_password_callback(
71  [](std::size_t,
72  boost::asio::ssl::context_base::password_purpose)
73  {
74  return "test";
75  });
76 
77  sslCtx_.set_options(
78  boost::asio::ssl::context::default_workarounds |
79  boost::asio::ssl::context::no_sslv2 |
80  boost::asio::ssl::context::single_dh_use);
81 
82  sslCtx_.use_certificate_chain(
83  boost::asio::buffer(cert().data(), cert().size()));
84 
85  sslCtx_.use_private_key(
86  boost::asio::buffer(key().data(), key().size()),
87  boost::asio::ssl::context::file_format::pem);
88 
89  sslCtx_.use_tmp_dh(
90  boost::asio::buffer(dh().data(), dh().size()));
91  }
92 
93 public:
94  struct Validator
95  {
99  };
100 
101  static
104  PublicKey const& pk,
105  SecretKey const& sk,
106  PublicKey const& spk,
107  SecretKey const& ssk,
108  int seq)
109  {
110  STObject st(sfGeneric);
111  st[sfSequence] = seq;
112  st[sfPublicKey] = pk;
113  st[sfSigningPubKey] = spk;
114 
115  sign(st, HashPrefix::manifest, *publicKeyType(spk), ssk);
118 
119  Serializer s;
120  st.add(s);
121 
122  return base64_encode (std::string(
123  static_cast<char const*> (s.data()), s.size()));
124  }
125 
126  static
127  Validator
129  {
130  auto const secret = randomSecretKey();
131  auto const masterPublic =
133  auto const signingKeys = randomKeyPair(KeyType::secp256k1);
134  return { masterPublic, signingKeys.first, makeManifestString (
135  masterPublic, secret, signingKeys.first, signingKeys.second, 1) };
136  }
137 
139  boost::asio::io_context& ioc,
140  std::vector<Validator> const& validators,
142  bool useSSL = false,
143  int version = 1,
144  bool immediateStart = true,
145  int sequence = 1)
146  : sock_{ioc}
147  , ep_{beast::IP::Address::from_string(
149  // 0 means let OS pick the port based on what's available
150  0}
151  , acceptor_{ioc}
152  , useSSL_{useSSL}
155  {
156  auto const keys = randomKeyPair(KeyType::secp256k1);
157  auto const manifest = makeManifestString (
160  keys.first,
161  keys.second,
162  1);
163 
164  std::string data = "{\"sequence\":" + std::to_string(sequence) +
165  ",\"expiration\":" +
166  std::to_string(expiration.time_since_epoch().count()) +
167  ",\"validators\":[";
168 
169  for (auto const& val : validators)
170  {
171  data += "{\"validation_public_key\":\"" + strHex(val.masterPublic) +
172  "\",\"manifest\":\"" + val.manifest + "\"},";
173  }
174  data.pop_back();
175  data += "]}";
176  std::string blob = base64_encode(data);
177  auto const sig = sign(keys.first, keys.second, makeSlice(data));
178  getList_ = [blob, sig, manifest, version](int interval) {
180  l << "{\"blob\":\"" << blob << "\"" <<
181  ",\"signature\":\"" << strHex(sig) << "\"" <<
182  ",\"manifest\":\"" << manifest << "\"" <<
183  ",\"refresh_interval\": " << interval <<
184  ",\"version\":" << version << '}';
185  return l.str();
186  };
187 
188  if (useSSL_)
189  {
190  // This holds the self-signed certificate used by the server
192  }
193 
194  if (immediateStart)
195  start();
196  }
197 
198  void start()
199  {
200  error_code ec;
201  acceptor_.open(ep_.protocol());
202  acceptor_.set_option(
203  boost::asio::ip::tcp::acceptor::reuse_address(true), ec);
204  acceptor_.bind(ep_);
205  acceptor_.listen(boost::asio::socket_base::max_connections);
206  acceptor_.async_accept(
207  sock_,
208  std::bind(
209  &TrustedPublisherServer::on_accept, this, std::placeholders::_1));
210  }
211 
212  void stop()
213  {
214  error_code ec;
215  acceptor_.close(ec);
216  // TODO consider making this join
217  // any running do_peer threads
218  }
219 
221  {
222  stop();
223  }
224 
227  {
228  return acceptor_.local_endpoint();
229  }
230 
231  PublicKey const&
233  {
234  return publisherPublic_;
235  }
236 
237  /* CA/self-signed certs :
238  *
239  * The following three methods return certs/keys used by
240  * server and/or client to do the SSL handshake. These strings
241  * were generated using the script below. The server key and cert
242  * are used to configure the server (see load_server_certificate
243  * above). The ca.crt should be used to configure the client
244  * when ssl verification is enabled.
245  *
246  * note:
247  * cert() ==> server.crt
248  * key() ==> server.key
249  * ca_cert() ==> ca.crt
250  * dh() ==> dh.pem
251  ```
252  #!/usr/bin/env bash
253 
254  mkdir -p /tmp/__certs__
255  pushd /tmp/__certs__
256  rm *.crt *.key *.pem
257 
258  # generate CA
259  openssl genrsa -out ca.key 2048
260  openssl req -new -x509 -nodes -days 10000 -key ca.key -out ca.crt \
261  -subj "/C=US/ST=CA/L=Los Angeles/O=rippled-unit-tests/CN=example.com"
262  # generate private cert
263  openssl genrsa -out server.key 2048
264  # Generate certificate signing request
265  # since our unit tests can run in either ipv4 or ipv6 mode,
266  # we need to use extensions (subjectAltName) so that we can
267  # associate both ipv4 and ipv6 localhost addresses with this cert
268  cat >"extras.cnf" <<EOF
269  [req]
270  req_extensions = v3_req
271  distinguished_name = req_distinguished_name
272 
273  [req_distinguished_name]
274 
275  [v3_req]
276  subjectAltName = @alt_names
277 
278  [alt_names]
279  DNS.1 = localhost
280  IP.1 = ::1
281  EOF
282  openssl req -new -key server.key -out server.csr \
283  -config extras.cnf \
284  -subj "/C=US/ST=California/L=San Francisco/O=rippled-unit-tests/CN=127.0.0.1" \
285 
286  # Create public certificate by signing with our CA
287  openssl x509 -req -days 10000 -in server.csr -CA ca.crt -CAkey ca.key -out server.crt \
288  -extfile extras.cnf -set_serial 01 -extensions v3_req
289 
290  # generate DH params for server
291  openssl dhparam -out dh.pem 2048
292  # verify certs
293  openssl verify -CAfile ca.crt server.crt
294  openssl x509 -in server.crt -text -noout
295  popd
296  ```
297  */
298  static
299  std::string const&
301  {
302  static std::string const cert {R"cert(
303 -----BEGIN CERTIFICATE-----
304 MIIDczCCAlugAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEL
305 MAkGA1UECAwCQ0ExFDASBgNVBAcMC0xvcyBBbmdlbGVzMRswGQYDVQQKDBJyaXBw
306 bGVkLXVuaXQtdGVzdHMxFDASBgNVBAMMC2V4YW1wbGUuY29tMB4XDTE5MDgwNzE3
307 MzM1OFoXDTQ2MTIyMzE3MzM1OFowazELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
308 bGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xGzAZBgNVBAoMEnJpcHBs
309 ZWQtdW5pdC10ZXN0czESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjANBgkqhkiG9w0B
310 AQEFAAOCAQ8AMIIBCgKCAQEA5Ky0UE9K+gFOznfwBvq2HfnQOOPGtVf4G9m63b5V
311 QNJYCSNiYxkGZW72ESM3XA8BledlkV9pwIm17+7ucB1Ed3efQjQDq2RSk5LDYDaa
312 r0Qzzy0EC3b9+AKA6mAoVY6s1Qws/YvM4esz0H+SVvtVcFqA46kRWhJN7M5ic1lu
313 d58fAq04BHqi5zOEOzfHJYPGUgQOxRTHluYkkkBrL2xioHHnOROshW+PIYFiAc/h
314 WPzuihPHnKaziPRw+O6O8ysnCxycQHgqtvx73T52eJdLxtr3ToRWaY/8VF/Cog5c
315 uvWEtg6EucGOszIH8O7eJWaJpVpAfZIX+c62MQWLpOLi/QIDAQABoyowKDAmBgNV
316 HREEHzAdgglsb2NhbGhvc3SHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQEF
317 BQADggEBAOhLAO/e0lGi9TZ2HiVi4sJ7KVQaBQHGhfsysILoQNHrNqDypPc/ZrSa
318 WQ2OqyUeltMnUdN5S1h3MKRZlbAeBQlwkPdjTzlzWkCMWB5BsfIGy5ovqmNQ7zPa
319 Khg5oxq3mU8ZLiJP4HngyU+hOOCt5tttex2S8ubjFT+3C3cydLKEOXCUPspaVkKn
320 Eq8WSBoYTvyUVmSi6+m6HGiowWsM5Qgj93IRW6JCbkgfPeKXC/5ykAPQcFHwNaKT
321 rpWokcavZyMbVjRsbzCQcc7n2j7tbLOu2svSLy6oXwG6n/bEagl5WpN2/TzQuwe7
322 f5ktutc4DDJSV7fuYYCuGumrHAjcELE=
323 -----END CERTIFICATE-----
324 )cert"};
325  return cert;
326  }
327 
328  static
329  std::string const&
330  key()
331  {
332  static std::string const key {R"pkey(
333 -----BEGIN RSA PRIVATE KEY-----
334 MIIEpQIBAAKCAQEA5Ky0UE9K+gFOznfwBvq2HfnQOOPGtVf4G9m63b5VQNJYCSNi
335 YxkGZW72ESM3XA8BledlkV9pwIm17+7ucB1Ed3efQjQDq2RSk5LDYDaar0Qzzy0E
336 C3b9+AKA6mAoVY6s1Qws/YvM4esz0H+SVvtVcFqA46kRWhJN7M5ic1lud58fAq04
337 BHqi5zOEOzfHJYPGUgQOxRTHluYkkkBrL2xioHHnOROshW+PIYFiAc/hWPzuihPH
338 nKaziPRw+O6O8ysnCxycQHgqtvx73T52eJdLxtr3ToRWaY/8VF/Cog5cuvWEtg6E
339 ucGOszIH8O7eJWaJpVpAfZIX+c62MQWLpOLi/QIDAQABAoIBACf8mzs/4lh9Sg6I
340 ooxV4uqy+Fo6WlDzpQsZs7d6xOWk4ogWi+nQQnISSS0N/2w1o41W/UfCa3ejnRDr
341 sv4f4A0T+eFVvx6FWHs9urRkWAA16OldccufbyGjLm/NiMANRuOqUWO0woru2gyn
342 git7n6EZ8lfdBI+/i6jRHh4VkV+ROt5Zbp9zuJsj0yMqJH7J6Ebtl1jAF6PemLBL
343 yxdiYqR8LKTunTGGP/L+4K5a389oPDcJ1+YX805NEopmfrIhPr+BQYdz8905aVFk
344 FSS4TJy23EhFLzKf3+iSept6Giim+2yy2rv1RPCKgjOXbJ+4LD48xumDol6XWgYr
345 1CBzQIECgYEA/jBEGOjV02a9A3C5RJxZMawlGwGrvvALG2UrKvwQc595uxwrUw9S
346 Mn3ZQBEGnEWwEf44jSpWzp8TtejMxEvrU5243eWgwif1kqr1Mcj54DR7Qm15/hsj
347 M3nA2WscVG2OHBs4AwzMCHE2vfEAkbz71s6xonhg6zvsC26Zy3hYPqkCgYEA5k3k
348 OuCeG5FXW1/GzhvVFuhl6msNKzuUnLmJg6500XPny5Xo7W3RMvjtTM2XLt1USU6D
349 arMCCQ1A8ku1SoFdSw5RC6Fl8ZoUFBz9FPPwT6usQssGyFxiiqdHLvTlk12NNCk3
350 vJYsdQ+v/dKuZ8T4U3GTgQSwPTj6J0kJUf5y2jUCgYEA+hi/R8r/aArz+kiU4T78
351 O3Vm5NWWCD3ij8fQ23A7N6g3e7RRpF20wF02vmSCHowqmumI9swrsQyvthIiNxmD
352 pzfORvXCYIY0h2SR77QQt1qr1EYm+6/zyJgI+WL78s4APwNA7y9OKRhLhkN0DfDl
353 0Qp5mKPcqFbC/tSJmbsFCFECgYEAwlLC2rMgdV5jeWQNGWf+mv+ozu1ZBTuWn88l
354 qwiO5RSJZwysp3nb5MiJYh6vDAoQznIDDQrSEtUuEcOzypPxJh2EYO3kWMGLY5U6
355 Lm3OPUs7ZHhu1qytMRUISSS2eWucc4C72NJV3MhJ1T/pjQF0DuRsc5aDJoVm/bLw
356 vFCYlGkCgYEAgBDIIqdo1th1HE95SQfpP2wV/jA6CPamIciNwS3bpyhDBqs9oLUc
357 qzXidOpXAVYg1wl/BqpaCQcmmhCrnSLJYdOMpudVyLCCfYmBJ0bs2DCAe5ibGbL7
358 VruAOjS4yBepkXJU9xwKHxDmgTo/oQ5smq7SNOUWDSElVI/CyZ0x7qA=
359 -----END RSA PRIVATE KEY-----
360 )pkey"};
361  return key;
362  }
363 
364  static
365  std::string const&
366  ca_cert()
367  {
368  static std::string const cert {R"cert(
369 -----BEGIN CERTIFICATE-----
370 MIIDQjCCAioCCQDxKQafEvp+VTANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJV
371 UzELMAkGA1UECAwCQ0ExFDASBgNVBAcMC0xvcyBBbmdlbGVzMRswGQYDVQQKDBJy
372 aXBwbGVkLXVuaXQtdGVzdHMxFDASBgNVBAMMC2V4YW1wbGUuY29tMB4XDTE5MDgw
373 NzE3MzM1OFoXDTQ2MTIyMzE3MzM1OFowYzELMAkGA1UEBhMCVVMxCzAJBgNVBAgM
374 AkNBMRQwEgYDVQQHDAtMb3MgQW5nZWxlczEbMBkGA1UECgwScmlwcGxlZC11bml0
375 LXRlc3RzMRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD
376 ggEPADCCAQoCggEBAO9oqh72ttM7hjPnbMcJw0EuyULocEn2hlg4HE4YtzaxlRIz
377 dHm8nMkG/9yGmHBCuue/Gzssm/CzlduGezae01p8eaFUuEJsjxdrXe89Wk2QH+dm
378 Fn+SRbGcHaaTV/cyJrvusG7pOu95HL2eebuwiZ+tX5JP01R732iQt8Beeygh/W4P
379 n2f//fAxbdAIWzx2DH6cmSNe6lpoQe/MN15o8V3whutcC3fkis6wcA7BKZcdVdL2
380 daFWA6mt4SPWldOfWQVAIX4vRvheWPy34OLCgx+wZWg691Lwd1F+paarKombatUt
381 vKMTeolFYl3zkZZMYvR0Oyrt5NXUhRfmG7xR3bkCAwEAATANBgkqhkiG9w0BAQsF
382 AAOCAQEAggKO5WdtU67QPcAdo1Uar0SFouvVLwxJvoKlQ5rqF3idd0HnFVy7iojW
383 G2sZq7z8SNDMkUXZLbcbYNRyrZI0PdjfI0kyNpaa3pEcPcR8aOcTEOtW6V67FrPG
384 8aNYpr6a8PPq12aHzPSNjlUGot/qffGIQ0H2OqdWMOUXMMFnmH2KnnWi46Aq3gaF
385 uyHGrEczjJAK7NTzP8A7fbrmT00Sn6ft1FriQyhvDkUgPXBGWKpOFO84V27oo0ZL
386 xXQHDWcpX+8yNKynjafkXLx6qXwcySF2bKcTIRsxlN6WNRqZ+wqpNStkjuoFkYR/
387 IfW9PBfO/gCtNJQ+lqpoTd3kLBCAng==
388 -----END CERTIFICATE-----
389 )cert"};
390  return cert;
391  }
392 
393  static
394  std::string const&
395  dh()
396  {
397  static std::string const dh {R"dh(
398 -----BEGIN DH PARAMETERS-----
399 MIIBCAKCAQEAnJaaKu3U2a7ZVBvIC+NVNHXo9q6hNCazze+4pwXAKBVXH0ozInEw
400 WKozYxVJLW7dvDHdjdFOSuTLQDqaPW9zVMQKM0BKu81+JyfJi7C3HYKUw7ECVHp4
401 DLvhDe6N5eBj/t1FUwcfS2VNIx4QcJiw6FH3CwNNee1fIi5VTRJp2GLUuMCHkT/I
402 FTODJ+Anw12cJqLdgQfV74UV/Y7JCQl3/DOIy+2YkmX8vWVHX1h6EI5Gw4a3jgqF
403 gVyCOWoVCfgu37H5e7ERyoAxigiP8hMqoGpmJUYJghVKWoFgNUqXw+guVJ56eIuH
404 0wVs/LXflOZ42PJAiwv4LTNOtpG2pWGjOwIBAg==
405 -----END DH PARAMETERS-----
406 )dh"};
407  return dh;
408  }
409 
410 
411 private:
412  struct lambda
413  {
414  int id;
417  boost::asio::executor_work_guard<boost::asio::executor> work;
418  bool ssl;
419 
420  lambda(
421  int id_,
422  TrustedPublisherServer& self_,
423  socket_type&& sock_,
424  bool ssl_)
425  : id(id_)
426  , self(self_)
427  , sock(std::move(sock_))
428  , work(sock_.get_executor())
429  , ssl(ssl_)
430  {
431  }
432 
433  void
434  operator()()
435  {
436  self.do_peer(id, std::move(sock), ssl);
437  }
438  };
439 
440  void
442  {
443  // ec must be checked before `acceptor_` or the member variable may be
444  // accessed after the destructor has completed
445  if (ec || !acceptor_.is_open())
446  return;
447 
448  static int id_ = 0;
449  std::thread{lambda{++id_, *this, std::move(sock_), useSSL_}}.detach();
450  acceptor_.async_accept(
451  sock_,
452  std::bind(
453  &TrustedPublisherServer::on_accept, this, std::placeholders::_1));
454  }
455 
456  void
457  do_peer(int id, socket_type&& s, bool ssl)
458  {
459  using namespace boost::beast;
460  using namespace boost::asio;
461  socket_type sock(std::move(s));
462  flat_buffer sb;
463  error_code ec;
464  boost::optional<ssl_stream<ip::tcp::socket&>> ssl_stream;
465 
466  if (ssl)
467  {
468  // Construct the stream around the socket
469  ssl_stream.emplace(sock, sslCtx_);
470  // Perform the SSL handshake
471  ssl_stream->handshake(ssl::stream_base::server, ec);
472  if(ec)
473  return;
474  }
475 
476  for (;;)
477  {
478  resp_type res;
479  req_type req;
480  try
481  {
482  if (ssl)
483  http::read(*ssl_stream, sb, req, ec);
484  else
485  http::read(sock, sb, req, ec);
486 
487  if (ec)
488  break;
489 
490  auto path = req.target().to_string();
491  res.insert("Server", "TrustedPublisherServer");
492  res.version(req.version());
493  res.keep_alive(req.keep_alive());
494  bool prepare = true;
495 
496  if (boost::starts_with(path, "/validators"))
497  {
498  res.result(http::status::ok);
499  res.insert("Content-Type", "application/json");
500  if (path == "/validators/bad")
501  res.body() = "{ 'bad': \"1']" ;
502  else if (path == "/validators/missing")
503  res.body() = "{\"version\": 1}";
504  else
505  {
506  int refresh = 5;
507  if (boost::starts_with(path, "/validators/refresh"))
508  refresh =
509  boost::lexical_cast<unsigned int>(
510  path.substr(20));
511  res.body() = getList_(refresh);
512  }
513  }
514  else if (boost::starts_with(path, "/textfile"))
515  {
516  prepare = false;
517  res.result(http::status::ok);
518  res.insert("Content-Type", "text/example");
519  // if huge was requested, lie about content length
520  std::uint64_t cl =
521  boost::starts_with(path, "/textfile/huge") ?
523  1024;
524  res.content_length(cl);
525  if (req.method() == http::verb::get)
526  {
527  std::stringstream body;
528  for (auto i=0; i<1024; ++i)
529  body << static_cast<char>(rand_int<short>(32, 126)),
530  res.body() = body.str();
531  }
532  }
533  else if (boost::starts_with(path, "/sleep/"))
534  {
535  auto const sleep_sec =
536  boost::lexical_cast<unsigned int>(path.substr(7));
538  std::chrono::seconds{sleep_sec});
539  }
540  else if (boost::starts_with(path, "/redirect"))
541  {
542  if (boost::ends_with(path, "/301"))
543  res.result(http::status::moved_permanently);
544  else if (boost::ends_with(path, "/302"))
545  res.result(http::status::found);
546  else if (boost::ends_with(path, "/307"))
547  res.result(http::status::temporary_redirect);
548  else if (boost::ends_with(path, "/308"))
549  res.result(http::status::permanent_redirect);
550 
551  std::stringstream location;
552  if (boost::starts_with(path, "/redirect_to/"))
553  {
554  location << path.substr(13);
555  }
556  else if (! boost::starts_with(path, "/redirect_nolo"))
557  {
558  location << (ssl ? "https://" : "http://") <<
559  local_endpoint() <<
560  (boost::starts_with(path, "/redirect_forever/") ?
561  path : "/validators");
562  }
563  if (! location.str().empty())
564  res.insert("Location", location.str());
565  }
566  else
567  {
568  // unknown request
569  res.result(boost::beast::http::status::not_found);
570  res.insert("Content-Type", "text/html");
571  res.body() = "The file '" + path + "' was not found";
572  }
573 
574  if (prepare)
575  res.prepare_payload();
576  }
577  catch (std::exception const& e)
578  {
579  res = {};
580  res.result(boost::beast::http::status::internal_server_error);
581  res.version(req.version());
582  res.insert("Server", "TrustedPublisherServer");
583  res.insert("Content-Type", "text/html");
584  res.body() = std::string{"An internal error occurred"} + e.what();
585  res.prepare_payload();
586  }
587 
588  if (ssl)
589  write(*ssl_stream, res, ec);
590  else
591  write(sock, res, ec);
592 
593  if (ec || req.need_eof())
594  break;
595  }
596 
597  // Perform the SSL shutdown
598  if (ssl)
599  ssl_stream->shutdown(ec);
600  }
601 };
602 
603 } // namespace test
604 } // namespace ripple
605 #endif
ripple::test::TrustedPublisherServer::publisherPublic
PublicKey const & publisherPublic() const
Definition: TrustedPublisherServer.h:232
ripple::test::TrustedPublisherServer::lambda::sock
socket_type sock
Definition: TrustedPublisherServer.h:336
ripple::test::TrustedPublisherServer::lambda::lambda
lambda(int id_, TrustedPublisherServer &self_, socket_type &&sock_, bool ssl_)
Definition: TrustedPublisherServer.h:340
std::this_thread::sleep_for
T sleep_for(T... args)
ripple::makeSlice
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:199
std::bind
T bind(T... args)
std::string
STL class.
std::exception
STL class.
ripple::sfGeneric
const SField sfGeneric(access, 0)
Definition: SField.h:317
ripple::publicKeyType
boost::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:207
ripple::test::TrustedPublisherServer::getList_
std::function< std::string(int)> getList_
Definition: TrustedPublisherServer.h:55
ripple::test::TrustedPublisherServer::Validator::manifest
std::string manifest
Definition: TrustedPublisherServer.h:98
ripple::test::TrustedPublisherServer::resp_type
boost::beast::http::response< boost::beast::http::string_body > resp_type
Definition: TrustedPublisherServer.h:49
ripple::test::TrustedPublisherServer::local_endpoint
endpoint_type local_endpoint() const
Definition: TrustedPublisherServer.h:226
ripple::test::TrustedPublisherServer::publisherSecret_
SecretKey publisherSecret_
Definition: TrustedPublisherServer.h:61
ripple::HashPrefix::manifest
@ manifest
Manifest.
ripple::sfSigningPubKey
const SF_Blob sfSigningPubKey(access, STI_VL, 3, "SigningPubKey")
Definition: SField.h:442
std::vector
STL class.
ripple::sfSequence
const SF_U32 sfSequence(access, STI_UINT32, 4, "Sequence")
Definition: SField.h:340
ripple::base64_encode
std::string base64_encode(std::uint8_t const *data, std::size_t len)
Definition: base64.cpp:227
std::chrono::seconds
ripple::sfMasterSignature
const SF_Blob sfMasterSignature(access, STI_VL, 18, "MasterSignature", SField::sMD_Default, SField::notSigning)
Definition: SField.h:457
ripple::test::TrustedPublisherServer::sslCtx_
boost::asio::ssl::context sslCtx_
Definition: TrustedPublisherServer.h:59
std::stringstream
STL class.
ripple::test::TrustedPublisherServer::useSSL_
bool useSSL_
Definition: TrustedPublisherServer.h:58
std::function
ripple::test::TrustedPublisherServer::on_accept
void on_accept(error_code ec)
Definition: TrustedPublisherServer.h:361
ripple::test::TrustedPublisherServer::lambda::self
TrustedPublisherServer & self
Definition: TrustedPublisherServer.h:335
ripple::test::TrustedPublisherServer::ca_cert
static std::string const & ca_cert()
Definition: TrustedPublisherServer.h:316
ripple::NodeStore::write
void write(nudb::detail::ostream &os, std::size_t t)
Definition: varint.h:145
ripple::test::TrustedPublisherServer::key
static std::string const & key()
Definition: TrustedPublisherServer.h:308
ripple::test::TrustedPublisherServer::req_type
boost::beast::http::request< boost::beast::http::string_body > req_type
Definition: TrustedPublisherServer.h:48
ripple::test::TrustedPublisherServer::ep_
endpoint_type ep_
Definition: TrustedPublisherServer.h:53
ripple::Serializer::data
void const * data() const noexcept
Definition: Serializer.h:79
ripple::test::TrustedPublisherServer::lambda::ssl
bool ssl
Definition: TrustedPublisherServer.h:338
ripple::test::TrustedPublisherServer::sock_
socket_type sock_
Definition: TrustedPublisherServer.h:52
ripple::KeyType::ed25519
@ ed25519
ripple::test::jtx::expiration
Set Expiration on a JTx.
Definition: Check_test.cpp:29
ripple::test::TrustedPublisherServer::cert
static std::string const & cert()
Definition: TrustedPublisherServer.h:300
ripple::test::getEnvLocalhostAddr
const char * getEnvLocalhostAddr()
Definition: envconfig.h:32
ripple::test::TrustedPublisherServer::makeManifestString
static std::string makeManifestString(PublicKey const &pk, SecretKey const &sk, PublicKey const &spk, SecretKey const &ssk, int seq)
Definition: TrustedPublisherServer.h:103
thread
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
ripple::derivePublicKey
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
Definition: SecretKey.cpp:228
ripple::test::TrustedPublisherServer::Validator
Definition: TrustedPublisherServer.h:94
ripple::test::TrustedPublisherServer::start
void start()
Definition: TrustedPublisherServer.h:198
std::to_string
T to_string(T... args)
boost::asio
Definition: Overlay.h:42
ripple::test::TrustedPublisherServer::stop
void stop()
Definition: TrustedPublisherServer.h:212
std::chrono::time_point
ripple::test::TrustedPublisherServer
Definition: TrustedPublisherServer.h:42
std::uint64_t
ripple::SecretKey
A secret key.
Definition: SecretKey.h:36
ripple::test::TrustedPublisherServer::socket_type
boost::asio::ip::tcp::socket socket_type
Definition: TrustedPublisherServer.h:46
ripple::test::TrustedPublisherServer::lambda::id
int id
Definition: TrustedPublisherServer.h:334
ripple::test::TrustedPublisherServer::randomValidator
static Validator randomValidator()
Definition: TrustedPublisherServer.h:128
ripple::test::TrustedPublisherServer::address_type
boost::asio::ip::address address_type
Definition: TrustedPublisherServer.h:45
ripple::test::TrustedPublisherServer::load_server_certificate
void load_server_certificate()
Definition: TrustedPublisherServer.h:68
ripple::KeyType::secp256k1
@ secp256k1
ripple::Serializer
Definition: Serializer.h:43
ripple::randomKeyPair
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
Definition: SecretKey.cpp:286
ripple::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:32
ripple::STObject
Definition: STObject.h:51
ripple::sfPublicKey
const SF_Blob sfPublicKey(access, STI_VL, 1, "PublicKey")
Definition: SField.h:440
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::TrustedPublisherServer::lambda::work
boost::asio::executor_work_guard< boost::asio::executor > work
Definition: TrustedPublisherServer.h:337
ripple::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:73
ripple::STObject::add
virtual void add(Serializer &s) const override
Definition: STObject.h:343
ripple::test::TrustedPublisherServer::TrustedPublisherServer
TrustedPublisherServer(boost::asio::io_context &ioc, std::vector< Validator > const &validators, NetClock::time_point expiration, bool useSSL=false, int version=1, bool immediateStart=true, int sequence=1)
Definition: TrustedPublisherServer.h:138
ripple::sign
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &m)
Generate a signature for a message.
Definition: SecretKey.cpp:132
ripple::test::TrustedPublisherServer::Validator::masterPublic
PublicKey masterPublic
Definition: TrustedPublisherServer.h:96
std
STL namespace.
ripple::test::TrustedPublisherServer::Validator::signingPublic
PublicKey signingPublic
Definition: TrustedPublisherServer.h:97
ripple::test::TrustedPublisherServer::dh
static std::string const & dh()
Definition: TrustedPublisherServer.h:324
ripple::test::TrustedPublisherServer::endpoint_type
boost::asio::ip::tcp::endpoint endpoint_type
Definition: TrustedPublisherServer.h:44
ripple::test::TrustedPublisherServer::lambda::operator()
void operator()()
Definition: TrustedPublisherServer.h:354
std::stringstream::str
T str(T... args)
std::size_t
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:70
std::numeric_limits::max
T max(T... args)
ripple::test::TrustedPublisherServer::error_code
boost::system::error_code error_code
Definition: TrustedPublisherServer.h:50
ripple::test::TrustedPublisherServer::acceptor_
boost::asio::ip::tcp::acceptor acceptor_
Definition: TrustedPublisherServer.h:54
std::data
T data(T... args)
std::exception::what
T what(T... args)
ripple::randomSecretKey
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
Definition: SecretKey.cpp:184
ripple::test::TrustedPublisherServer::do_peer
void do_peer(int id, socket_type &&s, bool ssl)
Definition: TrustedPublisherServer.h:377
ripple::test::TrustedPublisherServer::publisherPublic_
PublicKey publisherPublic_
Definition: TrustedPublisherServer.h:62
ripple::test::TrustedPublisherServer::~TrustedPublisherServer
~TrustedPublisherServer()
Definition: TrustedPublisherServer.h:220