mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
sshmngr: configurable backend
Make the backend daemon configurable, please note, still need to disable dropbear as default in config and choose the backend based on config in sshmngr
This commit is contained in:
parent
8557dbc1a7
commit
1393125ceb
13 changed files with 387 additions and 1059 deletions
|
|
@ -8,12 +8,18 @@ choice
|
||||||
|
|
||||||
config SSHMNGR_BACKEND_OPENSSH
|
config SSHMNGR_BACKEND_OPENSSH
|
||||||
bool "Use openssh for ssh"
|
bool "Use openssh for ssh"
|
||||||
|
help
|
||||||
|
Enable this option to use openssh for ssh.
|
||||||
|
|
||||||
config SSHMNGR_BACKEND_OPENSSH_PAM
|
config SSHMNGR_BACKEND_OPENSSH_PAM
|
||||||
bool "Use openssh with PAM for ssh"
|
bool "Use openssh with PAM for ssh"
|
||||||
|
help
|
||||||
|
Enable this option to use PAM for ssh.
|
||||||
|
|
||||||
config SSHMNGR_BACKEND_DROPBEAR
|
config SSHMNGR_BACKEND_DROPBEAR
|
||||||
bool "Use dropbear for ssh"
|
bool "Use dropbear for ssh"
|
||||||
|
help
|
||||||
|
Enable this option to use dropbear for ssh.
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
|
|
@ -7,33 +7,31 @@ include $(TOPDIR)/rules.mk
|
||||||
PKG_NAME:=sshmngr
|
PKG_NAME:=sshmngr
|
||||||
PKG_VERSION:=1.0.0
|
PKG_VERSION:=1.0.0
|
||||||
|
|
||||||
|
LOCAL_DEV:=0
|
||||||
|
ifneq ($(LOCAL_DEV),1)
|
||||||
|
PKG_SOURCE_PROTO:=git
|
||||||
|
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/sshmngr.git
|
||||||
|
PKG_SOURCE_VERSION:=9758a7a0f798ad2b19597f4ec161e82edbdb2753
|
||||||
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||||
|
PKG_MIRROR_HASH:=skip
|
||||||
|
endif
|
||||||
|
|
||||||
PKG_LICENSE:=BSD-3-Clause
|
PKG_LICENSE:=BSD-3-Clause
|
||||||
PKG_LICENSE_FILES:=LICENSE
|
PKG_LICENSE_FILES:=LICENSE
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
include ../bbfdm/bbfdm.mk
|
include ../bbfdm/bbfdm.mk
|
||||||
|
|
||||||
BACKEND:=+dropbear
|
MAKE_PATH:=src
|
||||||
|
|
||||||
ifeq ($(CONFIG_SSHMNGR_BACKEND_OPENSSH),y)
|
|
||||||
BACKEND:=+openssh-server +openssh-client-utils
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_SSHMNGR_BACKEND_OPENSSH_PAM),y)
|
|
||||||
BACKEND:=+openssh-server-pam +openssh-client-utils
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_SSHMNGR_BACKEND_DROPBEAR),y)
|
|
||||||
BACKEND:=+dropbear
|
|
||||||
endif
|
|
||||||
$(info "BACKEND IS:")
|
|
||||||
$(info $(BACKEND))
|
|
||||||
|
|
||||||
define Package/sshmngr
|
define Package/sshmngr
|
||||||
SECTION:=utils
|
SECTION:=net
|
||||||
CATEGORY:=Utilities
|
CATEGORY:=Network
|
||||||
SUBMENU:=TRx69
|
|
||||||
TITLE:=Package to add Device.SSH data model support.
|
TITLE:=Package to add Device.SSH data model support.
|
||||||
DEPENDS:=$(BACKEND) +libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api
|
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api
|
||||||
$(info $(DEPENDS))
|
DEPENDS+=+SSHMNGR_BACKEND_OPENSSH:openssh-server +SSHMNGR_BACKEND_OPENSSH:openssh-client-utils
|
||||||
|
DEPENDS+=+SSHMNGR_BACKEND_OPENSSH_PAM:openssh-server-pam +SSHMNGR_BACKEND_OPENSSH_PAM:openssh-client-utils
|
||||||
|
DEPENDS+=+SSHMNGR_BACKEND_DROPBEAR:dropbear
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/sshmngr/description
|
define Package/sshmngr/description
|
||||||
|
|
@ -44,10 +42,21 @@ define Package/$(PKG_NAME)/config
|
||||||
source "$(SOURCE)/Config.in"
|
source "$(SOURCE)/Config.in"
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
ifeq ($(LOCAL_DEV),1)
|
||||||
|
define Build/Prepare
|
||||||
|
$(CP) -rf ./sshmngr/* $(PKG_BUILD_DIR)/
|
||||||
|
endef
|
||||||
|
endif
|
||||||
|
|
||||||
define Package/sshmngr/install
|
define Package/sshmngr/install
|
||||||
$(INSTALL_DIR) $(1)/etc/sshmngr
|
$(INSTALL_DIR) $(1)/etc/sshmngr
|
||||||
$(CP) ./files/* $(1)/
|
$(CP) ./files/common/* $(1)/
|
||||||
$(CP) $(PKG_BUILD_DIR)/libsshmngr.so $(1)/etc/sshmngr
|
ifeq ($(CONFIG_SSHMNGR_BACKEND_DROPBEAR),y)
|
||||||
|
$(CP) ./files/dropbear_backend/* $(1)/
|
||||||
|
else
|
||||||
|
$(CP) ./files/openssh_backend/* $(1)/
|
||||||
|
endif
|
||||||
|
$(CP) $(PKG_BUILD_DIR)/src/libsshmngr.so $(1)/etc/sshmngr
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call BuildPackage,sshmngr))
|
$(eval $(call BuildPackage,sshmngr))
|
||||||
|
|
|
||||||
6
sshmngr/files/common/etc/config/sshmngr
Normal file
6
sshmngr/files/common/etc/config/sshmngr
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
config server 'ssh1'
|
||||||
|
option enable '1'
|
||||||
|
option PasswordAuth '1'
|
||||||
|
option RootPasswordAuth '1'
|
||||||
|
option RootLogin '1'
|
||||||
|
option Port '22'
|
||||||
15
sshmngr/files/common/etc/init.d/sshmngr
Executable file
15
sshmngr/files/common/etc/init.d/sshmngr
Executable file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
|
||||||
|
START=18
|
||||||
|
USE_PROCD=1
|
||||||
|
|
||||||
|
. /lib/sshmngr/sshmngr.sh
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
start_sshmngr_service
|
||||||
|
}
|
||||||
|
|
||||||
|
service_triggers() {
|
||||||
|
configure_ssh
|
||||||
|
procd_add_reload_trigger sshmngr
|
||||||
|
}
|
||||||
71
sshmngr/files/common/lib/sshmngr/sshmngr.sh
Executable file
71
sshmngr/files/common/lib/sshmngr/sshmngr.sh
Executable file
|
|
@ -0,0 +1,71 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. /etc/bbfdm/bbfdm_services.sh
|
||||||
|
. /lib/sshmngr/backend.sh
|
||||||
|
|
||||||
|
SSHMNGR_JSON_INPUT="/etc/sshmngr/input.json"
|
||||||
|
TEMP_UCI_PATH="/tmp/sshmngr"
|
||||||
|
|
||||||
|
start_sshmngr_service()
|
||||||
|
{
|
||||||
|
bbfdm_add_service "bbfdm.sshmngr" "${SSHMNGR_JSON_INPUT}"
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_server_section()
|
||||||
|
{
|
||||||
|
local cfg="$1"
|
||||||
|
local enable
|
||||||
|
local PasswordAuth=""
|
||||||
|
local Port=""
|
||||||
|
local RootPasswordAuth=""
|
||||||
|
local RootLogin=""
|
||||||
|
local Interface=""
|
||||||
|
local SSHKeepAlive=""
|
||||||
|
local IdleTimeout=""
|
||||||
|
local MaxAuthTries=""
|
||||||
|
local ServerName="${cfg}"
|
||||||
|
|
||||||
|
config_get_bool enable $cfg enable 0
|
||||||
|
|
||||||
|
[ $enable -eq 0 ] && return
|
||||||
|
|
||||||
|
config_get PasswordAuth $cfg PasswordAuth
|
||||||
|
config_get Port $cfg Port
|
||||||
|
config_get RootPasswordAuth $cfg RootPasswordAuth
|
||||||
|
config_get RootLogin $cfg RootLogin
|
||||||
|
config_get Interface $cfg Interface
|
||||||
|
config_get SSHKeepAlive $cfg SSHKeepAlive
|
||||||
|
config_get IdleTimeout $cfg IdleTimeout
|
||||||
|
config_get MaxAuthTries $cfg MaxAuthTries
|
||||||
|
|
||||||
|
# add section
|
||||||
|
uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName=$CONFIG
|
||||||
|
|
||||||
|
# set options
|
||||||
|
[ -n "$PasswordAuth" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.PasswordAuth=$PasswordAuth
|
||||||
|
[ -n "$Port" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.Port=$Port
|
||||||
|
[ -n "$RootPasswordAuth" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.RootPasswordAuth=$RootPasswordAuth
|
||||||
|
[ -n "$RootLogin" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.RootLogin=$RootLogin
|
||||||
|
[ -n "$Interface" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.Interface=$Interface
|
||||||
|
[ -n "$SSHKeepAlive" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.SSHKeepAlive=$SSHKeepAlive
|
||||||
|
[ -n "$IdleTimeout" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.IdleTimeout=$IdleTimeout
|
||||||
|
[ -n "$MaxAuthTries" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.MaxAuthTries=$MaxAuthTries
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_ssh()
|
||||||
|
{
|
||||||
|
# remove temp UCI
|
||||||
|
rm -rf "$TEMP_UCI_PATH"/$CONFIG 2>/dev/null
|
||||||
|
mkdir -p "$TEMP_UCI_PATH"
|
||||||
|
touch "$TEMP_UCI_PATH"/$CONFIG
|
||||||
|
|
||||||
|
# read all sshmngr server sections and then apply them to $CONFIG UCI
|
||||||
|
config_load sshmngr
|
||||||
|
config_foreach handle_server_section server
|
||||||
|
|
||||||
|
uci -c "$TEMP_UCI_PATH" commit $CONFIG
|
||||||
|
|
||||||
|
cp "$TEMP_UCI_PATH"/$CONFIG /etc/config/$CONFIG
|
||||||
|
|
||||||
|
/etc/init.d/$CONFIG reload
|
||||||
|
}
|
||||||
222
sshmngr/files/common/usr/libexec/rpcd/sshmngr
Executable file
222
sshmngr/files/common/usr/libexec/rpcd/sshmngr
Executable file
|
|
@ -0,0 +1,222 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. /usr/share/libubox/jshn.sh
|
||||||
|
. /lib/sshmngr/backend.sh
|
||||||
|
|
||||||
|
TEMP_KEY_FILE="/tmp/tempkeyfile"
|
||||||
|
|
||||||
|
add_server_name()
|
||||||
|
{
|
||||||
|
local server_sec="${1}"
|
||||||
|
|
||||||
|
config_get_bool enable "${server_sec}" enable 0
|
||||||
|
if [ "${enable}" -eq 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
server_names="${server_names} ${server_sec}"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_all_servers()
|
||||||
|
{
|
||||||
|
server_names=""
|
||||||
|
|
||||||
|
config_load sshmngr
|
||||||
|
config_foreach add_server_name server
|
||||||
|
|
||||||
|
echo "${server_names}"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_pid()
|
||||||
|
{
|
||||||
|
local server_name="$1"
|
||||||
|
local pid_file="$(get_pid_file "$server_name")"
|
||||||
|
local server_pid=0
|
||||||
|
|
||||||
|
# if proper file exists
|
||||||
|
if [ -f "${pid_file}" ] && [ -s "${pid_file}" ]; then
|
||||||
|
server_pid="$(cat "${pid_file}")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$server_pid"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
list)
|
||||||
|
echo '{ "dump" : {"server_name":"string"}, "kill_session" : {"session_pid":"string","server_name":"string"}, "list_keys" : {}, "add_pubkey" : {"current_key":"string","new_key":"string"}, "remove_pubkey" : {"key":"string"} }'
|
||||||
|
;;
|
||||||
|
call)
|
||||||
|
case "$2" in
|
||||||
|
dump)
|
||||||
|
read -r input
|
||||||
|
json_load "${input}"
|
||||||
|
json_get_var server_name "server_name"
|
||||||
|
json_cleanup
|
||||||
|
|
||||||
|
if [ -z "$server_name" ]; then
|
||||||
|
servers="$(get_all_servers)"
|
||||||
|
else
|
||||||
|
servers="$server_name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
json_init
|
||||||
|
|
||||||
|
for server in $servers; do
|
||||||
|
json_add_object "$server"
|
||||||
|
|
||||||
|
pid_file="$(get_pid_file "$server")"
|
||||||
|
server_pid="$(get_pid "$server")"
|
||||||
|
|
||||||
|
if [ "$server_pid" -eq 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# get all current sessions
|
||||||
|
session_pids="$(get_session_pids "$pid_file")"
|
||||||
|
|
||||||
|
json_add_string "pid" "$server_pid"
|
||||||
|
json_add_array "sessions"
|
||||||
|
|
||||||
|
for session_pid in $session_pids; do
|
||||||
|
# if pid equals server pid then skip
|
||||||
|
[ "$session_pid" -eq "$server_pid" ] && continue
|
||||||
|
|
||||||
|
# get this session's ppid
|
||||||
|
session_ppid="$(grep PPid /proc/$session_pid/status | awk '{print $2}')"
|
||||||
|
|
||||||
|
# if session's parent is this server
|
||||||
|
if [ "$session_ppid" -eq "$server_pid" ]; then
|
||||||
|
session="$(netstat -ntp | grep $session_pid/ | awk '{print $5,$7}' | cut -d'/' -f 1)"
|
||||||
|
|
||||||
|
# return session IP, Port, PID
|
||||||
|
ip=$(echo "$session" | cut -d ':' -f 1)
|
||||||
|
port=$(echo "$session" | cut -d ':' -f 2 | cut -d ' ' -f 1)
|
||||||
|
pid=$(echo "$session" | cut -d ':' -f 2 | cut -d ' ' -f 2)
|
||||||
|
|
||||||
|
json_add_object
|
||||||
|
json_add_string "ip" "$ip"
|
||||||
|
json_add_string "port" "$port"
|
||||||
|
json_add_string "pid" "$pid"
|
||||||
|
json_close_object
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
json_close_array
|
||||||
|
json_close_object
|
||||||
|
done
|
||||||
|
|
||||||
|
json_dump
|
||||||
|
;;
|
||||||
|
|
||||||
|
kill_session)
|
||||||
|
read -r input
|
||||||
|
json_load "${input}"
|
||||||
|
json_get_var session_pid "session_pid"
|
||||||
|
json_get_var server_name "server_name"
|
||||||
|
json_cleanup
|
||||||
|
|
||||||
|
if [ "$session_pid" -gt 0 ]; then
|
||||||
|
kill -15 "$session_pid"
|
||||||
|
else
|
||||||
|
[ -n "$server_name" ] || return
|
||||||
|
|
||||||
|
# if server_name is present
|
||||||
|
# get all current sessions
|
||||||
|
pid_file="$(get_pid_file "$server_name")"
|
||||||
|
server_pid="$(get_pid "$server_name")"
|
||||||
|
|
||||||
|
if [ "$server_pid" -eq 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# get all current sessions
|
||||||
|
session_pids="$(get_session_pids "$pid_file")"
|
||||||
|
|
||||||
|
for session_pid in $session_pids; do
|
||||||
|
# if pid equals server pid then skip
|
||||||
|
[ "$session_pid" -eq "$server_pid" ] && continue
|
||||||
|
|
||||||
|
# get this session's ppid
|
||||||
|
session_ppid="$(grep PPid /proc/$session_pid/status | awk '{print $2}')"
|
||||||
|
|
||||||
|
# if session's parent is this server
|
||||||
|
if [ "$session_ppid" -eq "$server_pid" ]; then
|
||||||
|
kill -15 "$session_pid"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
list_keys)
|
||||||
|
# remove empty lines from file
|
||||||
|
sed -i '/^[[:space:]]*$/d' "$KEY_FILE"
|
||||||
|
|
||||||
|
json_init
|
||||||
|
json_add_array "keys"
|
||||||
|
|
||||||
|
while read line; do
|
||||||
|
json_add_string "key" "${line}"
|
||||||
|
done < "$KEY_FILE"
|
||||||
|
|
||||||
|
json_close_array
|
||||||
|
json_dump
|
||||||
|
;;
|
||||||
|
|
||||||
|
add_pubkey)
|
||||||
|
read -r input
|
||||||
|
json_load "${input}"
|
||||||
|
json_get_var current_key "current_key"
|
||||||
|
json_get_var new_key "new_key"
|
||||||
|
json_cleanup
|
||||||
|
|
||||||
|
if [ -n "${new_key}" ]; then
|
||||||
|
if [ -n "${current_key}" ]; then
|
||||||
|
rm -rf TEMP_KEY_FILE
|
||||||
|
touch TEMP_KEY_FILE
|
||||||
|
|
||||||
|
# sed -i "s/${current_key}/${new_key}/g" ${KEY_FILE}
|
||||||
|
# sed is not advisable because the separator ("/") or anything else
|
||||||
|
# can be present in the string
|
||||||
|
while read line; do
|
||||||
|
if [ "${line}" == "${current_key}" ]; then
|
||||||
|
echo "${new_key}" >> TEMP_KEY_FILE
|
||||||
|
else
|
||||||
|
echo "${line}" >> TEMP_KEY_FILE
|
||||||
|
fi
|
||||||
|
done < "$KEY_FILE"
|
||||||
|
|
||||||
|
mv TEMP_KEY_FILE "$KEY_FILE"
|
||||||
|
else
|
||||||
|
echo "${new_key}" >> ${KEY_FILE}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
remove_pubkey)
|
||||||
|
read -r input
|
||||||
|
json_load "${input}"
|
||||||
|
json_get_var key "key"
|
||||||
|
json_cleanup
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "${key}" ]; then
|
||||||
|
rm -rf TEMP_KEY_FILE
|
||||||
|
touch TEMP_KEY_FILE
|
||||||
|
|
||||||
|
# sed -i "/${key}/d" ${KEY_FILE}
|
||||||
|
# sed -i "s/${current_key}/${new_key}/g" ${KEY_FILE}
|
||||||
|
# sed is not advisable because the separator ("/") or anything else
|
||||||
|
# can be present in the string
|
||||||
|
while read line; do
|
||||||
|
if [ "${line}" != "${key}" ]; then
|
||||||
|
echo "${line}" >> TEMP_KEY_FILE
|
||||||
|
fi
|
||||||
|
done < "$KEY_FILE"
|
||||||
|
|
||||||
|
mv TEMP_KEY_FILE "$KEY_FILE"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
20
sshmngr/files/dropbear_backend/lib/sshmngr/backend.sh
Executable file
20
sshmngr/files/dropbear_backend/lib/sshmngr/backend.sh
Executable file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. /lib/functions.sh
|
||||||
|
|
||||||
|
KEY_FILE="/etc/dropbear/authorized_keys"
|
||||||
|
CONFIG="dropbear"
|
||||||
|
|
||||||
|
get_pid_file()
|
||||||
|
{
|
||||||
|
local ServerName="$1"
|
||||||
|
|
||||||
|
echo "/var/run/$CONFIG.$ServerName.pid"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_session_pids()
|
||||||
|
{
|
||||||
|
local PidFile="$1"
|
||||||
|
|
||||||
|
echo "$(ps -w | grep $PidFile | grep -v grep | awk '{print $1}')"
|
||||||
|
}
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/sh /etc/rc.common
|
|
||||||
|
|
||||||
START=18
|
|
||||||
USE_PROCD=1
|
|
||||||
|
|
||||||
. /etc/bbfdm/bbfdm_services.sh
|
|
||||||
|
|
||||||
SSHMNGR_JSON_INPUT="/etc/sshmngr/input.json"
|
|
||||||
|
|
||||||
start_service() {
|
|
||||||
bbfdm_add_service "bbfdm.sshmngr" "${SSHMNGR_JSON_INPUT}"
|
|
||||||
}
|
|
||||||
|
|
||||||
service_triggers() {
|
|
||||||
procd_add_reload_trigger sshmngr
|
|
||||||
}
|
|
||||||
18
sshmngr/files/openssh_backend/lib/sshmngr/backend.sh
Executable file
18
sshmngr/files/openssh_backend/lib/sshmngr/backend.sh
Executable file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. /lib/functions.sh
|
||||||
|
|
||||||
|
CONFIG="sshd"
|
||||||
|
KEY_FILE="/root/.ssh/authorized_keys"
|
||||||
|
|
||||||
|
get_pid_file()
|
||||||
|
{
|
||||||
|
local ServerName="$1"
|
||||||
|
|
||||||
|
echo "/var/run/$CONFIG.$ServerName.pid"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_session_pids()
|
||||||
|
{
|
||||||
|
echo "$(ps -w | grep sshd | grep pts | awk '{print $1}')"
|
||||||
|
}
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
LIB = libsshmngr.so
|
|
||||||
|
|
||||||
LIB_OBJS = sshmngr.o
|
|
||||||
|
|
||||||
PROG_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC
|
|
||||||
LIB_LDFLAGS = $(LDFLAGS)
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
$(CC) $(PROG_CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
all: $(LIB)
|
|
||||||
|
|
||||||
$(LIB): $(LIB_OBJS)
|
|
||||||
$(CC) $(PROG_CFLAGS) -shared -o $@ $^ $(LIB_LDFLAGS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.o $(LIB)
|
|
||||||
|
|
@ -1,982 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2023 iopsys Software Solutions AB
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License version 2.1
|
|
||||||
* as published by the Free Software Foundation
|
|
||||||
*
|
|
||||||
* Author Suvendhu Hansa <suvendhu.hansa@iopsys.eu>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sshmngr.h"
|
|
||||||
|
|
||||||
#define DROPBEAR_KEY_FILE "/etc/dropbear/authorized_keys"
|
|
||||||
|
|
||||||
struct ssh_session_args {
|
|
||||||
struct list_head list;
|
|
||||||
char ip[45];
|
|
||||||
char port[6];
|
|
||||||
char pid[15];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dmmap_ssh
|
|
||||||
{
|
|
||||||
struct list_head list;
|
|
||||||
struct uci_section *config_section;
|
|
||||||
struct uci_section *dmmap_section;
|
|
||||||
struct list_head *sessions;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void add_pubkey(const char *cur, const char *new)
|
|
||||||
{
|
|
||||||
if (DM_STRLEN(cur) == 0) {
|
|
||||||
if (DM_STRLEN(new) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
FILE *fp = fopen(DROPBEAR_KEY_FILE, "a");
|
|
||||||
if (fp != NULL) {
|
|
||||||
fputs(new, fp);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
char line[5120] = {0};
|
|
||||||
FILE *fp = fopen(DROPBEAR_KEY_FILE, "r");
|
|
||||||
FILE *tmp = fopen("replace.tmp", "w");
|
|
||||||
|
|
||||||
if (fp == NULL || tmp == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
|
||||||
remove_new_line(line);
|
|
||||||
if (DM_STRCMP(line, cur) == 0 && DM_STRLEN(new) != 0)
|
|
||||||
fputs(new, tmp);
|
|
||||||
else
|
|
||||||
fputs(line, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
fclose(tmp);
|
|
||||||
|
|
||||||
remove(DROPBEAR_KEY_FILE);
|
|
||||||
rename("replace.tmp", DROPBEAR_KEY_FILE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void remove_pubkey(const char *key)
|
|
||||||
{
|
|
||||||
if (DM_STRLEN(key) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
char line[5120] = {0};
|
|
||||||
FILE *fp = fopen(DROPBEAR_KEY_FILE, "r");
|
|
||||||
FILE *tmp = fopen("replace.tmp", "w");
|
|
||||||
|
|
||||||
if (fp == NULL || tmp == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
|
||||||
remove_new_line(line);
|
|
||||||
if (DM_STRCMP(line, key) != 0)
|
|
||||||
fputs(line, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
fclose(tmp);
|
|
||||||
|
|
||||||
remove(DROPBEAR_KEY_FILE);
|
|
||||||
rename("replace.tmp", DROPBEAR_KEY_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool key_exist_in_keyfile(const char *key)
|
|
||||||
{
|
|
||||||
if (DM_STRLEN(key) == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
char line[5120] = {0};
|
|
||||||
FILE *fp = fopen(DROPBEAR_KEY_FILE, "r");
|
|
||||||
if (fp == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool ret = false;
|
|
||||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
|
||||||
remove_new_line(line);
|
|
||||||
if (DM_STRCMP(line, key) == 0) {
|
|
||||||
ret = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool key_exists(const char *key)
|
|
||||||
{
|
|
||||||
struct uci_section *s = NULL, *stmp = NULL;
|
|
||||||
bool exists = false;
|
|
||||||
|
|
||||||
uci_path_foreach_sections_safe(bbfdm, "dmmap_dropbear", "authkey", stmp, s) {
|
|
||||||
char *val = NULL;
|
|
||||||
dmuci_get_value_by_section_string(s, "pubkey", &val);
|
|
||||||
if (DM_STRCMP(val, key) == 0) {
|
|
||||||
exists = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return exists;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_ssh_config_dup_list(struct list_head *dup_list, struct uci_section *config_section, struct uci_section *dmmap_section)
|
|
||||||
{
|
|
||||||
struct dmmap_ssh *dmmap_config;
|
|
||||||
|
|
||||||
dmmap_config = dmcalloc(1, sizeof(struct dmmap_ssh));
|
|
||||||
list_add_tail(&dmmap_config->list, dup_list);
|
|
||||||
dmmap_config->config_section = config_section;
|
|
||||||
dmmap_config->dmmap_section = dmmap_section;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_ssh_config_dup_list(struct list_head *dup_list)
|
|
||||||
{
|
|
||||||
struct dmmap_ssh *dmmap_config = NULL, *tmp = NULL;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(dmmap_config, tmp, dup_list, list) {
|
|
||||||
list_del(&dmmap_config->list);
|
|
||||||
dmfree(dmmap_config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void synchronize_ssh_config_sections_with_dmmap(char *package, char *section_type, char *dmmap_package, struct list_head *dup_list)
|
|
||||||
{
|
|
||||||
struct uci_section *s, *stmp, *dmmap_sect;
|
|
||||||
char *v;
|
|
||||||
|
|
||||||
uci_foreach_sections(package, section_type, s) {
|
|
||||||
/*
|
|
||||||
* create/update corresponding dmmap section that have same config_section link and using param_value_array
|
|
||||||
*/
|
|
||||||
if ((dmmap_sect = get_dup_section_in_dmmap(dmmap_package, section_type, section_name(s))) == NULL) {
|
|
||||||
dmuci_add_section_bbfdm(dmmap_package, section_type, &dmmap_sect);
|
|
||||||
dmuci_set_value_by_section_bbfdm(dmmap_sect, "section_name", section_name(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add system and dmmap sections to the list
|
|
||||||
*/
|
|
||||||
add_ssh_config_dup_list(dup_list, s, dmmap_sect);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Delete unused dmmap sections
|
|
||||||
*/
|
|
||||||
uci_path_foreach_sections_safe(bbfdm, dmmap_package, section_type, stmp, s) {
|
|
||||||
dmuci_get_value_by_section_string(s, "section_name", &v);
|
|
||||||
if (get_origin_section_from_config(package, section_type, v) == NULL)
|
|
||||||
dmuci_delete_by_section(s, NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ssh_server_session_init(struct list_head *sess_list)
|
|
||||||
{
|
|
||||||
char cmd[512] = {0};
|
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd), "netstat -ntp | grep dropbear | awk \'{print $5,$7}\' | cut -d\'/\' -f 1");
|
|
||||||
FILE *pp = popen(cmd, "r");
|
|
||||||
if (pp == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
char line[256] = {0};
|
|
||||||
while (fgets(line, sizeof(line), pp) != NULL) {
|
|
||||||
remove_new_line(line);
|
|
||||||
if (DM_STRLEN(line) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
char *port = NULL;
|
|
||||||
char *pid = NULL;
|
|
||||||
|
|
||||||
char *chr = strchr(line, ':');
|
|
||||||
if (chr) {
|
|
||||||
*chr = 0;
|
|
||||||
port = chr + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DM_STRLEN(port) != 0) {
|
|
||||||
char *sp = strchr(port, ' ');
|
|
||||||
if (sp) {
|
|
||||||
*sp = 0;
|
|
||||||
pid = sp + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ssh_session_args *session = dmcalloc(1, sizeof(struct ssh_session_args));
|
|
||||||
if (session == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
strncpy(session->ip, line, sizeof(session->ip));
|
|
||||||
if (DM_STRLEN(port) != 0) {
|
|
||||||
snprintf(session->port, sizeof(session->port), "%s", port);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DM_STRLEN(pid) != 0) {
|
|
||||||
snprintf(session->pid, sizeof(session->pid), "%s", pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
list_add_tail(&session->list, sess_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
pclose(pp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_ssh_session_list(struct list_head *sess_list)
|
|
||||||
{
|
|
||||||
struct ssh_session_args *session = NULL, *tmp = NULL;
|
|
||||||
list_for_each_entry_safe(session, tmp, sess_list, list) {
|
|
||||||
list_del(&session->list);
|
|
||||||
dmfree(session);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void close_active_sessions(struct uci_section *s)
|
|
||||||
{
|
|
||||||
bool b;
|
|
||||||
char *value = dmuci_get_value_by_section_fallback_def(s, "enable", "1");
|
|
||||||
string_to_bool(value, &b);
|
|
||||||
if (!b)
|
|
||||||
return;
|
|
||||||
|
|
||||||
char pid_file[125] = {0};
|
|
||||||
char *sec_name = section_name(s);
|
|
||||||
if (DM_STRLEN(sec_name) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
snprintf(pid_file, sizeof(pid_file), "/var/run/dropbear.%s.pid", sec_name);
|
|
||||||
if (DM_STRLEN(pid_file) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
FILE *fp = fopen(pid_file, "r");
|
|
||||||
if (fp == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
unsigned int pid;
|
|
||||||
if (fscanf(fp, "%u", &pid) != 1) {
|
|
||||||
fclose(fp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
char cmd[512] = {0};
|
|
||||||
snprintf(cmd, sizeof(cmd), "ps -w | grep %s | grep -v grep | awk \'{print $1}\'", pid_file);
|
|
||||||
FILE *pp = popen(cmd, "r");
|
|
||||||
if (pp == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
char line[15] = {0};
|
|
||||||
while (fgets(line, sizeof(line), pp) != NULL) {
|
|
||||||
remove_new_line(line);
|
|
||||||
if (DM_STRLEN(line) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (strtoul(line, NULL, 10) == pid)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd), "kill -15 %s", line);
|
|
||||||
if (system(cmd) == -1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pclose(pp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* ADD & DEL OBJ
|
|
||||||
*************************************************************/
|
|
||||||
static int addObjSSHServer(char *refparam, struct dmctx *ctx, void *data, char **instance)
|
|
||||||
{
|
|
||||||
struct uci_section *s = NULL, *dmmap_s = NULL;
|
|
||||||
char s_name[16];
|
|
||||||
|
|
||||||
snprintf(s_name, sizeof(s_name), "server_%s", *instance);
|
|
||||||
|
|
||||||
dmuci_add_section("dropbear", "dropbear", &s);
|
|
||||||
dmuci_rename_section_by_section(s, s_name);
|
|
||||||
dmuci_set_value_by_section(s, "enable", "0");
|
|
||||||
dmuci_set_value_by_section(s, "Port", "22");
|
|
||||||
dmuci_set_value_by_section(s, "IdleTimeout", "180");
|
|
||||||
dmuci_set_value_by_section(s, "SSHKeepAlive", "300");
|
|
||||||
dmuci_set_value_by_section(s, "RootLogin", "0");
|
|
||||||
dmuci_set_value_by_section(s, "PasswordAuth", "0");
|
|
||||||
dmuci_set_value_by_section(s, "RootPasswordAuth", "0");
|
|
||||||
dmuci_set_value_by_section(s, "MaxAuthTries", "3");
|
|
||||||
|
|
||||||
dmuci_add_section_bbfdm("dmmap_dropbear", "dropbear", &dmmap_s);
|
|
||||||
dmuci_set_value_by_section(dmmap_s, "section_name", s_name);
|
|
||||||
dmuci_set_value_by_section(dmmap_s, "server_instance", *instance);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int delObjSSHServer(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
|
|
||||||
{
|
|
||||||
struct uci_section *s = NULL, *stmp = NULL;
|
|
||||||
|
|
||||||
switch (del_action) {
|
|
||||||
case DEL_INST:
|
|
||||||
close_active_sessions(((struct dmmap_ssh *)data)->config_section);
|
|
||||||
dmuci_delete_by_section(((struct dmmap_ssh *)data)->config_section, NULL, NULL);
|
|
||||||
dmuci_delete_by_section(((struct dmmap_ssh *)data)->dmmap_section, NULL, NULL);
|
|
||||||
break;
|
|
||||||
case DEL_ALL:
|
|
||||||
uci_foreach_sections_safe("dropbear", "dropbear", stmp, s) {
|
|
||||||
struct uci_section *dmmap_section = NULL;
|
|
||||||
get_dmmap_section_of_config_section("dmmap_dropbear", "dropbear", section_name(s), &dmmap_section);
|
|
||||||
close_active_sessions(s);
|
|
||||||
dmuci_delete_by_section(s, NULL, NULL);
|
|
||||||
dmuci_delete_by_section(dmmap_section, NULL, NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int addObjSSHKey(char *refparam, struct dmctx *ctx, void *data, char **instance)
|
|
||||||
{
|
|
||||||
struct uci_section *s = NULL;
|
|
||||||
|
|
||||||
dmuci_add_section_bbfdm("dmmap_dropbear", "authkey", &s);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int delObjSSHKey(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
|
|
||||||
{
|
|
||||||
struct uci_section *s = NULL, *stmp = NULL;
|
|
||||||
char *value = NULL;
|
|
||||||
|
|
||||||
switch (del_action) {
|
|
||||||
case DEL_INST:
|
|
||||||
dmuci_get_value_by_section_string((struct uci_section *)data, "pubkey", &value);
|
|
||||||
remove_pubkey(value);
|
|
||||||
dmuci_delete_by_section((struct uci_section *)data, NULL, NULL);
|
|
||||||
break;
|
|
||||||
case DEL_ALL:
|
|
||||||
uci_path_foreach_sections_safe(bbfdm, "dmmap_dropbear", "authkey", stmp, s) {
|
|
||||||
dmuci_get_value_by_section_string(s, "pubkey", &value);
|
|
||||||
remove_pubkey(value);
|
|
||||||
dmuci_delete_by_section(s, NULL, NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* ENTRY METHODS
|
|
||||||
*************************************************************/
|
|
||||||
static int browseSSHServerInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
|
|
||||||
{
|
|
||||||
struct dmmap_ssh *p = NULL;
|
|
||||||
LIST_HEAD(dup_list);
|
|
||||||
LIST_HEAD(session_list);
|
|
||||||
char *inst = NULL;
|
|
||||||
|
|
||||||
ssh_server_session_init(&session_list);
|
|
||||||
synchronize_ssh_config_sections_with_dmmap("dropbear", "dropbear", "dmmap_dropbear", &dup_list);
|
|
||||||
list_for_each_entry(p, &dup_list, list) {
|
|
||||||
bool b;
|
|
||||||
char *enable = dmuci_get_value_by_section_fallback_def(p->config_section, "enable", "1");
|
|
||||||
char *act_date = dmuci_get_value_by_section_fallback_def(p->dmmap_section, "activationdate", "");
|
|
||||||
|
|
||||||
string_to_bool(enable, &b);
|
|
||||||
if (b && DM_STRLEN(act_date) == 0) {
|
|
||||||
char *tm = NULL;
|
|
||||||
dm_time_format(time(NULL), &tm);
|
|
||||||
dmuci_set_value_by_section(p->dmmap_section, "activationdate", tm);
|
|
||||||
}
|
|
||||||
|
|
||||||
p->sessions = &session_list;
|
|
||||||
|
|
||||||
inst = handle_instance(dmctx, parent_node, p->dmmap_section, "server_instance", "server_alias");
|
|
||||||
|
|
||||||
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p, inst) == DM_STOP)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free_ssh_session_list(&session_list);
|
|
||||||
free_ssh_config_dup_list(&dup_list);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int browseSSHKeyInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
|
|
||||||
{
|
|
||||||
struct uci_section *s = NULL, *stmp = NULL;
|
|
||||||
char *inst = NULL;
|
|
||||||
char line[5120] = {0};
|
|
||||||
|
|
||||||
/* create entries for the keys available in DROPBEAR_KEY_FILE but not in dmmap */
|
|
||||||
FILE *fp = fopen(DROPBEAR_KEY_FILE, "r");
|
|
||||||
if (fp != NULL) {
|
|
||||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
|
||||||
struct uci_section *dmmap_sect = NULL;
|
|
||||||
remove_new_line(line);
|
|
||||||
bool exists = false;
|
|
||||||
|
|
||||||
uci_path_foreach_sections_safe(bbfdm, "dmmap_dropbear", "authkey", stmp, s) {
|
|
||||||
char *val = NULL;
|
|
||||||
dmuci_get_value_by_section_string(s, "pubkey", &val);
|
|
||||||
if (DM_STRCMP(val, line) == 0) {
|
|
||||||
exists = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!exists) {
|
|
||||||
dmmap_sect = NULL;
|
|
||||||
dmuci_add_section_bbfdm("dmmap_dropbear", "authkey", &dmmap_sect);
|
|
||||||
dmuci_set_value_by_section(dmmap_sect, "pubkey", line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* delete keys from dmmap which are not available in DROPBEAR_KEY_FILE */
|
|
||||||
stmp = NULL;
|
|
||||||
s = NULL;
|
|
||||||
uci_path_foreach_sections_safe(bbfdm, "dmmap_dropbear", "authkey", stmp, s) {
|
|
||||||
char *val = NULL;
|
|
||||||
dmuci_get_value_by_section_string(s, "pubkey", &val);
|
|
||||||
if (!key_exist_in_keyfile(val)) {
|
|
||||||
dmuci_delete_by_section(s, NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* enlist objects */
|
|
||||||
stmp = NULL;
|
|
||||||
s = NULL;
|
|
||||||
uci_path_foreach_sections_safe(bbfdm, "dmmap_dropbear", "authkey", stmp, s) {
|
|
||||||
inst = handle_instance(dmctx, parent_node, s, "instance", "alias");
|
|
||||||
|
|
||||||
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)s, inst) == DM_STOP)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int browseSSHServerSessionInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
|
|
||||||
{
|
|
||||||
bool b;
|
|
||||||
char *inst = NULL;
|
|
||||||
int id = 0;
|
|
||||||
|
|
||||||
struct uci_section *s = ((struct dmmap_ssh *)prev_data)->config_section;
|
|
||||||
char *value = dmuci_get_value_by_section_fallback_def(s, "enable", "1");
|
|
||||||
string_to_bool(value, &b);
|
|
||||||
if (!b)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
char pid_file[125] = {0};
|
|
||||||
char *sec_name = section_name(s);
|
|
||||||
if (DM_STRLEN(sec_name) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
snprintf(pid_file, sizeof(pid_file), "/var/run/dropbear.%s.pid", sec_name);
|
|
||||||
if (DM_STRLEN(pid_file) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
FILE *fp = fopen(pid_file, "r");
|
|
||||||
if (fp == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
unsigned int pid;
|
|
||||||
if (fscanf(fp, "%u", &pid) != 1) {
|
|
||||||
fclose(fp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
char cmd[512] = {0};
|
|
||||||
snprintf(cmd, sizeof(cmd), "ps -w | grep %s | grep -v grep | awk \'{print $1}\'", pid_file);
|
|
||||||
FILE *pp = popen(cmd, "r");
|
|
||||||
if (pp == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char line[15] = {0};
|
|
||||||
while (fgets(line, sizeof(line), pp) != NULL) {
|
|
||||||
remove_new_line(line);
|
|
||||||
if (DM_STRLEN(line) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (strtoul(line, NULL, 10) == pid) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ssh_session_args *session = NULL;
|
|
||||||
struct list_head *sess_list = ((struct dmmap_ssh *)prev_data)->sessions;
|
|
||||||
bool found = false;
|
|
||||||
list_for_each_entry(session, sess_list, list) {
|
|
||||||
if (DM_STRCMP(session->pid, line) == 0) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
inst = handle_instance_without_section(dmctx, parent_node, ++id);
|
|
||||||
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)session, inst) == DM_STOP)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pclose(pp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* GET & SET PARAM
|
|
||||||
**************************************************************/
|
|
||||||
static int get_ssh_server_num(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
int cnt = get_number_of_entries(ctx, data, instance, browseSSHServerInst);
|
|
||||||
dmasprintf(value, "%d", cnt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_key_num(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
int cnt = get_number_of_entries(ctx, data, instance, browseSSHKeyInst);
|
|
||||||
dmasprintf(value, "%d", cnt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
*value = "Enabled";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_session_num(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
int cnt = get_number_of_entries(ctx, data, instance, browseSSHServerSessionInst);
|
|
||||||
dmasprintf(value, "%d", cnt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_ssh *)data)->config_section, "enable", "1");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_server_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
bool b;
|
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
case VALUECHECK:
|
|
||||||
if (bbfdm_validate_boolean(ctx, value))
|
|
||||||
return FAULT_9007;
|
|
||||||
break;
|
|
||||||
case VALUESET:
|
|
||||||
string_to_bool(value, &b);
|
|
||||||
char *cur = dmuci_get_value_by_section_fallback_def(((struct dmmap_ssh *)data)->config_section, "enable", "1");
|
|
||||||
bool cur_val;
|
|
||||||
string_to_bool(cur, &cur_val);
|
|
||||||
|
|
||||||
if (b == cur_val)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (b) {
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->config_section, "enable", "1");
|
|
||||||
char *tm = NULL;
|
|
||||||
dm_time_format(time(NULL), &tm);
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->dmmap_section, "activationdate", tm);
|
|
||||||
} else {
|
|
||||||
close_active_sessions(((struct dmmap_ssh *)data)->config_section);
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->config_section, "enable", "0");
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->dmmap_section, "activationdate", "");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
return bbf_get_alias(ctx, ((struct dmmap_ssh *)data)->dmmap_section, "server_alias", instance, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_server_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
return bbf_set_alias(ctx, ((struct dmmap_ssh *)data)->dmmap_section, "server_alias", instance, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
char *linker = NULL;
|
|
||||||
|
|
||||||
dmuci_get_value_by_section_string(((struct dmmap_ssh *)data)->config_section, "Interface", &linker);
|
|
||||||
adm_entry_get_reference_param(ctx, "Device.IP.Interface.*.Name", linker, value);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_server_interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
char *allowed_objects[] = {"Device.IP.Interface.", NULL};
|
|
||||||
struct dm_reference reference = {0};
|
|
||||||
|
|
||||||
bbf_get_reference_args(value, &reference);
|
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
case VALUECHECK:
|
|
||||||
if (bbfdm_validate_string(ctx, reference.path, -1, 256, NULL, NULL))
|
|
||||||
return FAULT_9007;
|
|
||||||
|
|
||||||
if (dm_validate_allowed_objects(ctx, &reference, allowed_objects))
|
|
||||||
return FAULT_9007;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case VALUESET:
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->config_section, "Interface", reference.value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_ssh *)data)->config_section, "Port", "22");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_server_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
switch (action) {
|
|
||||||
case VALUECHECK:
|
|
||||||
if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1","65535"}},1))
|
|
||||||
return FAULT_9007;
|
|
||||||
break;
|
|
||||||
case VALUESET:
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->config_section, "Port", value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_idle(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_ssh *)data)->config_section, "IdleTimeout", "0");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_server_idle(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
switch (action) {
|
|
||||||
case VALUECHECK:
|
|
||||||
if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{NULL,NULL}},1))
|
|
||||||
return FAULT_9007;
|
|
||||||
break;
|
|
||||||
case VALUESET:
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->config_section, "IdleTimeout", value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_keepalive(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_ssh *)data)->config_section, "SSHKeepAlive", "300");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_server_keepalive(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
switch (action) {
|
|
||||||
case VALUECHECK:
|
|
||||||
if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{NULL,NULL}},1))
|
|
||||||
return FAULT_9007;
|
|
||||||
break;
|
|
||||||
case VALUESET:
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->config_section, "SSHKeepAlive", value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_rootlogin(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_ssh *)data)->config_section, "RootLogin", "1");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_server_rootlogin(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
bool b;
|
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
case VALUECHECK:
|
|
||||||
if (bbfdm_validate_boolean(ctx, value))
|
|
||||||
return FAULT_9007;
|
|
||||||
break;
|
|
||||||
case VALUESET:
|
|
||||||
string_to_bool(value, &b);
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->config_section, "RootLogin", b ? "1" : "0");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_passwordlogin(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_ssh *)data)->config_section, "PasswordAuth", "1");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_server_passwordlogin(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
bool b;
|
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
case VALUECHECK:
|
|
||||||
if (bbfdm_validate_boolean(ctx, value))
|
|
||||||
return FAULT_9007;
|
|
||||||
break;
|
|
||||||
case VALUESET:
|
|
||||||
string_to_bool(value, &b);
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->config_section, "PasswordAuth", b ? "1" : "0");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_rootpasswordlogin(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_ssh *)data)->config_section, "RootPasswordAuth", "1");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_server_rootpasswordlogin(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
bool b;
|
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
case VALUECHECK:
|
|
||||||
if (bbfdm_validate_boolean(ctx, value))
|
|
||||||
return FAULT_9007;
|
|
||||||
break;
|
|
||||||
case VALUESET:
|
|
||||||
string_to_bool(value, &b);
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->config_section, "RootPasswordAuth", b ? "1" : "0");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_maxauthtries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_ssh *)data)->config_section, "MaxAuthTries", "3");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_server_maxauthtries(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
switch (action) {
|
|
||||||
case VALUECHECK:
|
|
||||||
if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{NULL,NULL}},1))
|
|
||||||
return FAULT_9007;
|
|
||||||
break;
|
|
||||||
case VALUESET:
|
|
||||||
dmuci_set_value_by_section(((struct dmmap_ssh *)data)->config_section, "MaxAuthTries", value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_activationdate(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
dmuci_get_value_by_section_string(((struct dmmap_ssh *)data)->dmmap_section, "activationdate", value);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_pid(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
bool b;
|
|
||||||
struct uci_section *s = ((struct dmmap_ssh *)data)->config_section;
|
|
||||||
char *en = dmuci_get_value_by_section_fallback_def(s, "enable", "1");
|
|
||||||
|
|
||||||
*value = "0";
|
|
||||||
string_to_bool(en, &b);
|
|
||||||
if (!b)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
char *sec_name = section_name(s);
|
|
||||||
if (DM_STRLEN(sec_name) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
char pid_file[256] = {0};
|
|
||||||
snprintf(pid_file, sizeof(pid_file), "/var/run/dropbear.%s.pid", sec_name);
|
|
||||||
if (DM_STRLEN(pid_file) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
FILE *fp = fopen(pid_file, "r");
|
|
||||||
if (fp == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
unsigned int pid;
|
|
||||||
if (fscanf(fp, "%u", &pid) != 1) {
|
|
||||||
fclose(fp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
dmasprintf(value, "%u", pid);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_session_ip(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
struct ssh_session_args *args = (struct ssh_session_args *)data;
|
|
||||||
*value = DM_STRLEN(args->ip) ? dmstrdup(args->ip) : "";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_server_session_port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
struct ssh_session_args *args = (struct ssh_session_args *)data;
|
|
||||||
*value = DM_STRLEN(args->port) ? dmstrdup(args->port) : "";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_key_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
return bbf_get_alias(ctx, (struct uci_section *)data, "alias", instance, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_key_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
return bbf_set_alias(ctx, (struct uci_section *)data, "alias", instance, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ssh_key_pubkey(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
|
||||||
{
|
|
||||||
dmuci_get_value_by_section_string((struct uci_section *)data, "pubkey", value);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_ssh_key_pubkey(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
char *cur_val = NULL;
|
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
case VALUECHECK:
|
|
||||||
if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL))
|
|
||||||
return FAULT_9007;
|
|
||||||
|
|
||||||
/* check if same as current key value */
|
|
||||||
dmuci_get_value_by_section_string((struct uci_section *)data, "pubkey", &cur_val);
|
|
||||||
if (DM_STRCMP(cur_val, value) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (key_exists(value))
|
|
||||||
return FAULT_9001;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case VALUESET:
|
|
||||||
/* check if same as current key value then nothing to do */
|
|
||||||
dmuci_get_value_by_section_string((struct uci_section *)data, "pubkey", &cur_val);
|
|
||||||
if (DM_STRCMP(cur_val, value) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
add_pubkey(cur_val, value);
|
|
||||||
dmuci_set_value_by_section((struct uci_section *)data, "pubkey", value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int operate_session_delete(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
struct ssh_session_args *args = (struct ssh_session_args *)data;
|
|
||||||
if (DM_STRLEN(args->pid) != 0) {
|
|
||||||
char cmd[128] = {0};
|
|
||||||
snprintf(cmd, sizeof(cmd), "kill -15 %s", args->pid);
|
|
||||||
ret = system(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ret != -1) ? 0 : USP_FAULT_COMMAND_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************
|
|
||||||
* OBJ & LEAF DEFINITION
|
|
||||||
***********************************************************************************************************************************/
|
|
||||||
/* *** Device.SSH. *** */
|
|
||||||
DMOBJ tDeviceSSHObj[] = {
|
|
||||||
{"SSH", &DMREAD, NULL, NULL, "file:/etc/config/dropbear", NULL, NULL, NULL, tSSHObj, tSSHParams, NULL, BBFDM_BOTH, NULL},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
DMOBJ tSSHObj[] = {
|
|
||||||
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
|
|
||||||
{"Server", &DMWRITE, addObjSSHServer, delObjSSHServer, NULL, browseSSHServerInst, NULL, NULL, tSSHServerObj, tSSHServerParams, NULL, BBFDM_BOTH, NULL},
|
|
||||||
{"AuthorizedKey", &DMWRITE, addObjSSHKey, delObjSSHKey, NULL, browseSSHKeyInst, NULL, NULL, NULL, tSSHKeyParams, NULL, BBFDM_BOTH, NULL},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
DMOBJ tSSHServerObj[] = {
|
|
||||||
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
|
|
||||||
{"Session", &DMREAD, NULL, NULL, NULL, browseSSHServerSessionInst, NULL, NULL, NULL, tSSHServerSessionParams, NULL, BBFDM_BOTH, NULL},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* *** Device.SSH. *** */
|
|
||||||
DMLEAF tSSHParams[] = {
|
|
||||||
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
|
|
||||||
{"ServerNumberOfEntries", &DMREAD, DMT_UNINT, get_ssh_server_num, NULL, BBFDM_BOTH},
|
|
||||||
{"AuthorizedKeyNumberOfEntries", &DMREAD, DMT_UNINT, get_ssh_key_num, NULL, BBFDM_BOTH},
|
|
||||||
{"Status", &DMREAD, DMT_STRING, get_ssh_status, NULL, BBFDM_BOTH},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* *** Device.SSH.Server. *** */
|
|
||||||
DMLEAF tSSHServerParams[] = {
|
|
||||||
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
|
|
||||||
{"Enable", &DMWRITE, DMT_BOOL, get_ssh_server_enable, set_ssh_server_enable, BBFDM_BOTH},
|
|
||||||
{"Alias", &DMWRITE, DMT_STRING, get_ssh_server_alias, set_ssh_server_alias, BBFDM_BOTH, DM_FLAG_UNIQUE},
|
|
||||||
{"Interface", &DMWRITE, DMT_STRING, get_ssh_server_interface, set_ssh_server_interface, BBFDM_BOTH, DM_FLAG_REFERENCE},
|
|
||||||
{"Port", &DMWRITE, DMT_UNINT, get_ssh_server_port, set_ssh_server_port, BBFDM_BOTH},
|
|
||||||
{"IdleTimeout", &DMWRITE, DMT_UNINT, get_ssh_server_idle, set_ssh_server_idle, BBFDM_BOTH},
|
|
||||||
{"KeepAlive", &DMWRITE, DMT_UNINT, get_ssh_server_keepalive, set_ssh_server_keepalive, BBFDM_BOTH},
|
|
||||||
{"AllowRootLogin", &DMWRITE, DMT_BOOL, get_ssh_server_rootlogin, set_ssh_server_rootlogin, BBFDM_BOTH},
|
|
||||||
{"AllowPasswordLogin", &DMWRITE, DMT_BOOL, get_ssh_server_passwordlogin, set_ssh_server_passwordlogin, BBFDM_BOTH},
|
|
||||||
{"AllowRootPasswordLogin", &DMWRITE, DMT_BOOL, get_ssh_server_rootpasswordlogin, set_ssh_server_rootpasswordlogin, BBFDM_BOTH},
|
|
||||||
{"MaxAuthTries", &DMWRITE, DMT_UNINT, get_ssh_server_maxauthtries, set_ssh_server_maxauthtries, BBFDM_BOTH},
|
|
||||||
{"ActivationDate", &DMREAD, DMT_TIME, get_ssh_server_activationdate, NULL, BBFDM_BOTH},
|
|
||||||
{"PID", &DMREAD, DMT_UNINT, get_ssh_server_pid, NULL, BBFDM_BOTH},
|
|
||||||
{"SessionNumberOfEntries", &DMREAD, DMT_UNINT, get_ssh_server_session_num, NULL, BBFDM_BOTH},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
DMLEAF tSSHServerSessionParams[] = {
|
|
||||||
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
|
|
||||||
{"IPAddress", &DMREAD, DMT_STRING, get_ssh_server_session_ip, NULL, BBFDM_BOTH},
|
|
||||||
{"Port", &DMREAD, DMT_UNINT, get_ssh_server_session_port, NULL, BBFDM_BOTH},
|
|
||||||
{"Delete()", &DMSYNC, DMT_COMMAND, NULL, operate_session_delete, BBFDM_USP},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
DMLEAF tSSHKeyParams[] = {
|
|
||||||
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
|
|
||||||
{"Alias", &DMWRITE, DMT_STRING, get_ssh_key_alias, set_ssh_key_alias, BBFDM_BOTH, DM_FLAG_UNIQUE},
|
|
||||||
{"Key", &DMWRITE, DMT_STRING, get_ssh_key_pubkey, set_ssh_key_pubkey, BBFDM_BOTH},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ********** DynamicObj ********** */
|
|
||||||
DM_MAP_OBJ tDynamicObj[] = {
|
|
||||||
/* parentobj, nextobject, parameter */
|
|
||||||
{"Device.", tDeviceSSHObj, NULL},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2023 iopsys Software Solutions AB
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License version 2.1
|
|
||||||
* as published by the Free Software Foundation
|
|
||||||
*
|
|
||||||
* Author Suvendhu Hansa <suvendhu.hansa@iopsys.eu>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SSH_H
|
|
||||||
#define __SSH_H
|
|
||||||
|
|
||||||
#include "libbbfdm-api/dmcommon.h"
|
|
||||||
|
|
||||||
extern DMOBJ tSSHObj[];
|
|
||||||
extern DMOBJ tSSHServerObj[];
|
|
||||||
extern DMLEAF tSSHParams[];
|
|
||||||
extern DMLEAF tSSHServerParams[];
|
|
||||||
extern DMLEAF tSSHServerSessionParams[];
|
|
||||||
extern DMLEAF tSSHKeyParams[];
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Loading…
Add table
Reference in a new issue