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