├── .gitignore ├── .gitmodules ├── BUILD_CROSS.md ├── BUILD_UNIX.md ├── BUILD_WIN32.md ├── CHANGELOG.md ├── CMakeLists.txt ├── LICENSE.txt ├── README.md ├── builddeps ├── build_boost.bat ├── build_boost.sh ├── build_openssl.bat └── build_openssl.sh ├── certs ├── CMakeLists.txt ├── WARNING ├── certificate.crt ├── dh4096.pem ├── private.key ├── server.crt ├── server.key └── trusted │ ├── ca.crt │ ├── ca.key │ ├── ca.srl │ └── extfile.ext ├── cmake ├── arm-linux-gnueabihf.cmake ├── file2string.cmake ├── source_group_by_folder.cmake └── unit_tests.cmake ├── img ├── CMakeLists.txt ├── icon.icns ├── icon.ico └── icon.rc ├── src ├── CMakeLists.txt ├── client │ ├── CMakeLists.txt │ ├── ssf.cpp │ └── ssfcp.cpp ├── common │ ├── boost │ │ └── fiber │ │ │ ├── basic_endpoint.hpp │ │ │ ├── basic_fiber_demux.hpp │ │ │ ├── basic_fiber_demux_service.hpp │ │ │ ├── basic_fiber_demux_service.ipp │ │ │ ├── datagram_fiber.hpp │ │ │ ├── datagram_fiber_service.hpp │ │ │ ├── detail │ │ │ ├── basic_fiber_demux_impl.hpp │ │ │ ├── basic_fiber_impl.hpp │ │ │ ├── fiber_buffer.hpp │ │ │ ├── fiber_header.hpp │ │ │ ├── fiber_id.hpp │ │ │ ├── io_fiber_accept_op.hpp │ │ │ ├── io_fiber_dgr_read_op.hpp │ │ │ ├── io_fiber_read_op.hpp │ │ │ ├── io_operation.hpp │ │ │ └── io_ssl_read_op.hpp │ │ │ ├── fiber_acceptor_service.hpp │ │ │ ├── stream_fiber.hpp │ │ │ └── stream_fiber_service.hpp │ ├── config │ │ ├── circuit.cpp │ │ ├── circuit.h │ │ ├── config.cpp │ │ ├── config.h │ │ ├── proxy.cpp │ │ ├── proxy.h │ │ ├── services.cpp │ │ ├── services.h │ │ ├── tls.cpp │ │ ├── tls.h │ │ ├── unix_default_config.cpp │ │ └── win_default_config.cpp │ ├── crypto │ │ ├── hash.h │ │ ├── md5.cpp │ │ ├── md5.h │ │ ├── sha1.cpp │ │ ├── sha1.h │ │ ├── sha256.cpp │ │ └── sha256.h │ ├── error │ │ ├── error.cpp │ │ └── error.h │ ├── filesystem │ │ ├── filesystem.cpp │ │ ├── filesystem.h │ │ ├── path.cpp │ │ └── path.h │ └── utils │ │ └── to_underlying.h ├── compat │ ├── CMakeLists.txt │ ├── iob_func.cpp │ └── memcpy.cpp ├── core │ ├── async_engine.cpp │ ├── async_engine.h │ ├── client │ │ ├── client.cpp │ │ ├── client.h │ │ ├── client_helper.cpp │ │ ├── client_helper.h │ │ ├── session.h │ │ ├── session.ipp │ │ └── status.h │ ├── command_line │ │ ├── base.cpp │ │ ├── base.h │ │ ├── copy │ │ │ ├── command_line.cpp │ │ │ └── command_line.h │ │ ├── standard │ │ │ ├── command_line.cpp │ │ │ └── command_line.h │ │ └── user_service_option_factory.h │ ├── factories │ │ └── service_factory.h │ ├── factory_manager │ │ └── service_factory_manager.h │ ├── network_protocol.cpp │ ├── network_protocol.h │ ├── server │ │ ├── server.h │ │ └── server.ipp │ ├── service_manager │ │ └── service_manager.h │ └── transport_virtual_layer_policies │ │ ├── init_packets │ │ ├── ssf_reply.cpp │ │ ├── ssf_reply.h │ │ ├── ssf_request.cpp │ │ └── ssf_request.h │ │ └── transport_protocol_policy.h ├── network │ ├── CMakeLists.txt │ ├── ssf │ │ ├── error │ │ │ ├── error.h │ │ │ └── error.ipp │ │ ├── io │ │ │ ├── accept_op.h │ │ │ ├── buffers.h │ │ │ ├── composed_op.h │ │ │ ├── connect_op.h │ │ │ ├── get_op.h │ │ │ ├── handler_helpers.h │ │ │ ├── op.h │ │ │ ├── push_op.h │ │ │ ├── read_op.h │ │ │ ├── read_stream_op.h │ │ │ └── write_op.h │ │ ├── layer │ │ │ ├── accept_op.h │ │ │ ├── basic_empty_datagram.h │ │ │ ├── basic_empty_stream.h │ │ │ ├── basic_endpoint.h │ │ │ ├── basic_impl.h │ │ │ ├── basic_resolver.h │ │ │ ├── congestion │ │ │ │ └── drop_tail_policy.h │ │ │ ├── connect_op.h │ │ │ ├── cryptography │ │ │ │ ├── basic_crypto_stream.h │ │ │ │ ├── crypto_stream_op.h │ │ │ │ └── tls │ │ │ │ │ └── OpenSSL │ │ │ │ │ ├── helpers.cpp │ │ │ │ │ ├── helpers.h │ │ │ │ │ └── impl.h │ │ │ ├── data_link │ │ │ │ ├── basic_circuit_acceptor_service.h │ │ │ │ ├── basic_circuit_protocol.h │ │ │ │ ├── basic_circuit_socket_service.h │ │ │ │ ├── circuit_endpoint_context.h │ │ │ │ ├── circuit_helpers.cpp │ │ │ │ ├── circuit_helpers.h │ │ │ │ ├── circuit_op.h │ │ │ │ ├── helpers.h │ │ │ │ └── simple_circuit_policy.h │ │ │ ├── datagram │ │ │ │ ├── basic_datagram.h │ │ │ │ ├── basic_flags.h │ │ │ │ ├── basic_header.h │ │ │ │ ├── basic_payload.h │ │ │ │ └── empty_component.h │ │ │ ├── interface_layer │ │ │ │ ├── basic_interface.h │ │ │ │ ├── basic_interface_manager.h │ │ │ │ ├── basic_interface_protocol.cc │ │ │ │ ├── basic_interface_protocol.h │ │ │ │ ├── basic_interface_service.h │ │ │ │ ├── generic_interface_socket.h │ │ │ │ ├── interface_buffers.h │ │ │ │ └── specific_interface_socket.h │ │ │ ├── io_handler.h │ │ │ ├── multiplexing │ │ │ │ ├── basic_demultiplexer.h │ │ │ │ ├── basic_multiplexer.h │ │ │ │ ├── basic_multiplexer_protocol.h │ │ │ │ ├── basic_multiplexer_socket_service.h │ │ │ │ ├── demultiplexer_manager.h │ │ │ │ ├── multiplexer_manager.h │ │ │ │ ├── port_multiplex_id.h │ │ │ │ ├── protocol_and_port_multiplex_id.h │ │ │ │ └── protocol_multiplex_id.h │ │ │ ├── network │ │ │ │ ├── basic_network_protocol.h │ │ │ │ ├── basic_network_raw_socket_service.h │ │ │ │ ├── basic_network_socket_service.h │ │ │ │ └── network_id.h │ │ │ ├── parameters.cpp │ │ │ ├── parameters.h │ │ │ ├── physical │ │ │ │ ├── host.cpp │ │ │ │ ├── host.h │ │ │ │ ├── tcp.cpp │ │ │ │ ├── tcp.h │ │ │ │ ├── tcp_helpers.cpp │ │ │ │ ├── tcp_helpers.h │ │ │ │ ├── tlsotcp.h │ │ │ │ ├── udp.h │ │ │ │ ├── udp_helpers.cpp │ │ │ │ └── udp_helpers.h │ │ │ ├── protocol_attributes.h │ │ │ ├── proxy │ │ │ │ ├── auth_strategy.cpp │ │ │ │ ├── auth_strategy.h │ │ │ │ ├── base64.cpp │ │ │ │ ├── base64.h │ │ │ │ ├── basic_auth_strategy.cpp │ │ │ │ ├── basic_auth_strategy.h │ │ │ │ ├── basic_proxy_acceptor_service.h │ │ │ │ ├── basic_proxy_protocol.h │ │ │ │ ├── basic_proxy_socket_service.h │ │ │ │ ├── connect_op.h │ │ │ │ ├── digest_auth_strategy.cpp │ │ │ │ ├── digest_auth_strategy.h │ │ │ │ ├── http_connect_op.h │ │ │ │ ├── http_request.cpp │ │ │ │ ├── http_request.h │ │ │ │ ├── http_response.cpp │ │ │ │ ├── http_response.h │ │ │ │ ├── http_response_builder.cpp │ │ │ │ ├── http_response_builder.h │ │ │ │ ├── http_session_initializer.cpp │ │ │ │ ├── http_session_initializer.h │ │ │ │ ├── negotiate_auth_strategy.cpp │ │ │ │ ├── negotiate_auth_strategy.h │ │ │ │ ├── ntlm_auth_strategy.cpp │ │ │ │ ├── ntlm_auth_strategy.h │ │ │ │ ├── platform_auth_impl.h │ │ │ │ ├── proxy_endpoint_context.cpp │ │ │ │ ├── proxy_endpoint_context.h │ │ │ │ ├── proxy_helpers.cpp │ │ │ │ ├── proxy_helpers.h │ │ │ │ ├── socks4_strategy.cpp │ │ │ │ ├── socks4_strategy.h │ │ │ │ ├── socks5_strategy.cpp │ │ │ │ ├── socks5_strategy.h │ │ │ │ ├── socks_connect_op.h │ │ │ │ ├── socks_session_initializer.cpp │ │ │ │ ├── socks_session_initializer.h │ │ │ │ ├── socks_strategy.h │ │ │ │ ├── unix │ │ │ │ │ ├── gssapi_auth_impl.cpp │ │ │ │ │ └── gssapi_auth_impl.h │ │ │ │ └── windows │ │ │ │ │ ├── sspi_auth_impl.cpp │ │ │ │ │ └── sspi_auth_impl.h │ │ │ ├── queue │ │ │ │ ├── active_item.h │ │ │ │ ├── async_queue.h │ │ │ │ ├── async_queue_service.h │ │ │ │ ├── commutator.h │ │ │ │ ├── send_queued_datagram_socket.h │ │ │ │ └── tagged_item.h │ │ │ ├── receive_from_op.h │ │ │ └── routing │ │ │ │ ├── basic_routed_protocol.h │ │ │ │ ├── basic_routed_socket_service.h │ │ │ │ ├── basic_router.h │ │ │ │ ├── basic_router_service.h │ │ │ │ ├── basic_routing_selector.h │ │ │ │ └── basic_routing_table.h │ │ ├── log │ │ │ ├── log.cpp │ │ │ └── log.h │ │ ├── network │ │ │ ├── base_session.h │ │ │ ├── manager.h │ │ │ ├── object_io_helpers.h │ │ │ ├── session_forwarder.h │ │ │ ├── socket_link.h │ │ │ └── socks │ │ │ │ ├── socks.h │ │ │ │ ├── v4 │ │ │ │ ├── reply.cpp │ │ │ │ ├── reply.h │ │ │ │ ├── request.cpp │ │ │ │ └── request.h │ │ │ │ └── v5 │ │ │ │ ├── reply.cpp │ │ │ │ ├── reply.h │ │ │ │ ├── reply_auth.cpp │ │ │ │ ├── reply_auth.h │ │ │ │ ├── request.cpp │ │ │ │ ├── request.h │ │ │ │ ├── request_auth.cpp │ │ │ │ ├── request_auth.h │ │ │ │ └── types.h │ │ ├── system │ │ │ ├── basic_interfaces_collection.h │ │ │ ├── specific_interfaces_collection.h │ │ │ ├── system_interfaces.cpp │ │ │ ├── system_interfaces.h │ │ │ ├── system_routers.cpp │ │ │ └── system_routers.h │ │ └── utils │ │ │ ├── cleaner.h │ │ │ ├── enum.h │ │ │ └── map_helpers.h │ └── tests │ │ ├── CMakeLists.txt │ │ ├── circuit_test_fixture.h │ │ ├── datagram_protocol_helpers.h │ │ ├── interface_layer_tests.cpp │ │ ├── interface_protocol_helpers.h │ │ ├── interface_test_fixture.h │ │ ├── interfaces_system_tests.cpp │ │ ├── link_layer_tests.cpp │ │ ├── log_tests.cpp │ │ ├── physical_layer_tests.cpp │ │ ├── proxy │ │ ├── README.md │ │ └── proxy.json.dist │ │ ├── proxy_auth_strategies_tests.cpp │ │ ├── proxy_layer_tests.cpp │ │ ├── proxy_test_fixture.cpp │ │ ├── proxy_test_fixture.h │ │ ├── queue_tests.cpp │ │ ├── router_system_tests.cpp │ │ ├── routing_layer_tests.cpp │ │ ├── routing_test_fixture.h │ │ ├── stream_protocol_helpers.h │ │ ├── system │ │ ├── circuit_tlsotcp_accept1_config.json │ │ ├── circuit_tlsotcp_accept2_config.json │ │ ├── circuit_tlsotcp_accept3_config.json │ │ ├── circuit_tlsotcp_connect_config.json │ │ ├── fail_router_config.json │ │ ├── fail_tcp_accept_config.json │ │ ├── fail_tcp_connect_config.json │ │ ├── link_tcp_accept_config.json │ │ ├── link_tcp_connect_config.json │ │ ├── link_tlsotcp_accept_config.json │ │ ├── link_tlsotcp_connect_config.json │ │ ├── router_config.json │ │ ├── system_multiple_config.json │ │ ├── system_reconnect_config.json │ │ ├── tcp_accept_config.json │ │ ├── tcp_connect_config.json │ │ ├── tlsotcp_accept_config.json │ │ └── tlsotcp_connect_config.json │ │ ├── tools.h │ │ ├── transport_layer_tests.cpp │ │ ├── transport_test_fixture.h │ │ ├── virtual_network_helpers.cpp │ │ └── virtual_network_helpers.h ├── server │ ├── CMakeLists.txt │ └── ssfd.cpp ├── services │ ├── CMakeLists.txt │ ├── admin │ │ ├── admin.h │ │ ├── admin.ipp │ │ ├── admin_command.h │ │ ├── command_factory.h │ │ └── requests │ │ │ ├── create_service_request.h │ │ │ ├── service_status.h │ │ │ └── stop_service_request.h │ ├── base_service.h │ ├── base_service_config.cpp │ ├── base_service_config.h │ ├── copy │ │ ├── config.cpp │ │ ├── config.h │ │ ├── copy_client.h │ │ ├── copy_context.cpp │ │ ├── copy_context.h │ │ ├── copy_server.h │ │ ├── copy_session.h │ │ ├── error_code.cpp │ │ ├── error_code.h │ │ ├── file_acceptor.h │ │ ├── file_sender.h │ │ ├── i_copy_state.h │ │ ├── packet.cpp │ │ ├── packet.h │ │ ├── packet │ │ │ ├── check.h │ │ │ ├── control.h │ │ │ ├── data.h │ │ │ ├── error.h │ │ │ ├── error_code.h │ │ │ └── init.h │ │ ├── packet_helper.h │ │ └── state │ │ │ ├── on_abort.cpp │ │ │ ├── on_abort.h │ │ │ ├── receiver │ │ │ ├── abort_receiver_state.h │ │ │ ├── receive_file_state.h │ │ │ ├── send_abort_ack_state.h │ │ │ ├── send_eof_state.h │ │ │ ├── send_init_reply_state.h │ │ │ ├── send_integrity_check_reply_state.h │ │ │ ├── wait_close_state.h │ │ │ ├── wait_init_request_state.h │ │ │ └── wait_integrity_check_request_state.h │ │ │ └── sender │ │ │ ├── abort_sender_state.h │ │ │ ├── close_state.h │ │ │ ├── send_file_state.h │ │ │ ├── send_init_request_state.h │ │ │ ├── send_integrity_check_request_state.h │ │ │ ├── wait_abort_ack_state.h │ │ │ ├── wait_eof_state.h │ │ │ ├── wait_init_reply_state.h │ │ │ └── wait_integrity_check_reply_state.h │ ├── datagram │ │ ├── datagram_link.h │ │ └── datagram_link_operator.h │ ├── datagrams_to_fibers │ │ ├── config.cpp │ │ ├── config.h │ │ ├── datagrams_to_fibers.h │ │ └── datagrams_to_fibers.ipp │ ├── fibers_to_datagrams │ │ ├── config.cpp │ │ ├── config.h │ │ ├── fibers_to_datagrams.h │ │ └── fibers_to_datagrams.ipp │ ├── fibers_to_sockets │ │ ├── config.cpp │ │ ├── config.h │ │ ├── fibers_to_sockets.h │ │ ├── fibers_to_sockets.ipp │ │ └── session.h │ ├── process │ │ ├── config.cpp │ │ ├── config.h │ │ ├── posix │ │ │ ├── session.h │ │ │ └── session.ipp │ │ ├── server.h │ │ ├── server.ipp │ │ └── windows │ │ │ ├── session.h │ │ │ └── session.ipp │ ├── service_id.h │ ├── service_port.h │ ├── sockets_to_fibers │ │ ├── config.cpp │ │ ├── config.h │ │ ├── session.h │ │ ├── sockets_to_fibers.h │ │ └── sockets_to_fibers.ipp │ ├── socks │ │ ├── config.cpp │ │ ├── config.h │ │ ├── socks_server.h │ │ ├── socks_server.ipp │ │ ├── socks_version.h │ │ ├── v4 │ │ │ ├── session.h │ │ │ └── session.ipp │ │ └── v5 │ │ │ ├── session.h │ │ │ └── session.ipp │ ├── user_service_factory.h │ └── user_services │ │ ├── base_user_service.h │ │ ├── copy.h │ │ ├── option_parser.cpp │ │ ├── option_parser.h │ │ ├── parameters.h │ │ ├── port_forwarding.h │ │ ├── remote_port_forwarding.h │ │ ├── remote_shell.h │ │ ├── remote_socks.h │ │ ├── remote_udp_port_forwarding.h │ │ ├── shell.h │ │ ├── socks.h │ │ └── udp_port_forwarding.h ├── tests │ ├── CMakeLists.txt │ ├── commandline │ │ ├── CMakeLists.txt │ │ └── commandline_tests.cpp │ ├── config │ │ ├── CMakeLists.txt │ │ ├── config_files │ │ │ ├── arguments.json │ │ │ ├── circuit.json │ │ │ ├── complete.json │ │ │ ├── empty.json │ │ │ ├── proxy.json │ │ │ ├── services.json │ │ │ ├── tls_buffer.json │ │ │ ├── tls_complete.json │ │ │ ├── tls_partial.json │ │ │ └── wrong_format.json │ │ └── load_config_tests.cpp │ ├── filesystem │ │ ├── CMakeLists.txt │ │ └── filesystem_tests.cpp │ ├── network │ │ ├── CMakeLists.txt │ │ ├── circuit_tests.cpp │ │ ├── fiber_asio_tests.cpp │ │ ├── ssf_client_server_cipher_suites_tests.cpp │ │ ├── ssf_client_server_tests.cpp │ │ ├── ssf_client_tests.cpp │ │ ├── ssf_fixture_test.cpp │ │ ├── ssf_fixture_test.h │ │ └── ssf_server_tests.cpp │ ├── services │ │ ├── CMakeLists.txt │ │ ├── copy_fixture_test.cpp │ │ ├── copy_fixture_test.h │ │ ├── copy_tests.cpp │ │ ├── datagram_fixture_test.h │ │ ├── datagram_forward_tests.cpp │ │ ├── files_to_copy │ │ │ ├── test_file1.txt │ │ │ └── test_file2.txt │ │ ├── option_parser_tests.cpp │ │ ├── remote_datagram_forward_tests.cpp │ │ ├── remote_shell_tests.cpp │ │ ├── remote_socks_tests.cpp │ │ ├── remote_stream_forwarding_tests.cpp │ │ ├── service_fixture_test.h │ │ ├── shell_fixture_test.h │ │ ├── shell_tests.cpp │ │ ├── socks_fixture_test.h │ │ ├── socks_helpers.cpp │ │ ├── socks_helpers.h │ │ ├── socks_tests.cpp │ │ ├── stream_fixture_test.h │ │ ├── stream_forwarding_tests.cpp │ │ ├── tcp_helpers.cpp │ │ ├── tcp_helpers.h │ │ ├── udp_helpers.cpp │ │ └── udp_helpers.h │ ├── tls_config_helper.cpp │ └── tls_config_helper.h └── versions.h.in ├── third_party ├── http-parser │ └── CMakeLists.txt ├── json │ └── CMakeLists.txt ├── msgpack │ └── CMakeLists.txt └── spdlog │ └── CMakeLists.txt └── tools ├── generate_unix_release.sh └── generate_win_release.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | src/framework/tests/proxy/proxy.json 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/http-parser/http-parser"] 2 | path = third_party/http-parser/http-parser 3 | url = https://github.com/nodejs/http-parser.git 4 | [submodule "third_party/googletest"] 5 | path = third_party/googletest 6 | url = https://github.com/google/googletest.git 7 | [submodule "third_party/msgpack/msgpack-c"] 8 | path = third_party/msgpack/msgpack-c 9 | url = https://github.com/msgpack/msgpack-c.git 10 | [submodule "third_party/spdlog/spdlog"] 11 | path = third_party/spdlog/spdlog 12 | url = https://github.com/gabime/spdlog.git 13 | [submodule "third_party/cxxopts"] 14 | path = third_party/cxxopts 15 | url = https://github.com/jarro2783/cxxopts.git 16 | [submodule "third_party/json/json"] 17 | path = third_party/json/json 18 | url = https://github.com/nlohmann/json.git 19 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 SSF 2 | 3 | This software is using: 4 | * Boost project released with Boost Software License 1.0 5 | * OpenSSL project released with OpenSSL License and SSLeay License 6 | * Google Test project released with BSD 3-Clause license 7 | * CMake modules project released with Boost Software License 1.0 8 | * HTTP Parser project released with MIT license 9 | * cxxopts project released with MIT license 10 | * spdlog project released with MIT license 11 | * msgpack-c project released with Boost Software License 1.0 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in 21 | all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | THE SOFTWARE. 30 | -------------------------------------------------------------------------------- /builddeps/build_boost.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | setlocal enabledelayedexpansion 4 | 5 | set BOOST_LIBRARIES=system,date_time,filesystem,thread,chrono 6 | 7 | if "%3"=="32" ( 8 | set ARCH=32 9 | ) 10 | if "%3"=="64" ( 11 | set ARCH=64 12 | ) 13 | 14 | if not "%ARCH%"=="" ( 15 | if not "%4"=="" goto start 16 | ) 17 | 18 | echo Usage: %0 boost_archive_path boost_version [32^|64] destination_dir 1>&2 19 | exit /B 1 20 | 21 | :start 22 | set WORKING_DIR=%cd% 23 | set BOOST_ARCHIVE=%~f1 24 | set BOOST_VERSION=%2 25 | set BOOST_SOURCE=%cd%\boost_%BOOST_VERSION% 26 | echo Using Boost archive %BOOST_ARCHIVE% (%BOOST_VERSION%) into %BOOST_SOURCE% 27 | set DIST_DIR=%~f4 28 | echo Destination dir: %DIST_DIR% 29 | set BASE_DIR=%~dp0 30 | set BOOST_BUILD_DIR=%cd%\boost.build%ARCH% 31 | set BOOST_STAGE_DIR=%cd%\boost.stage%ARCH% 32 | 33 | set PATH=%PATH%;C:\Program Files\7-Zip 34 | 35 | if not exist %BOOST_SOURCE% ( 36 | echo [*] Decompressing %BOOST_ARCHIVE% 37 | 7z x -so %BOOST_ARCHIVE% | 7z x -si -aoa -ttar 38 | ) 39 | 40 | if not exist %BOOST_SOURCE%/b2.exe ( 41 | echo [*] Bootstrapping Boost 42 | cd /D %BOOST_SOURCE% 43 | call bootstrap.bat 44 | ) 45 | 46 | echo [*] Building Boost 47 | 48 | set B2_ARGS=--build-dir=%BOOST_BUILD_DIR% --stagedir=%BOOST_STAGE_DIR% -j%NUMBER_OF_PROCESSORS% 49 | for %%l in (%BOOST_LIBRARIES%) do ( 50 | set B2_ARGS=!B2_ARGS! --with-%%l 51 | ) 52 | set B2_ARGS=!B2_ARGS! link=static runtime-link=static variant=debug,release address-model=%ARCH% cxxflags="-GR-" 53 | if "%ARCH%"=="32" ( 54 | set B2_ARGS=!B2_ARGS! asmflags=\safeseh 55 | ) 56 | 57 | cd /D %BOOST_SOURCE% 58 | mkdir %BOOST_BUILD_DIR% 2> NUL 59 | b2.exe %B2_ARGS% --prefix=%DIST_DIR% stage install 60 | 61 | cd /D %WORKING_DIR% -------------------------------------------------------------------------------- /builddeps/build_boost.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BOOST_LIBRARIES="system date_time filesystem thread chrono" 4 | 5 | if [ $# -lt 3 ]; then 6 | echo "Usage: $0 boost_archive boost_version destination_dir [32|64]" 1>&2 7 | exit 1 8 | fi 9 | 10 | variant=${VARIANT:-debug} 11 | arch=$(${CROSS_PREFIX}g++ -dumpmachine | cut -d '-' -f 1) 12 | 13 | BOOST_ARCHIVE=$(realpath $1) 14 | BOOST_VERSION=$2 15 | BOOST_SOURCE=boost_${BOOST_VERSION} 16 | DIST_DIR=$(realpath $3) 17 | address_model=$4 18 | 19 | BOOST_BUILD_DIR=$(realpath .)/boost.build 20 | BOOST_STAGE_DIR=$(realpath .)/boost.stage 21 | 22 | cores=$(nproc 2> /dev/null || echo 1) 23 | 24 | if [ ! -d ${BOOST_SOURCE} ]; then 25 | echo "[*] Decompressing ${BOOST_ARCHIVE}" 26 | bzip2 -d ${BOOST_ARCHIVE} -c | tar xv 27 | fi 28 | 29 | if [ ! -x ${BOOST_SOURCE}/b2 ]; then 30 | echo "[*] Bootstrapping Boost" 31 | (cd ${BOOST_SOURCE} && sh bootstrap.sh) 32 | fi 33 | 34 | sed -i.old "s/using gcc \(.*\); $/using gcc : ${arch} : ${CROSS_PREFIX}g++ ; /" ${BOOST_SOURCE}/project-config.jam 35 | 36 | echo "[*] Building Boost" 37 | B2_ARGS="--build-dir=${BOOST_BUILD_DIR} --stagedir=${BOOST_STAGE_DIR} -j ${cores}" 38 | for l in ${BOOST_LIBRARIES}; do 39 | B2_ARGS="${B2_ARGS} --with-${l}" 40 | done 41 | if [ "${address_model}" != "" ]; then 42 | B2_ARGS="${B2_ARGS} address-model=${address_model}" 43 | fi 44 | B2_ARGS="${B2_ARGS} toolset=gcc-${arch} link=static runtime-link=static variant=${variant} cxxflags=-fno-rtti" 45 | 46 | (cd ${BOOST_SOURCE} && ./b2 ${B2_ARGS} --prefix=${DIST_DIR} stage install) 47 | -------------------------------------------------------------------------------- /builddeps/build_openssl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ $# -lt 3 ]; then 4 | echo "Usage: $0 openssl_archive openssl_version destination_dir [32]" 1>&2 5 | exit 1 6 | fi 7 | 8 | OPENSSL_ARCHIVE=$(realpath $1) 9 | OPENSSL_VERSION=$2 10 | OPENSSL_SOURCE=openssl-${OPENSSL_VERSION} 11 | DIST_DIR=$(realpath $3) 12 | 13 | if [ ! -d ${OPENSSL_SOURCE} ]; then 14 | echo "[*] Decompressing ${OPENSSL_ARCHIVE}" 15 | gzip -d ${OPENSSL_ARCHIVE} -c | tar xv 16 | fi 17 | 18 | CONFIG_ARGS="--prefix=${DIST_DIR} no-shared no-err -DOPENSSLDIR=\"\" -DENGINESDIR=\"\"" 19 | 20 | if [ "${CROSS_PREFIX}" = "" ]; then 21 | if [ "$4" = "32" ]; then 22 | (cd ${OPENSSL_SOURCE} && perl Configure ${CONFIG_ARGS} -m32 linux-generic32) 23 | else 24 | (cd ${OPENSSL_SOURCE} && sh ./config ${CONFIG_ARGS}) 25 | fi 26 | else 27 | arch=$(${CROSS_PREFIX}g++ -dumpmachine | cut -d '-' -f 1) 28 | case "${arch}" in 29 | mips) 30 | os_comp=linux-mips32 31 | ;; 32 | arm) 33 | os_comp=linux-armv4 34 | ;; 35 | *) 36 | echo "Cross-compiling currently unsupported for architecture: ${arch}" 2>&1 37 | exit 1 38 | ;; 39 | esac 40 | (cd ${OPENSSL_SOURCE} && perl Configure --cross-compile-prefix=${CROSS_PREFIX} ${CONFIG_ARGS} ${os_comp}) 41 | fi 42 | 43 | (cd ${OPENSSL_SOURCE} && make all install_sw) 44 | -------------------------------------------------------------------------------- /certs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(TEST_CERT_FILES ${CMAKE_CURRENT_SOURCE_DIR}/certificate.crt 2 | ${CMAKE_CURRENT_SOURCE_DIR}/private.key 3 | ${CMAKE_CURRENT_SOURCE_DIR}/server.crt 4 | ${CMAKE_CURRENT_SOURCE_DIR}/server.key 5 | ${CMAKE_CURRENT_SOURCE_DIR}/dh4096.pem PARENT_SCOPE) 6 | set(TEST_CERT_TRUSTED_FILES ${CMAKE_CURRENT_SOURCE_DIR}/trusted/ca.crt PARENT_SCOPE) 7 | 8 | function(copy_certs _tgt) 9 | add_custom_command(TARGET ${_tgt} POST_BUILD 10 | COMMAND ${CMAKE_COMMAND} -E make_directory $/certs/trusted 11 | COMMAND ${CMAKE_COMMAND} -E copy ${TEST_CERT_FILES} $/certs 12 | COMMAND ${CMAKE_COMMAND} -E copy ${TEST_CERT_TRUSTED_FILES} $/certs/trusted) 13 | endfunction(copy_certs) 14 | 15 | include(file2string) 16 | 17 | file2string(test_client_cert certificate.crt client_cert.h) 18 | file2string(test_client_key private.key client_key.h) 19 | file2string(test_server_cert server.crt server_cert.h) 20 | file2string(test_server_key server.key server_key.h) 21 | file2string(test_server_dh_param dh4096.pem server_dh_param.h) 22 | file2string(test_ca_cert trusted/ca.crt ca_cert.h) 23 | 24 | add_library(test_certs INTERFACE) 25 | target_include_directories(test_certs INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) 26 | -------------------------------------------------------------------------------- /certs/WARNING: -------------------------------------------------------------------------------- 1 | These certificates are provided for test purpose only. 2 | You should generate your own certificates as explained in the website. -------------------------------------------------------------------------------- /certs/dh4096.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN DH PARAMETERS----- 2 | MIICCAKCAgEAseqOk+DzWryjmv42VdCyQ+7xOyzM5hq9fLpAuM5OWzl0ieTuKs7D 3 | oDbYiWW61FwPupMThl1O7Sp6N2eFqsppnRDuR9ZGMHbEjJQCHwwQzWlXyB1u5xv9 4 | IOIxIZPXiR7IT22xGiB2YjS7oMZguRaAQWys8SG7N5eKeQ30G8FS+DZmS4wEGUac 5 | Ah1qysta4pzyWeQNUDgwghyT+EsTrdTUuWt6ebbnIHnKbr3FQVs6SVZlp2IEun3V 6 | 4WrTs19tt2nwxn4Ttig+9/WHePgmxYzMM3KImJNEOO3iDwl7w0sJp3j5RGW5Dh/C 7 | vVNtlbo1wZIWLVZTFBTlwVFVCMSRMoghwLoG5hC4GyQVT8rdj+zn0+VLXKCqyDXg 8 | e3YzqnbMBeI1sp2ai4RFjd+d0jt1mXOaGXNV4dYSyQh6+7AFzptDwsSZ7/kfr/SY 9 | w0xtMu/vqcj8TnQO8Lq3s2Et1oF+MFbh/kWCagYLcXG1eD8Lmxi104NwRMQYTsUz 10 | IRcjLN5xdI2CtQVIbg1zdC3+Ciu+xJXfg1fYK9ZLBst31Pj/ZUaJlR0IOumboE4k 11 | obGA87LOAbXB5LfTj7hROOhn4/NJLj/CHXXCPpXixE890Z5wo2f/PG+4umL4DTkK 12 | hr/xGr7EJr1iLuv8ulDaApPR4MYbfEOUwpo3oqBRJFh1m5gahndmtqMCAQI= 13 | -----END DH PARAMETERS----- 14 | -------------------------------------------------------------------------------- /certs/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFRTCCAy2gAwIBAgIJAK8e45jVbgd/MA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV 3 | BAYTAkJFMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxCzAJBgNVBAMTAkNBMB4XDTE3MDEyNzEzMTYzN1oXDTI3 5 | MDEyNTEzMTYzN1owVjELMAkGA1UEBhMCQkUxEzARBgNVBAgMClNvbWUtU3RhdGUx 6 | ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGU2Vy 7 | dmVyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvk2u8gG75eSrrtmN 8 | Yy9y52MFSLo81X322cs3m5jHT4N2Rm0ouGCsetD2zOhMkXUtsaWEIflVqc7Js1BL 9 | skxHcHerYgxkqBjs3sEWAS71xlbksdAexLw7l32a5WSAXKUl01MCROJ0R+Yb2xP5 10 | crG/nZcPB/zHhcyaQqEMZHKtp9180g13Qr9B+2fVp8FgHeGtF4NgXsuilPckny6g 11 | 6gac8aiy0pJ50KAmdlBwPuax8/gvMLEQhF6aHV9h2rXLg+d+QbScctRz4mm2X4si 12 | QJczV4+DsVyp8NqPNgpU+ht/X3VpDm4X+kohAOJE+z9oZ4G5CMw7Mdo8ZgFkvly1 13 | 6LtFhxVmHFVPla3PtOFxgo4npDVu9IKAYVEJYQ6w3GSTRaXnWm/TKSQPQWQEGnLO 14 | GltWjCXrcjkprrRmb3fBjpwEGCDXcDxtGc3A0hWIoyhktyHthCyoeEuyTMoUzyUB 15 | MndZCyd4sJPUjK+yHuO/vlEMe14aVmKpMfv3+of/dgvBlM6Oqx920tCnnB7paupU 16 | GNNxC8BNyaOj76P7DEmwJ+ZjeJwfO04jM0QZyS0CIXoDPsmkWRnBmNNxqfUNOA4k 17 | jeXZ0krlhnIeUODEiZ06wg/yBK6Q98Y1c+JR9hlKtWjUEawp/ZAfzR2N12zx9hgz 18 | sTkuWmACmBSU5rMLuntoSTqtBx8CAwEAAaMaMBgwCQYDVR0TBAIwADALBgNVHQ8E 19 | BAMCBeAwDQYJKoZIhvcNAQEFBQADggIBAJiJy9To/IWujFM9oSMWv0kDMHjj/VRs 20 | Sfh8ayYcHonIY0uom1FhKc1jXSFJywQZIiSnKDIaOVls50FOeLHeQQJwR0JzeUGx 21 | 3gRkh4wTBJV/nNd1OzQC0XPsKWDPhIT59ADOBL3F9aIYpINmENrjHyqesM8YiSH9 22 | hgkx4ZPqEdYqGOAYr138DldOXMyotxcYA1mds/ZLG1flmi0WkyoOSegzpxIsY0OA 23 | fMDz0Q+1XOmuxD76SofigkccDMXq1GZBU8ZppVRoLiZkLu0gEFZxLyTTlAC9ZWZS 24 | PczrLW0T6tu70lm3VKTeHDwmMoTfjv5zpSS8zFf3lE9AEtK/r1HmiwAV8mB1vsRf 25 | ULaKHcjbclJswiB1hrW3Sn0bpWfwuSS/6CO7L23NjKhM41fxd6qjlDJFYuxaOcQZ 26 | 9K9Vs+BrWRGoDXo1GdVqRk1RbZDVGNiSNuM43RzKCMjsIA4P7in71rtGHvIexBTp 27 | 7q2dAyMgDHlKTy+bVc/NyBdYjfPI87vB/SNgFPPwlJl5N8fBelbl1lO0A1I6kVul 28 | Rn5XD4wXW2R2KE3uIJWf7vsdOEPN0GP+OO7h0S5STHkasIXnM9PUxA1Ytrg+xX2h 29 | N7vYM4AEvTl2cYOZLc5/AVo+KgQV8zBohrB+hw4L1ksKz6+XQFEHKqIi0i3aWNDK 30 | q4SabXH0i9kd 31 | -----END CERTIFICATE----- 32 | -------------------------------------------------------------------------------- /certs/trusted/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIF3TCCA8WgAwIBAgIJAPrG1z5hkxBBMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV 3 | BAYTAkJFMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxCzAJBgNVBAMTAkNBMB4XDTE1MDYwMTAxMTgwMVoXDTI1 5 | MDUyOTAxMTgwMVowUjELMAkGA1UEBhMCQkUxEzARBgNVBAgTClNvbWUtU3RhdGUx 6 | ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDELMAkGA1UEAxMCQ0Ew 7 | ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDmT2S1frBI4532bASwbuNH 8 | gK5dlSv9PbpvEPTL8G4t4SMBTNXSMr2ScXZC0SRppTgrEyvK2P85YKaUucnX4T7R 9 | r2i36j+UPC+509Oh+J9yp9TdBulNgM0VNiJCns+UFC2dRHVR7/0UX850YUhazISF 10 | DeC8cnrDs4VZiImeDDGlFDUFfoHU7IX8ta/NWFc6cYHoDk2/Ye+FBJ1RM4iw7n5D 11 | jW8sdTM886GaCjlyLt2R0iY9lVQnuAuMn/TzWCE86TWfpgYZz2uiBIs7ZhOckv37 12 | 2Mij7D12kKG882StT2jqihMz1ncCkKquWdQoXZs+sTQfvlS9SKCTvIog4aMbBvIM 13 | fzUkFUJMxAk0CBe49OFOdfNw7eTES7TuI90D08WB5cPBOrBLS66xAdw7DFIT49dx 14 | A9tQTqzgp5wfyQUW6RhNiygNeamIY7HwPFQsFC7WKwIfYcXQWQAZDS0YdSXSvrqS 15 | 2paoilVfxLsi1SM2NdiQudUIbTPYAblAlP7Mbe90QizzeDbLgEJw5Anapyksw2SP 16 | wyLSVM5uXFy/KS9fYAyBmSr0XEaTS7SC76uHPJa4Iffv+gKzJkB/UWNbz39PSF+R 17 | Xuz/Dvc7DskOPnkZcm4KZtOiS/dzB/B8+0EWhFn6n2mIlq2eGwwXf62XFeUiQ0wo 18 | zrzQRWoSUF6XiqZnU6SZ7wIDAQABo4G1MIGyMB0GA1UdDgQWBBRRdZlEXKYtmKsW 19 | 5HmAxoSyKH/YMjCBggYDVR0jBHsweYAUUXWZRFymLZirFuR5gMaEsih/2DKhVqRU 20 | MFIxCzAJBgNVBAYTAkJFMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJ 21 | bnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxCzAJBgNVBAMTAkNBggkA+sbXPmGTEEEw 22 | DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAgEAmDjjNo2bLDoFeMhLGcV6 23 | 1F4ZdB1wWJvfufGmFjHGjXTlgXA5u/L+fz1LqLqMoQHRxUczL0ZgE+8JwXaWsqdY 24 | Wnz8F1h6u0HZemWb5YlaNDeHCrTcb4Xi8SS6A0AbEdL2M6ydOOxtjtDCTMxrTAAP 25 | mDVJN9Kfl7+kmgjuAWbVdeRSP0sKVqocCGmENX61tWaT9zappUb9l6wxe7J48geu 26 | bN8Q6hAzarrqdQFvNG8DkZkizHKXwGVO0v9SuFhRy8nGb41OCHiRbLunzkQbJfwC 27 | WOL9kfH/u9R11Eli8Wq2A0pEOb7zx5m1B+RRhlBtOpXgsRpJaGrNBrj6ATa2gc0X 28 | vU4f9aIr/urHKu1FO/q1K4D+yelS7E87HohXdMmnhKNYl3L/Y1ylQnDVwXb3uGK5 29 | HeWIf0EvcgPPQdabReQgh2Ybn40Ec5txtlkfQXQ76VBOosEZ+Kbep50J1szt5wrJ 30 | e5MqhZIxvTSVwW3iwt2v2VYLzGX+zCcPaXFCVlEelLVF4VGXOxzm4pMmoBWe/0+B 31 | JJkQoO0B8PWaDHIjxQTCHo8enBf1yWUOTBysuL+HA8rZ0VC5OOVvHWeqS5C3jlYa 32 | lph+bp6iO/FAoIeigorNWkDQrmNqH6F+37i9Jse8vrPsbtxA1YwYfKeIDxO6CMHH 33 | 1aDJ/d7Oqd2Bda1uHMKMm4Y= 34 | -----END CERTIFICATE----- 35 | -------------------------------------------------------------------------------- /certs/trusted/ca.srl: -------------------------------------------------------------------------------- 1 | AF1EE398D56E077E 2 | -------------------------------------------------------------------------------- /certs/trusted/extfile.ext: -------------------------------------------------------------------------------- 1 | [ v3_req_p ] 2 | basicConstraints = CA:FALSE 3 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment 4 | 5 | [ v3_ca_p ] 6 | basicConstraints = CA:TRUE 7 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment, keyCertSign 8 | -------------------------------------------------------------------------------- /cmake/arm-linux-gnueabihf.cmake: -------------------------------------------------------------------------------- 1 | include(CMakeForceCompiler) 2 | set(CMAKE_SYSTEM_NAME Linux) 3 | CMAKE_FORCE_C_COMPILER(arm-linux-gnueabihf-gcc GNU) 4 | CMAKE_FORCE_CXX_COMPILER(arm-linux-gnueabihf-g++ GNU) 5 | set(CMAKE_SIZEOF_VOID_P 4) 6 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14") 7 | -------------------------------------------------------------------------------- /cmake/file2string.cmake: -------------------------------------------------------------------------------- 1 | function(file2string varname input output) 2 | get_filename_component(output ${output} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}) 3 | message(STATUS "Generating define header file ${output} from file ${input}") 4 | file(READ ${input} _data_ascii) 5 | 6 | string(TOUPPER ${varname} upper_varname) 7 | file(WRITE ${output} "const char ${upper_varname}[] = R\"RAWSTRING(${_data_ascii})RAWSTRING\";") 8 | endfunction(file2string) 9 | -------------------------------------------------------------------------------- /cmake/source_group_by_folder.cmake: -------------------------------------------------------------------------------- 1 | macro(source_group_by_folder target) 2 | set(SOURCE_GROUP_DELIMITER "/") 3 | 4 | get_target_property(target_src ${target} SOURCES) 5 | 6 | set(last_dir "") 7 | set(dir_files "") 8 | 9 | foreach(file ${target_src}) 10 | get_filename_component(dir "${file}" PATH) 11 | if (NOT "${dir}" STREQUAL "${last_dir}") 12 | if (dir_files) 13 | source_group("${last_dir}" FILES ${dir_files}) 14 | endif (dir_files) 15 | set(dir_files "") 16 | endif (NOT "${dir}" STREQUAL "${last_dir}") 17 | set(dir_files ${dir_files} ${file}) 18 | set(last_dir "${dir}") 19 | endforeach(file) 20 | 21 | if (files) 22 | source_group("${last_dir}" FILES ${files}) 23 | endif (files) 24 | endmacro(source_group_by_folder) 25 | 26 | -------------------------------------------------------------------------------- /cmake/unit_tests.cmake: -------------------------------------------------------------------------------- 1 | enable_testing() 2 | 3 | add_library(gtest STATIC EXCLUDE_FROM_ALL third_party/googletest/googletest/src/gtest-all.cc) 4 | if(UNIX) 5 | target_link_libraries(gtest PUBLIC pthread) 6 | endif(UNIX) 7 | add_library(gtest_main STATIC EXCLUDE_FROM_ALL third_party/googletest/googletest/src/gtest_main.cc) 8 | target_link_libraries(gtest_main gtest) 9 | target_include_directories(gtest 10 | PRIVATE ${CMAKE_SOURCE_DIR}/third_party/googletest/googletest 11 | PUBLIC ${CMAKE_SOURCE_DIR}/third_party/googletest/googletest/include 12 | ) 13 | target_include_directories(gtest_main 14 | PRIVATE ${CMAKE_SOURCE_DIR}/third_party/googletest/googletest 15 | PUBLIC ${CMAKE_SOURCE_DIR}/third_party/googletest/googletest/include 16 | ) 17 | set_property(TARGET gtest PROPERTY FOLDER "Unit Tests") 18 | set_property(TARGET gtest_main PROPERTY FOLDER "Unit Tests") 19 | 20 | add_custom_target(build_tests ALL) 21 | 22 | function(add_unit_test targetname) 23 | message(STATUS "Registering unit test ${targetname}") 24 | 25 | add_dependencies(build_tests ${targetname}) 26 | 27 | if (TARGET gtest_main) 28 | target_link_libraries(${targetname} gtest_main) 29 | endif() 30 | 31 | add_test(NAME ${targetname} 32 | COMMAND ${targetname} --gtest_output=xml:${CMAKE_BINARY_DIR}/gtest_reports/${targetname}.xml) 33 | endfunction(add_unit_test) 34 | -------------------------------------------------------------------------------- /img/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(ICON_RC ${CMAKE_CURRENT_SOURCE_DIR}/icon.rc PARENT_SCOPE) 2 | -------------------------------------------------------------------------------- /img/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securesocketfunneling/ssf/2caaaab4ef8def710f960b8ea96937f6a80fe060/img/icon.icns -------------------------------------------------------------------------------- /img/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securesocketfunneling/ssf/2caaaab4ef8def710f960b8ea96937f6a80fe060/img/icon.ico -------------------------------------------------------------------------------- /img/icon.rc: -------------------------------------------------------------------------------- 1 | IDR_MAINFRAME ICON DISCARDABLE "icon.ico" -------------------------------------------------------------------------------- /src/client/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(ssf ssf.cpp ${ICON_RC}) 2 | target_link_libraries(ssf ssf_framework) 3 | set_property(TARGET ssf PROPERTY FOLDER "Executables") 4 | copy_certs(ssf) 5 | 6 | add_executable(ssfcp ssfcp.cpp ${ICON_RC}) 7 | target_link_libraries(ssfcp ssf_framework) 8 | set_property(TARGET ssfcp PROPERTY FOLDER "Executables") 9 | copy_certs(ssfcp) 10 | 11 | install(TARGETS ssf ssfcp RUNTIME DESTINATION bin) 12 | -------------------------------------------------------------------------------- /src/common/config/circuit.cpp: -------------------------------------------------------------------------------- 1 | #include "common/config/circuit.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace ssf { 8 | namespace config { 9 | 10 | CircuitNode::CircuitNode(const std::string& addr, const std::string& port) 11 | : addr_(addr), port_(port) {} 12 | 13 | Circuit::Circuit() : nodes_() {} 14 | 15 | void Circuit::Update(const Json& json) { 16 | for (const auto& child : json) { 17 | if (child.count("host") == 1 && child.count("port") == 1) { 18 | std::string host(child.at("host").get()); 19 | std::string port(child.at("port").get()); 20 | boost::trim(host); 21 | boost::trim(port); 22 | nodes_.emplace_back(host, port); 23 | } 24 | } 25 | } 26 | 27 | void Circuit::Log() const { 28 | if (nodes_.size() == 0) { 29 | SSF_LOG("config", info, "[circuit] "); 30 | return; 31 | } 32 | 33 | unsigned int i = 0; 34 | for (const auto& node : nodes_) { 35 | ++i; 36 | SSF_LOG("config", info, "[circuit] {}. <{}:{}>", std::to_string(i), 37 | node.addr(), node.port()); 38 | } 39 | } 40 | 41 | } // config 42 | } // ssf 43 | -------------------------------------------------------------------------------- /src/common/config/circuit.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_COMMON_CONFIG_CIRCUIT_H_ 2 | #define SSF_COMMON_CONFIG_CIRCUIT_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace ssf { 10 | namespace config { 11 | 12 | class CircuitNode { 13 | public: 14 | CircuitNode(const std::string& addr, const std::string& port); 15 | 16 | public: 17 | inline std::string addr() const { return addr_; } 18 | inline void set_addr(const std::string& addr) { addr_ = addr; } 19 | 20 | inline std::string port() const { return port_; } 21 | inline void set_port(const std::string& port) { port_ = port; } 22 | 23 | private: 24 | std::string addr_; 25 | std::string port_; 26 | }; 27 | 28 | using NodeList = std::list; 29 | 30 | class Circuit { 31 | public: 32 | using Json = nlohmann::json; 33 | 34 | public: 35 | Circuit(); 36 | 37 | public: 38 | void Update(const Json& json); 39 | 40 | void Log() const; 41 | 42 | const NodeList& nodes() const { return nodes_; }; 43 | 44 | private: 45 | NodeList nodes_; 46 | }; 47 | 48 | } // config 49 | } // ssf 50 | 51 | #endif // SSF_COMMON_CONFIG_CIRCUIT_H_ 52 | -------------------------------------------------------------------------------- /src/common/config/tls.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_COMMON_CONFIG_TLS_H_ 2 | #define SSF_COMMON_CONFIG_TLS_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace ssf { 9 | namespace config { 10 | 11 | class TlsParam { 12 | public: 13 | enum class Type { kFile = 0, kBuffer }; 14 | TlsParam(Type param_type, const std::string& param_value); 15 | 16 | void Set(Type param_type, const std::string& param_value); 17 | 18 | std::string ToString() const; 19 | bool IsBuffer() const; 20 | std::string value() const { return value_; } 21 | 22 | private: 23 | Type type_; 24 | std::string value_; 25 | }; 26 | 27 | class Tls { 28 | public: 29 | using Json = nlohmann::json; 30 | 31 | public: 32 | Tls(); 33 | 34 | public: 35 | void Update(const Json& pt); 36 | 37 | void Log() const; 38 | 39 | const TlsParam& ca_cert() const { return ca_cert_; } 40 | TlsParam* mutable_ca_cert() { return &ca_cert_; } 41 | const TlsParam& cert() const { return cert_; } 42 | TlsParam* mutable_cert() { return &cert_; } 43 | const TlsParam& key() const { return key_; } 44 | TlsParam* mutable_key() { return &key_; } 45 | const std::string& key_password() const { return key_password_; } 46 | const TlsParam& dh() const { return dh_; } 47 | TlsParam* mutable_dh() { return &dh_; } 48 | const std::string& cipher_alg() const { return cipher_alg_; } 49 | 50 | private: 51 | // CA certificate 52 | TlsParam ca_cert_; 53 | // Certificate 54 | TlsParam cert_; 55 | // Certificate key 56 | TlsParam key_; 57 | // Key password 58 | std::string key_password_; 59 | // Diffie-Hellman ephemeral parameters 60 | TlsParam dh_; 61 | // Cipher suite algorithms 62 | std::string cipher_alg_; 63 | }; 64 | 65 | } // config 66 | } // ssf 67 | 68 | #endif // SSF_COMMON_CONFIG_TLS_H_ -------------------------------------------------------------------------------- /src/common/config/unix_default_config.cpp: -------------------------------------------------------------------------------- 1 | #include "common/config/config.h" 2 | 3 | const char* ssf::config::Config::default_config_ = R"RAWSTRING( 4 | { 5 | "ssf": { 6 | "arguments": "", 7 | "circuit": [], 8 | "tls": { 9 | "ca_cert_path": "./certs/trusted/ca.crt", 10 | "cert_path": "./certs/certificate.crt", 11 | "key_path": "./certs/private.key", 12 | "key_password": "", 13 | "dh_path": "./certs/dh4096.pem", 14 | "cipher_alg": "DHE-RSA-AES256-GCM-SHA384" 15 | }, 16 | "http_proxy": { 17 | "host": "", 18 | "port": "", 19 | "user_agent": "", 20 | "credentials": { 21 | "username": "", 22 | "password": "", 23 | "domain": "", 24 | "reuse_ntlm": true, 25 | "reuse_nego": true 26 | } 27 | }, 28 | "socks_proxy": { 29 | "version": 5, 30 | "host": "", 31 | "port": "1080" 32 | }, 33 | "services": { 34 | "datagram_forwarder": { "enable": true }, 35 | "datagram_listener": { 36 | "enable": true, 37 | "gateway_ports": false 38 | }, 39 | "stream_forwarder": { "enable": true }, 40 | "stream_listener": { 41 | "enable": true, 42 | "gateway_ports": false 43 | }, 44 | "copy": { "enable": false }, 45 | "shell": { 46 | "enable": false, 47 | "path": "/bin/bash", 48 | "args": "" 49 | }, 50 | "socks": { "enable": true } 51 | } 52 | } 53 | } 54 | )RAWSTRING"; 55 | -------------------------------------------------------------------------------- /src/common/config/win_default_config.cpp: -------------------------------------------------------------------------------- 1 | #include "common/config/config.h" 2 | 3 | const char* ssf::config::Config::default_config_ = R"RAWSTRING( 4 | { 5 | "ssf": { 6 | "arguments": "", 7 | "circuit": [], 8 | "tls": { 9 | "ca_cert_path": "./certs/trusted/ca.crt", 10 | "cert_path": "./certs/certificate.crt", 11 | "key_path": "./certs/private.key", 12 | "key_password": "", 13 | "dh_path": "./certs/dh4096.pem", 14 | "cipher_alg": "DHE-RSA-AES256-GCM-SHA384" 15 | }, 16 | "http_proxy": { 17 | "host": "", 18 | "port": "", 19 | "user_agent": "", 20 | "credentials": { 21 | "username": "", 22 | "password": "", 23 | "domain": "", 24 | "reuse_ntlm": true, 25 | "reuse_nego": true 26 | } 27 | }, 28 | "socks_proxy": { 29 | "version": 5, 30 | "host": "", 31 | "port": "1080" 32 | }, 33 | "services": { 34 | "datagram_forwarder": { "enable": true }, 35 | "datagram_listener": { 36 | "enable": true, 37 | "gateway_ports": false 38 | }, 39 | "stream_forwarder": { "enable": true }, 40 | "stream_listener": { 41 | "enable": true, 42 | "gateway_ports": false 43 | }, 44 | "copy": { "enable": false }, 45 | "shell": { 46 | "enable": false, 47 | "path": "C:\\windows\\system32\\cmd.exe", 48 | "args": "" 49 | }, 50 | "socks": { "enable": true } 51 | } 52 | } 53 | } 54 | )RAWSTRING"; 55 | -------------------------------------------------------------------------------- /src/common/crypto/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_COMMON_CRYPTO_HASH_H_ 2 | #define SSF_COMMON_CRYPTO_HASH_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "common/error/error.h" 9 | #include "common/filesystem/filesystem.h" 10 | #include "common/filesystem/path.h" 11 | 12 | namespace ssf { 13 | namespace crypto { 14 | 15 | template 16 | typename Hash::Digest HashFile(const ssf::Path& path, uint64_t stop_offset, 17 | boost::system::error_code& ec) { 18 | typename Hash::Digest digest; 19 | std::array buffer; 20 | 21 | std::ifstream file(path.GetString(), 22 | std::ifstream::binary | std::ifstream::in); 23 | if (!file.is_open()) { 24 | ec.assign(boost::system::errc::bad_file_descriptor, 25 | boost::system::get_system_category()); 26 | return {}; 27 | } 28 | 29 | Hash hash; 30 | 31 | uint64_t remaining = stop_offset; 32 | uint64_t read_len; 33 | do { 34 | read_len = (remaining < buffer.size()) ? remaining : buffer.size(); 35 | file.read(buffer.data(), read_len); 36 | remaining -= file.gcount(); 37 | hash.Update(buffer, static_cast(file.gcount())); 38 | } while (!file.eof() && remaining > 0); 39 | 40 | hash.Finalize(&digest); 41 | 42 | return digest; 43 | } 44 | 45 | template 46 | typename Hash::Digest HashFile(const ssf::Path& path, 47 | boost::system::error_code& ec) { 48 | ssf::Filesystem fs; 49 | auto filesize = fs.GetFilesize(path, ec); 50 | if (ec) { 51 | SSF_LOG("crypto", error, "hash: could not get filesize of {}", 52 | path.GetString()); 53 | return {}; 54 | } 55 | return HashFile(path, filesize, ec); 56 | } 57 | 58 | } // crypto 59 | } // ssf 60 | 61 | #endif // SSF_COMMON_CRYPTO_HASH_H_ 62 | -------------------------------------------------------------------------------- /src/common/crypto/md5.cpp: -------------------------------------------------------------------------------- 1 | #include "common/crypto/md5.h" 2 | 3 | namespace ssf { 4 | namespace crypto { 5 | 6 | Md5::Md5() : context_() { MD5_Init(&context_); } 7 | 8 | void Md5::Finalize(Digest* digest) { MD5_Final(digest->data(), &context_); } 9 | 10 | } // crypto 11 | } // ssf -------------------------------------------------------------------------------- /src/common/crypto/md5.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_COMMON_CRYPTO_MD5_H_ 2 | #define SSF_COMMON_CRYPTO_MD5_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "common/filesystem/path.h" 12 | 13 | namespace ssf { 14 | namespace crypto { 15 | 16 | class Md5 { 17 | public: 18 | using Digest = std::array; 19 | using Buffer = std::vector; 20 | 21 | public: 22 | Md5(); 23 | 24 | template 25 | void Update(const Buffer& buffer, std::size_t length) { 26 | MD5_Update(&context_, buffer.data(), length); 27 | } 28 | 29 | void Finalize(Digest* digest); 30 | 31 | private: 32 | MD5_CTX context_; 33 | }; 34 | 35 | } // crypto 36 | } // ssf 37 | 38 | #endif // SSF_COMMON_CRYPTO_MD5_H_ -------------------------------------------------------------------------------- /src/common/crypto/sha1.cpp: -------------------------------------------------------------------------------- 1 | #include "common/crypto/sha1.h" 2 | 3 | namespace ssf { 4 | namespace crypto { 5 | 6 | Sha1::Sha1() : context_() { SHA_Init(&context_); } 7 | 8 | void Sha1::Finalize(Digest* digest) { SHA_Final(digest->data(), &context_); } 9 | 10 | } // crypto 11 | } // ssf -------------------------------------------------------------------------------- /src/common/crypto/sha1.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_COMMON_CRYPTO_SHA1_H_ 2 | #define SSF_COMMON_CRYPTO_SHA1_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "common/filesystem/path.h" 12 | 13 | namespace ssf { 14 | namespace crypto { 15 | 16 | class Sha1 { 17 | public: 18 | using Digest = std::array; 19 | using Buffer = std::vector; 20 | 21 | public: 22 | Sha1(); 23 | 24 | template 25 | void Update(const Buffer& buffer, std::size_t length) { 26 | SHA_Update(&context_, buffer.data(), length); 27 | } 28 | 29 | void Finalize(Digest* digest); 30 | 31 | private: 32 | SHA_CTX context_; 33 | }; 34 | 35 | } // crypto 36 | } // ssf 37 | 38 | #endif // SSF_COMMON_CRYPTO_SHA1_H_ -------------------------------------------------------------------------------- /src/common/crypto/sha256.cpp: -------------------------------------------------------------------------------- 1 | #include "common/crypto/sha256.h" 2 | 3 | namespace ssf { 4 | namespace crypto { 5 | 6 | Sha256::Sha256() : context_() { SHA256_Init(&context_); } 7 | 8 | void Sha256::Finalize(Digest* digest) { 9 | SHA256_Final(digest->data(), &context_); 10 | } 11 | 12 | } // crypto 13 | } // ssf -------------------------------------------------------------------------------- /src/common/crypto/sha256.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_COMMON_CRYPTO_SHA256_H_ 2 | #define SSF_COMMON_CRYPTO_SHA256_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "common/filesystem/path.h" 12 | 13 | namespace ssf { 14 | namespace crypto { 15 | 16 | class Sha256 { 17 | public: 18 | using Digest = std::array; 19 | using Buffer = std::vector; 20 | 21 | public: 22 | Sha256(); 23 | 24 | template 25 | void Update(const Buffer& buffer, std::size_t length) { 26 | SHA256_Update(&context_, buffer.data(), length); 27 | } 28 | 29 | void Finalize(Digest* digest); 30 | 31 | private: 32 | SHA256_CTX context_; 33 | }; 34 | 35 | } // crypto 36 | } // ssf 37 | 38 | #endif // SSF_COMMON_CRYPTO_SHA1_H_ -------------------------------------------------------------------------------- /src/common/filesystem/filesystem.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_COMMON_FILESYSTEM_FILESYSTEM_H_ 2 | #define SSF_COMMON_FILESYSTEM_FILESYSTEM_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "common/filesystem/path.h" 10 | 11 | namespace ssf { 12 | 13 | class Filesystem { 14 | public: 15 | Filesystem(); 16 | 17 | bool IsFile(const Path& path, boost::system::error_code& ec) const; 18 | 19 | bool IsDirectory(const Path& path, boost::system::error_code& ec) const; 20 | 21 | bool Exists(const Path& path, boost::system::error_code& ec) const; 22 | 23 | uint64_t GetFilesize(const Path& path, boost::system::error_code& ec) const; 24 | 25 | bool MakeDirectory(const Path& path, boost::system::error_code& ec) const; 26 | 27 | bool MakeDirectories(const Path& path, boost::system::error_code& ec) const; 28 | 29 | bool Remove(const Path& path, boost::system::error_code& ec) const; 30 | 31 | bool RemoveAll(const Path& path, boost::system::error_code& ec) const; 32 | 33 | std::list ListFiles(const Path& path, bool recursive, 34 | boost::system::error_code& ec) const; 35 | 36 | private: 37 | void ListFilesRec(const Path& input_dir, 38 | const Path& base_dir, 39 | bool recursive, 40 | const std::regex& filepath_regex, 41 | std::list& files, 42 | boost::system::error_code& ec) const; 43 | }; 44 | 45 | } // ssf 46 | 47 | #endif // SSF_COMMON_FILESYSTEM_FILESYSTEM_H_ 48 | -------------------------------------------------------------------------------- /src/common/filesystem/path.cpp: -------------------------------------------------------------------------------- 1 | #include "common/filesystem/path.h" 2 | 3 | namespace ssf { 4 | 5 | Path::Path() : path_() {} 6 | 7 | Path::Path(const Path& path) : path_() { path_ = path.GetString(); } 8 | 9 | Path::Path(const boost::filesystem::path& path) : path_(path) {} 10 | 11 | Path::Path(const char* path) : path_() { path_ = path; } 12 | 13 | Path::Path(const std::string& path) : path_() { path_ = path; } 14 | 15 | Path::~Path() {} 16 | 17 | Path& Path::operator=(const Path& other) { 18 | path_ = other.GetString(); 19 | return *this; 20 | } 21 | 22 | Path& Path::operator=(const std::string& other) { 23 | path_ = other; 24 | return *this; 25 | } 26 | 27 | Path& Path::operator=(const char* other) { 28 | path_ = other; 29 | return *this; 30 | } 31 | 32 | Path& Path::operator+=(const Path& other) { 33 | path_ += other.path_; 34 | return *this; 35 | } 36 | 37 | Path& Path::operator+=(const std::string& other) { 38 | path_ += boost::filesystem::path(other); 39 | return *this; 40 | } 41 | 42 | Path& Path::operator+=(const char* other) { 43 | path_ += boost::filesystem::path(other); 44 | return *this; 45 | } 46 | 47 | Path& Path::operator/=(const Path& other) { 48 | path_ /= other.path_; 49 | return *this; 50 | } 51 | 52 | Path& Path::operator/=(const std::string& other) { 53 | path_ /= boost::filesystem::path(other); 54 | return *this; 55 | } 56 | 57 | Path& Path::operator/=(const char* other) { 58 | path_ /= boost::filesystem::path(other); 59 | return *this; 60 | } 61 | 62 | bool Path::operator==(const Path& path) const { 63 | return GetString() == path.GetString(); 64 | } 65 | 66 | Path Path::GetParent() const { return Path(path_.parent_path()); } 67 | 68 | Path Path::GetFilename() const { return Path(path_.filename()); } 69 | 70 | Path Path::GetExtension() const { return Path(path_.extension()); } 71 | 72 | bool Path::IsEmpty() const { return path_.empty(); } 73 | 74 | bool Path::IsRelative() const { return path_.is_relative(); } 75 | 76 | bool Path::IsAbsolute() const { return path_.is_absolute(); } 77 | 78 | bool Path::HasExtension() const { return path_.has_extension(); } 79 | 80 | std::string Path::GetString() const { return path_.generic_string(); } 81 | 82 | } // ssf 83 | -------------------------------------------------------------------------------- /src/common/filesystem/path.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_COMMON_FILESYSTEM_PATH_H_ 2 | #define SSF_COMMON_FILESYSTEM_PATH_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace ssf { 9 | 10 | class Path { 11 | public: 12 | Path(); 13 | Path(const Path& path); 14 | Path(const boost::filesystem::path& path); 15 | Path(const std::string& path); 16 | Path(const char* path); 17 | 18 | ~Path(); 19 | 20 | Path& operator=(const Path& other); 21 | Path& operator=(const std::string& other); 22 | Path& operator=(const char* other); 23 | 24 | Path& operator/=(const Path& other); 25 | Path& operator/=(const std::string& other); 26 | Path& operator/=(const char* other); 27 | 28 | Path& operator+=(const Path& other); 29 | Path& operator+=(const std::string& other); 30 | Path& operator+=(const char* other); 31 | 32 | bool operator==(const Path& path) const; 33 | 34 | friend Path operator/(Path lhs, const Path& rhs) { 35 | lhs /= rhs; 36 | return lhs; 37 | } 38 | 39 | Path GetParent() const; 40 | Path GetFilename() const; 41 | Path GetExtension() const; 42 | bool IsEmpty() const; 43 | bool IsRelative() const; 44 | bool IsAbsolute() const; 45 | bool HasExtension() const; 46 | 47 | Path MakeRelative(const Path& base, boost::system::error_code& ec) const; 48 | 49 | std::string GetString() const; 50 | 51 | private: 52 | boost::filesystem::path path_; 53 | }; 54 | 55 | } // ssf 56 | 57 | #endif // SSF_COMMON_FILESYSTEM_PATH_H_ 58 | -------------------------------------------------------------------------------- /src/common/utils/to_underlying.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_COMMON_UTILS_TO_UNDERLYING_H_ 2 | #define SSF_COMMON_UTILS_TO_UNDERLYING_H_ 3 | 4 | #include 5 | 6 | namespace ssf { 7 | 8 | template 9 | constexpr typename std::underlying_type_t to_underlying(const Enum& value) { 10 | return static_cast>(value); 11 | } 12 | 13 | } // ssf 14 | 15 | #endif // SSF_COMMON_UTILS_TO_UNDERLYING_H_ 16 | 17 | -------------------------------------------------------------------------------- /src/compat/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(iob_func STATIC EXCLUDE_FROM_ALL iob_func.cpp) 2 | set_property(TARGET iob_func PROPERTY FOLDER "Compat") 3 | 4 | add_library(memcpy STATIC EXCLUDE_FROM_ALL memcpy.cpp) 5 | target_link_libraries(memcpy PUBLIC "-Wl,--wrap=memcpy") 6 | set_property(TARGET memcpy PROPERTY FOLDER "Compat") 7 | -------------------------------------------------------------------------------- /src/compat/iob_func.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | FILE _iob[] = { *stdin, *stdout, *stderr }; 4 | extern "C" FILE * __cdecl __iob_func(void) { return _iob; } 5 | -------------------------------------------------------------------------------- /src/compat/memcpy.cpp: -------------------------------------------------------------------------------- 1 | #if defined(__GNUC__) && \ 2 | (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && \ 3 | defined(__LP64__) && (__LP64__ >= 1) && defined(__x86_64__) 4 | 5 | #include 6 | 7 | // wrap memcpy and force use 2.2.5 version 8 | 9 | __asm__(".symver memcpy, memcpy@GLIBC_2.2.5"); 10 | 11 | extern "C" { 12 | void *__wrap_memcpy(void *dest, const void *src, size_t n) { 13 | return memcpy(dest, src, n); 14 | } 15 | } 16 | #endif // GCC >= 4.7 and 64 bits 17 | -------------------------------------------------------------------------------- /src/core/async_engine.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "core/async_engine.h" 5 | 6 | #include "ssf/log/log.h" 7 | 8 | namespace ssf { 9 | 10 | AsyncEngine::AsyncEngine() 11 | : io_service_(), p_worker_(nullptr), threads_(), is_started_(false) {} 12 | 13 | AsyncEngine::~AsyncEngine() { Stop(); } 14 | 15 | boost::asio::io_service& AsyncEngine::get_io_service() { return io_service_; } 16 | 17 | void AsyncEngine::Start() { 18 | if (is_started_) { 19 | return; 20 | } 21 | 22 | SSF_LOG("async_engine", debug, "starting"); 23 | is_started_ = true; 24 | p_worker_.reset(new boost::asio::io_service::work(io_service_)); 25 | for (uint8_t i = 0; i < std::thread::hardware_concurrency(); ++i) { 26 | threads_.emplace_back([this]() { 27 | boost::system::error_code ec; 28 | io_service_.run(ec); 29 | if (ec) { 30 | SSF_LOG("async_engine", error, "run io_service failed: {}", 31 | ec.message()); 32 | } 33 | }); 34 | } 35 | } 36 | 37 | void AsyncEngine::Stop() { 38 | if (!is_started_) { 39 | return; 40 | } 41 | 42 | SSF_LOG("async_engine", debug, "stop"); 43 | p_worker_.reset(nullptr); 44 | for (auto& thread : threads_) { 45 | if (thread.joinable()) { 46 | thread.join(); 47 | } 48 | } 49 | io_service_.stop(); 50 | io_service_.reset(); 51 | is_started_ = false; 52 | } 53 | 54 | bool AsyncEngine::IsStarted() const { return is_started_; } 55 | 56 | } // ssf 57 | -------------------------------------------------------------------------------- /src/core/async_engine.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_CORE_ASYNC_ENGINE_H_ 2 | #define SSF_CORE_ASYNC_ENGINE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace ssf { 11 | 12 | class AsyncEngine { 13 | private: 14 | using WorkerPtr = std::unique_ptr; 15 | 16 | public: 17 | AsyncEngine(); 18 | ~AsyncEngine(); 19 | 20 | AsyncEngine(const AsyncEngine&) = delete; 21 | AsyncEngine& operator=(const AsyncEngine&) = delete; 22 | 23 | boost::asio::io_service& get_io_service(); 24 | 25 | void Start(); 26 | void Stop(); 27 | 28 | bool IsStarted() const; 29 | 30 | private: 31 | boost::asio::io_service io_service_; 32 | WorkerPtr p_worker_; 33 | std::vector threads_; 34 | bool is_started_; 35 | }; 36 | 37 | } // ssf 38 | 39 | #endif // SSF_CORE_ASYNC_RUNNER_H_ 40 | -------------------------------------------------------------------------------- /src/core/client/client_helper.cpp: -------------------------------------------------------------------------------- 1 | #include "core/client/client_helper.h" 2 | 3 | namespace ssf { 4 | 5 | NetworkProtocol::Query GenerateNetworkQuery( 6 | const std::string& remote_addr, const std::string& remote_port, 7 | const ssf::config::Config& ssf_config) { 8 | // put remote_addr and remote_port as last node in the circuit 9 | std::string first_node_addr; 10 | std::string first_node_port; 11 | ssf::config::NodeList nodes = ssf_config.circuit().nodes(); 12 | if (nodes.size()) { 13 | auto first_node = nodes.front(); 14 | nodes.pop_front(); 15 | first_node_addr = first_node.addr(); 16 | first_node_port = first_node.port(); 17 | nodes.emplace_back(remote_addr, remote_port); 18 | } else { 19 | first_node_addr = remote_addr; 20 | first_node_port = remote_port; 21 | } 22 | 23 | return NetworkProtocol::GenerateClientQuery(first_node_addr, first_node_port, 24 | ssf_config, nodes); 25 | } 26 | 27 | } // ssf 28 | -------------------------------------------------------------------------------- /src/core/client/client_helper.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_CORE_CLIENT_CLIENT_HELPER_H_ 2 | #define SSF_CORE_CLIENT_CLIENT_HELPER_H_ 3 | 4 | #include 5 | 6 | #include "common/config/config.h" 7 | #include "core/network_protocol.h" 8 | 9 | namespace ssf { 10 | 11 | using NetworkProtocol = ssf::network::NetworkProtocol; 12 | 13 | NetworkProtocol::Query GenerateNetworkQuery(const std::string& remote_addr, 14 | const std::string& remote_port, 15 | const ssf::config::Config& config); 16 | 17 | } // ssf 18 | 19 | #endif // SSF_CORE_CLIENT_CLIENT_HELPER_H_ 20 | -------------------------------------------------------------------------------- /src/core/client/status.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_CORE_CLIENT_STATUS_H_ 2 | #define SSF_CORE_CLIENT_STATUS_H_ 3 | 4 | namespace ssf { 5 | 6 | enum class Status { 7 | kInitialized, 8 | kEndpointNotResolvable, 9 | kServerUnreachable, 10 | kServerNotSupported, 11 | kDisconnected, 12 | kConnected, 13 | kRunning 14 | }; 15 | 16 | } // ssf 17 | 18 | #endif // SSF_CORE_CLIENT_STATUS_H_ 19 | -------------------------------------------------------------------------------- /src/core/command_line/copy/command_line.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_CORE_COMMAND_LINE_COPY_COMMAND_LINE_H_ 2 | #define SSF_CORE_COMMAND_LINE_COPY_COMMAND_LINE_H_ 3 | 4 | #include 5 | 6 | #include "core/command_line/base.h" 7 | 8 | namespace ssf { 9 | namespace command_line { 10 | 11 | class CopyCommandLine : public Base { 12 | public: 13 | CopyCommandLine(); 14 | 15 | bool stdin_input() const; 16 | 17 | bool from_client_to_server() const; 18 | 19 | bool resume() const; 20 | 21 | bool recursive() const; 22 | 23 | bool check_file_integrity() const; 24 | 25 | uint32_t max_parallel_copies() const; 26 | 27 | std::string input_pattern() const; 28 | 29 | std::string output_pattern() const; 30 | 31 | protected: 32 | bool IsServerCli() override; 33 | void ParseOptions(const Options& opts, 34 | boost::system::error_code& ec) override; 35 | void InitOptions(Options& opts) override; 36 | 37 | private: 38 | void ParseFirstArgument(const std::string& first_arg, 39 | boost::system::error_code& parse_ec); 40 | 41 | void ParseSecondArgument(const std::string& second_arg, 42 | boost::system::error_code& parse_ec); 43 | 44 | void ExtractHostPattern(const std::string& string, std::string* p_host, 45 | std::string* p_pattern, 46 | boost::system::error_code& ec) const; 47 | 48 | private: 49 | std::string input_pattern_; 50 | std::string output_pattern_; 51 | bool from_client_to_server_; 52 | bool stdin_input_; 53 | bool resume_; 54 | bool recursive_; 55 | bool check_file_integrity_; 56 | uint32_t max_parallel_copies_; 57 | }; 58 | 59 | } // command_line 60 | } // ssf 61 | 62 | #endif // SSF_CORE_COMMAND_LINE_COPY_COMMAND_LINE_H_ 63 | -------------------------------------------------------------------------------- /src/core/command_line/standard/command_line.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_CORE_COMMAND_LINE_STANDARD_COMMAND_LINE_H 2 | #define SSF_CORE_COMMAND_LINE_STANDARD_COMMAND_LINE_H 3 | 4 | #include 5 | 6 | #include "core/command_line/base.h" 7 | 8 | namespace ssf { 9 | namespace command_line { 10 | 11 | class StandardCommandLine : public Base { 12 | public: 13 | StandardCommandLine(bool is_server = false); 14 | 15 | bool show_status() const { return show_status_; } 16 | 17 | bool relay_only() const { return relay_only_; } 18 | 19 | bool gateway_ports() const { return gateway_ports_; } 20 | 21 | uint32_t max_connection_attempts() const { return max_connection_attempts_; } 22 | 23 | uint32_t reconnection_timeout() const { return reconnection_timeout_; } 24 | 25 | bool no_reconnection() const { return no_reconnection_; } 26 | 27 | protected: 28 | void InitOptions(Options& opts) override; 29 | bool IsServerCli() override; 30 | void ParseOptions(const Options& opts, 31 | boost::system::error_code& ec) override; 32 | 33 | private: 34 | bool is_server_; 35 | bool show_status_; 36 | bool relay_only_; 37 | bool gateway_ports_; 38 | uint32_t max_connection_attempts_; 39 | uint32_t reconnection_timeout_; 40 | bool no_reconnection_; 41 | }; 42 | 43 | } // command_line 44 | } // ssf 45 | 46 | #endif // SSF_CORE_COMMAND_LINE_STANDARD_COMMAND_LINE_H 47 | -------------------------------------------------------------------------------- /src/core/factory_manager/service_factory_manager.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_CORE_FACTORY_MANAGER_SERVICE_FACTORY_MANAGER_H_ 2 | #define SSF_CORE_FACTORY_MANAGER_SERVICE_FACTORY_MANAGER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ssf { 9 | 10 | template 11 | class ServiceFactory; 12 | 13 | template 14 | class ServiceFactoryManager { 15 | private: 16 | using ServiceFactoryPtr = std::shared_ptr>; 17 | using ServiceFactoryMap = std::map; 18 | 19 | public: 20 | static bool RegisterServiceFactory(Demux* index, 21 | ServiceFactoryPtr p_factory) { 22 | std::unique_lock lock(mutex_); 23 | auto inserted = 24 | service_factories_.insert(std::make_pair(index, std::move(p_factory))); 25 | return inserted.second; 26 | } 27 | 28 | static bool UnregisterServiceFactory(Demux* index) { 29 | std::unique_lock lock(mutex_); 30 | 31 | auto it = service_factories_.find(index); 32 | 33 | if (it != std::end(service_factories_)) { 34 | auto& p_service_factory = it->second; 35 | p_service_factory->StopAllLocalServices(); 36 | service_factories_.erase(index); 37 | return true; 38 | } else { 39 | return false; 40 | } 41 | } 42 | 43 | static ServiceFactoryPtr GetServiceFactory(Demux* index) { 44 | std::unique_lock lock(mutex_); 45 | 46 | auto it = service_factories_.find(index); 47 | 48 | if (it != std::end(service_factories_)) { 49 | return it->second; 50 | } else { 51 | return nullptr; 52 | } 53 | } 54 | 55 | private: 56 | static std::recursive_mutex mutex_; 57 | static ServiceFactoryMap service_factories_; 58 | }; 59 | 60 | template 61 | std::recursive_mutex ServiceFactoryManager::mutex_; 62 | 63 | template 64 | typename ServiceFactoryManager::ServiceFactoryMap 65 | ServiceFactoryManager::service_factories_; 66 | 67 | } // ssf 68 | 69 | #endif // SSF_CORE_FACTORY_MANAGER_SERVICE_FACTORY_MANAGER_H_ 70 | -------------------------------------------------------------------------------- /src/core/transport_virtual_layer_policies/init_packets/ssf_reply.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf_reply.h" 2 | 3 | namespace ssf { 4 | 5 | SSFReply::SSFReply() : result_(false) {} 6 | SSFReply::SSFReply(bool result) : result_(result) {} 7 | 8 | bool SSFReply::result() const { return result_; } 9 | 10 | std::array 11 | SSFReply::const_buffer() const { 12 | std::array buf = { 13 | {boost::asio::const_buffer(&result_, sizeof(result_))}}; 14 | 15 | return buf; 16 | } 17 | 18 | std::array 19 | SSFReply::buffer() { 20 | std::array buf = { 21 | {boost::asio::mutable_buffer(&result_, sizeof(result_))}}; 22 | 23 | return buf; 24 | } 25 | 26 | } // ssf 27 | -------------------------------------------------------------------------------- /src/core/transport_virtual_layer_policies/init_packets/ssf_reply.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_CORE_TRANSPORT_VIRTUAL_LAYER_POLICIES_INIT_PACKETS_SSF_REPLY_H_ 2 | #define SSF_CORE_TRANSPORT_VIRTUAL_LAYER_POLICIES_INIT_PACKETS_SSF_REPLY_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace ssf { 11 | 12 | class SSFReply { 13 | public: 14 | enum { field_number = 1, total_size = sizeof(bool) }; 15 | 16 | public: 17 | SSFReply(); 18 | SSFReply(bool result); 19 | 20 | bool result() const; 21 | 22 | std::array const_buffer() const; 23 | 24 | std::array buffer(); 25 | 26 | private: 27 | bool result_; 28 | }; 29 | 30 | using SSFReplyPtr = std::shared_ptr; 31 | 32 | } // ssf 33 | 34 | #endif // SSF_CORE_TRANSPORT_VIRTUAL_LAYER_POLICIES_INIT_PACKETS_SSF_REPLY_H_ 35 | -------------------------------------------------------------------------------- /src/core/transport_virtual_layer_policies/init_packets/ssf_request.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf_request.h" 2 | 3 | namespace ssf { 4 | 5 | SSFRequest::SSFRequest() : version_(0) {} 6 | 7 | SSFRequest::SSFRequest(VersionField version) : version_(version) {} 8 | 9 | SSFRequest::VersionField SSFRequest::version() const { return version_; } 10 | 11 | std::array 12 | SSFRequest::const_buffer() const { 13 | std::array buf = { 14 | {boost::asio::const_buffer(&version_, sizeof(version_))}}; 15 | 16 | return buf; 17 | } 18 | 19 | std::array 20 | SSFRequest::buffer() { 21 | std::array buf = { 22 | {boost::asio::mutable_buffer(&version_, sizeof(version_))}}; 23 | 24 | return buf; 25 | } 26 | 27 | } // ssf 28 | -------------------------------------------------------------------------------- /src/core/transport_virtual_layer_policies/init_packets/ssf_request.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_CORE_TRANSPORT_VIRTUAL_LAYER_POLICIES_INIT_PACKETS_SSF_REQUEST_H_ 2 | #define SSF_CORE_TRANSPORT_VIRTUAL_LAYER_POLICIES_INIT_PACKETS_SSF_REQUEST_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace ssf { 11 | 12 | class SSFRequest { 13 | public: 14 | using VersionField = uint32_t; 15 | 16 | enum { field_number = 1, total_size = sizeof(VersionField) }; 17 | 18 | public: 19 | SSFRequest(); 20 | SSFRequest(VersionField version); 21 | 22 | VersionField version() const; 23 | 24 | std::array const_buffer() const; 25 | std::array buffer(); 26 | 27 | private: 28 | VersionField version_; 29 | }; 30 | 31 | using SSFRequestPtr = std::shared_ptr; 32 | 33 | } // ssf 34 | 35 | #endif // SSF_CORE_TRANSPORT_VIRTUAL_LAYER_POLICIES_INIT_PACKETS_SSF_REQUEST_H_ 36 | -------------------------------------------------------------------------------- /src/network/ssf/io/buffers.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_IO_BUFFERS_H_ 2 | #define SSF_IO_BUFFERS_H_ 3 | 4 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 5 | #pragma once 6 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 7 | 8 | #include 9 | 10 | namespace ssf { 11 | namespace io { 12 | 13 | template 14 | class fixed_buffer_sequence { 15 | public: 16 | typedef std::vector buffer_type; 17 | typedef typename buffer_type::value_type value_type; 18 | typedef typename buffer_type::iterator iterator; 19 | typedef typename buffer_type::const_iterator const_iterator; 20 | 21 | fixed_buffer_sequence() : buffers_() {} 22 | 23 | template 24 | fixed_buffer_sequence(const BufferSequence& buffers) 25 | : buffers_() { 26 | for (const auto& buffer : buffers) { 27 | buffers_.push_back(buffer); 28 | } 29 | } 30 | 31 | iterator begin() { return buffers_.begin(); } 32 | iterator end() { return buffers_.end(); } 33 | 34 | const_iterator begin() const { return buffers_.begin(); } 35 | const_iterator end() const { return buffers_.end(); } 36 | 37 | void push_back(const value_type& val) { buffers_.push_back(val); } 38 | void push_back(value_type&& val) { buffers_.push_back(std::move(val)); } 39 | 40 | private: 41 | buffer_type buffers_; 42 | }; 43 | 44 | typedef fixed_buffer_sequence 45 | fixed_mutable_buffer_sequence; 46 | 47 | typedef fixed_buffer_sequence 48 | fixed_const_buffer_sequence; 49 | 50 | } // io 51 | } // ssf 52 | 53 | #endif // SSF_IO_BUFFERS_H_ 54 | -------------------------------------------------------------------------------- /src/network/ssf/layer/congestion/drop_tail_policy.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_CONGESTION_DROP_TAIL_POLICY_H_ 2 | #define SSF_LAYER_CONGESTION_DROP_TAIL_POLICY_H_ 3 | 4 | namespace ssf { 5 | namespace layer { 6 | namespace congestion { 7 | 8 | template 9 | class DropTailPolicy { 10 | public: 11 | template 12 | bool IsAddable(const Queue& queue, const Packet& packet) { 13 | return queue.size() < MaxSize; 14 | } 15 | 16 | template 17 | bool IsAddable(const Queue& queue) { 18 | return queue.size() < MaxSize; 19 | } 20 | }; 21 | 22 | } // congestion 23 | } // layer 24 | } // ssf 25 | 26 | #endif // SSF_LAYER_CONGESTION_DROP_TAIL_POLICY_H_ 27 | -------------------------------------------------------------------------------- /src/network/ssf/layer/data_link/circuit_endpoint_context.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_DATA_LINK_CIRCUIT_ENDPOINT_CONTEXT_H_ 2 | #define SSF_LAYER_DATA_LINK_CIRCUIT_ENDPOINT_CONTEXT_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace ssf { 10 | namespace layer { 11 | namespace data_link { 12 | 13 | struct CircuitEndpointContext { 14 | using ID = std::string; 15 | using SerializedForwardBlocks = std::string; 16 | using Details = std::string; 17 | using SerializedDefaultParameters = std::string; 18 | 19 | bool operator==(const CircuitEndpointContext& rhs) const { 20 | return id == rhs.id; 21 | } 22 | 23 | bool operator!=(const CircuitEndpointContext& rhs) const { 24 | return !(*this == rhs); 25 | } 26 | 27 | bool operator<(const CircuitEndpointContext& rhs) const { 28 | return id < rhs.id; 29 | } 30 | 31 | bool forward; 32 | // TODO change std::string to uint32_t for id (?) 33 | ID id; 34 | SerializedForwardBlocks forward_blocks; 35 | SerializedDefaultParameters default_parameters; 36 | Details details; 37 | }; 38 | 39 | } // data_link 40 | } // layer 41 | } // ssf 42 | 43 | #endif // SSF_LAYER_DATA_LINK_CIRCUIT_ENDPOINT_CONTEXT_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/data_link/helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_DATA_LINK_HELPERS_H_ 2 | #define SSF_LAYER_DATA_LINK_HELPERS_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "ssf/layer/basic_endpoint.h" 10 | 11 | namespace ssf { 12 | namespace layer { 13 | namespace data_link { 14 | namespace detail { 15 | 16 | template 17 | bool is_endpoint_forwarding( 18 | const basic_VirtualLink_endpoint& endpoint) { 19 | return endpoint.is_set() && endpoint.endpoint_context().forward; 20 | } 21 | 22 | } // detail 23 | } // data_link 24 | } // layer 25 | } // ssf 26 | 27 | #endif // SSF_LAYER_DATA_LINK_HELPERS_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/datagram/basic_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_DATAGRAM_BASIC_FLAGS_H_ 2 | #define SSF_LAYER_DATAGRAM_BASIC_FLAGS_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace ssf { 9 | namespace layer { 10 | 11 | template 12 | class basic_Flags { 13 | public: 14 | typedef io::fixed_const_buffer_sequence ConstBuffers; 15 | typedef io::fixed_mutable_buffer_sequence MutableBuffers; 16 | enum { size = sizeof(BasicType) }; 17 | 18 | public: 19 | basic_Flags() {} 20 | basic_Flags(BasicType raw_flags) : raw_flags_(raw_flags) {} 21 | 22 | ~basic_Flags() {} 23 | 24 | ConstBuffers GetConstBuffers() const { 25 | ConstBuffers buffers; 26 | buffers.push_back(boost::asio::buffer(&raw_flags_, sizeof(raw_flags_))); 27 | return buffers; 28 | } 29 | 30 | void GetConstBuffers(ConstBuffers* p_buffers) const { 31 | p_buffers->push_back(boost::asio::buffer(&raw_flags_, sizeof(raw_flags_))); 32 | } 33 | 34 | MutableBuffers GetMutableBuffers() { 35 | MutableBuffers buffers; 36 | buffers.push_back(boost::asio::buffer(&raw_flags_, sizeof(raw_flags_))); 37 | return buffers; 38 | } 39 | 40 | void GetMutableBuffers(MutableBuffers* p_buffers) { 41 | p_buffers->push_back(boost::asio::buffer(&raw_flags_, sizeof(raw_flags_))); 42 | } 43 | 44 | BasicType raw_flags() const { return raw_flags_ } 45 | void set_raw_flags(BasicType raw_flags) { raw_flags_ = raw_flags; } 46 | 47 | private: 48 | BasicType raw_flags_; 49 | }; 50 | 51 | } // layer 52 | } // ssf 53 | 54 | #endif // SSF_LAYER_DATAGRAM_BASIC_FLAGS_H_ 55 | -------------------------------------------------------------------------------- /src/network/ssf/layer/datagram/empty_component.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_DATAGRAM_EMPTY_COMPONENT_H_ 2 | #define SSF_LAYER_DATAGRAM_EMPTY_COMPONENT_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | namespace ssf { 11 | namespace layer { 12 | 13 | class EmptyComponent { 14 | public: 15 | typedef io::fixed_const_buffer_sequence ConstBuffers; 16 | typedef io::fixed_mutable_buffer_sequence MutableBuffers; 17 | enum { size = 0 }; 18 | 19 | public: 20 | EmptyComponent() {} 21 | ~EmptyComponent() {} 22 | 23 | ConstBuffers GetConstBuffers() const { return ConstBuffers(); } 24 | void GetConstBuffers(ConstBuffers* p_buffers) const {} 25 | 26 | MutableBuffers GetMutableBuffers() { return MutableBuffers(); } 27 | void GetMutableBuffers(MutableBuffers* p_buffers) {} 28 | }; 29 | 30 | } // layer 31 | } // ssf 32 | 33 | #endif // SSF_LAYER_DATAGRAM_EMPTY_COMPONENT_H_ 34 | -------------------------------------------------------------------------------- /src/network/ssf/layer/interface_layer/basic_interface_manager.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_INTERFACE_LAYER_BASIC_INTERFACE_MANAGER_H_ 2 | #define SSF_LAYER_INTERFACE_LAYER_BASIC_INTERFACE_MANAGER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace ssf { 11 | namespace layer { 12 | namespace interface_layer { 13 | 14 | template 15 | class basic_InterfaceManager { 16 | public: 17 | typedef std::shared_ptr SocketPtr; 18 | typedef typename Protocol::endpoint_context_type EndpointContext; 19 | 20 | public: 21 | basic_InterfaceManager() : mutex_(), available_sockets_() {} 22 | 23 | std::size_t Count(const EndpointContext& endpoint) { 24 | return available_sockets_.count(endpoint); 25 | } 26 | 27 | boost::optional Find(const EndpointContext& endpoint) { 28 | std::unique_lock lock_sockets(mutex_); 29 | auto p_socket_it = available_sockets_.find(endpoint); 30 | if (p_socket_it != available_sockets_.end()) { 31 | return boost::optional(p_socket_it->second); 32 | } 33 | return boost::optional(); 34 | } 35 | 36 | bool Emplace(const EndpointContext& endpoint, SocketPtr p_socket) { 37 | std::unique_lock lock_sockets(mutex_); 38 | auto inserted = available_sockets_.emplace(endpoint, p_socket); 39 | 40 | return inserted.second; 41 | } 42 | 43 | bool Erase(const EndpointContext& endpoint) { 44 | std::unique_lock lock_sockets(mutex_); 45 | return 1 == available_sockets_.erase(endpoint); 46 | } 47 | 48 | private: 49 | std::mutex mutex_; 50 | std::map available_sockets_; 51 | }; 52 | 53 | } // interface_layer 54 | } // layer 55 | } // ssf 56 | 57 | #endif // SSF_LAYER_INTERFACE_LAYER_BASIC_INTERFACE_MANAGER_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/interface_layer/basic_interface_protocol.cc: -------------------------------------------------------------------------------- 1 | #include "ssf/layer/interface_layer/basic_interface_protocol.h" 2 | 3 | namespace ssf { 4 | namespace layer { 5 | namespace interface_layer { 6 | 7 | basic_InterfaceProtocol::interface_manager_type 8 | basic_InterfaceProtocol::interface_manager_; 9 | 10 | } // interface_layer 11 | } // layer 12 | } // ssf 13 | -------------------------------------------------------------------------------- /src/network/ssf/layer/interface_layer/generic_interface_socket.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_INTERFACE_LAYER_GENERIC_INTERFACE_SOCKET_H_ 2 | #define SSF_LAYER_INTERFACE_LAYER_GENERIC_INTERFACE_SOCKET_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "ssf/layer/io_handler.h" 13 | #include "ssf/layer/interface_layer/interface_buffers.h" 14 | 15 | namespace ssf { 16 | namespace layer { 17 | namespace interface_layer { 18 | 19 | template 20 | class generic_interface_socket { 21 | public: 22 | typedef Protocol protocol_type; 23 | 24 | private: 25 | typedef typename protocol_type::endpoint endpoint_type; 26 | 27 | public: 28 | virtual std::size_t available(boost::system::error_code& ec) = 0; 29 | 30 | virtual boost::system::error_code cancel(boost::system::error_code& ec) = 0; 31 | 32 | virtual void close(boost::system::error_code& ec) = 0; 33 | 34 | virtual void connect(boost::system::error_code& ec) = 0; 35 | 36 | virtual void async_receive(interface_mutable_buffers buffers, 37 | ssf::layer::WrappedIOHandler handler) = 0; 38 | 39 | virtual void async_send(interface_const_buffers buffers, 40 | ssf::layer::WrappedIOHandler handler) = 0; 41 | }; 42 | 43 | } // interface_layer 44 | } // layer 45 | } // ssf 46 | 47 | #endif // SSF_LAYER_INTERFACE_LAYER_GENERIC_INTERFACE_SOCKET_H_ 48 | -------------------------------------------------------------------------------- /src/network/ssf/layer/interface_layer/interface_buffers.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_INTERFACE_LAYER_INTERFACE_BUFFERS_H_ 2 | #define SSF_LAYER_INTERFACE_LAYER_INTERFACE_BUFFERS_H_ 3 | 4 | #include "ssf/io/buffers.h" 5 | 6 | namespace ssf { 7 | namespace layer { 8 | namespace interface_layer { 9 | 10 | typedef io::fixed_mutable_buffer_sequence interface_mutable_buffers; 11 | typedef io::fixed_const_buffer_sequence interface_const_buffers; 12 | 13 | } // interface_layer 14 | } // layer 15 | } // ssf 16 | 17 | #endif // SSF_LAYER_INTERFACE_LAYER_INTERFACE_BUFFERS_H_ 18 | -------------------------------------------------------------------------------- /src/network/ssf/layer/io_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_IO_HANDLER_H_ 2 | #define SSF_LAYER_IO_HANDLER_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace ssf { 9 | namespace layer { 10 | 11 | class BaseIOHandler { 12 | public: 13 | virtual ~BaseIOHandler() {} 14 | virtual void operator()(const boost::system::error_code&, std::size_t) = 0; 15 | virtual void operator()(const boost::system::error_code&, std::size_t) const = 0; 16 | }; 17 | 18 | template 19 | class IOHandler : public BaseIOHandler { 20 | public: 21 | IOHandler() {} 22 | IOHandler(SubHandler handler) : handler_(std::move(handler)) {} 23 | 24 | void operator()(const boost::system::error_code& ec, std::size_t length) { 25 | handler_(ec, length); 26 | } 27 | 28 | void operator()(const boost::system::error_code& ec, std::size_t length) const { 29 | handler_(ec, length); 30 | } 31 | 32 | private: 33 | SubHandler handler_; 34 | }; 35 | 36 | typedef std::shared_ptr BaseIOHandlerPtr; 37 | 38 | class WrappedIOHandler { 39 | public: 40 | WrappedIOHandler() : p_handler_(nullptr) {} 41 | 42 | template 43 | WrappedIOHandler(Handler handler) 44 | : p_handler_(std::make_shared>(std::move(handler))) {} 45 | 46 | WrappedIOHandler(const WrappedIOHandler& other) 47 | : p_handler_(other.p_handler_) {} 48 | 49 | WrappedIOHandler(WrappedIOHandler&& other) 50 | : p_handler_(std::move(other.p_handler_)) {} 51 | 52 | ~WrappedIOHandler() {} 53 | 54 | void operator()(const boost::system::error_code& ec, std::size_t length) { 55 | if (p_handler_) { 56 | (*p_handler_)(ec, length); 57 | } 58 | } 59 | 60 | void operator()(const boost::system::error_code& ec, 61 | std::size_t length) const { 62 | if (p_handler_) { 63 | (*p_handler_)(ec, length); 64 | } 65 | } 66 | 67 | private: 68 | BaseIOHandlerPtr p_handler_; 69 | }; 70 | 71 | } // layer 72 | } // ssf 73 | 74 | #endif // SSF_LAYER_IO_HANDLER_H_ 75 | -------------------------------------------------------------------------------- /src/network/ssf/layer/parameters.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf/layer/parameters.h" 2 | 3 | #include 4 | #include 5 | 6 | namespace ssf { 7 | namespace layer { 8 | 9 | std::string serialize_parameter_stack(const ParameterStack &stack) { 10 | std::ostringstream ostrs; 11 | 12 | msgpack::pack(ostrs, stack); 13 | 14 | return ostrs.str(); 15 | } 16 | 17 | ParameterStack unserialize_parameter_stack( 18 | const std::string &serialized_stack) { 19 | try { 20 | auto obj_handle = 21 | msgpack::unpack(serialized_stack.data(), serialized_stack.size()); 22 | auto obj = obj_handle.get(); 23 | 24 | return obj.as(); 25 | } catch (const std::exception &) { 26 | return ParameterStack(); 27 | } 28 | } 29 | 30 | } // layer 31 | } // ssf 32 | -------------------------------------------------------------------------------- /src/network/ssf/layer/parameters.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PARAMETERS_H_ 2 | #define SSF_LAYER_PARAMETERS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ssf { 9 | namespace layer { 10 | 11 | using LayerParameters = std::map; 12 | using ParameterStack = std::list; 13 | 14 | std::string serialize_parameter_stack(const ParameterStack& stack); 15 | 16 | ParameterStack unserialize_parameter_stack(const std::string& serialized_stack); 17 | 18 | } // layer 19 | } // ssf 20 | 21 | #endif // SSF_LAYER_PARAMETERS_H_ 22 | -------------------------------------------------------------------------------- /src/network/ssf/layer/physical/host.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf/layer/physical/host.h" 2 | 3 | #include "ssf/utils/map_helpers.h" 4 | 5 | namespace ssf { 6 | namespace layer { 7 | namespace physical { 8 | 9 | Host::Host() : addr_(""), port_("") {} 10 | 11 | Host::Host(const LayerParameters& parameters) 12 | : addr_(ssf::helpers::GetField("addr", parameters)), 13 | port_(ssf::helpers::GetField("port", parameters)) {} 14 | 15 | } // physical 16 | } // layer 17 | } // ssf -------------------------------------------------------------------------------- /src/network/ssf/layer/physical/host.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PHYSICAL_HOST_H_ 2 | #define SSF_LAYER_PHYSICAL_HOST_H_ 3 | 4 | #include 5 | 6 | #include "ssf/layer/parameters.h" 7 | 8 | namespace ssf { 9 | namespace layer { 10 | namespace physical { 11 | 12 | class Host { 13 | public: 14 | Host(); 15 | Host(const LayerParameters& parameters); 16 | 17 | inline const std::string& addr() const { return addr_; } 18 | 19 | inline const std::string& port() const { return port_; } 20 | 21 | private: 22 | std::string addr_; 23 | std::string port_; 24 | }; 25 | 26 | } // physical 27 | } // layer 28 | } // ssf 29 | 30 | #endif // SSF_LAYER_PHYSICAL_HOST_H_ 31 | -------------------------------------------------------------------------------- /src/network/ssf/layer/physical/tcp.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf/layer/physical/tcp.h" 2 | 3 | namespace ssf { 4 | namespace layer { 5 | namespace physical { 6 | 7 | const char* tcp::NAME = "TCP"; 8 | 9 | } // physical 10 | } // layer 11 | } // ssf 12 | -------------------------------------------------------------------------------- /src/network/ssf/layer/physical/tcp.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PHYSICAL_TCP_H_ 2 | #define SSF_LAYER_PHYSICAL_TCP_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "ssf/layer/basic_empty_stream.h" 14 | #include "ssf/layer/parameters.h" 15 | #include "ssf/layer/physical/tcp_helpers.h" 16 | #include "ssf/layer/protocol_attributes.h" 17 | #include "ssf/layer/physical/host.h" 18 | 19 | namespace ssf { 20 | namespace layer { 21 | namespace physical { 22 | 23 | class tcp { 24 | public: 25 | enum { 26 | id = 1, 27 | overhead = 0, 28 | facilities = ssf::layer::facilities::stream, 29 | mtu = 65535 - overhead 30 | }; 31 | enum { endpoint_stack_size = 1 }; 32 | 33 | static const char* NAME; 34 | 35 | using socket_context = int; 36 | using acceptor_context = int; 37 | using acceptor = boost::asio::ip::tcp::acceptor; 38 | using endpoint = boost::asio::ip::tcp::endpoint; 39 | using resolver = boost::asio::ip::tcp::resolver; 40 | using socket = boost::asio::ip::tcp::socket; 41 | 42 | private: 43 | using query = ParameterStack; 44 | 45 | public: 46 | operator boost::asio::ip::tcp() { return boost::asio::ip::tcp::v4(); } 47 | 48 | static std::string get_name() { return NAME; } 49 | 50 | static endpoint make_endpoint(boost::asio::io_service& io_service, 51 | query::const_iterator parameters_it, uint32_t, 52 | boost::system::error_code& ec) { 53 | return ssf::layer::physical::detail::make_tcp_endpoint(io_service, 54 | *parameters_it, ec); 55 | } 56 | 57 | static std::string get_address(const endpoint& endpoint) { 58 | return endpoint.address().to_string(); 59 | } 60 | 61 | static unsigned short get_port(const endpoint& endpoint) { 62 | return endpoint.port(); 63 | } 64 | }; 65 | 66 | using TCPPhysicalLayer = VirtualEmptyStreamProtocol; 67 | 68 | } // physical 69 | } // layer 70 | } // ssf 71 | 72 | #endif // SSF_LAYER_PHYSICAL_TCP_H_ 73 | -------------------------------------------------------------------------------- /src/network/ssf/layer/physical/tcp_helpers.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf/error/error.h" 2 | 3 | #include "ssf/layer/physical/host.h" 4 | #include "ssf/layer/physical/tcp_helpers.h" 5 | 6 | namespace ssf { 7 | namespace layer { 8 | namespace physical { 9 | namespace detail { 10 | 11 | boost::asio::ip::tcp::endpoint make_tcp_endpoint( 12 | boost::asio::io_service& io_service, const LayerParameters& parameters, 13 | boost::system::error_code& ec) { 14 | Host host(parameters); 15 | 16 | if (!host.port().empty()) { 17 | if (!host.addr().empty()) { 18 | boost::asio::ip::tcp::resolver resolver(io_service); 19 | boost::asio::ip::tcp::resolver::query query(host.addr(), host.port()); 20 | boost::asio::ip::tcp::resolver::iterator iterator( 21 | resolver.resolve(query, ec)); 22 | 23 | if (!ec) { 24 | return boost::asio::ip::tcp::endpoint(*iterator); 25 | } 26 | } else { 27 | try { 28 | return boost::asio::ip::tcp::endpoint( 29 | boost::asio::ip::tcp::v4(), (uint16_t)std::stoul(host.port())); 30 | } catch (const std::exception&) { 31 | ec.assign(ssf::error::bad_address, ssf::error::get_ssf_category()); 32 | return boost::asio::ip::tcp::endpoint(); 33 | } 34 | } 35 | } 36 | 37 | return boost::asio::ip::tcp::endpoint(); 38 | } 39 | 40 | } // detail 41 | } // physical 42 | } // layer 43 | } // ssf 44 | -------------------------------------------------------------------------------- /src/network/ssf/layer/physical/tcp_helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PHYSICAL_TCP_HELPERS_H_ 2 | #define SSF_LAYER_PHYSICAL_TCP_HELPERS_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "ssf/layer/parameters.h" 10 | 11 | namespace ssf { 12 | namespace layer { 13 | namespace physical { 14 | namespace detail { 15 | 16 | boost::asio::ip::tcp::endpoint make_tcp_endpoint( 17 | boost::asio::io_service& io_service, const LayerParameters& parameters, 18 | boost::system::error_code& ec); 19 | 20 | } // detail 21 | } // physical 22 | } // layer 23 | } // ssf 24 | 25 | #endif // SSF_LAYER_PHYSICAL_TCP_HELPERS_H_ 26 | -------------------------------------------------------------------------------- /src/network/ssf/layer/physical/tlsotcp.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PHYSICAL_TLSOTCP_H_ 2 | #define SSF_LAYER_PHYSICAL_TLSOTCP_H_ 3 | 4 | #include "ssf/layer/cryptography/basic_crypto_stream.h" 5 | #include "ssf/layer/cryptography/tls/OpenSSL/impl.h" 6 | 7 | #include "ssf/layer/physical/tcp.h" 8 | 9 | namespace ssf { 10 | namespace layer { 11 | namespace physical { 12 | 13 | using TLSboTCPPhysicalLayer = cryptography::basic_CryptoStreamProtocol< 14 | tcp, cryptography::buffered_tls>; 15 | 16 | using TLSoTCPPhysicalLayer = 17 | cryptography::basic_CryptoStreamProtocol; 18 | 19 | } // physical 20 | } // layer 21 | } // ssf 22 | 23 | #endif // SSF_LAYER_PHYSICAL_TLSOTCP_H_ 24 | -------------------------------------------------------------------------------- /src/network/ssf/layer/physical/udp.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PHYSICAL_UDP_H_ 2 | #define SSF_LAYER_PHYSICAL_UDP_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "ssf/layer/basic_empty_datagram.h" 10 | #include "ssf/layer/parameters.h" 11 | #include "ssf/layer/physical/udp_helpers.h" 12 | #include "ssf/layer/protocol_attributes.h" 13 | 14 | namespace ssf { 15 | namespace layer { 16 | namespace physical { 17 | 18 | class udp { 19 | public: 20 | enum { 21 | id = 11, 22 | overhead = 0, 23 | facilities = ssf::layer::facilities::datagram, 24 | mtu = 1500 - overhead 25 | }; 26 | 27 | enum { endpoint_stack_size = 1 }; 28 | 29 | using socket_context = int; 30 | using acceptor_context = int; 31 | using endpoint = boost::asio::ip::udp::endpoint; 32 | using resolver = boost::asio::ip::udp::resolver; 33 | using socket = boost::asio::ip::udp::socket; 34 | 35 | private: 36 | using query = ParameterStack; 37 | 38 | public: 39 | operator boost::asio::ip::udp() { return boost::asio::ip::udp::v4(); } 40 | 41 | static endpoint make_endpoint(boost::asio::io_service& io_service, 42 | query::const_iterator parameters_it, uint32_t, 43 | boost::system::error_code& ec) { 44 | return ssf::layer::physical::detail::make_udp_endpoint(io_service, 45 | *parameters_it, ec); 46 | } 47 | 48 | static std::string get_address(const endpoint& endpoint) { 49 | return endpoint.address().to_string(); 50 | } 51 | }; 52 | 53 | using UDPPhysicalLayer = VirtualEmptyDatagramProtocol; 54 | 55 | } // physical 56 | } // layer 57 | } // ssf 58 | 59 | #endif // SSF_LAYER_PHYSICAL_UDP_H_ 60 | -------------------------------------------------------------------------------- /src/network/ssf/layer/physical/udp_helpers.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf/error/error.h" 2 | 3 | #include "ssf/layer/physical/host.h" 4 | #include "ssf/layer/physical/udp_helpers.h" 5 | 6 | namespace ssf { 7 | namespace layer { 8 | namespace physical { 9 | namespace detail { 10 | 11 | boost::asio::ip::udp::endpoint make_udp_endpoint( 12 | boost::asio::io_service& io_service, const LayerParameters& parameters, 13 | boost::system::error_code& ec) { 14 | Host host(parameters); 15 | 16 | if (!host.port().empty()) { 17 | if (!host.addr().empty()) { 18 | boost::asio::ip::udp::resolver resolver(io_service); 19 | boost::asio::ip::udp::resolver::query query(host.addr(), host.port()); 20 | boost::asio::ip::udp::resolver::iterator iterator( 21 | resolver.resolve(query, ec)); 22 | 23 | if (!ec) { 24 | return boost::asio::ip::udp::endpoint(*iterator); 25 | } 26 | } else { 27 | try { 28 | return boost::asio::ip::udp::endpoint( 29 | boost::asio::ip::udp::v4(), (uint16_t)std::stoul(host.port())); 30 | } catch (const std::exception&) { 31 | ec.assign(ssf::error::bad_address, ssf::error::get_ssf_category()); 32 | return boost::asio::ip::udp::endpoint(); 33 | } 34 | } 35 | } 36 | 37 | return boost::asio::ip::udp::endpoint(); 38 | } 39 | 40 | } // detail 41 | } // physical 42 | } // layer 43 | } // ssf 44 | -------------------------------------------------------------------------------- /src/network/ssf/layer/physical/udp_helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PHYSICAL_UDP_HELPERS_H_ 2 | #define SSF_LAYER_PHYSICAL_UDP_HELPERS_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "ssf/layer/parameters.h" 10 | 11 | namespace ssf { 12 | namespace layer { 13 | namespace physical { 14 | namespace detail { 15 | 16 | boost::asio::ip::udp::endpoint make_udp_endpoint( 17 | boost::asio::io_service& io_service, const LayerParameters& parameters, 18 | boost::system::error_code& ec); 19 | 20 | } // detail 21 | } // physical 22 | } // layer 23 | } // ssf 24 | 25 | #endif // SSF_LAYER_PHYSICAL_UDP_HELPERS_H_ 26 | -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/auth_strategy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ssf/layer/proxy/auth_strategy.h" 4 | 5 | namespace ssf { 6 | namespace layer { 7 | namespace proxy { 8 | 9 | std::string AuthStrategy::ExtractAuthToken(const HttpResponse& response) const { 10 | std::string challenge_str; 11 | auto auth_name = AuthName(); 12 | 13 | auto hdr_values = response.GetHeaderValues( 14 | proxy_authentication() ? "Proxy-Authenticate" : "WWW-Authenticate"); 15 | for (auto& hdr_value : hdr_values) { 16 | // find auth header 17 | if (hdr_value.find(auth_name) == 0) { 18 | challenge_str = hdr_value.substr(auth_name.length()); 19 | break; 20 | } 21 | } 22 | 23 | if (challenge_str.empty()) { 24 | return ""; 25 | } 26 | 27 | boost::trim(challenge_str); 28 | 29 | return challenge_str; 30 | } 31 | 32 | } // proxy 33 | } // layer 34 | } // ssf -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/auth_strategy.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_AUTH_STRATEGY_H_ 2 | #define SSF_LAYER_PROXY_AUTH_STRATEGY_H_ 3 | 4 | #include 5 | 6 | #include "ssf/layer/proxy/http_request.h" 7 | #include "ssf/layer/proxy/http_response.h" 8 | #include "ssf/layer/proxy/proxy_endpoint_context.h" 9 | 10 | namespace ssf { 11 | namespace layer { 12 | namespace proxy { 13 | 14 | class AuthStrategy { 15 | public: 16 | enum Status : int { 17 | kAuthenticationFailure = -1, 18 | kAuthenticating = 0, 19 | kAuthenticated = 1 20 | }; 21 | 22 | public: 23 | virtual ~AuthStrategy() {} 24 | 25 | virtual std::string AuthName() const = 0; 26 | 27 | virtual bool Support(const HttpResponse& response) const = 0; 28 | 29 | virtual void ProcessResponse(const HttpResponse& response) = 0; 30 | 31 | virtual void PopulateRequest(HttpRequest* p_request) = 0; 32 | 33 | inline Status status() const { return status_; } 34 | 35 | protected: 36 | AuthStrategy(const HttpProxy& proxy_ctx, Status status) 37 | : proxy_ctx_(proxy_ctx), status_(status), proxy_authentication_(false) {} 38 | 39 | inline bool proxy_authentication() const { return proxy_authentication_; } 40 | inline void set_proxy_authentication(const HttpResponse& response) { 41 | proxy_authentication_ = 42 | !response.GetHeaderValues("Proxy-Authenticate").empty(); 43 | } 44 | 45 | std::string ExtractAuthToken(const HttpResponse& response) const; 46 | 47 | protected: 48 | HttpProxy proxy_ctx_; 49 | Status status_; 50 | 51 | private: 52 | bool proxy_authentication_; 53 | }; 54 | 55 | } // proxy 56 | } // layer 57 | } // ssf 58 | 59 | #endif // SSF_LAYER_PROXY_AUTH_STRATEGY__H -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/base64.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_BASE64_H_ 2 | #define SSF_LAYER_PROXY_BASE64_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace ssf { 10 | namespace layer { 11 | namespace proxy { 12 | 13 | class Base64 { 14 | public: 15 | using Buffer = std::vector; 16 | 17 | public: 18 | static std::string Encode(const std::string& input); 19 | static std::string Encode(const Buffer& input); 20 | static Buffer Decode(const std::string& input); 21 | }; 22 | 23 | } // proxy 24 | } // layer 25 | } // ssf 26 | 27 | #endif // SSF_LAYER_PROXY_BASE64_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/basic_auth_strategy.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf/layer/proxy/base64.h" 2 | #include "ssf/layer/proxy/basic_auth_strategy.h" 3 | 4 | namespace ssf { 5 | namespace layer { 6 | namespace proxy { 7 | 8 | BasicAuthStrategy::BasicAuthStrategy(const HttpProxy& proxy_ctx) 9 | : AuthStrategy(proxy_ctx, Status::kAuthenticating), 10 | request_populated_(false) {} 11 | 12 | std::string BasicAuthStrategy::AuthName() const { return "Basic"; } 13 | 14 | bool BasicAuthStrategy::Support(const HttpResponse& response) const { 15 | return !request_populated_ && response.IsAuthenticationAllowed(AuthName()); 16 | } 17 | 18 | void BasicAuthStrategy::ProcessResponse(const HttpResponse& response) { 19 | if (response.Success()) { 20 | status_ = Status::kAuthenticated; 21 | return; 22 | } 23 | 24 | if (!Support(response)) { 25 | status_ = Status::kAuthenticationFailure; 26 | return; 27 | } 28 | 29 | set_proxy_authentication(response); 30 | } 31 | 32 | void BasicAuthStrategy::PopulateRequest(HttpRequest* p_request) { 33 | std::stringstream ss_credentials, header_value; 34 | ss_credentials << proxy_ctx_.username << ":" << proxy_ctx_.password; 35 | 36 | header_value << AuthName() << " " << Base64::Encode(ss_credentials.str()); 37 | 38 | p_request->AddHeader( 39 | proxy_authentication() ? "Proxy-Authorization" : "Authorization", 40 | header_value.str()); 41 | 42 | request_populated_ = true; 43 | } 44 | 45 | } // proxy 46 | } // layer 47 | } // ssf -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/basic_auth_strategy.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_BASIC_AUTH_STRATEGY_H_ 2 | #define SSF_LAYER_PROXY_BASIC_AUTH_STRATEGY_H_ 3 | 4 | #include "ssf/layer/proxy/auth_strategy.h" 5 | 6 | namespace ssf { 7 | namespace layer { 8 | namespace proxy { 9 | 10 | class BasicAuthStrategy : public AuthStrategy { 11 | public: 12 | BasicAuthStrategy(const HttpProxy& proxy); 13 | 14 | virtual ~BasicAuthStrategy(){}; 15 | 16 | std::string AuthName() const override; 17 | 18 | bool Support(const HttpResponse& response) const override; 19 | 20 | void ProcessResponse(const HttpResponse& response) override; 21 | 22 | void PopulateRequest(HttpRequest* p_request) override; 23 | 24 | private: 25 | bool request_populated_; 26 | }; 27 | 28 | } // proxy 29 | } // layer 30 | } // ssf 31 | 32 | #endif // SSF_LAYER_PROXY_BASIC_AUTH_STRATEGY_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/digest_auth_strategy.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_DIGEST_AUTH_STRATEGY_H_ 2 | #define SSF_LAYER_PROXY_DIGEST_AUTH_STRATEGY_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "ssf/layer/proxy/auth_strategy.h" 11 | 12 | namespace ssf { 13 | namespace layer { 14 | namespace proxy { 15 | 16 | class DigestAuthStrategy : public AuthStrategy { 17 | private: 18 | using Md5Digest = std::array; 19 | 20 | enum Qop { kNone, kAuth, kAuthInt }; 21 | 22 | public: 23 | DigestAuthStrategy(const HttpProxy& proxy_ctx); 24 | 25 | virtual ~DigestAuthStrategy(){}; 26 | 27 | std::string AuthName() const override; 28 | 29 | inline void set_cnonce(const std::string& cnonce) { cnonce_ = cnonce; } 30 | 31 | bool Support(const HttpResponse& response) const override; 32 | 33 | void ProcessResponse(const HttpResponse& response) override; 34 | 35 | void PopulateRequest(HttpRequest* p_request) override; 36 | 37 | private: 38 | void ParseDigestChallenge(const HttpResponse& response); 39 | std::string GenerateResponseDigest(const HttpRequest& request); 40 | std::string GenerateA1Hash(); 41 | std::string GenerateA2Hash(const HttpRequest& request); 42 | static std::string GenerateRandomString(std::size_t strlen); 43 | static std::string BufferToHex(unsigned char* buffer, std::size_t buffer_len); 44 | 45 | private: 46 | std::map challenge_; 47 | bool request_populated_; 48 | Qop qop_; 49 | std::string cnonce_; 50 | uint32_t nonce_count_; 51 | }; 52 | 53 | } // proxy 54 | } // layer 55 | } // ssf 56 | 57 | #endif // SSF_LAYER_PROXY_DIGEST_AUTH_STRATEGY_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/http_request.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ssf/layer/proxy/http_request.h" 4 | 5 | namespace ssf { 6 | namespace layer { 7 | namespace proxy { 8 | 9 | HttpRequest::HttpRequest() : method_(), uri_(), headers_() {} 10 | 11 | void HttpRequest::Reset(const std::string& method, const std::string& uri) { 12 | method_ = method; 13 | uri_ = uri; 14 | headers_.clear(); 15 | body_.clear(); 16 | AddHeader("Connection", "keep-alive"); 17 | } 18 | 19 | void HttpRequest::AddHeader(const std::string& name, const std::string& value) { 20 | headers_[name] = value; 21 | } 22 | 23 | std::string HttpRequest::GetHeaderValue(const std::string& name) { 24 | HeadersMap::const_iterator it = headers_.find(name); 25 | if (it == headers_.end()) { 26 | // header not found 27 | return ""; 28 | } 29 | 30 | return it->second; 31 | } 32 | 33 | std::string HttpRequest::Serialize() const { 34 | std::stringstream ss_request; 35 | std::string eol("\r\n"); 36 | 37 | ss_request << method_ << " " << uri_ << " HTTP/1.1" << eol; 38 | 39 | for (const auto& header : headers_) { 40 | ss_request << header.first << ": " << header.second << eol; 41 | } 42 | if (body_.size() > 0) { 43 | ss_request << "Content-Length: " << body_.size() << eol; 44 | } 45 | ss_request << eol; 46 | ss_request << body_; 47 | 48 | return ss_request.str(); 49 | } 50 | 51 | } // proxy 52 | } // layer 53 | } // ssf -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/http_request.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_HTTP_REQUEST_H_ 2 | #define SSF_LAYER_PROXY_HTTP_REQUEST_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ssf { 9 | namespace layer { 10 | namespace proxy { 11 | 12 | class HttpRequest { 13 | private: 14 | using HeadersMap = std::map; 15 | 16 | public: 17 | HttpRequest(); 18 | 19 | inline std::string method() const { return method_; } 20 | inline std::string uri() const { return uri_; } 21 | inline std::string body() const { return body_; } 22 | inline void set_body(const std::string& body) { body_ = body; } 23 | 24 | void Reset(const std::string& method, const std::string& uri); 25 | 26 | void AddHeader(const std::string& name, const std::string& value); 27 | 28 | std::string GetHeaderValue(const std::string& name); 29 | 30 | std::string Serialize() const; 31 | 32 | private: 33 | std::string method_; 34 | std::string uri_; 35 | HeadersMap headers_; 36 | std::string body_; 37 | }; 38 | 39 | } // proxy 40 | } // layer 41 | } // ssf 42 | 43 | #endif // SSF_LAYER_PROXY_HTTP_REQUEST_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/http_response.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_HTTP_RESPONSE_H_ 2 | #define SSF_LAYER_PROXY_HTTP_RESPONSE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ssf { 9 | namespace layer { 10 | namespace proxy { 11 | 12 | class HttpResponse { 13 | public: 14 | enum StatusCode : int { 15 | kOk = 200, 16 | kMovedPermanently = 301, 17 | kMovedTemporarily = 302, 18 | kUnauthorized = 401, 19 | kProxyAuthenticationRequired = 407 20 | }; 21 | 22 | private: 23 | using HeaderValues = std::list; 24 | using HeadersMap = std::map; 25 | 26 | public: 27 | HttpResponse(); 28 | 29 | inline int status_code() const { return status_code_; } 30 | inline void set_status_code(int status_code) { status_code_ = status_code; } 31 | 32 | inline std::string body() { return body_; } 33 | inline void set_body(const std::string& body) { body_ = body; } 34 | 35 | HeaderValues GetHeaderValues(const std::string& name) const; 36 | void AddHeader(const std::string& name, const std::string& value); 37 | 38 | void Reset(); 39 | 40 | bool Success() const; 41 | bool Redirected() const; 42 | 43 | bool CloseConnection() const; 44 | 45 | bool AuthenticationRequired() const; 46 | 47 | bool IsAuthenticationAllowed(const std::string& auth_name) const; 48 | 49 | private: 50 | // content offset in header or std::string::npos if not found 51 | std::size_t HeaderContains(const std::string& header_name, 52 | const std::string& content) const; 53 | 54 | bool HasHeaderValueBeginsWith(const std::string& header_name, 55 | const std::string& begin_with) const; 56 | 57 | private: 58 | int status_code_; 59 | HeadersMap headers_; 60 | std::string body_; 61 | }; 62 | 63 | } // proxy 64 | } // layer 65 | } // ssf 66 | 67 | #endif // SSF_LAYER_PROXY_HTTP_RESPONSE_H_ 68 | -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/http_session_initializer.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_HTTP_SESSION_INITIALIZER_H_ 2 | #define SSF_LAYER_PROXY_HTTP_SESSION_INITIALIZER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "ssf/layer/proxy/auth_strategy.h" 11 | #include "ssf/layer/proxy/http_response.h" 12 | #include "ssf/layer/proxy/proxy_endpoint_context.h" 13 | 14 | namespace ssf { 15 | namespace layer { 16 | namespace proxy { 17 | 18 | class HttpSessionInitializer { 19 | private: 20 | using AuthList = std::list>; 21 | 22 | public: 23 | enum Status : int { kError = -1, kSuccess = 0, kContinue = 1 }; 24 | enum Stage : int { kConnect = 1, kProcessing = 2 }; 25 | 26 | public: 27 | HttpSessionInitializer(); 28 | 29 | void Reset(const std::string& target_host, const std::string& target_port, 30 | const ProxyEndpointContext& proxy_ep_ctx); 31 | 32 | inline Status status() { return status_; } 33 | 34 | inline Stage stage() { return stage_; } 35 | 36 | void PopulateRequest(HttpRequest* p_request, boost::system::error_code& ec); 37 | 38 | void ProcessResponse(const HttpResponse& response, 39 | boost::system::error_code& ec); 40 | 41 | private: 42 | void SetAuthStrategy(const HttpResponse& response); 43 | 44 | private: 45 | Status status_; 46 | Stage stage_; 47 | std::string target_host_; 48 | std::string target_port_; 49 | ProxyEndpointContext proxy_ep_ctx_; 50 | AuthList auth_strategies_; 51 | AuthStrategy* p_current_auth_strategy_; 52 | }; 53 | 54 | } // proxy 55 | } // layer 56 | } // ssf 57 | 58 | #endif // SSF_LAYER_PROXY_HTTP_SESSION_INITIALIZER_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/negotiate_auth_strategy.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_NEGOTIATE_AUTH_STRATEGY_H_ 2 | #define SSF_LAYER_PROXY_NEGOTIATE_AUTH_STRATEGY_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "ssf/layer/proxy/auth_strategy.h" 8 | #include "ssf/layer/proxy/platform_auth_impl.h" 9 | 10 | namespace ssf { 11 | namespace layer { 12 | namespace proxy { 13 | 14 | class NegotiateAuthStrategy : public AuthStrategy { 15 | public: 16 | NegotiateAuthStrategy(const HttpProxy& proxy_ctx); 17 | 18 | virtual ~NegotiateAuthStrategy(){}; 19 | 20 | std::string AuthName() const override; 21 | 22 | bool Support(const HttpResponse& response) const override; 23 | 24 | void ProcessResponse(const HttpResponse& response) override; 25 | 26 | void PopulateRequest(HttpRequest* p_request) override; 27 | 28 | private: 29 | std::unique_ptr p_impl_; 30 | }; 31 | 32 | } // proxy 33 | } // layer 34 | } // ssf 35 | 36 | #endif // SSF_LAYER_PROXY_NEGOTIATE_AUTH_STRATEGY_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/ntlm_auth_strategy.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_NTLM_AUTH_STRATEGY_H_ 2 | #define SSF_LAYER_PROXY_NTLM_AUTH_STRATEGY_H_ 3 | 4 | #include "ssf/layer/proxy/auth_strategy.h" 5 | #include "ssf/layer/proxy/platform_auth_impl.h" 6 | 7 | namespace ssf { 8 | namespace layer { 9 | namespace proxy { 10 | 11 | class NtlmAuthStrategy : public AuthStrategy { 12 | public: 13 | NtlmAuthStrategy(const HttpProxy& proxy_ctx); 14 | 15 | virtual ~NtlmAuthStrategy(){}; 16 | 17 | std::string AuthName() const override; 18 | 19 | bool Support(const HttpResponse& response) const override; 20 | 21 | void ProcessResponse(const HttpResponse& response) override; 22 | 23 | void PopulateRequest(HttpRequest* p_request) override; 24 | 25 | private: 26 | std::unique_ptr p_impl_; 27 | }; 28 | 29 | } // proxy 30 | } // layer 31 | } // ssf 32 | 33 | #endif // SSF_LAYER_PROXY_NTLM_AUTH_STRATEGY_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/platform_auth_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_PLATFORM_AUTH_IMPL_H_ 2 | #define SSF_LAYER_PROXY_PLATFORM_AUTH_IMPL_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "ssf/layer/proxy/proxy_endpoint_context.h" 9 | 10 | namespace ssf { 11 | namespace layer { 12 | namespace proxy { 13 | 14 | class PlatformAuthImpl { 15 | public: 16 | enum State { kFailure, kInit, kContinue, kSuccess }; 17 | using Token = std::vector; 18 | 19 | public: 20 | virtual ~PlatformAuthImpl() {} 21 | 22 | virtual bool Init() = 0; 23 | virtual bool ProcessServerToken(const Token& server_token) = 0; 24 | virtual Token GetAuthToken() = 0; 25 | 26 | protected: 27 | PlatformAuthImpl(const HttpProxy& proxy_ctx) 28 | : state_(kInit), proxy_ctx_(proxy_ctx) {} 29 | 30 | protected: 31 | State state_; 32 | HttpProxy proxy_ctx_; 33 | }; 34 | 35 | } // proxy 36 | } // layer 37 | } // ssf 38 | 39 | #endif // SSF_LAYER_PROXY_PLATFORM_AUTH_IMPL_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/proxy_helpers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "ssf/error/error.h" 5 | #include "ssf/layer/proxy/proxy_helpers.h" 6 | #include "ssf/log/log.h" 7 | #include "ssf/utils/map_helpers.h" 8 | 9 | namespace ssf { 10 | namespace layer { 11 | namespace proxy { 12 | 13 | bool CanResolveHost(boost::asio::io_service& io_service, 14 | const std::string& addr, const std::string& port) { 15 | boost::system::error_code ec; 16 | boost::asio::ip::tcp::resolver resolver(io_service); 17 | boost::asio::ip::tcp::resolver::query query(addr, port); 18 | resolver.resolve(query, ec); 19 | 20 | return ec.value() == 0; 21 | } 22 | 23 | ProxyEndpointContext MakeProxyContext(boost::asio::io_service& io_service, 24 | const LayerParameters& parameters, 25 | boost::system::error_code& ec) { 26 | ProxyEndpointContext context; 27 | 28 | context.Init(parameters); 29 | 30 | if (context.HttpProxyEnabled() && 31 | !CanResolveHost(io_service, context.http_proxy().host, 32 | context.http_proxy().port)) { 33 | ec.assign(ssf::error::bad_address, ssf::error::get_ssf_category()); 34 | SSF_LOG("network_proxy", error, 35 | "could not resolve HTTP target address <{}:{}>", 36 | context.http_proxy().host, context.http_proxy().port); 37 | } 38 | if (context.SocksProxyEnabled() && 39 | !CanResolveHost(io_service, context.socks_proxy().host, 40 | context.socks_proxy().port)) { 41 | ec.assign(ssf::error::bad_address, ssf::error::get_ssf_category()); 42 | 43 | SSF_LOG("network_proxy", error, 44 | "could not resolve SOCKS target address <{}:{}>", 45 | context.socks_proxy().host, context.socks_proxy().port); 46 | } 47 | 48 | return context; 49 | } 50 | 51 | } // proxy 52 | } // layer 53 | } // ssf -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/proxy_helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_PROXY_HELPERS_H_ 2 | #define SSF_LAYER_PROXY_PROXY_HELPERS_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "ssf/layer/parameters.h" 9 | 10 | #include "ssf/layer/proxy/proxy_endpoint_context.h" 11 | 12 | namespace ssf { 13 | namespace layer { 14 | namespace proxy { 15 | 16 | ProxyEndpointContext MakeProxyContext(boost::asio::io_service& io_service, 17 | const LayerParameters& parameters, 18 | boost::system::error_code& ec); 19 | 20 | } // proxy 21 | } // layer 22 | } // ssf 23 | 24 | #endif // SSF_LAYER_PROXY_PROXY_HELPERS_H_ 25 | -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/socks4_strategy.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_SOCKS4_STRATEGY_H_ 2 | #define SSF_LAYER_PROXY_SOCKS4_STRATEGY_H_ 3 | 4 | #include "ssf/layer/proxy/socks_strategy.h" 5 | 6 | #include "ssf/network/socks/v4/request.h" 7 | #include "ssf/network/socks/v4/reply.h" 8 | 9 | namespace ssf { 10 | namespace layer { 11 | namespace proxy { 12 | 13 | class Socks4Strategy : public SocksStrategy { 14 | private: 15 | using Request = ssf::network::socks::v4::Request; 16 | using Reply = ssf::network::socks::v4::Reply; 17 | 18 | public: 19 | Socks4Strategy(); 20 | 21 | // SocksStrategy 22 | void Init(boost::system::error_code& ec) override; 23 | 24 | void PopulateRequest(const std::string& host, uint16_t port, 25 | Buffer* p_request, uint32_t* p_expected_response_size, 26 | boost::system::error_code& ec) override; 27 | void ProcessResponse(const Buffer& response, 28 | boost::system::error_code& ec) override; 29 | }; 30 | 31 | } // proxy 32 | } // layer 33 | } // ssf 34 | 35 | #endif // SSF_LAYER_PROXY_SOCKS4_STRATEGY_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/socks_session_initializer.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_SOCKS_SESSION_INITIALIZER_H_ 2 | #define SSF_LAYER_PROXY_SOCKS_SESSION_INITIALIZER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "ssf/layer/proxy/proxy_endpoint_context.h" 13 | #include "ssf/layer/proxy/socks4_strategy.h" 14 | #include "ssf/layer/proxy/socks5_strategy.h" 15 | 16 | namespace ssf { 17 | namespace layer { 18 | namespace proxy { 19 | 20 | class SocksSessionInitializer { 21 | public: 22 | using Buffer = std::vector; 23 | enum class Status : int { kError = -1, kSuccess = 0, kContinue = 1 }; 24 | 25 | public: 26 | SocksSessionInitializer(); 27 | 28 | void Reset(const std::string& target_host, const std::string& target_port, 29 | const ProxyEndpointContext& proxy_ep_ctx, 30 | boost::system::error_code& ec); 31 | 32 | inline Status status() { return status_; } 33 | 34 | void PopulateRequest(Buffer* p_request, uint32_t* p_expected_response_size, 35 | boost::system::error_code& ec); 36 | 37 | void ProcessResponse(const Buffer& response, boost::system::error_code& ec); 38 | 39 | private: 40 | Status status_; 41 | std::string target_host_; 42 | uint16_t target_port_; 43 | ProxyEndpointContext proxy_ep_ctx_; 44 | 45 | Socks4Strategy socks4_strategy_; 46 | Socks5Strategy socks5_strategy_; 47 | }; 48 | 49 | } // ssf 50 | } // layer 51 | } // ssf 52 | 53 | #endif // SSF_LAYER_PROXY_SOCKS_SESSION_INITIALIZER_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/socks_strategy.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_SOCKS_STRATEGY_H_ 2 | #define SSF_LAYER_PROXY_SOCKS_STRATEGY_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "ssf/layer/proxy/proxy_endpoint_context.h" 8 | 9 | namespace ssf { 10 | namespace layer { 11 | namespace proxy { 12 | 13 | class SocksStrategy { 14 | public: 15 | enum State { 16 | kError = -1, 17 | kAuthenticating = 0, 18 | kConnecting = 1, 19 | kConnected = 2 20 | }; 21 | 22 | using Buffer = std::vector; 23 | 24 | public: 25 | virtual ~SocksStrategy() {} 26 | 27 | virtual void Init(boost::system::error_code& ec) = 0; 28 | 29 | // @param p_expected_response_size response size in bytes expected from this 30 | // request 31 | virtual void PopulateRequest(const std::string& host, uint16_t port, 32 | Buffer* p_request, 33 | uint32_t* p_expected_response_size, 34 | boost::system::error_code& ec) = 0; 35 | 36 | virtual void ProcessResponse(const Buffer& response, 37 | boost::system::error_code& ec) = 0; 38 | 39 | State state() const { return state_; }; 40 | void set_state(State state) { state_ = state; } 41 | 42 | protected: 43 | SocksStrategy(State state) : state_(state) {} 44 | 45 | private: 46 | State state_; 47 | }; 48 | 49 | } // proxy 50 | } // layer 51 | } // ssf 52 | 53 | #endif // SSF_LAYER_PROXY_SOCKS_STRATEGY_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/unix/gssapi_auth_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_UNIX_GSSAPI_AUTH_IMPL_H_ 2 | #define SSF_LAYER_PROXY_UNIX_GSSAPI_AUTH_IMPL_H_ 3 | 4 | #if defined(__APPLE__) 5 | #include 6 | #if defined(MAC_OS_X_VERSION_10_9) && \ 7 | MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 8 | #define GSSKRB_APPLE_DEPRECATED(x) 9 | #endif 10 | #endif 11 | 12 | #if defined(__APPLE__) 13 | #include 14 | #else 15 | #include 16 | #endif 17 | 18 | #include "ssf/layer/proxy/platform_auth_impl.h" 19 | 20 | namespace ssf { 21 | namespace layer { 22 | namespace proxy { 23 | 24 | class GSSAPIAuthImpl : public PlatformAuthImpl { 25 | private: 26 | using fct_gss_init_sec_context_t = decltype(&gss_init_sec_context); 27 | using fct_gss_import_name_t = decltype(&gss_import_name); 28 | using fct_gss_release_buffer_t = decltype(&gss_release_buffer); 29 | using fct_gss_delete_sec_context_t = decltype(&gss_delete_sec_context); 30 | using fct_gss_release_name_t = decltype(&gss_release_name); 31 | 32 | public: 33 | GSSAPIAuthImpl(const HttpProxy& proxy_ctx); 34 | 35 | virtual ~GSSAPIAuthImpl(); 36 | 37 | bool Init() override; 38 | bool ProcessServerToken(const Token& server_token) override; 39 | Token GetAuthToken() override; 40 | 41 | private: 42 | bool InitLibrary(); 43 | void LogError(OM_uint32 major_status); 44 | 45 | private: 46 | void* h_gss_api_; 47 | gss_ctx_id_t h_sec_ctx_; 48 | gss_name_t server_name_; 49 | Token auth_token_; 50 | 51 | fct_gss_init_sec_context_t fct_gss_init_sec_context_; 52 | fct_gss_import_name_t fct_gss_import_name_; 53 | fct_gss_release_buffer_t fct_gss_release_buffer_; 54 | fct_gss_delete_sec_context_t fct_gss_delete_sec_context_; 55 | fct_gss_release_name_t fct_gss_release_name_; 56 | }; 57 | 58 | } // proxy 59 | } // layer 60 | } // ssf 61 | 62 | #endif // SSF_LAYER_PROXY_UNIX_GSSAPI_AUTH_IMPL_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/proxy/windows/sspi_auth_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_PROXY_WINDOWS_SSPI_AUTH_IMPL_H_ 2 | #define SSF_LAYER_PROXY_WINDOWS_SSPI_AUTH_IMPL_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "ssf/layer/proxy/platform_auth_impl.h" 8 | 9 | #define SECURITY_WIN32 10 | #include 11 | #include 12 | 13 | namespace ssf { 14 | namespace layer { 15 | namespace proxy { 16 | 17 | class SSPIAuthImpl : public PlatformAuthImpl { 18 | private: 19 | using SecPackageNames = std::array; 20 | 21 | public: 22 | enum SecurityPackage { kNTLM = 0, kNegotiate }; 23 | 24 | public: 25 | SSPIAuthImpl(SecurityPackage sec_package, const HttpProxy& proxy_ctx); 26 | 27 | virtual ~SSPIAuthImpl(); 28 | 29 | bool Init() override; 30 | bool ProcessServerToken(const Token& server_token) override; 31 | Token GetAuthToken() override; 32 | 33 | private: 34 | static std::string GenerateSecurityPackageName(SecurityPackage sec_package); 35 | bool IsSecurityContextSet(); 36 | std::string GenerateServiceName(SecurityPackage sec_package); 37 | void Clear(); 38 | 39 | private: 40 | static SecPackageNames sec_package_names_; 41 | SecurityPackage sec_package_; 42 | CredHandle h_cred_; 43 | CtxtHandle h_sec_ctx_; 44 | Token output_token_; 45 | std::size_t output_token_length_; 46 | std::string service_name_; 47 | }; 48 | 49 | } // proxy 50 | } // layer 51 | } // ssf 52 | 53 | #endif // SSF_LAYER_PROXY_WINDOWS_SSPI_AUTH_IMPL_H_ -------------------------------------------------------------------------------- /src/network/ssf/layer/queue/active_item.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_QUEUE_ACTIVE_ITEM_H_ 2 | #define SSF_LAYER_QUEUE_ACTIVE_ITEM_H_ 3 | 4 | #include 5 | 6 | namespace ssf { 7 | namespace layer { 8 | namespace queue { 9 | 10 | template 11 | class ActiveItem { 12 | public: 13 | ActiveItem(Item item) : active_(true), item_(std::move(item)) {} 14 | 15 | bool IsActive() const { return active_; } 16 | 17 | void Disactivate() { active_ = false; } 18 | 19 | const Item& item() const { return item_; } 20 | Item& item() { return item_; } 21 | 22 | private: 23 | bool active_; 24 | Item item_; 25 | }; 26 | 27 | template 28 | using ActiveItemPtr = std::shared_ptr>; 29 | 30 | template 31 | ActiveItem::type> make_active( 32 | Item&& item) { 33 | return ActiveItem::type>( 34 | std::forward(item)); 35 | } 36 | 37 | template 38 | ActiveItemPtr::type> make_shared_active( 39 | Item&& item) { 40 | return std::make_shared< 41 | ActiveItem::type>>( 42 | std::forward); 43 | } 44 | 45 | } // queue 46 | } // layer 47 | } // ssf 48 | 49 | #endif // SSF_LAYER_QUEUE_ACTIVE_ITEM_H_ 50 | -------------------------------------------------------------------------------- /src/network/ssf/layer/queue/tagged_item.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_QUEUE_TAGGED_ITEM_H_ 2 | #define SSF_LAYER_QUEUE_TAGGED_ITEM_H_ 3 | 4 | #include 5 | 6 | namespace ssf { 7 | namespace layer { 8 | namespace queue { 9 | 10 | template 11 | struct TaggedItem { 12 | TaggedItem(Tag t, Item i) : tag(std::move(t)), item(std::move(i)) {} 13 | 14 | Tag tag; 15 | Item item; 16 | }; 17 | 18 | template 19 | using TaggedItemPtr = std::shared_ptr>; 20 | 21 | template 22 | TaggedItem::type, 23 | typename std::remove_reference::type> 24 | make_tagged(Tag&& tag, Item&& item) { 25 | return TaggedItem::type, 26 | typename std::remove_reference::type>{ 27 | std::forward(tag), std::forward(item)}; 28 | } 29 | 30 | template 31 | TaggedItemPtr::type, 32 | typename std::remove_reference::type> 33 | make_shared_tagged(Tag&& tag, Item&& item) { 34 | return std::make_shared< 35 | TaggedItem::type, 36 | typename std::remove_reference::type>>( 37 | std::forward(tag), std::forward(item)); 38 | } 39 | 40 | } // queue 41 | } // layer 42 | } // ssf 43 | 44 | #endif // SSF_LAYER_QUEUE_TAGGED_ITEM_H_ 45 | -------------------------------------------------------------------------------- /src/network/ssf/layer/routing/basic_routing_selector.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LAYER_ROUTING_BASIC_ROUTING_SELECTOR_H_ 2 | #define SSF_LAYER_ROUTING_BASIC_ROUTING_SELECTOR_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "ssf/error/error.h" 12 | 13 | namespace ssf { 14 | namespace layer { 15 | namespace routing { 16 | 17 | template 18 | class RoutingSelector { 19 | public: 20 | typedef TRoutingTable RoutingTable; 21 | 22 | public: 23 | RoutingSelector() : p_routing_table_(nullptr) {} 24 | 25 | RoutingSelector(RoutingSelector&& other) 26 | : p_routing_table_(std::move(other.p_routing_selector)) {} 27 | 28 | void set_routing_table(RoutingTable* p_routing_table) { 29 | p_routing_table_ = p_routing_table; 30 | } 31 | 32 | /// Update p_id by resolving the destination id of the element 33 | bool operator()(Identifier* p_id, Element* p_element) const { 34 | boost::system::error_code ec; 35 | 36 | *p_id = p_routing_table_->Resolve( 37 | p_element->header().id().GetSecondHalfId(), ec); 38 | 39 | return !ec; 40 | } 41 | 42 | private: 43 | RoutingTable* p_routing_table_; 44 | }; 45 | 46 | } // routing 47 | } // layer 48 | } // ssf 49 | 50 | #endif // SSF_LAYER_ROUTING_BASIC_ROUTING_SELECTOR_H_ 51 | -------------------------------------------------------------------------------- /src/network/ssf/log/log.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf/log/log.h" 2 | 3 | #ifdef SSF_DISABLE_LOGS 4 | 5 | void SetLogLevel(spdlog::level::level_enum level) {} 6 | 7 | #else 8 | 9 | #if defined(_MSC_VER) 10 | #include "spdlog/sinks/msvc_sink.h" 11 | #elif defined(__unix__) || defined(__APPLE__) 12 | #include "spdlog/sinks/ansicolor_sink.h" 13 | #ifdef SSF_ENABLE_SYSLOG 14 | #define SPDLOG_ENABLE_SYSLOG 15 | #include "spdlog/sinks/syslog_sink.h" 16 | #endif 17 | #endif // defined(_MSC_VER) 18 | 19 | void SetLogLevel(spdlog::level::level_enum level) { 20 | ssf::log::GetManager().SetLevel(level); 21 | } 22 | 23 | namespace ssf { 24 | namespace log { 25 | 26 | Manager& GetManager() { 27 | static Manager manager; 28 | return manager; 29 | } 30 | 31 | Manager::Manager() { 32 | spdlog::set_level(spdlog::level::info); 33 | spdlog::set_pattern("[%Y-%m-%dT%H:%M:%S%z] [%l] [%n] %v"); 34 | } 35 | 36 | std::shared_ptr Manager::GetChannel(const std::string& name) { 37 | auto channel = spdlog::get(name); 38 | if (!channel) { 39 | channel = CreateChannel(name); 40 | } 41 | return channel; 42 | } 43 | 44 | void Manager::SetLevel(spdlog::level::level_enum level) { 45 | spdlog::set_level(level); 46 | } 47 | 48 | std::shared_ptr Manager::CreateChannel( 49 | const std::string& name) { 50 | std::vector sinks; 51 | 52 | #if defined(_MSC_VER) 53 | sinks.push_back(std::make_shared()); 54 | sinks.push_back(std::make_shared()); 55 | #elif defined(__unix__) || defined(__APPLE__) 56 | sinks.push_back(std::make_shared()); 57 | #if defined(SSF_ENABLE_SYSLOG) 58 | sinks.push_back(std::make_shared()); 59 | #endif // defined(SSF_ENABLE_SYSLOG) 60 | #endif // defined(_MSC_VER) 61 | 62 | std::shared_ptr logger; 63 | try { 64 | logger = spdlog::create(name, sinks.cbegin(), sinks.cend()); 65 | } catch (const std::exception&) { 66 | logger = spdlog::get(name); 67 | } 68 | 69 | return logger; 70 | } 71 | 72 | } // log 73 | } // ssf 74 | 75 | #endif // SSF_DISABLE_LOGS 76 | -------------------------------------------------------------------------------- /src/network/ssf/log/log.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_LOG_LOG_H_ 2 | #define SSF_LOG_LOG_H_ 3 | 4 | #include 5 | 6 | void SetLogLevel(spdlog::level::level_enum level = spdlog::level::info); 7 | 8 | #ifdef SSF_DISABLE_LOGS 9 | #define SSF_LOG(...) 10 | #else 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace ssf { 18 | namespace log { 19 | 20 | class Manager { 21 | public: 22 | Manager(); 23 | 24 | std::shared_ptr GetChannel(const std::string& channel); 25 | void SetLevel(spdlog::level::level_enum level); 26 | 27 | private: 28 | std::shared_ptr CreateChannel(const std::string& channel); 29 | }; 30 | 31 | Manager& GetManager(); 32 | 33 | #define SSF_LOG(channel, level, ...) \ 34 | ssf::log::GetManager().GetChannel(channel)->level(__VA_ARGS__); 35 | 36 | } // log 37 | } // ssf 38 | 39 | #endif // SSF_DISABLE_LOGS 40 | 41 | #endif // SSF_LOG_LOG_H_ 42 | -------------------------------------------------------------------------------- /src/network/ssf/network/base_session.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_NETWORK_BASE_SESSION_H_ 2 | #define SSF_NETWORK_BASE_SESSION_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace ssf { 9 | 10 | /// Base class for ActionableItem types 11 | class BaseSession : public std::enable_shared_from_this { 12 | public: 13 | BaseSession() {} 14 | virtual void start(boost::system::error_code&) = 0; 15 | virtual void stop(boost::system::error_code&) = 0; 16 | virtual ~BaseSession() {} 17 | 18 | private: 19 | // Make non-copyable 20 | BaseSession(const BaseSession&); 21 | BaseSession& operator=(const BaseSession&); 22 | }; 23 | 24 | typedef std::shared_ptr BaseSessionPtr; 25 | 26 | } // ssf 27 | 28 | #endif // SSF_NETWORK_BASE_SESSION_H_ 29 | -------------------------------------------------------------------------------- /src/network/ssf/network/socks/socks.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_NETWORK_SOCKS_H_ 2 | #define SSF_NETWORK_SOCKS_H_ 3 | 4 | #include 5 | 6 | namespace ssf { 7 | namespace network { 8 | 9 | struct Socks { 10 | enum class Version : uint8_t { kVUnknown = 0, kV4 = 0x04, kV5 = 0x05 }; 11 | }; 12 | 13 | } // network 14 | } // ssf 15 | 16 | #endif // SSF_NETWORK_SOCKS_H_ 17 | -------------------------------------------------------------------------------- /src/network/ssf/network/socks/v4/reply.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ssf/network/socks/v4/reply.h" 4 | 5 | #include "ssf/network/socks/socks.h" 6 | 7 | namespace ssf { 8 | namespace network { 9 | namespace socks { 10 | namespace v4 { 11 | 12 | Reply::Reply() 13 | : null_byte_(0), 14 | status_(ToIntegral(Status::kFailed)), 15 | port_high_byte_(0), 16 | port_low_byte_(0), 17 | address_() {} 18 | 19 | Reply::Reply(const boost::system::error_code& err, 20 | const boost::asio::ip::tcp::endpoint& ep) 21 | : null_byte_(0), status_(ToIntegral(Status::kFailed)) { 22 | uint16_t port = ep.port(); 23 | port_high_byte_ = (port >> 8) & 0xff; 24 | port_low_byte_ = port & 0xff; 25 | address_ = ep.address().to_v4().to_bytes(); 26 | if (!err) { 27 | status_ = ToIntegral(Status::kGranted); 28 | } 29 | } 30 | 31 | std::array Reply::ConstBuffer() const { 32 | return {{boost::asio::buffer(&null_byte_, 1), boost::asio::buffer(&status_, 1), 33 | boost::asio::buffer(&port_high_byte_, 1), 34 | boost::asio::buffer(&port_low_byte_, 1), 35 | boost::asio::buffer(address_)}}; 36 | } 37 | 38 | std::array Reply::MutBuffer() { 39 | return {{boost::asio::buffer(&null_byte_, 1), boost::asio::buffer(&status_, 1), 40 | boost::asio::buffer(&port_high_byte_, 1), 41 | boost::asio::buffer(&port_low_byte_, 1), 42 | boost::asio::buffer(address_)}}; 43 | } 44 | 45 | } // v4 46 | } // socks 47 | } // network 48 | } // ssf 49 | -------------------------------------------------------------------------------- /src/network/ssf/network/socks/v4/reply.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_NETWORK_SOCKS_V4_REPLY_H_ 2 | #define SSF_NETWORK_SOCKS_V4_REPLY_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace ssf { 14 | namespace network { 15 | namespace socks { 16 | namespace v4 { 17 | 18 | class Reply { 19 | public: 20 | // Status constants 21 | enum class Status : uint8_t { 22 | kGranted = 0x5a, 23 | kFailed = 0x5b, 24 | kFailedNoIdentd = 0x5c, 25 | kFailedBadUser = 0x5d 26 | }; 27 | 28 | public: 29 | Reply(); 30 | Reply(const boost::system::error_code&, 31 | const boost::asio::ip::tcp::endpoint&); 32 | 33 | uint8_t null_byte() { return null_byte_; } 34 | 35 | Status status() const { return Status(status_); } 36 | 37 | std::array ConstBuffer() const; 38 | std::array MutBuffer(); 39 | 40 | private: 41 | uint8_t null_byte_; 42 | uint8_t status_; 43 | uint8_t port_high_byte_; 44 | uint8_t port_low_byte_; 45 | boost::asio::ip::address_v4::bytes_type address_; 46 | }; 47 | 48 | } // v4 49 | } // socks 50 | } // network 51 | } // ssf 52 | 53 | #endif // SSF_NETWORK_SOCKS_V4_REPLY_H_ 54 | -------------------------------------------------------------------------------- /src/network/ssf/network/socks/v4/request.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_NETWORK_SOCKS_V4_REQUEST_H_ 2 | #define SSF_NETWORK_SOCKS_V4_REQUEST_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace ssf { 17 | namespace network { 18 | namespace socks { 19 | namespace v4 { 20 | 21 | class Request { 22 | public: 23 | enum class Command : uint8_t { kConnect = 0x01, kBind = 0x02 }; 24 | 25 | public: 26 | void Init(Command cmd, const std::string& addr, uint16_t port, 27 | boost::system::error_code& ec); 28 | 29 | uint8_t command() const { return command_; }; 30 | 31 | std::string name() const { return name_; }; 32 | 33 | std::string domain() const { return domain_; }; 34 | 35 | uint16_t port() const; 36 | 37 | void set_name(const std::string& name) { name_ = name; } 38 | 39 | void set_domain(const std::string& domain) { domain_ = domain; } 40 | 41 | bool Is4aVersion() const; 42 | 43 | boost::asio::ip::tcp::endpoint Endpoint() const; 44 | 45 | std::array MutBuffer(); 46 | 47 | std::vector ConstBuffer() const; 48 | 49 | private: 50 | uint8_t version_; 51 | uint8_t command_; 52 | uint8_t port_high_byte_; 53 | uint8_t port_low_byte_; 54 | uint8_t null_byte_; 55 | boost::asio::ip::address_v4::bytes_type address_; 56 | std::string name_; 57 | std::string domain_; 58 | }; 59 | 60 | } // v4 61 | } // socks 62 | } // network 63 | } // ssf 64 | 65 | #endif // SSF_NETWORK_SOCKS_V4_REQUEST_H_ 66 | -------------------------------------------------------------------------------- /src/network/ssf/network/socks/v5/reply_auth.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf/network/socks/v5/reply_auth.h" 2 | 3 | #include "ssf/network/socks/socks.h" 4 | 5 | #include "ssf/utils/enum.h" 6 | 7 | namespace ssf { 8 | namespace network { 9 | namespace socks { 10 | namespace v5 { 11 | 12 | ReplyAuth::ReplyAuth() {} 13 | 14 | ReplyAuth::ReplyAuth(AuthMethod auth_method) 15 | : version_(ToIntegral(Socks::Version::kV5)), 16 | auth_method_(ToIntegral(auth_method)) {} 17 | 18 | std::array ReplyAuth::ConstBuffer() const { 19 | return {{ 20 | boost::asio::buffer(&version_, 1), boost::asio::buffer(&auth_method_, 1) 21 | }}; 22 | } 23 | 24 | std::array ReplyAuth::MutBuffer() { 25 | return {{boost::asio::buffer(&version_, 1), 26 | boost::asio::buffer(&auth_method_, 1)}}; 27 | } 28 | 29 | } // v5 30 | } // socks 31 | } // network 32 | } // ssf 33 | -------------------------------------------------------------------------------- /src/network/ssf/network/socks/v5/reply_auth.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_NETWORK_SOCKS_V5_REPLY_AUTH_H_ 2 | #define SSF_NETWORK_SOCKS_V5_REPLY_AUTH_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "ssf/network/socks/v5/request_auth.h" 10 | #include "ssf/network/socks/v5/types.h" 11 | 12 | namespace ssf { 13 | namespace network { 14 | namespace socks { 15 | namespace v5 { 16 | 17 | class ReplyAuth { 18 | public: 19 | ReplyAuth(); 20 | ReplyAuth(AuthMethod auth_method); 21 | 22 | uint8_t auth_method() const { return auth_method_; } 23 | 24 | std::array ConstBuffer() const; 25 | std::array MutBuffer(); 26 | 27 | private: 28 | uint8_t version_; 29 | uint8_t auth_method_; 30 | }; 31 | 32 | } // v5 33 | } // socks 34 | } // network 35 | } // ssf 36 | 37 | #endif // SSF_NETWORK_SOCKS_V5_REPLY_AUTH_H_ 38 | -------------------------------------------------------------------------------- /src/network/ssf/network/socks/v5/request.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_NETWORK_SOCKS_V5_REQUEST_H_ 2 | #define SSF_NETWORK_SOCKS_V5_REQUEST_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "ssf/network/socks/v5/types.h" 17 | 18 | namespace ssf { 19 | namespace network { 20 | namespace socks { 21 | namespace v5 { 22 | 23 | class Request { 24 | public: 25 | void Init(const std::string& target_addr, uint16_t target_port, 26 | boost::system::error_code& ec); 27 | 28 | uint8_t version() const { return version_; } 29 | 30 | uint8_t command() const { return command_; } 31 | 32 | uint8_t address_type() const { return address_type_; } 33 | 34 | boost::asio::ip::address_v4::bytes_type ipv4() const { return ipv4_; } 35 | 36 | uint8_t domain_length() const { return domain_length_; } 37 | 38 | std::vector domain() const { return domain_; } 39 | 40 | boost::asio::ip::address_v6::bytes_type ipv6() const { return ipv6_; } 41 | 42 | uint16_t port() const; 43 | 44 | std::vector ConstBuffers() const; 45 | 46 | std::array FirstPartBuffers(); 47 | std::array DomainLengthBuffer(); 48 | std::vector AddressBuffer(); 49 | std::array PortBuffers(); 50 | 51 | private: 52 | uint8_t version_; 53 | uint8_t command_; 54 | uint8_t reserved_; 55 | uint8_t address_type_; 56 | 57 | boost::asio::ip::address_v4::bytes_type ipv4_; 58 | 59 | uint8_t domain_length_; 60 | std::vector domain_; 61 | 62 | boost::asio::ip::address_v6::bytes_type ipv6_; 63 | 64 | uint8_t port_high_byte_; 65 | uint8_t port_low_byte_; 66 | }; 67 | 68 | } // v5 69 | } // socks 70 | } // network 71 | } // ssf 72 | 73 | #endif // SSF_NETWORK_SOCKS_V5_REQUEST_H_ 74 | -------------------------------------------------------------------------------- /src/network/ssf/network/socks/v5/request_auth.cpp: -------------------------------------------------------------------------------- 1 | #include "ssf/network/socks/v5/request_auth.h" 2 | 3 | #include "ssf/network/socks/socks.h" 4 | 5 | #include "ssf/utils/enum.h" 6 | 7 | namespace ssf { 8 | namespace network { 9 | namespace socks { 10 | namespace v5 { 11 | 12 | RequestAuth::RequestAuth() 13 | : version_(ToIntegral(Socks::Version::kV5)), auth_supported_count_(0) {} 14 | 15 | void RequestAuth::Init(const std::vector& methods) { 16 | version_ = ToIntegral(Socks::Version::kV5); 17 | auth_supported_count_ = static_cast(methods.size()); 18 | for (const auto& method : methods) { 19 | auth_methods_.push_back(ToIntegral(method)); 20 | } 21 | } 22 | 23 | void RequestAuth::AddAuthMethod(uint8_t auth_method) { 24 | auth_methods_.push_back(auth_method); 25 | } 26 | 27 | boost::asio::mutable_buffers_1 RequestAuth::MutAuthSupportedBuffers() { 28 | return boost::asio::mutable_buffers_1( 29 | boost::asio::buffer(&auth_supported_count_, 1)); 30 | } 31 | 32 | boost::asio::mutable_buffers_1 RequestAuth::MutAuthBuffers() { 33 | if (auth_methods_.size() != auth_supported_count_) { 34 | auth_methods_.resize(auth_supported_count_); 35 | } 36 | 37 | return boost::asio::mutable_buffers_1(boost::asio::buffer(auth_methods_)); 38 | } 39 | 40 | std::vector RequestAuth::ConstBuffers() { 41 | return {{boost::asio::buffer(&version_, 1), 42 | boost::asio::buffer(&auth_supported_count_, 1), 43 | boost::asio::buffer(auth_methods_)}}; 44 | } 45 | 46 | bool RequestAuth::IsNoAuthPresent() { 47 | for (const auto& auth_method : auth_methods_) { 48 | if (auth_method == ToIntegral(AuthMethod::kNoAuth)) { 49 | return true; 50 | } 51 | } 52 | 53 | return false; 54 | } 55 | 56 | } // v5 57 | } // socks 58 | } // network 59 | } // ssf 60 | -------------------------------------------------------------------------------- /src/network/ssf/network/socks/v5/request_auth.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_NETWORK_SOCKS_V5_REQUEST_AUTH_H_ 2 | #define SSF_NETWORK_SOCKS_V5_REQUEST_AUTH_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "ssf/network/socks/v5/types.h" 11 | 12 | namespace ssf { 13 | namespace network { 14 | namespace socks { 15 | namespace v5 { 16 | 17 | class RequestAuth { 18 | public: 19 | RequestAuth(); 20 | 21 | void Init(const std::vector& methods); 22 | 23 | uint8_t auth_supported_count() const { return auth_supported_count_; } 24 | 25 | void AddAuthMethod(uint8_t auth_method); 26 | 27 | boost::asio::mutable_buffers_1 MutAuthSupportedBuffers(); 28 | boost::asio::mutable_buffers_1 MutAuthBuffers(); 29 | std::vector ConstBuffers(); 30 | 31 | bool IsNoAuthPresent(); 32 | 33 | private: 34 | uint8_t version_; 35 | uint8_t auth_supported_count_; 36 | std::vector auth_methods_; 37 | }; 38 | 39 | } // v5 40 | } // socks 41 | } // network 42 | } // ssf 43 | 44 | #endif // SSF_NETWORK_SOCKS_V5_REQUEST_AUTH_H_ 45 | -------------------------------------------------------------------------------- /src/network/ssf/network/socks/v5/types.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_NETWORK_SOCKS_V5_TYPES_H_ 2 | #define SSF_NETWORK_SOCKS_V5_TYPES_H_ 3 | 4 | #include 5 | 6 | namespace ssf { 7 | namespace network { 8 | namespace socks { 9 | namespace v5 { 10 | 11 | // Authentication method constants 12 | enum class AuthMethod : uint8_t { 13 | kNoAuth = 0x00, 14 | kGSSAPI = 0x01, 15 | kUserPassword = 0x02, 16 | kUnsupportedAuth = 0xFF 17 | }; 18 | 19 | // Command types constants 20 | enum class CommandType : uint8_t { kConnect = 0x01, kBind = 0x02, kUDP = 0x03 }; 21 | 22 | // Address type constants 23 | enum class AddressType : uint8_t { kIPv4 = 0x01, kDNS = 0x03, kIPv6 = 0x04 }; 24 | 25 | // Command status constants 26 | enum class CommandStatus : uint8_t { 27 | kSucceeded = 0x00, 28 | kGeneralServerFailure = 0x01, 29 | kConnectionNotAllowed = 0x02, 30 | kNetworkUnreachable = 0x03, 31 | kHostUnreachable = 0x04, 32 | kConnectionRefused = 0x05, 33 | kTTLExpired = 0x06, 34 | kCommandNotSupported = 0x07, 35 | kAddressTypeNotSupported = 0x08 36 | }; 37 | 38 | } // v5 39 | } // socks 40 | } // network 41 | } // ssf 42 | 43 | #endif // SSF_NETWORK_SOCKS_V5_TYPES_H_ 44 | -------------------------------------------------------------------------------- /src/network/ssf/system/basic_interfaces_collection.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SYSTEM_BASIC_INTERFACES_COLLECTION_H_ 2 | #define SSF_SYSTEM_BASIC_INTERFACES_COLLECTION_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace ssf { 10 | namespace system { 11 | 12 | class BasicInterfacesCollection { 13 | public: 14 | using PropertyTree = boost::property_tree::ptree; 15 | using MountCallback = 16 | std::function; 17 | 18 | public: 19 | virtual ~BasicInterfacesCollection() {} 20 | 21 | virtual std::string GetName() = 0; 22 | 23 | virtual void AsyncMount(boost::asio::io_service& io_service, 24 | const PropertyTree& property_tree, 25 | MountCallback mount_handler) = 0; 26 | 27 | virtual void RemountDownInterfaces() = 0; 28 | 29 | virtual void Umount(const std::string& interface_name) = 0; 30 | 31 | virtual void UmountAll() = 0; 32 | }; 33 | 34 | } // system 35 | } // ssf 36 | 37 | #endif // SSF_SYSTEM_BASIC_INTERFACES_COLLECTION_H_ 38 | -------------------------------------------------------------------------------- /src/network/ssf/utils/cleaner.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_UTILS_CLEANER_H_ 2 | #define SSF_UTILS_CLEANER_H_ 3 | 4 | #include 5 | 6 | class ScopeCleaner { 7 | private: 8 | typedef std::function Handler; 9 | 10 | public: 11 | ScopeCleaner(Handler handler) : handler_(std::move(handler)) {} 12 | ~ScopeCleaner() { 13 | try { 14 | handler_(); 15 | } catch (...) { 16 | // Swallows exceptions 17 | } 18 | } 19 | 20 | private: 21 | Handler handler_; 22 | }; 23 | 24 | #endif // SSF_UTILS_CLEANER_H_ 25 | -------------------------------------------------------------------------------- /src/network/ssf/utils/enum.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_UTILS_ENUM_H_ 2 | #define SSF_UTILS_ENUM_H_ 3 | 4 | #include 5 | 6 | namespace ssf { 7 | 8 | template 9 | auto ToIntegral(Enum value) -> 10 | typename std::underlying_type::type { 11 | return static_cast::type>(value); 12 | } 13 | 14 | } // ssf 15 | 16 | #endif // SSF_UTILS_ENUM_H_ -------------------------------------------------------------------------------- /src/network/ssf/utils/map_helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_UTILS_MAP_HELPERS_H_ 2 | #define SSF_UTILS_MAP_HELPERS_H_ 3 | 4 | #include 5 | 6 | namespace ssf { 7 | namespace helpers { 8 | 9 | template 10 | Value GetField(const Key field, const std::map& parameters) { 11 | auto it = parameters.find(field); 12 | 13 | if (it == std::end(parameters)) { 14 | return Value(); 15 | } 16 | 17 | return it->second; 18 | } 19 | 20 | } // helpers 21 | } // ssf 22 | 23 | #endif // SSF_UTILS_MAP_HELPERS_H_ 24 | -------------------------------------------------------------------------------- /src/network/tests/log_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ssf/log/log.h" 4 | 5 | TEST(LogTests, DefaultLog) { 6 | SSF_LOG("test", critical, "critical"); 7 | SSF_LOG("test", error, "error"); 8 | SSF_LOG("test", warn, "warning"); 9 | SSF_LOG("test", info, "info"); 10 | SSF_LOG("test", debug, "debug"); 11 | SSF_LOG("test", trace, "trace"); 12 | } 13 | 14 | TEST(LogTests, TraceLog) { 15 | SetLogLevel(spdlog::level::trace); 16 | SSF_LOG("test", critical, "critical"); 17 | SSF_LOG("test", error, "error"); 18 | SSF_LOG("test", warn, "warning"); 19 | SSF_LOG("test", info, "info"); 20 | SSF_LOG("test", debug, "debug"); 21 | SSF_LOG("test", trace, "trace"); 22 | } 23 | 24 | TEST(LogTests, CriticalLog) { 25 | SetLogLevel(spdlog::level::critical); 26 | SSF_LOG("test", critical, "critical"); 27 | SSF_LOG("test", error, "error"); 28 | SSF_LOG("test", warn, "warning"); 29 | SSF_LOG("test", info, "info"); 30 | SSF_LOG("test", debug, "debug"); 31 | SSF_LOG("test", trace, "trace"); 32 | } 33 | 34 | TEST(LogTests, NoLog) { 35 | SetLogLevel(spdlog::level::off); 36 | SSF_LOG("test", critical, "critical"); 37 | SSF_LOG("test", error, "error"); 38 | SSF_LOG("test", warn, "warning"); 39 | SSF_LOG("test", info, "info"); 40 | SSF_LOG("test", debug, "debug"); 41 | SSF_LOG("test", trace, "trace"); 42 | } -------------------------------------------------------------------------------- /src/network/tests/proxy/README.md: -------------------------------------------------------------------------------- 1 | # Proxy test configuration 2 | 3 | * Copy file 'proxy.json.dist' into 'proxy.json' 4 | * Fill options with correct values: 5 | - target_host: FQDN of your machine reachable from proxy only 6 | - target_port: port of test server (9000 by default) 7 | - proxy_host: address of http proxy 8 | - proxy_port: port of http proxy 9 | - username: username for proxy authentication 10 | - password: password for proxy authentication 11 | - domain: user domain (NTLM and Negotiate auth on Windows only) 12 | - reuse_ntlm: reuse current computer user credentials to authenticate with proxy NTLM auth (SSO) 13 | - reuse_kerb: reuse current computer user credentials (Kerberos ticket) to authenticate with proxy Negotiate auth (SSO) 14 | * Run `cmake ..` at project build directory 15 | * Build and run `proxy_layer_tests` 16 | -------------------------------------------------------------------------------- /src/network/tests/proxy/proxy.json.dist: -------------------------------------------------------------------------------- 1 | { 2 | "target_host": "public.fqdn.name", 3 | "target_port": "9000", 4 | "proxy_host": "proxy.example.com", 5 | "proxy_port": "3128", 6 | "socks_host": "proxy.example.com", 7 | "socks_port": "1080", 8 | "username": "", 9 | "password": "", 10 | "domain": "", 11 | "reuse_ntlm": "true", 12 | "reuse_kerb": "true" 13 | } 14 | -------------------------------------------------------------------------------- /src/network/tests/proxy_test_fixture.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_TESTS_PROXY_TEST_FIXTURE_H_ 2 | #define SSF_TESTS_PROXY_TEST_FIXTURE_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "ssf/layer/parameters.h" 9 | 10 | namespace ssf { 11 | namespace tests { 12 | 13 | class Address { 14 | public: 15 | Address(); 16 | Address(const std::string& addr, const std::string& port); 17 | Address(const Address& address); 18 | Address& operator=(const Address& address); 19 | 20 | ssf::layer::LayerParameters ToProxyParam(); 21 | 22 | ssf::layer::LayerParameters ToTCPParam(); 23 | 24 | bool IsSet(); 25 | 26 | private: 27 | std::string addr_; 28 | std::string port_; 29 | }; 30 | 31 | } // tests 32 | } // ssf 33 | 34 | class ProxyTestFixture : public ::testing::Test { 35 | protected: 36 | ProxyTestFixture(); 37 | 38 | virtual ~ProxyTestFixture(); 39 | 40 | virtual void SetUp(); 41 | 42 | virtual void TearDown(); 43 | 44 | bool Initialized(); 45 | 46 | ssf::layer::LayerParameters GetProxyTcpParam() const; 47 | 48 | ssf::layer::LayerParameters GetLocalTcpParam() const; 49 | 50 | ssf::layer::LayerParameters GetProxyParam() const; 51 | 52 | ssf::layer::LayerParameters GetSocksProxyParam() const; 53 | 54 | private: 55 | bool ParseConfigFile(const std::string& filepath); 56 | std::string GetOption(const std::string& name) const; 57 | 58 | protected: 59 | std::string config_file_; 60 | std::map config_options_; 61 | }; 62 | 63 | #endif // SSF_TESTS_PROXY_TEST_FIXTURE_H_ 64 | -------------------------------------------------------------------------------- /src/network/tests/system/circuit_tlsotcp_accept1_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "circuit_tlsotcp_accept1", 3 | "type": "ACCEPT", 4 | "layer_stack": { 5 | "layer": "CIRCUIT", 6 | "parameters": { 7 | "local_id": "server", 8 | "forward": true, 9 | "nodes": [] 10 | }, 11 | "sublayer": { 12 | "layer": "TLS", 13 | "parameters": { 14 | "ca_file": "./certs/trusted/ca.crt", 15 | "crt_file": "./certs/certificate.crt", 16 | "key_file": "./certs/private.key", 17 | "dhparam_file": "./certs/dh4096.pem" 18 | }, 19 | "sublayer": { 20 | "layer": "TCP", 21 | "parameters": { 22 | "port": "6000" 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/network/tests/system/circuit_tlsotcp_accept2_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "circuit_tlsotcp_accept2", 3 | "type": "ACCEPT", 4 | "layer_stack": { 5 | "layer": "CIRCUIT", 6 | "parameters": { 7 | "local_id": "server", 8 | "forward": true, 9 | "nodes": [] 10 | }, 11 | "sublayer": { 12 | "layer": "TLS", 13 | "parameters": { 14 | "ca_file": "./certs/trusted/ca.crt", 15 | "crt_file": "./certs/certificate.crt", 16 | "key_file": "./certs/private.key", 17 | "dhparam_file": "./certs/dh4096.pem" 18 | }, 19 | "sublayer": { 20 | "layer": "TCP", 21 | "parameters": { 22 | "port": "6001" 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/network/tests/system/circuit_tlsotcp_accept3_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "circuit_tlsotcp_accept3", 3 | "type": "ACCEPT", 4 | "layer_stack": { 5 | "layer": "CIRCUIT", 6 | "parameters": { 7 | "local_id": "server", 8 | "forward": true, 9 | "nodes": [] 10 | }, 11 | "sublayer": { 12 | "layer": "TLS", 13 | "parameters": { 14 | "ca_file": "./certs/trusted/ca.crt", 15 | "crt_file": "./certs/certificate.crt", 16 | "key_file": "./certs/private.key", 17 | "dhparam_file": "./certs/dh4096.pem" 18 | }, 19 | "sublayer": { 20 | "layer": "TCP", 21 | "parameters": { 22 | "port": "6002" 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/network/tests/system/circuit_tlsotcp_connect_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "circuit_tlsotcp_connect", 3 | "type": "CONNECT", 4 | "layer_stack": { 5 | "layer": "CIRCUIT", 6 | "parameters": { 7 | "remote_id": "server", 8 | "nodes": [ 9 | { 10 | "layer": "TLS", 11 | "parameters": { 12 | "ca_file": "./certs/trusted/ca.crt", 13 | "crt_file": "./certs/certificate.crt", 14 | "key_file": "./certs/private.key", 15 | "dhparam_file": "./certs/dh4096.pem" 16 | }, 17 | "sublayer": { 18 | "layer": "TCP", 19 | "parameters": { 20 | "addr": "127.0.0.1", 21 | "port": "6000" 22 | } 23 | } 24 | }, 25 | { 26 | "layer": "TLS", 27 | "parameters": { 28 | "ca_file": "./certs/trusted/ca.crt", 29 | "crt_file": "./certs/certificate.crt", 30 | "key_file": "./certs/private.key", 31 | "dhparam_file": "./certs/dh4096.pem" 32 | }, 33 | "sublayer": { 34 | "layer": "TCP", 35 | "parameters": { 36 | "addr": "127.0.0.1", 37 | "port": "6001" 38 | } 39 | } 40 | } 41 | ] 42 | }, 43 | "sublayer": { 44 | "layer": "TLS", 45 | "parameters": { 46 | "ca_file": "./certs/trusted/ca.crt", 47 | "crt_file": "./certs/certificate.crt", 48 | "key_file": "./certs/private.key", 49 | "dhparam_file": "./certs/dh4096.pem" 50 | }, 51 | "sublayer": { 52 | "layer": "TCP", 53 | "parameters": { 54 | "addr": "127.0.0.1", 55 | "port": "6002" 56 | } 57 | } 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /src/network/tests/system/fail_router_config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "router": "router1", 4 | "networks": { 5 | "1" : "simple_lo1", 6 | "3" : "simple_tls_lo1" 7 | }, 8 | "routes": { 9 | "2": "3" 10 | "4": "1" 11 | } 12 | }, 13 | { 14 | "router": "router2", 15 | "networks": { 16 | "2" : "simple_lo3", 17 | "4" : "simple_tls_lo2" 18 | }, 19 | "routes": { 20 | "1": "4", 21 | "4": "2" 22 | } 23 | } 24 | ] -------------------------------------------------------------------------------- /src/network/tests/system/fail_tcp_accept_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "tcp_accept", 3 | "type": "ACCEPT", 4 | "ttl": 5, 5 | "delay": 200, 6 | "layer_stack": { 7 | "layer": "TCP", 8 | "parameters": { 9 | "port": "9000" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/network/tests/system/fail_tcp_connect_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "tcp_connect", 3 | "type": "CONNECT", 4 | "ttl": 1, 5 | "delay": 200, 6 | "layer_stack": { 7 | "layer": "TCP", 8 | "parameters": { 9 | "port": "10000", 10 | "addr": "127.0.0.1" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/network/tests/system/link_tcp_accept_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "link_tcp_accept", 3 | "type": "ACCEPT", 4 | "layer_stack": { 5 | "layer": "CIRCUIT", 6 | "parameters": { 7 | "forward": false, 8 | "local_id": "server" 9 | }, 10 | "sublayer": { 11 | "layer": "TCP", 12 | "parameters": { 13 | "port": "9000" 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/network/tests/system/link_tcp_connect_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "link_tcp_connect", 3 | "type": "CONNECT", 4 | "layer_stack": { 5 | "layer": "CIRCUIT", 6 | "parameters": { 7 | "remote_id": "server", 8 | "nodes": [] 9 | }, 10 | "sublayer": { 11 | "layer": "TCP", 12 | "parameters": { 13 | "addr": "127.0.0.1", 14 | "port": "9000" 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/network/tests/system/link_tlsotcp_accept_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "link_tlsotcp_accept", 3 | "type": "ACCEPT", 4 | "layer_stack": { 5 | "layer": "CIRCUIT", 6 | "parameters": { 7 | "local_id": "server", 8 | "forward": true, 9 | "nodes": [] 10 | }, 11 | "sublayer": { 12 | "layer": "TLS", 13 | "parameters": { 14 | "ca_file": "./certs/trusted/ca.crt", 15 | "crt_file": "./certs/certificate.crt", 16 | "key_file": "./certs/private.key", 17 | "dhparam_file": "./certs/dh4096.pem" 18 | }, 19 | "sublayer": { 20 | "layer": "TCP", 21 | "parameters": { 22 | "port": "9000" 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/network/tests/system/link_tlsotcp_connect_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "link_tlsotcp_connect", 3 | "type": "CONNECT", 4 | "layer_stack": { 5 | "layer": "CIRCUIT", 6 | "parameters": { 7 | "remote_id": "server", 8 | "nodes": [] 9 | }, 10 | "sublayer": { 11 | "layer": "TLS", 12 | "parameters": { 13 | "ca_file": "./certs/trusted/ca.crt", 14 | "crt_file": "./certs/certificate.crt", 15 | "key_file": "./certs/private.key", 16 | "dhparam_file": "./certs/dh4096.pem" 17 | }, 18 | "sublayer": { 19 | "layer": "TCP", 20 | "parameters": { 21 | "addr": "127.0.0.1", 22 | "port": "9000" 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/network/tests/system/router_config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "router": "router1", 4 | "networks": { 5 | "1": "circuit_tlsotcp_connect", 6 | "3": "circuit_tcp_connect", 7 | "5": "tlsotcp_connect", 8 | "7": "tcp_connect" 9 | }, 10 | "routes": { 11 | "2": "7", 12 | "4": "1", 13 | "6": "3", 14 | "8": "5" 15 | } 16 | }, 17 | { 18 | "router": "router2", 19 | "networks": { 20 | "2": "circuit_tlsotcp_accept", 21 | "4": "circuit_tcp_accept", 22 | "6": "tlsotcp_accept", 23 | "8": "tcp_accept" 24 | }, 25 | "routes": { 26 | "1": "4", 27 | "3": "6", 28 | "5": "8", 29 | "7": "2" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /src/network/tests/system/system_reconnect_config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "interface": "tcp_connect", 4 | "type": "CONNECT", 5 | "layer_stack": { 6 | "layer": "TCP", 7 | "parameters": { 8 | "port": "8000", 9 | "addr": "127.0.0.1" 10 | } 11 | } 12 | } 13 | ] -------------------------------------------------------------------------------- /src/network/tests/system/tcp_accept_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "tcp_accept", 3 | "type": "ACCEPT", 4 | "ttl": 5, 5 | "delay": 200, 6 | "layer_stack": { 7 | "layer": "TCP", 8 | "parameters": { 9 | "port": "9000" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/network/tests/system/tcp_connect_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "tcp_connect", 3 | "type": "CONNECT", 4 | "ttl": 1, 5 | "delay": 200, 6 | "layer_stack": { 7 | "layer": "TCP", 8 | "parameters": { 9 | "port": "9000", 10 | "addr": "127.0.0.1" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/network/tests/system/tlsotcp_accept_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "tlsotcp_accept", 3 | "type": "ACCEPT", 4 | "layer_stack": { 5 | "layer": "TLS", 6 | "parameters": { 7 | "ca_file": "./certs/trusted/ca.crt", 8 | "crt_file": "./certs/certificate.crt", 9 | "key_file": "./certs/private.key", 10 | "dhparam_file": "./certs/dh4096.pem" 11 | }, 12 | "sublayer": { 13 | "layer": "TCP", 14 | "parameters": { 15 | "port": "9000" 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/network/tests/system/tlsotcp_connect_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "interface": "tlsotcp_connect", 3 | "type": "CONNECT", 4 | "layer_stack": { 5 | "layer": "TLS", 6 | "parameters": { 7 | "ca_file": "./certs/trusted/ca.crt", 8 | "crt_file": "./certs/certificate.crt", 9 | "key_file": "./certs/private.key", 10 | "dhparam_file": "./certs/dh4096.pem" 11 | }, 12 | "sublayer": { 13 | "layer": "TCP", 14 | "parameters": { 15 | "port": "9000", 16 | "addr": "127.0.0.1" 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/network/tests/tools.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_TESTS_TOOLS_H_ 2 | #define SSF_TESTS_TOOLS_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "ssf/log/log.h" 9 | 10 | class TimedScope { 11 | public: 12 | TimedScope() : creation_time_(std::chrono::high_resolution_clock::now()) {} 13 | 14 | virtual ~TimedScope() { PrintDuration(); } 15 | 16 | void ResetTime() { 17 | creation_time_ = std::chrono::high_resolution_clock::now(); 18 | } 19 | 20 | std::chrono::nanoseconds Duration() const { 21 | return std::chrono::high_resolution_clock::now() - creation_time_; 22 | } 23 | 24 | double FloatSecondDuration() const { 25 | return this->Duration().count() / static_cast(1000) / 26 | static_cast(1000) / static_cast(1000); 27 | } 28 | 29 | void PrintDuration() { 30 | SSF_LOG("test", debug, "Timed scope: {}", Duration().count()); 31 | } 32 | 33 | private: 34 | std::chrono::time_point creation_time_; 35 | }; 36 | 37 | class ScopedBandWidth : public TimedScope { 38 | public: 39 | ScopedBandWidth(uint64_t bits) : TimedScope(), bits_(bits) {} 40 | 41 | virtual ~ScopedBandWidth() { PrintBandWidth(); } 42 | 43 | void ResetBits() { bits_ = 0; } 44 | 45 | void ResetBits(uint64_t bits) { bits_ = bits; } 46 | 47 | void AddBits(uint64_t bits) { bits_ += bits; } 48 | 49 | double BandWidth() const { return bits_ / this->FloatSecondDuration(); } 50 | 51 | void PrintBandWidth() const { 52 | SSF_LOG("test", info, 53 | "Bandwidth: transferred {} bits in {} seconds ==> {} Mbits/s", 54 | bits_, this->FloatSecondDuration(), (BandWidth() / 1000 / 1000)); 55 | } 56 | 57 | private: 58 | uint64_t bits_; 59 | }; 60 | 61 | #endif // SSF_TESTS_TOOLS_H_ 62 | -------------------------------------------------------------------------------- /src/network/tests/transport_layer_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "tests/datagram_protocol_helpers.h" 4 | #include "tests/stream_protocol_helpers.h" 5 | #include "tests/transport_test_fixture.h" 6 | 7 | #include "ssf/layer/parameters.h" 8 | 9 | TEST_F(TransportTestFixture, DISABLED_DatagramTransportTest) {} 10 | 11 | TEST_F(TransportTestFixture, DISABLED_StreamTransportTest) {} 12 | -------------------------------------------------------------------------------- /src/server/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(ssfd ssfd.cpp ${ICON_RC}) 2 | target_link_libraries(ssfd ssf_framework) 3 | set_property(TARGET ssfd PROPERTY FOLDER "Executables") 4 | copy_certs(ssfd) 5 | 6 | install(TARGETS ssfd RUNTIME DESTINATION bin) 7 | -------------------------------------------------------------------------------- /src/services/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT DEP_BOOST_VERSION) 2 | set(DEP_BOOST_VERSION 1.55.0) 3 | endif() 4 | 5 | add_subdirectory(socks) 6 | add_subdirectory(fibers_to_sockets) 7 | add_subdirectory(sockets_to_fibers) 8 | -------------------------------------------------------------------------------- /src/services/admin/admin_command.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_ADMIN_ADMIN_COMMAND_H_ 2 | #define SSF_SERVICES_ADMIN_ADMIN_COMMAND_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace ssf { 14 | namespace services { 15 | namespace admin { 16 | 17 | class AdminCommand { 18 | public: 19 | AdminCommand(uint32_t serial, uint32_t command_id, 20 | uint32_t serialize_arguments_size, 21 | std::string serialized_arguments) 22 | : serial_(serial), 23 | command_id_(command_id), 24 | serialize_arguments_size_(serialize_arguments_size), 25 | serialized_arguments_(serialized_arguments) {} 26 | 27 | std::array const_buffers() const { 28 | std::array buf = { 29 | {boost::asio::buffer(&serial_, sizeof(serial_)), 30 | boost::asio::buffer(&command_id_, sizeof(command_id_)), 31 | boost::asio::buffer(&serialize_arguments_size_, 32 | sizeof(serialize_arguments_size_)), 33 | boost::asio::buffer(serialized_arguments_)}}; 34 | 35 | return buf; 36 | } 37 | 38 | private: 39 | uint32_t serial_; 40 | uint32_t command_id_; 41 | uint32_t serialize_arguments_size_; 42 | std::string serialized_arguments_; 43 | }; 44 | 45 | } // admin 46 | } // services 47 | } // ssf 48 | 49 | #endif // SSF_SERVICES_ADMIN_ADMIN_COMMAND_H_ 50 | -------------------------------------------------------------------------------- /src/services/base_service_config.cpp: -------------------------------------------------------------------------------- 1 | #include "services/base_service_config.h" 2 | 3 | namespace ssf { 4 | 5 | BaseServiceConfig::BaseServiceConfig(bool enabled) : enabled_(enabled) {} 6 | 7 | BaseServiceConfig::~BaseServiceConfig() {} 8 | 9 | } // ssf 10 | -------------------------------------------------------------------------------- /src/services/base_service_config.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_BASE_SERVICE_CONFIG_H_ 2 | #define SSF_SERVICES_BASE_SERVICE_CONFIG_H_ 3 | 4 | namespace ssf { 5 | 6 | class BaseServiceConfig { 7 | public: 8 | virtual ~BaseServiceConfig(); 9 | 10 | inline bool enabled() const { return enabled_; } 11 | 12 | inline void set_enabled(bool enabled) { enabled_ = enabled; } 13 | 14 | protected: 15 | BaseServiceConfig(bool enabled); 16 | 17 | private: 18 | bool enabled_; 19 | }; 20 | 21 | } // ssf 22 | 23 | #endif // SSF_SERVICES_BASE_SERVICE_CONFIG_H_ -------------------------------------------------------------------------------- /src/services/copy/config.cpp: -------------------------------------------------------------------------------- 1 | #include "services/copy/config.h" 2 | 3 | namespace ssf { 4 | namespace services { 5 | namespace copy { 6 | 7 | Config::Config() : BaseServiceConfig(false) {} 8 | 9 | Config::Config(const Config& copy_service) 10 | : BaseServiceConfig(copy_service.enabled()) {} 11 | 12 | } // copy 13 | } // services 14 | } // ssf -------------------------------------------------------------------------------- /src/services/copy/config.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_CONFIG_H_ 2 | #define SSF_SERVICES_COPY_CONFIG_H_ 3 | 4 | #include "services/base_service_config.h" 5 | 6 | namespace ssf { 7 | namespace services { 8 | namespace copy { 9 | 10 | class Config : public BaseServiceConfig { 11 | public: 12 | Config(); 13 | Config(const Config& process_service); 14 | }; 15 | 16 | } // copy 17 | } // services 18 | } // ssf 19 | 20 | #endif // SSF_SERVICES_COPY_CONFIG_H_ -------------------------------------------------------------------------------- /src/services/copy/error_code.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_ERROR_CODE_H_ 2 | #define SSF_SERVICES_COPY_ERROR_CODE_H_ 3 | 4 | #include 5 | 6 | namespace ssf { 7 | namespace services { 8 | namespace copy { 9 | 10 | enum ErrorCode { 11 | kSuccess = 0, 12 | 13 | kUnknown = 200, 14 | kFailure, 15 | kInterrupted, 16 | kFilesPartiallyCopied, 17 | kNoFileCopied, 18 | 19 | kNetworkError, 20 | kCopyStopped, 21 | 22 | kInboundPacketNotSupported, 23 | kOutboundPacketNotGenerated, 24 | 25 | kInitRequestPacketNotGenerated, 26 | kInitRequestPacketCorrupted, 27 | kInitReplyPacketNotGenerated, 28 | kInitReplyPacketCorrupted, 29 | kIntegrityCheckRequestPacketNotGenerated, 30 | kIntegrityCheckRequestPacketCorrupted, 31 | kIntegrityCheckReplyPacketNotGenerated, 32 | kIntegrityCheckReplyPacketCorrupted, 33 | 34 | kInputDirectoryNotFound, 35 | kOutputDirectoryNotFound, 36 | kOutputFileDirectoryNotFound, 37 | 38 | kInputFileNotAvailable, 39 | kOutputFileNotAvailable, 40 | 41 | kInputFileReadError, 42 | kOutputFileWriteError, 43 | 44 | kInputFileDigestNotAvailable, 45 | kOutputFileDigestNotAvailable, 46 | 47 | kResumeFileTransferNotPermitted, 48 | 49 | kOutputFileCorrupted, 50 | 51 | kCopyInitializationFailed, 52 | kSenderInputFileListingFailed, 53 | 54 | kCopyRequestAckNotReceived, 55 | kCopyRequestCorrupted, 56 | 57 | kClientCopyRequestNotSent, 58 | 59 | kFileAcceptorNotBound, 60 | kFileAcceptorNotListening, 61 | }; 62 | 63 | namespace detail { 64 | class copy_category : public boost::system::error_category { 65 | public: 66 | const char* name() const BOOST_SYSTEM_NOEXCEPT; 67 | 68 | std::string message(int value) const; 69 | }; 70 | } // detail 71 | 72 | inline const boost::system::error_category& get_copy_category() { 73 | static detail::copy_category instance; 74 | return instance; 75 | } 76 | 77 | } // copy 78 | } // services 79 | } // ssf 80 | 81 | #endif // SSF_SERVICES_COPY_ERROR_CODE_H_ 82 | -------------------------------------------------------------------------------- /src/services/copy/i_copy_state.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_I_COPY_STATE_H_ 2 | #define SSF_SERVICES_COPY_I_COPY_STATE_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "common/error/error.h" 9 | 10 | #include "services/copy/packet.h" 11 | 12 | namespace ssf { 13 | namespace services { 14 | namespace copy { 15 | 16 | class CopyContext; 17 | 18 | class ICopyState { 19 | public: 20 | virtual ~ICopyState() {} 21 | 22 | virtual void Enter(CopyContext* context, boost::system::error_code& ec) {} 23 | 24 | virtual void Exit(CopyContext* context, boost::system::error_code& ec) {} 25 | 26 | virtual bool IsClosed(CopyContext* context) { return false; } 27 | 28 | virtual bool FillOutboundPacket(CopyContext* context, Packet* packet, 29 | boost::system::error_code& ec) = 0; 30 | 31 | virtual void ProcessInboundPacket(CopyContext* context, const Packet& packet, 32 | boost::system::error_code& ec) = 0; 33 | 34 | virtual bool IsTerminal(CopyContext* context) = 0; 35 | }; 36 | 37 | using ICopyStateUPtr = std::unique_ptr; 38 | 39 | } // copy 40 | } // services 41 | } // ssf 42 | 43 | #endif // SSF_SERVICES_COPY_I_COPY_STATE_H_ 44 | -------------------------------------------------------------------------------- /src/services/copy/packet.cpp: -------------------------------------------------------------------------------- 1 | #include "services/copy/packet.h" 2 | 3 | namespace ssf { 4 | namespace services { 5 | namespace copy { 6 | 7 | Packet::Packet() : type_(PacketType::kUnknown), payload_size_(0), buffer_() {} 8 | 9 | PacketType Packet::type() const { return type_; } 10 | 11 | void Packet::set_type(PacketType type) { type_ = type; } 12 | 13 | uint32_t Packet::payload_size() const { return payload_size_; } 14 | 15 | void Packet::set_payload_size(uint32_t size) { payload_size_ = size; } 16 | 17 | const Packet::Buffer& Packet::buffer() const { return buffer_; } 18 | 19 | Packet::Buffer& Packet::buffer() { return buffer_; } 20 | 21 | Packet::ConstBufSeq Packet::GetConstBuf() const { 22 | return {{boost::asio::buffer(&type_, sizeof(type_)), 23 | boost::asio::buffer(&payload_size_, sizeof(payload_size_)), 24 | boost::asio::buffer(buffer_, payload_size_)}}; 25 | } 26 | 27 | Packet::HeaderConstBufSeq Packet::GetHeaderConstBuf() const { 28 | return {{boost::asio::buffer(&type_, sizeof(type_)), 29 | boost::asio::buffer(&payload_size_, sizeof(payload_size_))}}; 30 | } 31 | 32 | Packet::HeaderMutBufSeq Packet::GetHeaderMutBuf() { 33 | return {{boost::asio::buffer(&type_, sizeof(type_)), 34 | boost::asio::buffer(&payload_size_, sizeof(payload_size_))}}; 35 | } 36 | 37 | boost::asio::mutable_buffers_1 Packet::GetPayloadMutBuf() { 38 | return {boost::asio::buffer(buffer_, payload_size_)}; 39 | } 40 | 41 | } // copy 42 | } // services 43 | } // ssf 44 | -------------------------------------------------------------------------------- /src/services/copy/packet.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_PACKET_H_ 2 | #define SSF_SERVICES_COPY_PACKET_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | namespace ssf { 12 | namespace services { 13 | namespace copy { 14 | 15 | enum class PacketType : uint32_t { 16 | // copy session 17 | kUnknown = 0, 18 | kInitRequest, 19 | kInitReply, 20 | kCheckIntegrityRequest, 21 | kCheckIntegrityReply, 22 | kData, 23 | kEof, 24 | kAbort, 25 | kAbortAck, 26 | // control channel 27 | kCopyRequest, 28 | CopyRequestAck, 29 | kCopyFinished 30 | }; 31 | 32 | class Packet { 33 | public: 34 | static const uint64_t kMaxPayloadSize = 50 * 1024; 35 | using Buffer = std::array; 36 | 37 | using ConstBufSeq = std::array; 38 | using HeaderConstBufSeq = std::array; 39 | using HeaderMutBufSeq = std::array; 40 | 41 | public: 42 | Packet(); 43 | PacketType type() const; 44 | void set_type(PacketType type); 45 | boost::asio::const_buffers_1 GetTypeConstBuf() const; 46 | boost::asio::mutable_buffers_1 GetTypeMutBuf(); 47 | 48 | uint32_t payload_size() const; 49 | void set_payload_size(uint32_t size); 50 | const Buffer& buffer() const; 51 | Buffer& buffer(); 52 | 53 | ConstBufSeq GetConstBuf() const; 54 | HeaderConstBufSeq GetHeaderConstBuf() const; 55 | HeaderMutBufSeq GetHeaderMutBuf(); 56 | boost::asio::mutable_buffers_1 GetPayloadMutBuf(); 57 | 58 | private: 59 | PacketType type_; 60 | uint32_t payload_size_; 61 | Buffer buffer_; 62 | }; 63 | 64 | using PacketPtr = std::shared_ptr; 65 | 66 | } // copy 67 | } // services 68 | } // ssf 69 | 70 | #endif // SSF_SERVICES_COPY_PACKET_H_ 71 | -------------------------------------------------------------------------------- /src/services/copy/packet/check.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_PACKET_CHECK_H_ 2 | #define SSF_SERVICES_COPY_PACKET_CHECK_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "common/crypto/sha1.h" 9 | #include "services/copy/packet.h" 10 | 11 | namespace ssf { 12 | namespace services { 13 | namespace copy { 14 | 15 | enum CheckIntegrityStatus { 16 | kCheckIntegrityFailed = 0, 17 | kCheckIntegritySucceeded 18 | }; 19 | 20 | template 21 | struct CheckIntegrityRequest { 22 | static const PacketType kType = PacketType::kCheckIntegrityRequest; 23 | using Digest = typename Hash::Digest; 24 | 25 | CheckIntegrityRequest() : input_file_digest({{0}}) {} 26 | CheckIntegrityRequest(const Digest& i_input_file_digest) 27 | : input_file_digest(i_input_file_digest) {} 28 | 29 | Digest input_file_digest; 30 | 31 | MSGPACK_DEFINE(input_file_digest) 32 | }; 33 | 34 | template 35 | struct CheckIntegrityReply { 36 | static const PacketType kType = PacketType::kCheckIntegrityReply; 37 | using Digest = typename Hash::Digest; 38 | 39 | CheckIntegrityReply() 40 | : req(), output_file_digest({{0}}), status(kCheckIntegrityFailed) {} 41 | 42 | CheckIntegrityReply(const CheckIntegrityRequest& i_req, 43 | const Digest& i_output_file_digest, 44 | CheckIntegrityStatus i_status) 45 | : req(i_req), 46 | output_file_digest(i_output_file_digest), 47 | status(i_status) {} 48 | 49 | CheckIntegrityRequest req; 50 | Digest output_file_digest; 51 | CheckIntegrityStatus status; 52 | 53 | MSGPACK_DEFINE(req, output_file_digest, status) 54 | }; 55 | 56 | } // copy 57 | } // services 58 | } // ssf 59 | 60 | MSGPACK_ADD_ENUM(ssf::services::copy::CheckIntegrityStatus); 61 | 62 | #endif // SSF_SERVICES_COPY_PACKET_CHECK_H_ 63 | -------------------------------------------------------------------------------- /src/services/copy/packet/data.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_PACKET_DATA_H_ 2 | #define SSF_SERVICES_COPY_PACKET_DATA_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace ssf { 9 | namespace services { 10 | namespace copy { 11 | 12 | struct Data {}; 13 | 14 | } // copy 15 | } // services 16 | } // ssf 17 | 18 | #endif // SSF_SERVICES_COPY_PACKET_DATA_H_ 19 | 20 | -------------------------------------------------------------------------------- /src/services/copy/packet/error.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_PACKET_ERROR_H_ 2 | #define SSF_SERVICES_COPY_PACKET_ERROR_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "common/error/error.h" 9 | #include "services/copy/packet.h" 10 | #include "services/copy/packet/error_code.h" 11 | 12 | namespace ssf { 13 | namespace services { 14 | namespace copy { 15 | 16 | struct Abort { 17 | static const PacketType kType = PacketType::kAbort; 18 | 19 | Abort() : error_code(ErrorCode::kUnknown) {} 20 | Abort(ErrorCode i_error_code) : error_code(i_error_code) {} 21 | 22 | ErrorCode error_code; 23 | 24 | MSGPACK_DEFINE(error_code) 25 | }; 26 | 27 | struct AbortAck { 28 | static const PacketType kType = PacketType::kAbortAck; 29 | 30 | AbortAck() : error_code(ErrorCode::kUnknown) {} 31 | AbortAck(ErrorCode i_error_code) : error_code(i_error_code) {} 32 | 33 | ErrorCode error_code; 34 | 35 | MSGPACK_DEFINE(error_code) 36 | }; 37 | 38 | } // copy 39 | } // services 40 | } // ssf 41 | 42 | #endif // SSF_SERVICES_COPY_PACKET_ERROR_H_ -------------------------------------------------------------------------------- /src/services/copy/packet/error_code.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_PACKET_ERROR_CODE_H_ 2 | #define SSF_SERVICES_COPY_PACKET_ERROR_CODE_H_ 3 | 4 | #include 5 | 6 | #include "services/copy/error_code.h" 7 | 8 | MSGPACK_ADD_ENUM(ssf::services::copy::ErrorCode); 9 | 10 | #endif // SSF_SERVICES_COPY_PACKET_ERROR_CODE_H_ -------------------------------------------------------------------------------- /src/services/copy/state/on_abort.cpp: -------------------------------------------------------------------------------- 1 | #include "services/copy/state/on_abort.h" 2 | 3 | #include 4 | 5 | #include "services/copy/copy_context.h" 6 | #include "services/copy/packet.h" 7 | #include "services/copy/packet/error.h" 8 | #include "services/copy/packet_helper.h" 9 | #include "services/copy/state/receiver/send_abort_ack_state.h" 10 | #include "services/copy/state/sender/close_state.h" 11 | 12 | namespace ssf { 13 | namespace services { 14 | namespace copy { 15 | 16 | void OnReceiverAbortPacket(CopyContext* context, const Packet& packet, 17 | boost::system::error_code& ec) { 18 | Abort abort; 19 | PacketToPayload(packet, abort, ec); 20 | if (ec) { 21 | SSF_LOG("microservice", error, 22 | "[copy][on_receiver_abort] cannot convert packet to abort message"); 23 | return; 24 | } 25 | context->error_code = abort.error_code; 26 | 27 | context->SetState(SendAbortAckState::Create()); 28 | } 29 | 30 | void OnSenderAbortPacket(CopyContext* context, const Packet& packet, 31 | boost::system::error_code& ec) { 32 | Abort abort; 33 | PacketToPayload(packet, abort, ec); 34 | if (ec) { 35 | SSF_LOG("microservice", error, 36 | "[copy][on_sender_abort] cannot convert packet to abort message"); 37 | return; 38 | } 39 | context->error_code = abort.error_code; 40 | 41 | context->SetState(CloseState::Create()); 42 | } 43 | 44 | } // copy 45 | } // services 46 | } // ssf -------------------------------------------------------------------------------- /src/services/copy/state/on_abort.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_STATE_ON_ABORT_H_ 2 | #define SSF_SERVICES_COPY_STATE_ON_ABORT_H_ 3 | 4 | #include 5 | 6 | namespace ssf { 7 | namespace services { 8 | namespace copy { 9 | 10 | class CopyContext; 11 | class Packet; 12 | 13 | void OnReceiverAbortPacket(CopyContext* context, const Packet& packet, 14 | boost::system::error_code& ec); 15 | 16 | void OnSenderAbortPacket(CopyContext* context, const Packet& packet, 17 | boost::system::error_code& ec); 18 | 19 | } // copy 20 | } // services 21 | } // ssf 22 | 23 | #endif // SSF_SERVICES_COPY_STATE_ON_ABORT_H_ 24 | -------------------------------------------------------------------------------- /src/services/copy/state/receiver/send_abort_ack_state.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_STATE_RECEIVER_SEND_EOF_STATE_H_ 2 | #define SSF_SERVICES_COPY_STATE_RECEIVER_SEND_EOF_STATE_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include "common/error/error.h" 11 | 12 | #include "services/copy/i_copy_state.h" 13 | #include "services/copy/packet/error.h" 14 | #include "services/copy/packet_helper.h" 15 | #include "services/copy/state/receiver/wait_close_state.h" 16 | 17 | namespace ssf { 18 | namespace services { 19 | namespace copy { 20 | 21 | class SendAbortAckState : ICopyState { 22 | public: 23 | template 24 | static ICopyStateUPtr Create(Args&&... args) { 25 | return ICopyStateUPtr(new SendAbortAckState(std::forward(args)...)); 26 | } 27 | 28 | private: 29 | SendAbortAckState() : ICopyState() {} 30 | 31 | public: 32 | // ICopyState 33 | void Enter(CopyContext* context, boost::system::error_code& ec) { 34 | SSF_LOG("microservice", trace, "[copy][send_abort_ack] enter"); 35 | } 36 | 37 | bool FillOutboundPacket(CopyContext* context, Packet* packet, 38 | boost::system::error_code& ec) { 39 | AbortAck ack(context->error_code); 40 | 41 | PayloadToPacket(ack, packet, ec); 42 | if (ec) { 43 | SSF_LOG("microservice", debug, 44 | "[copy][send_abort_ack] cannot convert abort ack to packet"); 45 | return false; 46 | } 47 | 48 | context->SetState(WaitCloseState::Create()); 49 | 50 | return true; 51 | } 52 | 53 | void ProcessInboundPacket(CopyContext* context, const Packet& packet, 54 | boost::system::error_code& ec) { 55 | if (packet.type() == PacketType::kAbort) { 56 | return OnReceiverAbortPacket(context, packet, ec); 57 | } 58 | } 59 | 60 | bool IsTerminal(CopyContext* context) { return false; } 61 | }; 62 | 63 | } // copy 64 | } // services 65 | } // ssf 66 | 67 | #endif // SSF_SERVICES_COPY_STATE_RECEIVER_SEND_EOF_STATE_H_ 68 | -------------------------------------------------------------------------------- /src/services/copy/state/receiver/wait_close_state.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_STATE_RECEIVER_WAIT_CLOSE_STATE_H_ 2 | #define SSF_SERVICES_COPY_STATE_RECEIVER_WAIT_CLOSE_STATE_H_ 3 | 4 | #include 5 | 6 | #include "common/error/error.h" 7 | 8 | #include "services/copy/i_copy_state.h" 9 | 10 | namespace ssf { 11 | namespace services { 12 | namespace copy { 13 | 14 | class WaitCloseState : ICopyState { 15 | public: 16 | template 17 | static ICopyStateUPtr Create(Args&&... args) { 18 | return ICopyStateUPtr(new WaitCloseState(std::forward(args)...)); 19 | } 20 | 21 | public: 22 | // ICopyState 23 | void Enter(CopyContext* context, boost::system::error_code& ec) override { 24 | SSF_LOG("microservice", trace, "[copy][wait_close] enter"); 25 | } 26 | 27 | bool FillOutboundPacket(CopyContext* context, Packet* packet, 28 | boost::system::error_code& ec) override { 29 | return false; 30 | } 31 | void ProcessInboundPacket(CopyContext* context, const Packet& packet, 32 | boost::system::error_code& ec) override { 33 | if (packet.type() == PacketType::kAbort) { 34 | return OnReceiverAbortPacket(context, packet, ec); 35 | } 36 | 37 | // noop 38 | } 39 | 40 | bool IsClosed(CopyContext* context) override { return false; } 41 | 42 | bool IsTerminal(CopyContext* context) override { return true; } 43 | }; 44 | 45 | } // copy 46 | } // services 47 | } // ssf 48 | 49 | #endif // SSF_SERVICES_COPY_STATE_RECEIVER_WAIT_CLOSE_STATE_H_ 50 | -------------------------------------------------------------------------------- /src/services/copy/state/sender/close_state.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_STATE_SENDER_CLOSE_STATE_H_ 2 | #define SSF_SERVICES_COPY_STATE_SENDER_CLOSE_STATE_H_ 3 | 4 | #include 5 | 6 | #include "common/error/error.h" 7 | 8 | #include "services/copy/i_copy_state.h" 9 | 10 | namespace ssf { 11 | namespace services { 12 | namespace copy { 13 | 14 | class CloseState : ICopyState { 15 | public: 16 | template 17 | static ICopyStateUPtr Create(Args&&... args) { 18 | return ICopyStateUPtr(new CloseState(std::forward(args)...)); 19 | } 20 | 21 | public: 22 | // ICopyState 23 | void Enter(CopyContext* context, boost::system::error_code& ec) override { 24 | SSF_LOG("microservice", trace, "[copy][close] enter"); 25 | } 26 | 27 | bool FillOutboundPacket(CopyContext* context, Packet* packet, 28 | boost::system::error_code& ec) override { 29 | return false; 30 | } 31 | void ProcessInboundPacket(CopyContext* context, const Packet& packet, 32 | boost::system::error_code& ec) override { 33 | // noop 34 | } 35 | 36 | bool IsClosed(CopyContext* context) override { return true; } 37 | 38 | bool IsTerminal(CopyContext* context) override { return true; } 39 | }; 40 | 41 | } // copy 42 | } // services 43 | } // ssf 44 | 45 | #endif // SSF_SERVICES_COPY_STATE_SENDER_CLOSE_STATE_H_ 46 | -------------------------------------------------------------------------------- /src/services/copy/state/sender/wait_abort_ack_state.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_COPY_STATE_SENDER_WAIT_ABORT_ACK_STATE_H_ 2 | #define SSF_SERVICES_COPY_STATE_SENDER_WAIT_ABORT_ACK_STATE_H_ 3 | 4 | #include 5 | 6 | #include "common/error/error.h" 7 | 8 | #include "services/copy/i_copy_state.h" 9 | #include "services/copy/state/sender/close_state.h" 10 | 11 | namespace ssf { 12 | namespace services { 13 | namespace copy { 14 | 15 | class WaitAbortAckState : ICopyState { 16 | public: 17 | template 18 | static ICopyStateUPtr Create(Args&&... args) { 19 | return ICopyStateUPtr(new WaitAbortAckState(std::forward(args)...)); 20 | } 21 | 22 | public: 23 | // ICopyState 24 | void Enter(CopyContext* context, boost::system::error_code& ec) override { 25 | SSF_LOG("microservice", trace, "[copy][wait_abort_ack] enter"); 26 | } 27 | 28 | bool FillOutboundPacket(CopyContext* context, Packet* packet, 29 | boost::system::error_code& ec) override { 30 | return false; 31 | } 32 | 33 | void ProcessInboundPacket(CopyContext* context, const Packet& packet, 34 | boost::system::error_code& ec) override { 35 | if (packet.type() != PacketType::kAbortAck) { 36 | SSF_LOG("microservice", debug, 37 | "[copy][wait_abort_ack] cannot process inbound packet"); 38 | ec.assign(::error::protocol_error, ::error::get_ssf_category()); 39 | return; 40 | } 41 | 42 | context->SetState(CloseState::Create()); 43 | } 44 | 45 | bool IsTerminal(CopyContext* context) override { return false; } 46 | }; 47 | 48 | } // copy 49 | } // services 50 | } // ssf 51 | 52 | #endif // SSF_SERVICES_COPY_STATE_SENDER_WAIT_ABORT_ACK_STATE_H_ 53 | -------------------------------------------------------------------------------- /src/services/datagrams_to_fibers/config.cpp: -------------------------------------------------------------------------------- 1 | #include "services/datagrams_to_fibers/config.h" 2 | 3 | namespace ssf { 4 | namespace services { 5 | namespace datagrams_to_fibers { 6 | 7 | Config::Config() : BaseServiceConfig(true), gateway_ports_(false) {} 8 | 9 | Config::Config(const Config& datagram_listener) 10 | : BaseServiceConfig(datagram_listener.enabled()), 11 | gateway_ports_(datagram_listener.gateway_ports_) {} 12 | 13 | } // datagrams_to_fibers 14 | } // services 15 | } // ssf -------------------------------------------------------------------------------- /src/services/datagrams_to_fibers/config.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_DATAGRAMS_TO_FIBERS_CONFIG_H_ 2 | #define SSF_SERVICES_DATAGRAMS_TO_FIBERS_CONFIG_H_ 3 | 4 | #include "services/base_service_config.h" 5 | 6 | namespace ssf { 7 | namespace services { 8 | namespace datagrams_to_fibers { 9 | 10 | class Config : public BaseServiceConfig { 11 | public: 12 | Config(); 13 | Config(const Config& datagram_listener); 14 | 15 | inline bool gateway_ports() const { return gateway_ports_; } 16 | inline void set_gateway_ports(bool gateway_ports) { 17 | gateway_ports_ = gateway_ports; 18 | } 19 | 20 | private: 21 | bool gateway_ports_; 22 | }; 23 | 24 | } // datagrams_to_fibers 25 | } // services 26 | } // ssf 27 | 28 | #endif // SSF_SERVICES_DATAGRAMS_TO_FIBERS_CONFIG_H_ -------------------------------------------------------------------------------- /src/services/fibers_to_datagrams/config.cpp: -------------------------------------------------------------------------------- 1 | #include "services/fibers_to_datagrams/config.h" 2 | 3 | namespace ssf { 4 | namespace services { 5 | namespace fibers_to_datagrams { 6 | 7 | Config::Config() : BaseServiceConfig(true) {} 8 | 9 | Config::Config(const Config& datagram_forwarder) 10 | : BaseServiceConfig(datagram_forwarder.enabled()) {} 11 | 12 | } // fibers_to_datagrams 13 | } // services 14 | } // ssf -------------------------------------------------------------------------------- /src/services/fibers_to_datagrams/config.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_FIBERS_TO_DATAGRAMS_CONFIG_H_ 2 | #define SSF_SERVICES_FIBERS_TO_DATAGRAMS_CONFIG_H_ 3 | 4 | #include "services/base_service_config.h" 5 | 6 | namespace ssf { 7 | namespace services { 8 | namespace fibers_to_datagrams { 9 | 10 | class Config : public BaseServiceConfig { 11 | public: 12 | Config(); 13 | Config(const Config& datagram_forwarder); 14 | }; 15 | 16 | } // fibers_to_datagrams 17 | } // services 18 | } // ssf 19 | 20 | #endif // SSF_SERVICES_FIBERS_TO_DATAGRAMS_CONFIG_H_ -------------------------------------------------------------------------------- /src/services/fibers_to_sockets/config.cpp: -------------------------------------------------------------------------------- 1 | #include "services/fibers_to_sockets/config.h" 2 | 3 | namespace ssf { 4 | namespace services { 5 | namespace fibers_to_sockets { 6 | 7 | Config::Config() : BaseServiceConfig(true) {} 8 | 9 | Config::Config(const Config& stream_forwarder) 10 | : BaseServiceConfig(stream_forwarder.enabled()) {} 11 | 12 | } // fibers_to_sockets 13 | } // services 14 | } // ssf -------------------------------------------------------------------------------- /src/services/fibers_to_sockets/config.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_FIBERS_TO_SOCKETS_CONFIG_H_ 2 | #define SSF_SERVICES_FIBERS_TO_SOCKETS_CONFIG_H_ 3 | 4 | #include "services/base_service_config.h" 5 | 6 | namespace ssf { 7 | namespace services { 8 | namespace fibers_to_sockets { 9 | 10 | class Config : public BaseServiceConfig { 11 | public: 12 | Config(); 13 | Config(const Config& stream_forwarder); 14 | }; 15 | 16 | } // fibers_to_sockets 17 | } // services 18 | } // ssf 19 | 20 | #endif // SSF_SERVICES_FIBERS_TO_SOCKETS_CONFIG_H_ -------------------------------------------------------------------------------- /src/services/process/config.cpp: -------------------------------------------------------------------------------- 1 | #include "services/process/config.h" 2 | 3 | namespace ssf { 4 | namespace services { 5 | namespace process { 6 | 7 | Config::Config() : BaseServiceConfig(false), path_(""), args_("") {} 8 | 9 | Config::Config(const Config& process_service) 10 | : BaseServiceConfig(process_service.enabled()), 11 | path_(process_service.path_), 12 | args_(process_service.args_) {} 13 | 14 | } // process 15 | } // services 16 | } // ssf -------------------------------------------------------------------------------- /src/services/process/config.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_PROCESS_CONFIG_H_ 2 | #define SSF_SERVICES_PROCESS_CONFIG_H_ 3 | 4 | #include 5 | 6 | #include "services/base_service_config.h" 7 | 8 | namespace ssf { 9 | namespace services { 10 | namespace process { 11 | 12 | class Config : public BaseServiceConfig { 13 | public: 14 | Config(); 15 | Config(const Config& process_service); 16 | 17 | inline std::string path() const { return path_; } 18 | inline void set_path(const std::string& path) { path_ = path; } 19 | 20 | inline std::string args() const { return args_; } 21 | inline void set_args(const std::string& args) { args_ = args; } 22 | 23 | private: 24 | std::string path_; 25 | std::string args_; 26 | }; 27 | 28 | } // process 29 | } // services 30 | } // ssf 31 | 32 | #endif // SSF_SERVICES_PROCESS_CONFIG_H_ -------------------------------------------------------------------------------- /src/services/service_id.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_SERVICE_ID_H_ 2 | #define SSF_SERVICES_SERVICE_ID_H_ 3 | 4 | namespace ssf { 5 | namespace services { 6 | 7 | enum class MicroserviceId { 8 | kMin = 0, 9 | kAdmin, 10 | kCopyServer, 11 | kDatagramsToFibers, 12 | kFibersToDatagrams, 13 | kSocketsToFibers, 14 | kFibersToSockets, 15 | kProcessServer, 16 | kSocksServer, 17 | kMax 18 | }; 19 | 20 | } // services 21 | } // ssf 22 | 23 | #endif // SSF_SERVICES_SERVICE_ID_H_ 24 | -------------------------------------------------------------------------------- /src/services/service_port.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_SERVICE_PORT_H_ 2 | #define SSF_SERVICES_SERVICE_PORT_H_ 3 | 4 | namespace ssf { 5 | namespace services { 6 | 7 | enum class MicroservicePort { 8 | kMin = (1 << 17), 9 | kAdmin, 10 | kCopyServer, 11 | kCopyFileAcceptor, 12 | kMax 13 | }; 14 | 15 | } // services 16 | } // ssf 17 | 18 | #endif // SSF_SERVICES_SERVICE_PORT_H_ 19 | -------------------------------------------------------------------------------- /src/services/sockets_to_fibers/config.cpp: -------------------------------------------------------------------------------- 1 | #include "services/sockets_to_fibers/config.h" 2 | 3 | namespace ssf { 4 | namespace services { 5 | namespace sockets_to_fibers { 6 | 7 | Config::Config() : BaseServiceConfig(true), gateway_ports_(false) {} 8 | 9 | Config::Config(const Config& stream_listener) 10 | : BaseServiceConfig(stream_listener.enabled()), 11 | gateway_ports_(stream_listener.gateway_ports_) {} 12 | 13 | } // sockets_to_fibers 14 | } // services 15 | } // ssf -------------------------------------------------------------------------------- /src/services/sockets_to_fibers/config.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_SOCKETS_TO_FIBERS_CONFIG_H_ 2 | #define SSF_SERVICES_SOCKETS_TO_FIBERS_CONFIG_H_ 3 | 4 | #include "services/base_service_config.h" 5 | 6 | namespace ssf { 7 | namespace services { 8 | namespace sockets_to_fibers { 9 | 10 | class Config : public BaseServiceConfig { 11 | public: 12 | Config(); 13 | Config(const Config& stream_listener); 14 | 15 | inline bool gateway_ports() const { return gateway_ports_; } 16 | inline void set_gateway_ports(bool gateway_ports) { 17 | gateway_ports_ = gateway_ports; 18 | } 19 | 20 | private: 21 | bool gateway_ports_; 22 | }; 23 | 24 | } // sockets_to_fibers 25 | } // services 26 | } // ssf 27 | 28 | #endif // SSF_SERVICES_SOCKETS_TO_FIBERS_CONFIG_H_ -------------------------------------------------------------------------------- /src/services/socks/config.cpp: -------------------------------------------------------------------------------- 1 | #include "services/socks/config.h" 2 | 3 | namespace ssf { 4 | namespace services { 5 | namespace socks { 6 | 7 | Config::Config() : BaseServiceConfig(true) {} 8 | 9 | Config::Config(const Config& process_service) 10 | : BaseServiceConfig(process_service.enabled()) {} 11 | 12 | } // socks 13 | } // services 14 | } // ssf -------------------------------------------------------------------------------- /src/services/socks/config.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_SOCKS_CONFIG_H_ 2 | #define SSF_SERVICES_SOCKS_CONFIG_H_ 3 | 4 | #include 5 | 6 | #include "services/base_service_config.h" 7 | 8 | namespace ssf { 9 | namespace services { 10 | namespace socks { 11 | 12 | class Config : public BaseServiceConfig { 13 | public: 14 | Config(); 15 | Config(const Config& process_service); 16 | }; 17 | 18 | } // socks 19 | } // services 20 | } // ssf 21 | 22 | #endif // SSF_SERVICES_SOCKS_CONFIG_H_ -------------------------------------------------------------------------------- /src/services/socks/socks_version.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_SOCKS_VERSION_H_ 2 | #define SSF_SERVICES_SOCKS_VERSION_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ssf { 9 | namespace services { 10 | namespace socks { 11 | 12 | class Version { 13 | public: 14 | uint8_t Number() const { return version_number_; } 15 | 16 | std::array MutBuffer() { 17 | std::array buf = { 18 | {boost::asio::buffer(&version_number_, 1)}}; 19 | return buf; 20 | } 21 | 22 | private: 23 | uint8_t version_number_; 24 | }; 25 | 26 | } // socks 27 | } // services 28 | } // ssf 29 | 30 | #endif // SSF_SERVICES_SOCKS_VERSION_H_ 31 | -------------------------------------------------------------------------------- /src/services/user_services/base_user_service.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_USER_SERVICES_BASE_USER_SERVICE_H_ 2 | #define SSF_SERVICES_USER_SERVICES_BASE_USER_SERVICE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "services/admin/requests/create_service_request.h" 9 | #include "services/admin/requests/stop_service_request.h" 10 | 11 | #include "services/user_services/parameters.h" 12 | 13 | #include "core/command_line/base.h" 14 | 15 | namespace ssf { 16 | namespace services { 17 | 18 | template 19 | class BaseUserService 20 | : public std::enable_shared_from_this> { 21 | public: 22 | typedef typename std::shared_ptr> BaseUserServicePtr; 23 | 24 | BaseUserService() {} 25 | virtual ~BaseUserService() {} 26 | 27 | virtual std::vector> 28 | GetRemoteServiceCreateVector() = 0; 29 | virtual std::vector> 30 | GetRemoteServiceStopVector(Demux& demux) = 0; 31 | virtual uint32_t CheckRemoteServiceStatus(Demux& demux) = 0; 32 | 33 | virtual std::string GetName() = 0; 34 | 35 | virtual bool StartLocalServices(Demux& demux) = 0; 36 | virtual void StopLocalServices(Demux& demux) = 0; 37 | 38 | private: 39 | BaseUserService(const BaseService&) = delete; 40 | BaseUserService& operator=(const BaseService&) = delete; 41 | }; 42 | 43 | } // services 44 | } // ssf 45 | 46 | #endif // SSF_SERVICES_USER_SERVICES_BASE_USER_SERVICE_H_ 47 | -------------------------------------------------------------------------------- /src/services/user_services/option_parser.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_OPTION_PARSER_H_ 2 | #define SSF_SERVICES_OPTION_PARSER_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | namespace ssf { 11 | namespace services { 12 | 13 | struct Endpoint { 14 | Endpoint(); 15 | 16 | std::string addr; 17 | uint16_t port; 18 | }; 19 | 20 | struct ForwardOptions { 21 | ForwardOptions(); 22 | Endpoint from; 23 | Endpoint to; 24 | }; 25 | 26 | class OptionParser { 27 | public: 28 | // Parse forward option 29 | // Expected format: [[loc_addr]:]loc_port:rem_addr:rem_port 30 | // If loc_addr is empty on purpose, set its value as "*" 31 | // Set ec if parsing failed 32 | static ForwardOptions ParseForwardOptions(const std::string& option, 33 | boost::system::error_code& ec); 34 | 35 | // Parse listening option 36 | // Expected format: [[loc_addr]:]loc_port 37 | // If loc_addr is empty on purpose, set its value as "*" 38 | // Set ec if parsing failed 39 | static Endpoint ParseListeningOption(const std::string& option, 40 | boost::system::error_code& ec); 41 | 42 | static uint16_t ParsePort(const std::string& port, 43 | boost::system::error_code& ec); 44 | }; 45 | 46 | } // services 47 | } // ssf 48 | 49 | #endif // SSF_SERVICES_OPTION_PARSER_H_ -------------------------------------------------------------------------------- /src/services/user_services/parameters.h: -------------------------------------------------------------------------------- 1 | #ifndef SSF_SERVICES_USER_SERVICES_PARAMETERS_H_ 2 | #define SSF_SERVICES_USER_SERVICES_PARAMETERS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ssf { 9 | 10 | using UserServiceParameterBag = std::map; 11 | using UserServiceParameters = 12 | std::map>; 13 | 14 | } // ssf 15 | 16 | #endif // SSF_SERVICES_USER_SERVICES_PARAMETERS_H_ 17 | -------------------------------------------------------------------------------- /src/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(tls_config_helper STATIC EXCLUDE_FROM_ALL 2 | tls_config_helper.h tls_config_helper.cpp) 3 | target_link_libraries(tls_config_helper PUBLIC ssf_framework test_certs) 4 | 5 | set_property(TARGET tls_config_helper PROPERTY FOLDER "Unit Tests") 6 | 7 | add_subdirectory(commandline) 8 | add_subdirectory(config) 9 | add_subdirectory(filesystem) 10 | add_subdirectory(network) 11 | add_subdirectory(services) 12 | -------------------------------------------------------------------------------- /src/tests/commandline/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # --- Command line tests 2 | 3 | add_executable(commandline_tests EXCLUDE_FROM_ALL commandline_tests.cpp) 4 | target_link_libraries(commandline_tests ssf_framework) 5 | add_unit_test(commandline_tests) 6 | set_property(TARGET commandline_tests PROPERTY FOLDER "Unit Tests/CommandLine") 7 | -------------------------------------------------------------------------------- /src/tests/config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB_RECURSE CONFIG_TEST_FILES 2 | "${CMAKE_CURRENT_SOURCE_DIR}/config_files/*.json") 3 | 4 | file(MAKE_DIRECTORY config_files) 5 | file(COPY ${CONFIG_TEST_FILES} DESTINATION config_files) 6 | 7 | # --- Config tests 8 | 9 | # --- Load config test 10 | add_executable(load_config_tests EXCLUDE_FROM_ALL load_config_tests.cpp) 11 | target_link_libraries(load_config_tests ssf_framework gtest) 12 | set_property(TARGET load_config_tests PROPERTY FOLDER "Unit Tests/Config") 13 | add_unit_test(load_config_tests) 14 | -------------------------------------------------------------------------------- /src/tests/config/config_files/arguments.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssf": { 3 | "arguments": "-c \"a/path to/config_file.json\" -D 9000 -X 10000 -L 11000:localhost:12000" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/tests/config/config_files/circuit.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssf": { 3 | "circuit" : [ 4 | {"host": "127.0.0.1" , "port": "8011"}, 5 | {"host": "127.0.0.2" , "port": "8012"}, 6 | {"host": "127.0.0.3" , "port": "8013"} 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/tests/config/config_files/complete.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssf": { 3 | "tls" : { 4 | "ca_cert_path": " test_ca_path", 5 | "cert_path": "test_cert_path ", 6 | "key_path": " test_key_path ", 7 | "key_password": " test_key_password ", 8 | "dh_path": " test_dh_path ", 9 | "cipher_alg": " test_cipher_alg " 10 | }, 11 | "http_proxy" : { 12 | "host": " 127.0.0.1 ", 13 | "port": " 8080 ", 14 | "user_agent": " Mozilla/5.0", 15 | "credentials": { 16 | "username": " test_user ", 17 | "password": " test_password ", 18 | "domain": " test_domain ", 19 | "reuse_ntlm": false, 20 | "reuse_kerb": false 21 | } 22 | }, 23 | "socks_proxy": { 24 | "version": 4, 25 | "host": " 127.0.0.2 ", 26 | "port": " 1080 " 27 | }, 28 | "services" : { 29 | "shell": { 30 | "path": "/bin/custom_path", 31 | "args": "-custom args" 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/tests/config/config_files/empty.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securesocketfunneling/ssf/2caaaab4ef8def710f960b8ea96937f6a80fe060/src/tests/config/config_files/empty.json -------------------------------------------------------------------------------- /src/tests/config/config_files/proxy.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssf": { 3 | "http_proxy" : { 4 | "host": "127.0.0.1", 5 | "port": "8080", 6 | "user_agent": "Mozilla/5.0 ", 7 | "credentials": { 8 | "username": "test_user", 9 | "password": "test_password", 10 | "domain": "test_domain", 11 | "reuse_ntlm": false, 12 | "reuse_kerb": false 13 | } 14 | }, 15 | "socks_proxy": { 16 | "version": 5, 17 | "host": "127.0.0.2", 18 | "port": "1080" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/tests/config/config_files/services.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssf": { 3 | "services" : { 4 | "datagram_forwarder": { "enable": false }, 5 | "datagram_listener": { 6 | "enable": false, 7 | "gateway_ports": true 8 | }, 9 | "stream_forwarder": { "enable": false }, 10 | "stream_listener": { 11 | "enable": false, 12 | "gateway_ports": true 13 | }, 14 | "copy": { "enable": true }, 15 | "shell": { 16 | "enable": true, 17 | "path": "/bin/custom_path", 18 | "args": "-custom args" 19 | }, 20 | "socks": { "enable": false } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/tests/config/config_files/tls_buffer.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssf": { 3 | "tls" : { 4 | "ca_cert_buffer": "test_ca_cert_buffer", 5 | "cert_buffer": "test_cert_buffer", 6 | "key_buffer": "test_key_buffer", 7 | "key_password": "test_key_password", 8 | "dh_buffer": "test_dh_buffer", 9 | "cipher_alg": "test_cipher_alg" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/tests/config/config_files/tls_complete.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssf": { 3 | "tls" : { 4 | "ca_cert_path": "test_ca_path", 5 | "cert_path": "test_cert_path", 6 | "key_buffer": "test_key_buffer", 7 | "key_password": "test_key_password", 8 | "dh_path": "test_dh_path", 9 | "cipher_alg": "test_cipher_alg" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/tests/config/config_files/tls_partial.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssf": { 3 | "tls" : { 4 | "ca_cert_path": "test_ca_path", 5 | "key_path": "test_key_path", 6 | "dh_path": "test_dh_path" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/tests/config/config_files/wrong_format.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssf": { 3 | "tls" : { 4 | "ca_cert_path": "test" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/tests/filesystem/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # --- Filesystem tests 2 | file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/filesystem) 3 | 4 | add_executable(filesystem_tests EXCLUDE_FROM_ALL filesystem_tests.cpp) 5 | target_link_libraries(filesystem_tests ssf_framework gtest) 6 | set_property(TARGET filesystem_tests PROPERTY FOLDER "Unit Tests/Filesystem") 7 | add_unit_test(filesystem_tests) 8 | -------------------------------------------------------------------------------- /src/tests/network/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(fixture_test STATIC EXCLUDE_FROM_ALL ssf_fixture_test.h ssf_fixture_test.cpp) 2 | target_link_libraries(fixture_test gtest ssf_framework) 3 | set_property(TARGET fixture_test PROPERTY FOLDER "Unit Tests/Network") 4 | 5 | # --- Fiber asio tests 6 | add_executable(fiber_asio_tests EXCLUDE_FROM_ALL fiber_asio_tests.cpp) 7 | target_link_libraries(fiber_asio_tests ssf_framework tls_config_helper) 8 | add_unit_test(fiber_asio_tests) 9 | set_property(TARGET fiber_asio_tests PROPERTY FOLDER "Unit Tests/Network") 10 | 11 | # --- SSF Client Server tests 12 | add_executable(ssf_client_server_tests EXCLUDE_FROM_ALL ssf_client_server_tests.cpp) 13 | target_link_libraries(ssf_client_server_tests ssf_framework tls_config_helper) 14 | add_unit_test(ssf_client_server_tests) 15 | set_property(TARGET ssf_client_server_tests PROPERTY FOLDER "Unit Tests/Network") 16 | 17 | # --- SSF Client Server cipher suites tests 18 | add_executable(ssf_client_server_cipher_suites_tests EXCLUDE_FROM_ALL ssf_client_server_cipher_suites_tests.cpp) 19 | target_link_libraries(ssf_client_server_cipher_suites_tests ssf_framework tls_config_helper) 20 | add_unit_test(ssf_client_server_cipher_suites_tests) 21 | set_property(TARGET ssf_client_server_cipher_suites_tests PROPERTY FOLDER "Unit Tests/Network") 22 | 23 | # --- SSF Client tests 24 | add_executable(ssf_client_tests EXCLUDE_FROM_ALL ssf_client_tests.cpp) 25 | target_link_libraries(ssf_client_tests ssf_framework fixture_test tls_config_helper) 26 | add_unit_test(ssf_client_tests) 27 | set_property(TARGET ssf_client_tests PROPERTY FOLDER "Unit Tests/Network") 28 | 29 | # --- SSF Server tests 30 | add_executable(ssf_server_tests EXCLUDE_FROM_ALL ssf_server_tests.cpp) 31 | target_link_libraries(ssf_server_tests ssf_framework fixture_test tls_config_helper) 32 | add_unit_test(ssf_server_tests) 33 | set_property(TARGET ssf_server_tests PROPERTY FOLDER "Unit Tests/Network") 34 | 35 | # --- Circuit tests 36 | add_executable(circuit_tests EXCLUDE_FROM_ALL circuit_tests.cpp) 37 | target_link_libraries(circuit_tests ssf_framework tls_config_helper) 38 | add_unit_test(circuit_tests) 39 | set_property(TARGET circuit_tests PROPERTY FOLDER "Unit Tests/Network") 40 | -------------------------------------------------------------------------------- /src/tests/services/datagram_fixture_test.h: -------------------------------------------------------------------------------- 1 | #ifndef TESTS_SERVICES_DATAGRAM_FIXTURE_TEST_H_ 2 | #define TESTS_SERVICES_DATAGRAM_FIXTURE_TEST_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "tests/services/service_fixture_test.h" 13 | #include "tests/services/udp_helpers.h" 14 | 15 | template