[package] sslh: update to 1.9
[packages.git] / net / sslh / files / sslh.init
1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2009-2011 OpenWrt.org
3
4 NAME=sslh
5 PROG=/usr/sbin/sslh
6 START=95
7 PIDCOUNT=0
8 EXTRA_COMMANDS="killclients"
9 EXTRA_HELP="    killclients Kill ${NAME} processes except servers and yourself"
10
11 sslh_start()
12 {
13         local section="$1"
14
15         # check if section is enabled (default)
16         local enabled
17         config_get_bool enabled "${section}" enable 1
18         [ "${enabled}" -eq 0 ] && return 1
19
20         # increase pid file count to handle multiple instances correctly
21         PIDCOUNT="$(( ${PIDCOUNT} + 1 ))"
22
23         # prepare parameters (initialise with pid file)
24         local args="-P /var/run/${NAME}.${PIDCOUNT}.pid"
25         local val
26         # A) listen parameter
27         config_get vals "${section}" listen
28         [ -n "${vals}" ] && for val in $vals; do append args "-p ${val}"; done
29         # B) ssh parameter
30         config_get val "${section}" ssh
31         [ -n "${val}" ] && append args "--ssh ${val}"
32         # C) ssl parameter
33         config_get val "${section}" ssl
34         [ -n "${val}" ] && append args "--ssl ${val}"
35         # D) openvpn parameter
36         config_get val "${section}" openvpn
37         [ -n "${val}" ] && append args "--openvpn ${val}"
38         # E) tinc parameter
39         config_get val "${section}" tinc
40         [ -n "${val}" ] && append args "--tinc ${val}"
41         # F) timeout (before a connection is considered to be SSH)
42         config_get val "${section}" timeout
43         [ -n "${val}" ] && append args "-t ${val}"
44         # G) verbose parameter
45         local verbosed
46         config_get_bool verbosed "${section}" verbose 0
47         [ "${verbosed}" -ne 0 ] && append args "-v"
48
49         # execute program and return its exit code
50         [ "${verbosed}" -ne 0 ] && echo "${initscript}: section ${section} started via ${PROG} ${args}"
51         ${PROG} ${args}
52         return $?
53 }
54
55 start()
56 {
57         config_load "${NAME}"
58         config_foreach sslh_start sslh
59 }
60
61 stop()
62 {
63         local pidfile
64         local rc=0
65
66         # killing all server processes
67         for pidfile in `ls /var/run/${NAME}.*.pid`
68          do
69                 start-stop-daemon -q -K -s KILL -p "${pidfile}" -n "${NAME}"
70                 [ $? -ne 0 ] && rc=1
71                 rm -f "${pidfile}"
72         done
73         [ -z "${pidfile}" ] && echo "${initscript}: no pid files, if you get problems with start then try killclients"
74         [ ${rc} -ne 0 ] && echo "${initscript}: inconsistency in pid files, if you get problems with start then try killclients"
75 }
76
77 killclients()
78 {
79         local ignore=''
80         local server
81         local pid
82         local connection
83         local proto
84         local address
85
86         # if this script is run from inside a client session, then ignore that session
87         pid="$$"
88         while [ "${pid}" -ne 0 ]
89          do
90                 # get parent process id
91                 pid=`cut -d ' ' -f 4 "/proc/${pid}/stat"`
92                 [ "${pid}" -eq 0 ] && break
93
94                 # check if pid is connected to a client connection
95                 # a) get established connection for pid
96                 connection=`netstat -tupn 2>/dev/null | sed "s/[ ]\+/ /g" | grep -e "ESTABLISHED ${pid}/"`
97                 [ -z "${connection}" ] && continue
98                 #    get connection details for foreign address
99                 proto=`echo ${connection} | cut -d ' ' -f 1`
100                 address=`echo ${connection} | cut -d ' ' -f 5`
101
102                 # b) get pid for foreign address, only possible if foreign address is from this machine itself
103                 connection=`netstat -tupn 2>/dev/null | sed "s/[ ]\+/ /g" | grep -e "^${proto}.*${address}.*ESTABLISHED.*/${NAME}"`
104                 [ -z "${connection}" ] && continue
105                 #    check that the local address (field 4) corresponds to the foreign address of the previous connection
106                 server=`echo ${connection} | cut -d ' ' -f 4`
107                 [ "${server}" != "${address}" ] && continue
108                 #    get pid from connection
109                 server=`echo ${connection} | cut -d ' ' -f 7 | cut -d '/' -f 1`
110
111                 # check if client connection
112                 grep -F -q -e "${PROG}" "/proc/${server}/cmdline" && {
113                         append ignore "${server}"
114                         break
115                 }
116         done
117
118         # get all server pids that should be ignored
119         for server in `cat /var/run/${NAME}.*.pid`
120          do
121                 append ignore "${server}"
122         done
123
124         # get all running pids and kill client connections
125         local skip
126         for pid in `pidof "${NAME}"`
127          do
128                 # check if correct program, otherwise process next pid
129                 grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" || {
130                         continue
131                 }
132
133                 # check if pid should be ignored (servers, ourself)
134                 skip=0
135                 for server in ${ignore}
136                  do
137                         if [ "${pid}" == "${server}" ]
138                          then
139                                 skip=1
140                                 break
141                         fi
142                 done
143                 [ "${skip}" -ne 0 ] && continue
144
145                 # kill process
146                 echo "${initscript}: Killing ${pid}..."
147                 kill -KILL ${pid}
148         done
149 }