handle zero size Base64 conversions
[strongswan.git] / src / _updown_espmark / _updown_espmark
1 #! /bin/sh
2 # iproute2 version, default updown script
3 #
4 # Copyright (C) 2003-2004 Nigel Meteringham
5 # Copyright (C) 2003-2004 Tuomo Soini
6 # Copyright (C) 2002-2004 Michael Richardson
7 # Copyright (C) 2005      Andreas Steffen <andreas.steffen@strongsec.com>
8
9 # This program is free software; you can redistribute it and/or modify it
10 # under the terms of the GNU General Public License as published by the
11 # Free Software Foundation; either version 2 of the License, or (at your
12 # option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
13
14 # This program is distributed in the hope that it will be useful, but
15 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 # for more details.
18
19
20
21 # CAUTION:  Installing a new version of strongSwan will install a new
22 # copy of this script, wiping out any custom changes you make.  If
23 # you need changes, make a copy of this under another name, and customize
24 # that, and use the (left/right)updown parameters in ipsec.conf to make
25 # FreeS/WAN use yours instead of this default one.
26
27 # things that this script gets (from ipsec_pluto(8) man page)
28 #
29 #
30 #      PLUTO_VERSION
31 #              indicates  what  version of this interface is being
32 #              used.  This document describes version  1.1.   This
33 #              is upwardly compatible with version 1.0.
34 #
35 #       PLUTO_VERB
36 #              specifies the name of the operation to be performed
37 #              (prepare-host, prepare-client, up-host, up-client,
38 #              down-host, or down-client).  If the address family
39 #              for security gateway to security gateway communica-
40 #              tions is IPv6, then a suffix of -v6 is added to the
41 #              verb.
42 #
43 #       PLUTO_CONNECTION
44 #              is the name of the  connection  for  which  we  are
45 #              routing.
46 #
47 #       PLUTO_NEXT_HOP
48 #              is the next hop to which packets bound for the peer
49 #              must be sent.
50 #
51 #       PLUTO_INTERFACE
52 #              is the name of the ipsec interface to be used.
53 #
54 #       PLUTO_ME
55 #              is the IP address of our host.
56 #
57 #       PLUTO_MY_ID
58 #              is the ID of our host.
59 #
60 #       PLUTO_MY_CLIENT
61 #              is the IP address / count of our client subnet.  If
62 #              the  client  is  just  the  host,  this will be the
63 #              host's own IP address / max (where max  is  32  for
64 #              IPv4 and 128 for IPv6).
65 #
66 #       PLUTO_MY_CLIENT_NET
67 #              is the IP address of our client net.  If the client
68 #              is just the host, this will be the  host's  own  IP
69 #              address.
70 #
71 #       PLUTO_MY_CLIENT_MASK
72 #              is  the  mask for our client net.  If the client is
73 #              just the host, this will be 255.255.255.255.
74 #
75 #       PLUTO_MY_SOURCEIP
76 #              if non-empty, then the source address for the route will be
77 #              set to this IP address.
78 #
79 #       PLUTO_MY_PROTOCOL
80 #              is the IP protocol that will be transported.
81 #
82 #       PLUTO_MY_PORT
83 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
84 #              restricted on our side.
85 #
86 #       PLUTO_PEER
87 #              is the IP address of our peer.
88 #
89 #       PLUTO_PEER_ID
90 #              is the ID of our peer.
91 #
92 #       PLUTO_PEER_CA
93 #              is the CA which issued the cert of our peer.
94 #
95 #       PLUTO_PEER_CLIENT
96 #              is the IP address / count of the peer's client sub-
97 #              net.   If the client is just the peer, this will be
98 #              the peer's own IP address / max (where  max  is  32
99 #              for IPv4 and 128 for IPv6).
100 #
101 #       PLUTO_PEER_CLIENT_NET
102 #              is the IP address of the peer's client net.  If the
103 #              client is just the peer, this will  be  the  peer's
104 #              own IP address.
105 #
106 #       PLUTO_PEER_CLIENT_MASK
107 #              is  the  mask  for  the  peer's client net.  If the
108 #              client   is   just   the   peer,   this   will   be
109 #              255.255.255.255.
110 #
111 #       PLUTO_PEER_PROTOCOL
112 #              is the IP protocol that will be transported.
113 #
114 #       PLUTO_PEER_PORT
115 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
116 #              restricted on the peer side.
117 #
118 #       PLUTO_XAUTH_ID
119 #              is an optional user ID employed by the XAUTH protocol
120 #
121 #       PLUTO_MARK_IN
122 #              is an optional XFRM mark set on the inbound IPsec SA
123 #
124 #       PLUTO_MARK_OUT
125 #              is an optional XFRM mark set on the outbound IPsec SA
126 #
127 #       PLUTO_UDP_ENC
128 #              contains the remote UDP port in the case of ESP_IN_UDP
129 #              encapsulation
130 #
131
132 # logging of VPN connections
133 #
134 # tag put in front of each log entry:
135 TAG=vpn
136 #
137 # syslog facility and priority used:
138 FAC_PRIO=local0.notice
139 #
140 # to create a special vpn logging file, put the following line into
141 # the syslog configuration file /etc/syslog.conf:
142 #
143 # local0.notice                   -/var/log/vpn
144 #
145
146 # check interface version
147 case "$PLUTO_VERSION" in
148 1.[0])  # Older Pluto?!?  Play it safe, script may be using new features.
149         echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
150         echo "$0:       called by obsolete Pluto?" >&2
151         exit 2
152         ;;
153 1.*)    ;;
154 *)      echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2
155         exit 2
156         ;;
157 esac
158
159 # check parameter(s)
160 case "$1:$*" in
161 ':')                    # no parameters
162         ;;
163 ipfwadm:ipfwadm)        # due to (left/right)firewall; for default script only
164         ;;
165 custom:*)               # custom parameters (see above CAUTION comment)
166         ;;
167 *)      echo "$0: unknown parameters \`$*'" >&2
168         exit 2
169         ;;
170 esac
171
172 # utility functions for route manipulation
173 # Meddling with this stuff should not be necessary and requires great care.
174 uproute() {
175         doroute add
176         ip route flush cache
177 }
178 downroute() {
179         doroute delete
180         ip route flush cache
181 }
182
183 addsource() {
184         st=0
185         if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
186         then
187             it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
188             oops="`eval $it 2>&1`"
189             st=$?
190             if test " $oops" = " " -a " $st" != " 0"
191             then
192                 oops="silent error, exit status $st"
193             fi
194             if test " $oops" != " " -o " $st" != " 0"
195             then
196                 echo "$0: addsource \`$it' failed ($oops)" >&2
197             fi
198         fi
199         return $st
200 }
201
202 doroute() {
203         st=0
204         parms="$PLUTO_PEER_CLIENT"
205
206         parms2=
207         if [ -n "$PLUTO_NEXT_HOP" ]
208         then
209            parms2="via $PLUTO_NEXT_HOP"
210         fi
211         parms2="$parms2 dev $PLUTO_INTERFACE"
212
213         if [ -z "$PLUTO_MY_SOURCEIP" ]
214         then
215             for dir in /etc/sysconfig /etc/conf.d; do
216                 if [ -f "$dir/defaultsource" ]
217                 then
218                     . "$dir/defaultsource"
219                 fi
220             done
221
222             if [ -n "$DEFAULTSOURCE" ]
223             then
224                 PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
225             fi
226         fi
227
228         parms3=
229         if test "$1" = "add" -a -n "$PLUTO_MY_SOURCEIP"
230         then
231             addsource
232             parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*}"
233         fi
234
235         case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
236         "0.0.0.0/0.0.0.0")
237                 # opportunistic encryption work around
238                 # need to provide route that eclipses default, without 
239                 # replacing it.
240                 it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
241                         ip route $1 128.0.0.0/1 $parms2 $parms3"
242                 ;;
243         *)      it="ip route $1 $parms $parms2 $parms3"
244                 ;;
245         esac
246         oops="`eval $it 2>&1`"
247         st=$?
248         if test " $oops" = " " -a " $st" != " 0"
249         then
250             oops="silent error, exit status $st"
251         fi
252         if test " $oops" != " " -o " $st" != " 0"
253         then
254             echo "$0: doroute \`$it' failed ($oops)" >&2
255         fi
256         return $st
257 }
258  
259 # define ESP mark
260 ESP_MARK=50
261
262 # add the following static rule to the INPUT chain in the mangle table
263 # iptables -t mangle -A INPUT -p 50 -j MARK --set-mark 50
264
265 # NAT traversal via UDP encapsulation is supported with the rule
266 # iptables -t mangle -A INPUT -p udp --dport 4500 -j MARK --set-mark 50
267
268 # in the presence of KLIPS and ipsecN interfaces do not use ESP mark rules
269 if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
270 then
271         CHECK_MARK=""
272 else
273         CHECK_MARK="-m mark --mark $ESP_MARK"
274 fi
275
276 # are there port numbers?
277 if [ "$PLUTO_MY_PORT" != 0 ]
278 then
279         S_MY_PORT="--sport $PLUTO_MY_PORT"
280         D_MY_PORT="--dport $PLUTO_MY_PORT"
281 fi
282 if [ "$PLUTO_PEER_PORT" != 0 ]
283 then
284         S_PEER_PORT="--sport $PLUTO_PEER_PORT"
285         D_PEER_PORT="--dport $PLUTO_PEER_PORT"
286 fi
287
288 # resolve octal escape sequences
289 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
290 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
291
292 # the big choice
293 case "$PLUTO_VERB:$1" in
294 prepare-host:*|prepare-client:*)
295         # delete possibly-existing route (preliminary to adding a route)
296         case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
297         "0.0.0.0/0.0.0.0")
298                 # need to provide route that eclipses default, without 
299                 # replacing it.
300                 parms1="0.0.0.0/1"
301                 parms2="128.0.0.0/1"
302                 it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
303                 oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
304                 ;;
305         *)
306                 parms="$PLUTO_PEER_CLIENT"
307                 it="ip route delete $parms 2>&1"
308                 oops="`ip route delete $parms 2>&1`"
309                 ;;
310         esac
311         status="$?"
312         if test " $oops" = " " -a " $status" != " 0"
313         then
314                 oops="silent error, exit status $status"
315         fi
316         case "$oops" in
317         *'RTNETLINK answers: No such process'*) 
318                 # This is what route (currently -- not documented!) gives
319                 # for "could not find such a route".
320                 oops=
321                 status=0
322                 ;;
323         esac
324         if test " $oops" != " " -o " $status" != " 0"
325         then
326                 echo "$0: \`$it' failed ($oops)" >&2
327         fi
328         exit $status
329         ;;
330 route-host:*|route-client:*)
331         # connection to me or my client subnet being routed
332         uproute
333         ;;
334 unroute-host:*|unroute-client:*)
335         # connection to me or my client subnet being unrouted
336         downroute
337         ;;
338 up-host:*)
339         # connection to me coming up
340         # If you are doing a custom version, firewall commands go here.
341         iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
342             -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
343             -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
344         iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
345             -s $PLUTO_ME $S_MY_PORT \
346             -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
347         #
348         if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
349         then
350           logger -t $TAG -p $FAC_PRIO \
351             "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
352         else
353           logger -t $TAG -p $FAC_PRIO \
354             "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
355         fi
356         ;;
357 down-host:*)
358         # connection to me going down
359         # If you are doing a custom version, firewall commands go here.
360         # connection to me going down
361         # If you are doing a custom version, firewall commands go here.
362         iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
363             -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
364             -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
365         iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
366             -s $PLUTO_ME $S_MY_PORT \
367             -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
368         #
369         if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
370         then
371           logger -t $TAG -p $FAC_PRIO -- \
372             "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
373         else
374           logger -t $TAG -p $FAC_PRIO -- \
375           "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
376         fi
377         ;;
378 up-client:)
379         # connection to my client subnet coming up
380         # If you are doing a custom version, firewall commands go here.
381         iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
382             -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
383             -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
384         iptables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
385             -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
386             -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
387                $CHECK_MARK -j ACCEPT
388         #
389         if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
390         then
391           logger -t $TAG -p $FAC_PRIO \
392             "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
393         else
394           logger -t $TAG -p $FAC_PRIO \
395             "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
396         fi
397         ;;
398 down-client:)
399         # connection to my client subnet going down
400         # If you are doing a custom version, firewall commands go here.
401         iptables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
402             -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
403             -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
404         iptables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
405             -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
406             -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
407                $CHECK_MARK -j ACCEPT
408         #
409         if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
410         then
411           logger -t $TAG -p $FAC_PRIO -- \
412             "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
413         else
414           logger -t $TAG -p $FAC_PRIO -- \
415             "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
416         fi
417         ;;
418 up-client:ipfwadm)
419         # connection to client subnet, with (left/right)firewall=yes, coming up
420         # This is used only by the default updown script, not by your custom
421         # ones, so do not mess with it; see CAUTION comment up at top.
422         ipfwadm -F -i accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
423                 -D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
424         ;;
425 down-client:ipfwadm)
426         # connection to client subnet, with (left/right)firewall=yes, going down
427         # This is used only by the default updown script, not by your custom
428         # ones, so do not mess with it; see CAUTION comment up at top.
429         ipfwadm -F -d accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
430                 -D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
431         ;;
432 #
433 # IPv6
434 #
435 prepare-host-v6:*|prepare-client-v6:*)
436         ;;
437 route-host-v6:*|route-client-v6:*)
438         # connection to me or my client subnet being routed
439         #uproute_v6
440         ;;
441 unroute-host-v6:*|unroute-client-v6:*)
442         # connection to me or my client subnet being unrouted
443         #downroute_v6
444         ;;
445 up-host-v6:*)
446         # connection to me coming up
447         # If you are doing a custom version, firewall commands go here.
448         ;;
449 down-host-v6:*)
450         # connection to me going down
451         # If you are doing a custom version, firewall commands go here.
452         ;;
453 up-client-v6:)
454         # connection to my client subnet coming up
455         # If you are doing a custom version, firewall commands go here.
456         ;;
457 down-client-v6:)
458         # connection to my client subnet going down
459         # If you are doing a custom version, firewall commands go here.
460         ;;
461 *)      echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
462         exit 1
463         ;;
464 esac