30 #ifndef MONERO_TRANSPORT_H
31 #define MONERO_TRANSPORT_H
34 #include <boost/asio.hpp>
35 #include <boost/asio/deadline_timer.hpp>
36 #include <boost/array.hpp>
37 #include <boost/utility/string_ref.hpp>
40 #include <type_traits>
41 #include "net/http_client.h"
43 #include "rapidjson/document.h"
44 #include "rapidjson/writer.h"
45 #include "rapidjson/stringbuffer.h"
51 #include "messages/messages.pb.h"
52 #include "messages/messages-common.pb.h"
53 #include "messages/messages-management.pb.h"
54 #include "messages/messages-monero.pb.h"
59 using json = rapidjson::Document;
61 namespace http = epee::net_utils::http;
65 uint64_t
pack_version(uint32_t major, uint32_t minor=0, uint32_t patch=0);
68 bool t_serialize(
const std::string & in, std::string & out);
69 bool t_serialize(
const epee::wipeable_string & in, std::string & out);
73 bool t_deserialize(
const std::string & in, std::string & out);
74 bool t_deserialize(std::string & in, epee::wipeable_string & out);
78 template<
class t_req,
class t_res,
class t_transport>
79 bool invoke_bridge_http(
const boost::string_ref uri,
const t_req & out_struct, t_res & result_struct, t_transport&
transport,
const boost::string_ref method =
"POST", std::chrono::milliseconds timeout = std::chrono::seconds(180))
81 std::string req_param;
84 http::fields_list additional_params;
85 additional_params.push_back(std::make_pair(
"Origin",
"https://monero.trezor.io"));
86 additional_params.push_back(std::make_pair(
"Content-Type",
"application/json; charset=utf-8"));
88 const http::http_response_info* pri =
nullptr;
89 const auto data_cleaner = epee::misc_utils::create_scope_leave_handler([&]() {
90 if (!req_param.empty()) {
91 memwipe(&req_param[0], req_param.size());
96 if(!
transport.invoke(uri, method, req_param, timeout, &pri, std::move(additional_params)))
98 MERROR(
"Failed to invoke http request to " << uri);
104 MERROR(
"Failed to invoke http request to " << uri <<
", internal error (null response ptr)");
108 if(pri->m_response_code != 200)
110 MERROR(
"Failed to invoke http request to " << uri <<
", wrong response code: " << pri->m_response_code
111 <<
" Response Body: " << pri->m_body);
115 return t_deserialize(
const_cast<http::http_response_info*
>(pri)->m_body, result_struct);
130 virtual void read(
Transport &
transport, std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr)= 0;
139 void read(
Transport &
transport, std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr)
override;
151 virtual bool ping() {
return false; };
152 virtual std::string
get_path()
const {
return ""; };
156 virtual void write(
const google::protobuf::Message & req) =0;
157 virtual void read(std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr) =0;
158 virtual std::shared_ptr<Transport>
find_debug() {
return nullptr; };
161 virtual size_t read_chunk(
void * buff,
size_t size) {
return 0; };
162 virtual std::ostream&
dump(std::ostream& o)
const {
return o <<
"Transport<>"; }
174 boost::optional<std::string> device_path = boost::none,
175 boost::optional<std::string> bridge_host = boost::none);
181 std::string
get_path()
const override;
184 void open()
override;
185 void close()
override;
187 void write(
const google::protobuf::Message &req)
override;
188 void read(std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr)
override;
191 std::ostream&
dump(std::ostream& o)
const override;
203 using boost::asio::ip::udp;
209 boost::optional<std::string> device_path=boost::none,
210 boost::optional<std::shared_ptr<Protocol>> proto=boost::none);
218 bool ping()
override;
219 std::string
get_path()
const override;
222 void open()
override;
223 void close()
override;
224 std::shared_ptr<Transport>
find_debug()
override;
226 void write(
const google::protobuf::Message &req)
override;
227 void read(std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr)
override;
229 void write_chunk(
const void * buff,
size_t size)
override;
230 size_t read_chunk(
void * buff,
size_t size)
override;
232 std::ostream&
dump(std::ostream& o)
const override;
236 ssize_t
receive(
void * buff,
size_t size, boost::system::error_code * error_code=
nullptr,
bool no_throw=
false, boost::posix_time::time_duration timeout=boost::posix_time::seconds(10));
238 static void handle_receive(
const boost::system::error_code& ec, std::size_t length,
239 boost::system::error_code* out_ec, std::size_t* out_length);
240 bool ping_int(boost::posix_time::time_duration timeout=boost::posix_time::milliseconds(1500));
252 #ifdef WITH_DEVICE_TREZOR_WEBUSB
255 class WebUsbTransport :
public Transport {
258 explicit WebUsbTransport(
259 boost::optional<libusb_device_descriptor*> descriptor = boost::none,
260 boost::optional<std::shared_ptr<Protocol>> proto = boost::none
263 virtual ~WebUsbTransport();
265 static const char * PATH_PREFIX;
267 std::string get_path()
const override;
270 void open()
override;
271 void close()
override;
272 std::shared_ptr<Transport> find_debug()
override;
274 void write(
const google::protobuf::Message &req)
override;
275 void read(std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr)
override;
277 void write_chunk(
const void * buff,
size_t size)
override;
278 size_t read_chunk(
void * buff,
size_t size)
override;
280 std::ostream& dump(std::ostream& o)
const override;
283 void require_device()
const;
284 void require_connected()
const;
285 int get_interface()
const;
286 unsigned char get_endpoint()
const;
288 std::shared_ptr<Protocol> m_proto;
290 libusb_context *m_usb_session;
291 libusb_device *m_usb_device;
292 libusb_device_handle *m_usb_device_handle;
293 std::unique_ptr<libusb_device_descriptor> m_usb_device_desc;
294 std::vector<uint8_t> m_port_numbers;
298 #ifdef WITH_TREZOR_DEBUGGING
322 std::shared_ptr<Transport>
transport(
const std::string & path);
327 template<
class t_transport=Transport>
334 return std::dynamic_pointer_cast<t_transport>(t);
342 std::shared_ptr<google::protobuf::Message>
recvMsg;
348 const std::shared_ptr<google::protobuf::Message> &
recvMsg)
350 reason = std::string(
"Trezor returned unexpected message: ") + std::to_string(
recvType);
369 hw::trezor::messages::MessageType
m_type;
370 std::shared_ptr<google::protobuf::Message>
m_msg;
380 template<
class t_message=google::protobuf::Message>
381 std::shared_ptr<t_message>
383 boost::optional<messages::MessageType> resp_type = boost::none)
386 BOOST_STATIC_ASSERT(boost::is_base_of<google::protobuf::Message, t_message>::value);
392 std::shared_ptr<google::protobuf::Message> msg_resp;
393 hw::trezor::messages::MessageType msg_resp_type;
394 transport.read(msg_resp, &msg_resp_type);
397 messages::MessageType required_type = resp_type ? resp_type.get() : MessageMapper::get_message_wire_number<t_message>();
399 if (msg_resp_type == required_type) {
400 return message_ptr_retype<t_message>(msg_resp);
401 }
else if (msg_resp_type == messages::MessageType_Failure){
409 std::ostream&
operator<<(std::ostream& o, std::shared_ptr<hw::trezor::Transport>
const& t);
static void close()
Definition: blockchain_blackball.cpp:281
static void open(MDB_env *&env, const boost::filesystem::path &path, uint64_t db_flags, bool readonly)
Definition: blockchain_prune.cpp:63
Definition: transport.hpp:171
std::string m_bridge_host
Definition: transport.hpp:195
virtual ~BridgeTransport()=default
static const char * PATH_PREFIX
Definition: transport.hpp:179
void close() override
Definition: transport.cpp:422
void write(const google::protobuf::Message &req) override
Definition: transport.cpp:443
BridgeTransport(boost::optional< std::string > device_path=boost::none, boost::optional< std::string > bridge_host=boost::none)
Definition: transport.cpp:333
boost::optional< std::string > m_session
Definition: transport.hpp:197
const boost::optional< json > & device_info() const
Definition: transport.cpp:495
boost::optional< json > m_device_info
Definition: transport.hpp:199
boost::optional< std::string > m_device_path
Definition: transport.hpp:196
std::string get_path() const override
Definition: transport.cpp:356
boost::optional< epee::wipeable_string > m_response
Definition: transport.hpp:198
void enumerate(t_transport_vect &res) override
Definition: transport.cpp:365
void read(std::shared_ptr< google::protobuf::Message > &msg, messages::MessageType *msg_type=nullptr) override
Definition: transport.cpp:467
std::ostream & dump(std::ostream &o) const override
Definition: transport.cpp:499
epee::net_utils::http::http_simple_client m_http_client
Definition: transport.hpp:194
void open() override
Definition: transport.cpp:401
Definition: transport.hpp:363
bool m_empty
Definition: transport.hpp:371
std::shared_ptr< google::protobuf::Message > m_msg
Definition: transport.hpp:370
GenericMessage()
Definition: transport.hpp:365
bool empty() const
Definition: transport.hpp:367
GenericMessage(messages::MessageType m_type, const std::shared_ptr< google::protobuf::Message > &m_msg)
hw::trezor::messages::MessageType m_type
Definition: transport.hpp:369
Definition: transport.hpp:133
void write(Transport &transport, const google::protobuf::Message &req) override
Definition: transport.cpp:202
void read(Transport &transport, std::shared_ptr< google::protobuf::Message > &msg, messages::MessageType *msg_type=nullptr) override
Definition: transport.cpp:239
virtual ~ProtocolV1()=default
Definition: transport.hpp:123
virtual void session_end(Transport &transport)
Definition: transport.hpp:128
virtual void session_begin(Transport &transport)
Definition: transport.hpp:127
virtual ~Protocol()=default
virtual void read(Transport &transport, std::shared_ptr< google::protobuf::Message > &msg, messages::MessageType *msg_type=nullptr)=0
virtual void write(Transport &transport, const google::protobuf::Message &req)=0
Definition: transport.hpp:146
virtual std::shared_ptr< Transport > find_debug()
Definition: transport.hpp:158
virtual void close()
Definition: transport.hpp:155
virtual void enumerate(t_transport_vect &res)
Definition: transport.hpp:153
virtual void read(std::shared_ptr< google::protobuf::Message > &msg, messages::MessageType *msg_type=nullptr)=0
Transport()
Definition: transport.cpp:293
virtual void write_chunk(const void *buff, size_t size)
Definition: transport.hpp:160
virtual size_t read_chunk(void *buff, size_t size)
Definition: transport.hpp:161
virtual std::ostream & dump(std::ostream &o) const
Definition: transport.hpp:162
virtual bool pre_open()
Definition: transport.cpp:297
virtual std::string get_path() const
Definition: transport.hpp:152
virtual bool pre_close()
Definition: transport.cpp:313
virtual void open()
Definition: transport.hpp:154
virtual bool ping()
Definition: transport.hpp:151
virtual void write(const google::protobuf::Message &req)=0
long m_open_counter
Definition: transport.hpp:164
virtual ~Transport()=default
Definition: transport.hpp:205
int m_device_port
Definition: transport.hpp:244
boost::asio::io_service m_io_service
Definition: transport.hpp:247
bool ping() override
Definition: transport.cpp:565
void write(const google::protobuf::Message &req) override
Definition: transport.cpp:744
std::shared_ptr< Protocol > m_proto
Definition: transport.hpp:242
udp::endpoint m_endpoint
Definition: transport.hpp:249
static const char * PATH_PREFIX
Definition: transport.hpp:214
void enumerate(t_transport_vect &res) override
Definition: transport.cpp:585
std::ostream & dump(std::ostream &o) const override
Definition: transport.cpp:785
void check_deadline()
Definition: transport.cpp:752
void open() override
Definition: transport.cpp:601
void write_chunk(const void *buff, size_t size) override
Definition: transport.cpp:648
static const char * DEFAULT_HOST
Definition: transport.hpp:215
size_t read_chunk(void *buff, size_t size) override
Definition: transport.cpp:661
void require_socket()
Definition: transport.cpp:559
bool ping_int(boost::posix_time::time_duration timeout=boost::posix_time::milliseconds(1500))
Definition: transport.cpp:569
void close() override
Definition: transport.cpp:620
virtual ~UdpTransport()=default
std::string m_device_host
Definition: transport.hpp:243
std::unique_ptr< udp::socket > m_socket
Definition: transport.hpp:246
static const int DEFAULT_PORT
Definition: transport.hpp:216
ssize_t receive(void *buff, size_t size, boost::system::error_code *error_code=nullptr, bool no_throw=false, boost::posix_time::time_duration timeout=boost::posix_time::seconds(10))
Definition: transport.cpp:695
std::string get_path() const override
Definition: transport.cpp:554
UdpTransport(boost::optional< std::string > device_path=boost::none, boost::optional< std::shared_ptr< Protocol >> proto=boost::none)
Definition: transport.cpp:529
std::shared_ptr< Transport > find_debug() override
Definition: transport.cpp:635
boost::asio::deadline_timer m_deadline
Definition: transport.hpp:248
static void handle_receive(const boost::system::error_code &ec, std::size_t length, boost::system::error_code *out_ec, std::size_t *out_length)
Definition: transport.cpp:779
void read(std::shared_ptr< google::protobuf::Message > &msg, messages::MessageType *msg_type=nullptr) override
Definition: transport.cpp:748
Definition: exceptions.hpp:115
ProtocolException()
Definition: exceptions.hpp:118
boost::optional< std::string > reason
Definition: exceptions.hpp:62
Definition: transport.hpp:339
UnexpectedMessageException()
Definition: transport.hpp:346
hw::trezor::messages::MessageType recvType
Definition: transport.hpp:341
std::shared_ptr< google::protobuf::Message > recvMsg
Definition: transport.hpp:342
UnexpectedMessageException(hw::trezor::messages::MessageType recvType, const std::shared_ptr< google::protobuf::Message > &recvMsg)
Definition: transport.hpp:347
void sort_transports_by_env(t_transport_vect &res)
Definition: transport.cpp:1190
std::shared_ptr< t_message > exchange_message(Transport &transport, const google::protobuf::Message &req, boost::optional< messages::MessageType > resp_type=boost::none)
Definition: transport.hpp:382
std::ostream & operator<<(std::ostream &o, hw::trezor::Transport const &t)
Definition: transport.cpp:1270
rapidjson::Document json
Definition: transport.hpp:59
void throw_failure_exception(const messages::common::Failure *failure)
Definition: transport.cpp:1236
bool t_serialize(const std::string &in, std::string &out)
Definition: transport.cpp:55
bool t_deserialize(const std::string &in, std::string &out)
Definition: transport.cpp:79
const std::string DEFAULT_BRIDGE
Definition: transport.hpp:63
rapidjson::Value json_val
Definition: transport.hpp:60
std::shared_ptr< Transport > transport(const std::string &path)
Definition: transport.cpp:1223
uint64_t pack_version(uint32_t major, uint32_t minor, uint32_t patch)
Definition: transport.cpp:100
bool invoke_bridge_http(const boost::string_ref uri, const t_req &out_struct, t_res &result_struct, t_transport &transport, const boost::string_ref method="POST", std::chrono::milliseconds timeout=std::chrono::seconds(180))
Definition: transport.hpp:79
std::shared_ptr< t_transport > transport_typed(const std::string &path)
Definition: transport.hpp:328
std::vector< std::shared_ptr< Transport > > t_transport_vect
Definition: transport.hpp:144
void enumerate(t_transport_vect &res)
Definition: transport.cpp:1163
Definition: device.cpp:38
#define true
Definition: stdbool.h:36