dropbear.init 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #!/bin/sh /etc/rc.common
  2. # Copyright (C) 2006-2010 OpenWrt.org
  3. # Copyright (C) 2006 Carlos Sobrinho
  4. START=19
  5. STOP=50
  6. USE_PROCD=1
  7. PROG=/usr/sbin/dropbear
  8. NAME=dropbear
  9. PIDCOUNT=0
  10. EXTRA_COMMANDS="killclients"
  11. EXTRA_HELP=" killclients Kill ${NAME} processes except servers and yourself"
  12. _dropbearkey()
  13. {
  14. /usr/bin/dropbearkey "$@" 0<&- 1>&- 2>&-
  15. }
  16. # $1 - host key file name
  17. hk_verify()
  18. {
  19. [ -f "$1" ] || return 1
  20. [ -s "$1" ] || return 2
  21. _dropbearkey -y -f "$1" || return 3
  22. return 0
  23. }
  24. # $1 - hk_verify() return code
  25. hk_errmsg()
  26. {
  27. case "$1" in
  28. 0) ;;
  29. 1) echo "file does not exist" ;;
  30. 2) echo "file has zero length" ;;
  31. 3) echo "file is not valid host key or not supported" ;;
  32. *) echo "unknown error" ;;
  33. esac
  34. }
  35. # $1 - config option
  36. # $2 - host key file name
  37. hk_config()
  38. {
  39. local x m
  40. hk_verify "$2"; x=$?
  41. case "$x" in
  42. 0) procd_append_param command -r "$2"
  43. ;;
  44. *) m=$(hk_errmsg "$x")
  45. logger -t "${NAME}" -p daemon.warn \
  46. "option '$1', value '$2': $m, skipping"
  47. ;;
  48. esac
  49. }
  50. # $1 - host key file name
  51. hk_config__keyfile()
  52. {
  53. hk_config 'keyfile' "$1"
  54. }
  55. hk_generate_as_needed()
  56. {
  57. local kdir kgen ktype tdir kcount tfile
  58. kdir='/etc/dropbear'
  59. kgen=''
  60. for ktype in ecdsa rsa; do
  61. hk_verify "${kdir}/dropbear_${ktype}_host_key" && continue
  62. kgen="${kgen} ${ktype}"
  63. done
  64. [ -z "${kgen}" ] && return
  65. tdir=$(mktemp -d); chmod 0700 "${tdir}"
  66. kcount=0
  67. for ktype in ${kgen}; do
  68. tfile="${tdir}/dropbear_${ktype}_host_key"
  69. if ! _dropbearkey -t ${ktype} -f "${tfile}"; then
  70. # unsupported key type
  71. rm -f "${tfile}"
  72. continue
  73. fi
  74. kcount=$((kcount+1))
  75. done
  76. if [ ${kcount} -ne 0 ]; then
  77. mkdir -p "${kdir}"; chmod 0700 "${kdir}"; chown root "${kdir}"
  78. mv -f "${tdir}/"* "${kdir}/"
  79. fi
  80. rm -rf "${tdir}"
  81. }
  82. append_ports()
  83. {
  84. local ipaddrs="$1"
  85. local port="$2"
  86. [ -z "$ipaddrs" ] && {
  87. procd_append_param command -p "$port"
  88. return
  89. }
  90. for addr in $ipaddrs; do
  91. procd_append_param command -p "$addr:$port"
  92. done
  93. }
  94. validate_section_dropbear()
  95. {
  96. uci_load_validate dropbear dropbear "$1" "$2" \
  97. 'PasswordAuth:bool:1' \
  98. 'enable:bool:1' \
  99. 'Interface:string' \
  100. 'GatewayPorts:bool:0' \
  101. 'RootPasswordAuth:bool:1' \
  102. 'RootLogin:bool:1' \
  103. 'rsakeyfile:file' \
  104. 'keyfile:list(file)' \
  105. 'BannerFile:file' \
  106. 'Port:port:22' \
  107. 'SSHKeepAlive:uinteger:300' \
  108. 'IdleTimeout:uinteger:0' \
  109. 'MaxAuthTries:uinteger:3' \
  110. 'RecvWindowSize:uinteger:0' \
  111. 'mdns:bool:1'
  112. }
  113. dropbear_instance()
  114. {
  115. local ipaddrs
  116. [ "$2" = 0 ] || {
  117. echo "validation failed"
  118. return 1
  119. }
  120. [ -n "${Interface}" ] && {
  121. [ -n "${BOOT}" ] && return 0
  122. network_get_ipaddrs_all ipaddrs "${Interface}" || {
  123. echo "interface ${Interface} has no physdev or physdev has no suitable ip"
  124. return 1
  125. }
  126. }
  127. [ "${enable}" = "0" ] && return 1
  128. PIDCOUNT="$(( ${PIDCOUNT} + 1))"
  129. local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid"
  130. procd_open_instance
  131. procd_set_param command "$PROG" -F -P "$pid_file"
  132. [ "${PasswordAuth}" -eq 0 ] && procd_append_param command -s
  133. [ "${GatewayPorts}" -eq 1 ] && procd_append_param command -a
  134. [ "${RootPasswordAuth}" -eq 0 ] && procd_append_param command -g
  135. [ "${RootLogin}" -eq 0 ] && procd_append_param command -w
  136. if [ -n "${rsakeyfile}" ]; then
  137. logger -t ${NAME} -p daemon.warn \
  138. "option 'rsakeyfile' is considered to be deprecated and" \
  139. "will be removed in future releases, use 'keyfile' instead"
  140. hk_config 'rsakeyfile' "${rsakeyfile}"
  141. fi
  142. config_list_foreach "$1" "keyfile" hk_config__keyfile
  143. [ -n "${BannerFile}" ] && procd_append_param command -b "${BannerFile}"
  144. append_ports "${ipaddrs}" "${Port}"
  145. [ "${IdleTimeout}" -ne 0 ] && procd_append_param command -I "${IdleTimeout}"
  146. [ "${SSHKeepAlive}" -ne 0 ] && procd_append_param command -K "${SSHKeepAlive}"
  147. [ "${MaxAuthTries}" -ne 0 ] && procd_append_param command -T "${MaxAuthTries}"
  148. [ "${RecvWindowSize}" -gt 0 -a "${RecvWindowSize}" -le 1048576 ] && \
  149. procd_append_param command -W "${RecvWindowSize}"
  150. [ "${mdns}" -ne 0 ] && procd_add_mdns "ssh" "tcp" "$Port" "daemon=dropbear"
  151. procd_set_param respawn
  152. procd_close_instance
  153. }
  154. load_interfaces()
  155. {
  156. config_get interface "$1" Interface
  157. config_get enable "$1" enable 1
  158. [ "${enable}" = "1" ] && interfaces=" ${interface} ${interfaces}"
  159. }
  160. boot()
  161. {
  162. BOOT=1
  163. start "$@"
  164. }
  165. start_service()
  166. {
  167. hk_generate_as_needed
  168. . /lib/functions.sh
  169. . /lib/functions/network.sh
  170. config_load "${NAME}"
  171. config_foreach validate_section_dropbear dropbear dropbear_instance
  172. }
  173. service_triggers()
  174. {
  175. local interfaces
  176. procd_add_config_trigger "config.change" "dropbear" /etc/init.d/dropbear reload
  177. config_load "${NAME}"
  178. config_foreach load_interfaces dropbear
  179. [ -n "${interfaces}" ] && {
  180. for n in $interfaces ; do
  181. procd_add_interface_trigger "interface.*" $n /etc/init.d/dropbear reload
  182. done
  183. }
  184. procd_add_validation validate_section_dropbear
  185. }
  186. shutdown() {
  187. # close all open connections
  188. killall dropbear
  189. }
  190. killclients()
  191. {
  192. local ignore=''
  193. local server
  194. local pid
  195. # if this script is run from inside a client session, then ignore that session
  196. pid="$$"
  197. while [ "${pid}" -ne 0 ]
  198. do
  199. # get parent process id
  200. pid=`cut -d ' ' -f 4 "/proc/${pid}/stat"`
  201. [ "${pid}" -eq 0 ] && break
  202. # check if client connection
  203. grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" && {
  204. append ignore "${pid}"
  205. break
  206. }
  207. done
  208. # get all server pids that should be ignored
  209. for server in `cat /var/run/${NAME}.*.pid`
  210. do
  211. append ignore "${server}"
  212. done
  213. # get all running pids and kill client connections
  214. local skip
  215. for pid in `pidof "${NAME}"`
  216. do
  217. # check if correct program, otherwise process next pid
  218. grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" || {
  219. continue
  220. }
  221. # check if pid should be ignored (servers, ourself)
  222. skip=0
  223. for server in ${ignore}
  224. do
  225. if [ "${pid}" = "${server}" ]
  226. then
  227. skip=1
  228. break
  229. fi
  230. done
  231. [ "${skip}" -ne 0 ] && continue
  232. # kill process
  233. echo "${initscript}: Killing ${pid}..."
  234. kill -KILL ${pid}
  235. done
  236. }