dropbear: 'rsakeyfile' -> 'keyfile' transition
[openwrt/staging/jow.git] / package / network / services / dropbear / files / dropbear.init
index 506f7dac654572b6cfc6e6a7f8bf607f1e09e423..18273e63d0e9085918d66a30cef5c3a9366aa943 100755 (executable)
@@ -9,8 +9,8 @@ USE_PROCD=1
 PROG=/usr/sbin/dropbear
 NAME=dropbear
 PIDCOUNT=0
-EXTRA_COMMANDS="killclients"
-EXTRA_HELP="   killclients Kill ${NAME} processes except servers and yourself"
+
+extra_command "killclients" "Kill ${NAME} processes except servers and yourself"
 
 _dropbearkey()
 {
@@ -60,6 +60,43 @@ hk_config__keyfile()
        hk_config 'keyfile' "$1"
 }
 
+hk_generate_as_needed()
+{
+       local kdir kgen ktype tdir kcount tfile
+       kdir='/etc/dropbear'
+
+       kgen=''
+       for ktype in ed25519 ecdsa rsa; do
+               hk_verify "${kdir}/dropbear_${ktype}_host_key" && continue
+
+               kgen="${kgen} ${ktype}"
+       done
+
+       [ -z "${kgen}" ] && return
+
+       tdir=$(mktemp -d); chmod 0700 "${tdir}"
+
+       kcount=0
+       for ktype in ${kgen}; do
+               tfile="${tdir}/dropbear_${ktype}_host_key"
+
+               if ! _dropbearkey -t ${ktype} -f "${tfile}"; then
+                       # unsupported key type
+                       rm -f "${tfile}"
+                       continue
+               fi
+
+               kcount=$((kcount+1))
+       done
+
+       if [ ${kcount} -ne 0 ]; then
+               mkdir -p "${kdir}"; chmod 0700 "${kdir}"; chown root "${kdir}"
+               mv -f "${tdir}/"* "${kdir}/"
+       fi
+
+       rm -rf "${tdir}"
+}
+
 append_ports()
 {
        local ipaddrs="$1"
@@ -82,12 +119,13 @@ validate_section_dropbear()
                'enable:bool:1' \
                'Interface:string' \
                'GatewayPorts:bool:0' \
+               'ForceCommand:string' \
                'RootPasswordAuth:bool:1' \
                'RootLogin:bool:1' \
                'rsakeyfile:file' \
                'keyfile:list(file)' \
                'BannerFile:file' \
-               'Port:list(port):22' \
+               'Port:port:22' \
                'SSHKeepAlive:uinteger:300' \
                'IdleTimeout:uinteger:0' \
                'MaxAuthTries:uinteger:3' \
@@ -117,19 +155,29 @@ dropbear_instance()
        PIDCOUNT="$(( ${PIDCOUNT} + 1))"
        local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid"
 
+       # Increase default receive window size to increase
+       # throughput on high latency links
+       if [ "${RecvWindowSize}" -eq "0" ]; then
+               RecvWindowSize="262144"
+       fi
+
        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
+       [ -n "${ForceCommand}" ] && procd_append_param command -c "${ForceCommand}"
        [ "${RootPasswordAuth}" -eq 0 ] && procd_append_param command -g
        [ "${RootLogin}" -eq 0 ] && procd_append_param command -w
+       config_list_foreach "$1" 'keyfile' hk_config__keyfile
        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"
+               logger -s -t "${NAME}" -p daemon.crit \
+                 "Option 'rsakeyfile' is considered to be DEPRECATED and will be REMOVED in future releases, use 'keyfile' list instead"
+               sed -i.before-upgrade -E -e 's/option(\s+)rsakeyfile/list keyfile/' \
+                 "/etc/config/${NAME}"
+               logger -s -t "${NAME}" -p daemon.crit \
+                 "Auto-transition 'option rsakeyfile' => 'list keyfile' in /etc/config/${NAME} is done, please verify your configuration"
                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}"
@@ -142,29 +190,6 @@ dropbear_instance()
        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
@@ -181,7 +206,7 @@ boot()
 
 start_service()
 {
-       [ -s /etc/dropbear/dropbear_rsa_host_key ] || keygen
+       hk_generate_as_needed
 
        . /lib/functions.sh
        . /lib/functions/network.sh
@@ -224,7 +249,7 @@ killclients()
        while [ "${pid}" -ne 0 ]
         do
                # get parent process id
-               pid=`cut -d ' ' -f 4 "/proc/${pid}/stat"`
+               pid=$(cut -d ' ' -f 4 "/proc/${pid}/stat")
                [ "${pid}" -eq 0 ] && break
 
                # check if client connection
@@ -235,14 +260,14 @@ killclients()
        done
 
        # get all server pids that should be ignored
-       for server in `cat /var/run/${NAME}.*.pid`
+       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}"`
+       for pid in $(pidof "${NAME}")
         do
                # check if correct program, otherwise process next pid
                grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" || {