Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __TLS_TUNNEL_H__
00030 #define __TLS_TUNNEL_H__
00031
00032 #include <boost/bind.hpp>
00033 #include <boost/function.hpp>
00034 #include <boost/lexical_cast.hpp>
00035 #include <boost/enable_shared_from_this.hpp>
00036 #if defined(HAVE_BOOST_ASIO_HPP)
00037 # include <boost/asio.hpp>
00038 #else
00039 # include <asio.hpp>
00040 #endif
00041 #include <string>
00042 #include <vector>
00043 #ifdef _MSC_VER
00044 typedef long ssize_t;
00045 typedef int pid_t;
00046 #endif
00047 #include <gnutls/gnutls.h>
00048 #include <gnutls/x509.h>
00049
00050 namespace tls_tunnel {
00051
00052 typedef boost::shared_ptr<asio::ip::tcp::socket> socket_ptr_t;
00053 typedef boost::shared_ptr<gnutls_session_t> session_ptr_t;
00054 typedef boost::shared_ptr< std::vector<char> > buffer_ptr_t;
00055
00056 class Exception {
00057 public:
00058 Exception(const std::string& message);
00059 const std::string& message() const;
00060 private:
00061 std::string message_;
00062 };
00063
00064 class Transport : public boost::enable_shared_from_this<Transport> {
00065 public:
00066 asio::io_service& io_service();
00067 void run();
00068 void stop();
00069
00070 protected:
00071 Transport();
00072 virtual ~Transport();
00073
00074 private:
00075 asio::io_service io_service_;
00076 asio::io_service::work work_;
00077 };
00078
00079 typedef boost::shared_ptr<Transport> transport_ptr_t;
00080
00081 class ClientTransport : public Transport {
00082 public:
00083 ClientTransport(const std::string& host, unsigned short port,
00084 boost::function<void (transport_ptr_t, socket_ptr_t)> on_connect);
00085 void connect();
00086 private:
00087 std::string host_;
00088 unsigned short port_;
00089 boost::function<void (transport_ptr_t, socket_ptr_t)> on_connect_;
00090 };
00091
00092
00093 class ServerTransport : public Transport {
00094 public:
00095 ServerTransport(const std::string& ip, unsigned short port,
00096 boost::function<void (transport_ptr_t, socket_ptr_t)> on_connect);
00097 void accept();
00098 private:
00099 void on_accept(const asio::error_code& error, socket_ptr_t socket_ptr);
00100
00101 asio::ip::tcp::acceptor acceptor_;
00102 boost::function<void (transport_ptr_t, socket_ptr_t)> on_connect_;
00103 };
00104
00105 class Proxy {
00106 public:
00107 virtual ~Proxy();
00108 static bool tls_tunnel_init();
00109 static void tls_tunnel_deinit();
00110 virtual void setup() = 0;
00111 void run();
00112 virtual void stop();
00113
00114 protected:
00115 Proxy(const std::string& ca_file);
00116
00117 void on_local_read(const asio::error_code& error, std::size_t bytes_transferred,
00118 transport_ptr_t transport_ptr, session_ptr_t session_ptr, socket_ptr_t local_socket_ptr,
00119 buffer_ptr_t local_buffer_ptr, socket_ptr_t remote_socket_ptr);
00120 void tunnel(transport_ptr_t transport_ptr, session_ptr_t session_ptr,
00121 socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr);
00122 void disconnect_(transport_ptr_t transport_ptr, session_ptr_t session_ptr,
00123 socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr);
00124
00125 gnutls_certificate_credentials_t x509cred;
00126
00127 transport_ptr_t transport_ptr_;
00128
00129 private:
00130 void tunnel_(transport_ptr_t transport_ptr, session_ptr_t session_ptr,
00131 socket_ptr_t local_socket_ptr, buffer_ptr_t local_buffer_ptr,
00132 socket_ptr_t remote_socket);
00133
00134 asio::thread* t;
00135 };
00136
00137
00138 class ClientProxy : public Proxy {
00139 public:
00140 ClientProxy(const std::string& connect_address, unsigned short connect_port,
00141 const std::string& ca_file, bool check_hostname);
00142
00143 virtual void setup();
00144 virtual void stop();
00145
00146 const std::string& local_address() const;
00147 unsigned short local_port() const;
00148
00149 private:
00150 void on_transport_connect(transport_ptr_t transport_ptr, socket_ptr_t remote_socket_ptr);
00151 void on_client_connect(const asio::error_code& error, transport_ptr_t transport_ptr,
00152 session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr);
00153 session_ptr_t setup_tls_session(socket_ptr_t remote_socket_ptr);
00154
00155 std::string local_address_;
00156 unsigned short local_port_;
00157 std::string connect_address_;
00158 unsigned short connect_port_;
00159 boost::shared_ptr<asio::ip::tcp::acceptor> acceptor_ptr;
00160 bool check_hostname_;
00161 };
00162
00163 class ServerProxy : public Proxy {
00164 public:
00165 ServerProxy(const std::string& bind_ip, unsigned short bind_port, unsigned short local_port,
00166 const std::string& ca_file, const std::string& cert_file, const std::string& key_file);
00167
00168 virtual void setup();
00169
00170 private:
00171 void on_transport_connect(transport_ptr_t transport_ptr, socket_ptr_t remote_socket_ptr);
00172 session_ptr_t setup_tls_session(socket_ptr_t remote_socket_ptr);
00173
00174 std::string bind_ip_;
00175 unsigned short bind_port_;
00176 unsigned short local_port_;
00177 gnutls_dh_params_t dh_params;
00178 };
00179
00180 }
00181
00182 #endif