diff --git a/src/LocalproxyConfig.h b/src/LocalproxyConfig.h index 0f12ead..7f8a488 100644 --- a/src/LocalproxyConfig.h +++ b/src/LocalproxyConfig.h @@ -71,6 +71,10 @@ namespace aws { * The tunnel access token which the user gets when they open the tunnel. */ std::string access_token { }; + /** + * The reverse proxy tunnel endpoint path. + */ + std::string url_path { }; proxy_mode mode{ proxy_mode::UNKNOWN }; /** * A unique client-token to ensure only the agent which generated the token may connect to a tunnel diff --git a/src/TcpAdapterProxy.cpp b/src/TcpAdapterProxy.cpp index 599f432..2872189 100644 --- a/src/TcpAdapterProxy.cpp +++ b/src/TcpAdapterProxy.cpp @@ -111,7 +111,7 @@ namespace aws { namespace iot { namespace securedtunneling { { std::ostringstream request_stream; request_stream << request; - std::string unfiltered_request_string = request_stream.str(); + std::string unfiltered_request_string = request_stream.str(); std::tuple token_filter_range = get_access_token_range(unfiltered_request_string); return (boost::format("%1%***ACCESS_TOKEN_REMOVED***%2%") % unfiltered_request_string.substr(0, std::get<0>(token_filter_range)) % @@ -842,13 +842,13 @@ namespace aws { namespace iot { namespace securedtunneling { } tac.wss = std::make_shared(tac.adapter_config, &log, tac.io_ctx); tac.wss->control_callback(std::bind(&tcp_adapter_proxy::handle_web_socket_control_message, this, std::ref(tac), std::placeholders::_1, std::placeholders::_2)); - + static std::string user_agent_string = (boost::format("localproxy %1% %2%-bit/boost-%3%.%4%.%5%/openssl-%6%.%7%.%8%/protobuf-%9%") % BOOST_PLATFORM % (sizeof(void*)*8) % (BOOST_VERSION / 100000) % ((BOOST_VERSION / 100) % 1000) % (BOOST_VERSION % 100) % (OPENSSL_VERSION_NUMBER >> 28) % ((OPENSSL_VERSION_NUMBER >> 20) & 0xF) % ((OPENSSL_VERSION_NUMBER >> 12) & 0xF) % google::protobuf::internal::VersionString(GOOGLE_PROTOBUF_VERSION) ).str(); - + //the actual work of this function starts here BOOST_LOG_SEV(log, info) << "Attempting to establish web socket connection with endpoint wss://" << tac.adapter_config.proxy_host << ":" << tac.adapter_config.proxy_port; @@ -940,7 +940,7 @@ namespace aws { namespace iot { namespace securedtunneling { //next do web socket upgrade - add two custom headers tac.wss->async_handshake_ex(tac.wss_response, tac.adapter_config.proxy_host.c_str(), - (boost::format("/tunnel?%1%=%2%")%PROXY_MODE_QUERY_PARAM % get_proxy_mode_string(tac.adapter_config.mode)).str(), + (boost::format("%1%?%2%=%3%")% tac.adapter_config.url_path.c_str() %PROXY_MODE_QUERY_PARAM % get_proxy_mode_string(tac.adapter_config.mode)).str(), [&](boost::beast::websocket::request_type &request) { request.set(boost::beast::http::field::sec_websocket_protocol, GET_SETTING(settings, WEB_SOCKET_SUBPROTOCOL)); @@ -1959,7 +1959,7 @@ namespace aws { namespace iot { namespace securedtunneling { std::uint16_t port_to_connect = boost::lexical_cast(src_port); BOOST_LOG_SEV(log, debug) << "Port to connect " << port_to_connect; server->resolver_.async_resolve(tac.bind_address_actual, src_port, - boost::asio::ip::resolver_base::passive, + boost::asio::ip::resolver_base::passive, [=, &tac](boost::system::error_code const &ec, tcp::resolver::results_type results) { if (ec) @@ -2122,7 +2122,7 @@ namespace aws { namespace iot { namespace securedtunneling { void tcp_adapter_proxy::async_setup_dest_tcp_socket(tcp_adapter_context &tac, string const & service_id, uint32_t const & connection_id, bool is_first_connection) { BOOST_LOG_SEV(log, trace) << "Setup destination tcp socket for service id" << service_id; - std::shared_ptr retry_config = + std::shared_ptr retry_config = std::make_shared(tac.io_ctx, GET_SETTING(settings, TCP_CONNECTION_RETRY_COUNT), GET_SETTING(settings, TCP_CONNECTION_RETRY_DELAY_MS), diff --git a/src/main.cpp b/src/main.cpp index 902e796..6b74c19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -161,6 +161,7 @@ bool process_cli(int argc, char ** argv, LocalproxyConfig &cfg, ptree &settings, ("access-token,t", value()->required(), "Client access token") ("client-token,i", value(), "Optional Client Token") ("proxy-endpoint,e", value(), "Endpoint of proxy server with port (if not default 443). Example: data.tunneling.iot.us-east-1.amazonaws.com:443") + ("endpoint-path,p", value()->default_value("/tunnel"), "Endpoint path of proxy server if need extra path. Example: reverse-proxy.domain.com/aws-data-service/tunnel, so you connect with -e reverse-proxy.domain.com -p /aws-data-service/tunnel") ("region,r", value(), "Endpoint region where tunnel exists. Mutually exclusive flag with --proxy-endpoint") ("source-listen-port,s", value(), "Sets the mappings between source listening ports and service identifier. Example: SSH1=5555 or 5555") ("destination-app,d", value(), "Sets the mappings between the endpoint(address:port/port) and service identifier. Example: SSH1=127.0.0.1:22 or 22") @@ -200,7 +201,7 @@ bool process_cli(int argc, char ** argv, LocalproxyConfig &cfg, ptree &settings, store(parse_config_file(vm["config"].as().c_str(), cliargs_desc), vm); } //either way, parse from environment - store(parse_environment(cliargs_desc, + store(parse_environment(cliargs_desc, [](std::string name) -> std::string { if (name == ACCESS_TOKEN_ENV_VARIABLE) @@ -234,6 +235,7 @@ bool process_cli(int argc, char ** argv, LocalproxyConfig &cfg, ptree &settings, BOOST_LOG_TRIVIAL(warning) << "Found access token supplied via CLI arg. Consider using environment variable " << ACCESS_TOKEN_ENV_VARIABLE << " instead"; } cfg.access_token = vm["access-token"].as(); + cfg.url_path = vm["endpoint-path"].as(); if (vm.count("client-token") != 0) {