#!/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' \ 'dsskeyfile: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 \ dsskeyfile 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 "${dsskeyfile}" ] && procd_append_param command -d "${dsskeyfile}" [ -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_close_instance } keygen() { for keytype in rsa dss; 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 } start_service() { [ -s /etc/dropbear/dropbear_rsa_host_key -a \ -s /etc/dropbear/dropbear_dss_host_key ] || keygen . /lib/functions.sh . /lib/functions/network.sh config_load "${NAME}" config_foreach dropbear_instance dropbear } service_triggers() { procd_add_reload_trigger "dropbear" 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 }