summaryrefslogtreecommitdiff
path: root/programs/auto
diff options
context:
space:
mode:
Diffstat (limited to 'programs/auto')
-rw-r--r--programs/auto/.cvsignore1
-rw-r--r--programs/auto/Makefile21
-rw-r--r--programs/auto/auto.8481
-rwxr-xr-xprograms/auto/auto.in660
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