]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/example/cpp03/ssl/client.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / asio / example / cpp03 / ssl / client.cpp
1 //
2 // client.cpp
3 // ~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #include <cstdlib>
12 #include <iostream>
13 #include <boost/bind.hpp>
14 #include <boost/asio.hpp>
15 #include <boost/asio/ssl.hpp>
16
17 enum { max_length = 1024 };
18
19 class client
20 {
21 public:
22 client(boost::asio::io_context& io_context,
23 boost::asio::ssl::context& context,
24 boost::asio::ip::tcp::resolver::results_type endpoints)
25 : socket_(io_context, context)
26 {
27 socket_.set_verify_mode(boost::asio::ssl::verify_peer);
28 socket_.set_verify_callback(
29 boost::bind(&client::verify_certificate, this, _1, _2));
30
31 boost::asio::async_connect(socket_.lowest_layer(), endpoints,
32 boost::bind(&client::handle_connect, this,
33 boost::asio::placeholders::error));
34 }
35
36 bool verify_certificate(bool preverified,
37 boost::asio::ssl::verify_context& ctx)
38 {
39 // The verify callback can be used to check whether the certificate that is
40 // being presented is valid for the peer. For example, RFC 2818 describes
41 // the steps involved in doing this for HTTPS. Consult the OpenSSL
42 // documentation for more details. Note that the callback is called once
43 // for each certificate in the certificate chain, starting from the root
44 // certificate authority.
45
46 // In this example we will simply print the certificate's subject name.
47 char subject_name[256];
48 X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
49 X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
50 std::cout << "Verifying " << subject_name << "\n";
51
52 return preverified;
53 }
54
55 void handle_connect(const boost::system::error_code& error)
56 {
57 if (!error)
58 {
59 socket_.async_handshake(boost::asio::ssl::stream_base::client,
60 boost::bind(&client::handle_handshake, this,
61 boost::asio::placeholders::error));
62 }
63 else
64 {
65 std::cout << "Connect failed: " << error.message() << "\n";
66 }
67 }
68
69 void handle_handshake(const boost::system::error_code& error)
70 {
71 if (!error)
72 {
73 std::cout << "Enter message: ";
74 std::cin.getline(request_, max_length);
75 size_t request_length = strlen(request_);
76
77 boost::asio::async_write(socket_,
78 boost::asio::buffer(request_, request_length),
79 boost::bind(&client::handle_write, this,
80 boost::asio::placeholders::error,
81 boost::asio::placeholders::bytes_transferred));
82 }
83 else
84 {
85 std::cout << "Handshake failed: " << error.message() << "\n";
86 }
87 }
88
89 void handle_write(const boost::system::error_code& error,
90 size_t bytes_transferred)
91 {
92 if (!error)
93 {
94 boost::asio::async_read(socket_,
95 boost::asio::buffer(reply_, bytes_transferred),
96 boost::bind(&client::handle_read, this,
97 boost::asio::placeholders::error,
98 boost::asio::placeholders::bytes_transferred));
99 }
100 else
101 {
102 std::cout << "Write failed: " << error.message() << "\n";
103 }
104 }
105
106 void handle_read(const boost::system::error_code& error,
107 size_t bytes_transferred)
108 {
109 if (!error)
110 {
111 std::cout << "Reply: ";
112 std::cout.write(reply_, bytes_transferred);
113 std::cout << "\n";
114 }
115 else
116 {
117 std::cout << "Read failed: " << error.message() << "\n";
118 }
119 }
120
121 private:
122 boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
123 char request_[max_length];
124 char reply_[max_length];
125 };
126
127 int main(int argc, char* argv[])
128 {
129 try
130 {
131 if (argc != 3)
132 {
133 std::cerr << "Usage: client <host> <port>\n";
134 return 1;
135 }
136
137 boost::asio::io_context io_context;
138
139 boost::asio::ip::tcp::resolver resolver(io_context);
140 boost::asio::ip::tcp::resolver::results_type endpoints =
141 resolver.resolve(argv[1], argv[2]);
142
143 boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
144 ctx.load_verify_file("ca.pem");
145
146 client c(io_context, ctx, endpoints);
147
148 io_context.run();
149 }
150 catch (std::exception& e)
151 {
152 std::cerr << "Exception: " << e.what() << "\n";
153 }
154
155 return 0;
156 }