├── tools └── CMakeLists.txt ├── bindings ├── CMakeLists.txt └── python │ ├── CMakeLists.txt │ ├── examples │ ├── timeout_port.py │ ├── stdin.py │ ├── test_end.py │ ├── data_trigger.py │ ├── certifs.py │ └── http.py │ └── pynodescan.cpp ├── src ├── include │ └── ns │ │ ├── config.h.in │ │ ├── errors.h │ │ ├── log.h │ │ ├── timestamp.h │ │ ├── ipstr.h │ │ ├── lvl4_buffer.h │ │ ├── state_machine.h │ │ ├── data_trigger_base.h │ │ ├── static_max_size.h │ │ ├── connected_target.h │ │ ├── action.h │ │ ├── host_state_machine.h │ │ ├── protocols │ │ ├── ssh.h │ │ ├── sip.h │ │ ├── ssl_structs.h │ │ └── ssl.h │ │ ├── data_trigger_variant.h │ │ ├── target.h │ │ ├── lvl4_properties_storage.h │ │ ├── data_triggers.h │ │ ├── engine.h │ │ ├── target_file.h │ │ ├── lvl4_state_machine.h │ │ ├── buffer.h │ │ ├── async_engine.h │ │ └── target_set.h ├── CMakeLists.txt ├── timestamp.cpp ├── state_machine.cpp ├── connected_target.cpp ├── ipstr.cpp ├── host_state_machine.cpp ├── engine.cpp ├── target.cpp ├── lvl4_state_machine.cpp ├── data_triggers.cpp ├── protocols │ ├── sip.cpp │ ├── ssl.cpp │ └── ssh.cpp ├── target_file.cpp ├── target_set.cpp └── async_engine.cpp ├── .gitignore ├── CMakeLists.txt ├── CMakeCompilers.txt ├── CMakeRequiredLibraries.txt ├── tests ├── CMakeLists.txt ├── ssh.cpp ├── buffer.cpp ├── server_recon.py ├── sip.cpp ├── size_trigger.cpp ├── recon.cpp ├── target_set.cpp ├── data_trigger_variant.cpp ├── http.cpp └── ssl.cpp ├── README.md ├── LICENSE └── cmake └── FindTBB.cmake /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bindings/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(python) 2 | -------------------------------------------------------------------------------- /src/include/ns/config.h.in: -------------------------------------------------------------------------------- 1 | #ifndef NS_CONFIG_H_IN 2 | #define NS_CONFIG_H_IN 3 | 4 | #if @NODESCAN_USE_LOG@ 5 | #define USE_BOOST_LOG 6 | #endif 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/include/ns/errors.h: -------------------------------------------------------------------------------- 1 | #ifndef NS_ERROS_H 2 | #define NS_ERROS_H 3 | 4 | namespace ns { 5 | 6 | enum class errors : int { 7 | NS_TIMEOUT = 1000, 8 | WILL_RECONNECT 9 | }; 10 | 11 | } 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Compiled Dynamic libraries 8 | *.so 9 | *.dylib 10 | *.dll 11 | 12 | # Compiled Static libraries 13 | *.lai 14 | *.la 15 | *.a 16 | *.lib 17 | 18 | # Executables 19 | *.exe 20 | *.out 21 | *.app 22 | -------------------------------------------------------------------------------- /src/include/ns/log.h: -------------------------------------------------------------------------------- 1 | #ifndef NS_LOG_H 2 | #define NS_LOG_H 3 | 4 | #include 5 | 6 | #ifdef USE_BOOST_LOG 7 | #include 8 | #include 9 | #include 10 | #endif 11 | 12 | #ifndef USE_BOOST_LOG 13 | #define _D(...) 14 | #else 15 | #define _D(a) a 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /bindings/python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PYTHON_SRC_FILES 2 | pynodescan.cpp 3 | ) 4 | 5 | add_library(pynodescan SHARED ${PYTHON_SRC_FILES}) 6 | set_target_properties(pynodescan PROPERTIES PREFIX "") # We need our ".so" to be named "pyleeloo" (same name as in the BOOST_PYTHON_MODULE macro) 7 | target_link_libraries(pynodescan nodescan) 8 | 9 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())" OUTPUT_VARIABLE PYTHON_INSTALL OUTPUT_STRIP_TRAILING_WHITESPACE) 10 | install(TARGETS pynodescan LIBRARY DESTINATION ${PYTHON_INSTALL}/) 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(nodescan) 3 | 4 | enable_testing() 5 | 6 | if(NOT NODESCAN_USE_LOG) 7 | set(NODESCAN_USE_LOG 0) 8 | endif() 9 | 10 | include(CMakeCompilers.txt) 11 | include(CMakeRequiredLibraries.txt) 12 | 13 | include_directories(${CMAKE_SOURCE_DIR}/src/include) 14 | include_directories(${CMAKE_BINARY_DIR}/src/include) 15 | 16 | add_subdirectory(src) 17 | if (NOT (DEFINED NO_TESTS OR NO_TESTS)) 18 | add_subdirectory(tests) 19 | endif() 20 | if (NOT (DEFINED NO_TOOLS OR NO_TOOLS)) 21 | add_subdirectory(tools) 22 | endif() 23 | add_subdirectory(bindings) 24 | -------------------------------------------------------------------------------- /CMakeCompilers.txt: -------------------------------------------------------------------------------- 1 | if ((CMAKE_COMPILER_IS_GNUCC) OR ("CMAKE_CXX_COMPILER_ID" STREQUAL "Clang")) 2 | set(GCC_OPTS "") 3 | if (GCC_ARCH) 4 | set(GCC_OPTS "-march=${GCC_ARCH} -mtune=${GCC_ARCH}") 5 | endif() 6 | 7 | set(CMAKE_CXX_FLAGS_COMMON "-Wall -Wextra -std=c++11 ${GCC_OPTS}") 8 | #set(CMAKE_CXX_FLAGS_COMMON "-Wall -Wextra -std=c++11 ${GCC_OPTS} -fvisibility=hidden") 9 | 10 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_COMMON} -g3 -DNDEBUG") 11 | set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_COMMON} -g3 -O3 -DNDEBUG") 12 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_COMMON} -O3 -DNDEBUG") 13 | endif() 14 | -------------------------------------------------------------------------------- /bindings/python/examples/timeout_port.py: -------------------------------------------------------------------------------- 1 | import pyleeloo 2 | import pynodescan 3 | 4 | ips = pyleeloo.ip_list_intervals() 5 | ips.add("127.0.0.1") 6 | 7 | ports = pyleeloo.port_list_intervals() 8 | ports.add(pyleeloo.tcp_port(5555)) 9 | ports.add(pyleeloo.tcp_port(5556)) 10 | 11 | targets = pynodescan.IPV4TargetSet(ips, ports) 12 | 13 | engine = pynodescan.AsyncEngine(targets, 2, 60) 14 | def on_connect(t, l, h): 15 | print("on_connect %s" % str(t.port())) 16 | return True 17 | engine.set_lvl4_connected_callback(on_connect) 18 | 19 | def timeout_of_target(t): 20 | if t.port() == pyleeloo.tcp_port(5555): 21 | return 5 22 | return 10 23 | 24 | engine.set_timeout_of_target(timeout_of_target) 25 | engine.set_lvl4_finish_callback(lambda t, b, e: print("finish for %s/%d" % (str(t.port()), e))) 26 | 27 | engine.launch() 28 | -------------------------------------------------------------------------------- /CMakeRequiredLibraries.txt: -------------------------------------------------------------------------------- 1 | # Python and boost python 2 | if(NOT DEFINED PYTHON_VERSION) 3 | set(PYTHON_VERSION 3.3) 4 | endif() 5 | string(REGEX REPLACE "\\." "" PYTHON_VERSION_BOOST ${PYTHON_VERSION}) 6 | find_package(PythonLibs ${PYTHON_VERSION} REQUIRED) 7 | set(PythonInterp_FIND_VERSION ${PYTHON_VERSION}) 8 | find_package(PythonInterp) 9 | 10 | set(BOOST_COMPONENTS python-py${PYTHON_VERSION_BOOST} random serialization) 11 | if(NODESCAN_USE_LOG) 12 | set(BOOST_COMPONENTS ${BOOST_COMPONENTS} log) 13 | endif() 14 | 15 | find_package(Boost COMPONENTS ${BOOST_COMPONENTS} REQUIRED) 16 | add_definitions(-DBOOST_LOG_DYN_LINK) 17 | 18 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") 19 | find_package(TBB REQUIRED) 20 | 21 | include_directories(${BOOST_LIBRARIES}) 22 | include_directories(${PYTHON_INCLUDE_DIRS}) 23 | include_directories(${TBB_INCLUDE_DIRS}) 24 | -------------------------------------------------------------------------------- /bindings/python/examples/stdin.py: -------------------------------------------------------------------------------- 1 | import pyleeloo 2 | import pynodescan 3 | import ipaddress 4 | 5 | targets = pynodescan.ReinjectableTargetStdin(pyleeloo.tcp_port(1245)) 6 | engine = pynodescan.AsyncEngine(targets, 1, 100) 7 | 8 | def ip2str(ip): 9 | return str(ipaddress.ip_address(ip)) 10 | 11 | def send_hello(self, target, lvl4sm, hsm): 12 | print("send hello to %s" % ip2str(target.ipv4())) 13 | s = "hello" 14 | target.send(s) 15 | return False 16 | 17 | n = 4 18 | def finish(target, err): 19 | print("finished for %s/%s: %d" % (ip2str(target.ipv4()), str(target.port()), err)) 20 | global n 21 | if n > 0: 22 | targets.add_target(pynodescan.Target(target.ipv4(), pyleeloo.tcp_port(1246))) 23 | n -= 1 24 | 25 | engine.set_lvl4_connected_callback(send_hello) 26 | engine.set_lvl4_finish_callback(finish) 27 | engine.launch() 28 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LINK_LIBRARIES nodescan ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} ${TBB_LIBRARIES}) 2 | 3 | add_executable(size_trigger size_trigger.cpp) 4 | target_link_libraries(size_trigger ${LINK_LIBRARIES}) 5 | 6 | add_executable(http http.cpp) 7 | target_link_libraries(http ${LINK_LIBRARIES}) 8 | 9 | add_executable(buffer buffer.cpp) 10 | target_link_libraries(buffer ${LINK_LIBRARIES}) 11 | add_test(TestBuffer buffer) 12 | 13 | add_executable(data_trigger_variant data_trigger_variant.cpp) 14 | target_link_libraries(data_trigger_variant ${LINK_LIBRARIES}) 15 | add_test(TestDataTriggerVariant data_trigger_variant) 16 | 17 | add_executable(recon recon.cpp) 18 | target_link_libraries(recon ${LINK_LIBRARIES}) 19 | 20 | add_executable(ssl ssl.cpp) 21 | target_link_libraries(ssl ${LINK_LIBRARIES}) 22 | 23 | add_executable(ssh ssh.cpp) 24 | target_link_libraries(ssh ${LINK_LIBRARIES}) 25 | 26 | add_executable(sip sip.cpp) 27 | target_link_libraries(sip ${LINK_LIBRARIES}) 28 | 29 | add_executable(target_set target_set.cpp) 30 | target_link_libraries(target_set ${LINK_LIBRARIES}) 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | nodescan 2 | ======== 3 | 4 | Nodescan is an asynchronous scanning library. It allows the building of custom 5 | asynchronous scanners, from the target specification to the level 7 processing. 6 | 7 | For now, it only supports one asynchronous engine with UNIX sockets. 8 | 9 | 10 | Installation 11 | ============ 12 | 13 | These libraries needs to be installed: 14 | 15 | * libleeloo: refer to https://github.com/quarkslab/libleeloo. It needs to be compiled with boost serialization support (see libleeloo's README for more informations) 16 | * boost-python 17 | * boost-random 18 | * boost-log 19 | 20 | Under debian based system, you can do: 21 | 22 | # apt-get install boost-{python,random,log}-dev 23 | 24 | 25 | To build it, follow these instructions: 26 | 27 | $ cd /path/to/source 28 | $ mkdir build 29 | $ cd build 30 | $ cmake -DCMAKE_BUILD_TYPE=release .. 31 | $ make 32 | $ sudo make install 33 | 34 | 35 | Usage 36 | ===== 37 | 38 | There are usage C++ examples in the "tests" directory. Python bindings examples 39 | can be found in bindings/python/examples. 40 | -------------------------------------------------------------------------------- /tests/ssh.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | int main() 14 | { 15 | leeloo::ip_list_intervals ips; 16 | ips.add("127.0.0.1"); 17 | ips.add("91.121.152.104"); 18 | ips.aggregate(); 19 | std::cout << "IPs count: " << ips.size() << std::endl; 20 | 21 | leeloo::port_list_intervals ports; 22 | ports.add(leeloo::tcp_port(22)); 23 | 24 | ns::IPV4TargetSet targets(ips, ports); 25 | ns::AsyncEngine engine(targets, 10000, 120); 26 | 27 | engine.set_lvl4_connected_callback( 28 | ns::protocols::SSH().on_certificate( 29 | [](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&, unsigned char* buf, uint32_t size) 30 | { 31 | std::cerr.write((const char*) buf, size); 32 | std::cerr.flush(); 33 | return false; 34 | } 35 | ) 36 | ); 37 | 38 | engine.launch(); 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /bindings/python/examples/test_end.py: -------------------------------------------------------------------------------- 1 | import pyleeloo 2 | import pynodescan 3 | import ipaddress 4 | 5 | ips = pyleeloo.ip_list_intervals() 6 | ips.add("127.0.0.1") 7 | 8 | ports = pyleeloo.port_list_intervals() 9 | ports.add(pyleeloo.port(1245, pyleeloo.protocol.TCP)) 10 | 11 | targets = pynodescan.IPV4TargetSet(ips, ports) 12 | engine = pynodescan.AsyncEngine(targets, 1, 600) 13 | 14 | def ip2str(ip): 15 | return str(ipaddress.ip_address(ip)) 16 | 17 | def p(t, l, h, buf): 18 | print("recv: " + buf.tobytes().decode('ascii')) 19 | return True 20 | 21 | def send_hello(target, lvl4sm, hsm): 22 | print("send hello to %s" % ip2str(target.ipv4())) 23 | s = "hello" 24 | target.send(s) 25 | lvl4sm.set_char_data_trigger('Z', p) 26 | return True 27 | 28 | def finish(target, buf, err): 29 | print("finish with errcode %d and buffer %s" % (err, buf.tobytes().decode('ascii'))) 30 | 31 | n = 0 32 | def watch_timeout(t): 33 | global n 34 | print("watch timeout for %s" % (ip2str(t.ipv4()))) 35 | n += 1 36 | return n < 4 37 | 38 | engine.set_watch_timeout(watch_timeout, 1) 39 | engine.set_lvl4_connected_callback(send_hello) 40 | engine.set_lvl4_finish_callback(finish) 41 | 42 | engine.launch() 43 | -------------------------------------------------------------------------------- /tests/buffer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | typedef ns::Buffer BufferU8; 6 | 7 | int main() 8 | { 9 | int ret = 0; 10 | #define CHECK(b)\ 11 | if (!(b)) {\ 12 | ret = 1;\ 13 | std::cerr << #b << " check failed" << std::endl;\ 14 | }\ 15 | 16 | BufferU8 b; 17 | CHECK(b.begin() == nullptr); 18 | unsigned char* buf = b.grow_by(10); 19 | CHECK(b.size() == 10); 20 | CHECK(b.allocated_size() >= 10); 21 | CHECK(buf == b.begin()); 22 | CHECK(buf+10 == b.end()); 23 | 24 | memset(buf, 'A', 10); 25 | 26 | BufferU8 bc(b); 27 | CHECK(bc.begin() != nullptr); 28 | CHECK(bc.begin() != b.begin()); 29 | CHECK(bc.size() == b.size()); 30 | CHECK(memcmp(b.begin(), bc.begin(), 10) == 0); 31 | 32 | buf = b.grow_by(10); 33 | CHECK(b.size() == 20); 34 | CHECK(b.allocated_size() >= 20); 35 | CHECK(bc.size() == 10); 36 | memset(buf, 'B', 10); 37 | CHECK(memcmp(b.begin(), "AAAAAAAAAABBBBBBBBBB", 20) == 0); 38 | 39 | BufferU8 bm(std::move(b)); 40 | CHECK(bm.begin() != b.begin()); 41 | CHECK(bm.size() == 20); 42 | CHECK(memcmp(bm.begin(), "AAAAAAAAAABBBBBBBBBB", 20) == 0); 43 | 44 | bm.pop_by(5); 45 | CHECK(bm.size() == 15); 46 | CHECK(memcmp(bm.begin(), "AAAAABBBBBBBBBB", 15) == 0); 47 | 48 | return ret; 49 | } 50 | -------------------------------------------------------------------------------- /bindings/python/examples/data_trigger.py: -------------------------------------------------------------------------------- 1 | import pyleeloo 2 | import pynodescan 3 | 4 | ips = pyleeloo.ip_list_intervals() 5 | ips.add("127.0.0.1") 6 | 7 | ports = pyleeloo.port_list_intervals() 8 | ports.add(pyleeloo.port(2000, pyleeloo.protocol.TCP)) 9 | 10 | targets = pynodescan.IPV4TargetSet(ips, ports) 11 | 12 | engine = pynodescan.AsyncEngine(targets) 13 | 14 | def trigger(target, lvl4sm, hsm, buf): 15 | print(buf.tobytes()) 16 | return False 17 | 18 | def print_true(s): 19 | print(s) 20 | return False 21 | 22 | class NewlineDataTrigger(): 23 | def __init__(self, func): 24 | self.__func = func 25 | 26 | def process_buffer(self, target, lvl4sm, hsm, buf, prev_pos): 27 | s = buf.data().tobytes().decode('ascii') 28 | ret = True 29 | if '\n' in s: 30 | lines = s.split('\n')[:-1] 31 | n = 0 32 | for l in lines: 33 | n += len(l)+1 34 | ret = self.__func(l) 35 | buf.pop_by(n) 36 | return ret 37 | 38 | def connected_callback(target, lvl4sm, hsm): 39 | target.send("hello") 40 | 41 | lvl4sm.set_data_trigger(NewlineDataTrigger(lambda s: print_true(s))) 42 | return True 43 | 44 | engine.set_lvl4_connected_callback(connected_callback) 45 | 46 | engine.launch() 47 | -------------------------------------------------------------------------------- /tests/server_recon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3.3 2 | # 3 | 4 | import socket, random 5 | 6 | 7 | TCP_IP = '127.0.0.1' 8 | TCP_PORT = 1245 9 | 10 | server_sock = None 11 | def main(): 12 | global server_sock 13 | server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 14 | server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 15 | server_sock.bind((TCP_IP, TCP_PORT)) 16 | server_sock.listen(1) 17 | 18 | l = ['a', 'b', 'c', 'd'] 19 | random.shuffle(l) 20 | random_str = ''.join(l) 21 | 22 | conn, addr = server_sock.accept() 23 | print 'Connection address:', addr 24 | data = conn.recv(5) 25 | str_ = data.decode('ascii') 26 | if str_ != "break": 27 | print("invalid proto") 28 | return 29 | conn.send(random_str.encode('ascii')) 30 | print("sent " + random_str) 31 | conn.close() 32 | 33 | conn, addr = server_sock.accept() 34 | print 'Connection address step2:', addr 35 | data = conn.recv(4) 36 | str_ = data.decode('ascii') 37 | if str_ != random_str: 38 | print("bad string returned: " + str_) 39 | return 40 | print("Received good str!") 41 | conn.close() 42 | 43 | try: 44 | main() 45 | except KeyboardInterrupt: 46 | pass 47 | 48 | if server_sock: 49 | server_sock.close() 50 | -------------------------------------------------------------------------------- /tests/sip.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | 14 | int main() 15 | { 16 | leeloo::ip_list_intervals ips; 17 | ips.add("91.121.152.104"); 18 | ips.aggregate(); 19 | std::cout << "IPs count: " << ips.size() << std::endl; 20 | 21 | leeloo::port_list_intervals ports; 22 | ports.add(leeloo::udp_port(5060)); 23 | 24 | ns::IPV4TargetSet targets(ips, ports); 25 | ns::AsyncEngine engine(targets, 10000, 120); 26 | 27 | engine.set_lvl4_connected_callback( 28 | ns::protocols::SIP() 29 | .on_header( 30 | [](ns::ConnectedTarget const&, ns::Lvl4SM&, ns::HostSM&, const char* key, const char* value) 31 | { 32 | std::cout << key << ": " << value << std::endl; 33 | return true; 34 | } 35 | ) 36 | .on_invalid_header( 37 | [](ns::ConnectedTarget const&, ns::Lvl4SM&, ns::HostSM&, unsigned char* buf, size_t n) 38 | { 39 | std::cout << "invalid header: " << std::endl; 40 | std::cout.write((const char*) buf, n); 41 | std::cout.flush(); 42 | return true; 43 | } 44 | ) 45 | ); 46 | 47 | engine.launch(); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Quarkslab 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the {organization} nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SRC_FILES 2 | async_engine.cpp 3 | data_triggers.cpp 4 | engine.cpp 5 | host_state_machine.cpp 6 | ipstr.cpp 7 | lvl4_state_machine.cpp 8 | state_machine.cpp 9 | target.cpp 10 | target_set.cpp 11 | target_file.cpp 12 | timestamp.cpp 13 | connected_target.cpp 14 | protocols/ssl.cpp 15 | protocols/ssh.cpp 16 | protocols/sip.cpp 17 | ) 18 | 19 | set(CONFIG_H ${CMAKE_CURRENT_BINARY_DIR}/include/ns/config.h) 20 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/ns/config.h.in ${CONFIG_H}) 21 | 22 | set(HEADER_DIST_FILES 23 | include/ns/action.h 24 | include/ns/async_engine.h 25 | include/ns/buffer.h 26 | include/ns/connected_target.h 27 | include/ns/data_trigger_base.h 28 | include/ns/data_triggers.h 29 | include/ns/data_trigger_variant.h 30 | include/ns/engine.h 31 | include/ns/host_state_machine.h 32 | include/ns/ipstr.h 33 | include/ns/lvl4_buffer.h 34 | include/ns/lvl4_properties_storage.h 35 | include/ns/lvl4_state_machine.h 36 | include/ns/state_machine.h 37 | include/ns/static_max_size.h 38 | include/ns/target_file.h 39 | include/ns/target.h 40 | include/ns/target_set.h 41 | include/ns/timestamp.h 42 | 43 | include/ns/protocols/sip.h 44 | include/ns/protocols/ssh.h 45 | include/ns/protocols/ssl.h 46 | include/ns/protocols/ssl_structs.h 47 | 48 | ${CONFIG_H} 49 | ) 50 | 51 | add_library(nodescan SHARED ${SRC_FILES}) 52 | target_link_libraries(nodescan leeloo ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} ${TBB_LIBRARIES}) 53 | 54 | install(TARGETS nodescan LIBRARY DESTINATION lib) 55 | install(FILES ${HEADER_DIST_FILES} DESTINATION include/ns) 56 | -------------------------------------------------------------------------------- /tests/size_trigger.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | int main() 11 | { 12 | leeloo::ip_list_intervals ips; 13 | ips.add("127.0.0.1"); 14 | 15 | leeloo::port_list_intervals ports; 16 | ports.add(2000, 2009, leeloo::port::protocol_enum::TCP); 17 | 18 | ns::IPV4TargetSet targets(ips, ports); 19 | ns::AsyncEngine engine(targets); 20 | engine.set_lvl4_connected_callback( 21 | [](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&) 22 | { 23 | std::cout << "send hello to port " << t.port_value() << std::endl; 24 | const char* req = "hello"; 25 | t.send((unsigned char*) req, strlen(req)); 26 | 27 | std::cout << "wait for hi on port " << t.port_value() << std::endl; 28 | lvl4sm.set_trigger(2, 29 | [](ns::ConnectedTarget const& t, ns::Lvl4SM&, ns::HostSM&, unsigned char* buf, uint32_t size) 30 | { 31 | std::cout << "received '"; 32 | std::cout.write(reinterpret_cast(buf), static_cast(size)); 33 | std::cout << "' on port " << t.port_value() << std::endl; 34 | return false; 35 | } 36 | ); 37 | 38 | return true; 39 | } 40 | ); 41 | engine.set_lvl4_finish_callback( 42 | [](ns::Target const& target, const unsigned char*, size_t, int err) 43 | { 44 | std::cout << "finish for port " << target.port_value() << ": " << strerror(err) << std::endl; 45 | }); 46 | engine.launch(); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /tests/recon.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | leeloo::ip_list_intervals ips; 14 | ips.add("127.0.0.1"); 15 | 16 | leeloo::port_list_intervals ports; 17 | ports.add(leeloo::tcp_port(1245)); 18 | 19 | typedef std::array random_str_type; 20 | ns::Lvl4PropertiesStorage props; 21 | 22 | ns::IPV4TargetSet targets(ips, ports); 23 | ns::AsyncEngine engine(targets); 24 | engine.set_lvl4_connected_callback( 25 | [&props](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&) 26 | { 27 | const char* payload = "break"; 28 | t.send((unsigned char*) payload, strlen(payload)); 29 | 30 | std::cout << "payload sent" << std::endl; 31 | 32 | lvl4sm.set_trigger(4, 33 | [&props](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&, unsigned char* buf, uint32_t) 34 | { 35 | memcpy(std::begin(props[t]), buf, 4); 36 | std::cout << "received '"; 37 | std::cout.write((const char*) buf, 4); 38 | std::cout << "'" << std::endl; 39 | lvl4sm.set_reconnect(true); 40 | lvl4sm.set_on_connect( 41 | [&props](ns::ConnectedTarget const& t, ns::Lvl4SM&, ns::HostSM&) 42 | { 43 | std::cout << "reconnected to server" << std::endl; 44 | t.send((unsigned char*) std::begin(props[t]), 4); 45 | return false; 46 | }); 47 | return true; 48 | }); 49 | return true; 50 | }); 51 | engine.launch(); 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /tests/target_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | 11 | int main(int argc, char** argv) 12 | { 13 | leeloo::ip_list_intervals ips; 14 | leeloo::port_list_intervals ports; 15 | 16 | ips.add("10/8"); 17 | ports.add(10, 200, leeloo::port::protocol_enum::TCP); 18 | 19 | ns::IPV4TargetSet set(ips, ports); 20 | 21 | set.init(); 22 | 23 | for (int i = 0; i < 100; i++) { 24 | ns::Target t = set.next_target(); 25 | if (i % 10 != 0) { 26 | ns::HostSM hsm; 27 | set.target_finished(t, hsm); 28 | } 29 | } 30 | 31 | std::stringstream ss; 32 | set.save_state(ss); 33 | 34 | std::cout << ss.str() << std::endl; 35 | ss.seekg(0, std::stringstream::beg); 36 | 37 | leeloo::ip_list_intervals new_ips; 38 | leeloo::port_list_intervals new_ports; 39 | ns::IPV4TargetSet deser(new_ips, new_ports); 40 | deser.restore_state(ss); 41 | 42 | std::stringstream ss2; 43 | deser.save_state(ss2); 44 | std::cout << ss2.str() << std::endl; 45 | 46 | /*if (ss != ss2) { 47 | std::cerr << "Deserialize - >serialize -> deserialize gave different results" << std::endl; 48 | return 1; 49 | }*/ 50 | 51 | for (int i = 0; i < 50; i++) { 52 | if (set.next_target() != deser.next_target()) { 53 | std::cerr << "Issue at " << i << std::endl; 54 | return 1; 55 | } 56 | } 57 | 58 | ips.clear(); 59 | ips.add("127.0.0.1"); 60 | ns::RepeatableTargetSet rsets(ips, ports); 61 | rsets.init(); 62 | ns::Target t; 63 | do { 64 | t = rsets.next_target(); 65 | std::cout << t.ipv4() << "/" << t.is_end() << std::endl; 66 | } 67 | while (!t.is_end()); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /src/timestamp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | 33 | 34 | time_t ns::timestamp() 35 | { 36 | return time(NULL); 37 | } 38 | -------------------------------------------------------------------------------- /src/include/ns/timestamp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef TIMESTAMP_H 32 | #define TIMESTAMP_H 33 | 34 | #include 35 | 36 | namespace ns { 37 | 38 | time_t timestamp(); 39 | 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/include/ns/ipstr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef IPSTR_H 32 | #define IPSTR_H 33 | 34 | #include 35 | 36 | namespace ns { 37 | 38 | const char* ipstr(uint32_t ip); 39 | 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/include/ns/lvl4_buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_LVL4_BUFFER_H 32 | #define NS_LVL4_BUFFER_H 33 | 34 | #include 35 | 36 | namespace ns { 37 | 38 | typedef Buffer Lvl4Buffer; 39 | 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /bindings/python/examples/certifs.py: -------------------------------------------------------------------------------- 1 | import ipaddress 2 | 3 | class ProtoRouter: 4 | def __init__(self, routes): 5 | self.__routes = routes 6 | self.__default_route = None 7 | 8 | @property 9 | def routes(self): return self.__routes 10 | 11 | def default_route(self, cb): 12 | self.__default_route = cb 13 | return self 14 | 15 | def __call__(self, target, lvl4sm, hsm): 16 | route = self.routes.get(target.port(), self.__default_route) 17 | if route == None: 18 | return False 19 | return route(target, lvl4sm, hsm) 20 | 21 | import pyleeloo 22 | import pynodescan 23 | 24 | ips = pyleeloo.ip_list_intervals() 25 | ips.add("103.2.184.0/22") 26 | ips.add("115.126.160.0/19") 27 | ips.add("103.2.184.0/23") 28 | ips.add("127.0.0.1") 29 | 30 | ports = pyleeloo.port_list_intervals() 31 | tcp_22 = pyleeloo.port(22, pyleeloo.protocol.TCP) 32 | tcp_443 = pyleeloo.port(443, pyleeloo.protocol.TCP) 33 | ports.add(tcp_22) 34 | ports.add(tcp_443) 35 | 36 | targets = pynodescan.IPV4TargetSet(ips, ports) 37 | 38 | def ip_target(t): 39 | return str(ipaddress.ip_address(t.ipv4())) 40 | 41 | def save_certif(name): 42 | def _cb(t, lvl4sm, hsm, buf): 43 | with open("%s_%s" % (name, ip_target(t)), "wb+") as f: 44 | f.write(buf.tobytes()) 45 | return False 46 | return _cb 47 | 48 | engine = pynodescan.AsyncEngine(targets, 40000, 60) 49 | engine.set_lvl4_connected_callback( 50 | ProtoRouter({tcp_22: pynodescan.protocols.SSH().on_certificate(save_certif("ssh")).on_invalid_answer(lambda t, lvl4sm, hsm, buf: print("SSH failed for %s" % ip_target(t))), 51 | tcp_443: pynodescan.protocols.SSL().on_certificate(save_certif("ssl"))}) 52 | ) 53 | 54 | try: 55 | engine.auto_save_state("scan_state.xml", 60) 56 | engine.launch() 57 | except KeyboardInterrupt: 58 | engine.save_state("scan_state.xml") 59 | -------------------------------------------------------------------------------- /src/state_machine.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | ns::StateMachine::StateMachine(): 35 | _valid(false), 36 | _ts(0), 37 | _watch_ts(timestamp()) 38 | { 39 | } 40 | 41 | void ns::StateMachine::update_ts() 42 | { 43 | _ts = timestamp(); 44 | } 45 | -------------------------------------------------------------------------------- /src/connected_target.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | int ns::ConnectedTarget::send(const char* str) const 36 | { 37 | return send((unsigned char*) str, strlen(str)); 38 | } 39 | 40 | int ns::ConnectedTarget::send(unsigned char* buf, size_t s) const 41 | { 42 | return write(_s, buf, s); 43 | } 44 | -------------------------------------------------------------------------------- /src/ipstr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | const char* ns::ipstr(uint32_t ip) 35 | { 36 | static char ipstr[18]; 37 | // Quick'n'dirty 38 | snprintf(ipstr, 18, "%d.%d.%d.%d", (ip >> 24), 39 | (ip >> 16) & 0xFF, 40 | (ip >> 8) & 0xFF, 41 | ip & 0xFF); 42 | return ipstr; 43 | } 44 | -------------------------------------------------------------------------------- /src/include/ns/state_machine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_STATE_MACHINE_H 32 | #define NS_STATE_MACHINE_H 33 | 34 | #include 35 | 36 | namespace ns { 37 | 38 | class StateMachine 39 | { 40 | public: 41 | StateMachine(); 42 | 43 | public: 44 | void update_ts(); 45 | time_t ts() const { return _ts; } 46 | 47 | void update_watch_ts(time_t const ts) { _watch_ts = ts; } 48 | time_t watch_ts() const { return _watch_ts; } 49 | 50 | inline void set_valid(bool v) { _valid = v; } 51 | inline bool valid() const { return _valid; } 52 | 53 | private: 54 | bool _valid; 55 | time_t _ts; 56 | time_t _watch_ts; 57 | }; 58 | 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/host_state_machine.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | ns::HostSM::HostSM() 43 | { } 44 | 45 | ns::HostSM::~HostSM() 46 | { 47 | } 48 | 49 | void ns::HostSM::on_alive() 50 | { 51 | _on_alive(*this); 52 | } 53 | 54 | void ns::HostSM::port_done(leeloo::port port) 55 | { 56 | _ports_done.add(port); 57 | if (const_cast(_ports_done).intervals().size() > 100) { 58 | // Attempt to save memory 59 | _ports_done.aggregate(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/include/ns/data_trigger_base.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_DATA_TRIGGER_BASE_H 32 | #define NS_DATA_TRIGGER_BASE_H 33 | 34 | #include 35 | #include 36 | 37 | namespace ns { 38 | 39 | class DataTrigger 40 | { 41 | public: 42 | enum ProcessReturnCode 43 | { 44 | NoMoreToProcess, 45 | CanProcessAgain, 46 | ConnectionEnd 47 | }; 48 | 49 | public: 50 | virtual ~DataTrigger() 51 | { } 52 | 53 | public: 54 | // Returns true to go on with this connection, or false to stop it! 55 | virtual ProcessReturnCode process_buffer(ConnectedTarget const&, Lvl4SM&, HostSM&, Lvl4Buffer&, uint32_t /*prev_pos*/) { return NoMoreToProcess; } 56 | }; 57 | 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/include/ns/static_max_size.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_STATIC_MAX_SIZE_H 32 | #define NS_STATIC_MAX_SIZE_H 33 | 34 | #include 35 | 36 | namespace ns { 37 | 38 | template 39 | struct static_max_size; 40 | 41 | template 42 | struct static_max_size 43 | { 44 | static constexpr size_t value = boost::static_unsigned_max::value>::value; 45 | }; 46 | 47 | template 48 | struct static_max_size 49 | { 50 | static constexpr size_t value = boost::static_unsigned_max::value; 51 | }; 52 | 53 | template 54 | struct static_max_size 55 | { 56 | static constexpr size_t value = sizeof(T0); 57 | }; 58 | 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/engine.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | 33 | 34 | ns::Engine::Engine(ns::TargetSet& targets): 35 | _targets(targets), 36 | _time_autosave(0) 37 | { 38 | } 39 | 40 | bool ns::Engine::target_finished(Target const& t, HostSM& hsm) 41 | { 42 | return _targets.target_finished(t, hsm); 43 | } 44 | 45 | void ns::Engine::auto_save_state(const char* file, uint32_t time_s) 46 | { 47 | if (file == NULL) { 48 | _time_autosave = 0; 49 | return; 50 | } 51 | 52 | _file_autosave = file; 53 | _time_autosave = time_s; 54 | _last_save = 0; 55 | } 56 | 57 | bool ns::Engine::should_save_state() 58 | { 59 | if (_time_autosave == 0 || _file_autosave.empty()) { 60 | return false; 61 | } 62 | 63 | const time_t now = time(NULL); 64 | if ((now-_last_save) >= _time_autosave) { 65 | _last_save = now; 66 | return true; 67 | } 68 | return false; 69 | } 70 | -------------------------------------------------------------------------------- /tests/data_trigger_variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | int g_last_trigger = -1; 11 | typedef std::function myfunc; 12 | 13 | bool destructor_called_1 = false; 14 | bool destructor_called_2 = false; 15 | 16 | struct FakeDataTrigger1: public ns::DataTrigger 17 | { 18 | public: 19 | FakeDataTrigger1(myfunc const& f): 20 | _f(f) 21 | { } 22 | 23 | ~FakeDataTrigger1() 24 | { 25 | destructor_called_1 = true; 26 | } 27 | public: 28 | ns::DataTrigger::ProcessReturnCode process_buffer(ns::ConnectedTarget const&, ns::Lvl4SM&, ns::HostSM&, ns::Lvl4Buffer&, uint32_t) override 29 | { 30 | g_last_trigger = 1; 31 | return ns::DataTrigger::NoMoreToProcess; 32 | } 33 | 34 | private: 35 | myfunc _f; 36 | }; 37 | 38 | struct FakeDataTrigger2: public ns::DataTrigger 39 | { 40 | public: 41 | FakeDataTrigger2(myfunc const& f): 42 | _f(f) 43 | { } 44 | 45 | ~FakeDataTrigger2() 46 | { 47 | destructor_called_2 = true; 48 | } 49 | public: 50 | ns::DataTrigger::ProcessReturnCode process_buffer(ns::ConnectedTarget const&, ns::Lvl4SM&, ns::HostSM&, ns::Lvl4Buffer&, uint32_t) override 51 | { 52 | g_last_trigger = 2; 53 | return ns::DataTrigger::NoMoreToProcess; 54 | } 55 | 56 | private: 57 | myfunc _f; 58 | }; 59 | 60 | int do_test() 61 | { 62 | ns::Lvl4Buffer buf; 63 | ns::Lvl4SM lvl4sm; 64 | ns::HostSM hsm; 65 | ns::Target target; 66 | ns::ConnectedTarget ctarget(-1, target); 67 | 68 | ns::DataTriggerVariant variant; 69 | variant.set([](int i) { std::cout << i << std::endl; }); 70 | variant.process_buffer(ctarget, lvl4sm, hsm, buf, 0); 71 | if (g_last_trigger != 1) { 72 | std::cout << "Wrong trigger called!" << std::endl; 73 | return 1; 74 | } 75 | variant.set([](int i) { std::cout << i << std::endl; }); 76 | variant.process_buffer(ctarget, lvl4sm, hsm, buf, 0); 77 | if (g_last_trigger != 2) { 78 | std::cout << "Wrong trigger called!" << std::endl; 79 | return 1; 80 | } 81 | return 0; 82 | } 83 | 84 | int main() 85 | { 86 | int ret = do_test(); 87 | if (!destructor_called_1) { 88 | std::cerr << "Destructor of FakeDataTrigger1 has never been called!" << std::endl; 89 | ret = 1; 90 | } 91 | if (!destructor_called_2) { 92 | std::cerr << "Destructor of FakeDataTrigger2 has never been called!" << std::endl; 93 | ret = 1; 94 | } 95 | return ret; 96 | } 97 | -------------------------------------------------------------------------------- /src/include/ns/connected_target.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_CONNECTED_TARGET_H 32 | #define NS_CONNECTED_TARGET_H 33 | 34 | #include 35 | #include 36 | 37 | namespace ns { 38 | 39 | class Target; 40 | 41 | class ConnectedTarget 42 | { 43 | public: 44 | ConnectedTarget(int s, Target const& t): 45 | _t(t), 46 | _s(s) 47 | { } 48 | 49 | public: 50 | int send(const char* buf) const; 51 | int send(unsigned char* buf, size_t s) const; 52 | 53 | inline uint32_t ipv4() const { return _t.ipv4(); } 54 | inline leeloo::port port() const { return _t.port(); } 55 | inline uint16_t port_value() const { return port().value(); } 56 | inline uint16_t port_protocol() const { return port().protocol(); } 57 | 58 | operator Target const&() const { return _t; } 59 | Target const& target() const { return _t; } 60 | 61 | private: 62 | Target const& _t; 63 | int _s; 64 | }; 65 | 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/include/ns/action.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_ACTION_H 32 | #define NS_ACTION_H 33 | 34 | #include 35 | #include 36 | 37 | namespace ns { 38 | 39 | class HostSM; 40 | class Lvl4SM; 41 | class ConnectedTarget; 42 | class Target; 43 | 44 | typedef std::function HostAction; 45 | typedef std::function Lvl4DataAction; 46 | typedef std::function Lvl4Action; 47 | 48 | typedef std::function Lvl4Finish; 49 | typedef std::function StatusDisplay; 50 | typedef std::function WatchTimeout; 51 | typedef std::function TimeoutTarget; 52 | 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/include/ns/host_state_machine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_HOST_PROPS_H 32 | #define NS_HOST_PROPS_H 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | namespace ns { 43 | 44 | // Host state machine 45 | class HostSM: public StateMachine 46 | { 47 | public: 48 | HostSM(); 49 | ~HostSM(); 50 | 51 | public: 52 | void on_alive(); 53 | void set_on_alive(HostAction const& ha) { _on_alive = ha; } 54 | 55 | public: 56 | void port_done(leeloo::port port); 57 | uint32_t ports_done_count() { return _ports_done.size(); } 58 | 59 | void set_rand_idx_ip(uint32_t idx) { _rand_idx_ip = idx; } 60 | uint32_t rand_idx_ip() const { return _rand_idx_ip; } 61 | 62 | private: 63 | HostAction _on_alive; 64 | leeloo::port_list_intervals _ports_done; 65 | 66 | uint32_t _rand_idx_ip; 67 | }; 68 | 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /tests/http.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | leeloo::ip_list_intervals ips; 14 | ips.add("127.0.0.1"); 15 | 16 | leeloo::port_list_intervals ports; 17 | ports.add(leeloo::tcp_port(80)); 18 | 19 | ns::IPV4TargetSet targets(ips, ports); 20 | ns::AsyncEngine engine(targets); 21 | 22 | ns::Lvl4PropertiesStorage props; 23 | 24 | engine.set_lvl4_connected_callback( 25 | [&props](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&) 26 | { 27 | const char* req = "GET / HTTP/1.0\n\n"; 28 | t.send((unsigned char*) req, strlen(req)); 29 | props[t] = 0; 30 | 31 | lvl4sm.set_trigger('\n', 32 | [&props](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&, unsigned char* buf, uint32_t size) 33 | { 34 | if (size == 0) { 35 | std::cout << "received empty line on port " << t.port_value() << std::endl; 36 | return true; 37 | } 38 | if (buf[size-1] == '\r') { 39 | size--; 40 | } 41 | std::cout << "received '"; 42 | std::cout.write(reinterpret_cast(buf), static_cast(size)); 43 | std::cout << "' on port " << t.port_value() << std::endl; 44 | 45 | if (size == 0) { 46 | uint32_t& content_length = props[t]; 47 | if (content_length == 0) { 48 | std::cerr << "No content-length provided!" << std::endl; 49 | return false; 50 | } 51 | lvl4sm.set_trigger(content_length, 52 | [](ns::ConnectedTarget const&, ns::Lvl4SM&, ns::HostSM&, unsigned char* buf, uint32_t size) 53 | { 54 | std::cout << "received content:" << std::endl; 55 | std::cout.write((const char*) buf, size); 56 | return false; 57 | }); 58 | return true; 59 | } 60 | char* dpts = (char*) memchr(buf, ':', size); 61 | if (dpts == nullptr) { 62 | if (size >= 4 && buf[0] == 'H' && buf[1] == 'T' && buf[2] == 'T' && buf[3] == 'P') { 63 | return true; 64 | } 65 | std::cout << "invalid header" << std::endl; 66 | return false; 67 | } 68 | *dpts = 0; 69 | if (strcasecmp((const char*) buf, "Content-length") == 0) { 70 | buf[size] = 0; 71 | props[t] = atoll(dpts+1); 72 | } 73 | return true; 74 | } 75 | ); 76 | 77 | return true; 78 | } 79 | ); 80 | engine.launch(); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /src/include/ns/protocols/ssh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_PROTOCOLS_SSH_H 32 | #define NS_PROTOCOLS_SSH_H 33 | 34 | #include 35 | 36 | namespace ns { 37 | 38 | class ConnectedTarget; 39 | class Lvl4SM; 40 | class HostSM; 41 | 42 | namespace protocols { 43 | 44 | class SSH 45 | { 46 | public: 47 | SSH& on_certificate(Lvl4DataAction const& a) { _cb_certif = a; return *this; } 48 | SSH& on_invalid_answer(Lvl4DataAction const& a) { _cb_invalid = a; return *this; } 49 | 50 | public: 51 | bool operator()(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&) const; 52 | 53 | private: 54 | template 55 | static bool call_cb(Action const& action, Args && ... args) 56 | { 57 | if (action) { 58 | return action(std::forward(args)...); 59 | } 60 | return def; 61 | } 62 | 63 | private: 64 | ns::Lvl4DataAction _cb_certif; 65 | ns::Lvl4DataAction _cb_invalid; 66 | }; 67 | 68 | } // protocols 69 | 70 | } // ns 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/target.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #include 37 | 38 | ns::Target ns::Target::end() 39 | { 40 | return Target(0xFFFFFFFF, leeloo::port(0xFFFF, leeloo::port::protocol_enum::UNSUPPORTED)); 41 | } 42 | 43 | ns::Target ns::Target::from_socket(int s) 44 | { 45 | struct sockaddr_in sa; 46 | socklen_t size = sizeof(sockaddr_in); 47 | getpeername(s, (sockaddr*) &sa, &size); 48 | 49 | int type; 50 | unsigned int length = sizeof(int); 51 | getsockopt(s, SOL_SOCKET, SO_TYPE, &type, &length); 52 | 53 | int proto; 54 | length = sizeof(int); 55 | getsockopt(s, SOL_SOCKET, SO_PROTOCOL, &proto, &length); 56 | 57 | return Target(ntohl(sa.sin_addr.s_addr), leeloo::port(ntohs(sa.sin_port), leeloo::port::protocol_from_socket_type(type, proto))); 58 | } 59 | 60 | sockaddr_in ns::Target::to_sockaddr_in() const 61 | { 62 | sockaddr_in addr; 63 | memset(&addr, 0, sizeof(sockaddr_in)); 64 | addr.sin_family = AF_INET; 65 | 66 | addr.sin_addr.s_addr = htonl(ipv4()); 67 | addr.sin_port = htons(port_value()); 68 | 69 | return addr; 70 | } 71 | -------------------------------------------------------------------------------- /src/include/ns/protocols/sip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_PROTOCOLS_SIP_H 32 | #define NS_PROTOCOLS_SIP_H 33 | 34 | #include 35 | #include 36 | 37 | namespace ns { 38 | 39 | class ConnectedTarget; 40 | class Lvl4SM; 41 | class HostSM; 42 | 43 | namespace protocols { 44 | 45 | class SIP 46 | { 47 | typedef std::function HeaderDataAction; 48 | 49 | public: 50 | SIP& on_header(HeaderDataAction const& cb) 51 | { 52 | _cb_header = cb; 53 | return *this; 54 | } 55 | 56 | SIP& on_invalid_header(ns::Lvl4DataAction const& cb) 57 | { 58 | _cb_invalid_header = cb; 59 | return *this; 60 | } 61 | 62 | public: 63 | bool operator()(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&) const; 64 | 65 | private: 66 | template 67 | static bool call_cb(Action const& action, Args && ... args) 68 | { 69 | if (action) { 70 | return action(std::forward(args)...); 71 | } 72 | return def; 73 | } 74 | 75 | private: 76 | HeaderDataAction _cb_header; 77 | ns::Lvl4DataAction _cb_invalid_header; 78 | }; 79 | 80 | } // protocols 81 | 82 | } // ns 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /bindings/python/examples/http.py: -------------------------------------------------------------------------------- 1 | import pyleeloo 2 | import pynodescan 3 | 4 | ips = pyleeloo.ip_list_intervals() 5 | ips.add("127.0.0.1") 6 | ips.add("173.194.34.14") 7 | 8 | ports = pyleeloo.port_list_intervals() 9 | ports.add(pyleeloo.port(80, pyleeloo.protocol.TCP)) 10 | 11 | targets = pynodescan.IPV4TargetSet(ips, ports) 12 | 13 | engine = pynodescan.AsyncEngine(targets, 100, 1) 14 | 15 | class Callable: 16 | def __init__(self, method): 17 | self.__method = method 18 | 19 | def __call__(self, *args, **kwargs): 20 | return self.__method(*args, **kwargs) 21 | 22 | class HTTPMethod: 23 | def __init__(self, method, url, headers): 24 | self.__method = method 25 | self.__url = url 26 | self.__headers = headers 27 | self._cb_headers = lambda t,k,v: True 28 | self._cb_content = lambda t,c: None 29 | self.__properties = pynodescan.Lvl4Properties(dict) 30 | 31 | def __call__(self, target, lvl4sm, hsm): 32 | s = "%s %s HTTP/1.0\n\n" % (self.__method, self.__url) 33 | target.send(s) 34 | self.__properties[target]['code'] = None 35 | self.__properties[target]['content-length'] = None 36 | 37 | lvl4sm.set_char_data_trigger('\n', Callable(self._on_newline)) 38 | return True 39 | 40 | def on_header(self, cb): 41 | self._cb_header = cb 42 | return self 43 | 44 | def on_content(self, cb): 45 | self._cb_content = cb 46 | return self 47 | 48 | def _on_newline(self, target, lvl4sm, hsm, buf): 49 | s = buf.tobytes().decode('ascii') 50 | if s.startswith("HTTP"): 51 | fields = s.split(' ') 52 | self.__properties[target]['code'] = int(fields[1]) 53 | return True 54 | 55 | print("after starts: " + s) 56 | header = s.split(':') 57 | if len(header) == 1: 58 | cl = self.__properties[target]['content-length'] 59 | if cl == None: 60 | return False 61 | lvl4sm.set_size_data_trigger(cl, Callable(self._on_content)) 62 | return True 63 | elif len(header) > 2: 64 | header = [header[0], ":".join(header[1:])] 65 | 66 | key, value = header 67 | if key == "Content-Length": 68 | self.__properties[target]['content-length'] = int(value) 69 | 70 | return self._cb_header(target, header[0], header[1]) 71 | 72 | def _on_content(self, target, lvl4sm, hsm, buf): 73 | self._cb_content(target, self.__properties[target]['code'], buf.tobytes()) 74 | self.__properties.remove(target) 75 | return False 76 | 77 | def print_header(t, k, v): 78 | print(t, k, v) 79 | return True 80 | 81 | engine.set_lvl4_connected_callback( 82 | HTTPMethod("GET", "/", {'User-agent': "My little poney 1.0"}) 83 | .on_header(print_header) 84 | .on_content(lambda target, code, content: print(code, content)) 85 | ) 86 | 87 | engine.launch() 88 | -------------------------------------------------------------------------------- /src/lvl4_state_machine.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | ns::Lvl4SM::Lvl4SM(): 38 | _reconnect(false), 39 | _reprocess(false) 40 | { 41 | } 42 | 43 | ns::Lvl4SM::~Lvl4SM() 44 | { 45 | } 46 | 47 | bool ns::Lvl4SM::process_lvl4_data(int s, uint32_t navail, Target const& target, HostSM& hsm) 48 | { 49 | _D(BOOST_LOG_NAMED_SCOPE("Lvl4SM::process_lvl4_data")); 50 | 51 | uint32_t prev_pos = _buf.size(); 52 | unsigned char* buf_read = _buf.grow_by(navail); 53 | int nread = read(s, buf_read, navail); 54 | if (nread <= 0) { 55 | // TODO: callback 56 | _D(BOOST_LOG_TRIVIAL(trace) << s << "invalid read size: " << strerror(errno) << std::endl); 57 | return false; 58 | } 59 | int ret; 60 | do { 61 | ret = _trigger.process_buffer(ConnectedTarget(s, target), *this, hsm, _buf, prev_pos); 62 | prev_pos = 0; 63 | } 64 | while (ret == DataTrigger::CanProcessAgain); 65 | return ret == DataTrigger::NoMoreToProcess; 66 | } 67 | 68 | bool ns::Lvl4SM::process_buffer(int s, Target const& target, HostSM& hsm) 69 | { 70 | int ret; 71 | do { 72 | ret = _trigger.process_buffer(ConnectedTarget(s, target), *this, hsm, _buf, 0); 73 | } 74 | while (ret == DataTrigger::CanProcessAgain); 75 | return ret == DataTrigger::NoMoreToProcess; 76 | } 77 | -------------------------------------------------------------------------------- /src/include/ns/data_trigger_variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_TRIGGER_VARIANT_H 32 | #define NS_TRIGGER_VARIANT_H 33 | 34 | #include 35 | #include 36 | 37 | namespace ns { 38 | 39 | class DataTrigger; 40 | 41 | // TODO: we can win space by using a simple integer to remember on which type 42 | // to cast (and do not use any virtual methods). 43 | // This requires some C++11 magic :) 44 | template 45 | class DataTriggerVariant 46 | { 47 | static constexpr size_t max_size = static_max_size::value; 48 | 49 | public: 50 | DataTriggerVariant() 51 | { 52 | new (storage()) DataTrigger(); 53 | } 54 | 55 | ~DataTriggerVariant() 56 | { 57 | storage()->~DataTrigger(); 58 | } 59 | 60 | public: 61 | template 62 | inline void set(Args && ... args) 63 | { 64 | storage()->~DataTrigger(); 65 | new (storage()) T(std::forward(args)...); 66 | } 67 | 68 | template 69 | inline int process_buffer(Args && ... args) 70 | { 71 | return storage()->process_buffer(std::forward(args)...); 72 | } 73 | 74 | inline DataTrigger const* trigger() const { return reinterpret_cast(&_storage[0]); } 75 | 76 | private: 77 | inline DataTrigger* storage() { return reinterpret_cast(&_storage[0]); } 78 | 79 | private: 80 | uint8_t _storage[max_size]; 81 | }; 82 | 83 | } 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/include/ns/target.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_TARGET_H 32 | #define NS_TARGET_H 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | namespace ns { 39 | 40 | class Target 41 | { 42 | public: 43 | Target() { } 44 | 45 | Target(uint32_t ipv4, leeloo::port port_): 46 | _ipv4(ipv4), 47 | _port(port_) 48 | { } 49 | 50 | public: 51 | inline uint32_t ipv4() const { return _ipv4; } 52 | inline leeloo::port port() const { return _port; } 53 | inline uint16_t port_value() const { return port().value(); } 54 | inline uint16_t port_protocol() const { return port().protocol(); } 55 | 56 | inline bool is_end() const { return _ipv4 == 0xFFFFFFFF && port_value() == 0xFFFF; } 57 | 58 | static Target from_socket(int s); 59 | sockaddr_in to_sockaddr_in() const; 60 | 61 | public: 62 | // Make this usable in an std::map 63 | inline bool operator<(Target const& o) const 64 | { 65 | if (ipv4() == o.ipv4()) { 66 | return port().as_u32() < o.port().as_u32(); 67 | } 68 | return ipv4() < o.ipv4(); 69 | } 70 | 71 | inline bool operator==(Target const& o) const 72 | { 73 | return ipv4() == o.ipv4() and port() == o.port(); 74 | } 75 | 76 | inline bool operator!=(Target const& o) const 77 | { 78 | return ipv4() != o.ipv4() or port() != o.port(); 79 | } 80 | 81 | public: 82 | static Target end(); 83 | 84 | private: 85 | uint32_t _ipv4; 86 | leeloo::port _port; 87 | }; 88 | 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/include/ns/lvl4_properties_storage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef LVL4_PROPERTIES_STORAGE_H 32 | #define LVL4_PROPERTIES_STORAGE_H 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | 39 | namespace ns { 40 | 41 | template 42 | class Lvl4PropertiesStorage 43 | { 44 | typedef Properties properties_type; 45 | typedef std::map storage_type; 46 | 47 | public: 48 | typedef std::function func_new_property; 49 | 50 | public: 51 | Lvl4PropertiesStorage(): 52 | _new([] { return properties_type(); }) 53 | { } 54 | 55 | Lvl4PropertiesStorage(func_new_property const& f): 56 | _new(f) 57 | { } 58 | 59 | 60 | public: 61 | properties_type& properties_of(Target const& target) 62 | { 63 | typename storage_type::iterator it = _storage.find(target); 64 | if (it != _storage.end()) { 65 | return it->second; 66 | } 67 | return _storage.insert(std::make_pair(target, std::move(_new()))).first->second; 68 | } 69 | 70 | properties_type& operator[](Target const& target) { return properties_of(target); } 71 | 72 | void remove(Target const& target) 73 | { 74 | typename storage_type::iterator it = _storage.find(target); 75 | if (it != _storage.end()) { 76 | _storage.erase(it); 77 | } 78 | } 79 | 80 | void clear() 81 | { 82 | _storage->~storage_type(); 83 | new (&_storage) storage_type(); 84 | } 85 | 86 | private: 87 | storage_type _storage; 88 | func_new_property _new; 89 | }; 90 | 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /src/include/ns/data_triggers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_DATA_TRIGGERS_H 32 | #define NS_DATA_TRIGGERS_H 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | 39 | namespace ns { 40 | 41 | class SizeDataTrigger: public DataTrigger 42 | { 43 | public: 44 | SizeDataTrigger(uint32_t size, Lvl4DataAction const& f): 45 | _f(f), 46 | _size(size) 47 | { } 48 | 49 | public: 50 | virtual ProcessReturnCode process_buffer(ConnectedTarget const& target, Lvl4SM&, HostSM&, Lvl4Buffer&, uint32_t prev_pos) override; 51 | 52 | private: 53 | Lvl4DataAction _f; 54 | uint32_t _size; 55 | }; 56 | 57 | class CharDataTrigger: public DataTrigger 58 | { 59 | public: 60 | CharDataTrigger(unsigned char c, Lvl4DataAction const& f): 61 | _f(f), 62 | _c(c) 63 | { } 64 | 65 | public: 66 | virtual ProcessReturnCode process_buffer(ConnectedTarget const& target, Lvl4SM&, HostSM&, Lvl4Buffer&, uint32_t prev_pos) override; 67 | 68 | private: 69 | Lvl4DataAction _f; 70 | unsigned char _c; 71 | }; 72 | 73 | class PythonDataTrigger: public DataTrigger 74 | { 75 | public: 76 | PythonDataTrigger(boost::python::object const& obj): 77 | _trigger(obj) 78 | { } 79 | 80 | public: 81 | virtual ProcessReturnCode process_buffer(ConnectedTarget const&, Lvl4SM&, HostSM&, Lvl4Buffer&, uint32_t prev_pos) override; 82 | 83 | private: 84 | boost::python::object _trigger; 85 | }; 86 | 87 | typedef DataTriggerVariant DataTriggersVariant; 88 | 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/data_triggers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | 38 | #include 39 | 40 | ns::DataTrigger::ProcessReturnCode ns::SizeDataTrigger::process_buffer(ConnectedTarget const& target, Lvl4SM& lvl4sm, HostSM& hsm, Lvl4Buffer& buf, uint32_t) 41 | { 42 | if (buf.size() < _size) { 43 | return NoMoreToProcess; 44 | } 45 | assert(_f); 46 | const size_t size = _size; 47 | const bool ret = _f(target, lvl4sm, hsm, buf.begin(), size); 48 | if (!ret) { 49 | return ConnectionEnd; 50 | } 51 | buf.pop_by(size); 52 | return CanProcessAgain; 53 | } 54 | 55 | ns::DataTrigger::ProcessReturnCode ns::CharDataTrigger::process_buffer(ConnectedTarget const& target, Lvl4SM& lvl4sm, HostSM& hsm, Lvl4Buffer& buf, uint32_t prev_pos) 56 | { 57 | unsigned char* pc = std::find(buf.begin()+prev_pos, buf.end(), _c); 58 | if (pc == buf.end()) { 59 | return NoMoreToProcess; 60 | } 61 | const uintptr_t pos = ((uintptr_t)pc - (uintptr_t)buf.begin()); 62 | const bool ret = _f(target, lvl4sm, hsm, buf.begin(), pos); 63 | if (!ret) { 64 | return ConnectionEnd; 65 | } 66 | buf.pop_by(pos+1); 67 | return CanProcessAgain; 68 | } 69 | 70 | ns::DataTrigger::ProcessReturnCode ns::PythonDataTrigger::process_buffer(ConnectedTarget const& target, Lvl4SM& lvl4sm, HostSM& hsm, Lvl4Buffer& buf, uint32_t prev_pos) 71 | { 72 | return boost::python::extract(_trigger.attr("process_buffer")(target, boost::ref(lvl4sm), boost::ref(hsm), boost::ref(buf), prev_pos)); 73 | } 74 | -------------------------------------------------------------------------------- /src/include/ns/engine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_ENGINE_H 32 | #define NS_ENGINE_H 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | 43 | #include 44 | #include 45 | #include 46 | 47 | namespace ns { 48 | 49 | class Engine 50 | { 51 | public: 52 | Engine(TargetSet& targets); 53 | 54 | public: 55 | // Engine interface 56 | virtual void launch() = 0; 57 | virtual void launch_shrd(uint32_t idx, uint32_t total) = 0; 58 | 59 | void auto_save_state(const char* file, uint32_t time_s); 60 | 61 | void save_state(const char* file) { _targets.save_state(file); } 62 | void restore_state(const char* file) { _targets.restore_state(file); } 63 | 64 | protected: 65 | inline void init_scan() { _targets.init(); } 66 | inline void init_shrd_scan(uint32_t shrd_idx, uint32_t shrd_count) { _targets.init_shrd(shrd_idx, shrd_count); } 67 | 68 | //inline void save_state(std::ostream& os) { _targets.save_state(os); } 69 | //inline void restore_state(std::istream& is) { _targets.restore_state(is); } 70 | 71 | inline Target next_target() { return _targets.next_target(); } 72 | bool target_finished(Target const& t, HostSM& hsm); 73 | inline void init_host_sm(Target const& t, HostSM& hsm) { _targets.init_host_sm(t, hsm); } 74 | 75 | bool should_save_state(); 76 | 77 | const char* file_autosave() const { return _file_autosave.c_str(); } 78 | 79 | private: 80 | TargetSet& _targets; 81 | std::string _file_autosave; 82 | time_t _last_save; 83 | time_t _time_autosave; // in seconds 84 | }; 85 | 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /src/include/ns/protocols/ssl_structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_PROTOCOLS_SSL_STRUCTS_H 32 | #define NS_PROTOCOLS_SSL_STRUCTS_H 33 | 34 | #include 35 | 36 | namespace ns { 37 | namespace protocols { 38 | namespace __impl { 39 | 40 | #pragma pack(push) 41 | #pragma pack(1) 42 | struct ProtocolVersion 43 | { 44 | uint8_t major; 45 | uint8_t minor; 46 | }; 47 | 48 | struct Random 49 | { 50 | uint32_t gmt_unix_time; 51 | uint8_t random_bytes[28]; 52 | }; 53 | 54 | struct SessionID 55 | { 56 | uint8_t length; 57 | }; 58 | 59 | struct CipherSuite 60 | { 61 | uint16_t length; 62 | uint16_t data[10]; 63 | }; 64 | 65 | struct CompressionMethod 66 | { 67 | uint8_t length; 68 | uint8_t data; 69 | }; 70 | 71 | struct ClientHello 72 | { 73 | ProtocolVersion client_version; 74 | Random random; 75 | SessionID session_id; 76 | CipherSuite cipher_suites; 77 | CompressionMethod compression_methods; 78 | uint16_t ext_length; 79 | }; 80 | 81 | struct TLS 82 | { 83 | uint8_t msg_type; 84 | ProtocolVersion client_version; 85 | uint16_t length; 86 | }; 87 | 88 | struct Handshake 89 | { 90 | uint32_t msg_type: 8; 91 | uint32_t length2: 8; 92 | uint32_t length1: 8; 93 | uint32_t length0: 8; 94 | 95 | uint32_t get_length() const { return (length2 << 16) | (length1 << 8) | (length0); } 96 | }; 97 | 98 | struct Certificate 99 | { 100 | uint32_t length2: 8; 101 | uint32_t length1: 8; 102 | uint32_t length0: 8; 103 | 104 | uint32_t get_length() const { return (length2 << 16) | (length1 << 8) | (length0); } 105 | }; 106 | 107 | } // __impl 108 | } // protocols 109 | } // ns 110 | 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /src/protocols/sip.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | namespace nsp = ns::protocols; 35 | 36 | static const char* get_options = R"str(OPTIONS sip:sip@127.0.0.1 SIP/2.0 37 | Via: SIP/2.0/UDP 127.0.0.1;branch=z9hG4bKhjhs8ass877 38 | Max-Forwards: 70 39 | To: 40 | From: Alice ;tag=1928301774 41 | Call-ID: a84b4c76e66710 42 | CSeq: 63104 OPTIONS 43 | Contact: 44 | Accept: application/sdp 45 | Content-Length: 0 46 | 47 | 48 | )str"; 49 | 50 | static const char* sip_20 = "SIP/2.0"; 51 | 52 | bool nsp::SIP::operator()(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&) const 53 | { 54 | t.send(get_options); 55 | ns::Lvl4DataAction cb_invalid_header = _cb_invalid_header; 56 | HeaderDataAction cb_header = _cb_header; 57 | lvl4sm.set_trigger('\n', 58 | [cb_invalid_header,cb_header](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) 59 | { 60 | if (size < 1) { 61 | return call_cb(cb_invalid_header, t, lvl4sm, hsm, buf, size); 62 | } 63 | if (buf[size-1] != '\r') { 64 | return call_cb(cb_invalid_header, t, lvl4sm, hsm, buf, size); 65 | } 66 | buf[size-1] = 0; 67 | if (size == 1) { 68 | return false; 69 | } 70 | char* dot = (char*) memchr(buf, ':', size); 71 | if (dot == nullptr) { 72 | if ((size > strlen(sip_20)) && (memcmp(buf, sip_20, strlen(sip_20)) == 0)) { 73 | return true; 74 | } 75 | return call_cb(cb_invalid_header, t, lvl4sm, hsm, buf, size); 76 | } 77 | *dot = 0; 78 | char* value = dot+1; 79 | if (*value != 0 && (*(value+1) == ' ')) { 80 | value++; 81 | } 82 | return call_cb(cb_header, t, lvl4sm, hsm, (const char*) buf, value); 83 | } 84 | ); 85 | return true; 86 | } 87 | -------------------------------------------------------------------------------- /src/include/ns/protocols/ssl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_PROTOCOLS_SSL_H 32 | #define NS_PROTOCOLS_SSL_H 33 | 34 | #include 35 | #include 36 | 37 | namespace ns { 38 | 39 | namespace protocols { 40 | 41 | class SSL 42 | { 43 | public: 44 | typedef std::function CipherDataAction; 45 | public: 46 | SSL(); 47 | 48 | public: 49 | SSL& on_protocol_failure(Lvl4DataAction const& f) 50 | { 51 | _on_failure = f; 52 | return *this; 53 | } 54 | 55 | SSL& on_cipher(CipherDataAction const& f) 56 | { 57 | _on_cipher = f; 58 | return *this; 59 | } 60 | 61 | SSL& on_certificate(ns::Lvl4DataAction const& f) 62 | { 63 | _on_certif = f; 64 | return *this; 65 | } 66 | 67 | public: 68 | bool operator()(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&) const; 69 | 70 | private: 71 | bool on_tls_header(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&, unsigned char* buf, uint32_t size, ns::Lvl4DataAction const& on_hs) const; 72 | 73 | bool on_handshake1(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&, unsigned char* buf, uint32_t size) const; 74 | 75 | bool on_handshake2(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) const; 76 | 77 | private: 78 | template 79 | static bool call_cb(Action const& action, Args && ... args) 80 | { 81 | if (action) { 82 | return action(std::forward(args)...); 83 | } 84 | return def; 85 | } 86 | 87 | private: 88 | uint8_t client_hello[sizeof(__impl::TLS)+sizeof(__impl::Handshake)+sizeof(__impl::ClientHello)]; 89 | ns::Lvl4DataAction _on_certif; 90 | CipherDataAction _on_cipher; 91 | ns::Lvl4DataAction _on_failure; 92 | }; 93 | 94 | } // protocols 95 | 96 | } // leeloo 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/include/ns/target_file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_TARGET_FILE_H 32 | #define NS_TARGET_FILE_H 33 | 34 | #include 35 | 36 | #include 37 | 38 | namespace ns { 39 | 40 | class Engine; 41 | class HostSM; 42 | 43 | #if 0 44 | class TargetFile: public TargetSet 45 | { 46 | friend class Engine; 47 | 48 | public: 49 | TargetFile(const char* file); 50 | TargetFile(std::istream& is); 51 | 52 | public: 53 | void init() override; 54 | void init_shrd(uint32_t shrd_idx, uint32_t shrd_count); 55 | 56 | void save_state(std::ostream& os) override; 57 | void restore_state(std::istream& is) override; 58 | 59 | Target next_target() override; 60 | bool target_finished(Target const& target, HostSM& hsm); 61 | 62 | void init_host_sm(Target const& target, HostSM& hsm); 63 | 64 | private: 65 | void open_file(const char* file); 66 | std::istream& stream() { return *_stream; } 67 | 68 | private: 69 | boost::shared_ptr _storage; 70 | std::istream* _stream; 71 | size_t _cur_line; 72 | }; 73 | #endif 74 | 75 | class TargetAsyncFile: public TargetSet 76 | { 77 | public: 78 | TargetAsyncFile(int fd, leeloo::port const& def_port); 79 | 80 | public: 81 | virtual void init() override; 82 | virtual void init_shrd(uint32_t shrd_idx, uint32_t shrd_count) override; 83 | 84 | virtual void save_state(const char*) override { }; 85 | virtual void restore_state(const char*) override { }; 86 | 87 | virtual void save_state(std::ostream&) override { }; 88 | virtual void restore_state(std::istream&) override { }; 89 | 90 | virtual Target next_target() override; 91 | 92 | virtual bool target_finished(Target const&, HostSM&) override 93 | { 94 | return true; 95 | } 96 | 97 | private: 98 | inline int fd() const { return _fd; } 99 | Target next_target_in_buf(); 100 | 101 | private: 102 | Lvl4Buffer _buf; 103 | int _fd; 104 | leeloo::port _def_port; 105 | }; 106 | 107 | class TargetStdin: public TargetAsyncFile 108 | { 109 | public: 110 | TargetStdin(leeloo::port const& def_port); 111 | }; 112 | 113 | } 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /src/include/ns/lvl4_state_machine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_LVL4_STATE_MACHINE 32 | #define NS_LVL4_STATE_MACHINE 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | namespace ns { 45 | 46 | class Lvl4SM: public StateMachine 47 | { 48 | public: 49 | Lvl4SM(); 50 | ~Lvl4SM(); 51 | 52 | public: 53 | bool process_lvl4_data(int s, uint32_t navail, Target const& target, HostSM& hsm); 54 | bool process_buffer(int s, Target const& target, HostSM& hsm); 55 | 56 | void set_reconnect(bool v) { _reconnect = v; } 57 | bool reconnect() const { return _reconnect; } 58 | 59 | Lvl4Action const& get_on_connect() const { return _func_connect; } 60 | void set_on_connect(Lvl4Action const f) { _func_connect = f; } 61 | 62 | inline bool on_connect(int s, Target const& target, HostSM& hsm) 63 | { 64 | if (!_func_connect) { 65 | std::cerr << "Warning: no on_connect func for " << target.ipv4() << std::endl; 66 | return false; 67 | } 68 | return _func_connect(ConnectedTarget(s, target), *this, hsm); 69 | } 70 | 71 | inline void free_buffer() { _buf.free(); } 72 | 73 | template 74 | void set_trigger(Args && ... args) 75 | { 76 | _trigger.set(std::forward(args)...); 77 | _reprocess = true; 78 | } 79 | 80 | DataTrigger const* data_trigger() const { return _trigger.trigger(); } 81 | 82 | bool should_process_buffer() 83 | { 84 | if (_reprocess) { 85 | _reprocess = false; 86 | return true; 87 | } 88 | return false; 89 | } 90 | 91 | Lvl4Buffer const& buffer() const { return _buf; } 92 | 93 | void remove_data_trigger() 94 | { 95 | set_trigger(); 96 | _reprocess = false; 97 | } 98 | 99 | private: 100 | bool _reconnect; 101 | bool _reprocess; 102 | 103 | Lvl4Action _func_connect; 104 | DataTriggersVariant _trigger; 105 | 106 | Lvl4Buffer _buf; 107 | }; 108 | 109 | } 110 | 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /tests/ssl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | int main() 14 | { 15 | leeloo::ip_list_intervals ips; 16 | ips.add("27.122.0.0/22"); 17 | ips.add("61.5.208.0/24"); 18 | ips.add("61.5.209.32/27"); 19 | ips.add("61.5.209.64/26"); 20 | ips.add("61.5.209.128/25"); 21 | ips.add("61.5.210.0/30"); 22 | ips.add("61.5.210.8/30"); 23 | ips.add("61.5.210.160/27"); 24 | ips.add("61.5.211.0/24"); 25 | ips.add("61.5.212.0/26"); 26 | ips.add("61.5.221.0/25"); 27 | ips.add("61.5.223.0/24"); 28 | ips.add("101.101.0.0/18"); 29 | ips.add("103.2.184.0/23"); 30 | ips.add("103.2.187.0/24"); 31 | ips.add("103.17.44.0/22"); 32 | ips.add("103.23.52.0/22"); 33 | ips.add("103.29.152.0/22"); 34 | ips.add("113.20.32.0/19"); 35 | ips.add("113.21.96.0/20"); 36 | ips.add("114.69.176.0/20"); 37 | ips.add("114.69.192.0/22"); 38 | ips.add("114.69.200.0/22"); 39 | ips.add("114.69.204.0/23"); 40 | ips.add("114.69.206.0/24"); 41 | ips.add("114.69.208.0/21"); 42 | ips.add("114.69.216.0/22"); 43 | ips.add("115.126.160.0/19"); 44 | ips.add("118.179.224.0/19"); 45 | ips.add("175.158.128.0/18"); 46 | ips.add("180.214.96.0/19"); 47 | ips.add("193.51.249.0/24"); 48 | ips.add("194.214.55.0/24"); 49 | ips.add("194.254.189.0/24"); 50 | ips.add("195.221.84.0/24"); 51 | ips.add("202.0.157.0/24"); 52 | ips.add("202.22.128.0/19"); 53 | ips.add("202.22.224.0/20"); 54 | ips.add("202.87.128.0/30"); 55 | ips.add("202.87.128.20/30"); 56 | ips.add("202.87.128.24/30"); 57 | ips.add("202.87.128.44/30"); 58 | ips.add("202.87.128.60/30"); 59 | ips.add("202.87.128.68/30"); 60 | ips.add("202.87.128.108/30"); 61 | ips.add("202.87.128.112/30"); 62 | ips.add("202.87.128.128/30"); 63 | ips.add("202.87.128.136/29"); 64 | ips.add("202.87.128.144/29"); 65 | ips.add("202.87.128.160/30"); 66 | ips.add("202.87.128.172/30"); 67 | ips.add("202.87.128.200/30"); 68 | ips.add("202.87.128.208/29"); 69 | ips.add("202.87.129.0/24"); 70 | ips.add("202.87.130.0/27"); 71 | ips.add("202.87.131.80/30"); 72 | ips.add("202.87.131.196/30"); 73 | ips.add("202.87.131.224/28"); 74 | ips.add("202.87.132.0/25"); 75 | ips.add("202.87.132.184/29"); 76 | ips.add("202.87.133.16/28"); 77 | ips.add("202.87.133.48/28"); 78 | ips.add("202.87.134.0/26"); 79 | ips.add("202.87.134.120/29"); 80 | ips.add("202.87.134.128/26"); 81 | ips.add("202.87.134.248/29"); 82 | ips.add("202.87.138.0/24"); 83 | ips.add("202.87.139.28/30"); 84 | ips.add("202.87.139.36/30"); 85 | ips.add("202.87.139.40/30"); 86 | ips.add("202.87.139.148/30"); 87 | ips.add("202.87.139.160/30"); 88 | ips.add("202.87.140.0/22"); 89 | ips.add("202.87.144.0/22"); 90 | ips.add("202.87.148.0/24"); 91 | ips.add("202.87.150.120/29"); 92 | ips.add("202.87.150.248/30"); 93 | ips.add("202.87.156.0/24"); 94 | ips.add("202.166.176.0/21"); 95 | ips.add("202.171.64.0/20"); 96 | ips.add("203.80.48.0/21"); 97 | ips.add("203.147.64.0/20"); 98 | ips.add("203.147.80.0/21"); 99 | ips.add("220.156.160.0/20"); 100 | ips.add("223.29.128.0/19"); 101 | ips.add("223.29.160.0/21"); 102 | ips.add("223.29.168.0/22"); 103 | ips.add("223.29.172.0/23"); 104 | ips.aggregate(); 105 | std::cout << "IPs count: " << ips.size() << std::endl; 106 | 107 | leeloo::port_list_intervals ports; 108 | ports.add(leeloo::tcp_port(443)); 109 | 110 | ns::IPV4TargetSet targets(ips, ports); 111 | ns::AsyncEngine engine(targets, 100, 10); 112 | 113 | engine.set_lvl4_connected_callback( 114 | ns::protocols::SSL().on_certificate([](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&, unsigned char* buf, uint32_t size) 115 | { 116 | std::stringstream path; 117 | path << "cert_" << t.ipv4() << "_" << t.port().value(); 118 | FILE* f = fopen(path.str().c_str(), "w+"); 119 | fwrite(buf, 1, size, f); 120 | fclose(f); 121 | // This crashes for an obscure reason in -03... 122 | // std::ofstream of(path.str(), std::ofstream::out | std::ofstream::trunc); 123 | // of.write((const char*) buf, size); 124 | // of.close(); 125 | return true; 126 | }) 127 | ); 128 | 129 | engine.launch(); 130 | 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /src/target_file.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | #if 0 41 | ns::TargetFile::TargetFile(const char* file) 42 | { 43 | open_file(file); 44 | } 45 | 46 | void ns::TargetFile::open_file(const char* file) 47 | { 48 | _storage.reset(new std::ifstream(file, std::ifstream::in)); 49 | _stream = _storage.get(); 50 | _cur_line = 0; 51 | } 52 | 53 | ns::TargetFile::TargetFile(std::istream& is): 54 | _stream(&is), 55 | _cur_line(0) 56 | { 57 | } 58 | 59 | void ns::TargetFile::init() 60 | { 61 | _cur_line = 0; 62 | } 63 | 64 | void ns::TargetFile::init_shrd(uint32_t /*shrd_idx*/, uint32_t /*shrd_count*/) 65 | { 66 | } 67 | 68 | void ns::TargetFile::save_state(std::ostream& os) 69 | { 70 | os << _cur_line; 71 | } 72 | 73 | void ns::TargetFile::restore_state(std::istream& is) 74 | { 75 | is >> _cur_line; 76 | } 77 | #endif 78 | 79 | // Async file 80 | // 81 | 82 | ns::TargetAsyncFile::TargetAsyncFile(int fd, leeloo::port const& port): 83 | _fd(fd), 84 | _def_port(port) 85 | { 86 | } 87 | 88 | void ns::TargetAsyncFile::init() 89 | { 90 | fcntl(fd(), F_SETFL, fcntl(fd(), F_GETFL) | O_NONBLOCK); 91 | } 92 | 93 | void ns::TargetAsyncFile::init_shrd(uint32_t, uint32_t) 94 | { 95 | } 96 | 97 | ns::Target ns::TargetAsyncFile::next_target() 98 | { 99 | if (_buf.size() > 0) { 100 | Target ret = next_target_in_buf(); 101 | if (ret != Target::end()) { 102 | return ret; 103 | } 104 | } 105 | 106 | fd_set rfds; 107 | FD_ZERO(&rfds); 108 | FD_SET(STDIN_FILENO, &rfds); 109 | 110 | struct timeval tv; 111 | memset(&tv, 0, sizeof(struct timeval)); 112 | int sel_ret = select(STDIN_FILENO+1, &rfds, nullptr, nullptr, &tv); 113 | if (sel_ret == -1) { 114 | return Target::end(); 115 | } 116 | if (sel_ret == 0) { 117 | throw NextTargetWouldBlock(); 118 | } 119 | 120 | int navail; 121 | if (ioctl(fd(), FIONREAD, &navail) == -1) { 122 | return Target::end(); 123 | } 124 | std::cout << "navail: " << navail << std::endl; 125 | if (navail == 0) { 126 | return Target::end(); 127 | } 128 | 129 | unsigned char* buf_read = _buf.grow_by(navail); 130 | int nread = read(fd(), buf_read, navail); 131 | if (nread <= 0) { 132 | return Target::end(); 133 | } 134 | 135 | Target ret = next_target_in_buf(); 136 | if (ret == Target::end()) { 137 | throw NextTargetWouldBlock(); 138 | } 139 | return ret; 140 | } 141 | 142 | ns::Target ns::TargetAsyncFile::next_target_in_buf() 143 | { 144 | const unsigned char* newline = (const unsigned char*) memchr(_buf.begin(), '\n', _buf.size()); 145 | if (!newline) { 146 | return Target::end(); 147 | } 148 | 149 | const size_t size = (uintptr_t)(newline) - (uintptr_t)(_buf.begin()); 150 | bool valid = false; 151 | uint32_t ipv4 = leeloo::ips_parser::ipv4toi((const char*) _buf.begin(), size, valid); 152 | _buf.pop_by(size+1); 153 | if (!valid) { 154 | return Target::end(); 155 | } 156 | return Target(ipv4, _def_port); 157 | 158 | } 159 | 160 | ns::TargetStdin::TargetStdin(leeloo::port const& def_port): 161 | TargetAsyncFile(STDIN_FILENO, def_port) 162 | { 163 | } 164 | -------------------------------------------------------------------------------- /src/target_set.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #include 42 | 43 | boost::random::mt19937 g_mt_rand_ips; 44 | boost::random::mt19937 g_mt_rand_ports; 45 | 46 | void ns::TargetSet::save_state(const char* file) 47 | { 48 | std::ofstream os(file, std::ofstream::out | std::ofstream::trunc); 49 | save_state(os); 50 | os.close(); 51 | } 52 | 53 | void ns::TargetSet::restore_state(const char* file) 54 | { 55 | std::ifstream is(file, std::ifstream::in); 56 | restore_state(is); 57 | is.close(); 58 | } 59 | 60 | ns::IPV4TargetSet::IPV4TargetSet(leeloo::ip_list_intervals& ipv4s, leeloo::port_list_intervals& ports): 61 | _ipv4s(ipv4s), 62 | _ports(ports) 63 | { 64 | } 65 | 66 | void ns::IPV4TargetSet::init() 67 | { 68 | _ipv4s.aggregate(); 69 | _ports.aggregate(); 70 | 71 | _ipv4s.create_index_cache(256); 72 | _ports.create_index_cache(16); 73 | 74 | _rand_v4.init(_ipv4s, leeloo::random_engine(g_mt_rand_ips)); 75 | _rand_port.init(_ports, leeloo::random_engine(g_mt_rand_ports)); 76 | } 77 | 78 | void ns::IPV4TargetSet::init_shrd(uint32_t /*shrd_idx*/, uint32_t /*shrd_count*/) 79 | { 80 | } 81 | 82 | ns::Target ns::IPV4TargetSet::next_target() 83 | { 84 | if (_rand_port.end()) { 85 | _rand_v4.next(); 86 | _rand_port.init(_ports, leeloo::random_engine(g_mt_rand_ports)); 87 | } 88 | if (_rand_v4.end()) { 89 | return Target::end(); 90 | } 91 | 92 | const uint32_t ip = _rand_v4.get_current(_ipv4s); 93 | const leeloo::port port = leeloo::port(_rand_port(_ports)); 94 | 95 | return Target(ip, port); 96 | } 97 | 98 | void ns::IPV4TargetSet::save_state(std::ostream& os) 99 | { 100 | boost::archive::xml_oarchive xmlo(os); 101 | xmlo << boost::serialization::make_nvp("ipv4s", _ipv4s); 102 | xmlo << boost::serialization::make_nvp("ports", _ports); 103 | _rand_v4.save_state(xmlo); 104 | _rand_port.save_state(xmlo); 105 | } 106 | 107 | void ns::IPV4TargetSet::restore_state(std::istream& is) 108 | { 109 | boost::archive::xml_iarchive xmli(is); 110 | xmli >> boost::serialization::make_nvp("ipv4s", _ipv4s); 111 | xmli >> boost::serialization::make_nvp("ports", _ports); 112 | _rand_v4.restore_state(xmli, _ipv4s, leeloo::random_engine(g_mt_rand_ips)); 113 | _rand_port.restore_state(xmli, _ports, leeloo::random_engine(g_mt_rand_ports)); 114 | 115 | _ipv4s.create_index_cache(256); 116 | _ports.create_index_cache(16); 117 | } 118 | 119 | bool ns::IPV4TargetSet::target_finished(Target const& target, HostSM& hsm) 120 | { 121 | hsm.port_done(target.port()); 122 | if (hsm.ports_done_count() == ports_count()) { 123 | // Target is done 124 | _rand_v4.step_done(hsm.rand_idx_ip()); 125 | // true means that the HostSM object can be deleted 126 | return true; 127 | } 128 | return false; 129 | } 130 | 131 | void ns::IPV4TargetSet::init_host_sm(Target const&, HostSM& hsm) 132 | { 133 | hsm.set_rand_idx_ip(_rand_v4.get_current_step()); 134 | } 135 | -------------------------------------------------------------------------------- /src/include/ns/buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_BUFFER_H 32 | #define NS_BUFFER_H 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | #include 40 | 41 | namespace ns { 42 | 43 | template 44 | class Buffer 45 | { 46 | static_assert(std::is_pod::value, "T must be a POD"); 47 | 48 | typedef SizeType size_type; 49 | typedef T value_type; 50 | typedef T* pointer_type; 51 | typedef T const* const_pointer_type; 52 | 53 | public: 54 | Buffer(): 55 | _buffer(nullptr), 56 | _buf_size(0), 57 | _buf_pos(0) 58 | { } 59 | 60 | Buffer(Buffer const& o): 61 | Buffer() 62 | { 63 | copy(o); 64 | } 65 | 66 | Buffer(Buffer&& o): 67 | _buffer(nullptr) 68 | { 69 | move(std::move(o)); 70 | } 71 | 72 | ~Buffer() 73 | { 74 | if (_buffer) { 75 | ::free(_buffer); 76 | } 77 | } 78 | 79 | public: 80 | void free() 81 | { 82 | if (_buffer) { 83 | ::free(_buffer); 84 | _buffer = NULL; 85 | _buf_pos = 0; 86 | _buf_size = 0; 87 | } 88 | } 89 | 90 | public: 91 | Buffer& operator=(Buffer const& o) 92 | { 93 | if (&o != this) { 94 | copy(o); 95 | } 96 | return *this; 97 | } 98 | 99 | Buffer& operator=(Buffer&& o) 100 | { 101 | if (&o != this) { 102 | move(std::move(o)); 103 | } 104 | return *this; 105 | } 106 | 107 | public: 108 | // TODO: replace by malloc_usable_size and save memory! 109 | inline size_type allocated_size() const { return _buf_size; } 110 | inline size_type size() const { return _buf_pos; } 111 | 112 | inline pointer_type begin() { return _buffer; } 113 | inline const_pointer_type begin() const { return _buffer; } 114 | 115 | inline pointer_type end() { return _buffer + size(); } 116 | inline const_pointer_type end() const { return _buffer + size(); } 117 | 118 | inline pointer_type at(size_type const i) { return begin()+i; } 119 | inline const_pointer_type at(size_type const i) const { return begin()+i; } 120 | 121 | inline pointer_type operator[](size_type const i) { return at(i); } 122 | inline const_pointer_type operator[](size_type const i) const { return at(i); } 123 | 124 | public: 125 | // Returns a pointer to the previous position of the possibly new allocated buffer 126 | pointer_type grow_by(size_type n) 127 | { 128 | size_type old_pos = size(); 129 | allocate(size() + n); 130 | size_() += n; 131 | return begin()+old_pos; 132 | } 133 | 134 | void pop_by(size_type n) 135 | { 136 | assert(n <= _buf_pos); 137 | const size_type rem = size()-n; 138 | memmove(_buffer, _buffer + n, rem); 139 | size_() -= n; 140 | } 141 | 142 | private: 143 | inline size_type& size_() { return _buf_pos; } 144 | inline size_type& allocated_size_() { return _buf_size; } 145 | 146 | static inline size_type size_buf(size_type n) { return n*sizeof(size_type); } 147 | 148 | void allocate(size_type n) 149 | { 150 | if (_buffer) { 151 | if (allocated_size() < n) { 152 | _buffer = reinterpret_cast(realloc(_buffer, size_buf(n))); 153 | allocated_size_() = n; 154 | } 155 | } 156 | else { 157 | _buffer = reinterpret_cast(malloc(size_buf(n))); 158 | allocated_size_() = n; 159 | } 160 | } 161 | 162 | void copy(Buffer const& o) 163 | { 164 | allocate(o.size()); 165 | memcpy(_buffer, o._buffer, size_buf(o.size())); 166 | size_() = o.size(); 167 | } 168 | 169 | void move(Buffer&& o) 170 | { 171 | if (_buffer) { 172 | ::free(_buffer); 173 | } 174 | _buffer = o._buffer; 175 | allocated_size_() = o.allocated_size(); 176 | size_() = o.size(); 177 | o._buffer = nullptr; 178 | o.size_() = 0; 179 | o.allocated_size_() = 0; 180 | } 181 | 182 | private: 183 | pointer_type _buffer; 184 | size_type _buf_size; 185 | size_type _buf_pos; 186 | }; 187 | 188 | } 189 | 190 | #endif 191 | -------------------------------------------------------------------------------- /src/include/ns/async_engine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_ASYNC_SCAN_H 32 | #define NS_ASYNC_SCAN_H 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | struct epoll_event; 47 | 48 | namespace ns { 49 | 50 | class Target; 51 | class TargetSet; 52 | 53 | class AsyncEngine: public Engine 54 | { 55 | public: 56 | typedef std::map hosts_sms_type; 57 | typedef std::map lvl4_sms_type; 58 | typedef std::map sockets_targets_type; 59 | 60 | public: 61 | AsyncEngine(TargetSet& targets, uint32_t nsockets = 1000, uint32_t timeout = 5); 62 | 63 | public: 64 | // Implement the interface of an engine 65 | void launch(); 66 | void launch_shrd(uint32_t idx, uint32_t total); 67 | 68 | public: 69 | void set_lvl4_connected_callback(Lvl4Action const& a) 70 | { 71 | _callback_lvl4_connected = a; 72 | } 73 | 74 | void set_lvl4_finish_callback(Lvl4Finish const& f) { _callback_finish = f; } 75 | 76 | void set_status_display_callback(StatusDisplay const& f, uint32_t timeout) 77 | { 78 | _callback_status = f; 79 | _timeout_status_display = timeout; 80 | } 81 | 82 | void set_watch_timeout(WatchTimeout const& f, uint32_t timeout) 83 | { 84 | _watch_timeout = timeout; 85 | _watch_timeout_cb = f; 86 | } 87 | 88 | void set_timeout_of_target(TimeoutTarget const& f) 89 | { 90 | _callback_timeout_target = f; 91 | } 92 | 93 | void ensure_available_sockets(const size_t n); 94 | 95 | public: 96 | uint32_t timeout() const { return _timeout; } 97 | uint32_t watch_timeout() const { return _watch_timeout; } 98 | uint32_t nsockets() const { return _nsockets; } 99 | 100 | private: 101 | void do_async_scan(); 102 | void init_sockets(); 103 | void connect_ip(uint32_t const ip, uint16_t const port); 104 | 105 | private: 106 | void free_socket(int s); 107 | 108 | HostSM& host_sm(uint32_t ip) 109 | { 110 | auto it = _hosts_sms.find(ip); 111 | if (it == _hosts_sms.end()) { 112 | return _hosts_sms.insert(std::make_pair(ip, HostSM())).first->second; 113 | } 114 | return it->second; 115 | } 116 | 117 | void del_host_sm(Target const& t) 118 | { 119 | _hosts_sms.erase(t.ipv4()); 120 | } 121 | 122 | void add_connected_socket(int s); 123 | void add_connecting_socket(int s); 124 | void remove_connecting_socket(int s); 125 | void remove_connected_socket(int s); 126 | 127 | inline int& epoll() { return _epoll; } 128 | 129 | bool process_free_socks(); 130 | int process_events(); 131 | size_t process_dirty_and_timeouts(); 132 | 133 | void process_connecting_ready(int s, Lvl4SM& lvl4sm); 134 | void process_connected_ready(int s, Target const& target, Lvl4SM& lvl4sm); 135 | 136 | void reconnect(int s, Target const& target, Lvl4SM const& lvl4sm); 137 | int create_socket(int& s, Target const& target); 138 | 139 | Target const& target_from_socket(int s) const 140 | { 141 | sockets_targets_type::const_iterator it = _sockets_targets.find(s); 142 | assert(it != _sockets_targets.end()); 143 | return it->second; 144 | } 145 | 146 | Lvl4SM& new_lvl4_sm(int s) 147 | { 148 | return _lvl4_sms.insert(std::make_pair(s, Lvl4SM())).first->second; 149 | } 150 | 151 | void del_lvl4_sm(int s) 152 | { 153 | _lvl4_sms.erase(s); 154 | } 155 | 156 | Lvl4SM& lvl4_sm(epoll_event const& ev); 157 | 158 | Lvl4SM& lvl4_sm(int s) 159 | { 160 | return _lvl4_sms[s]; 161 | } 162 | 163 | void callback_finish(Target const& t, Lvl4Buffer const& buf, int error) 164 | { 165 | if (_callback_finish) { 166 | _callback_finish(t, buf.begin(), buf.size(), error); 167 | } 168 | } 169 | 170 | void socket_finished(int s, int err); 171 | 172 | bool should_call_status_display(); 173 | 174 | bool has_watch_timedout(time_t ts, int s, Lvl4SM& lvl4sm) const; 175 | 176 | inline uint32_t timeout_of_target(Target const& t) const 177 | { 178 | if (_callback_timeout_target) { 179 | return _callback_timeout_target(t); 180 | } 181 | return _timeout; 182 | } 183 | 184 | private: 185 | hosts_sms_type _hosts_sms; 186 | lvl4_sms_type _lvl4_sms; 187 | sockets_targets_type _sockets_targets; 188 | uint32_t _avail_socks; 189 | int _epoll; 190 | Lvl4Action _callback_lvl4_connected; 191 | 192 | // Configuration 193 | uint32_t _nsockets; 194 | uint32_t _timeout; 195 | uint32_t _watch_timeout; 196 | WatchTimeout _watch_timeout_cb; 197 | 198 | // Status 199 | size_t _nlaunched; 200 | size_t _ndone; 201 | 202 | // Errors 203 | Lvl4Finish _callback_finish; 204 | 205 | // Timeout of target 206 | TimeoutTarget _callback_timeout_target; 207 | 208 | // Status display 209 | StatusDisplay _callback_status; 210 | uint32_t _timeout_status_display; // in seconds 211 | time_t _last_time_status_display; 212 | }; 213 | 214 | } 215 | 216 | #endif 217 | -------------------------------------------------------------------------------- /src/include/ns/target_set.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef NS_TARGET_SET_H 32 | #define NS_TARGET_SET_H 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include 44 | #include 45 | 46 | namespace ns { 47 | 48 | class Engine; 49 | class HostSM; 50 | 51 | struct NextTargetWouldBlock 52 | { }; 53 | 54 | class TargetSet 55 | { 56 | public: 57 | virtual void init() = 0; 58 | virtual void init_shrd(uint32_t shrd_idx, uint32_t shrd_count) = 0; 59 | 60 | virtual void save_state(const char* file); 61 | virtual void restore_state(const char* file); 62 | 63 | virtual void save_state(std::ostream& os) = 0; 64 | virtual void restore_state(std::istream& is) = 0; 65 | 66 | virtual Target next_target() = 0; 67 | virtual bool target_finished(Target const& target, HostSM& hsm) = 0; 68 | 69 | virtual void init_host_sm(Target const&, HostSM&) { }; 70 | }; 71 | 72 | class IPV4TargetSet: public TargetSet 73 | { 74 | friend class Engine; 75 | 76 | typedef leeloo::list_intervals_random_promise v4_random_state; 77 | typedef leeloo::list_intervals_random port_random_state; 78 | 79 | public: 80 | IPV4TargetSet(leeloo::ip_list_intervals& ipv4s, leeloo::port_list_intervals& ports); 81 | 82 | public: 83 | leeloo::ip_list_intervals const& ipv4s() const { return _ipv4s; } 84 | leeloo::port_list_intervals const& ports() const { return _ports; } 85 | 86 | /*void add_ipv4(uint32_t ip); 87 | void add_ipv4s(uint32_t start, uint32_t end); 88 | void add_ipv4s(const char* ip); 89 | 90 | void add_port(uint16_t port); 91 | void add_ports(uint16_t start, uint16_t end);*/ 92 | 93 | public: 94 | void init() override; 95 | void init_shrd(uint32_t shrd_idx, uint32_t shrd_count); 96 | 97 | void save_state(std::ostream& os) override; 98 | void restore_state(std::istream& is) override; 99 | 100 | Target next_target() override; 101 | bool target_finished(Target const& target, HostSM& hsm); 102 | 103 | void init_host_sm(Target const& target, HostSM& hsm); 104 | 105 | inline uint32_t ports_count() const { return _rand_port.size_original(); } 106 | 107 | private: 108 | //void reaggregate_ips(); 109 | //void reaggregate_ports(); 110 | 111 | private: 112 | leeloo::ip_list_intervals& _ipv4s; 113 | leeloo::port_list_intervals& _ports; 114 | 115 | v4_random_state _rand_v4; 116 | port_random_state _rand_port; 117 | }; 118 | 119 | class SimpleTargetSet: public TargetSet 120 | { 121 | typedef std::set target_storage_type; 122 | 123 | public: 124 | void add_target(Target const& target) 125 | { 126 | target_storage_type::iterator it = _targets.insert(target).first; 127 | if (_it == _targets.end()) { 128 | _it = it; 129 | } 130 | } 131 | 132 | void remove_target(Target const& target) 133 | { 134 | target_storage_type::iterator it = _targets.find(target); 135 | if (it == _targets.end()) { 136 | return; 137 | } 138 | if (it == _it) { 139 | ++_it; 140 | } 141 | _targets.erase(it); 142 | } 143 | 144 | virtual void init() 145 | { 146 | _it = _targets.begin(); 147 | } 148 | 149 | virtual void init_shrd(uint32_t /*shrd_idx*/, uint32_t /*shrd_count*/) { } 150 | 151 | virtual void save_state(std::ostream&) 152 | { } 153 | virtual void restore_state(std::istream&) 154 | { } 155 | 156 | virtual Target next_target() 157 | { 158 | if (_it == _targets.end()) { 159 | return Target::end(); 160 | } 161 | Target const& ret = *_it; 162 | ++_it; 163 | return ret; 164 | } 165 | 166 | virtual bool target_finished(Target const&, HostSM&) { return true; } 167 | 168 | private: 169 | target_storage_type _targets; 170 | target_storage_type::const_iterator _it; 171 | }; 172 | 173 | template 174 | class RepeatableTargetSet: public T 175 | { 176 | public: 177 | typedef T target_set_base_type; 178 | 179 | public: 180 | using T::T; 181 | 182 | public: 183 | Target next_target() override 184 | { 185 | Target ret = target_set_base_type::next_target(); 186 | if (ret.is_end()) { 187 | this->init(); 188 | ret = target_set_base_type::next_target(); 189 | } 190 | return ret; 191 | } 192 | }; 193 | 194 | template 195 | class ReinjectableTargetSet: public T 196 | { 197 | public: 198 | typedef T target_set_base_type; 199 | 200 | public: 201 | using T::T; 202 | 203 | public: 204 | void emplace_target(Target&& t) 205 | { 206 | _targets.emplace(std::move(t)); 207 | } 208 | 209 | void add_target(Target const& t) 210 | { 211 | _targets.push(t); 212 | } 213 | 214 | public: 215 | Target next_target() override 216 | { 217 | // Added targets are done first 218 | if (_targets.size() > 0) { 219 | Target ret = std::move(_targets.front()); 220 | _targets.pop(); 221 | return ret; 222 | } 223 | return target_set_base_type::next_target(); 224 | } 225 | 226 | private: 227 | std::queue _targets; 228 | }; 229 | 230 | } 231 | 232 | #endif 233 | -------------------------------------------------------------------------------- /src/protocols/ssl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | namespace nsp = ns::protocols; 40 | using nsp::__impl::TLS; 41 | using nsp::__impl::Handshake; 42 | using nsp::__impl::ClientHello; 43 | using nsp::__impl::Certificate; 44 | 45 | #pragma pack(pop) 46 | 47 | nsp::SSL::SSL() 48 | { 49 | TLS tls; 50 | tls.msg_type = 0x16; // handshake 51 | tls.client_version = {3, 0}; 52 | tls.length = htons(sizeof(Handshake)+sizeof(ClientHello)); 53 | 54 | Handshake hs; 55 | hs.msg_type = 1; // client_hello 56 | hs.length2 = 0; 57 | hs.length1 = 0; 58 | hs.length0 = sizeof(ClientHello); 59 | 60 | ClientHello ch; 61 | ch.client_version = {3, 0}; 62 | ch.random.gmt_unix_time = htonl(time(NULL)); 63 | memset(&ch.random.random_bytes[0], 0xAA, 28); 64 | ch.session_id.length = 0; 65 | ch.cipher_suites.length = htons(sizeof(ch.cipher_suites.data)); 66 | ch.cipher_suites.data[0] = 0x0100; 67 | ch.cipher_suites.data[1] = 0x0200; 68 | ch.cipher_suites.data[2] = 0x3B00; 69 | ch.cipher_suites.data[3] = 0x0400; 70 | ch.cipher_suites.data[4] = 0x0500; 71 | ch.cipher_suites.data[5] = 0x0A00; 72 | ch.cipher_suites.data[6] = 0x2F00; 73 | ch.cipher_suites.data[7] = 0x3500; 74 | ch.cipher_suites.data[8] = 0x3C00; 75 | ch.cipher_suites.data[9] = 0x3D00; 76 | ch.compression_methods = {1, 0}; 77 | ch.ext_length = 0; 78 | 79 | memcpy(client_hello, &tls, sizeof(TLS)); 80 | memcpy(client_hello+sizeof(TLS), &hs, sizeof(Handshake)); 81 | memcpy(client_hello+sizeof(TLS)+sizeof(Handshake), &ch, sizeof(ClientHello)); 82 | } 83 | 84 | bool nsp::SSL::operator()(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&) const 85 | { 86 | t.send((unsigned char*) client_hello, sizeof(client_hello)); 87 | lvl4sm.set_trigger(sizeof(TLS), 88 | [this](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) -> bool 89 | { return this->on_tls_header(t, lvl4sm, hsm, buf, size, [this](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) { return this->on_handshake1(t, lvl4sm, hsm, buf, size); }); }); 90 | 91 | return true; 92 | } 93 | 94 | bool nsp::SSL::on_tls_header(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size, ns::Lvl4DataAction const& on_hs) const 95 | { 96 | TLS const* tls = reinterpret_cast(buf); 97 | if (tls->msg_type != 0x16) { // Handshake 98 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 99 | } 100 | lvl4sm.set_trigger(ntohs(tls->length), on_hs); 101 | return true; 102 | } 103 | 104 | bool nsp::SSL::on_handshake1(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) const 105 | { 106 | if (size < sizeof(Handshake)) { 107 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 108 | } 109 | size -= sizeof(Handshake); 110 | Handshake const* hs = reinterpret_cast(buf); 111 | if (hs->msg_type != 2) { // Server hello 112 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 113 | } 114 | int length = hs->get_length(); 115 | if (length != size) { 116 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 117 | } 118 | buf += sizeof(Handshake); 119 | uint16_t cipher = *((uint16_t*)(&buf[size-3])); 120 | if (!call_cb(_on_cipher, t, lvl4sm, hsm, cipher)) { 121 | return false; 122 | } 123 | 124 | lvl4sm.set_trigger(sizeof(TLS), 125 | [this](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) -> bool 126 | { return on_tls_header(t, lvl4sm, hsm, buf, size, [this](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) { return this->on_handshake2(t, lvl4sm, hsm, buf, size); }); }); 127 | return true; 128 | } 129 | 130 | bool nsp::SSL::on_handshake2(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) const 131 | { 132 | if (size < sizeof(Handshake)) { 133 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 134 | } 135 | size -= sizeof(Handshake); 136 | Handshake const* hs = reinterpret_cast(buf); 137 | int length = hs->get_length(); 138 | if (hs->msg_type != 11) { // Certificates 139 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 140 | } 141 | if (length != size) { 142 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 143 | } 144 | buf += sizeof(Handshake); 145 | if (size < 3) { 146 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 147 | } 148 | Certificate const* crts = reinterpret_cast(buf); 149 | int crts_len = crts->get_length(); 150 | size -= 3; 151 | buf += 3; 152 | if (crts_len != size) { 153 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 154 | } 155 | while (crts_len > 0) { 156 | Certificate const* crt = reinterpret_cast(buf); 157 | if (crts_len < 3) { 158 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 159 | } 160 | int crt_len = crt->get_length(); 161 | if (crts_len < crt_len) { 162 | return call_cb(_on_failure, t, lvl4sm, hsm, buf, size); 163 | } 164 | buf += 3; 165 | crts_len -= 3; 166 | if (!call_cb(_on_certif, t, lvl4sm, hsm, buf, crt_len)) { 167 | return false; 168 | } 169 | buf += crt_len; 170 | crts_len -= crt_len; 171 | } 172 | return false; 173 | } 174 | -------------------------------------------------------------------------------- /src/async_engine.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #define _BSD_SOURCE 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include 47 | 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #define MAX_EVENTS 1024 56 | 57 | static uint32_t socket_bytes_avail(int s) 58 | { 59 | int ret; 60 | ioctl(s, FIONREAD, &ret); 61 | return ret; 62 | } 63 | 64 | static int new_socket(int type, int proto) 65 | { 66 | int s = socket(AF_INET, type, proto); 67 | fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK); 68 | return s; 69 | } 70 | 71 | ns::AsyncEngine::AsyncEngine(TargetSet& targets, uint32_t nsockets, uint32_t timeout): 72 | Engine(targets), 73 | _nsockets(nsockets), 74 | _timeout(timeout), 75 | _timeout_status_display(0) 76 | { 77 | init_sockets(); 78 | } 79 | 80 | void ns::AsyncEngine::init_sockets() 81 | { 82 | _avail_socks = nsockets(); 83 | /* 84 | free_socks().reserve(nsockets()); 85 | for (uint32_t i = 0; i < nsockets(); i++) { 86 | const int s = new_socket(); 87 | _lvl4_sms.insert(std::make_pair(s, Lvl4SM())); 88 | free_socks().push_back(s); 89 | } 90 | */ 91 | } 92 | 93 | void ns::AsyncEngine::remove_connected_socket(int s) 94 | { 95 | struct epoll_event ev; 96 | ev.events = EPOLLIN; 97 | ev.data.fd = s; 98 | epoll_ctl(epoll(), EPOLL_CTL_DEL, s, &ev); 99 | } 100 | 101 | void ns::AsyncEngine::free_socket(int s) 102 | { 103 | remove_connecting_socket(s); 104 | remove_connected_socket(s); 105 | 106 | close(s); 107 | del_lvl4_sm(s); 108 | _avail_socks++; 109 | _sockets_targets.erase(s); 110 | } 111 | 112 | void ns::AsyncEngine::socket_finished(int s, int err) 113 | { 114 | _ndone++; 115 | Target t = target_from_socket(s); 116 | Lvl4SM& lvl4sm = lvl4_sm(s); 117 | Lvl4Buffer const& buf = lvl4sm.buffer(); 118 | callback_finish(t, buf, err); 119 | lvl4sm.free_buffer(); 120 | if (target_finished(t, host_sm(t.ipv4()))) { 121 | del_host_sm(t); 122 | } 123 | free_socket(s); 124 | } 125 | 126 | void ns::AsyncEngine::process_connecting_ready(int s, Lvl4SM& lvl4sm) 127 | { 128 | _D(BOOST_LOG_NAMED_SCOPE("AsyncEngine::process_connecting_ready")); 129 | 130 | int err; 131 | socklen_t size = sizeof(int); 132 | getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &size); 133 | if (err != 0) { 134 | //BOOST_LOG_TRIVIAL(trace) << "Error with " << ipstr(ipv4) << ": " << strerror(err) << std::endl; 135 | socket_finished(s, err); 136 | return; 137 | } 138 | 139 | Target target = target_from_socket(s); 140 | const uint32_t ipv4 = target.ipv4(); 141 | _D(BOOST_LOG_TRIVIAL(trace) << "Connected to " << ipstr(ipv4) << std::endl); 142 | 143 | const bool ret = lvl4sm.on_connect(s, target, host_sm(ipv4)); 144 | 145 | if (ret == false) { 146 | // The end for him 147 | socket_finished(s, 0); 148 | _D(BOOST_LOG_TRIVIAL(trace) << "on_connect action returned false for " << ipstr(ipv4) << std::endl); 149 | } 150 | else { 151 | remove_connecting_socket(s); 152 | add_connected_socket(s); 153 | lvl4sm.update_ts(); 154 | } 155 | } 156 | 157 | void ns::AsyncEngine::reconnect(int s, Target const& target, Lvl4SM const& lvl4sm) 158 | { 159 | _D(BOOST_LOG_TRIVIAL(trace) << "reconnect" << std::endl); 160 | Lvl4Action cur_action = lvl4sm.get_on_connect(); 161 | 162 | remove_connected_socket(s); 163 | close(s); 164 | _avail_socks++; 165 | 166 | create_socket(s, target); 167 | lvl4_sm(s).set_on_connect(cur_action); 168 | add_connecting_socket(s); 169 | } 170 | 171 | int ns::AsyncEngine::create_socket(int& s, Target const& target) 172 | { 173 | assert(_avail_socks > 0); 174 | /*struct in_addr addr_; 175 | addr_.s_addr = htonl(target.ipv4()); 176 | std::cerr << "Connecting to " << inet_ntoa(addr_) << "..." << std::endl;*/ 177 | 178 | leeloo::port port = target.port(); 179 | s = new_socket(port.socket_type(), port.socket_proto()); 180 | if (s == -1) { 181 | return errno; 182 | } 183 | _avail_socks--; 184 | sockaddr_in addr = target.to_sockaddr_in(); 185 | int ret = connect(s, (const sockaddr*) &addr, sizeof(struct sockaddr_in)); 186 | Lvl4SM& lvl4sm = new_lvl4_sm(s); 187 | lvl4sm.set_valid(true); 188 | lvl4sm.set_on_connect(_callback_lvl4_connected); 189 | lvl4sm.update_ts(); 190 | _sockets_targets.insert(std::make_pair(s, target)); 191 | return ret; 192 | } 193 | 194 | void ns::AsyncEngine::process_connected_ready(int s, Target const& target, Lvl4SM& lvl4sm) 195 | { 196 | _D(BOOST_LOG_NAMED_SCOPE("AsyncEngine::process_connected_ready")); 197 | uint32_t navail = socket_bytes_avail(s); 198 | const uint32_t ipv4 = target.ipv4(); 199 | if (navail == 0) { 200 | _D(BOOST_LOG_TRIVIAL(trace) << ipstr(ipv4) << " remote host deconnected" << std::endl); 201 | if (lvl4sm.reconnect()) { 202 | Lvl4Buffer const& buf = lvl4sm.buffer(); 203 | callback_finish(target, buf, (int) errors::WILL_RECONNECT); 204 | lvl4sm.free_buffer(); 205 | reconnect(s, target, lvl4sm); 206 | return; 207 | } 208 | socket_finished(s, ECONNRESET); 209 | return; 210 | } 211 | 212 | // Returns true to go on 213 | // false to remove 214 | bool ret = lvl4sm.process_lvl4_data(s, navail, target, host_sm(ipv4)); 215 | _D(BOOST_LOG_TRIVIAL(trace) << ipstr(ipv4) << " process_lvl4_data returned " << ret << std::endl); 216 | lvl4sm.update_ts(); 217 | 218 | if (ret == false) { 219 | _D(BOOST_LOG_TRIVIAL(trace) << ipstr(ipv4) << " free socket!" << std::endl); 220 | // Free socket, this is the end for this one! 221 | socket_finished(s, 0); 222 | } 223 | } 224 | 225 | void ns::AsyncEngine::add_connecting_socket(int s) 226 | { 227 | struct epoll_event ev; 228 | ev.events = EPOLLOUT; 229 | ev.data.fd = s; 230 | epoll_ctl(epoll(), EPOLL_CTL_ADD, s, &ev); 231 | } 232 | 233 | void ns::AsyncEngine::add_connected_socket(int s) 234 | { 235 | struct epoll_event ev; 236 | ev.events = EPOLLIN; 237 | ev.data.fd = s; 238 | epoll_ctl(epoll(), EPOLL_CTL_ADD, s, &ev); 239 | } 240 | 241 | void ns::AsyncEngine::remove_connecting_socket(int s) 242 | { 243 | struct epoll_event ev; 244 | // &ev isn't mandatory, but there is a bug before 2.6.9 that 245 | // makes epoll crashes if &ev == nullptr 246 | epoll_ctl(epoll(), EPOLL_CTL_DEL, s, &ev); 247 | } 248 | 249 | void ns::AsyncEngine::launch() 250 | { 251 | init_scan(); 252 | do_async_scan(); 253 | } 254 | 255 | void ns::AsyncEngine::launch_shrd(uint32_t, uint32_t) 256 | { 257 | //init_shrd_scan(idx, total); 258 | do_async_scan(); 259 | } 260 | 261 | bool ns::AsyncEngine::process_free_socks() 262 | { 263 | std::vector::const_iterator it_socks; 264 | _D(BOOST_LOG_TRIVIAL(trace) << "begin free socks" << std::endl); 265 | const uint32_t avail_socks = _avail_socks; 266 | try { 267 | for (uint32_t i = 0; i < avail_socks; i++) { 268 | int ret, s; 269 | Target cur_target; 270 | while (true) { 271 | cur_target = next_target(); 272 | if (cur_target.is_end()) { 273 | return false; 274 | } 275 | _nlaunched++; 276 | ret = create_socket(s, cur_target); 277 | if (ret == 0) { 278 | break; 279 | } 280 | else { 281 | if (errno == EINPROGRESS) { 282 | break; 283 | } 284 | socket_finished(s, errno); 285 | _D(BOOST_LOG_TRIVIAL(trace) << s << " Error connecting to " << ipstr(cur_target.ipv4()) << ": " << errno << " " << strerror(errno) << std::endl); 286 | } 287 | } 288 | _D(BOOST_LOG_TRIVIAL(trace) << "Connecting to " << ipstr(cur_target.ipv4()) << std::endl); 289 | HostSM& hsm = host_sm(cur_target.ipv4()); 290 | init_host_sm(cur_target, hsm); 291 | 292 | add_connecting_socket(s); 293 | } 294 | } 295 | catch (NextTargetWouldBlock const&) { 296 | return true; 297 | } 298 | return true; 299 | } 300 | 301 | int ns::AsyncEngine::process_events() 302 | { 303 | static struct epoll_event events[MAX_EVENTS]; 304 | _D(BOOST_LOG_TRIVIAL(trace) << "begin epoll" << std::endl); 305 | // Poll this 306 | const int nfds = epoll_wait(epoll(), events, MAX_EVENTS, 1); 307 | for (int i = 0; i < nfds; i++) { 308 | struct epoll_event& ev = events[i]; 309 | const int fd = ev.data.fd; 310 | if ((ev.events & EPOLLOUT) == EPOLLOUT) { 311 | process_connecting_ready(fd, lvl4_sm(fd)); 312 | } 313 | else 314 | if ((ev.events & EPOLLIN) == EPOLLIN) { 315 | process_connected_ready(fd, target_from_socket(fd), lvl4_sm(fd)); 316 | } 317 | } 318 | 319 | return nfds; 320 | } 321 | 322 | bool ns::AsyncEngine::has_watch_timedout(time_t ts, int s, Lvl4SM& lvl4sm) const 323 | { 324 | if (!_watch_timeout_cb || (_watch_timeout == 0)) { 325 | return false; 326 | } 327 | 328 | if ((ts-lvl4sm.watch_ts()) >= watch_timeout()) { 329 | if (!_watch_timeout_cb(ConnectedTarget(s, Target::from_socket(s)))) { 330 | return true; 331 | } 332 | lvl4sm.update_watch_ts(ts); 333 | } 334 | return false; 335 | } 336 | 337 | size_t ns::AsyncEngine::process_dirty_and_timeouts() 338 | { 339 | _D(BOOST_LOG_TRIVIAL(trace) << "begin timeouts" << std::endl); 340 | lvl4_sms_type::iterator it; 341 | const time_t ts = timestamp(); 342 | size_t n_lvl4_sms_valid = 0; 343 | std::vector> to_process; 344 | std::vector timeouted; 345 | for (it = _lvl4_sms.begin(); it != _lvl4_sms.end(); it++) { 346 | Lvl4SM& p = it->second; 347 | if (p.valid()) { 348 | const int s = it->first; 349 | if (p.should_process_buffer()) { 350 | to_process.push_back(std::make_pair(s, &p)); 351 | } 352 | const uint32_t timeout_target = timeout_of_target(Target::from_socket(s)); 353 | if (((ts-p.ts()) >= timeout_target) || has_watch_timedout(ts, it->first, p)) { 354 | const int s = it->first; 355 | timeouted.push_back(s); 356 | } 357 | else { 358 | n_lvl4_sms_valid++; 359 | } 360 | } 361 | } 362 | 363 | // Do this out of this loop as some Lvl4SM can be deleted in the way. 364 | for (auto const& tp: to_process) { 365 | const int s = tp.first; 366 | Target target = target_from_socket(s); 367 | bool ret = tp.second->process_buffer(s, target, host_sm(target.ipv4())); 368 | if (!ret) { 369 | socket_finished(s, 0); 370 | continue; 371 | } 372 | } 373 | 374 | for (int s: timeouted) { 375 | socket_finished(s, (int) errors::NS_TIMEOUT); 376 | } 377 | 378 | return n_lvl4_sms_valid; 379 | } 380 | 381 | bool ns::AsyncEngine::should_call_status_display() 382 | { 383 | if (!_callback_status || _timeout_status_display == 0) { 384 | return false; 385 | } 386 | 387 | const time_t now = timestamp(); 388 | if (now-_last_time_status_display >= _timeout_status_display) { 389 | _last_time_status_display = now; 390 | return true; 391 | } 392 | 393 | return false; 394 | } 395 | 396 | void ns::AsyncEngine::do_async_scan() 397 | { 398 | _D(BOOST_LOG_NAMED_SCOPE("AsyncEngine::do_async_scan")); 399 | 400 | epoll() = epoll_create(nsockets()); 401 | 402 | _nlaunched = 0; 403 | _ndone = 0; 404 | 405 | _last_time_status_display = 0; 406 | 407 | process_free_socks(); 408 | 409 | while (true) { 410 | 411 | // Events processing 412 | const int nfds = process_events(); 413 | 414 | // Dirties and timeouts 415 | const size_t n_lvl4_sms_valid = process_dirty_and_timeouts(); 416 | 417 | // IP connect. It is done after the events processing because some of 418 | // them might have add new targets into the original set. 419 | const bool end_targets = !process_free_socks(); 420 | 421 | _D(BOOST_LOG_TRIVIAL(trace) << "nfds == " << nfds << " " 422 | << "n_lvl4_sms_valid == " << n_lvl4_sms_valid << " " 423 | << "end_targets == " << end_targets << std::endl); 424 | // Check for the end 425 | if (nfds == 0 && n_lvl4_sms_valid == 0 && end_targets) { 426 | break; 427 | } 428 | 429 | if (should_call_status_display()) { 430 | _callback_status(_nlaunched, _ndone); 431 | } 432 | 433 | if (should_save_state()) { 434 | save_state(file_autosave()); 435 | } 436 | } 437 | } 438 | 439 | ns::Lvl4SM& ns::AsyncEngine::lvl4_sm(epoll_event const& ev) 440 | { 441 | return lvl4_sm(ev.data.fd); 442 | } 443 | 444 | void ns::AsyncEngine::ensure_available_sockets(const size_t n) 445 | { 446 | if (_avail_socks < n) { 447 | _avail_socks += (n-_avail_socks); 448 | } 449 | } 450 | -------------------------------------------------------------------------------- /cmake/FindTBB.cmake: -------------------------------------------------------------------------------- 1 | # Locate Intel Threading Building Blocks include paths and libraries 2 | # FindTBB.cmake can be found at https://code.google.com/p/findtbb/ 3 | # Written by Hannes Hofmann 4 | # Improvements by Gino van den Bergen , 5 | # Florian Uhlig , 6 | # Jiri Marsik 7 | 8 | # The MIT License 9 | # 10 | # Copyright (c) 2011 Hannes Hofmann 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | # GvdB: This module uses the environment variable TBB_ARCH_PLATFORM which defines architecture and compiler. 31 | # e.g. "ia32/vc8" or "em64t/cc4.1.0_libc2.4_kernel2.6.16.21" 32 | # TBB_ARCH_PLATFORM is set by the build script tbbvars[.bat|.sh|.csh], which can be found 33 | # in the TBB installation directory (TBB_INSTALL_DIR). 34 | # 35 | # GvdB: Mac OS X distribution places libraries directly in lib directory. 36 | # 37 | # For backwards compatibility, you may explicitely set the CMake variables TBB_ARCHITECTURE and TBB_COMPILER. 38 | # TBB_ARCHITECTURE [ ia32 | em64t | itanium ] 39 | # which architecture to use 40 | # TBB_COMPILER e.g. vc9 or cc3.2.3_libc2.3.2_kernel2.4.21 or cc4.0.1_os10.4.9 41 | # which compiler to use (detected automatically on Windows) 42 | 43 | # This module respects 44 | # TBB_INSTALL_DIR or $ENV{TBB21_INSTALL_DIR} or $ENV{TBB_INSTALL_DIR} 45 | 46 | # This module defines 47 | # TBB_INCLUDE_DIRS, where to find task_scheduler_init.h, etc. 48 | # TBB_LIBRARY_DIRS, where to find libtbb, libtbbmalloc 49 | # TBB_DEBUG_LIBRARY_DIRS, where to find libtbb_debug, libtbbmalloc_debug 50 | # TBB_INSTALL_DIR, the base TBB install directory 51 | # TBB_LIBRARIES, the libraries to link against to use TBB. 52 | # TBB_DEBUG_LIBRARIES, the libraries to link against to use TBB with debug symbols. 53 | # TBB_FOUND, If false, don't try to use TBB. 54 | # TBB_INTERFACE_VERSION, as defined in tbb/tbb_stddef.h 55 | 56 | 57 | if (WIN32) 58 | # has em64t/vc8 em64t/vc9 59 | # has ia32/vc7.1 ia32/vc8 ia32/vc9 60 | set(_TBB_DEFAULT_INSTALL_DIR "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB") 61 | set(_TBB_LIB_NAME "tbb") 62 | set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") 63 | set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") 64 | set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") 65 | if (MSVC71) 66 | set (_TBB_COMPILER "vc7.1") 67 | endif(MSVC71) 68 | if (MSVC80) 69 | set(_TBB_COMPILER "vc8") 70 | endif(MSVC80) 71 | if (MSVC90) 72 | set(_TBB_COMPILER "vc9") 73 | endif(MSVC90) 74 | if(MSVC10) 75 | set(_TBB_COMPILER "vc10") 76 | endif(MSVC10) 77 | # Todo: add other Windows compilers such as ICL. 78 | set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) 79 | endif (WIN32) 80 | 81 | if (UNIX) 82 | if (APPLE) 83 | # MAC 84 | set(_TBB_DEFAULT_INSTALL_DIR "/Library/Frameworks/Intel_TBB.framework/Versions") 85 | # libs: libtbb.dylib, libtbbmalloc.dylib, *_debug 86 | set(_TBB_LIB_NAME "tbb") 87 | set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") 88 | set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") 89 | set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") 90 | # default flavor on apple: ia32/cc4.0.1_os10.4.9 91 | # Jiri: There is no reason to presume there is only one flavor and 92 | # that user's setting of variables should be ignored. 93 | if(NOT TBB_COMPILER) 94 | set(_TBB_COMPILER "cc4.0.1_os10.4.9") 95 | elseif (NOT TBB_COMPILER) 96 | set(_TBB_COMPILER ${TBB_COMPILER}) 97 | endif(NOT TBB_COMPILER) 98 | if(NOT TBB_ARCHITECTURE) 99 | set(_TBB_ARCHITECTURE "ia32") 100 | elseif(NOT TBB_ARCHITECTURE) 101 | set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) 102 | endif(NOT TBB_ARCHITECTURE) 103 | else (APPLE) 104 | # LINUX 105 | set(_TBB_DEFAULT_INSTALL_DIR "/opt/intel/tbb" "/usr/local/include" "/usr/include") 106 | set(_TBB_LIB_NAME "tbb") 107 | set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") 108 | set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") 109 | set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") 110 | # has em64t/cc3.2.3_libc2.3.2_kernel2.4.21 em64t/cc3.3.3_libc2.3.3_kernel2.6.5 em64t/cc3.4.3_libc2.3.4_kernel2.6.9 em64t/cc4.1.0_libc2.4_kernel2.6.16.21 111 | # has ia32/* 112 | # has itanium/* 113 | set(_TBB_COMPILER ${TBB_COMPILER}) 114 | set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) 115 | endif (APPLE) 116 | endif (UNIX) 117 | 118 | if (CMAKE_SYSTEM MATCHES "SunOS.*") 119 | # SUN 120 | # not yet supported 121 | # has em64t/cc3.4.3_kernel5.10 122 | # has ia32/* 123 | endif (CMAKE_SYSTEM MATCHES "SunOS.*") 124 | 125 | 126 | #-- Clear the public variables 127 | set (TBB_FOUND "NO") 128 | 129 | 130 | #-- Find TBB install dir and set ${_TBB_INSTALL_DIR} and cached ${TBB_INSTALL_DIR} 131 | # first: use CMake variable TBB_INSTALL_DIR 132 | if (TBB_INSTALL_DIR) 133 | set (_TBB_INSTALL_DIR ${TBB_INSTALL_DIR}) 134 | endif (TBB_INSTALL_DIR) 135 | # second: use environment variable 136 | if (NOT _TBB_INSTALL_DIR) 137 | if (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "") 138 | set (_TBB_INSTALL_DIR $ENV{TBB_INSTALL_DIR}) 139 | endif (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "") 140 | # Intel recommends setting TBB21_INSTALL_DIR 141 | if (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "") 142 | set (_TBB_INSTALL_DIR $ENV{TBB21_INSTALL_DIR}) 143 | endif (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "") 144 | if (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "") 145 | set (_TBB_INSTALL_DIR $ENV{TBB22_INSTALL_DIR}) 146 | endif (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "") 147 | if (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "") 148 | set (_TBB_INSTALL_DIR $ENV{TBB30_INSTALL_DIR}) 149 | endif (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "") 150 | endif (NOT _TBB_INSTALL_DIR) 151 | # third: try to find path automatically 152 | if (NOT _TBB_INSTALL_DIR) 153 | if (_TBB_DEFAULT_INSTALL_DIR) 154 | set (_TBB_INSTALL_DIR ${_TBB_DEFAULT_INSTALL_DIR}) 155 | endif (_TBB_DEFAULT_INSTALL_DIR) 156 | endif (NOT _TBB_INSTALL_DIR) 157 | # sanity check 158 | if (NOT _TBB_INSTALL_DIR) 159 | message ("ERROR: Unable to find Intel TBB install directory. ${_TBB_INSTALL_DIR}") 160 | else (NOT _TBB_INSTALL_DIR) 161 | # finally: set the cached CMake variable TBB_INSTALL_DIR 162 | if (NOT TBB_INSTALL_DIR) 163 | set (TBB_INSTALL_DIR ${_TBB_INSTALL_DIR} CACHE PATH "Intel TBB install directory") 164 | mark_as_advanced(TBB_INSTALL_DIR) 165 | endif (NOT TBB_INSTALL_DIR) 166 | 167 | 168 | #-- A macro to rewrite the paths of the library. This is necessary, because 169 | # find_library() always found the em64t/vc9 version of the TBB libs 170 | macro(TBB_CORRECT_LIB_DIR var_name) 171 | # if (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t") 172 | string(REPLACE em64t "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}}) 173 | # endif (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t") 174 | string(REPLACE ia32 "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}}) 175 | string(REPLACE vc7.1 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) 176 | string(REPLACE vc8 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) 177 | string(REPLACE vc9 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) 178 | string(REPLACE vc10 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) 179 | endmacro(TBB_CORRECT_LIB_DIR var_content) 180 | 181 | 182 | #-- Look for include directory and set ${TBB_INCLUDE_DIR} 183 | set (TBB_INC_SEARCH_DIR ${_TBB_INSTALL_DIR}/include) 184 | # Jiri: tbbvars now sets the CPATH environment variable to the directory 185 | # containing the headers. 186 | find_path(TBB_INCLUDE_DIR 187 | tbb/task_scheduler_init.h 188 | PATHS ${TBB_INC_SEARCH_DIR} ENV CPATH 189 | ) 190 | mark_as_advanced(TBB_INCLUDE_DIR) 191 | 192 | 193 | #-- Look for libraries 194 | # GvdB: $ENV{TBB_ARCH_PLATFORM} is set by the build script tbbvars[.bat|.sh|.csh] 195 | if (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") 196 | set (_TBB_LIBRARY_DIR 197 | ${_TBB_INSTALL_DIR}/lib/$ENV{TBB_ARCH_PLATFORM} 198 | ${_TBB_INSTALL_DIR}/$ENV{TBB_ARCH_PLATFORM}/lib 199 | ) 200 | endif (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") 201 | # Jiri: This block isn't mutually exclusive with the previous one 202 | # (hence no else), instead I test if the user really specified 203 | # the variables in question. 204 | if ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL "")) 205 | # HH: deprecated 206 | message(STATUS "[Warning] FindTBB.cmake: The use of TBB_ARCHITECTURE and TBB_COMPILER is deprecated and may not be supported in future versions. Please set \$ENV{TBB_ARCH_PLATFORM} (using tbbvars.[bat|csh|sh]).") 207 | # Jiri: It doesn't hurt to look in more places, so I store the hints from 208 | # ENV{TBB_ARCH_PLATFORM} and the TBB_ARCHITECTURE and TBB_COMPILER 209 | # variables and search them both. 210 | set (_TBB_LIBRARY_DIR "${_TBB_INSTALL_DIR}/${_TBB_ARCHITECTURE}/${_TBB_COMPILER}/lib" ${_TBB_LIBRARY_DIR}) 211 | endif ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL "")) 212 | 213 | # GvdB: Mac OS X distribution places libraries directly in lib directory. 214 | list(APPEND _TBB_LIBRARY_DIR ${_TBB_INSTALL_DIR}/lib) 215 | 216 | # Jiri: No reason not to check the default paths. From recent versions, 217 | # tbbvars has started exporting the LIBRARY_PATH and LD_LIBRARY_PATH 218 | # variables, which now point to the directories of the lib files. 219 | # It all makes more sense to use the ${_TBB_LIBRARY_DIR} as a HINTS 220 | # argument instead of the implicit PATHS as it isn't hard-coded 221 | # but computed by system introspection. Searching the LIBRARY_PATH 222 | # and LD_LIBRARY_PATH environment variables is now even more important 223 | # that tbbvars doesn't export TBB_ARCH_PLATFORM and it facilitates 224 | # the use of TBB built from sources. 225 | find_library(TBB_LIBRARY ${_TBB_LIB_NAME} HINTS ${_TBB_LIBRARY_DIR} 226 | PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) 227 | find_library(TBB_MALLOC_LIBRARY ${_TBB_LIB_MALLOC_NAME} HINTS ${_TBB_LIBRARY_DIR} 228 | PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) 229 | 230 | #Extract path from TBB_LIBRARY name 231 | get_filename_component(TBB_LIBRARY_DIR ${TBB_LIBRARY} PATH) 232 | 233 | #TBB_CORRECT_LIB_DIR(TBB_LIBRARY) 234 | #TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY) 235 | mark_as_advanced(TBB_LIBRARY TBB_MALLOC_LIBRARY) 236 | 237 | #-- Look for debug libraries 238 | # Jiri: Changed the same way as for the release libraries. 239 | find_library(TBB_LIBRARY_DEBUG ${_TBB_LIB_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} 240 | PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) 241 | find_library(TBB_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_MALLOC_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} 242 | PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) 243 | 244 | # Jiri: Self-built TBB stores the debug libraries in a separate directory. 245 | # Extract path from TBB_LIBRARY_DEBUG name 246 | get_filename_component(TBB_LIBRARY_DEBUG_DIR ${TBB_LIBRARY_DEBUG} PATH) 247 | 248 | #TBB_CORRECT_LIB_DIR(TBB_LIBRARY_DEBUG) 249 | #TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY_DEBUG) 250 | mark_as_advanced(TBB_LIBRARY_DEBUG TBB_MALLOC_LIBRARY_DEBUG) 251 | 252 | 253 | if (TBB_INCLUDE_DIR) 254 | if (TBB_LIBRARY) 255 | set (TBB_FOUND "YES") 256 | set (TBB_LIBRARIES ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY} ${TBB_LIBRARIES}) 257 | set (TBB_DEBUG_LIBRARIES ${TBB_LIBRARY_DEBUG} ${TBB_MALLOC_LIBRARY_DEBUG} ${TBB_DEBUG_LIBRARIES}) 258 | set (TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIR} CACHE PATH "TBB include directory" FORCE) 259 | set (TBB_LIBRARY_DIRS ${TBB_LIBRARY_DIR} CACHE PATH "TBB library directory" FORCE) 260 | # Jiri: Self-built TBB stores the debug libraries in a separate directory. 261 | set (TBB_DEBUG_LIBRARY_DIRS ${TBB_LIBRARY_DEBUG_DIR} CACHE PATH "TBB debug library directory" FORCE) 262 | mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARY_DIRS TBB_DEBUG_LIBRARY_DIRS TBB_LIBRARIES TBB_DEBUG_LIBRARIES) 263 | message(STATUS "Found Intel TBB") 264 | endif (TBB_LIBRARY) 265 | endif (TBB_INCLUDE_DIR) 266 | 267 | if (NOT TBB_FOUND) 268 | message("ERROR: Intel TBB NOT found!") 269 | message(STATUS "Looked for Threading Building Blocks in ${_TBB_INSTALL_DIR}") 270 | # do only throw fatal, if this pkg is REQUIRED 271 | if (TBB_FIND_REQUIRED) 272 | message(FATAL_ERROR "Could NOT find TBB library.") 273 | endif (TBB_FIND_REQUIRED) 274 | endif (NOT TBB_FOUND) 275 | 276 | endif (NOT _TBB_INSTALL_DIR) 277 | 278 | if (TBB_FOUND) 279 | set(TBB_INTERFACE_VERSION 0) 280 | FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS) 281 | STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}") 282 | set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}") 283 | endif (TBB_FOUND) 284 | -------------------------------------------------------------------------------- /src/protocols/ssh.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | namespace nsp = ns::protocols; 37 | 38 | unsigned char client_key_exchange[1456] = { 39 | 0x00, 0x00, 0x05, 0xAC, 0x04, 0x14, 0x45, 0x17, 0x1E, 0xD1, 0x8D, 0x29, 0x3F, 0xC8, 0xCF, 0xD0, 40 | 0xE6, 0x00, 0x22, 0xE8, 0xE5, 0x2C, 0x00, 0x00, 0x00, 0x38, 0x65, 0x63, 0x64, 0x68, 0x2D, 0x73, 41 | 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35, 0x36, 0x2C, 0x65, 0x63, 0x64, 42 | 0x68, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x33, 0x38, 0x34, 0x2C, 43 | 0x65, 0x63, 0x64, 0x68, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x35, 44 | 0x32, 0x31, 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2D, 0x72, 0x73, 0x61, 0x00, 0x00, 0x00, 45 | 0xE9, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x31, 46 | 0x39, 0x32, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2D, 0x63, 0x74, 47 | 0x72, 0x2C, 0x61, 0x72, 0x63, 0x66, 0x6F, 0x75, 0x72, 0x32, 0x35, 0x36, 0x2C, 0x61, 0x72, 0x63, 48 | 0x66, 0x6F, 0x75, 0x72, 0x31, 0x32, 0x38, 0x2C, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x67, 49 | 0x63, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x61, 50 | 0x65, 0x73, 0x32, 0x35, 0x36, 0x2D, 0x67, 0x63, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 51 | 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x63, 0x68, 0x61, 0x63, 0x68, 0x61, 0x32, 0x30, 0x2D, 0x70, 52 | 0x6F, 0x6C, 0x79, 0x31, 0x33, 0x30, 0x35, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 53 | 0x63, 0x6F, 0x6D, 0x2C, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x63, 0x62, 0x63, 0x2C, 0x33, 54 | 0x64, 0x65, 0x73, 0x2D, 0x63, 0x62, 0x63, 0x2C, 0x62, 0x6C, 0x6F, 0x77, 0x66, 0x69, 0x73, 0x68, 55 | 0x2D, 0x63, 0x62, 0x63, 0x2C, 0x63, 0x61, 0x73, 0x74, 0x31, 0x32, 0x38, 0x2D, 0x63, 0x62, 0x63, 56 | 0x2C, 0x61, 0x65, 0x73, 0x31, 0x39, 0x32, 0x2D, 0x63, 0x62, 0x63, 0x2C, 0x61, 0x65, 0x73, 0x32, 57 | 0x35, 0x36, 0x2D, 0x63, 0x62, 0x63, 0x2C, 0x61, 0x72, 0x63, 0x66, 0x6F, 0x75, 0x72, 0x2C, 0x72, 58 | 0x69, 0x6A, 0x6E, 0x64, 0x61, 0x65, 0x6C, 0x2D, 0x63, 0x62, 0x63, 0x40, 0x6C, 0x79, 0x73, 0x61, 59 | 0x74, 0x6F, 0x72, 0x2E, 0x6C, 0x69, 0x75, 0x2E, 0x73, 0x65, 0x00, 0x00, 0x00, 0xE9, 0x61, 0x65, 60 | 0x73, 0x31, 0x32, 0x38, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x31, 0x39, 0x32, 0x2D, 61 | 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 62 | 0x72, 0x63, 0x66, 0x6F, 0x75, 0x72, 0x32, 0x35, 0x36, 0x2C, 0x61, 0x72, 0x63, 0x66, 0x6F, 0x75, 63 | 0x72, 0x31, 0x32, 0x38, 0x2C, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x67, 0x63, 0x6D, 0x40, 64 | 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x61, 0x65, 0x73, 0x32, 65 | 0x35, 0x36, 0x2D, 0x67, 0x63, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 66 | 0x6F, 0x6D, 0x2C, 0x63, 0x68, 0x61, 0x63, 0x68, 0x61, 0x32, 0x30, 0x2D, 0x70, 0x6F, 0x6C, 0x79, 67 | 0x31, 0x33, 0x30, 0x35, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 68 | 0x2C, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x63, 0x62, 0x63, 0x2C, 0x33, 0x64, 0x65, 0x73, 69 | 0x2D, 0x63, 0x62, 0x63, 0x2C, 0x62, 0x6C, 0x6F, 0x77, 0x66, 0x69, 0x73, 0x68, 0x2D, 0x63, 0x62, 70 | 0x63, 0x2C, 0x63, 0x61, 0x73, 0x74, 0x31, 0x32, 0x38, 0x2D, 0x63, 0x62, 0x63, 0x2C, 0x61, 0x65, 71 | 0x73, 0x31, 0x39, 0x32, 0x2D, 0x63, 0x62, 0x63, 0x2C, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2D, 72 | 0x63, 0x62, 0x63, 0x2C, 0x61, 0x72, 0x63, 0x66, 0x6F, 0x75, 0x72, 0x2C, 0x72, 0x69, 0x6A, 0x6E, 73 | 0x64, 0x61, 0x65, 0x6C, 0x2D, 0x63, 0x62, 0x63, 0x40, 0x6C, 0x79, 0x73, 0x61, 0x74, 0x6F, 0x72, 74 | 0x2E, 0x6C, 0x69, 0x75, 0x2E, 0x73, 0x65, 0x00, 0x00, 0x01, 0x92, 0x68, 0x6D, 0x61, 0x63, 0x2D, 75 | 0x6D, 0x64, 0x35, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 76 | 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x31, 0x2D, 0x65, 0x74, 77 | 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 78 | 0x61, 0x63, 0x2D, 0x36, 0x34, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 79 | 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x31, 0x32, 0x38, 0x2D, 0x65, 80 | 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 81 | 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 0x35, 0x36, 0x2D, 0x65, 0x74, 0x6D, 82 | 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 83 | 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x35, 0x31, 0x32, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 84 | 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 85 | 0x72, 0x69, 0x70, 0x65, 0x6D, 0x64, 0x31, 0x36, 0x30, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 86 | 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 87 | 0x68, 0x61, 0x31, 0x2D, 0x39, 0x36, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 88 | 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x6D, 0x64, 0x35, 0x2D, 89 | 0x39, 0x36, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 90 | 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x6D, 0x64, 0x35, 0x2C, 0x68, 0x6D, 0x61, 0x63, 91 | 0x2D, 0x73, 0x68, 0x61, 0x31, 0x2C, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x36, 0x34, 0x40, 0x6F, 0x70, 92 | 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x31, 93 | 0x32, 0x38, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 94 | 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 0x35, 0x36, 0x2C, 0x68, 0x6D, 0x61, 95 | 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x35, 0x31, 0x32, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 96 | 0x72, 0x69, 0x70, 0x65, 0x6D, 0x64, 0x31, 0x36, 0x30, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x72, 97 | 0x69, 0x70, 0x65, 0x6D, 0x64, 0x31, 0x36, 0x30, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 98 | 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x31, 0x2D, 0x39, 99 | 0x36, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x6D, 0x64, 0x35, 0x2D, 0x39, 0x36, 0x00, 0x00, 0x01, 100 | 0x92, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x6D, 0x64, 0x35, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 101 | 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 102 | 0x68, 0x61, 0x31, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 103 | 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x36, 0x34, 0x2D, 0x65, 0x74, 0x6D, 0x40, 104 | 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 0x61, 0x63, 105 | 0x2D, 0x31, 0x32, 0x38, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 106 | 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 107 | 0x35, 0x36, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 108 | 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x35, 0x31, 0x32, 109 | 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 110 | 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x72, 0x69, 0x70, 0x65, 0x6D, 0x64, 0x31, 0x36, 0x30, 0x2D, 111 | 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 112 | 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x31, 0x2D, 0x39, 0x36, 0x2D, 0x65, 0x74, 0x6D, 113 | 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 114 | 0x63, 0x2D, 0x6D, 0x64, 0x35, 0x2D, 0x39, 0x36, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 115 | 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x6D, 0x64, 116 | 0x35, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x31, 0x2C, 0x75, 0x6D, 0x61, 0x63, 117 | 0x2D, 0x36, 0x34, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 118 | 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x31, 0x32, 0x38, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 119 | 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 120 | 0x35, 0x36, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x35, 0x31, 0x32, 121 | 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x72, 0x69, 0x70, 0x65, 0x6D, 0x64, 0x31, 0x36, 0x30, 0x2C, 122 | 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x72, 0x69, 0x70, 0x65, 0x6D, 0x64, 0x31, 0x36, 0x30, 0x40, 0x6F, 123 | 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 124 | 0x73, 0x68, 0x61, 0x31, 0x2D, 0x39, 0x36, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x6D, 0x64, 0x35, 125 | 0x2D, 0x39, 0x36, 0x00, 0x00, 0x00, 0x1A, 0x7A, 0x6C, 0x69, 0x62, 0x40, 0x6F, 0x70, 0x65, 0x6E, 126 | 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x7A, 0x6C, 0x69, 0x62, 0x2C, 0x6E, 0x6F, 0x6E, 127 | 0x65, 0x00, 0x00, 0x00, 0x1A, 0x7A, 0x6C, 0x69, 0x62, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 128 | 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x7A, 0x6C, 0x69, 0x62, 0x2C, 0x6E, 0x6F, 0x6E, 0x65, 0x00, 129 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 130 | }; 131 | 132 | /*static unsigned char client_dh[48] = { 133 | 0x00, 0x00, 0x00, 0x2C, 0x06, 0x1E, 0x00, 0x00, 0x00, 0x20, 0xDD, 0xDB, 0x1F, 0x6D, 0x4E, 0xC1, 134 | 0xAF, 0xBF, 0x01, 0x84, 0x9E, 0xA1, 0x4E, 0xF3, 0x81, 0x15, 0x99, 0x4E, 0x3B, 0x15, 0x18, 0x34, 135 | 0xD7, 0x15, 0xCA, 0x0D, 0x30, 0x8A, 0x0F, 0x49, 0x5F, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 136 | };*/ 137 | 138 | /*static unsigned char client_dh[80] = { 139 | 0x00, 0x00, 0x00, 0x4C, 0x05, 0x1E, 0x00, 0x00, 0x00, 0x41, 0x04, 0x3D, 0xE6, 0x95, 0x83, 0x2C, 140 | 0x1D, 0x83, 0x42, 0x6D, 0x4B, 0xCB, 0x09, 0x8C, 0xEE, 0xF6, 0x87, 0xF3, 0x4F, 0xAD, 0x89, 0xC3, 141 | 0x94, 0x89, 0x47, 0x6E, 0x60, 0x26, 0xC4, 0x19, 0xB9, 0x43, 0x40, 0x6B, 0xCC, 0x5B, 0x9C, 0x72, 142 | 0xBC, 0x01, 0x74, 0x0B, 0x37, 0x7E, 0x0B, 0xFA, 0x9F, 0xE6, 0x19, 0x88, 0x47, 0x57, 0x84, 0x34, 143 | 0x4B, 0x07, 0xE7, 0xA0, 0x42, 0x26, 0x08, 0x91, 0x47, 0x7F, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00 144 | };*/ 145 | 146 | static unsigned char client_dh[80] = { 147 | 0x00, 0x00, 0x00, 0x4C, 0x05, 0x1E, 0x00, 0x00, 0x00, 0x41, 0x04, 0x4A, 0x57, 0x2B, 0x2F, 0xA8, 148 | 0x30, 0xD4, 0x02, 0x92, 0x5F, 0x3E, 0xE6, 0x9F, 0x1F, 0xE6, 0x69, 0x67, 0x20, 0x58, 0x38, 0x38, 149 | 0x76, 0xD9, 0xA8, 0x3E, 0x32, 0x6B, 0xAD, 0xED, 0xBC, 0xBF, 0x0D, 0x9C, 0xAE, 0xBC, 0xAE, 0xBB, 150 | 0xCE, 0xB6, 0x96, 0xD4, 0x03, 0xB1, 0x04, 0x00, 0xA7, 0x16, 0xA9, 0x5D, 0x75, 0x66, 0x44, 0x5B, 151 | 0x6B, 0x8F, 0x63, 0x67, 0x08, 0x06, 0x47, 0xB6, 0x9C, 0x69, 0x6A, 0x00, 0x00, 0x00, 0x00, 0x00 152 | }; 153 | 154 | class SSHAnswer 155 | { 156 | public: 157 | SSHAnswer() { } 158 | SSHAnswer(SSHAnswer const& o): 159 | _next(o._next) 160 | { } 161 | public: 162 | SSHAnswer& next(ns::Lvl4DataAction const& n) { _next = n; return *this; } 163 | 164 | public: 165 | bool operator()(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&, unsigned char* buf, uint32_t size) const 166 | { 167 | if (!_next) { 168 | return false; 169 | } 170 | // TODO: check lengths from RFC 171 | uint32_t len = ntohl(*((uint32_t*)(buf))); 172 | uint8_t padding = buf[4]; 173 | len += padding; 174 | if (len <= 7) { 175 | return false; 176 | } 177 | len -= 7; 178 | ns::Lvl4DataAction next = _next; 179 | lvl4sm.set_trigger(len, 180 | [next](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) 181 | { 182 | return next(t, lvl4sm, hsm, buf, size); 183 | }); 184 | return true; 185 | } 186 | 187 | private: 188 | ns::Lvl4DataAction _next; 189 | }; 190 | 191 | class SSHGetCertificate 192 | { 193 | public: 194 | SSHGetCertificate& on_certificate(ns::Lvl4DataAction const& a) { _cb_certif = a; return *this; } 195 | SSHGetCertificate& on_invalid_answer(ns::Lvl4DataAction const& a) { _cb_invalid = a; return *this; } 196 | 197 | public: 198 | bool operator()(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) const 199 | { 200 | if (size < 1) { 201 | return call_cb(_cb_invalid, t, lvl4sm, hsm, buf, size); 202 | } 203 | if (buf[0] != 0x1f) { // DF reply 204 | return call_cb(_cb_invalid, t, lvl4sm, hsm, buf, size); 205 | } 206 | size--; 207 | buf++; 208 | if (size < 4) { 209 | return call_cb(_cb_invalid, t, lvl4sm, hsm, buf, size); 210 | } 211 | size -= 4; 212 | uint32_t len = ntohl(*((uint32_t*)buf)); 213 | buf += 4; 214 | if (size < len) { 215 | return call_cb(_cb_invalid, t, lvl4sm, hsm, buf, size); 216 | } 217 | 218 | if (_cb_certif) { 219 | return _cb_certif(t, lvl4sm, hsm, buf, size); 220 | } 221 | 222 | return false; 223 | } 224 | 225 | private: 226 | template 227 | static bool call_cb(ns::Lvl4DataAction const& action, Args && ... args) 228 | { 229 | if (action) { 230 | return action(std::forward(args)...); 231 | } 232 | return def; 233 | } 234 | 235 | private: 236 | ns::Lvl4DataAction _cb_certif; 237 | ns::Lvl4DataAction _cb_invalid; 238 | }; 239 | 240 | bool nsp::SSH::operator()(ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&) const 241 | { 242 | t.send("SSH-2.0-OpenSSH_6.6.1p1 my-little-poney\r\n"); 243 | Lvl4DataAction cb_certif = _cb_certif; 244 | Lvl4DataAction cb_invalid = _cb_invalid; 245 | lvl4sm.set_trigger('\n', 246 | [cb_certif,cb_invalid](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm, unsigned char* buf, uint32_t size) 247 | { 248 | if (size < 7) { 249 | return call_cb(cb_invalid, t, lvl4sm, hsm, buf, size); 250 | } 251 | if (memcmp(buf, "SSH-2.0", 7) != 0) { 252 | return call_cb(cb_invalid, t, lvl4sm, hsm, buf, size); 253 | } 254 | t.send(client_key_exchange, sizeof(client_key_exchange)); 255 | t.send(client_dh, sizeof(client_dh)); 256 | lvl4sm.set_trigger 257 | (5, SSHAnswer().next( 258 | [cb_certif,cb_invalid](ns::ConnectedTarget const& t, ns::Lvl4SM& lvl4sm, ns::HostSM&, unsigned char* buf, uint32_t size) 259 | { 260 | lvl4sm.set_trigger(5, 261 | SSHAnswer().next 262 | ( 263 | SSHGetCertificate().on_certificate(cb_certif) 264 | .on_invalid_answer(cb_invalid) 265 | ) 266 | ); 267 | return true; 268 | } 269 | ) 270 | ); 271 | return true; 272 | } 273 | ); 274 | return true; 275 | } 276 | -------------------------------------------------------------------------------- /bindings/python/pynodescan.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Quarkslab 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * * Neither the name of the {organization} nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | 45 | namespace nsp = ns::protocols; 46 | 47 | using namespace boost::python; 48 | 49 | static object object_from_ro_mem(const unsigned char* buf, size_t n) 50 | { 51 | if (buf == nullptr) { 52 | buf = (const unsigned char*) ""; 53 | n = 0; 54 | } 55 | #if PY_VERSION_HEX < 0x03000000 56 | return boost::python::object(boost::python::handle<>(PyBuffer_FromReadWriteMemory((void*) buf, n))); 57 | #else 58 | #if PY_VERSION_HEX < 0x03030000 59 | Py_buffer buffer; 60 | int res = PyBuffer_FillInfo(&buffer, 0, (void*) buf, n, true, PyBUF_CONTIG_RO); 61 | if (res == -1) { 62 | PyErr_Print(); 63 | return boost::python::object(); 64 | } 65 | return boost::python::object(boost::python::handle<>(PyMemoryView_FromBuffer(&buffer))); 66 | #else 67 | return boost::python::object(boost::python::handle<>(PyMemoryView_FromMemory((char*) buf, n, PyBUF_READ))); 68 | #endif 69 | #endif 70 | } 71 | 72 | struct NSTargetSetWrap: ns::TargetSet, wrapper 73 | { 74 | virtual void init() override 75 | { this->get_override("init")(); } 76 | 77 | virtual void init_shrd(uint32_t shrd_idx, uint32_t shrd_count) override 78 | { this->get_override("init_shrd")(shrd_idx, shrd_count); } 79 | 80 | virtual void save_state(const char* file) override 81 | { this->get_override("save_state")(file); } 82 | 83 | 84 | virtual void restore_state(const char* file) override 85 | { this->get_override("restore_state")(file); } 86 | 87 | virtual void save_state(std::ostream&) override 88 | { } 89 | 90 | virtual void restore_state(std::istream&) override 91 | { } 92 | 93 | virtual ns::Target next_target() 94 | { return this->get_override("next_target")(); } 95 | 96 | virtual bool target_finished(ns::Target const& target, ns::HostSM& hsm) 97 | { return this->get_override("target_finished")(target, hsm); } 98 | }; 99 | 100 | static void connected_target_send(ns::ConnectedTarget const& t, std::string const& s) 101 | { 102 | t.send((unsigned char*) s.c_str(), s.size()); 103 | } 104 | 105 | static void async_engine_set_lvl4_connected_callback(ns::AsyncEngine& e, boost::python::object const& f) 106 | { 107 | e.set_lvl4_connected_callback( 108 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm, ns::HostSM& hsm) -> bool 109 | { 110 | return extract(f(target, boost::ref(lvl4sm), boost::ref(hsm))); 111 | }); 112 | } 113 | 114 | static void async_engine_set_lvl4_finish_callback(ns::AsyncEngine& e, boost::python::object const& f) 115 | { 116 | e.set_lvl4_finish_callback( 117 | [f](ns::Target const& target, const unsigned char* buf, size_t size, int code) -> bool 118 | { 119 | return extract(f(target, object_from_ro_mem(buf, size), code)); 120 | }); 121 | } 122 | 123 | static void async_engine_set_status_display_callback(ns::AsyncEngine& e, boost::python::object const& f, uint32_t timeout) 124 | { 125 | e.set_status_display_callback( 126 | [f](uint32_t nlaunched, uint32_t ndone) 127 | { 128 | f(nlaunched, ndone); 129 | }, 130 | timeout); 131 | } 132 | 133 | static void async_engine_set_watch_timeout(ns::AsyncEngine& e, boost::python::object const& f, uint32_t const timeout) 134 | { 135 | e.set_watch_timeout( 136 | [f](ns::ConnectedTarget const& t) -> bool 137 | { 138 | return extract(f(t)); 139 | }, 140 | timeout); 141 | } 142 | 143 | static void async_engine_set_timeout_of_target(ns::AsyncEngine& e, boost::python::object const& f) 144 | { 145 | e.set_timeout_of_target( 146 | [f](ns::Target const& t) -> uint32_t 147 | { 148 | return extract(f(t)); 149 | }); 150 | } 151 | 152 | void lvl4sm_set_char_data_trigger(ns::Lvl4SM& lvl4sm, std::string const& c, boost::python::object const& f) 153 | { 154 | if (c.size() != 1) { 155 | PyErr_SetString(PyExc_ValueError, "string must contain only one character"); 156 | throw_error_already_set(); 157 | } 158 | lvl4sm.set_trigger(c[0], 159 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm_, ns::HostSM& hsm, unsigned char* buf, uint32_t size) -> bool 160 | { 161 | return extract(f(target, boost::ref(lvl4sm_), boost::ref(hsm), object_from_ro_mem(buf, size))); 162 | }); 163 | } 164 | 165 | void lvl4sm_set_size_data_trigger(ns::Lvl4SM& lvl4sm, size_t const n, boost::python::object const& f) 166 | { 167 | lvl4sm.set_trigger(n, 168 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm_, ns::HostSM& hsm, unsigned char* buf, uint32_t size) -> bool 169 | { 170 | return extract(f(target, boost::ref(lvl4sm_), boost::ref(hsm), object_from_ro_mem(buf, size))); 171 | }); 172 | } 173 | 174 | void lvl4sm_set_on_connect(ns::Lvl4SM& lvl4sm, boost::python::object const& f) 175 | { 176 | lvl4sm.set_on_connect( 177 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm_, ns::HostSM& hsm) -> bool 178 | { 179 | return extract(f(target, boost::ref(lvl4sm_), boost::ref(hsm))); 180 | }); 181 | } 182 | 183 | void lvl4sm_set_python_data_trigger(ns::Lvl4SM& lvl4sm, boost::python::object const& obj) 184 | { 185 | lvl4sm.set_trigger(obj); 186 | } 187 | 188 | boost::python::object lvl4buffer_data(ns::Lvl4Buffer& buf) 189 | { 190 | return object_from_ro_mem(buf.begin(), buf.size()); 191 | } 192 | 193 | 194 | typedef ns::Lvl4PropertiesStorage Lvl4PythonPropertiesStorage; 195 | 196 | object& python_properties_storage_get(Lvl4PythonPropertiesStorage& s, ns::ConnectedTarget const& t) 197 | { 198 | return s[t]; 199 | } 200 | 201 | void python_properties_storage_set(Lvl4PythonPropertiesStorage& s, ns::Target const& t, boost::python::object const& o) 202 | { 203 | s[t] = o; 204 | } 205 | 206 | void python_properties_storage_remove(Lvl4PythonPropertiesStorage& s, ns::ConnectedTarget const& t) 207 | { 208 | s.remove(t); 209 | } 210 | 211 | boost::shared_ptr python_properties_init(object const& type) 212 | { 213 | return boost::shared_ptr(new Lvl4PythonPropertiesStorage([type] { return type(); })); 214 | } 215 | 216 | void (ns::AsyncEngine::*async_engine_save_state)(const char* file) = &ns::AsyncEngine::save_state; 217 | void (ns::AsyncEngine::*async_engine_restore_state)(const char* file) = &ns::AsyncEngine::restore_state; 218 | 219 | //void (ns::TargetSet::*target_set_save_state)(const char* file) = &NSTargetSetWrap::save_state; 220 | //void (ns::TargetSet::*target_set_restore_state)(const char* file) = &ns::TargetSet::restore_state; 221 | 222 | struct PythonProtocols 223 | { }; 224 | 225 | nsp::SSL& ssl_on_certificate(nsp::SSL& ssl, object const& f) 226 | { 227 | return ssl.on_certificate( 228 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm_, ns::HostSM& hsm, unsigned char* buf, uint32_t size) -> bool 229 | { 230 | return extract(f(target, boost::ref(lvl4sm_), boost::ref(hsm), object_from_ro_mem(buf, size))); 231 | }); 232 | } 233 | 234 | nsp::SSL& ssl_on_cipher(nsp::SSL& ssl, object const& f) 235 | { 236 | return ssl.on_cipher( 237 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm_, ns::HostSM& hsm, uint16_t cipher) -> bool 238 | { 239 | return extract(f(target, boost::ref(lvl4sm_), boost::ref(hsm), cipher)); 240 | }); 241 | } 242 | 243 | nsp::SSL& ssl_on_protocol_failure(nsp::SSL& ssl, object const& f) 244 | { 245 | return ssl.on_protocol_failure( 246 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm_, ns::HostSM& hsm, unsigned char* buf, uint32_t size) -> bool 247 | { 248 | return extract(f(target, boost::ref(lvl4sm_), boost::ref(hsm), object_from_ro_mem(buf, size))); 249 | }); 250 | } 251 | 252 | nsp::SSH& ssh_on_invalid_answer(nsp::SSH& ssh, object const& f) 253 | { 254 | return ssh.on_invalid_answer( 255 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm_, ns::HostSM& hsm, unsigned char* buf, uint32_t size) -> bool 256 | { 257 | return extract(f(target, boost::ref(lvl4sm_), boost::ref(hsm), object_from_ro_mem(buf, size))); 258 | }); 259 | } 260 | 261 | nsp::SSH& ssh_on_certificate(nsp::SSH& ssh, object const& f) 262 | { 263 | return ssh.on_certificate( 264 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm_, ns::HostSM& hsm, unsigned char* buf, uint32_t size) -> bool 265 | { 266 | return extract(f(target, boost::ref(lvl4sm_), boost::ref(hsm), object_from_ro_mem(buf, size))); 267 | }); 268 | } 269 | 270 | nsp::SIP& sip_on_header(nsp::SIP& sip, object const& f) 271 | { 272 | return sip.on_header( 273 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm_, ns::HostSM& hsm, const char* key, const char* value) -> bool 274 | { 275 | return extract(f(target, boost::ref(lvl4sm_), boost::ref(hsm), key, value)); 276 | }); 277 | } 278 | 279 | nsp::SIP& sip_on_invalid_header(nsp::SIP& sip, object const& f) 280 | { 281 | return sip.on_invalid_header( 282 | [f](ns::ConnectedTarget const& target, ns::Lvl4SM& lvl4sm_, ns::HostSM& hsm, unsigned char* buf, uint32_t size) -> bool 283 | { 284 | return extract(f(target, boost::ref(lvl4sm_), boost::ref(hsm), object_from_ro_mem(buf, size))); 285 | }); 286 | } 287 | 288 | typedef ns::RepeatableTargetSet RepeatableIPV4TargetSet; 289 | 290 | uint64_t target_hash(ns::Target const& t) 291 | { 292 | return ((uint64_t) t.ipv4()) | (((uint64_t)(t.port().as_u32()))<<32); 293 | } 294 | 295 | typedef ns::RepeatableTargetSet RepeatableSimpleTargetSet; 296 | typedef ns::ReinjectableTargetSet ReinjectableTargetStdin; 297 | 298 | BOOST_PYTHON_MODULE(pynodescan) 299 | { 300 | class_("TargetSet") 301 | .def("init", pure_virtual(&ns::TargetSet::init)) 302 | .def("init_shrd", pure_virtual(&ns::TargetSet::init_shrd)) 303 | .def("next_target", pure_virtual(&ns::TargetSet::next_target)) 304 | .def("target_finished", pure_virtual(&ns::TargetSet::target_finished)) 305 | //.def("save_state", &target_set_save_state) 306 | //.def("restore_state", &target_set_restore_state) 307 | ; 308 | 309 | class_>("IPV4TargetSet", 310 | init(args("ips", "ports"))) 311 | ; 312 | 313 | class_>("RepeatableIPV4TargetSet", 314 | init(args("ips", "ports"))) 315 | ; 316 | 317 | class_>("SimpleTargetSet") 318 | .def("add_target", &ns::SimpleTargetSet::add_target) 319 | .def("remove_target", &ns::SimpleTargetSet::remove_target) 320 | ; 321 | 322 | class_>("RepeatableSimpleTargetSet") 323 | .def("add_target", &RepeatableSimpleTargetSet::add_target) 324 | .def("remove_target", &RepeatableSimpleTargetSet::remove_target) 325 | ; 326 | 327 | class_>("TargetStdin", 328 | init(args("def_port"), "Initialize a TargetStdin. def_port is the default port for read IP addresses")) 329 | ; 330 | 331 | class_>("ReinjectableTargetStdin", 332 | init(args("def_port"), "Initialize a ReinjectableTargetStdin. def_port is the default port for read IP addresses")) 333 | .def("add_target", &ReinjectableTargetStdin::add_target) 334 | ; 335 | 336 | class_("AsyncEngine", 337 | init(args("targets", "nsockets", "timeout"), "Initialize a new AsyncEngine, using a maximum of nsockets. timeouts is in seconds.")) 338 | .def("launch", &ns::AsyncEngine::launch) 339 | .def("launch_shrd", &ns::AsyncEngine::launch_shrd) 340 | .def("set_lvl4_connected_callback", &async_engine_set_lvl4_connected_callback) 341 | .def("set_lvl4_finish_callback", &async_engine_set_lvl4_finish_callback) 342 | .def("set_status_display_callback", async_engine_set_status_display_callback) 343 | .def("set_watch_timeout", async_engine_set_watch_timeout) 344 | .def("set_timeout_of_target", async_engine_set_timeout_of_target) 345 | .def("save_state", &ns::AsyncEngine::save_state) 346 | .def("restore_state", &ns::AsyncEngine::restore_state) 347 | .def("auto_save_state", &ns::AsyncEngine::auto_save_state) 348 | .def("ensure_available_sockets", &ns::AsyncEngine::ensure_available_sockets) 349 | ; 350 | 351 | class_("Target", 352 | init(args("ipv4", "port"), "Initialize a target object")) 353 | .def("ipv4", &ns::Target::ipv4) 354 | .def("port", &ns::Target::port) 355 | .def("port_value", &ns::Target::port_value) 356 | .def("port_protocol", &ns::Target::port_protocol) 357 | .def("is_end", &ns::Target::is_end) 358 | .def("__hash__", &target_hash) 359 | .def("__eq__", &ns::Target::operator==) 360 | ; 361 | 362 | class_("ConnectedTarget", 363 | init()) 364 | .def("send", &connected_target_send) 365 | .def("ipv4", &ns::ConnectedTarget::ipv4) 366 | .def("port", &ns::ConnectedTarget::port) 367 | .def("port_value", &ns::ConnectedTarget::port_value) 368 | .def("port_protocol", &ns::ConnectedTarget::port_protocol) 369 | .def("target", &ns::ConnectedTarget::target, return_value_policy()) 370 | ; 371 | 372 | class_("Lvl4SM") 373 | .def("set_reconnect", &ns::Lvl4SM::set_reconnect) 374 | .def("set_on_connect", lvl4sm_set_on_connect) 375 | .def("reconnect", &ns::Lvl4SM::reconnect) 376 | .def("set_char_data_trigger", lvl4sm_set_char_data_trigger) 377 | .def("set_size_data_trigger", lvl4sm_set_size_data_trigger) 378 | .def("set_data_trigger", lvl4sm_set_python_data_trigger) 379 | .def("remove_data_trigger", &ns::Lvl4SM::remove_data_trigger) 380 | ; 381 | 382 | class_("HostSM") 383 | ; 384 | 385 | class_("Lvl4Buffer") 386 | .def("data", &lvl4buffer_data) 387 | .def("pop_by", &ns::Lvl4Buffer::pop_by) 388 | ; 389 | 390 | class_>("Lvl4Properties", no_init) 391 | .def("__init__", make_constructor(python_properties_init)) 392 | .def("remove", &Lvl4PythonPropertiesStorage::remove) 393 | .def("remove", &python_properties_storage_remove) 394 | .def("__getitem__", &Lvl4PythonPropertiesStorage::properties_of, return_value_policy()) 395 | .def("__getitem__", &python_properties_storage_get, return_value_policy()) 396 | .def("__setitem__", &python_properties_storage_set) 397 | ; 398 | 399 | enum_("errors") 400 | .value("NS_TIMEOUT", ns::errors::NS_TIMEOUT) 401 | .value("WILL_RECONNECT", ns::errors::WILL_RECONNECT) 402 | ; 403 | 404 | scope protocols = class_("protocols"); 405 | 406 | class_("SSL") 407 | .def("__call__", &nsp::SSL::operator()) 408 | .def("on_certificate", &ssl_on_certificate, return_internal_reference<>()) 409 | .def("on_cipher", &ssl_on_cipher, return_internal_reference<>()) 410 | .def("on_protocol_failure", &ssl_on_protocol_failure, return_internal_reference<>()) 411 | ; 412 | 413 | class_("SSH") 414 | .def("__call__", &nsp::SSH::operator()) 415 | .def("on_certificate", &ssh_on_certificate, return_internal_reference<>()) 416 | .def("on_invalid_answer", &ssh_on_invalid_answer, return_internal_reference<>()) 417 | ; 418 | 419 | class_("SIP") 420 | .def("__call__", &nsp::SIP::operator()) 421 | .def("on_header", &sip_on_header, return_internal_reference<>()) 422 | .def("on_invalid_header", &sip_on_invalid_header, return_internal_reference<>()) 423 | ; 424 | } 425 | --------------------------------------------------------------------------------