diff --git a/CMakeLists.txt b/CMakeLists.txt index f55d3eb..4112f3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,10 +12,16 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-result -Wreturn-type") +#-------Bootstrap contract------- + add_executable(bootstrap_contract bootstrap-contract/bootstrap_contract.cpp ) +#-------Sashimono Agent------- + +add_subdirectory(src/killswitch) + add_executable(sagent src/conf.cpp src/comm/comm_handler.cpp @@ -32,6 +38,7 @@ add_executable(sagent ) target_link_libraries(sagent + killswitch libsodium.a libboost_stacktrace_backtrace.a sqlite3 diff --git a/src/killswitch/CMakeLists.txt b/src/killswitch/CMakeLists.txt new file mode 100644 index 0000000..96f0463 --- /dev/null +++ b/src/killswitch/CMakeLists.txt @@ -0,0 +1,38 @@ +### +# Compile-time timestamping library +# + +# Adapted from https://github.com/kraiskil/cmake_timestamp +# This is only used for the Sashimono Agent kill switch. + +#CMake 3.12 made using OBJECT libraries much nicer, so we use that. +cmake_minimum_required(VERSION 3.12) + +# Set CMake variable BUILD_TIME to 'now'. This 'now' is the time +# when CMake is run, not when the target builder (e.g. make) is run. +string(TIMESTAMP BUILD_TIME "%s" UTC) + +# Compile the library that contains the global variables +add_library( killswitch OBJECT killswitch.c) +target_compile_definitions( + killswitch + PRIVATE -DBUILD_TIME="${BUILD_TIME}" +) +target_include_directories( killswitch + PUBLIC + $ +) + +#Add a dummy target that removes the CMake variable BUILD_TIME from CMake's cache. +#this forces CMake to be-rerun when we hit this target. +add_custom_target( + clear_cache + COMMAND ${CMAKE_COMMAND} -U BUILD_TIME ${CMAKE_BINARY_DIR} +) + +#Have the cache clearing be run before trying to build the killswitch library. +#This (I think) is the same as a PRE_BUILD custom_command. But PRE_BUILD is +#available for VS generators only, on others it is synonymous to PRE_LINK, +#i.e. "post compile" +add_dependencies(killswitch clear_cache) + diff --git a/src/killswitch/killswitch.c b/src/killswitch/killswitch.c new file mode 100644 index 0000000..883a007 --- /dev/null +++ b/src/killswitch/killswitch.c @@ -0,0 +1,25 @@ +#include +#include +#include + +// BUILD_TIME symbol is populated via CMAKE build. +const char *build_time_sec_str = BUILD_TIME; +uint64_t MAX_LIMIT_SEC = 60 * 24 * 3600; +uint64_t build_time_sec = 0; + +/** + * Returns true if kill switch is activated (allowed time has expired). + * Otherwise returns false (can keep using Sashimono Agent). + * @param epoch_ms Current time in epoch milliseconds. + */ +bool kill_switch(const uint64_t epoch_ms) +{ + if (build_time_sec == 0) + { + char *eptr; + build_time_sec = strtoull(build_time_sec_str, &eptr, 10); + } + + const uint64_t epoch_sec = epoch_ms / 1000; + return !(epoch_sec > build_time_sec && (epoch_sec - build_time_sec) <= MAX_LIMIT_SEC); +} \ No newline at end of file diff --git a/src/killswitch/killswitch.h b/src/killswitch/killswitch.h new file mode 100644 index 0000000..456c3b3 --- /dev/null +++ b/src/killswitch/killswitch.h @@ -0,0 +1,18 @@ +#ifndef KILLSWITCH_H +#define KILLSWITCH_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +bool kill_switch(const uint64_t epoch_ms); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/src/killswitch/readme.txt b/src/killswitch/readme.txt new file mode 100644 index 0000000..51f8ef5 --- /dev/null +++ b/src/killswitch/readme.txt @@ -0,0 +1,4 @@ +Based on https://github.com/kraiskil/cmake_timestamp + +This whole folder exists to get the CMAKE compile/link time into the binary so we can perform +Sashimono Agent time-based kill switch check. This folder must be removed when we no longer need the kill switch. diff --git a/src/main.cpp b/src/main.cpp index 62f6c49..238ac8f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,8 @@ #include "crypto.hpp" #include "hp_manager.hpp" #include "version.hpp" +#include "util/util.hpp" +#include "killswitch/killswitch.h" #define PARSE_ERROR \ { \ @@ -139,6 +141,12 @@ int main(int argc, char **argv) } else if (conf::ctx.command == "run") { + if (kill_switch(util::get_epoch_milliseconds())) + { + std::cerr << "Sashimono Agent usage limit failure.\n"; + return -1; + } + if (conf::init() != 0) return -1;