X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=package%2Fnetwork%2Fservices%2Fdropbear%2Ffiles%2Fdropbear.init;h=173ab0928528b09598b28553f2ac31040122623e;hp=19aab3653bf7ba356c6ed8abe9c3157b37f1e08b;hb=5eb7864aadd5d4dffdb9befb87ba9a025a728b71;hpb=f2fdd8ebdb1617218201d16eeb54a5a905768764 diff --git a/package/network/services/dropbear/files/dropbear.init b/package/network/services/dropbear/files/dropbear.init index 19aab3653b..173ab09285 100755 --- a/package/network/services/dropbear/files/dropbear.init +++ b/package/network/services/dropbear/files/dropbear.init @@ -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,29 +12,109 @@ 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" +} + +hk_generate_as_needed() +{ + local kdir kgen ktype tdir kcount tfile + kdir='/etc/dropbear' + + kgen='' + for ktype in 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 ifname="$1" + local ipaddrs="$1" local port="$2" - grep -qs "^ *$ifname:" /proc/net/dev || { + [ -z "$ipaddrs" ] && { procd_append_param command -p "$port" return } - for addr in $( - ifconfig "$ifname" | sed -ne ' - /addr: *fe[89ab][0-9a-f]:/d - s/.* addr: *\([0-9a-f:\.]*\).*/\1/p - ' - ); do + for addr in $ipaddrs; do procd_append_param command -p "$addr:$port" done } validate_section_dropbear() { - uci_validate_section dropbear dropbear "${1}" \ + uci_load_validate dropbear dropbear "$1" "$2" \ 'PasswordAuth:bool:1' \ 'enable:bool:1' \ 'Interface:string' \ @@ -42,25 +122,34 @@ validate_section_dropbear() 'RootPasswordAuth:bool:1' \ 'RootLogin:bool:1' \ 'rsakeyfile:file' \ - 'dsskeyfile:file' \ + 'keyfile:list(file)' \ 'BannerFile:file' \ - 'Port:list(port):22' \ + 'Port:port:22' \ 'SSHKeepAlive:uinteger:300' \ - 'IdleTimeout:uinteger:0' - return $? + 'IdleTimeout:uinteger:0' \ + 'MaxAuthTries:uinteger:3' \ + 'RecvWindowSize:uinteger:0' \ + 'mdns:bool:1' } dropbear_instance() { - local PasswordAuth enable Interface GatewayPorts \ - RootPasswordAuth RootLogin rsakeyfile \ - dsskeyfile BannerFile Port + 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 + } + } + [ "${enable}" = "0" ] && return 1 PIDCOUNT="$(( ${PIDCOUNT} + 1))" local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid" @@ -71,57 +160,73 @@ 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}" - [ -n "${Interface}" ] && network_get_device Interface "${Interface}" - append_ports "${Interface}" "${Port}" + 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() +load_interfaces() { - 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 + config_get interface "$1" Interface + config_get enable "$1" enable 1 - 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 + [ "${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 + hk_generate_as_needed . /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='' @@ -162,7 +267,7 @@ killclients() skip=0 for server in ${ignore} do - if [ "${pid}" == "${server}" ] + if [ "${pid}" = "${server}" ] then skip=1 break