diff options
Diffstat (limited to 'programs/auto')
-rw-r--r-- | programs/auto/.cvsignore | 1 | ||||
-rw-r--r-- | programs/auto/Makefile | 21 | ||||
-rw-r--r-- | programs/auto/auto.8 | 481 | ||||
-rwxr-xr-x | programs/auto/auto.in | 660 |
4 files changed, 1163 insertions, 0 deletions
diff --git a/programs/auto/.cvsignore b/programs/auto/.cvsignore new file mode 100644 index 000000000..865faf10c --- /dev/null +++ b/programs/auto/.cvsignore @@ -0,0 +1 @@ +auto diff --git a/programs/auto/Makefile b/programs/auto/Makefile new file mode 100644 index 000000000..035dbf708 --- /dev/null +++ b/programs/auto/Makefile @@ -0,0 +1,21 @@ +# Makefile for miscelaneous programs +# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# RCSID $Id: Makefile,v 1.2 2006/02/10 11:28:38 as Exp $ + +FREESWANSRCDIR=../.. +include ${FREESWANSRCDIR}/Makefile.inc + +PROGRAM=auto + +include ../Makefile.program diff --git a/programs/auto/auto.8 b/programs/auto/auto.8 new file mode 100644 index 000000000..21b5fd11b --- /dev/null +++ b/programs/auto/auto.8 @@ -0,0 +1,481 @@ +.TH IPSEC_AUTO 8 "17 December 2004" +.\" RCSID $Id: auto.8,v 1.6 2004/12/17 22:34:38 as Exp $ +.SH NAME +ipsec auto \- control automatically-keyed IPsec connections +.SH SYNOPSIS +.B ipsec +.B auto +[ +.B \-\-show +] [ +.B \-\-showonly +] [ +.B \-\-asynchronous +] +.br +\ \ \ [ +.B \-\-config +configfile +] [ +.B \-\-verbose +] [ +.B \-\-type conn +] +.br +\ \ \ operation +connection +.sp +.B ipsec +.B auto +[ +.B \-\-show +] [ +.B \-\-showonly +] +.br +\ \ \ [ +.B \-\-config +configfile +] [ +.B \-\-verbose +] +.B \-\-type ca +.br +\ \ \ operation +ca +.sp +.B ipsec +.B auto +[ +.B \-\-show +] [ +.B \-\-showonly +] operation +.SH DESCRIPTION +.I Auto +manipulates automatically-keyed strongSwan IPsec connections, +setting them up and shutting them down +based on the information in the IPsec configuration file. +In the normal usage, +.I connection +is the name of a connection specification in the configuration file; +.I ca +is the name of a Certification Authority (CA) specification in the configuration file; +.I operation +is +.BR \-\-add , +.BR \-\-delete , +.BR \-\-replace , +.BR \-\-up , +.BR \-\-down , +.BR \-\-route , +or +.BR \-\-unroute . +The +.BR \-\-status +and +.BR \-\-statusall +.I operations +may take a +.I connection +name. +The +.BR \-\-ready , +.BR \-\-rereadsecrets , +.BR \-\-rereadgroups , +.BR \-\-rereadcacerts , +.BR \-\-rereadaacerts , +.BR \-\-rereadocspcerts , +.BR \-\-rereadacerts , +.BR \-\-rereadcrls , +.BR \-\-rereadall , +.BR \-\-listalgs , +.BR \-\-listpubkeys , +.BR \-\-listcerts , +.BR \-\-listcacerts , +.BR \-\-listaacerts , +.BR \-\-listocspcerts , +.BR \-\-listacerts , +.BR \-\-listgroups , +.BR \-\-listcainfos , +.BR \-\-listcrls , +.BR \-\-listocsp , +.BR \-\-listcards , +.BR \-\-listall , +and +.BR \-\-purgeocsp +.I operations +do not take a connection name. +.I Auto +generates suitable +commands and feeds them to a shell for execution. +.PP +The +.B \-\-add +operation adds a connection or ca specification to the internal database +within +.IR pluto ; +it will fail if +.I pluto +already has a specification by that name. +The +.B \-\-delete +operation deletes a connection or ca specification from +.IR pluto 's +internal database (also tearing down any connections based on it); +it will fail if the specification does not exist. +The +.B \-\-replace +operation is equivalent to +.B \-\-delete +(if there is already a specification by the given name) +followed by +.BR \-\-add , +and is a convenience for updating +.IR pluto 's +internal specification to match an external one. +(Note that a +.B \-\-rereadsecrets +may also be needed.) +The +.B \-\-rereadgroups +operation causes any changes to the policy group files to take effect +(this is currently a synonym for +.BR \-\-ready , +but that may change). +None of the other operations alters the internal database. +.PP +The +.B \-\-up +operation asks +.I pluto +to establish a connection based on an entry in its internal database. +The +.B \-\-down +operation tells +.I pluto +to tear down such a connection. +.PP +Normally, +.I pluto +establishes a route to the destination specified for a connection as +part of the +.B \-\-up +operation. +However, the route and only the route can be established with the +.B \-\-route +operation. +Until and unless an actual connection is established, +this discards any packets sent there, +which may be preferable to having them sent elsewhere based on a more +general route (e.g., a default route). +.PP +Normally, +.IR pluto 's +route to a destination remains in place when a +.B \-\-down +operation is used to take the connection down +(or if connection setup, or later automatic rekeying, fails). +This permits establishing a new connection (perhaps using a +different specification; the route is altered as necessary) +without having a ``window'' in which packets might go elsewhere +based on a more general route. +Such a route can be removed using the +.B \-\-unroute +operation +(and is implicitly removed by +.BR \-\-delete ). +.PP +The +.B \-\-ready +operation tells +.I pluto +to listen for connection-setup requests from other hosts. +Doing an +.B \-\-up +operation before doing +.B \-\-ready +on both ends is futile and will not work, +although this is now automated as part of IPsec startup and +should not normally be an issue. +.PP +The +.B \-\-status +operation asks +.I pluto +for current connection status either for all connections +(no connection argument) or a for specified +.I connection +name. For more detailed information use +.B \-\-statusall +\. The output format is ad-hoc and likely to change. +.PP +The +.B \-\-rereadsecrets +operation tells +.I pluto +to re-read the +.I /etc/ipsec.secrets +secret-keys file, +which it normally reads only at startup time. +(This is currently a synonym for +.BR \-\-ready , +but that may change.) +.PP +The +.B \-\-rereadcacerts +operation reads all certificate files contained in the +.IR /etc/ipsec.d/cacerts +directory and adds them to +.IR pluto 's +list of Certification Authority (CA) certificates. +.PP +The +.B \-\-rereadaacerts +operation reads all certificate files contained in the +.IR /etc/ipsec.d/aacerts +directory and adds them to +.IR pluto 's +list of Authorization Authority (AA) certificates. +.PP +The +.B \-\-rereadocspcerts +operation reads all certificate files contained in the +.IR /etc/ipsec.d/ocspcerts +directory and adds them to +.IR pluto 's +list of OCSP signer certificates. +.PP +The +.B \-\-rereadacerts +operation reads all certificate files contained in the +.IR /etc/ipsec.d/acerts +directory and adds them to +.IR pluto 's +list of attribute certificates. +.PP +The +.B \-\-rereadcrls +operation reads all certificate revocation list (CRL) files +contained in the +.IR /etc/ipsec.d/crls +directory and adds them to +.IR pluto 's +list of CRLs. +.PP +The +.B \-\-rereadall +operation is equivalent to the execution of +.BR \-\-rereadsecrets , +.BR \-\-rereadcacerts , +.BR \-\-rereadaacerts , +.BR \-\-rereadocspcerts , +.BR \-\-rereadacerts , +and +.BR \-\-rereadcrls . +.PP +The +.B \-\-listalgs +operation lists all registed IKE encryption and hash algorithms, +that are available to +.IR pluto , +as well as the Diffie-Hellman (DH) groups. +.PP +The +.B \-\-listpubkeys +operation lists all RSA public keys either received from peers +via the IKE protocol embedded in authenticated certificate payloads +or loaded locally using the +.BR rightcert \ / +.BR leftcert +or +.BR rightrsasigkey \ / +.BR leftrsasigkey +parameters in +.IR ipsec.conf (5). +.PP +The +.B \-\-listcerts +operation lists all X.509 and OpenPGP certificates loaded locally using the +.BR rightcert +and +.BR leftcert +parameters in +.IR ipsec.conf (5). +.PP +The +.B \-\-listcacerts +operation lists all X.509 CA certificates either loaded locally from the +.IR /etc/ipsec.d/cacerts +directory or received in PKCS#7-wrapped certificate payloads via +the IKE protocol. +.PP +The +.B \-\-listaacerts +operation lists all X.509 AA certificates loaded locally from the +.IR /etc/ipsec.d/aacerts +directory. +.PP +The +.B \-\-listocspcerts +operation lists all OCSP signer certificates either loaded locally from the +.IR /etc/ipsec.d/ocspcerts +directory or received via the Online Certificate Status Protocol +from an OCSP server. +.PP +The +.B \-\-listacerts +operation lists all X.509 attribute certificates loaded locally from the +.IR /etc/ipsec.d/acerts +directory. +.PP +The +.B \-\-listgropus +operation lists all groups that are either used in connection definitions in +.IR ipsec.conf (5) +or are embedded in loaded X.509 attributes certificates. +.PP +The +.B \-\-listcainfos +operation lists the certification authority information specified in the ca +sections of +.IR ipsec.conf (5). +.PP +The +.B \-\-listcrls +operation lists all Certificate Revocation Lists (CRLs) either loaded +locally from the +.IR /etc/ipsec.d/crls +directory or fetched dynamically from an HTTP or LDAP server. +.PP +The +.B \-\-listocsp +operation lists the certicates status information fetched from +OCSP servers. +.PP +The +.B \-\-purgeocsp +operation deletes any cached certificate status information and pending +OCSP fetch requests. +.PP +The +.B \-\-listcards +operation lists information about attached smartcards or crypto tokens. +.PP +The +.B \-\-listall +operation is equivalent to the execution of +.BR \-\-listalgs , +.BR \-\-listpubkeys , +.BR \-\-listcerts , +.BR \-\-listcacerts , +.BR \-\-listaacerts , +.BR \-\-listocspcerts , +.BR \-\-listacerts , +.BR \-\-listgroups , +.BR \-\-listcainfos , +.BR \-\-listcrls , +.BR \-\-listocsp , +and +.BR \-\-listcards . +.PP +The +.B \-\-show +option turns on the +.B \-x +option of the shell used to execute the commands, +so each command is shown as it is executed. +.PP +The +.B \-\-showonly +option causes +.I auto +to show the commands it would run, on standard output, +and not run them. +.PP +The +.B \-\-asynchronous +option, applicable only to the +.B up +operation, +tells +.I pluto +to attempt to establish the connection, +but does not delay to report results. +This is especially useful to start multiple connections in parallel +when network links are slow. +.PP +The +.B \-\-verbose +option instructs +.I auto +to pass through all output from +.IR ipsec_whack (8), +including log output that is normally filtered out as uninteresting. +.PP +The +.B \-\-config +option specifies a non-standard location for the IPsec +configuration file (default +.IR /etc/ipsec.conf ). +.PP +See +.IR ipsec.conf (5) +for details of the configuration file. +Apart from the basic parameters which specify the endpoints and routing +of a connection (\fBleft\fR +and +.BR right , +plus possibly +.BR leftsubnet , +.BR leftnexthop , +.BR leftfirewall , +their +.B right +equivalents, +and perhaps +.BR type ), +an +.I auto +connection almost certainly needs a +.B keyingtries +parameter (since the +.B keyingtries +default is poorly chosen). +.SH FILES +.ta \w'/var/run/ipsec.info'u+4n +/etc/ipsec.conf default IPSEC configuration file +.br +/var/run/ipsec.info \fB%defaultroute\fR information +.SH SEE ALSO +ipsec.conf(5), ipsec(8), ipsec_pluto(8), ipsec_whack(8), ipsec_manual(8) +.SH HISTORY +Written for the FreeS/WAN project +<http://www.freeswan.org> +by Henry Spencer. +Extended for the strongSwan project +<http://www.strongswan.org> +by Andreas Steffen. +.SH BUGS +Although an +.B \-\-up +operation does connection setup on both ends, +.B \-\-down +tears only one end of the connection down +(although the orphaned end will eventually time out). +.PP +There is no support for +.B passthrough +connections. +.PP +A connection description which uses +.B %defaultroute +for one of its +.B nexthop +parameters but not the other may be falsely +rejected as erroneous in some circumstances. +.PP +The exit status of +.B \-\-showonly +does not always reflect errors discovered during processing of the request. +(This is fine for human inspection, but not so good for use in scripts.) diff --git a/programs/auto/auto.in b/programs/auto/auto.in new file mode 100755 index 000000000..05568f9b5 --- /dev/null +++ b/programs/auto/auto.in @@ -0,0 +1,660 @@ +#! /bin/sh +# user interface to automatic keying and Pluto in general +# Copyright (C) 1998, 1999, 2000 Henry Spencer. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# RCSID $Id: auto.in,v 1.17 2006/04/20 04:42:12 as Exp $ + +me='ipsec auto' +usage="Usage: + $me [--showonly] [--asynchronous] --up connectionname + $me [--showonly] [-- type conn|ca] --{add|delete|replace|down} name + $me [--showonly] --{route|unroute} connectionname + $me [--showonly] --ready + $me [--showonly] --{status|statusall} [connectionname] + $me [--showonly] --{rereadsecrets|rereadgroups} + $me [--showonly] --{rereadcacerts|rereadaacerts|rereadocspcerts} + $me [--showonly] --{rereadacerts|rereadcrls|rereadall} + $me [--showonly] [--utc] --{listalgs|listpubkeys|listcerts} + $me [--showonly] [--utc] --{listcacerts|listaacerts|listocspcerts} + $me [--showonly] [--utc] --{listacerts|listgroups|listcainfos} + $me [--showonly] [--utc] --{listcrls|listocsp|listcards|listall} + $me [--showonly] --purgeocsp + + other options: [--config ipsecconfigfile] [--verbose] [--show]" + +showonly= +config= +info=/var/run/ipsec.info +shopts= +noinclude= +async= +logfilter='$1 != "002"' +op= +argc= +utc= +type="conn" +name="--name" + +for dummy +do + case "$1" in + --help) echo "$usage" ; exit 0 ;; + --version) echo "$me $IPSEC_VERSION" ; exit 0 ;; + --show) shopts=-x ;; + --showonly) showonly=yes ;; + --utc) utc="$1" ;; + --config) config="--config $2" ; shift ;; + --noinclude) noinclude=--noinclude ;; + --asynchronous) async="--asynchronous" ;; + --verbose) logfilter='1' ;; + --type) type="$2" ; shift ;; + --up|--down|--add|--delete|--replace|--route|--unroute) + if test " $op" != " " + then + echo "$usage" >&2 + exit 2 + fi + op="$1" + argc=1 + if test "$type" = "ca" + then + name="--caname" + case "$op" in + --add|--delete|--replace) ;; + --*) echo "$op option not supported for --type ca"; + exit 3 ;; + esac + fi + ;; + --status|--statusall) + if test " $op" != " " + then + echo "$usage" >&2 + exit 2 + fi + op="$1" + argc=1 + if test $# -eq 1 + then + argc=0; name= + fi + ;; + --ready|--rereadsecrets|--rereadgroups|\ + --rereadcacerts|--rereadaacerts|--rereadocspcerts|\ + --rereadacerts|--rereadcrls|--rereadall|\ + --listalgs|--listpubkeys|--listcerts|\ + --listcacerts|--listaacerts|--listocspcerts|\ + --listacerts|--listgroups|--listcainfos|\ + --listcrls|--listocsp|--listcards|--listall|\ + --purgeocsp) + if test " $op" != " " + then + echo "$usage" >&2 + exit 2 + fi + op="$1" + argc=0 + ;; + --) shift ; break ;; + -*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;; + *) break ;; + esac + shift +done + +names= +case "$op" in +--*) if test " $argc" -ne $# + then + echo "$usage" >&2 + exit 2 + fi + names="$*" + ;; +*) echo "$usage" >&2 ; exit 2 ;; +esac + + +runit() { + if test "$showonly" + then + cat + else + ( + echo '(' + cat + echo ')' + echo 'echo = $?' + ) | sh $shopts | + awk "/^= / { exit \$2 } $logfilter { print }" + fi +} + +case "$op" in +--ready) echo "ipsec whack --listen" | runit ; exit ;; +--rereadsecrets) echo "ipsec whack --rereadsecrets" | runit ; exit ;; +--rereadgroups) echo "ipsec whack --listen" | runit ; exit ;; +--rereadcacerts) echo "ipsec whack --rereadcacerts" | runit ; exit ;; +--rereadaacerts) echo "ipsec whack --rereadaacerts" | runit ; exit ;; +--rereadocspcerts) echo "ipsec whack --rereadocspcerts" | runit ; exit ;; +--rereadacerts) echo "ipsec whack --rereadacerts" | runit ; exit ;; +--rereadcrls) echo "ipsec whack --rereadcrls" | runit ; exit ;; +--rereadall) echo "ipsec whack --rereadall" | runit ; exit ;; +--listalgs) echo "ipsec whack --listalgs" | runit ; exit ;; +--listpubkeys) echo "ipsec whack $utc --listpubkeys" | runit ; exit ;; +--listcerts) echo "ipsec whack $utc --listcerts" | runit ; exit ;; +--listcacerts) echo "ipsec whack $utc --listcacerts" | runit ; exit ;; +--listaacerts) echo "ipsec whack $utc --listaacerts" | runit ; exit ;; +--listocspcerts) echo "ipsec whack $utc --listocspcerts" | runit ; exit ;; +--listacerts) echo "ipsec whack $utc --listacerts" | runit ; exit ;; +--listgroups) echo "ipsec whack $utc --listgroups" | runit ; exit ;; +--listcainfos) echo "ipsec whack $utc --listcainfos" | runit ; exit ;; +--listcrls) echo "ipsec whack $utc --listcrls" | runit ; exit ;; +--listocsp) echo "ipsec whack $utc --listocsp" | runit ; exit ;; +--listcards) echo "ipsec whack $utc --listcards" | runit ; exit ;; +--listall) echo "ipsec whack $utc --listall" | runit ; exit ;; +--purgeocsp) echo "ipsec whack $utc --purgeocsp" | runit ; exit ;; +--up) echo "ipsec whack $async --name $names --initiate" | runit ; exit ;; +--down) echo "ipsec whack --name $names --terminate" | runit ; exit ;; +--delete) echo "ipsec whack $name $names --delete" | runit ; exit ;; +--route) echo "ipsec whack --name $names --route" | runit ; exit ;; +--unroute) echo "ipsec whack --name $names --unroute" | runit ; exit ;; +--status) echo "ipsec whack $name $names --status" | runit ; exit ;; +--statusall) echo "ipsec whack $name $names --statusall" | runit ; exit ;; +esac + +if test -s $info +then + . $info +fi + +ipsec _confread $config $noinclude --type $type $names | +awk -v section="$type" ' BEGIN { + FS = "\t" + op = "'"$op"'" + err = "cat >&2" + draddr = "'"$defaultrouteaddr"'" + drnexthop = "'"$defaultroutenexthop"'" + failed = 0 + s[""] = "" + init() + print "PATH=\"'"$PATH"'\"" + print "export PATH" + flip["left"] = "right" + flip["right"] = "left" + } + function init(n) { + for (n in s) + delete s[n] + name = "" + seensome = 0 + } + $1 == ":" { + s[$2] = $3 + seensome = 1 + next + } + $1 == "!" { + if ($2 != "") + fail($2) + next + } + $1 == "=" { + if (name == "") + name = $2 + next + } + $1 == "." { + if (section == "ca") + output_ca() + else + output() + init() + next + } + { + fail("internal error, unknown type code " v($1)) + } + function fail(m) { + print "ipsec_auto: fatal error in " v(name) ": " m |err + failed = 1 + exit + } + function yesno(k) { + if ((k in s) && s[k] != "yes" && s[k] != "no") + fail("parameter " v(k) " must be \"yes\" or \"no\"") + } + function setdefault(k, val) { + if (!(k in s)) + s[k] = val + } + function was(new, old) { + if (!(new in s) && (old in s)) + s[new] = s[old] + } + function need(k) { + if (!(k in s)) + fail("connection has no " v(k) " parameter specified") + if (s[k] == "") + fail("parameter " v(k) " value must be non-empty") + } + function integer(k) { + if (!(k in s)) + return + if (s[k] !~ /^[0-9]+$/) + fail("parameter " v(k) " value must be integer") + } + function duration(k, n, t) { + if (!(k in s)) + return + t = s[k] + n = substr(t, 1, length(t)-1) + if (t ~ /^[0-9]+$/) + s[k] = t + else if (t ~ /^[0-9]+s$/) + s[k] = n + else if (t ~ /^[0-9]+(\.[0-9]+)?m$/) + s[k] = int(n*60) + else if (t ~ /^[0-9]+(\.[0-9]+)?h$/) + s[k] = int(n*3600) + else if (t ~ /^[0-9]+(\.[0-9]+)?d$/) + s[k] = int(n*3600*24) + else + fail("parameter " v(k) " not valid time, must be nnn[smhd]") + } + function nexthopset(dir, val, k) { + k = dir "nexthop" + if (k in s) + fail("non-default value of " k " is being overridden") + if (val != "") + s[k] = val + else if (k in s) + delete s[k] + } + function id(dir, k) { + k = dir "id" + if (!(k in s)) + k = dir + return s[k] + } + function whackkey(dir, which, flag, rk, n) { + if (id(dir) == "%opportunistic") + return + rk = s[dir which] + if (rk == "%dnsondemand") + { + kod="--dnskeyondemand" + return + } + if (rk == "" || rk == "%none" || rk == "%cert" || rk == "0x00") + return + n = "\"\\\"" name "\\\" " dir which"\"" + if (rk == "%dns" || rk == "%dnsonload") + { + if (id(flip[dir]) == "%opportunistic" || s[flip[dir]] == "%any") + return + print "ipsec whack --label", n, flag, + "--keyid", q(id(dir)), "\\" + } + else + { + print "ipsec whack --label", n, flag, + "--keyid", q(id(dir)), + "--pubkeyrsa", q(rk), "\\" + } + print "\t|| exit $?" + } + function q(str) { # quoting for shell + return "\"" str "\"" + } + function qs(k) { # utility abbreviation for q(s[k]) + return q(s[k]) + } + function v(str) { # quoting for human viewing + return "\"" str "\"" + } + function output() { + if (!seensome) + fail("internal error, output called inappropriately") + + setdefault("type", "tunnel") + type_flags = "" + t = s["type"] + if (t == "tunnel") { + # do NOT default subnets to side/32, despite what + # the docs say... + type_flags = "--tunnel" + } else if (t == "transport") { + if ("leftsubnet" in s) + fail("type=transport incompatible with leftsubnet") + if ("rightsubnet" in s) + fail("type=transport incompatible with rightsubnet") + type_flags = "" + } else if (t == "passthrough") { + type_flags = "--pass" + } else if (t == "drop") { + type_flags = "--drop" + } else if (t == "reject") { + type_flags = "--reject" + } else + fail("unknown type " v(t)) + + setdefault("failureshunt", "none") + t = s["failureshunt"] + if (t == "passthrough") + type_flags = type_flags " --failpass"; + else if (t == "drop") + type_flags = type_flags " --faildrop"; + else if (t == "reject") + type_flags = type_flags " --failreject"; + else if (t != "none") + fail("unknown failureshunt value " v(t)) + + need("left") + need("right") + if (s["left"] == "%defaultroute") { + if (s["right"] == "%defaultroute") + fail("left and right cannot both be %defaultroute") + if (draddr == "") + fail("%defaultroute requested but not known") + s["left"] = draddr + nexthopset("left", drnexthop) + } else if (s["right"] == "%defaultroute") { + if (draddr == "") + fail("%defaultroute requested but not known") + s["right"] = draddr + nexthopset("right", drnexthop) + } + + setdefault("keyexchange", "ike") + if (s["keyexchange"] != "ike") + fail("only know how to do keyexchange=ike") + setdefault("auth", "esp") + if (("auth" in s) && s["auth"] != "esp" && s["auth"] != "ah") + fail("only know how to do auth=esp or auth=ah") + yesno("pfs") + + setdefault("pfs", "yes") + duration("dpddelay") + duration("dpdtimeout") + if ("dpdaction" in s) + { + setdefault("dpddelay",30) + setdefault("dpdtimeout",120) + } + yesno("compress") + setdefault("compress", "no") + setdefault("keylife", "1h") + duration("keylife") + yesno("rekey") + setdefault("rekey", "yes") + setdefault("rekeymargin", "9m") + duration("rekeymargin") + setdefault("keyingtries", "%forever") + if (s["keyingtries"] == "%forever") + s["keyingtries"] = 0 + integer("keyingtries") + if ("rekeyfuzz" in s) { + if (s["rekeyfuzz"] !~ /%$/) + fail("rekeyfuzz must be nnn%") + r = s["rekeyfuzz"] + s["rekeyfuzz"] = substr(r, 1, length(r)-1) + integer("rekeyfuzz") + } + duration("ikelifetime") + setdefault("disablearrivalcheck", "no") + + setdefault("leftsendcert", "always") + setdefault("rightsendcert", "always") + + setdefault("leftnexthop", "%direct") + setdefault("rightnexthop", "%direct") + if (s["leftnexthop"] == s["left"]) + fail("left and leftnexthop must not be the same") + if (s["rightnexthop"] == s["right"]) + fail("right and rightnexthop must not be the same") + if (s["leftnexthop"] == "%defaultroute") { + if (drnexthop == "") + fail("%defaultroute requested but not known") + s["leftnexthop"] = drnexthop + } + if (s["rightnexthop"] == "%defaultroute") { + if (drnexthop == "") + fail("%defaultroute requested but not known") + s["rightnexthop"] = drnexthop + } + + if ("leftfirewall" in s && "leftupdown" in s) + fail("cannot have both leftfirewall and leftupdown") + if ("rightfirewall" in s && "rightupdown" in s) + fail("cannot have both rightfirewall and rightupdown") + setdefault("leftupdown", "ipsec _updown") + setdefault("rightupdown", "ipsec _updown") + setdefault("lefthostaccess", "no") + setdefault("righthostaccess", "no") + yesno("lefthostaccess") + yesno("righthostaccess") + lha = "" + if (s["lefthostaccess"] == "yes") + lha = "--hostaccess" + rha = "" + if (s["righthostaccess"] == "yes") + rha = "--hostaccess" + setdefault("leftfirewall", "no") + setdefault("rightfirewall", "no") + yesno("leftfirewall") + yesno("rightfirewall") + if (s["leftfirewall"] == "yes") + s["leftupdown"] = s["leftupdown"] " iptables" + if (s["rightfirewall"] == "yes") + s["rightupdown"] = s["rightupdown"] " iptables" + + setdefault("authby", "rsasig") + t = s["authby"] + if (t == "rsasig" || t == "secret|rsasig" || t == "rsasig|secret") { + authtype = "--rsasig" + type_flags = "--encrypt " type_flags + if (!("leftcert" in s)) { + setdefault("leftrsasigkey", "%cert") + if (id("left") == "%any" && + !(s["leftrsasigkey"] == "%cert" || + s["leftrsasigkey"] == "0x00") ) + fail("ID " v(id("left")) " cannot have RSA key") + } + if (!("rightcert" in s)) { + setdefault("rightrsasigkey", "%cert") + if (id("right") == "%any" && + !(s["rightrsasigkey"] == "%cert" || + s["rightrsasigkey"] == "0x00") ) + fail("ID " v(id("right")) " cannot have RSA key") + } + if (t != "rsasig") + authtype = authtype " --psk" + } else if (t == "secret") { + authtype = "--psk" + type_flags = "--encrypt " type_flags + } else if (t == "never") { + authtype = "" + } else { + fail("unknown authby value " v(t)) + } + + settings = type_flags + setdefault("ike", "3des-sha,3des-md5") + if (s["ike"] != "") + settings = settings " --ike " qs("ike") + setdefault("esp", "3des") + if (s["esp"] != "") + settings = settings " --esp " qs("esp") + if (s["auth"] == "ah") + settings = settings " --authenticate" + if (s["pfs"] == "yes") { + settings = settings " --pfs" + if (s["pfsgroup"] != "") + settings = settings " --pfsgroup " qs("pfsgroup") + } + + if (s["dpdaction"]) + settings = settings " --dpdaction " qs("dpdaction") + if (s["dpddelay"]) + settings = settings " --dpddelay " qs("dpddelay") + if (s["dpdtimeout"]) + settings = settings " --dpdtimeout " qs("dpdtimeout") + + if (s["compress"] == "yes") + settings = settings " --compress" + if (op == "--replace") + settings = settings " --delete" + if ("ikelifetime" in s) + settings = settings " --ikelifetime " qs("ikelifetime") + if (s["disablearrivalcheck"] == "yes") + settings = settings " --disablearrivalcheck" + settings = settings " " authtype + + lc = "" + rc = "" + if ("leftsubnet" in s) + lc = "--client " qs("leftsubnet") + if ("rightsubnet" in s) + rc = "--client " qs("rightsubnet") + if ("leftsubnetwithin" in s) + lc = lc " --clientwithin " qs("leftsubnetwithin") + if ("rightsubnetwithin" in s) + rc = rc " --clientwithin " qs("rightsubnetwithin") + lp = "" + rp = "" + if ("leftprotoport" in s) + lp = "--clientprotoport " qs("leftprotoport") + if ("rightprotoport" in s) + rp = "--clientprotoport " qs("rightprotoport") + lud = "--updown " qs("leftupdown") + rud = "--updown " qs("rightupdown") + + lid = "" + if ("leftid" in s) + lid = "--id " qs("leftid") + rid = "" + if ("rightid" in s) + rid = "--id " qs("rightid") + lsip = "" + if ("leftsourceip" in s) + lsip = "--srcip " qs("leftsourceip") + rsip = "" + if ("rightsourceip" in s) + rsip = "--srcip " qs("rightsourceip") + lscert = "" + if ("leftsendcert" in s) + lscert = "--sendcert " qs("leftsendcert") + rscert = "" + if ("rightsendcert" in s) + rscert = "--sendcert " qs("rightsendcert") + lcert = "" + if ("leftcert" in s) + lcert = "--cert " qs("leftcert") + rcert = "" + if ("rightcert" in s) + rcert = "--cert " qs("rightcert") + lca = "" + if ("leftca" in s) + lca = "--ca " qs("leftca") + rca = "" + if ("rightca" in s) + rca = "--ca " qs("rightca") + lgr = "" + if ("leftgroups" in s) + lgr = "--groups " qs("leftgroups") + rgr = "" + if ("rightgroups" in s) + rgr = "--groups " qs("rightgroups") + fuzz = "" + if ("rekeyfuzz" in s) + fuzz = "--rekeyfuzz " qs("rekeyfuzz") + rk = "" + if (s["rekey"] == "no") + rk = "--dontrekey" + pd = "" + if ("_plutodevel" in s) + pd = "--plutodevel " s["_plutodevel"] # not qs() + + lkod = "" + rkod = "" + if (authtype != "--psk") { + kod = "" + whackkey("left", "rsasigkey", "") + whackkey("left", "rsasigkey2", "--addkey") + lkod = kod + kod = "" + whackkey("right", "rsasigkey", "") + whackkey("right", "rsasigkey2", "--addkey") + rkod = kod + } + print "ipsec whack --name", name, settings, "\\" + print "\t--host", qs("left"), lc, lp, "--nexthop", + qs("leftnexthop"), lud, lha, lid, lkod, lscert, lcert, lca, lsip, lgr, "\\" + print "\t--to", "--host", qs("right"), rc, rp, "--nexthop", + qs("rightnexthop"), rud, rha, rid, rkod, rscert, rcert, rca, rsip, rgr, "\\" + print "\t--ipseclifetime", qs("keylife"), + "--rekeymargin", qs("rekeymargin"), "\\" + print "\t--keyingtries", qs("keyingtries"), fuzz, rk, pd, "\\" + print "\t|| exit $?" + } + function output_ca() { + if (!seensome) + fail("internal error, output called inappropriately") + settings = "" + if (op == "--replace") + settings = "--delete" + cacert = "" + if ("cacert" in s) + cacert = "--cacert " qs("cacert") + ldaphost = "" + if ("ldaphost" in s) + ldaphost = "--ldaphost " qs("ldaphost") + ldapbase = "" + if ("ldapbase" in s) + ldapbase = "--ldapbase " qs("ldapbase") + crluri = "" + if ("crluri" in s) + crluri = "--crluri " qs("crluri") + crluri2 = "" + if ("crluri2" in s) + crluri2 = "--crluri2 " qs("crluri2") + ocspuri = "" + if ("ocspuri" in s) + ocspuri = "--ocspuri " qs("ocspuri") + yesno("strictcrlpolicy") + setdefault("strictcrlpolicy", "no") + if (s["strictcrlpolicy"] == "yes") + settings = settings " --strictcrlpolicy" + yesno("cachecrls") + setdefault("cachecrls", "no") + if (s["cachecrls"] == "yes") + settings = settings " --cachecrls" + + print "ipsec whack --caname", name, settings, cacert, ldaphost, ldapbase, + crluri, crluri2, ocspuri, "\\" + print "\t|| exit $?" + } + END { + if (failed) { + print "# fatal error discovered, force failure using \"false\" command" + print "false" + exit 1 # just on general principles + } + if (seensome) { + if (section == "ca") + output_ca() + else + output() + } + }' | runit |