2 # user interface to automatic keying and Pluto in general
3 # Copyright (C) 1998, 1999, 2000 Henry Spencer.
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2 of the License, or (at your
8 # option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 # RCSID $Id: auto,v 1.73 2002/03/26 05:07:48 henry Exp $
19 $me [--showonly] [--asynchronous] --up connectionname
20 $me [--showonly] --{add|delete|replace|down} connectionname
21 $me [--showonly] --{route|unroute} connectionname
22 $me [--showonly] --{ready|status}
23 $me [--showonly] --{rereadsecrets|rereadmycert|rereadcacerts}
24 $me [--showonly] --{rereadcrls|rereadall}
25 $me [--showonly] [--utc] --{listpubkeys|listcerts|listcerts}
26 $me [--showonly] --{listcacerts|listcrls|listall}
27 other options: [--config ipsecconfigfile] [--verbose] [--show]"
31 info=/var/run/ipsec.info
35 logfilter='$1 != "002"'
43 --help) echo "$usage" ; exit 0 ;;
44 --version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
46 --showonly) showonly=yes ;;
48 --config) config="--config $2" ; shift ;;
49 --noinclude) noinclude=--noinclude ;;
50 --asynchronous) async="--asynchronous" ;;
51 --verbose) logfilter='1' ;;
52 --up|--down|--add|--delete|--replace|--route|--unroute)
62 --rereadsecrets|--rereadmycert|--rereadcacerts|\
63 --rereadcrls|--rereadall|\
64 --listpubkeys|--listcerts|--listcacerts|--listcrls|--listall)
74 -*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
82 2:*:up|2:*:down|2:*:add|2:*:delete|2:*:replace|2:*:route|2:*:unroute)
83 echo "$me: warning: obsolete command syntax used" >&2
87 1:ready:|1:status:|1:rereadsecrets:|1:rereadmycert|rereadcacerts|\
88 1:rereadcrls|1:rereadall|1:listpubkeys|1:listcerts|1:listcacerts|\
90 echo "$me: warning: obsolete command syntax used" >&2
93 --*) if test " $argc" -ne $#
100 *) echo "$usage" >&2 ; exit 2 ;;
116 awk "/^= / { exit \$2 } $logfilter { print }"
121 --ready) echo "ipsec whack --listen" | runit ; exit ;;
122 --rereadsecrets) echo "ipsec whack --rereadsecrets" | runit ; exit ;;
123 --rereadmycert) echo "ipsec whack --rereadmycert" | runit ; exit ;;
124 --rereadcacerts) echo "ipsec whack --rereadcacerts" | runit ; exit ;;
125 --rereadcrls) echo "ipsec whack --rereadcrls" | runit ; exit ;;
126 --rereadall) echo "ipsec whack --rereadall" | runit ; exit ;;
127 --listpubkeys) echo "ipsec whack $utc --listpubkeys" | runit ; exit ;;
128 --listcerts) echo "ipsec whack $utc --listcerts" | runit ; exit ;;
129 --listcacerts) echo "ipsec whack $utc --listcacerts" | runit ; exit ;;
130 --listcrls) echo "ipsec whack $utc --listcrls" | runit ; exit ;;
131 --listall) echo "ipsec whack $utc --listall" | runit ; exit ;;
132 --up) echo "ipsec whack $async --name $names --initiate" | runit ; exit ;;
133 --down) echo "ipsec whack --name $names --terminate" | runit ; exit ;;
134 --delete) echo "ipsec whack --name $names --delete" | runit ; exit ;;
135 --route) echo "ipsec whack --name $names --route" | runit ; exit ;;
136 --unroute) echo "ipsec whack --name $names --unroute" | runit ; exit ;;
137 --status) echo "ipsec whack --status" | runit ; exit ;;
145 ipsec _confread $config $noinclude $names |
150 draddr = "'"$defaultrouteaddr"'"
151 drnexthop = "'"$defaultroutenexthop"'"
155 print "PATH=\"'"$PATH"'\""
185 fail("internal error, unknown type code " v($1))
188 print "ipsec_auto: fatal error in " v(name) ": " m |err
193 if ((k in s) && s[k] != "yes" && s[k] != "no")
194 fail("parameter " v(k) " must be \"yes\" or \"no\"")
196 function default(k, val) {
200 function was(new, old) {
201 if (!(new in s) && (old in s))
206 fail("connection has no " v(k) " parameter specified")
208 fail("parameter " v(k) " value must be non-empty")
210 function integer(k) {
213 if (s[k] !~ /^[0-9]+$/)
214 fail("parameter " v(k) " value must be integer")
216 function duration(k, n, t) {
220 n = substr(t, 1, length(t)-1)
223 else if (t ~ /^[0-9]+s$/)
225 else if (t ~ /^[0-9]+(\.[0-9]+)?m$/)
227 else if (t ~ /^[0-9]+(\.[0-9]+)?h$/)
229 else if (t ~ /^[0-9]+(\.[0-9]+)?d$/)
230 s[k] = int(n*3600*24)
232 fail("parameter " v(k) " not valid time, must be nnn[smhd]")
234 function nexthopset(dir, val, k) {
237 fail("non-default value of " k " is being overridden")
243 function id(dir, k) {
249 function whackkey(dir, rk, n) {
250 if (id(dir) == "%opportunistic")
252 rk = s[dir "rsasigkey"]
253 if (rk == "" || rk == "%cert" || rk == "0x00")
255 n = "\"\\\"" name "\\\" " dir "rsasigkey\""
257 print "ipsec whack --label", n,
258 "--keyid", q(id(dir)), "\\"
260 print "ipsec whack --label", n, "--keyid", q(id(dir)),
261 "--pubkeyrsa", q(rk), "\\"
264 function q(str) { # quoting for shell
267 function qs(k) { # utility abbreviation for q(s[k])
270 function v(str) { # quoting for human viewing
275 fail("internal error, output called inappropriately")
277 default("type", "tunnel")
278 if (s["type"] == "tunnel") {
279 # do NOT default subnets to side/32, despite what
281 } else if (s["type"] == "transport") {
282 if ("leftsubnet" in s)
283 fail("type=transport incompatible with leftsubnet")
284 if ("rightsubnet" in s)
285 fail("type=transport incompatible with rightsubnet")
287 fail("only know how to do type tunnel or transport")
291 if (s["left"] == "%defaultroute") {
292 if (s["right"] == "%defaultroute")
293 fail("left and right cannot both be %defaultroute")
295 fail("%defaultroute requested but not known")
297 nexthopset("left", drnexthop)
298 } else if (s["right"] == "%defaultroute") {
300 fail("%defaultroute requested but not known")
302 nexthopset("right", drnexthop)
305 default("keyexchange", "ike")
306 if (s["keyexchange"] != "ike")
307 fail("only know how to do keyexchange=ike")
308 default("auth", "esp")
309 if (("auth" in s) && s["auth"] != "esp" && s["auth"] != "ah")
310 fail("only know how to do auth=esp or auth=ah")
312 default("pfs", "yes")
314 default("compress", "no")
315 was("keylife", "lifetime")
316 default("keylife", "8h")
319 default("rekey", "yes")
320 was("rekeymargin", "rekeystart")
321 default("rekeymargin", "9m")
322 duration("rekeymargin")
323 was("keyingtries", "rekeytries")
324 default("keyingtries", 3)
325 integer("keyingtries")
326 if ("rekeyfuzz" in s) {
327 if (s["rekeyfuzz"] !~ /%$/)
328 fail("rekeyfuzz must be nnn%")
330 s["rekeyfuzz"] = substr(r, 1, length(r)-1)
333 duration("ikelifetime")
334 default("disablearrivalcheck", "yes") # unfortunate
336 default("leftnexthop", "%direct")
337 default("rightnexthop", "%direct")
338 if (s["leftnexthop"] == s["left"])
339 fail("left and leftnexthop must not be the same")
340 if (s["rightnexthop"] == s["right"])
341 fail("right and rightnexthop must not be the same")
342 if (s["leftnexthop"] == "%defaultroute") {
344 fail("%defaultroute requested but not known")
345 s["leftnexthop"] = drnexthop
347 if (s["rightnexthop"] == "%defaultroute") {
349 fail("%defaultroute requested but not known")
350 s["rightnexthop"] = drnexthop
353 if ("leftfirewall" in s && "leftupdown" in s)
354 fail("cannot have both leftfirewall and leftupdown")
355 if ("rightfirewall" in s && "rightupdown" in s)
356 fail("cannot have both rightfirewall and rightupdown")
357 default("leftupdown", "ipsec _updown")
358 default("rightupdown", "ipsec _updown")
359 default("leftfirewall", "no")
360 default("rightfirewall", "no")
361 yesno("leftfirewall")
362 yesno("rightfirewall")
363 if (s["leftfirewall"] == "yes")
364 s["leftupdown"] = s["leftupdown"] " ipfwadm"
365 if (s["rightfirewall"] == "yes")
366 s["rightupdown"] = s["rightupdown"] " ipfwadm"
368 default("authby", "secret")
370 if (s["authby"] == "rsasig") {
371 authtype = "--rsasig"
372 if (!("leftcert" in s)) {
373 need("leftrsasigkey")
374 if (id("left") == "%any" &&
375 !(s["leftrsasigkey"] == "%cert" ||
376 s["leftrsasigkey"] == "0x00") )
377 fail("ID " v(id("left")) " cannot have RSA key")
379 if (!("rightcert" in s)) {
380 need("rightrsasigkey")
381 if (id("right") == "%any" &&
382 !(s["rightrsasigkey"] == "%cert" ||
383 s["rightrsasigkey"] == "0x00") )
384 fail("ID " v(id("right")) " cannot have RSA key")
386 } else if (s["authby"] != "secret")
387 fail("unknown authby value " v(s["authby"]))
389 settings = "--encrypt"
390 default("ike", "3des")
392 settings = settings " --ike " qs("ike")
393 default("esp", "3des")
395 settings = settings " --esp " qs("esp")
396 if (s["type"] != "transport")
397 settings = settings " --tunnel"
398 if (s["auth"] == "ah")
399 settings = settings " --authenticate"
400 if (s["pfs"] == "yes") {
401 settings = settings " --pfs"
402 if (s["pfsgroup"] != "")
403 settings = settings " --pfsgroup " qs("pfsgroup")
405 if (s["compress"] == "yes")
406 settings = settings " --compress"
407 if (op == "--replace")
408 settings = settings " --delete"
409 if ("ikelifetime" in s)
410 settings = settings " --ikelifetime " qs("ikelifetime")
411 if (s["disablearrivalcheck"] == "yes")
412 settings = settings " --disablearrivalcheck"
413 settings = settings " " authtype
417 if ("leftsubnet" in s)
418 lc = "--client " qs("leftsubnet")
419 if ("rightsubnet" in s)
420 rc = "--client " qs("rightsubnet")
421 if ("leftsubnetwithin" in s)
422 lc = lc " --clientwithin " qs("leftsubnetwithin")
423 if ("rightsubnetwithin" in s)
424 rc = rc " --clientwithin " qs("rightsubnetwithin")
427 if ("leftprotoport" in s)
428 lp = "--clientprotoport " qs("leftprotoport")
429 if ("rightprotoport" in s)
430 rp = "--clientprotoport " qs("rightprotoport")
431 lud = "--updown " qs("leftupdown")
432 rud = "--updown " qs("rightupdown")
435 lid = "--id " qs("leftid")
438 rid = "--id " qs("rightid")
441 lcert = "--cert " qs("leftcert")
443 if ("rightcert" in s)
444 rcert = "--cert " qs("rightcert")
446 if ("rekeyfuzz" in s)
447 fuzz = "--rekeyfuzz " qs("rekeyfuzz")
449 if (s["rekey"] == "no")
452 if ("_plutodevel" in s)
453 pd = "--plutodevel " s["_plutodevel"] # not qs()
455 if (authtype != "--psk") {
459 print "ipsec whack --name", name, settings, "\\"
460 print "\t--host", qs("left"), lc, lp,
461 "--nexthop", qs("leftnexthop"), lud, lid, lcert, "\\"
462 print "\t--to", "--host", qs("right"), rc, rp,
463 "--nexthop", qs("rightnexthop"), rud, rid, rcert, "\\"
464 print "\t--ipseclifetime", qs("keylife"),
465 "--rekeywindow", qs("rekeymargin"), "\\"
466 print "\t--keyingtries", qs("keyingtries"), fuzz, rk, pd, "\\"
471 print "# fatal error discovered, force failure using \"false\" command"
473 exit 1 # just on general principles