source: nscp/include/nsca/nsca_socket.hpp @ 9bd40e2

0.4.10.4.2
Last change on this file since 9bd40e2 was 9bd40e2, checked in by Michael Medin <michael@…>, 14 months ago
  • Refactored server internals to be more uniform (This is the first step to adding more protocols like NRDP and unit tests for check_nt)
  • Property mode set to 100644
File size: 3.8 KB
Line 
1#pragma once
2
3#include <boost/shared_ptr.hpp>
4#include <boost/asio.hpp>
5
6#include <socket/socket_helpers.hpp>
7
8#include <nsca/nsca_packet.hpp>
9#include <nsca/nsca_enrypt.hpp>
10
11using boost::asio::ip::tcp;
12
13namespace nsca {
14
15        class socket : public boost::noncopyable {
16        private:
17                boost::shared_ptr<tcp::socket> socket_;
18                boost::asio::io_service &io_service_;
19                nsca_encrypt crypt_inst;
20                int time;
21        public:
22                typedef boost::asio::basic_socket<tcp,boost::asio::stream_socket_service<tcp> >  basic_socket_type;
23
24        public:
25                socket(boost::asio::io_service &io_service) : io_service_(io_service), time(0) {
26                        socket_.reset(new tcp::socket(io_service_));
27                }
28                ~socket() {
29                        if (socket_)
30                                socket_->close();
31                        socket_.reset();
32                }
33
34                virtual void connect(std::string host, std::string port) {
35                        NSC_DEBUG_MSG(_T("Connecting to: ") + utf8::cvt<std::wstring>(host) + _T(" (") + utf8::cvt<std::wstring>(port) + _T(")"));
36                        tcp::resolver resolver(io_service_);
37                        tcp::resolver::query query(host, port);
38
39                        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
40                        tcp::resolver::iterator end;
41
42                        boost::system::error_code error = boost::asio::error::host_not_found;
43                        while (error && endpoint_iterator != end) {
44                                tcp::resolver::endpoint_type ep = *endpoint_iterator;
45                                socket_->close();
46                                socket_->connect(*endpoint_iterator++, error);
47                                NSC_DEBUG_MSG(_T("Connected to: ") + utf8::cvt<std::wstring>(ep.address().to_string()));
48                        }
49                        if (error) {
50                                NSC_DEBUG_MSG(_T("Failed to connect to:") + utf8::to_unicode(host));
51                                throw boost::system::system_error(error);
52                        }
53                }
54
55
56                virtual void shutdown() {
57                        NSC_DEBUG_MSG(_T("Ending socket (gracefully)"));
58                        // Initiate graceful connection closure.
59                        boost::system::error_code ignored_ec;
60                        if (socket_)
61                                socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
62                };
63                virtual void close() {
64                        if (socket_)
65                                socket_->close();
66                        socket_.reset();
67                };
68
69                virtual void send_nsca(const nsca::packet &packet, const boost::posix_time::seconds timeout) {
70                        if (!socket_ || !socket_->is_open()) {
71                                NSC_LOG_ERROR_STD(_T("Socket was closed when trying to send data..."));
72                                return;
73                        }
74                        std::string buffer = crypt_inst.get_rand_buffer(packet.get_packet_length());
75                        packet.get_buffer(buffer, time);
76                        crypt_inst.encrypt_buffer(buffer);
77                        NSC_DEBUG_MSG(_T("Sending data: ") + strEx::itos(buffer.size()));
78                        write_with_timeout(buffer, timeout);
79                }
80                virtual bool recv_iv(std::string password, int encryption_method, boost::posix_time::seconds timeout) {
81                        if (!socket_ || !socket_->is_open()) {
82                                NSC_LOG_ERROR_STD(_T("Socket was closed when trying to read data..."));
83                                return false;
84                        }
85                        unsigned int len = nsca::length::iv::get_packet_length();
86                        std::vector<char> buf(len);
87                        if (!read_with_timeout(buf, timeout)) {
88                                NSC_LOG_ERROR_STD(_T("Failed to read IV from server (using ") + strEx::itos(encryption_method) + _T(", ") + strEx::itos(len) + _T(")."));
89                                return false;
90                        }
91                        nsca::iv_packet iv_packet(std::string(buf.begin(), buf.end()));
92                        std::string iv = iv_packet.get_iv();
93                        time = iv_packet.get_time();
94                        NSC_DEBUG_MSG(_T("Encrypting using: ") + utf8::cvt<std::wstring>(nsca::nsca_encrypt::helpers::encryption_to_string(encryption_method)) + _T(", password '") + utf8::cvt<std::wstring>(password) + _T("'"));
95                        crypt_inst.encrypt_init(password, encryption_method, iv);
96                        return true;
97                }
98                virtual bool read_with_timeout(std::vector<char> &buf, boost::posix_time::seconds timeout) {
99                        return socket_helpers::io::read_with_timeout(*socket_, *socket_, boost::asio::buffer(buf), timeout);
100                }
101                virtual void write_with_timeout(std::string &buf, boost::posix_time::seconds timeout) {
102                        socket_helpers::io::write_with_timeout(*socket_, *socket_, boost::asio::buffer(buf), timeout);
103                }
104        };
105}
Note: See TracBrowser for help on using the repository browser.