OpenWrt – Rev 1

Subversion Repositories:
Rev:
#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2010 OpenWrt.org
# Copyright (C) 2006 Carlos Sobrinho

START=19
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_load_validate dropbear dropbear "$1" "$2" \
                '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' \
                'MaxAuthTries:uinteger:3' \
                'RecvWindowSize:uinteger:0' \
                'mdns:bool:1'
}

dropbear_instance()
{
        local ipaddrs

        [ "$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
                }
        }

        [ "${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}"
        [ "${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; 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
        config_get enable "$1" enable 1

        [ "${enable}" = "1" ] && interfaces=" ${interface} ${interfaces}"
}

boot()
{
        BOOT=1
        start "$@"
}

start_service()
{
        [ -s /etc/dropbear/dropbear_rsa_host_key ] || keygen

        . /lib/functions.sh
        . /lib/functions/network.sh

        config_load "${NAME}"
        config_foreach validate_section_dropbear dropbear dropbear_instance
}

service_triggers()
{
        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=''
        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
}