Added https support
This commit is contained in:
		
							parent
							
								
									0a14ec2fff
								
							
						
					
					
						commit
						04945291c1
					
				
							
								
								
									
										1
									
								
								html/index.html
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								html/index.html
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -38,9 +38,9 @@ public: | ||||
| namespace http { | ||||
| namespace server { | ||||
| 
 | ||||
| connection::connection(boost::asio::ip::tcp::socket socket, | ||||
| connection::connection(std::shared_ptr<ssl_socket> newSocketPtr, | ||||
|     connection_manager& manager, request_handler& handler, boost::asio::io_context& io_context) | ||||
|   : socket_(std::move(socket)), | ||||
|   : socketPtr(newSocketPtr), | ||||
|     connection_manager_(manager), | ||||
|     request_handler_(handler), | ||||
| 	io_context_(io_context), | ||||
| @ -50,18 +50,45 @@ connection::connection(boost::asio::ip::tcp::socket socket, | ||||
| 
 | ||||
| void connection::start() | ||||
| { | ||||
|   do_read(); | ||||
| 	doHandshake(); | ||||
| } | ||||
| 
 | ||||
| void connection::stop() | ||||
| { | ||||
|   socket_.close(); | ||||
|   socketPtr->lowest_layer().close(); | ||||
|   //socketPtr.reset();
 | ||||
| } | ||||
| 
 | ||||
| void connection::doHandshake() | ||||
| { | ||||
| 	std::cout << "ProxySession::asyncHandshake" << std::endl; | ||||
| 	auto self(shared_from_this()); | ||||
| 
 | ||||
| 	socketPtr->async_handshake(boost::asio::ssl::stream_base::server, | ||||
| 		[this, self](boost::system::error_code ec) { | ||||
| 
 | ||||
| 		std::cout << "ProxySession::asyncHandshake inner" << std::endl; | ||||
| 
 | ||||
| 		if (!ec) | ||||
| 		{ | ||||
| 			std::cout << "ProxySession::asyncHandshake inner2" << std::endl; | ||||
| 			do_read(); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (ec != boost::asio::error::operation_aborted) | ||||
| 			{ | ||||
| 				connection_manager_.stop(shared_from_this()); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| void connection::do_read() | ||||
| { | ||||
|   auto self(shared_from_this()); | ||||
|   socket_.async_read_some(boost::asio::buffer(buffer_), | ||||
|   socketPtr->async_read_some(boost::asio::buffer(buffer_), | ||||
|       [this, self](boost::system::error_code ec, std::size_t bytes_transferred) | ||||
|       { | ||||
|         if (!ec) | ||||
| @ -137,15 +164,15 @@ void connection::do_read() | ||||
| void connection::do_write() | ||||
| { | ||||
|   auto self(shared_from_this()); | ||||
|   boost::asio::async_write(socket_, reply_.to_buffers(), | ||||
|   boost::asio::async_write((*socketPtr), reply_.to_buffers(), | ||||
|       [this, self](boost::system::error_code ec, std::size_t) | ||||
|       { | ||||
|         if (!ec) | ||||
|         { | ||||
| 
 | ||||
|           // Initiate graceful connection closure.
 | ||||
|           boost::system::error_code ignored_ec; | ||||
|           socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, | ||||
|             ignored_ec); | ||||
| 		  socketPtr->shutdown(ignored_ec); | ||||
|         } | ||||
| 
 | ||||
|         if (ec != boost::asio::error::operation_aborted) | ||||
| @ -172,7 +199,7 @@ void connection::do_try_connect_remote(std::string host, std::string port) | ||||
| 		if (!ec) | ||||
| 		{ | ||||
| 			auto self(shared_from_this()); | ||||
| 			boost::asio::async_write(socket_, boost::asio::buffer(okReply), | ||||
| 			boost::asio::async_write((*socketPtr), boost::asio::buffer(okReply), | ||||
| 				[this, self](boost::system::error_code ec, std::size_t) | ||||
| 			{ | ||||
| 				if (!ec) | ||||
| @ -208,7 +235,7 @@ void connection::transferDataForward() | ||||
| { | ||||
| 	auto self(shared_from_this()); | ||||
| 
 | ||||
| 	socket_.async_read_some(boost::asio::buffer(forwardBuffer), | ||||
| 	socketPtr->async_read_some(boost::asio::buffer(forwardBuffer), | ||||
| 		[this, self](boost::system::error_code ec, std::size_t length) | ||||
| 	{ | ||||
| 		if (!ec) | ||||
| @ -283,7 +310,7 @@ void connection::transferDataBackward() | ||||
| 			std::cout << boost::lexical_cast<std::string>(int(backwardBuffer[length - 1])) << "\n"; | ||||
| 
 | ||||
| 
 | ||||
| 			boost::asio::async_write(socket_, | ||||
| 			boost::asio::async_write((*socketPtr), | ||||
| 				boost::asio::buffer(*data), | ||||
| 				[this, self, data](boost::system::error_code ec, std::size_t length) | ||||
| 			{ | ||||
|  | ||||
| @ -19,6 +19,23 @@ | ||||
| #include "request_handler.hpp" | ||||
| #include "request_parser.hpp" | ||||
| 
 | ||||
| 
 | ||||
| #ifndef SSL_R_SHORT_READ | ||||
| #define SSL_R_SHORT_READ 219 | ||||
| #endif | ||||
| 
 | ||||
| #include "ssl/ssl_locl.h" | ||||
| #include <boost/asio/ssl.hpp> | ||||
| 
 | ||||
| #if defined(close) | ||||
| #undef close | ||||
| #endif | ||||
| 
 | ||||
| typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| namespace http { | ||||
| namespace server { | ||||
| 
 | ||||
| @ -33,7 +50,7 @@ public: | ||||
|   connection& operator=(const connection&) = delete; | ||||
| 
 | ||||
|   /// Construct a connection with the given socket.
 | ||||
|   explicit connection(boost::asio::ip::tcp::socket socket, | ||||
|   explicit connection(std::shared_ptr<ssl_socket> newSocketPtr, | ||||
|       connection_manager& manager, request_handler& handler, boost::asio::io_context& io_context); | ||||
| 
 | ||||
|   /// Start the first asynchronous operation for the connection.
 | ||||
| @ -43,6 +60,9 @@ public: | ||||
|   void stop(); | ||||
| 
 | ||||
| private: | ||||
| 
 | ||||
|   void doHandshake(); | ||||
| 
 | ||||
|   /// Perform an asynchronous read operation.
 | ||||
|   void do_read(); | ||||
| 
 | ||||
| @ -50,7 +70,8 @@ private: | ||||
|   void do_write(); | ||||
| 
 | ||||
|   /// Socket for the connection.
 | ||||
|   boost::asio::ip::tcp::socket socket_; | ||||
|   //boost::asio::ip::tcp::socket socket_;
 | ||||
|   std::shared_ptr<ssl_socket> socketPtr; | ||||
| 
 | ||||
|   /// The manager for this connection.
 | ||||
|   connection_manager& connection_manager_; | ||||
|  | ||||
| @ -1,43 +0,0 @@ | ||||
| //
 | ||||
| // main.cpp
 | ||||
| // ~~~~~~~~
 | ||||
| //
 | ||||
| // Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 | ||||
| //
 | ||||
| // Distributed under the Boost Software License, Version 1.0. (See accompanying
 | ||||
| // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||||
| //
 | ||||
| 
 | ||||
| #include <iostream> | ||||
| #include <string> | ||||
| #include <boost/asio.hpp> | ||||
| #include "server.hpp" | ||||
| 
 | ||||
| int main_http(int argc, char* argv[]) | ||||
| { | ||||
|   try | ||||
|   { | ||||
|     // Check command line arguments.
 | ||||
|     if (argc != 4) | ||||
|     { | ||||
|       std::cerr << "Usage: http_server <address> <port> <doc_root>\n"; | ||||
|       std::cerr << "  For IPv4, try:\n"; | ||||
|       std::cerr << "    receiver 0.0.0.0 80 .\n"; | ||||
|       std::cerr << "  For IPv6, try:\n"; | ||||
|       std::cerr << "    receiver 0::0 80 .\n"; | ||||
|       return 1; | ||||
|     } | ||||
| 
 | ||||
|     // Initialise the server.
 | ||||
|     http::server::server s(argv[1], argv[2], argv[3]); | ||||
| 
 | ||||
|     // Run the server until stopped.
 | ||||
|     s.run(); | ||||
|   } | ||||
|   catch (std::exception& e) | ||||
|   { | ||||
|     std::cerr << "exception: " << e.what() << "\n"; | ||||
|   } | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| @ -16,12 +16,14 @@ namespace http { | ||||
| namespace server { | ||||
| 
 | ||||
| server::server(const std::string& address, const std::string& port, | ||||
|     const std::string& doc_root) | ||||
|     const std::string& doc_root, boost::asio::ssl::context& inSslContext) | ||||
|   : io_context_(1), | ||||
|     signals_(io_context_), | ||||
|     acceptor_(io_context_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 8043)), | ||||
|     connection_manager_(), | ||||
|     request_handler_(doc_root) | ||||
|     request_handler_(doc_root), | ||||
| 	sslContext(inSslContext), | ||||
| 	tempSocketPtr(std::make_shared<ssl_socket>(io_context_, inSslContext)) | ||||
| { | ||||
|   // Register to handle the signals that indicate when the server should exit.
 | ||||
|   // It is safe to register for the same signal multiple times in a program,
 | ||||
| @ -48,8 +50,9 @@ void server::run() | ||||
| 
 | ||||
| void server::do_accept() | ||||
| { | ||||
|   acceptor_.async_accept( | ||||
|       [this](boost::system::error_code ec, boost::asio::ip::tcp::socket socket) | ||||
| 	auto newSocketPtr = tempSocketPtr; | ||||
|   acceptor_.async_accept(tempSocketPtr->lowest_layer(), | ||||
|       [newSocketPtr, this](boost::system::error_code ec) | ||||
|       { | ||||
|         // Check whether the server was stopped by a signal before this
 | ||||
|         // completion handler had a chance to run.
 | ||||
| @ -61,9 +64,11 @@ void server::do_accept() | ||||
|         if (!ec) | ||||
|         { | ||||
|           connection_manager_.start(std::make_shared<connection>( | ||||
|               std::move(socket), connection_manager_, request_handler_, io_context_)); | ||||
| 			  newSocketPtr, connection_manager_, request_handler_, io_context_)); | ||||
|         } | ||||
| 
 | ||||
| 		this->tempSocketPtr = std::make_shared<ssl_socket>(io_context_, sslContext); | ||||
| 
 | ||||
|         do_accept(); | ||||
|       }); | ||||
| } | ||||
|  | ||||
| @ -17,6 +17,19 @@ | ||||
| #include "connection_manager.hpp" | ||||
| #include "request_handler.hpp" | ||||
| 
 | ||||
| 
 | ||||
| #ifndef SSL_R_SHORT_READ | ||||
| #define SSL_R_SHORT_READ 219 | ||||
| #endif | ||||
| 
 | ||||
| #include "ssl/ssl_locl.h" | ||||
| #include <boost/asio/ssl.hpp> | ||||
| 
 | ||||
| #if defined(close) | ||||
| #undef close | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| namespace http { | ||||
| namespace server { | ||||
| 
 | ||||
| @ -30,7 +43,7 @@ public: | ||||
|   /// Construct the server to listen on the specified TCP address and port, and
 | ||||
|   /// serve up files from the given directory.
 | ||||
|   explicit server(const std::string& address, const std::string& port, | ||||
|       const std::string& doc_root); | ||||
|       const std::string& doc_root, boost::asio::ssl::context& inSslContext); | ||||
| 
 | ||||
|   /// Run the server's io_context loop.
 | ||||
|   void run(); | ||||
| @ -56,6 +69,12 @@ private: | ||||
| 
 | ||||
|   /// The handler for all incoming requests.
 | ||||
|   request_handler request_handler_; | ||||
| 
 | ||||
| 
 | ||||
|   boost::asio::ssl::context& sslContext; | ||||
| 
 | ||||
| 
 | ||||
|   std::shared_ptr<ssl_socket> tempSocketPtr; | ||||
| }; | ||||
| 
 | ||||
| } // namespace server
 | ||||
|  | ||||
							
								
								
									
										767
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										767
									
								
								main.cpp
									
									
									
									
									
								
							| @ -10,714 +10,7 @@ | ||||
| #include <boost/thread.hpp> | ||||
| 
 | ||||
| 
 | ||||
| #if 0 | ||||
| #define SSL_R_SHORT_READ 219 | ||||
| #include "ssl/ssl_locl.h" | ||||
| #include <boost/asio/ssl.hpp> | ||||
| #endif | ||||
| 
 | ||||
| #if defined(close) | ||||
| #undef close | ||||
| #endif | ||||
| 
 | ||||
| enum AddressType | ||||
| { | ||||
| 	AT_IPV4 = 0, | ||||
| 	AT_HOST = 3, | ||||
| 	AT_IPV6 = 4 | ||||
| }; | ||||
| 
 | ||||
| class ConnectResponseRecord | ||||
| { | ||||
| public: | ||||
| 	std::vector<unsigned char> rawData; | ||||
| 
 | ||||
| 	enum ConnectResponseType | ||||
| 	{ | ||||
| 		CRT_SUCCESS = 0, | ||||
| 		CRT_GENERAL_SOCKS_SERVER_FAILURE = 1, | ||||
| 		CRT_CONNECTION_NOT_ALLOWED_BY_RULESET = 2, | ||||
| 		CRT_NETWORK_UNREACHABLE = 3, | ||||
| 		CRT_HOST_UNREACHABLE = 4, | ||||
| 		CRT_CONNECTION_REFUSED = 5, | ||||
| 		CRT_TTL_EXPIRED = 6, | ||||
| 		CRT_COMMAND_NOT_SUPPORTED = 7, | ||||
| 		CRT_ADDRESS_TYPE_NOT_SUPPORTED = 8, | ||||
| 		CRT_TO_FF_UNASSIGNED = 9 | ||||
| 	}; | ||||
| 
 | ||||
| 	ConnectResponseType connectResponseType; | ||||
| 
 | ||||
| 	AddressType addressType; | ||||
| 
 | ||||
| 	std::string address; | ||||
| 
 | ||||
| 	uint16_t port; | ||||
| }; | ||||
| 
 | ||||
| class ConnectRequestRecord | ||||
| { | ||||
| public: | ||||
| 	std::string address; | ||||
| 	uint16_t port; | ||||
| 
 | ||||
| 	std::string getRequestData(); | ||||
| }; | ||||
| 
 | ||||
| std::string ConnectRequestRecord::getRequestData() | ||||
| { | ||||
| 	std::string data = ""; | ||||
| 	data += 0x05; | ||||
| 	data += 0x01; | ||||
| 	data += char(0x00); | ||||
| 	data += 0x03; | ||||
| 	data += static_cast<unsigned char>(address.size()); | ||||
| 	data += address; | ||||
| 	data += port / 256; | ||||
| 	data += port % 256; | ||||
| 	return data; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class ProxySession : | ||||
| 	public std::enable_shared_from_this<ProxySession> | ||||
| { | ||||
| public: | ||||
| 	ProxySession(boost::asio::ip::tcp::socket inSocket, boost::asio::io_service& inIoService) | ||||
| 		: ioService(inIoService) | ||||
| 		, mSocket(std::move(inSocket)) | ||||
| 		, outsideConnectSocket(ioService) | ||||
| 	{ | ||||
| 		std::cout << "ProxySession Create" << std::endl; | ||||
| 	} | ||||
| 
 | ||||
| 	~ProxySession() | ||||
| 	{ | ||||
| 		std::cout << "ProxySession Destroy" << std::endl; | ||||
| 	} | ||||
| 
 | ||||
| 	void start() | ||||
| 	{ | ||||
| 		std::cout << "ProxySession::start" << std::endl; | ||||
| 		//asyncHandshake();
 | ||||
| 		readClientVersion(); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| private: | ||||
| 
 | ||||
| 	boost::asio::ip::tcp::socket& socket() | ||||
| 	{ | ||||
| 		return mSocket; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	std::array<unsigned char, 3> clientVersion; | ||||
| 	 | ||||
| 	void readClientVersion() | ||||
| 	{ | ||||
| 		std::cout << "ProxySession::readClientVersion" << std::endl; | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 		boost::asio::async_read(socket(), | ||||
| 			boost::asio::buffer(clientVersion.data(), clientVersion.size()), | ||||
| 			[this, self](boost::system::error_code ec, std::size_t /*length*/) | ||||
| 		{ | ||||
| 			std::cout << "ProxySession::readClientVersion inner" << std::endl; | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				if (clientVersion[0] == 0x05 && clientVersion[1] == 0x01 && clientVersion[2] == 0x02) | ||||
| 				{ | ||||
| 					sendServerVersion(); | ||||
| 				} | ||||
| 				else if (clientVersion[0] == 0x05 && clientVersion[1] == 0x01 && clientVersion[2] == 0x00) | ||||
| 				{ | ||||
| 					sendServerVersionNoAuth(); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					std::string msg = ec.message(); | ||||
| 					std::cout << msg << std::endl; | ||||
| 					socket().close(); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	void sendServerVersion() | ||||
| 	{ | ||||
| 
 | ||||
| 		std::cout << "ProxySession::sendServerVersion" << std::endl; | ||||
| 
 | ||||
| 		auto self(shared_from_this()); | ||||
| 	 | ||||
| 		std::array<char, 2> version = { 0x05, 0x02 }; | ||||
| 
 | ||||
| 		boost::asio::async_write(socket(), | ||||
| 			boost::asio::buffer(version.data(), version.size()), | ||||
| 			[this, self](boost::system::error_code ec, std::size_t length) | ||||
| 		{ | ||||
| 			std::cout << "ProxySession::sendServerVersion inner" << std::endl; | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				readLoginPassword(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	void sendServerVersionNoAuth() | ||||
| 	{ | ||||
| 
 | ||||
| 		std::cout << "ProxySession::sendServerVersionNoAuth" << std::endl; | ||||
| 
 | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 		std::array<char, 2> version = { 0x05, 0x00 }; | ||||
| 
 | ||||
| 		boost::asio::async_write(socket(), | ||||
| 			boost::asio::buffer(version.data(), version.size()), | ||||
| 			[this, self](boost::system::error_code ec, std::size_t length) | ||||
| 		{ | ||||
| 			std::cout << "ProxySession::sendServerVersionNoAuth inner" << std::endl; | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				//readLoginPassword();
 | ||||
| 				readConnectRequest(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 
 | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	void readLoginPassword() | ||||
| 	{ | ||||
| 		std::string login = "telegram-proxy-user"; | ||||
| 		std::string password = "telegram-telegram-999112"; | ||||
| 		std::string expectedData = ""; | ||||
| 		expectedData += 0x01; | ||||
| 		expectedData += static_cast<unsigned char>(login.size()); | ||||
| 		expectedData += login; | ||||
| 		expectedData += static_cast<unsigned char>(password.size()); | ||||
| 		expectedData += password; | ||||
| 
 | ||||
| 		std::shared_ptr<std::string> clientLoginPasswordPtr = std::make_shared<std::string>(); | ||||
| 
 | ||||
| 
 | ||||
| 		clientLoginPasswordPtr->resize(expectedData.size()); | ||||
| 
 | ||||
| 
 | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 
 | ||||
| 		boost::asio::async_read(socket(), | ||||
| 			boost::asio::buffer(&((*clientLoginPasswordPtr)[0]), clientLoginPasswordPtr->size()), | ||||
| 			[this, self, expectedData, clientLoginPasswordPtr](boost::system::error_code ec, std::size_t /*length*/) | ||||
| 		{ | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				if (*clientLoginPasswordPtr == expectedData) | ||||
| 				{ | ||||
| 					sendAuthStatus(); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					std::string msg = ec.message(); | ||||
| 					std::cout << msg << std::endl; | ||||
| 					socket().close(); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 			} | ||||
| 		}); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	std::array<unsigned char, 2> authStatus = std::array<unsigned char, 2>{ (unsigned char)0x01, (unsigned char)0x00 }; | ||||
| 
 | ||||
| 	void sendAuthStatus() | ||||
| 	{ | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 		 | ||||
| 
 | ||||
| 		boost::asio::async_write(socket(), | ||||
| 			boost::asio::buffer(authStatus.data(), authStatus.size()), | ||||
| 			[this, self](boost::system::error_code ec, std::size_t length) | ||||
| 		{ | ||||
| 
 | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				readConnectRequest(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	void readConnectRequest() | ||||
| 	{ | ||||
| 
 | ||||
| 		std::cout << "ProxySession::readConnectRequest" << std::endl; | ||||
| 
 | ||||
| 		std::shared_ptr<std::array<unsigned char, 5>> firstPartPtr = std::make_shared<std::array<unsigned char, 5>>(); | ||||
| 
 | ||||
| 
 | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 
 | ||||
| 		boost::asio::async_read(socket(), | ||||
| 			boost::asio::buffer(firstPartPtr->data(), firstPartPtr->size()), | ||||
| 			[this, self, firstPartPtr](boost::system::error_code ec, std::size_t /*length*/) | ||||
| 		{ | ||||
| 			std::cout << "ProxySession::readConnectRequest iner" << std::endl; | ||||
| 
 | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				if ((*firstPartPtr)[0] == 0x05 && (*firstPartPtr)[1] == 0x01 && (*firstPartPtr)[2] == 0x00) | ||||
| 				{ | ||||
| 					if ((*firstPartPtr)[3] == 0x03) | ||||
| 					{ | ||||
| 						readConnectRequestPart2(firstPartPtr); | ||||
| 					} | ||||
| 					else if ((*firstPartPtr)[3] == 0x01) | ||||
| 					{ | ||||
| 						readConnectRequestPart2IpAddress(firstPartPtr); | ||||
| 					} | ||||
| 
 | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					std::string msg = ec.message(); | ||||
| 					std::cout << msg << std::endl; | ||||
| 					socket().close(); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 			} | ||||
| 		}); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	void readConnectRequestPart2(std::shared_ptr<std::array<unsigned char, 5>> firstPartPtr) | ||||
| 	{ | ||||
| 		unsigned int len = (*firstPartPtr)[4]; | ||||
| 
 | ||||
| 		std::shared_ptr<std::vector<unsigned char>> secondPartPtr = std::make_shared<std::vector<unsigned char>>(); | ||||
| 
 | ||||
| 
 | ||||
| 		secondPartPtr->resize(len + 2); | ||||
| 
 | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 
 | ||||
| 		boost::asio::async_read(socket(), | ||||
| 			boost::asio::buffer(secondPartPtr->data(), secondPartPtr->size()), | ||||
| 			[this, self, firstPartPtr, secondPartPtr, len](boost::system::error_code ec, std::size_t /*length*/) | ||||
| 		{ | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 
 | ||||
| 				ConnectRequestRecord connectRequestRecord; | ||||
| 
 | ||||
| 				connectRequestRecord.address = std::string(&((*secondPartPtr)[0]), &((*secondPartPtr)[0]) + len); | ||||
| 				connectRequestRecord.port = (*secondPartPtr)[len] * 256 + (*secondPartPtr)[len + 1]; | ||||
| 
 | ||||
| 				boost::asio::ip::tcp::resolver resolver(this->ioService); | ||||
| 				auto endpointIterator = resolver.resolve({ connectRequestRecord.address, boost::lexical_cast<std::string>(connectRequestRecord.port) }); | ||||
| 
 | ||||
| 
 | ||||
| 				doConnectOutput(endpointIterator, connectRequestRecord); | ||||
| 
 | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 			} | ||||
| 		}); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	void readConnectRequestPart2IpAddress(std::shared_ptr<std::array<unsigned char, 5>> firstPartPtr) | ||||
| 	{ | ||||
| 		unsigned int ip1st = (*firstPartPtr)[4]; | ||||
| 
 | ||||
| 		std::shared_ptr<std::array<unsigned char, 5>> secondPartPtr = std::make_shared<std::array<unsigned char, 5>>(); | ||||
| 
 | ||||
| 
 | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 
 | ||||
| 		boost::asio::async_read(socket(), | ||||
| 			boost::asio::buffer(secondPartPtr->data(), secondPartPtr->size()), | ||||
| 			[this, self, firstPartPtr, secondPartPtr, ip1st](boost::system::error_code ec, std::size_t /*length*/) | ||||
| 		{ | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 
 | ||||
| 				ConnectRequestRecord connectRequestRecord; | ||||
| 
 | ||||
| 				connectRequestRecord.address = boost::lexical_cast<std::string>(static_cast<unsigned int>(ip1st)) + "." | ||||
| 					+ boost::lexical_cast<std::string>(static_cast<unsigned int>((*secondPartPtr)[0])) + "." | ||||
| 					+ boost::lexical_cast<std::string>(static_cast<unsigned int>((*secondPartPtr)[1])) + "." | ||||
| 					+ boost::lexical_cast<std::string>(static_cast<unsigned int>((*secondPartPtr)[2])); | ||||
| 
 | ||||
| 				connectRequestRecord.port = (*secondPartPtr)[3] * 256 + (*secondPartPtr)[4]; | ||||
| 
 | ||||
| 				boost::asio::ip::tcp::resolver resolver(this->ioService); | ||||
| 				auto endpointIterator = resolver.resolve({ connectRequestRecord.address, boost::lexical_cast<std::string>(connectRequestRecord.port) }); | ||||
| 
 | ||||
| 
 | ||||
| 				doConnectOutputIpAddress(endpointIterator, connectRequestRecord, { static_cast<unsigned char>(ip1st) , ((*secondPartPtr)[0]) , ((*secondPartPtr)[1]) , ((*secondPartPtr)[2]) }); | ||||
| 
 | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 			} | ||||
| 		}); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	void doConnectOutput(boost::asio::ip::tcp::resolver::iterator endpointIterator, ConnectRequestRecord connectRequestRecord) | ||||
| 	{ | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 		boost::asio::async_connect(outsideConnectSocket, endpointIterator, | ||||
| 			[this, self, connectRequestRecord](boost::system::error_code ec, boost::asio::ip::tcp::resolver::iterator) | ||||
| 		{ | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				sendConnectResponse(connectRequestRecord); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 				outsideConnectSocket.close(); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	void doConnectOutputIpAddress(boost::asio::ip::tcp::resolver::iterator endpointIterator, ConnectRequestRecord connectRequestRecord, std::array<unsigned char, 4> ipAddress) | ||||
| 	{ | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 		boost::asio::async_connect(outsideConnectSocket, endpointIterator, | ||||
| 			[this, self, connectRequestRecord, ipAddress](boost::system::error_code ec, boost::asio::ip::tcp::resolver::iterator) | ||||
| 		{ | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				sendConnectResponseIpAddress(connectRequestRecord, ipAddress); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 				outsideConnectSocket.close(); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	void sendConnectResponse(ConnectRequestRecord connectRequestRecord) | ||||
| 	{ | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 		std::string connectResponse; | ||||
| 
 | ||||
| 		connectResponse += 0x05; | ||||
| 		connectResponse += static_cast<char>(0x00); | ||||
| 		connectResponse += static_cast<char>(0x00); | ||||
| 		connectResponse += 0x03; | ||||
| 
 | ||||
| 		connectResponse += static_cast<unsigned char>(connectRequestRecord.address.size()); | ||||
| 		connectResponse += connectRequestRecord.address; | ||||
| 		connectResponse += static_cast<unsigned char>(connectRequestRecord.port / 256); | ||||
| 		connectResponse += static_cast<unsigned char>(connectRequestRecord.port % 256); | ||||
| 
 | ||||
| 
 | ||||
| 		boost::asio::async_write(socket(), | ||||
| 			boost::asio::buffer(connectResponse.data(), connectResponse.size()), | ||||
| 			[this, self](boost::system::error_code ec, std::size_t length) | ||||
| 		{ | ||||
| 
 | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				transferDataForward(); | ||||
| 				transferDataBackward(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 				outsideConnectSocket.close(); | ||||
| 			} | ||||
| 		}); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	void sendConnectResponseIpAddress(ConnectRequestRecord connectRequestRecord, std::array<unsigned char, 4> ipAddress) | ||||
| 	{ | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 		std::string connectResponse; | ||||
| 
 | ||||
| 		connectResponse += 0x05; | ||||
| 		connectResponse += static_cast<char>(0x00); | ||||
| 		connectResponse += static_cast<char>(0x00); | ||||
| 		connectResponse += 0x01; | ||||
| 
 | ||||
| 		connectResponse += ipAddress[0]; | ||||
| 		connectResponse += ipAddress[1]; | ||||
| 		connectResponse += ipAddress[2]; | ||||
| 		connectResponse += ipAddress[3]; | ||||
| 		connectResponse += static_cast<unsigned char>(connectRequestRecord.port / 256); | ||||
| 		connectResponse += static_cast<unsigned char>(connectRequestRecord.port % 256); | ||||
| 
 | ||||
| 
 | ||||
| 		boost::asio::async_write(socket(), | ||||
| 			boost::asio::buffer(connectResponse.data(), connectResponse.size()), | ||||
| 			[this, self](boost::system::error_code ec, std::size_t length) | ||||
| 		{ | ||||
| 
 | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				transferDataForward(); | ||||
| 				transferDataBackward(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				socket().close(); | ||||
| 				outsideConnectSocket.close(); | ||||
| 			} | ||||
| 		}); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	std::array<unsigned char, 8192> forwardBuffer; | ||||
| 	std::array<unsigned char, 8192> backwardBuffer; | ||||
| 	//unsigned char forwardChar;
 | ||||
| 	//unsigned char backwardChar;
 | ||||
| 
 | ||||
| 
 | ||||
| 	void transferDataForward() | ||||
| 	{ | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 		socket().async_read_some(boost::asio::buffer(forwardBuffer), | ||||
| 			[this, self](boost::system::error_code ec, std::size_t length) | ||||
| 		{ | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 
 | ||||
| 				std::shared_ptr<std::vector<unsigned char>> data = std::make_shared<std::vector<unsigned char>>(); | ||||
| 				data->resize(length); | ||||
| 
 | ||||
| 				std::copy(&forwardBuffer[0], &forwardBuffer[0] + length, &(*data)[0]); | ||||
| 
 | ||||
| 				std::cout << "Forward Received " << length << " Bytes, sending\n"; | ||||
| 
 | ||||
| 				std::cout << boost::lexical_cast<std::string>(int(forwardBuffer[0])) << "\n"; | ||||
| 				std::cout << boost::lexical_cast<std::string>(int(forwardBuffer[length - 1])) << "\n"; | ||||
| 
 | ||||
| 				 | ||||
| 
 | ||||
| 				boost::asio::async_write(outsideConnectSocket, | ||||
| 					boost::asio::buffer(*data), | ||||
| 					[this, self, data](boost::system::error_code ec, std::size_t length) | ||||
| 				{ | ||||
| 
 | ||||
| 					if (!ec) | ||||
| 					{ | ||||
| 						std::cout << "Forward Sent, now read again!\n"; | ||||
| 						transferDataForward(); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						std::string msg = ec.message(); | ||||
| 						std::cout << msg << std::endl; | ||||
| 						outsideConnectSocket.close(); | ||||
| 						socket().close(); | ||||
| 					} | ||||
| 				}); | ||||
| 			} | ||||
| 			else if (ec == boost::asio::error::eof) | ||||
| 			{ | ||||
| 				std::cout << "transferDataForward read end of file" << std::endl; | ||||
| 				if (length > 0) | ||||
| 				{ | ||||
| 					std::cout << "but length is positive" << std::endl; | ||||
| 				} | ||||
| 				return; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				outsideConnectSocket.close(); | ||||
| 				socket().close(); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	void transferDataBackward() | ||||
| 	{ | ||||
| 		auto self(shared_from_this()); | ||||
| 
 | ||||
| 		outsideConnectSocket.async_read_some(boost::asio::buffer(backwardBuffer), | ||||
| 			[this, self](boost::system::error_code ec, std::size_t length) | ||||
| 		{ | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 
 | ||||
| 				std::shared_ptr<std::vector<unsigned char>> data = std::make_shared<std::vector<unsigned char>>(); | ||||
| 				data->resize(length); | ||||
| 
 | ||||
| 				std::copy(&backwardBuffer[0], &backwardBuffer[0] + length, &(*data)[0]); | ||||
| 
 | ||||
| 				std::cout << "Backward Received " << length << " Bytes, sending\n"; | ||||
| 
 | ||||
| 				std::cout << boost::lexical_cast<std::string>(int(backwardBuffer[0])) << "\n"; | ||||
| 				std::cout << boost::lexical_cast<std::string>(int(backwardBuffer[length - 1])) << "\n"; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 				boost::asio::async_write(socket(), | ||||
| 					boost::asio::buffer(*data), | ||||
| 					[this, self, data](boost::system::error_code ec, std::size_t length) | ||||
| 				{ | ||||
| 
 | ||||
| 					if (!ec) | ||||
| 					{ | ||||
| 						std::cout << "Backward Sent, now read again!\n"; | ||||
| 						transferDataBackward(); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						std::string msg = ec.message(); | ||||
| 						std::cout << msg << std::endl; | ||||
| 						outsideConnectSocket.close(); | ||||
| 						socket().close(); | ||||
| 					} | ||||
| 				}); | ||||
| 			} | ||||
| 			else if (ec == boost::asio::error::eof) | ||||
| 			{ | ||||
| 				std::cout << "transferDataBackward read end of file" << std::endl; | ||||
| 				if (length > 0) | ||||
| 				{ | ||||
| 					std::cout << "but length is positive" << std::endl; | ||||
| 				} | ||||
| 				return; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				std::string msg = ec.message(); | ||||
| 				std::cout << msg << std::endl; | ||||
| 				outsideConnectSocket.close(); | ||||
| 				socket().close(); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	boost::asio::io_service& ioService; | ||||
| 
 | ||||
| 	boost::asio::ip::tcp::socket mSocket; | ||||
| 
 | ||||
| 	boost::asio::ip::tcp::socket outsideConnectSocket; | ||||
| 
 | ||||
| 	 | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class ProxyServer | ||||
| { | ||||
| public: | ||||
| 	ProxyServer(boost::asio::io_service& inIoService, | ||||
| 		const boost::asio::ip::tcp::endpoint& endpoint) | ||||
| 		: ioService(inIoService) | ||||
| 		, acceptor(inIoService, endpoint) | ||||
| 		, socket(inIoService) | ||||
| 	{ | ||||
| 		doAccept(); | ||||
| 	} | ||||
| 
 | ||||
| private: | ||||
| 	void doAccept() | ||||
| 	{ | ||||
| 		acceptor.async_accept(socket, | ||||
| 			[this](boost::system::error_code ec) | ||||
| 		{ | ||||
| 			if (!ec) | ||||
| 			{ | ||||
| 				std::make_shared<ProxySession>(std::move(socket), ioService)->start(); | ||||
| 			} | ||||
| 
 | ||||
| 			counter++; | ||||
| 
 | ||||
| 			socket = boost::asio::ip::tcp::socket(ioService); | ||||
| 
 | ||||
| 			doAccept(); | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	boost::asio::io_service& ioService; | ||||
| 
 | ||||
| 	boost::asio::ip::tcp::acceptor acceptor; | ||||
| 	boost::asio::ip::tcp::socket socket; | ||||
| 
 | ||||
| 	size_t counter = 0; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| #include "http/server.hpp" | ||||
| @ -728,8 +21,30 @@ int main() | ||||
| 	try | ||||
| 	{ | ||||
| 
 | ||||
| 		boost::asio::ssl::context sslContext(boost::asio::ssl::context::tls_server); | ||||
| 
 | ||||
| 		SSL_CTX_set_cipher_list(sslContext.native_handle(), "EECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS"); | ||||
| 
 | ||||
| 		sslContext.set_options(boost::asio::ssl::context::default_workarounds | ||||
| 			| boost::asio::ssl::context::verify_none | ||||
| 			| boost::asio::ssl::context::no_sslv2 | ||||
| 			| boost::asio::ssl::context::no_sslv3 | ||||
| 			| boost::asio::ssl::context::no_tlsv1 | ||||
| 			| boost::asio::ssl::context::single_dh_use | ||||
| 		); | ||||
| 
 | ||||
| 		std::function<std::string(std::size_t, boost::asio::ssl::context_base::password_purpose)> f = [](std::size_t, boost::asio::ssl::context_base::password_purpose) -> std::string { return ""; }; | ||||
| 		sslContext.set_password_callback(f); | ||||
| 
 | ||||
| 		sslContext.use_certificate_chain_file("server.crt"); | ||||
| 
 | ||||
| 		sslContext.use_private_key_file("server.key", boost::asio::ssl::context::pem); | ||||
| 
 | ||||
| 		sslContext.use_tmp_dh_file("dh2048.pem"); | ||||
| 
 | ||||
| 
 | ||||
| 		// Initialise the server.
 | ||||
| 		http::server::server s("0.0.0.0", "8043", "."); | ||||
| 		http::server::server s("0.0.0.0", "8043", "./html/", sslContext); | ||||
| 
 | ||||
| 		// Run the server until stopped.
 | ||||
| 		s.run(); | ||||
| @ -743,40 +58,4 @@ int main() | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int main_0() | ||||
| { | ||||
| 
 | ||||
| 	try | ||||
| 	{ | ||||
| 
 | ||||
| 		boost::asio::io_service ioService; | ||||
| 
 | ||||
| 		boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 8043); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		ProxyServer proxyServer(ioService, endpoint); | ||||
| 
 | ||||
| 
 | ||||
| 		boost::thread_group threadpool; | ||||
| 
 | ||||
| 		threadpool.create_thread( | ||||
| 			boost::bind(&boost::asio::io_service::run, &ioService) | ||||
| 		); | ||||
| 
 | ||||
| 
 | ||||
| 		threadpool.join_all(); | ||||
| 
 | ||||
| 		//ioService.run();
 | ||||
| 
 | ||||
| 	} | ||||
| 	catch (std::exception& e) | ||||
| 	{ | ||||
| 		std::cerr << "Exception: " << e.what() << "\n"; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -134,7 +134,6 @@ | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="http\connection.cpp" /> | ||||
|     <ClCompile Include="http\connection_manager.cpp" /> | ||||
|     <ClCompile Include="http\main_http.cpp" /> | ||||
|     <ClCompile Include="http\mime_types.cpp" /> | ||||
|     <ClCompile Include="http\reply.cpp" /> | ||||
|     <ClCompile Include="http\request_handler.cpp" /> | ||||
|  | ||||
| @ -27,9 +27,6 @@ | ||||
|     <ClCompile Include="http\connection_manager.cpp"> | ||||
|       <Filter>Source Files\http</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="http\main_http.cpp"> | ||||
|       <Filter>Source Files\http</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="http\mime_types.cpp"> | ||||
|       <Filter>Source Files\http</Filter> | ||||
|     </ClCompile> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user