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