Files
strongswan-ext/programs/manual/manual.in
T
Martin Willi 997358a6c4 - import of strongswan-2.7.0
- applied patch for charon
2006-04-28 07:14:48 +00:00

638 lines
16 KiB
Bash
Executable File

#! /bin/sh
# user interface to manual keying
# Copyright (C) 1998, 1999 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: manual.in,v 1.1 2004/03/15 20:35:28 as Exp $
me='ipsec manual'
usage="Usage:
$me [--showonly] --{up|down|route|unroute} name
$me [--showonly] --{up|down|route|unroute} --union partname ...
other options: [--config ipsecconfigfile] [--other] [--show]
[--iam ipaddress@interface]"
# make sure outputs of (e.g.) ifconfig are in English
unset LANG LANGUAGE LC_ALL LC_MESSAGES
showonly=
config=
info=/var/run/ipsec.info
shopts=
other=0
union=0
noinclude=
interfs=
op=
for dummy
do
case "$1" in
--help) echo "$usage" ; exit 0 ;;
--version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
--show) shopts=-x ;;
--showonly) showonly=yes ;;
--other) other=1 ;;
--union) union=1 ;;
--config) config="--config $2" ; shift ;;
--noinclude) noinclude=--noinclude ;;
--iam) interfs="$2" ; shift ;;
--up|--down|--route|--unroute)
if test " $op" != " "
then
echo "$usage" >&2
exit 2
fi
op="$1"
;;
--) shift ; break ;;
-*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
*) break ;;
esac
shift
done
case "$op$#:$union" in
[01]:*) echo "$usage" >&2 ; exit 2 ;;
2:0) echo "$me: warning: obsolete command syntax used" >&2
op="--$2"
names="$1"
;;
[0-9]*:1) ;;
--*) if test $# -eq 0
then
echo "$usage" >&2
exit 2
fi
names="$*"
;;
*) echo "$usage" >&2 ; exit 2 ;;
esac
if test " $op" = " "
then
# --union obsolete-syntax case, op is last argument
echo "$me: warning: obsolete command syntax used" >&2
names=
prev=
for arg
do
names="$names $prev"
prev="$arg"
done
op="--$prev"
fi
case "$op" in
--up|--down|--route|--unroute) ;;
*) echo "$usage" >&2 ; exit 2 ;;
esac
case "$interfs" in
'') interfs="`ifconfig |
awk ' /^ipsec/ { interf = $1 ; next }
/^[^ \t]/ { interf = "" ; next }
/^[ \t]*inet addr/ {
sub(/:/, " ", $0)
if (interf != "")
print $3 "@" interf
}' | tr '\n' ' '`"
;;
esac
if test -s $info
then
. $info
fi
ipsec _confread $config $noinclude $names |
awk ' BEGIN {
FS = "\t"
myname = "'"$me"'"
err = "cat >&2"
op = "'"$op"'"
other = '"$other"'
names = "'"$names"'"
interfs = "'"$interfs"'"
ni = split(interfs, terfs, " ")
if (ni == 0)
fail("no IPsec-enabled interfaces found")
for (i = 1; i <= ni; i++) {
nc = split(terfs[i], cpts, "@")
if (nc != 2)
fail("internal error on " terfs[i])
interface[cpts[1]] = cpts[2]
}
draddr = "'"$defaultrouteaddr"'"
drnexthop = "'"$defaultroutenexthop"'"
s[""] = ""
nlspi = 0
nrspi = 0
failed = 0
maskbits[0] = "0.0.0.0"
maskbits[1] = "128.0.0.0"
maskbits[2] = "192.0.0.0"
maskbits[3] = "224.0.0.0"
maskbits[4] = "240.0.0.0"
maskbits[5] = "248.0.0.0"
maskbits[6] = "252.0.0.0"
maskbits[7] = "254.0.0.0"
maskbits[8] = "255.0.0.0"
maskbits[9] = "255.128.0.0"
maskbits[10] = "255.192.0.0"
maskbits[11] = "255.224.0.0"
maskbits[12] = "255.240.0.0"
maskbits[13] = "255.248.0.0"
maskbits[14] = "255.252.0.0"
maskbits[15] = "255.254.0.0"
maskbits[16] = "255.255.0.0"
maskbits[17] = "255.255.128.0"
maskbits[18] = "255.255.192.0"
maskbits[19] = "255.255.224.0"
maskbits[20] = "255.255.240.0"
maskbits[21] = "255.255.248.0"
maskbits[22] = "255.255.252.0"
maskbits[23] = "255.255.254.0"
maskbits[24] = "255.255.255.0"
maskbits[25] = "255.255.255.128"
maskbits[26] = "255.255.255.192"
maskbits[27] = "255.255.255.224"
maskbits[28] = "255.255.255.240"
maskbits[29] = "255.255.255.248"
maskbits[30] = "255.255.255.252"
maskbits[31] = "255.255.255.254"
maskbits[32] = "255.255.255.255"
}
$1 == "=" {
next
}
$1 == "!" {
if ($2 != "")
fail($2)
next
}
$1 != ":" {
fail("internal error, unknown type code \"" $1 "\"")
}
{ s[$2] = $3 }
function q(s) {
return "\"" s "\""
}
function fail(m) {
print myname ": fatal error in " q(names) ": " m |err
failed = 1
exit
}
function swap(k, t, l, r) {
l = "left" k
r = "right" k
if ((l in s) && (r in s)) {
t = s[l]
s[l] = s[r]
s[r] = t
} else if (l in s) { # but not r
s[r] = s[l]
delete s[l]
} else if (r in s) { # but not l
s[l] = s[r]
delete s[r]
}
}
function yesno(k) {
if ((k in s) && s[k] != "yes" && s[k] != "no")
fail("parameter \"" k "\" must be \"yes\" or \"no\"")
}
function default(k, v) {
if (!(k in s))
s[k] = v
}
function need(k) {
if (!(k in s))
fail("connection has no \"" k "\" parameter specified")
if (s[k] == "")
fail("parameter \"" k "\" value must be non-empty")
}
function integer(k) {
if (!(k in s))
return
if (s[k] !~ /^[0-9]+$/)
fail("parameter \"" k "\" value must be integer")
}
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 leftward( t) {
nlspi++
if ("spi" in s)
return s["spi"]
t = spibase spil
spil += 2
return t
}
function rightward( t) {
nrspi++
if ("spi" in s)
return s["spi"]
t = spibase spir
spir += 2
return t
}
function netfix(dir, n, t) {
n = s[dir "subnet"]
if (n == "%default")
n = "0.0.0.0/0"
if (n !~ /\//)
fail(dir "subnet=" n " has no mask specified")
t = split(n, netfixarray, "/")
if (t != 2)
fail("bad syntax in " dir "subnet=" n)
s[dir "net"] = netfixarray[1]
s[dir "mask"] = mask(netfixarray[2])
}
function mask(m) {
if (m ~ /\./)
return m
if (!(m in maskbits))
fail("unknown mask syntax \"" m "\"")
return maskbits[m]
}
function bidir(name, l, r) {
l = "left" name
r = "right" name
if (!(l in s) && (name in s))
s[l] = s[name]
if (!(r in s) && (name in s))
s[r] = s[name]
if ((l in s) != (r in s))
fail("must give both or neither \"" l "\" and \"" \
r "\"")
}
function espspi(src, dest, spi, dir) {
if (!("esp" in s))
return
dir = (dest == me) ? "left" : "right"
print "ipsec spi --label", q(names), "--af inet",
"--said", ("esp" spi "@" dest), "\\"
print "\t--esp", s["esp"], "--src", src, "\\"
if ((dir "espauthkey") in s)
print "\t--authkey", s[dir "espauthkey"], "\\"
if ("espreplay_window" in s)
print "\t--replay_window", s["espreplay_window"], "\\"
if ((dir "espenckey") in s)
print "\t--enckey", s[dir "espenckey"], "&&"
else
print "\t&&"
}
function ahspi(src, dest, spi, dir) {
if (!("ah" in s))
return
dir = (dest == me) ? "left" : "right"
if (!((dir "ahkey") in s))
fail("AH specified but no ahkey= given")
print "ipsec spi --label", q(names), "--af inet",
"--said", ("ah" spi "@" dest), "\\"
print "\t--ah", s["ah"], "--src", src, "\\"
if ("ahreplay_window" in s)
print "\t--replay_window", s["ahreplay_window"], "\\"
print "\t--authkey", s[dir "ahkey"], "&&"
}
# issue a suitable invocation of updown command
function updown(verb, suffix, cmd) {
if ("leftupdown" in s) {
cmd = s["leftupdown"]
if (s["leftfirewall"] == "yes")
fail("cannot specify both updown and firewall")
} else {
cmd = "ipsec _updown"
if (s["leftfirewall"] == "yes")
cmd = cmd " ipfwadm"
}
print "PLUTO_VERB=" verb verbsuf " " cmd " " suffix
}
END {
#########
if (failed)
exit 1
default("type", "tunnel")
type = s["type"]
shunt = 0
if (type == "transport") {
if ("leftsubnet" in s)
fail("type=transport incompatible with leftsubnet")
if ("rightsubnet" in s)
fail("type=transport incompatible with rightsubnet")
} else if (type == "passthrough") {
shunt = 1;
p = "%pass"
} else if (type == "drop" || type == "reject") {
shunt = 1;
p = "%" type
} else if (type != "tunnel")
fail("only know how to do types tunnel/transport/passthrough")
if (shunt) {
if (("ah" in s) || ("esp" in s))
fail(type " connection may not specify AH or ESP")
} else {
if (!("ah" in s) && !("esp" in s))
fail("neither AH nor ESP specified for connection")
}
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)
}
leftsub = ("leftsubnet" in s) ? 1 : 0
default("leftsubnet", s["left"] "/32")
rightsub = ("rightsubnet" in s) ? 1 : 0
default("rightsubnet", s["right"] "/32")
default("leftfirewall", "no")
default("rightfirewall", "no")
yesno("leftfirewall")
yesno("rightfirewall")
integer("espreplay_window")
if (("espreplay_window" in s) && s["espreplay_window"] == 0)
delete s["espreplay_window"]
integer("ahreplay_window")
if (("ahreplay_window" in s) && s["ahreplay_window"] == 0)
delete s["ahreplay_window"]
netfix("left")
netfix("right")
default("leftnexthop", s["right"])
default("rightnexthop", s["left"])
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")
bidir("espenckey")
bidir("espauthkey")
bidir("ahkey")
if ("spi" in s && "spibase" in s)
fail("cannot specify both spi and spibase")
if (!shunt) {
if ("spibase" in s) {
b = s["spibase"]
if (b !~ /^0x[0-9a-fA-F]+0$/)
fail("bad syntax in spibase -- must be 0x...0")
spibase = substr(b, 1, length(b)-1)
} else {
need("spi")
if (s["spi"] !~ /^0x[0-9a-fA-F]+$/)
fail("bad syntax in spi -- must be 0x...")
}
}
spir = 0
spil = 1
# who am I?
me = ""
for (addr in interface) {
if (addr == s["left"] || addr == s["right"]) {
if (me != "")
fail("ambiguous: could be on \"" iface \
"\" or \"" interface[addr] "\"")
me = addr
iface = interface[addr]
}
}
if (me == "")
fail("cannot find interface for " s["left"] " or " s["right"])
if (other) {
if (s["left"] == me)
me = s["right"]
else if (s["right"] == me)
me = s["left"]
}
havesubnet = leftsubnet
if (s["right"] == me) {
swap("") # swaps "left" and "right"
swap("subnet")
swap("nexthop")
swap("net")
swap("mask")
swap("firewall")
swap("espspi")
swap("ahspi")
swap("espenckey")
swap("espauthkey")
swap("ahkey")
swap("updown")
t = spil
spil = spir
spir = t
havesubnet = rightsubnet
}
him = s["right"]
if (s["leftnexthop"] == "%defaultroute") {
if (drnexthop == "")
fail("%defaultroute requested but not known")
s["leftnexthop"] = drnexthop
}
tspi = rightward()
if (type == "tunnel") {
espi = rightward()
intspi = leftward()
} else
espi = tspi
if (s["rightespspi"] != "")
espi = s["rightespspi"]
respi = leftward()
if (s["leftespspi"] != "")
respi = s["leftespspi"]
if ("ah" in s) {
if ("esp" in s) {
aspi = rightward()
raspi = leftward()
} else {
aspi = espi
raspi = respi
}
if (s["rightahspi"] != "")
aspi = s["rightahspi"]
if (s["leftahspi"] != "")
raspi = s["leftahspi"]
}
routeid = "-net " s["rightnet"] " netmask " s["rightmask"]
if (s["rightmask"] == "255.255.255.255")
routeid = "-host " s["rightnet"]
print "PATH=\"'"$PATH"'\""
print "export PATH"
print "PLUTO_VERSION=1.1"
verbsuf = (havesubnet) ? "-client" : "-host"
print "PLUTO_CONNECTION=" q(names)
print "PLUTO_NEXT_HOP=" s["leftnexthop"]
print "PLUTO_INTERFACE=" iface
print "PLUTO_ME=" me
print "PLUTO_MY_CLIENT=" s["leftsubnet"]
print "PLUTO_MY_CLIENT_NET=" s["leftnet"]
print "PLUTO_MY_CLIENT_MASK=" s["leftmask"]
print "PLUTO_PEER=" him
print "PLUTO_PEER_CLIENT=" s["rightsubnet"]
print "PLUTO_PEER_CLIENT_NET=" s["rightnet"]
print "PLUTO_PEER_CLIENT_MASK=" s["rightmask"]
print "export PLUTO_VERSION PLUTO_CONNECTION PLUTO_NEXT_HOP"
print "export PLUTO_INTERFACE PLUTO_ME PLUTO_MY_CLIENT"
print "export PLUTO_MY_CLIENT_NET PLUTO_MY_CLIENT_MASK PLUTO_PEER"
print "export PLUTO_PEER_CLIENT PLUTO_PEER_CLIENT_NET"
print "export PLUTO_PEER_CLIENT_MASK"
if (op == "--up") {
print "{"
# first, the outbound SAs
if (type == "tunnel") {
print "ipsec spi --label", q(names), "--af inet",
"--said", ("tun" tspi "@" him), "\\"
print "\t--ip4", "--src", me, "--dst", him, "&&"
}
espspi(me, him, espi)
ahspi(me, him, aspi)
if (nrspi > 1) {
# group them
printf "ipsec spigrp --label %s --said ", q(names)
if (type == "tunnel")
printf "tun%s@%s ", tspi, him
if (("esp" in s))
printf "esp%s@%s ", espi, him
if ("ah" in s)
printf "ah%s@%s ", aspi, him
printf " &&\n"
}
# inbound SAs
if (type == "tunnel") {
print "ipsec spi --label", q(names), "--af inet",
"--said", ("tun" intspi "@" me), "\\"
print "\t--ip4", "--src", him, "--dst", me, "&&"
}
espspi(him, me, respi)
ahspi(him, me, raspi)
if (nlspi > 1) {
# group them
printf "ipsec spigrp --label %s --said ", q(names)
if (type == "tunnel")
printf "tun%s@%s ", intspi, me
if (("esp" in s))
printf "esp%s@%s ", respi, me
if ("ah" in s)
printf "ah%s@%s ", raspi, me
printf " &&\n"
}
# with the SAs in place, eroute to them
print "ipsec eroute --label", q(names),
"--eraf inet --replace", "\\"
if (!shunt) {
if (type == "tunnel")
p = "tun"
else if (("esp" in s))
p = "esp"
else
p = "ah"
p = p tspi "@" him
}
print "\t--src", s["leftsubnet"], "--dst", s["rightsubnet"],
"--said", p, "&&"
# with the eroute in place, NOW we can route to it
#print "{ route del", routeid, "2>/dev/null ; true ; } &&"
updown("prepare", "&&")
#print "route add", routeid, "dev", iface, "gw",
# s["leftnexthop"], "&&"
updown("route", "&&")
# and with all processing in place, we can penetrate firewall
#if (s["leftfirewall"] == "yes") {
# print "ipfwadm -F -i accept -b -S", s["leftsubnet"],
# "-D", s["rightsubnet"], "&&"
#}
updown("up", "&&")
print "true"
print "} || {"
} else if (op == "--route") {
#print "{ route del", routeid, "2>/dev/null ; true ; } &&"
updown("prepare", "&&")
#print "route add", routeid, "dev", iface, "gw",
# s["leftnexthop"]
updown("route")
exit 0
} else if (op == "--unroute") {
#print "route del", routeid, "dev", iface, "gw",
# s["leftnexthop"]
updown("unroute")
exit 0
} else # down
print "{"
# now do "down", unconditionally, since the desired output for "up"
# is { up && up && up && true } || { down ; down ; down }
# tear things down in fairly strict reverse order
#if (s["leftfirewall"] == "yes")
# print "ipfwadm -F -d accept -b -S", s["leftsubnet"],
# "-D", s["rightsubnet"]
updown("down")
#print "route del", routeid, "dev", iface, "gw", s["leftnexthop"]
print "# do not delete route"
print "ipsec eroute --label", q(names), "--eraf inet --del", "\\"
print "\t--src", s["leftsubnet"], "--dst", s["rightsubnet"]
#if ("ah" in s) {
# print "ipsec spi --label", q(names), "--af inet", "--del",
# "--said", ("ah" raspi "@" me)
#}
#if ("esp" in s) {
# print "ipsec spi --label", q(names), "--af inet", "--del",
# "--said", ("esp" respi "@" me)
#}
if (!shunt) {
if (type == "tunnel")
p = "tun"
else if (("esp" in s))
p = "esp"
else
p = "ah"
print "ipsec spi --label", q(names), "--af inet", "--del",
"--said", (p tspi "@" him),
" # outbound"
print "ipsec spi --label", q(names), "--af inet", "--del",
"--said", (p intspi "@" me),
" # inbound"
}
if (op == "--up")
print "} 2>/dev/null"
else
print "}"
#########
}' |
if test $showonly
then
cat
else
sh $shopts
fi