diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2015-08-07 15:05:23 +0300 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2015-08-07 15:05:23 +0300 |
commit | 5a4cbe950cd653385fc6e93aa860542b01bdf1bc (patch) | |
tree | 5a97277e5bb479b2d60147bb13f3c28ebc177a9b /client-qt/udm-client-qt/client_session.cpp | |
parent | 1461988ab8387f86d929cbba70bc4839447693f6 (diff) |
protocol:
renamed some vars to avoid collision with openssl
client-qt:
implemented ssl support
some work on connect_widget
Diffstat (limited to 'client-qt/udm-client-qt/client_session.cpp')
-rw-r--r-- | client-qt/udm-client-qt/client_session.cpp | 106 |
1 files changed, 88 insertions, 18 deletions
diff --git a/client-qt/udm-client-qt/client_session.cpp b/client-qt/udm-client-qt/client_session.cpp index c034aa1..d01d0f5 100644 --- a/client-qt/udm-client-qt/client_session.cpp +++ b/client-qt/udm-client-qt/client_session.cpp @@ -22,6 +22,7 @@ #include "client_session.h" #include <boost/bind.hpp> #include <boost/log/trivial.hpp> +#include <openssl/sha.h> std::shared_ptr<char*> pack_data(const std::string &buf, int *size_) { @@ -48,28 +49,86 @@ std::shared_ptr<char*> pack_msg(client_msg *msg, int *size_) } -client_session::client_session(QObject *parent, boost::asio::io_service *io_service) : QObject(parent), io_service_(*io_service), socket_(*io_service) +client_session::client_session(QObject *parent, boost::asio::io_service *io_service) : QObject(parent), io_service_(*io_service) { - + socket_ssl_ = nullptr; + ssl_enabled = false; } tcp::socket& client_session::socket() { - return socket_; + return *socket_; } void client_session::client_connect(QString host, QString password, int port) { //TODO: settings for connection timeout this->pasword = password; + if(!password.isEmpty()) + { + unsigned char hash[64]; + SHA512((unsigned char*)password.toUtf8().data(), password.length(), hash); + password_sha512 = (char*)hash; + } + + + char port_buf[6]; + snprintf(port_buf, 5, "%d", port); boost::asio::ip::tcp::resolver r(io_service_); - boost::asio::ip::tcp::endpoint ep; - ep.port(port); - ep.address(boost::asio::ip::address::from_string(host.toStdString())); - socket_.async_connect(ep, boost::bind(&client_session::handle_connect, this, boost::asio::placeholders::error)); + boost::asio::ip::tcp::resolver::query query(host.toUtf8().data(), port_buf); + boost::asio::ip::tcp::resolver::iterator it = r.resolve(query); + + socket_ = new tcp::socket(io_service_); + + if(!ssl_enabled) + boost::asio::async_connect(*socket_, it, boost::bind(&client_session::handle_connect, this, boost::asio::placeholders::error)); + else + boost::asio::async_connect(socket_ssl_->lowest_layer(), it, boost::bind(&client_session::handle_connect, this, boost::asio::placeholders::error)); +// socket_.async_connect(ep, boost::bind(&client_session::handle_connect, this, boost::asio::placeholders::error)); + io_service_.run(); } +void client_session::client_connect_ssl(QString host, QString password, int port, QString ssl_ca, QString ssl_crt, QString ssl_key) +{ + ssl_enabled = true; + this->pasword = password; + boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12); + ctx.load_verify_file(ssl_ca.toUtf8().data()); + ctx.use_certificate_file(ssl_crt.toUtf8().data(), boost::asio::ssl::context::pem); + ctx.use_private_key_file(ssl_key.toUtf8().data(), boost::asio::ssl::context::pem); + socket_ssl_ = new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(io_service_, ctx); + socket_ssl_->set_verify_mode(boost::asio::ssl::verify_peer); + socket_ssl_->set_verify_callback(boost::bind(&client_session::verify_certificate, this, _1, _2 )); + + char port_buf[6]; + snprintf(port_buf, 5, "%d", port); + boost::asio::ip::tcp::resolver r(io_service_); + boost::asio::ip::tcp::resolver::query query(host.toUtf8().data(), port_buf); + boost::asio::ip::tcp::resolver::iterator it = r.resolve(query); + + boost::asio::async_connect(socket_ssl_->lowest_layer(), it, boost::bind(&client_session::handle_connect, this, boost::asio::placeholders::error)); +} + +bool client_session::verify_certificate(bool preverified, boost::asio::ssl::verify_context& /*&ctx*/) +{ + // The verify callback can be used to check whether the certificate that is + // being presented is valid for the peer. For example, RFC 2818 describes + // the steps involved in doing this for HTTPS. Consult the OpenSSL + // documentation for more details. Note that the callback is called once + // for each certificate in the certificate chain, starting from the root + // certificate authority. + + // In this example we will simply print the certificate's subject name. +/* char subject_name[256]; + X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle()); + X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256); + std::cout << "Verifying " << subject_name << "\n"; */ + + return preverified; +} + + void client_session::handle_connect(const boost::system::error_code &e) { BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<typeid(this).name()<<"::"<<__func__; @@ -85,7 +144,10 @@ void client_session::handle_connect(const boost::system::error_code &e) emit client_connected(true, QString::fromStdString(e.message())); //listen for messages from server recv_data_ = new char[4]; - boost::asio::async_read(socket_, boost::asio::buffer(recv_data_, 4), boost::bind(&client_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + if(!ssl_enabled) + boost::asio::async_read(*socket_, boost::asio::buffer(recv_data_, 4), boost::bind(&client_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + else + boost::asio::async_read(*socket_ssl_, boost::asio::buffer(recv_data_, 4), boost::bind(&client_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } } @@ -99,7 +161,10 @@ void client_session::handle_read(const boost::system::error_code& error, size_t delete [] recv_data_; char *buf = new char[size]; boost::system::error_code ec; - socket_.read_some(boost::asio::buffer(buf, size), ec); + if(!ssl_enabled) + socket_->read_some(boost::asio::buffer(buf, size), ec); + else + socket_ssl_->read_some(boost::asio::buffer(buf, size), ec); if(ec) { @@ -124,7 +189,10 @@ void client_session::handle_read(const boost::system::error_code& error, size_t //check if someone connected to signal and delete message if noone //this will be limited to only one client connection because client will need to delete message manually recv_data_ = new char[4]; - boost::asio::async_read(socket_, boost::asio::buffer(recv_data_, 4), boost::bind(&client_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + if(!ssl_enabled) + boost::asio::async_read(*socket_, boost::asio::buffer(recv_data_, 4), boost::bind(&client_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + else + boost::asio::async_read(*socket_ssl_, boost::asio::buffer(recv_data_, 4), boost::bind(&client_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } // if(!parsed) else @@ -144,7 +212,10 @@ void client_session::send_message(client_msg &msg) { int size = 0; std::shared_ptr<char*> ptr = pack_msg(&msg, &size); - boost::asio::async_write(socket_, boost::asio::buffer(*ptr, size), boost::bind(&client_session::handle_write, this, boost::asio::placeholders::error)); + if(!ssl_enabled) + boost::asio::async_write(*socket_, boost::asio::buffer(*ptr, size), boost::bind(&client_session::handle_write, this, boost::asio::placeholders::error)); + else + boost::asio::async_write(*socket_ssl_, boost::asio::buffer(*ptr, size), boost::bind(&client_session::handle_write, this, boost::asio::placeholders::error)); } void client_session::handle_write(const boost::system::error_code& error) @@ -156,18 +227,17 @@ void client_session::handle_write(const boost::system::error_code& error) } -void client_session::run_io_service() -{ - io_service_.run(); -} - client_session::~client_session() { - //TODO: check this, reimplement + //TODO: correct thread termination, reimplement io_service_.stop(); + if(ssl_enabled) + delete socket_ssl_; + else + delete socket_; boost::asio::io_service *s = &io_service_; delete s; - emit terminate_thread(); + //emit terminate_thread(); } /*boost::asio::io_service &client_session::io_service() |