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