dropbear: introduce config option "keyfile" (replacement for "rsakeyfile")
[openwrt/staging/nbd.git] / package / network / services / dropbear / files / dropbear.init
index 6de0142728dfa127652ecceef1d25080069d800a..506f7dac654572b6cfc6e6a7f8bf607f1e09e423 100755 (executable)
@@ -2,7 +2,7 @@
 # Copyright (C) 2006-2010 OpenWrt.org
 # Copyright (C) 2006 Carlos Sobrinho
 
-START=50
+START=19
 STOP=50
 
 USE_PROCD=1
@@ -12,6 +12,54 @@ PIDCOUNT=0
 EXTRA_COMMANDS="killclients"
 EXTRA_HELP="   killclients Kill ${NAME} processes except servers and yourself"
 
+_dropbearkey()
+{
+       /usr/bin/dropbearkey "$@" 0<&- 1>&- 2>&-
+}
+
+# $1 - host key file name
+hk_verify()
+{
+       [ -f "$1" ] || return 1
+       [ -s "$1" ] || return 2
+       _dropbearkey -y -f "$1" || return 3
+       return 0
+}
+
+# $1 - hk_verify() return code
+hk_errmsg()
+{
+       case "$1" in
+       0) ;;
+       1) echo "file does not exist" ;;
+       2) echo "file has zero length" ;;
+       3) echo "file is not valid host key or not supported" ;;
+       *) echo "unknown error" ;;
+       esac
+}
+
+# $1 - config option
+# $2 - host key file name
+hk_config()
+{
+       local x m
+       hk_verify "$2"; x=$?
+       case "$x" in
+       0)      procd_append_param command -r "$2"
+               ;;
+       *)      m=$(hk_errmsg "$x")
+               logger -t "${NAME}" -p daemon.warn \
+                 "option '$1', value '$2': $m, skipping"
+               ;;
+       esac
+}
+
+# $1 - host key file name
+hk_config__keyfile()
+{
+       hk_config 'keyfile' "$1"
+}
+
 append_ports()
 {
        local ipaddrs="$1"
@@ -29,7 +77,7 @@ append_ports()
 
 validate_section_dropbear()
 {
-       uci_validate_section dropbear dropbear "${1}" \
+       uci_load_validate dropbear dropbear "$1" "$2" \
                'PasswordAuth:bool:1' \
                'enable:bool:1' \
                'Interface:string' \
@@ -37,27 +85,28 @@ validate_section_dropbear()
                'RootPasswordAuth:bool:1' \
                'RootLogin:bool:1' \
                'rsakeyfile:file' \
-               'dsskeyfile:file' \
+               'keyfile:list(file)' \
                'BannerFile:file' \
                'Port:list(port):22' \
                'SSHKeepAlive:uinteger:300' \
                'IdleTimeout:uinteger:0' \
-               'mdns:uinteger:1'
+               'MaxAuthTries:uinteger:3' \
+               'RecvWindowSize:uinteger:0' \
+               'mdns:bool:1'
 }
 
 dropbear_instance()
 {
-       local PasswordAuth enable Interface GatewayPorts \
-               RootPasswordAuth RootLogin rsakeyfile \
-               dsskeyfile BannerFile Port SSHKeepAlive IdleTimeout \
-               mdns ipaddrs
+       local ipaddrs
 
-       validate_section_dropbear "${1}" || {
+       [ "$2" = 0 ] || {
                echo "validation failed"
                return 1
        }
 
        [ -n "${Interface}" ] && {
+               [ -n "${BOOT}" ] && return 0
+
                network_get_ipaddrs_all ipaddrs "${Interface}" || {
                        echo "interface ${Interface} has no physdev or physdev has no suitable ip"
                        return 1
@@ -74,19 +123,28 @@ dropbear_instance()
        [ "${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 "${dsskeyfile}" ] && procd_append_param command -d "${dsskeyfile}"
+       if [ -n "${rsakeyfile}" ]; then
+               logger -t ${NAME} -p daemon.warn \
+                       "option 'rsakeyfile' is considered to be deprecated and" \
+                       "will be removed in future releases, use 'keyfile' instead"
+               hk_config 'rsakeyfile' "${rsakeyfile}"
+       fi
+       config_list_foreach "$1" "keyfile" hk_config__keyfile
        [ -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}"
+       [ "${MaxAuthTries}" -ne 0 ] && procd_append_param command -T "${MaxAuthTries}"
+       [ "${RecvWindowSize}" -gt 0 -a "${RecvWindowSize}" -le 1048576 ] && \
+               procd_append_param command -W "${RecvWindowSize}"
        [ "${mdns}" -ne 0 ] && procd_add_mdns "ssh" "tcp" "$Port" "daemon=dropbear"
+       procd_set_param respawn
        procd_close_instance
 }
 
 keygen()
 {
-       for keytype in rsa dss; do
+       for keytype in rsa; do
                # check for keys
                key=dropbear/dropbear_${keytype}_host_key
                [ -f /tmp/$key -o -s /etc/$key ] || {
@@ -107,24 +165,54 @@ keygen()
        chmod 0700 /etc/dropbear
 }
 
+load_interfaces()
+{
+       config_get interface "$1" Interface
+       config_get enable "$1" enable 1
+
+       [ "${enable}" = "1" ] && interfaces=" ${interface} ${interfaces}"
+}
+
+boot()
+{
+       BOOT=1
+       start "$@"
+}
+
 start_service()
 {
-       [ -s /etc/dropbear/dropbear_rsa_host_key -a \
-         -s /etc/dropbear/dropbear_dss_host_key ] || keygen
+       [ -s /etc/dropbear/dropbear_rsa_host_key ] || keygen
 
        . /lib/functions.sh
        . /lib/functions/network.sh
 
        config_load "${NAME}"
-       config_foreach dropbear_instance dropbear
+       config_foreach validate_section_dropbear dropbear dropbear_instance
 }
 
 service_triggers()
 {
-       procd_add_reload_trigger "dropbear"
+       local interfaces
+
+       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_add_validation validate_section_dropbear
 }
 
+shutdown() {
+       # close all open connections
+       killall dropbear
+}
+
 killclients()
 {
        local ignore=''