csshnpd: add new package
authorChris Swan <[email protected]>
Wed, 21 May 2025 09:46:40 +0000 (10:46 +0100)
committerFlorian Eckert <[email protected]>
Mon, 23 Jun 2025 11:54:07 +0000 (13:54 +0200)
Maintainer: @cpswan
Compile tested: x86_64 (snapshot r29619)
Run tested: x86_64 (snapshot r29619)

Description:
A C daemon for NoPorts, which allows TCP connections to be
established without exposing ports to the Internet.

More details at: https://docs.noports.com/

Signed-off-by: Chris Swan <[email protected]>
net/csshnpd/Makefile [new file with mode: 0644]
net/csshnpd/files/at_enroll.sh [new file with mode: 0644]
net/csshnpd/files/csshnpd.config [new file with mode: 0644]
net/csshnpd/files/csshnpd.init [new file with mode: 0644]
net/csshnpd/test.sh [new file with mode: 0644]

diff --git a/net/csshnpd/Makefile b/net/csshnpd/Makefile
new file mode 100644 (file)
index 0000000..65b41a8
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2025 The Atsign Foundation
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=csshnpd
+PKG_VERSION:=1.0.12
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-c$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/atsign-foundation/noports/releases/download/c$(PKG_VERSION)
+PKG_HASH:=02990724a29cc5a879e1ed282699a8b12fdcc008a9ab3acbfc987cd2ecdab7e4
+
+PKG_MAINTAINER:=Chris Swan <[email protected]>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-c$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS += \
+       -S . \
+       -DATSDK_BUILD_TESTS="OFF" \
+       -DATSDK_MEMCHECK="OFF" \
+       -DBUILD_SHARED_AND_STATIC_LIBS="OFF" \
+       -DCMAKE_EXPORT_COMPILE_COMMANDS="OFF" \
+       -DCMAKE_INSTALL_PREFIX="${PKG_BUILD_DIR}/build/release-static/tmp-install-dir" \
+       -DENABLE_PROGRAMS="OFF" \
+       -DENABLE_TARGET_EXPORT="OFF" \
+       -DENABLE_TESTING="OFF" \
+       -DNOPORTS_ATSDK_PATH="deps/atsdk-src" \
+       -DNOPORTS_BUILD_TESTS="OFF" \
+       -DNOPORTS_USE_SHARED_LIBS="ON"
+
+define Package/csshnpd
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=SSH
+  DEPENDS:=+libmbedtls +cJSON
+  TITLE:=NoPorts Daemon
+  URL:=https://noports.com
+endef
+
+define Package/csshnpd/description
+  A small and portable daemon for NoPorts.
+endef
+
+define Package/csshnpd/conffiles
+/etc/config/sshnpd
+endef
+
+define Package/csshnpd/install 
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/sshnpd/sshnpd $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/sshnpd/at_activate $(1)/usr/bin/
+       $(INSTALL_BIN) ./files/at_enroll.sh $(1)/usr/bin/
+
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/csshnpd.config $(1)/etc/config/sshnpd
+       
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/csshnpd.init $(1)/etc/init.d/sshnpd
+endef
+
+$(eval $(call BuildPackage,csshnpd))
diff --git a/net/csshnpd/files/at_enroll.sh b/net/csshnpd/files/at_enroll.sh
new file mode 100644 (file)
index 0000000..4a9d1ae
--- /dev/null
@@ -0,0 +1,60 @@
+#!/bin/sh
+. /lib/functions.sh
+enroll_atsign() {
+       local section="$1"
+
+       config_get atsign "$section" "atsign"
+       if [ -z "$atsign" ]; then
+               echo "sshnpd: atsign must be configured in /etc/config/sshnpd"
+               return 1
+       fi
+
+       config_get device "$section" "device"
+       if [ -z "$device" ]; then
+               echo "sshnpd: device must be configured in /etc/config/sshnpd"
+               return 1
+       fi
+
+       config_get otp "$section" "otp"
+       if [ -z "$otp" ]; then
+               echo "sshnpd: otp must be configured in /etc/config/sshnpd"
+               return 1
+       fi
+
+       config_get user             "$section" user
+       if [ -z "$user" ]; then
+               user='root'
+       fi
+
+       config_get home             "$section" home
+       if [ -z "$home" ]; then
+               if [ "$user" = "root" ]; then
+                       home='/root'
+               else
+                       home="/home/${user}"
+               fi
+       fi
+
+       if [ ! -d "${home}/.atsign/keys" ]; then
+               mkdir -p "${home}/.atsign/keys"
+       fi
+
+       if [ -f "${home}/.atsign/keys/${atsign}_key.atKeys" ]; then
+               echo "sshnpd: atsign keys file already present, exiting enrollment"
+               return 1
+       fi
+
+       echo
+       echo "To activate this enrollment run the following command line on a"
+       echo "system where the ${atsign} key has been activated:"
+       echo
+       echo "at_activate approve -a ${atsign} --arx noports --drx ${device}"
+       echo
+
+       at_activate enroll -a ${atsign} -s ${otp} -p noports \
+               -k ${home}/.atsign/keys/${atsign}_key.atKeys -d ${device} \
+               -n "sshnp:rw,sshrvd:rw"
+
+}
+config_load sshnpd
+config_foreach enroll_atsign sshnpd
diff --git a/net/csshnpd/files/csshnpd.config b/net/csshnpd/files/csshnpd.config
new file mode 100644 (file)
index 0000000..7ec3f22
--- /dev/null
@@ -0,0 +1,7 @@
+config sshnpd
+       option atsign   '@atsign'
+       option manager  '@manager'
+       option device   'devicename'
+       option args     ''
+       option otp      ''
+       option enabled  '0'
diff --git a/net/csshnpd/files/csshnpd.init b/net/csshnpd/files/csshnpd.init
new file mode 100644 (file)
index 0000000..d093d15
--- /dev/null
@@ -0,0 +1,86 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2007-2011 OpenWrt.org
+
+USE_PROCD=1
+START=80
+
+start_instance() {
+       local section="$1"
+
+       config_get_bool enabled "$section" enabled 1
+       [ "$enabled" != "1" ] && return 0
+
+       config_get atsign "$section" atsign
+       if [ -z "$atsign" ]; then
+               echo "sshnpd: atsign for this device is mandatory"
+               return 1
+       fi
+
+       config_get manager "$section" manager
+       if [ -z "$manager" ]; then
+               echo "sshnpd: manager for this device is mandatory"
+               return 1
+       fi
+
+       config_get device "$section" device
+       if [ -z "$device" ]; then
+               echo "sshnpd: device name is mandatory"
+               return 1
+       fi
+
+       config_get user "$section" user
+       if [ -z "$user" ]; then
+               user='root'
+       fi
+
+       config_get home "$section" home
+       if [ -z "$home" ]; then
+        if [ "$user" = "root" ]; then
+                               home='/root'
+        else
+                               home="/home/${user}"
+        fi
+       fi
+
+       if [ ! -f "${home}/.atsign/keys/${atsign}_key.atKeys" ]; then
+               echo "sshnpd: WARNING atsign keys not found in default location"
+       fi
+
+       if [ ! -d "${home}/.ssh" ]; then
+               mkdir ${home}/.ssh
+               chmod 700 ${home}/.ssh
+       fi
+
+       if [ ! -f "${home}/.ssh/authorized_keys" ]; then
+               touch ${home}/.ssh/authorized_keys
+               chmod 600 ${home}/.ssh/authorized_keys
+       fi
+
+       config_get args "$section" args
+
+       config_get pidfile "$section" pidfile
+
+       procd_open_instance "$section"
+       procd_set_param stdout 1
+       procd_set_param stderr 1
+       procd_set_param env USER=${user} HOME=${home}
+       procd_set_param command /usr/bin/sshnpd -a ${atsign} -m ${manager} -d ${device} ${args}
+       procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
+       [ -n "$pidfile" ] && procd_set_param pidfile "$pidfile"
+
+       [ -n "$pidfile" ] && procd_append_param env "SSHNPD_PIDFILE=$pidfile"
+
+       procd_close_instance
+}
+
+start_service() {
+       local instance=$1
+
+       config_load 'sshnpd'
+
+       if [ -n "$instance" ]; then
+               start_instance "$1"
+       else
+               config_foreach start_instance 'sshnpd'
+       fi
+}
diff --git a/net/csshnpd/test.sh b/net/csshnpd/test.sh
new file mode 100644 (file)
index 0000000..f447d93
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+sshnpd --help | grep "$2"