16122117a5
A dropbear instance having an interface config won't start if the interface is down as no IP address is available. Adding interface triggers for each configured interface executing the dropbear reload script will start the dropbear instance when the interface is up. Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
198 lines
4.4 KiB
Bash
Executable file
198 lines
4.4 KiB
Bash
Executable file
#!/bin/sh /etc/rc.common
|
|
# Copyright (C) 2006-2010 OpenWrt.org
|
|
# Copyright (C) 2006 Carlos Sobrinho
|
|
|
|
START=50
|
|
STOP=50
|
|
|
|
USE_PROCD=1
|
|
PROG=/usr/sbin/dropbear
|
|
NAME=dropbear
|
|
PIDCOUNT=0
|
|
EXTRA_COMMANDS="killclients"
|
|
EXTRA_HELP=" killclients Kill ${NAME} processes except servers and yourself"
|
|
|
|
append_ports()
|
|
{
|
|
local ipaddrs="$1"
|
|
local port="$2"
|
|
|
|
[ -z "$ipaddrs" ] && {
|
|
procd_append_param command -p "$port"
|
|
return
|
|
}
|
|
|
|
for addr in $ipaddrs; do
|
|
procd_append_param command -p "$addr:$port"
|
|
done
|
|
}
|
|
|
|
validate_section_dropbear()
|
|
{
|
|
uci_validate_section dropbear dropbear "${1}" \
|
|
'PasswordAuth:bool:1' \
|
|
'enable:bool:1' \
|
|
'Interface:string' \
|
|
'GatewayPorts:bool:0' \
|
|
'RootPasswordAuth:bool:1' \
|
|
'RootLogin:bool:1' \
|
|
'rsakeyfile:file' \
|
|
'BannerFile:file' \
|
|
'Port:list(port):22' \
|
|
'SSHKeepAlive:uinteger:300' \
|
|
'IdleTimeout:uinteger:0' \
|
|
'mdns:uinteger:1'
|
|
}
|
|
|
|
dropbear_instance()
|
|
{
|
|
local PasswordAuth enable Interface GatewayPorts \
|
|
RootPasswordAuth RootLogin rsakeyfile \
|
|
BannerFile Port SSHKeepAlive IdleTimeout \
|
|
mdns ipaddrs
|
|
|
|
validate_section_dropbear "${1}" || {
|
|
echo "validation failed"
|
|
return 1
|
|
}
|
|
|
|
[ -n "${Interface}" ] && {
|
|
network_get_ipaddrs_all ipaddrs "${Interface}" || {
|
|
echo "interface ${Interface} has no physdev or physdev has no suitable ip"
|
|
return 1
|
|
}
|
|
}
|
|
|
|
[ "${enable}" = "0" ] && return 1
|
|
PIDCOUNT="$(( ${PIDCOUNT} + 1))"
|
|
local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid"
|
|
|
|
procd_open_instance
|
|
procd_set_param command "$PROG" -F -P "$pid_file"
|
|
[ "${PasswordAuth}" -eq 0 ] && procd_append_param command -s
|
|
[ "${GatewayPorts}" -eq 1 ] && procd_append_param command -a
|
|
[ "${RootPasswordAuth}" -eq 0 ] && procd_append_param command -g
|
|
[ "${RootLogin}" -eq 0 ] && procd_append_param command -w
|
|
[ -n "${rsakeyfile}" ] && procd_append_param command -r "${rsakeyfile}"
|
|
[ -n "${BannerFile}" ] && procd_append_param command -b "${BannerFile}"
|
|
append_ports "${ipaddrs}" "${Port}"
|
|
[ "${IdleTimeout}" -ne 0 ] && procd_append_param command -I "${IdleTimeout}"
|
|
[ "${SSHKeepAlive}" -ne 0 ] && procd_append_param command -K "${SSHKeepAlive}"
|
|
[ "${mdns}" -ne 0 ] && procd_add_mdns "ssh" "tcp" "$Port" "daemon=dropbear"
|
|
procd_set_param respawn
|
|
procd_close_instance
|
|
}
|
|
|
|
keygen()
|
|
{
|
|
for keytype in rsa; do
|
|
# check for keys
|
|
key=dropbear/dropbear_${keytype}_host_key
|
|
[ -f /tmp/$key -o -s /etc/$key ] || {
|
|
# generate missing keys
|
|
mkdir -p /tmp/dropbear
|
|
[ -x /usr/bin/dropbearkey ] && {
|
|
/usr/bin/dropbearkey -t $keytype -f /tmp/$key 2>&- >&- && exec /etc/rc.common "$initscript" start
|
|
} &
|
|
exit 0
|
|
}
|
|
done
|
|
|
|
lock /tmp/.switch2jffs
|
|
mkdir -p /etc/dropbear
|
|
mv /tmp/dropbear/dropbear_* /etc/dropbear/
|
|
lock -u /tmp/.switch2jffs
|
|
chown root /etc/dropbear
|
|
chmod 0700 /etc/dropbear
|
|
}
|
|
|
|
load_interfaces()
|
|
{
|
|
config_get interface "$1" Interface
|
|
interfaces=" ${interface} ${interfaces}"
|
|
}
|
|
|
|
start_service()
|
|
{
|
|
[ -s /etc/dropbear/dropbear_rsa_host_key ] || keygen
|
|
|
|
. /lib/functions.sh
|
|
. /lib/functions/network.sh
|
|
|
|
config_load "${NAME}"
|
|
config_foreach dropbear_instance dropbear
|
|
}
|
|
|
|
service_triggers()
|
|
{
|
|
local interfaces
|
|
|
|
procd_open_trigger
|
|
procd_add_config_trigger "config.change" "dropbear" /etc/init.d/dropbear reload
|
|
|
|
config_load "${NAME}"
|
|
config_foreach load_interfaces dropbear
|
|
|
|
[ -n "${interfaces}" ] & {
|
|
for n in $interfaces ; do
|
|
procd_add_interface_trigger "interface.*" $n /etc/init.d/dropbear reload
|
|
done
|
|
}
|
|
procd_close_trigger
|
|
|
|
procd_add_validation validate_section_dropbear
|
|
}
|
|
|
|
killclients()
|
|
{
|
|
local ignore=''
|
|
local server
|
|
local pid
|
|
|
|
# if this script is run from inside a client session, then ignore that session
|
|
pid="$$"
|
|
while [ "${pid}" -ne 0 ]
|
|
do
|
|
# get parent process id
|
|
pid=`cut -d ' ' -f 4 "/proc/${pid}/stat"`
|
|
[ "${pid}" -eq 0 ] && break
|
|
|
|
# check if client connection
|
|
grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" && {
|
|
append ignore "${pid}"
|
|
break
|
|
}
|
|
done
|
|
|
|
# get all server pids that should be ignored
|
|
for server in `cat /var/run/${NAME}.*.pid`
|
|
do
|
|
append ignore "${server}"
|
|
done
|
|
|
|
# get all running pids and kill client connections
|
|
local skip
|
|
for pid in `pidof "${NAME}"`
|
|
do
|
|
# check if correct program, otherwise process next pid
|
|
grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" || {
|
|
continue
|
|
}
|
|
|
|
# check if pid should be ignored (servers, ourself)
|
|
skip=0
|
|
for server in ${ignore}
|
|
do
|
|
if [ "${pid}" = "${server}" ]
|
|
then
|
|
skip=1
|
|
break
|
|
fi
|
|
done
|
|
[ "${skip}" -ne 0 ] && continue
|
|
|
|
# kill process
|
|
echo "${initscript}: Killing ${pid}..."
|
|
kill -KILL ${pid}
|
|
done
|
|
}
|