dnc: add systemd

Change-Id: I6cbf939f35ddbd4b72d30e2bf43ad59f5e6a6658
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7b1b1e3..74f6741 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,6 +13,9 @@
 set (exec_prefix "\${prefix}")
 set (libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
 set (includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
+set (bindir "${CMAKE_INSTALL_FULL_BINDIR}")
+set (sysconfdir "${CMAKE_INSTALL_FULL_SYSCONFDIR}")
+set (top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
 set (VERSION ${CMAKE_PROJECT_VERSION})
 
 option(DHTNET_PUPNP "Enable UPnP support" ON)
@@ -21,6 +24,9 @@
 option(BUILD_TOOLS "Build tools" ON)
 option(BUILD_BENCHMARKS "Build benchamrks" ON)
 option(BUILD_DEPENDENCIES "Build dependencies" ON)
+option(DNC_SYSTEMD "Enable dnc systemd integration" ON)
+option (DNC_SYSTEMD_UNIT_FILE_LOCATION "Where to install systemd unit file")
+
 
 if (NOT MSVC)
     set(DEPENDENCIES_PATH ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/install/${TARGET})
@@ -105,6 +111,30 @@
         -D_UNICODE")
 endif()
 
+if (DNC_SYSTEMD)
+    if (NOT DEFINED DNC_SYSTEMD_UNIT_FILE_LOCATION OR NOT DNC_SYSTEMD_UNIT_FILE_LOCATION)
+            execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} systemd --variable=systemdsystemunitdir
+                            OUTPUT_VARIABLE SYSTEMD_UNIT_INSTALL_DIR)
+            message("-- Using Systemd unit installation directory by pkg-config: " ${SYSTEMD_UNIT_INSTALL_DIR})
+        else()
+            message("-- Using Systemd unit installation directory requested: " ${DNC_SYSTEMD_UNIT_FILE_LOCATION})
+            set(SYSTEMD_UNIT_INSTALL_DIR ${DNC_SYSTEMD_UNIT_FILE_LOCATION})
+        endif()
+
+        configure_file (
+            tools/dnc/systemd/dnc.service.in
+            systemd/dnc.service
+            @ONLY
+        )
+        if (SYSTEMD_UNIT_INSTALL_DIR)
+            string(REGEX REPLACE "[ \t\n]+" "" SYSTEMD_UNIT_INSTALL_DIR "${SYSTEMD_UNIT_INSTALL_DIR}")
+            set (systemdunitdir "${SYSTEMD_UNIT_INSTALL_DIR}")
+            install (FILES ${CMAKE_CURRENT_BINARY_DIR}/systemd/dnc.service DESTINATION ${systemdunitdir})
+            install (FILES tools/dnc/dnc.yaml DESTINATION ${sysconfdir}/dhtnet/)
+        else()
+            message(WARNING "Systemd unit installation directory not found. The systemd unit won't be installed.")
+    endif()
+endif()
 # Sources
 list (APPEND dhtnet_SOURCES
     src/connectionmanager.cpp
@@ -322,4 +352,4 @@
     #add_executable(tests_stringutils tests/testString_utils.cpp)
     #target_link_libraries(tests_stringutils PRIVATE dhtnet fmt::fmt PkgConfig::Cppunit)
     #add_test(NAME tests_stringutils COMMAND tests_stringutils)
-endif()
+endif()
\ No newline at end of file
diff --git a/tools/dnc/systemd/dnc.service.in b/tools/dnc/systemd/dnc.service.in
new file mode 100644
index 0000000..dedcea4
--- /dev/null
+++ b/tools/dnc/systemd/dnc.service.in
@@ -0,0 +1,43 @@
+[Unit]
+Description=Dnc server
+Documentation=man:dnc(1)
+After=network.target
+
+[Service]
+Type=simple
+User=dnc
+Group=dnc
+ExecStart=@bindir@/dnc -l -d @sysconfdir@/dhtnet/dnc.yaml -c @sysconfdir@/dhtnet/id/id-server.crt -p @sysconfdir@/dhtnet/id/id-server.pem
+Restart=on-failure
+RestartSec=2s
+LimitNOFILE=65536
+DynamicUser=yes
+KillMode=process
+WorkingDirectory=/tmp
+
+# Hardening
+CapabilityBoundingSet=CAP_NET_BIND_SERVICE
+LockPersonality=yes
+NoNewPrivileges=yes
+PrivateDevices=yes
+PrivateTmp=yes
+PrivateUsers=yes
+ProtectClock=yes
+ProtectControlGroups=yes
+ProtectHome=yes
+ProtectHostname=yes
+ProtectKernelLogs=yes
+ProtectKernelModules=yes
+ProtectKernelTunables=yes
+ProtectSystem=strict
+ReadOnlyDirectories=/
+ReadWriteDirectories=-/proc/self
+ReadWriteDirectories=-/var/run
+RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+RestrictNamespaces=yes
+RestrictRealtime=yes
+SystemCallArchitectures=native
+SystemCallFilter=@system-service
+
+[Install]
+WantedBy=multi-user.target