/ src / main.cpp
main.cpp
  1  // SPDX-FileCopyrightText: Copyright (C) 2025 Marek Küthe <m.k@mk16.de>
  2  //
  3  // SPDX-License-Identifier: GPL-3.0-or-later
  4  
  5  #include <iostream>
  6  #include <span>
  7  #include <stdexcept>
  8  #include <cstdlib>
  9  #include <boost/asio.hpp>
 10  #include <boost/log/trivial.hpp>
 11  #include "capability_managment.hpp"
 12  #include "configuration.hpp"
 13  #include "landlock.hpp"
 14  #include "mping_sender.hpp"
 15  #include "seccomp.hpp"
 16  
 17  int main(int argc, char * argv[])
 18  {
 19      try
 20      {
 21  #ifdef HAVE_LIBCAPNG
 22          CapabilityManagment::check_for_capabilites();
 23          CapabilityManagment::lock();
 24          CapabilityManagment::drop_all_capabilies();
 25  #endif
 26  #ifdef HAVE_LANDLOCK
 27          const LandlockRuleset landlock_ruleset_init(
 28              LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_WRITE_FILE |
 29                  LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_TRUNCATE |
 30                  LANDLOCK_ACCESS_FS_READ_DIR | LANDLOCK_ACCESS_FS_REMOVE_DIR |
 31                  LANDLOCK_ACCESS_FS_REMOVE_FILE | LANDLOCK_ACCESS_FS_MAKE_CHAR |
 32                  LANDLOCK_ACCESS_FS_MAKE_DIR | LANDLOCK_ACCESS_FS_MAKE_REG |
 33                  LANDLOCK_ACCESS_FS_MAKE_SOCK | LANDLOCK_ACCESS_FS_MAKE_FIFO |
 34                  LANDLOCK_ACCESS_FS_MAKE_BLOCK | LANDLOCK_ACCESS_FS_MAKE_SYM |
 35                  LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_IOCTL_DEV,
 36              LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP,
 37              LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL);
 38      #ifdef HAVE_LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON
 39          landlock_ruleset_init.restrict_self(
 40              LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON);
 41      #else
 42          landlock_ruleset_init.restrict_self();
 43      #endif
 44  #endif
 45  #ifdef HAVE_SECCOMP
 46          const SeccompFilterContext seccomp_context(SCMP_ACT_ALLOW);
 47          // see also
 48          // https://lists.boost.org/archives/list/boost-users@lists.boost.org/thread/YJ5RTK25HLPFEZ3XVBBFQDJOSPIIOBNA/
 49          // and https://sourceforge.net/p/asio/mailman/message/59260797/
 50          // due to complexity use seccomp blacklist
 51          seccomp_context.kill_chown();
 52          seccomp_context.kill_clock();
 53          seccomp_context.kill_cpu_emulation();
 54          seccomp_context.kill_debug();
 55          seccomp_context.kill_others();
 56          seccomp_context.kill_ipc();
 57          seccomp_context.kill_keyring();
 58          seccomp_context.kill_memlock();
 59          seccomp_context.kill_module();
 60          seccomp_context.kill_obsolete();
 61          seccomp_context.kill_privileged();
 62          seccomp_context.kill_rawio();
 63          seccomp_context.kill_reboot();
 64          seccomp_context.kill_resources();
 65          seccomp_context.kill_setuid();
 66          seccomp_context.kill_swap();
 67          seccomp_context.kill_sync();
 68          seccomp_context.kill_system_service();
 69          seccomp_context.kill_signal();
 70          seccomp_context.load();
 71  #endif
 72  
 73          const auto args = std::span(argv, static_cast<std::size_t>(argc));
 74          const MPingSender::Configuration config(args);
 75  
 76          BOOST_LOG_TRIVIAL(info)
 77              << "Boost version (compile time): " << (BOOST_VERSION / 100'000)
 78              << "." << (BOOST_VERSION / 100 % 1000) << "."
 79              << (BOOST_VERSION % 100);
 80  
 81  #ifdef HAVE_LIBCAPNG
 82          BOOST_LOG_TRIVIAL(info) << "libcapng: true";
 83  #else
 84          BOOST_LOG_TRIVIAL(info) << "libcapng: false";
 85  #endif
 86  
 87  #ifdef HAVE_SECCOMP
 88          BOOST_LOG_TRIVIAL(info) << "seccomp: true";
 89          const auto * seccomp_ver = seccomp_version();
 90          BOOST_LOG_TRIVIAL(info)
 91              << "seccomp version (runtime): " << seccomp_ver->major << "."
 92              << seccomp_ver->minor << "." << seccomp_ver->micro;
 93  #else
 94          BOOST_LOG_TRIVIAL(info) << "seccomp: false";
 95  #endif
 96  
 97  #ifdef HAVE_LANDLOCK
 98          BOOST_LOG_TRIVIAL(info) << "Landlock: true";
 99          BOOST_LOG_TRIVIAL(info)
100              << "Landlock ABI version: " << LandlockRuleset::get_abi_version();
101  #else
102          BOOST_LOG_TRIVIAL(info) << "Landlock: false";
103  #endif
104  
105          boost::asio::io_context io;
106  
107          const std::function<void(boost::system::error_code)> error_handler =
108              [](boost::system::error_code)
109          {
110              throw std::runtime_error("Fatal error");
111          };
112          const MPingSender::Sender sender(io.get_executor(),
113                                           error_handler,
114                                           error_handler,
115                                           config.get_bind_address(),
116                                           config.get_bind_port(),
117                                           config.get_address(),
118                                           config.get_port(),
119                                           config.get_ttl(),
120                                           config.get_interface_name());
121  
122          io.run();
123      }
124      catch (const std::exception& e)
125      {
126          BOOST_LOG_TRIVIAL(fatal) << "Error: " << e.what() << std::endl
127                                   << "Exit program.";
128          std::exit(EXIT_FAILURE); // NOLINT(concurrency-mt-unsafe)
129      }
130      return EXIT_SUCCESS;
131  }