dropbear: register a config.change trigger
[openwrt.git] / package / network / services / dropbear / files / dropbear.init
1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2006-2010 OpenWrt.org
3 # Copyright (C) 2006 Carlos Sobrinho
4
5 START=50
6 STOP=50
7
8 USE_PROCD=1
9
10 NAME=dropbear
11 PROG=/usr/sbin/dropbear
12 PIDCOUNT=0
13 EXTRA_COMMANDS="killclients"
14 EXTRA_HELP="    killclients Kill ${NAME} processes except servers and yourself"
15
16 dropbear_instance()
17 {
18         append_ports()
19         {
20                 local ifname="$1"
21                 local port="$2"
22
23                 grep -qs "^ *$ifname:" /proc/net/dev || {
24                         procd_append_param command -p "$port"
25                         return
26                 }
27
28                 for addr in $(
29                         ifconfig "$ifname" | sed -ne '
30                                 /addr: *fe[89ab][0-9a-f]:/d
31                                 s/.* addr: *\([0-9a-f:\.]*\).*/\1/p
32                         '
33                 ); do
34                         procd_append_param command -p "$addr:$port"
35                 done
36         }
37
38
39         local section="$1"
40
41         # check if section is enabled (default)
42         local enabled
43         config_get_bool enabled "${section}" enable 1
44         [ "${enabled}" -eq 0 ] && return 1
45
46         # increase pid file count to handle multiple instances correctly
47         PIDCOUNT="$(( ${PIDCOUNT} + 1))"
48
49         local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid"
50
51         procd_open_instance
52         procd_set_param command "$PROG" -F -P "$pid_file"
53
54         # prepare parameters (initialise with pid file)
55         local val
56
57         # A) password authentication
58         config_get_bool val "${section}" PasswordAuth 1
59         [ "${val}" -eq 0 ] && procd_append_param command -s
60
61         # B) listen interface and port
62         local port
63         local interface
64         config_get interface "${section}" Interface
65         [ -n "$interface" ] && network_get_device interface "$interface"
66         config_get port "${section}" Port 22
67         append_ports "$interface" "$port"
68         # C) banner file
69         config_get val "${section}" BannerFile
70         [ -f "${val}" ] && procd_append_param command -b "${val}"
71         # D) gatewayports
72         config_get_bool val "${section}" GatewayPorts 0
73         [ "${val}" -eq 1 ] && procd_append_param command -a
74         # E) root password authentication
75         config_get_bool val "${section}" RootPasswordAuth 1
76         [ "${val}" -eq 0 ] && procd_append_param command -g
77         # F) root login
78         config_get_bool val "${section}" RootLogin 1
79         [ "${val}" -eq 0 ] && procd_append_param command -w
80         # G) host keys
81         config_get val "${section}" rsakeyfile
82         [ -f "${val}" ] && procd_append_param command -r "${val}"
83         config_get val "${section}" dsskeyfile
84         [ -f "${val}" ] && procd_append_param command -d "${val}"
85
86         procd_close_instance
87 }
88
89 keygen()
90 {
91         for keytype in rsa dss; do
92                 # check for keys
93                 key=dropbear/dropbear_${keytype}_host_key
94                 [ -f /tmp/$key -o -s /etc/$key ] || {
95                         # generate missing keys
96                         mkdir -p /tmp/dropbear
97                         [ -x /usr/bin/dropbearkey ] && {
98                                 /usr/bin/dropbearkey -t $keytype -f /tmp/$key 2>&- >&- && exec /etc/rc.common "$initscript" start
99                         } &
100                 exit 0
101                 }
102         done
103
104         lock /tmp/.switch2jffs
105         mkdir -p /etc/dropbear
106         mv /tmp/dropbear/dropbear_* /etc/dropbear/
107         lock -u /tmp/.switch2jffs
108         chown root /etc/dropbear
109         chmod 0700 /etc/dropbear
110 }
111
112 start_service()
113 {
114         [ -s /etc/dropbear/dropbear_rsa_host_key -a \
115           -s /etc/dropbear/dropbear_dss_host_key ] || keygen
116
117         . /lib/functions.sh
118         . /lib/functions/network.sh
119
120         config_load "${NAME}"
121         config_foreach dropbear_instance dropbear
122 }
123
124 service_triggers()
125 {
126         procd_add_config_trigger "dropbear" "/etc/init.d/dropbear" "restart"
127 }
128
129 killclients()
130 {
131         local ignore=''
132         local server
133         local pid
134
135         # if this script is run from inside a client session, then ignore that session
136         pid="$$"
137         while [ "${pid}" -ne 0 ]
138          do
139                 # get parent process id
140                 pid=`cut -d ' ' -f 4 "/proc/${pid}/stat"`
141                 [ "${pid}" -eq 0 ] && break
142
143                 # check if client connection
144                 grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" && {
145                         append ignore "${pid}"
146                         break
147                 }
148         done
149
150         # get all server pids that should be ignored
151         for server in `cat /var/run/${NAME}.*.pid`
152          do
153                 append ignore "${server}"
154         done
155
156         # get all running pids and kill client connections
157         local skip
158         for pid in `pidof "${NAME}"`
159          do
160                 # check if correct program, otherwise process next pid
161                 grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" || {
162                         continue
163                 }
164
165                 # check if pid should be ignored (servers, ourself)
166                 skip=0
167                 for server in ${ignore}
168                  do
169                         if [ "${pid}" == "${server}" ]
170                          then
171                                 skip=1
172                                 break
173                         fi
174                 done
175                 [ "${skip}" -ne 0 ] && continue
176
177                 # kill process
178                 echo "${initscript}: Killing ${pid}..."
179                 kill -KILL ${pid}
180         done
181 }