- import of strongswan-2.7.0

- applied patch for charon
This commit is contained in:
Martin Willi
2006-04-28 07:14:48 +00:00
parent 52923c9acb
commit 997358a6c4
2043 changed files with 346842 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
# Makefile for the KLIPS interface utilities
# Copyright (C) 1998, 1999 Henry Spencer.
# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
#
# 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.8 2006/04/17 11:04:45 as Exp $
FREESWANSRCDIR=..
include ${FREESWANSRCDIR}/Makefile.inc
SUBDIRS=spi eroute spigrp tncfg klipsdebug pf_key proc pluto
SUBDIRS+=_confread _copyright _include _keycensor _plutoload _plutorun
SUBDIRS+=_realsetup _secretcensor _startklips _updown _updown_espmark
SUBDIRS+=auto barf ipsec look manual ranbits secrets starter
SUBDIRS+=rsasigkey send-pr setup showdefaults showhostkey calcgoo mailkey
SUBDIRS+=ikeping examples openac scepclient
ifeq ($(USE_LWRES),true)
SUBDIRS+=lwdnsq
endif
ifeq ($(USE_IPSECPOLICY),true)
SUBDIRS+=showpolicy
endif
def:
@echo "Please read doc/intro.html or INSTALL before running make"
@false
# programs
cleanall distclean mostlyclean realclean install programs checkprograms check clean spotless install_file_list:
@for d in $(SUBDIRS) ; \
do \
(cd $$d && $(MAKE) FREESWANSRCDIR=$(FREESWANSRCDIR)/.. $@ ) || exit 1;\
done; \
+150
View File
@@ -0,0 +1,150 @@
include ${FREESWANSRCDIR}/Makefile.ver
CFLAGS+=$(USERCOMPILE) -I${KLIPSINC}
CFLAGS+= -Wall
#CFLAGS+= -Wconversion
#CFLAGS+= -Wmissing-prototypes
CFLAGS+= -Wpointer-arith
CFLAGS+= -Wcast-qual
#CFLAGS+= -Wmissing-declarations
CFLAGS+= -Wstrict-prototypes
#CFLAGS+= -pedantic
#CFLAGS+= -W
#CFLAGS+= -Wwrite-strings
CFLAGS+= -Wbad-function-cast
# die if there are any warnings
ifndef WERROR
WERROR:= -Werror
endif
#CFLAGS+= ${WERROR}
ifneq ($(LD_LIBRARY_PATH),)
LDFLAGS=-L$(LD_LIBRARY_PATH)
endif
MANDIR8=$(MANTREE)/man8
MANDIR5=$(MANTREE)/man5
ifndef PROGRAMDIR
PROGRAMDIR=${LIBEXECDIR}
endif
ifndef MANPROGPREFIX
MANPROGPREFIX=ipsec_
endif
ifndef CONFDSUBDIR
CONFDSUBDIR=.
endif
all: $(PROGRAM)
programs: all
ifneq ($(PROGRAM),check)
check: $(PROGRAM)
endif
ifneq ($(NOINSTALL),true)
install:: $(PROGRAM) $(CONFFILES) $(EXTRA8MAN) $(EXTRA5MAN) $(EXTRA5PROC) $(LIBFILES) $(CONFDFILES)
@mkdir -p $(PROGRAMDIR) $(MANDIR8) $(MANDIR5) $(LIBDIR) $(CONFDIR) $(CONFDDIR) $(CONFDDIR)/$(CONFDSUBDIR) $(EXAMPLECONFDIR)
@if [ -n "$(PROGRAM)" ]; then $(INSTALL) $(INSTBINFLAGS) $(PROGRAM) $(PROGRAMDIR); fi
@$(foreach f, $(addsuffix .8, $(PROGRAM)), \
$(INSTALL) $(INSTMANFLAGS) $f $(MANDIR8)/$(MANPROGPREFIX)$f || exit 1; \
)
@$(foreach f, $(EXTRA8MAN), \
$(INSTALL) $(INSTMANFLAGS) $f $(MANDIR8)/ipsec_$f || exit 1; \
)
@$(foreach f, $(EXTRA5MAN), \
$(INSTALL) $(INSTMANFLAGS) $f $(MANDIR5)/$f || exit 1 ;\
)
@$(foreach f, $(EXTRA5PROC), \
$(INSTALL) $(INSTMANFLAGS) $f $(MANDIR5)/ipsec_$f || exit 1 ;\
)
@$(foreach f, $(LIBFILES), \
$(INSTALL) $(INSTCONFFLAGS) $f $(LIBDIR)/$f || exit 1 ;\
)
@$(foreach f, $(CONFFILES), \
if [ ! -f $(CONFDIR)/$f ]; then $(INSTALL) $(INSTCONFFLAGS) $f $(CONFDIR)/$f || exit 1; fi;\
$(INSTALL) $(INSTCONFFLAGS) $f $(EXAMPLECONFDIR)/$f-sample || exit 1; \
)
@$(foreach f, $(CONFDFILES), \
if [ ! -f $(CONFDDIR)/$(CONFDSUBDIR)/$f ]; then $(INSTALL) $(INSTCONFFLAGS) $f $(CONFDDIR)/$(CONFDSUBDIR)/$f || exit 1; fi;\
)
install_file_list::
@if [ -n "$(PROGRAM)" ]; then echo $(PROGRAMDIR)/$(PROGRAM); fi
@$(foreach f, $(addsuffix .8, $(PROGRAM)), \
echo $(MANDIR8)/${MANPROGPREFIX}$f; \
)
@$(foreach f, $(EXTRA8MAN), \
echo $(MANDIR8)/ipsec_$f; \
)
@$(foreach f, $(EXTRA5MAN), \
echo $(MANDIR5)/$f;\
)
@$(foreach f, $(EXTRA5PROC), \
echo $(MANDIR5)/ipsec_$f; \
)
@$(foreach f, $(LIBFILES), \
echo $(LIBDIR)/$f;\
)
@$(foreach f, $(CONFFILES), \
echo $(CONFDIR)/$f;\
echo $(EXAMPLECONFDIR)/$f-sample;\
)
@$(foreach f, $(CONFDFILES), \
echo $(CONFDDIR)/${CONFDSUBDIR}/$f;\
)
endif
# cancel the rule that compiles directly
%: %.c
%: %.o $(OBJS)
$(CC) $(CFLAGS) -o $@ $@.o ${OBJS} $(LDFLAGS) $(LIBS)
%: %.in ${FREESWANSRCDIR}/Makefile.inc ${FREESWANSRCDIR}/Makefile.ver
cat $< | sed -e "s/xxx/$(IPSECVERSION)/" \
-e "s:@IPSEC_DIR@:$(FINALBINDIR):" \
-e "s:@IPSEC_EXECDIR@:$(FINALLIBEXECDIR):" \
-e "s:@IPSEC_SBINDIR@:$(FINALSBINDIR):" \
-e "s:@IPSEC_LIBDIR@:$(FINALLIBDIR):" \
-e "s:@FINALCONFDIR@:$(FINALCONFDIR):" \
-e "s:@EXAMPLECONFDIR@:$(EXAMPLECONFDIR):" \
-e "s:@FINALDOCDIR@:$(FINALDOCDIR):" \
-e "s:@FINALEXAMPLECONFDIR@:$(FINALEXAMPLECONFDIR):" \
-e "s:@MODULE_GOO_LIST@:$(MODULE_GOO_LIST):" \
-e "s:@IPSEC_CONFS@:$(FINALCONFDIR):" \
-e "s:@IPSEC_CONFDDIR@:$(FINALCONFDDIR):" \
-e "s:@USE_IPROUTE2@:$(USE_IPROUTE2):" \
-e "s:@IPSEC_FIREWALLTYPE@:$(IPSEC_FIREWALLTYPE):" \
| cat >$@
if [ -x $< ]; then chmod +x $@; fi
if [ "${PROGRAM}.in" = $< ]; then chmod +x $@; fi
cleanall: clean
distclean: clean
mostlyclean: clean
realclean: clean
clean::
ifneq ($(strip $(PROGRAM)),)
@if [ -r $(PROGRAM).in ]; then rm -f $(PROGRAM); fi
@if [ -r $(PROGRAM).c ]; then rm -f $(PROGRAM); fi
@if [ -n "$(OBJS)" ]; then rm -f $(PROGRAM); fi
endif
@rm -f *.o
checkprograms:
+7
View File
@@ -0,0 +1,7 @@
_confread
ipsec.conf
block
clear
private
clear-or-private
private-or-clear
+27
View File
@@ -0,0 +1,27 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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 2004/03/31 19:23:00 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_confread
PROGRAMDIR=${LIBDIR}
EXTRA5MAN=ipsec.conf.5
CONFFILES=ipsec.conf
CONFDSUBDIR=policies
CONFDFILES=clear clear-or-private private-or-clear private block
include ../Makefile.program
+103
View File
@@ -0,0 +1,103 @@
Subject: [Design] changes to ipsec.conf
# RCSID $Id: README.conf.V2,v 1.1 2004/03/15 20:35:27 as Exp $
We are changing ipsec.conf for the 2.0 series of FreeS/WAN.
OE is enabled by default. This is accomplished by automatically
defining a conn "OEself" UNLESS the sysadmin defines one with the same
name:
conn OEself
# authby=rsasig # default
left=%defaultroute
leftrsasigkey=%dnsondemand # default
right=%opportunistic
rightrsasigkey=%dnsondemand # default
keyingtries=3
ikelifetime=1h
keylife=1h # default
rekey=no
# disablearrivalcheck=no # default
auto=route
This will only work if %defaultroute works.
The leftid will be the resulting IP address (won't work if
you haven't filled in the reverse DNS entry).
Unlike other conns, nothing in this implicit conn is changed by conn %default.
We'd like a better name. A conn name starting with % cannot be
defined by the sysadmin, so that is out. Names that haven't grabbed
us: OEhost, OElocalhost, OEthishost, OEforself, OE4self.
There is no requirement to have /etc/ipsec.conf. If you do, the first
significant line (non-blank, non-comment) must be (not indented):
version 2.0
This signifies that the file was intended for FreeS/WAN version 2.0.
The following table shows most changes. "-" means that the option
doesn't exist. "Recent Boilerplate" shows the effect of the "conn
%default" in the automatically installed /etc/ipsec.conf (not
installed if you already had one).
Option Old Default Recent Boilerplate New Default
====== =========== ================== ===========
config setup:
interfaces "" %defaultroute %defaultroute
plutoload "" %search - [same as %search]
plutostart "" %search - [same as %search]
uniqueids no yes yes
rp_filter - - 0
plutowait yes yes no
dump no no - [use dumpdir]
plutobackgroundload ignored ignored -
no_eroute_pass no no - [use packetdefault]
conn %default:
keyingtries 3 0 %forever [0 means this]
disablearrivalcheck yes no no
authby secret rsasig rsasig
leftrsasigkey "" %dnsondemand %dnsondemand
rightrsasigkey "" %dnsondemand %dnsondemand
lifetime ==keylife ==keylife - [use keylife]
rekeystart ==rekeymargin ==rekeymargin - [use rekeymargin]
rekeytries ==keyingtries ==keyingtries - [use keyingtries]
====== =========== ================== ===========
Option Old Default Recent Boilerplate New Default
The auto= mechanism has been extended to support manual conns. If you
specify auto=manual in a conn, an "ipsec manual" will be performed on
it at startup (ipsec setup start).
There is a new config setup option "rp_filter". It controls
/proc/sys/net/ipv4/conf/PHYS/rp_filter
for each PHYSical IP interface used by FreeS/WAN. Settings are:
%unchanged do not touch (but warn if wrong)
0 set to 0; default; means: no filtering
1 set to 1; means: loose filter
2 set to 1; means: strict filter
0 is often necessary for FreeS/WAN to function. Some folks
want other settings. Shutting down FreeS/WAN does not restore
the original value.
Currently ikelife defaults to 1 hour and keylife defaults to 8 hours.
There have been some rumblings that these are the wrong defaults, but
it isn't clear what would be best. Perhaps both should be closer.
Any thoughts of what these should be? Any Road Warrior or OE conn
should probably have carefully thought-out values explicitly
specified. The settings don't matter much for VPN connections.
keyingtries=%forever is the new improved notation for keyingtries=0.
Eventually the 0 notation will be eliminated.
Some options can now be set to %none to signify no setting. Otherwise
there would be no way for the user to override a default setting:
leftrsasigkey, rightrsasigkey [added in 1.98]
interfaces
Hugh Redelmeier
[email protected] voice: +1 416 482-8253
+28
View File
@@ -0,0 +1,28 @@
.TH _CONFREAD 8 "25 Apr 2002"
.\"
.\" RCSID $Id: _confread.8,v 1.1 2004/03/15 20:35:27 as Exp $
.\"
.SH NAME
ipsec _confread \- internal routing to parse config file
.SH DESCRIPTION
.I _confread
is an internal script used for parsing /etc/ipsec.conf into a canonical format.
.SH "SEE ALSO"
ipsec(8), ipsec_conf(8)
.SH HISTORY
Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
by Michael Richardson. Program written by Henry Spencer.
.\"
.\" $Log: _confread.8,v $
.\" Revision 1.1 2004/03/15 20:35:27 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.3 2002/09/16 01:28:43 dhr
.\"
.\" typo
.\"
.\" Revision 1.2 2002/04/29 22:39:31 mcr
.\" added basic man page for all internal commands.
.\"
.\"
.\"
+520
View File
@@ -0,0 +1,520 @@
#!/bin/sh
# configuration-file reader utility
# Copyright (C) 1999-2002 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: _confread.in,v 1.15 2006/04/20 04:42:12 as Exp $
#
# Extract configuration info from /etc/ipsec.conf, repackage as assignments
# to shell variables or tab-delimited fields. Success or failure is reported
# inline, as extra data, due to the vagaries of shell backquote handling.
# In the absence of --varprefix, output is tab-separated fields, like:
# = sectionname
# : parameter value
# ! status (empty for success, else complaint)
# In the presence of (say) "--varprefix IPSEC", output is like:
# IPSEC_confreadsection="sectionname"
# IPSECparameter="value"
# IPSEC_confreadstatus="status" (same empty/complaint convention)
#
# The "--search parametername" option inverts the search: instead of
# yielding the parameters of the specified name(s), it yields the names
# of sections with parameter <parametername> having (one of) the
# specified value(s). In this case, --varprefix output is a list of
# names in the <prefix>_confreadnames variable. Search values with
# white space in them are currently not handled properly.
#
# Typical usage:
# eval `ipsec _confread --varprefix IPSEC --type config setup`
# if test " $IPSEC_confreadstatus" != " "
# then
# echo "$0: $IPSEC_confreadstatus -- aborting" 2>&1
# exit 1
# fi
# absent default config file treated as empty
config=${IPSEC_CONFS-@FINALCONFDIR@}/ipsec.conf
if test ! -f "$config" ; then config=/dev/null ; fi
include=yes
type=conn
fieldfmt=yes
prefix=
search=
export=0
version=
optional=0
me="ipsec _confread"
for dummy
do
case "$1" in
--config) config="$2" ; shift ;;
--noinclude) include= ;;
--type) type="$2" ; shift ;;
--varprefix) fieldfmt=
prefix="$2"
shift ;;
--export) export=1 ;;
--search) search="$2" ; shift ;;
--version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
--optional) optional=1 ;;
--) shift ; break ;;
-*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
*) break ;;
esac
shift
done
if test "$include"
then
ipsec _include --inband $config
else
cat $config
fi |
awk 'BEGIN {
type = "'"$type"'"
names = "'"$*"'"
prefix = "'"$prefix"'"
export = "'"$export"'"
optional = 0 + '"$optional"'
myid = "'"$IPSECmyid"'"
search = "'"$search"'"
searching = 0
if (search != "") {
searching = 1
searchpat = search "[ \t]*=[ \t]*"
}
fieldfmt = 0
if ("'"$fieldfmt"'" == "yes")
fieldfmt = 1
including = 0
if ("'"$include"'" == "yes")
including = 1
filename = "'"$config"'"
lineno = 0
originalfilename = filename
if (fieldfmt)
bq = eq = "\""
else
bq = eq = "\\\""
failed = 0
insection = 0
wrongtype = 0
indefault = 0
outputting = 0
sawnondefault = 0
OFS = "\t"
o_status = "!"
o_parm = ":"
o_section = "="
o_names = "%"
o_end = "."
n = split(names, na, " ")
if (n == 0)
fail("no section names supplied")
for (i = 1; i <= n; i++) {
if (na[i] in wanted)
fail("section " bq na[i] eq " requested more than once")
wanted[na[i]] = 1
pending[na[i]] = 1
if (!searching && na[i] !~ /^[a-zA-Z][a-zA-Z0-9._-]*$/)
fail("invalid section name " bq na[i] eq)
}
good = "also alsoflip type auto authby _plutodevel"
left = " left leftsubnet leftnexthop leftfirewall lefthostaccess leftupdown"
akey = " keyexchange auth pfs keylife rekey rekeymargin rekeyfuzz"
akey = akey " dpdaction dpddelay dpdtimeout"
akey = akey " pfsgroup compress"
akey = akey " keyingtries ikelifetime disablearrivalcheck failureshunt ike"
mkey = " spibase spi esp espenckey espauthkey espreplay_window"
left = left " leftespenckey leftespauthkey leftahkey"
left = left " leftespspi leftahspi leftid leftrsasigkey leftrsasigkey2"
left = left " leftsendcert leftcert leftca leftsubnetwithin leftprotoport"
left = left " leftgroups leftsourceip"
mkey = mkey " ah ahkey ahreplay_window"
right = left
gsub(/left/, "right", right)
n = split(good left right akey mkey, g)
for (i = 1; i <= n; i++)
goodnames["conn:" g[i]] = 1
good = "also interfaces forwardcontrol myid"
good = good " syslog klipsdebug plutodebug plutoopts plutostderrlog"
good = good " plutorestartoncrash"
good = good " dumpdir manualstart pluto"
good = good " plutowait prepluto postpluto"
good = good " fragicmp hidetos rp_filter uniqueids"
good = good " overridemtu pkcs11module pkcs11keepstate pkcs11proxy"
good = good " nocrsend strictcrlpolicy crlcheckinterval cachecrls"
good = good " nat_traversal keep_alive force_keepalive"
good = good " disable_port_floating virtual_private"
n = split(good, g)
for (i = 1; i <= n; i++)
goodnames["config:" g[i]] = 1
good = "auto cacert ldaphost ldapbase crluri crluri2 ocspuri"
good = good " strictcrlpolicy"
n = split(good, g)
for (i = 1; i <= n; i++)
goodnames["ca:" g[i]] = 1
goodtypes["conn"] = 1
goodtypes["config"] = 1
goodtypes["ca"] = 1
badchars = ""
for (i = 1; i < 32; i++)
badchars = badchars sprintf("%c", i)
for (i = 127; i < 128+32; i++)
badchars = badchars sprintf("%c", i)
badchar = "[" badchars "]"
# if searching, seen is set of sectionnames which match
# if not searching, seen is set of parameter names found
seen[""] = ""
defaults[""] = ""
usesdefault[""] = ""
orientation = 1
}
function output(code, v1, v2) {
if (code == o_parm) {
if (v2 == "") # suppress empty parameters
return
if (privatename(v1)) # and private ones
return
if (v2 ~ badchar)
fail("parameter value " bq v2 eq " contains unprintable character")
}
if (fieldfmt) {
print code, v1, v2
return
}
if (code == o_status) {
v2 = v1
v1 = "_confreadstatus"
} else if (code == o_section) {
v2 = v1
v1 = "_confreadsection"
} else if (code == o_names) {
v2 = v1
v1 = "_confreadnames"
} else if (code != o_parm)
return # currently no variable version of o_end
print prefix v1 "=\"" v2 "\""
if (export)
print "export " prefix v1
}
function searchfound(sectionname, n, i, reflist) {
# a hit in x is a hit in everybody who refers to x too
n = split(refsto[sectionname], reflist, ";")
for (i = 1; i <= n; i++)
if (reflist[i] in seen)
fail("duplicated parameter " bq search eq)
else
seen[reflist[i]] = 1
seen[sectionname] = 1
}
function fail(msg) {
output(o_status, ("(" filename ", line " lineno ") " msg))
failed = 1
while ((getline junk) > 0)
continue
exit
}
function badname(n) {
if ((type ":" n) in goodnames)
return 0
if (privatename(n))
return 0
return 1
}
function privatename(n) {
if (n ~ /^[xX][-_]/)
return 1
return 0
}
function orient(n) {
if (orientation == -1) {
if (n ~ /left/)
gsub(/left/, "right", n)
else if (n ~ /right/)
gsub(/right/, "left", n)
}
return n
}
# in searching, referencing is transitive: xyz->from->to
function chainref(from, to, i, reflist, listnum) {
if (from in refsto) {
listnum = split(refsto[from], reflist, ";")
for (i = 1; i <= listnum; i++)
chainref(reflist[i], to)
}
if (to in refsto)
refsto[to] = refsto[to] ";" from
else
refsto[to] = from
}
# start of rules
{
lineno++
# lineno is now the number of this line
# we must remember indentation because comment stripping loses it
exdented = $0 !~ /^[ \t]/
sub(/^[ \t]+/, "") # get rid of leading white space
sub(/[ \t]+$/, "") # get rid of trailing white space
}
including && $0 ~ /^#[<>:]/ {
# _include control line
if ($1 ~ /^#[<>]$/) {
filename = $2
lineno = $3 - 1
} else if ($0 ~ /^#:/) {
msg = substr($0, 3)
gsub(/"/, "\\\"", msg)
fail(msg)
}
next
}
exdented {
# any non-leading-white-space line is a section end
### but not the end of relevant stuff, might be also= sections later
###if (insection && !indefault && !searching && outputting)
### output(o_end)
insection = 0
wrongtype = 0
indefault = 0
outputting = 0
}
/[ \t]#/ {
# strip trailing comments including the leading whitespace
# tricky because we must respect quotes
q = 0
for (i = 1; i <= NF; i++) {
if ($i ~ /^#/ && q % 2 == 0) {
NF = i - 1;
break
}
# using $i in gsub loses whitespace?!?
junk = $i
q += gsub(/"/, "&", junk)
}
}
$0 == "" || $0 ~ /^#/ {
# empty lines and comments are ignored
next
}
exdented && NF != 2 {
# bad section header
fail("section header " bq $0 eq " has wrong number of fields (" NF ")")
}
exdented && $1 == "version" {
version = $2 + 0
if (version < 2.0 || 2.0 < version)
fail("we only support version 2.0 ipsec.conf files, not " bq version eq)
next
}
version == "" {
fail("we only support version 2 ipsec.conf files")
}
exdented && !($1 in goodtypes) {
# unknown section type
fail("section type " bq $1 eq " not recognized")
}
exdented && $1 != type {
# section header, but not of the type we want
insection = 1
wrongtype = 1
next
}
extented {
# type fits
wrongtype = 0
}
exdented && $1 == "config" && $2 != "setup" {
fail("unknown config section " bq $2 eq)
}
exdented && $2 != "%default" {
# non-default section header of our type
sawnondefault = 1
}
exdented && searching && $2 != "%default" {
# section header, during search
insection = 1
sectionname = $2
usesdefault[sectionname] = 1 # tentatively
next
}
exdented && !searching && $2 in wanted {
# one of our wanted section headers
if (!($2 in pending))
fail("duplicate " type " section " bq $2 eq)
delete pending[$2]
tag = bq type " " $2 eq
outputting = 1
insection = 1
orientation = wanted[$2]
output(o_section, $2)
next
}
exdented && $2 == "%default" {
# relevant default section header
if (sawnondefault)
fail(bq $1 " %default" eq " sections must precede non-default ones")
tag = bq type " " $2 eq
indefault = 1
next
}
exdented {
# section header, but not one we want
insection = 1
next
}
!insection && !indefault {
# starts with white space but not in a section... oops
fail("parameter is not within a section")
}
!wrongtype && searching && $0 ~ searchpat {
# search found the right parameter name
match($0, searchpat)
rest = substr($0, RLENGTH+1)
if (rest ~ /^".*"$/)
rest = substr(rest, 2, length(rest)-2)
if (!indefault) {
if (!usesdefault[sectionname])
fail("duplicated parameter " bq search eq)
usesdefault[sectionname] = 0
} else if (search in defaults)
fail("duplicated parameter " bq search eq)
if (rest in wanted) { # a hit
if (indefault)
defaults[search] = rest
else
searchfound(sectionname)
} else {
# rather a kludge, but must check this somewhere
if (search == "auto" && rest !~ /^(add|route|start|ignore|manual)$/)
fail("illegal auto value " bq rest eq)
}
next
}
!searching && !outputting && !indefault {
# uninteresting line
next
}
$0 ~ /"/ && $0 !~ /^[^=]+=[ \t]*"[^"]*"$/ {
if (!searching)
fail("mismatched quotes in parameter value")
else
gsub(/"/, "", $0)
}
$0 !~ /^[a-zA-Z_][a-zA-Z0-9_-]*[ \t]*=/ {
if (searching)
next # just ignore it
fail("syntax error or illegal parameter name")
}
{
sub(/[ \t]*=[ \t]*/, "=") # get rid of white space around =
}
$0 ~ /^(also|alsoflip)=/ {
v = orientation
if ($0 ~ /^alsoflip/)
v = -v;
if (indefault)
fail("%default section may not contain " bq "also" eq " or " bq "alsoflip" eq " parameter")
sub(/^(also|alsoflip)=/, "")
if ($0 !~ /^[a-zA-Z][a-zA-Z0-9._-]*$/)
fail("invalid section name " bq $0 eq)
if (!searching) {
if ($0 in wanted)
fail("section " bq $0 eq " requested more than once")
wanted[$0] = v
pending[$0] = 1
} else
chainref(sectionname, $0)
next
}
!outputting && !indefault {
# uninteresting line even for a search
next
}
{
equal = match($0, /[=]/)
name = substr($0, 1, equal-1)
if (badname(name))
fail("unknown parameter name " bq name eq)
value = substr($0, equal+1)
if (value ~ /^"/)
value = substr(value, 2, length(value)-2)
else if (value ~ /[ \t]/)
fail("white space within non-quoted parameter " bq name eq)
}
indefault {
if (name in defaults)
fail("duplicated default parameter " bq name eq)
defaults[name] = value
next
}
{
name = orient(name)
if (name in seen)
fail("duplicated parameter " bq name eq)
seen[name] = 1
output(o_parm, name, value)
}
END {
if (failed)
exit 1
filename = originalfilename
unseen = ""
for (i in pending)
unseen = unseen " " i
if (!optional && !searching && unseen != "")
fail("did not find " type " section(s) " bq substr(unseen, 2) eq)
if (!searching) {
for (name in defaults)
if (!(name in seen))
output(o_parm, name, defaults[name])
} else {
if (defaults[search] in wanted)
for (name in usesdefault)
if (usesdefault[name])
seen[name] = 1
delete seen[""]
if (fieldfmt)
for (name in seen)
output(o_section, name)
else {
outlist = ""
for (name in seen)
if (outlist == "")
outlist = name
else
outlist = outlist " " name
output(o_names, outlist)
}
}
output(o_status, "")
}'
+8
View File
@@ -0,0 +1,8 @@
# This file defines the set of CIDRs (network/mask-length) to which
# communication should never be allowed.
#
# See @FINALDOCDIR@/policygroups.html for details.
#
# $Id: block.in,v 1.1 2004/03/15 20:35:27 as Exp $
#
+8
View File
@@ -0,0 +1,8 @@
# This file defines the set of CIDRs (network/mask-length) to which
# we will communicate in the clear, or, if the other side initiates IPSEC,
# using encryption. This behaviour is also called "Opportunistic Responder".
#
# See @FINALDOCDIR@/policygroups.html for details.
#
# $Id: clear-or-private.in,v 1.1 2004/03/15 20:35:27 as Exp $
#
+7
View File
@@ -0,0 +1,7 @@
# This file defines the set of CIDRs (network/mask-length) to which
# communication should always be in the clear.
#
# See @FINALDOCDIR@/policygroups.html for details.
#
# $Id: clear.in,v 1.1 2004/03/15 20:35:27 as Exp $
#
File diff suppressed because it is too large Load Diff
+44
View File
@@ -0,0 +1,44 @@
# /etc/ipsec.conf - strongSwan IPsec configuration file
# RCSID $Id: ipsec.conf.in,v 1.7 2006/01/31 13:09:10 as Exp $
# Manual: ipsec.conf.5
# Help: http://www.strongswan.org/docs/readme.htm
version 2.0 # conforms to second version of ipsec.conf specification
# basic configuration
config setup
# Debug-logging controls: "none" for (almost) none, "all" for lots.
# plutodebug=all
# crlcheckinterval=600
# strictcrlpolicy=yes
# cachecrls=yes
# nat_traversal=yes
# Uncomment to activate Opportunistic Encryption (OE)
# include /etc/ipsec.d/examples/oe.conf
# Add connections here.
# Sample VPN connections
#conn sample-self-signed
# left=%defaultroute
# leftsubnet=10.1.0.0/16
# leftcert=selfCert.der
# leftsendcert=never
# right=192.168.0.2
# rightsubnet=10.2.0.0/16
# rightcert=peerCert.der
# auto=start
#conn sample-with-ca-cert
# left=%defaultroute
# leftsubnet=10.1.0.0/16
# leftcert=myCert.pem
# right=192.168.0.2
# rightsubnet=10.2.0.0/16
# rightid="C=CH, O=Linux strongSwan CN=peer name"
# auto=start
+14
View File
@@ -0,0 +1,14 @@
# This file defines the set of CIDRs (network/mask-length) to which
# communication should be private, if possible, but in the clear otherwise.
#
# If the target has a TXT (later IPSECKEY) record that specifies
# authentication material, we will require private (i.e. encrypted)
# communications. If no such record is found, communications will be
# in the clear.
#
# See @FINALDOCDIR@/policygroups.html for details.
#
# $Id: private-or-clear.in,v 1.1 2004/03/15 20:35:27 as Exp $
#
0.0.0.0/0
+6
View File
@@ -0,0 +1,6 @@
# This file defines the set of CIDRs (network/mask-length) to which
# communication should always be private (i.e. encrypted).
# See @FINALDOCDIR@/policygroups.html for details.
#
# $Id: private.in,v 1.1 2004/03/15 20:35:27 as Exp $
#
+28
View File
@@ -0,0 +1,28 @@
#! /bin/sh
# internal utility for putting random keys into sample configuration file
# 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: randomize,v 1.1 2004/03/15 20:35:27 as Exp $
awk '/`[0-9]+`/ {
match($0, /`[0-9]+`/)
n = substr($0, RSTART+1, RLENGTH-2)
cmd = "./ranbits --quick " n
cmd | getline key
cmd | getline eof
close(cmd)
sub(/`[0-9]+`/, key, $0)
print
next
}
{ print }' $*
+1
View File
@@ -0,0 +1 @@
_copyright
+44
View File
@@ -0,0 +1,44 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_copyright
PROGRAMDIR=${LIBDIR}
LIBS=${FREESWANLIB}
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.3 2002/08/02 16:01:07 mcr
# moved user visible programs to $PREFIX/libexec, while moving
# private files to $PREFIX/lib.
#
# Revision 1.2 2002/06/02 22:02:14 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+32
View File
@@ -0,0 +1,32 @@
.TH _COPYRIGHT 8 "25 Apr 2002"
.\"
.\" RCSID $Id: _copyright.8,v 1.1 2004/03/15 20:35:27 as Exp $
.\"
.SH NAME
ipsec _copyright \- prints FreeSWAN copyright
.SH DESCRIPTION
.I _copyright
outputs the FreeSWAN copyright, and version numbers for "ipsec --copyright"
.SH "SEE ALSO"
ipsec(8)
.SH HISTORY
Man page written for the Linux FreeS/WAN project
<http://www.freeswan.org/>
by Michael Richardson. Program written by Henry Spencer.
.\"
.\" $Log: _copyright.8,v $
.\" Revision 1.1 2004/03/15 20:35:27 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.2 2002/04/29 22:39:31 mcr
.\" added basic man page for all internal commands.
.\"
.\" Revision 1.1 2002/04/26 01:21:43 mcr
.\" while tracking down a missing (not installed) /etc/ipsec.conf,
.\" MCR has decided that it is not okay for each program subdir to have
.\" some subset (determined with -f) of possible files.
.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
.\" Optional PROGRAM.5 files have been added to the makefiles.
.\"
.\"
.\"
+69
View File
@@ -0,0 +1,69 @@
/*
* copyright reporter
* (just avoids having the info in more than one place in the source)
* Copyright (C) 2001 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: _copyright.c,v 1.1 2004/03/15 20:35:27 as Exp $
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <freeswan.h>
char usage[] = "Usage: ipsec _copyright";
struct option opts[] = {
{"help", 0, NULL, 'h',},
{"version", 0, NULL, 'v',},
{0, 0, NULL, 0, },
};
char me[] = "ipsec _copyright"; /* for messages */
int
main(int argc, char *argv[])
{
int opt;
extern int optind;
int errflg = 0;
const char *version = ipsec_version_code();
const char **notice = ipsec_copyright_notice();
const char **co;
while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
switch (opt) {
case 'h': /* help */
printf("%s\n", usage);
exit(0);
break;
case 'v': /* version */
printf("%s %s\n", me, version);
exit(0);
break;
case '?':
default:
errflg = 1;
break;
}
if (errflg || optind != argc) {
fprintf(stderr, "%s\n", usage);
exit(2);
}
for (co = notice; *co != NULL; co++)
printf("%s\n", *co);
exit(0);
}
+1
View File
@@ -0,0 +1 @@
_include
+43
View File
@@ -0,0 +1,43 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_include
PROGRAMDIR=${LIBDIR}
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.3 2002/08/02 16:01:11 mcr
# moved user visible programs to $PREFIX/libexec, while moving
# private files to $PREFIX/lib.
#
# Revision 1.2 2002/06/02 22:02:14 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+35
View File
@@ -0,0 +1,35 @@
.TH _INCLUDE 8 "25 Apr 2002"
.\"
.\" RCSID $Id: _include.8,v 1.1 2004/03/15 20:35:27 as Exp $
.\"
.SH NAME
ipsec _include \- internal script to process config files
.SH DESCRIPTION
.I _include
is used by
.I _confread
to process
.B include
directives in /etc/ipsec.conf.
.SH "SEE ALSO"
ipsec(8), ipsec__confread(8)
.SH HISTORY
Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
by Michael Richardson. Program written by Henry Spencer.
.\"
.\" $Log: _include.8,v $
.\" Revision 1.1 2004/03/15 20:35:27 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.2 2002/04/29 22:39:31 mcr
.\" added basic man page for all internal commands.
.\"
.\" Revision 1.1 2002/04/26 01:21:43 mcr
.\" while tracking down a missing (not installed) /etc/ipsec.conf,
.\" MCR has decided that it is not okay for each program subdir to have
.\" some subset (determined with -f) of possible files.
.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
.\" Optional PROGRAM.5 files have been added to the makefiles.
.\"
.\"
.\"
+102
View File
@@ -0,0 +1,102 @@
#! /bin/sh
# implements nested file inclusion for control files, including wildcarding
# 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: _include.in,v 1.2 2004/03/15 21:03:06 as Exp $
#
# Output includes marker lines for file changes:
# "#< filename lineno" signals entry into that file
# "#> filename lineno" signals return to that file
# The lineno is the line number of the *next* line.
#
# Errors are reported with a "#:message" line rather than on stderr.
#
# Lines which look like marker and report lines are never passed through.
IPSEC_NAME="strongSwan"
usage="Usage: $0 file ..."
me="ipsec _include"
for dummy
do
case "$1" in
--inband) ;; # back compatibility
--help) echo "$usage" ; exit 0 ;;
--version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
--) shift ; break ;;
-*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
*) break ;;
esac
shift
done
case $# in
0) echo "$usage" >&2 ; exit 2 ;;
esac
for f
do
if test ! -r "$f"
then
if test ! "$f" = "/etc/ipsec.conf"
then
echo "#:cannot open configuration file \'$f\'"
if test "$f" = "/etc/ipsec.secrets"
then
echo "#:Your secrets file will be created when you start $IPSEC_NAME for the first time."
fi
exit 1
else
exit 1
fi
fi
done
awk 'BEGIN {
wasfile = ""
}
FNR == 1 {
print ""
print "#<", FILENAME, 1
lineno = 0
wasfile = FILENAME
}
{
lineno++
# lineno is now the number of this line
}
/^#[<>:]/ {
next
}
/^include[ \t]+/ {
orig = $0
sub(/[ \t]+#.*$/, "")
if (NF != 2) {
msg = "(" FILENAME ", line " lineno ")"
msg = msg " include syntax error in \"" orig "\""
print "#:" msg
exit 1
}
newfile = $2
if (newfile !~ /^\// && FILENAME ~ /\//) {
prefix = FILENAME
sub("[^/]+$", "", prefix)
newfile = prefix newfile
}
system("ipsec _include " newfile)
print ""
print "#>", FILENAME, lineno + 1
next
}
{ print }' $*
+1
View File
@@ -0,0 +1 @@
_keycensor
+43
View File
@@ -0,0 +1,43 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_keycensor
PROGRAMDIR=${LIBDIR}
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.3 2002/08/02 16:01:15 mcr
# moved user visible programs to $PREFIX/libexec, while moving
# private files to $PREFIX/lib.
#
# Revision 1.2 2002/06/02 22:02:14 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+33
View File
@@ -0,0 +1,33 @@
.TH _KEYCENSOR 8 "25 Apr 2002"
.\"
.\" RCSID $Id: _keycensor.8,v 1.1 2004/03/15 20:35:27 as Exp $
.\"
.SH NAME
ipsec _keycensor \- internal routine to remove sensitive information
.SH DESCRIPTION
.I _keycensor
is used by
.B ipsec barf
to process the /etc/ipsec.secrets file, removing private key info.
.SH "SEE ALSO"
ipsec(8), ipsec_barf(8)
.SH HISTORY
Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
by Michael Richardson. Original program by Henry Spencer.
.\"
.\" $Log: _keycensor.8,v $
.\" Revision 1.1 2004/03/15 20:35:27 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.2 2002/04/29 22:39:31 mcr
.\" added basic man page for all internal commands.
.\"
.\" Revision 1.1 2002/04/26 01:21:43 mcr
.\" while tracking down a missing (not installed) /etc/ipsec.conf,
.\" MCR has decided that it is not okay for each program subdir to have
.\" some subset (determined with -f) of possible files.
.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
.\" Optional PROGRAM.5 files have been added to the makefiles.
.\"
.\"
.\"
+52
View File
@@ -0,0 +1,52 @@
#! /bin/sh
# implements key censoring for barf
# Copyright (C) 1999, 2002 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: _keycensor.in,v 1.1 2004/03/15 20:35:27 as Exp $
usage="Usage: $0 [file ...]"
me="ipsec _keycensor"
for dummy
do
case "$1" in
--help) echo "$usage" ; exit 0 ;;
--version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
--) shift ; break ;;
-*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
*) break ;;
esac
shift
done
awk ' /(sig|enc|auth)key[ \t]*=[ \t]*[^%]/ {
i = match($0, /key[ \t]*=[ \t]*/)
i += RLENGTH
cold = substr($0, 1, i-1)
hot = substr($0, i)
sub(/[ \t]+(#.*)?$/, "", hot)
q = "'"'"'" # single quote
if (hot ~ q)
cooled = "[cannot be condensed]"
else if (hot ~ /^0s/)
cooled = "[keyid " substr(hot, 3, 9) "]"
else {
run = "echo " q hot q " | md5sum"
run | getline
close(run)
cooled = "[sums to " substr($1, 1, 4) "...]"
}
print cold cooled
next
}
{ print }' $*
+1
View File
@@ -0,0 +1 @@
_plutoload
+43
View File
@@ -0,0 +1,43 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_plutoload
PROGRAMDIR=${LIBDIR}
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.3 2002/08/02 16:01:19 mcr
# moved user visible programs to $PREFIX/libexec, while moving
# private files to $PREFIX/lib.
#
# Revision 1.2 2002/06/02 22:02:14 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+33
View File
@@ -0,0 +1,33 @@
.TH _PLUTOLOAD 8 "25 Apr 2002"
.\"
.\" RCSID $Id: _plutoload.8,v 1.1 2004/03/15 20:35:27 as Exp $
.\"
.SH NAME
ipsec _plutoload \- internal script to start pluto
.SH DESCRIPTION
.I _plutoload
is called by
.B _plutorun
to actually start the pluto executable.
.SH "SEE ALSO"
ipsec(8), ipsec_setup(8), ipsec__realsetup(8), ipsec__plutorun(8)
.SH HISTORY
Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
by Michael Richardson. Original program by Henry Spencer.
.\"
.\" $Log: _plutoload.8,v $
.\" Revision 1.1 2004/03/15 20:35:27 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.2 2002/04/29 22:39:31 mcr
.\" added basic man page for all internal commands.
.\"
.\" Revision 1.1 2002/04/26 01:21:43 mcr
.\" while tracking down a missing (not installed) /etc/ipsec.conf,
.\" MCR has decided that it is not okay for each program subdir to have
.\" some subset (determined with -f) of possible files.
.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
.\" Optional PROGRAM.5 files have been added to the makefiles.
.\"
.\"
.\"
+164
View File
@@ -0,0 +1,164 @@
#!/bin/sh
# Pluto database-loading script
# Copyright (C) 1998, 1999, 2001 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: _plutoload.in,v 1.2 2004/03/31 16:15:10 as Exp $
#
# exit status is 13 for protocol violation, that of Pluto otherwise
me='ipsec _plutoload' # for messages
for dummy
do
case "$1" in
--load) plutoload="$2" ; shift ;;
--start) plutostart="$2" ; shift ;;
--wait) plutowait="$2" ; shift ;;
--post) postpluto="$2" ; shift ;;
--) shift ; break ;;
-*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
*) break ;;
esac
shift
done
# load ca information
eval `ipsec _confread --varprefix PLUTO --type ca --search auto add start`
if test " $PLUTO_confreadstatus" != " "
then
echo "auto=add/start search: $PLUTO_confreadstatus"
echo "unable to determine what ca information to add -- adding none"
caload=
else
caload="$PLUTO_confreadnames"
fi
# searches, if needed
# the way the searches were done ensures plutoload >= plutoroute >= plutostart
# search for things to "ipsec auto --add": auto in "add" "route" "start"
eval `ipsec _confread --varprefix PLUTO --search auto add route start`
if test " $PLUTO_confreadstatus" != " "
then
echo "auto=add/route/start search: $PLUTO_confreadstatus"
echo "unable to determine what conns to add -- adding none"
plutoload=
else
plutoload="$PLUTO_confreadnames"
fi
# search for things to "ipsec auto --route": auto in "route" "start"
eval `ipsec _confread --varprefix PLUTO --search auto route start`
if test " $PLUTO_confreadstatus" != " "
then
echo "auto=route/start search: $PLUTO_confreadstatus"
echo "unable to determine what conns to route -- routing none"
plutoroute=
else
plutoroute="$PLUTO_confreadnames"
fi
# search for things to "ipsec auto --up": auto in "start"
eval `ipsec _confread --varprefix PLUTO --search auto start`
if test " $PLUTO_confreadstatus" != " "
then
echo "auto=start search: $PLUTO_confreadstatus"
echo "unable to determine what conns to start -- starting none"
plutostart=
else
plutostart="$PLUTO_confreadnames"
fi
# await Pluto's readiness (not likely to be an issue, but...)
eofed=y
while read saying
do
case "$saying" in
'Pluto initialized') eofed= ; break ;; # NOTE BREAK OUT
*) echo "pluto unexpectedly said \`$saying'" ;;
esac
done
if test "$eofed"
then
echo "pluto died unexpectedly!?!"
exit 13
fi
# ca database load
for tu in $caload
do
ipsec auto --type ca --add $tu ||
echo "...could not add ca \"$tu\""
done
# conn database load
for tu in $plutoload
do
ipsec auto --add $tu ||
echo "...could not add conn \"$tu\""
done
# enable listening
ipsec auto --ready
# execute any post-startup cleanup
if test " $postpluto" != " "
then
$postpluto
st=$?
if test " $st" -ne 0
then
echo "...postpluto command exited with status $st"
fi
fi
# quickly establish routing
for tu in $plutoroute
do
ipsec auto --route $tu ||
echo "...could not route conn \"$tu\""
done
# tunnel initiation, which may take a while
async=
if test " $plutowait" = " no"
then
async="--asynchronous"
fi
for tu in $plutostart
do
ipsec auto --up $async $tu ||
echo "...could not start conn \"$tu\""
done
# report any further utterances, and watch for exit status
eofed=y
while read saying
do
case "$saying" in
exit) eofed= ; break ;; # NOTE BREAK OUT
*) echo "pluto unexpectedly says \`$saying'" ;;
esac
done
if test "$eofed"
then
echo "pluto died without exit status!?!"
exit 13
fi
if read status
then
exit $status
else
echo "pluto yielded no exit status!?!"
exit 13
fi
+1
View File
@@ -0,0 +1 @@
_plutorun
+43
View File
@@ -0,0 +1,43 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_plutorun
PROGRAMDIR=${LIBDIR}
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.3 2002/08/02 16:01:26 mcr
# moved user visible programs to $PREFIX/libexec, while moving
# private files to $PREFIX/lib.
#
# Revision 1.2 2002/06/02 22:02:14 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+37
View File
@@ -0,0 +1,37 @@
.TH _PLUTORUN 8 "25 Apr 2002"
.\"
.\" RCSID $Id: _plutorun.8,v 1.1 2004/03/15 20:35:27 as Exp $
.\"
.SH NAME
ipsec _plutorun \- internal script to start pluto
.SH DESCRIPTION
.I _plutorun
is called by
.B _realsetup
to configure and bring up
.B ipsec_pluto(8).
It calls
.B _plutoload
to invoke pluto, and watches to makes sure that pluto is restarted if it fails.
.SH "SEE ALSO"
ipsec(8), ipsec_setup(8), ipsec__realsetup(8), ipsec__plutoload(8), ipsec_pluto(8).
.SH HISTORY
Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
by Michael Richardson. Original program written by Henry Spencer.
.\"
.\" $Log: _plutorun.8,v $
.\" Revision 1.1 2004/03/15 20:35:27 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.2 2002/04/29 22:39:31 mcr
.\" added basic man page for all internal commands.
.\"
.\" Revision 1.1 2002/04/26 01:21:43 mcr
.\" while tracking down a missing (not installed) /etc/ipsec.conf,
.\" MCR has decided that it is not okay for each program subdir to have
.\" some subset (determined with -f) of possible files.
.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
.\" Optional PROGRAM.5 files have been added to the makefiles.
.\"
.\"
.\"
+281
View File
@@ -0,0 +1,281 @@
#!/bin/sh
# Pluto control daemon
# Copyright (C) 1998, 1999, 2001 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: _plutorun.in,v 1.9 2005/10/16 13:28:15 as Exp $
me='ipsec _plutorun' # for messages
info=/var/run/ipsec.info
popts=
stderrlog=
plutorestartoncrash=true
wherelog=daemon.error
pidfile=/var/run/pluto.pid
verb="Starting"
for dummy
do
case "$1" in
--re) verb="Restarting" ;;
--plutorestartoncrash) plutorestartoncrash="$2"; shift ;;
--debug) plutodebug="$2" ; shift ;;
--uniqueids) uniqueids="$2" ; shift ;;
--nat_traversal) nat_traversal="$2" ; shift ;;
--keep_alive) keep_alive="$2" ; shift ;;
--force_keepalive) force_keepalive="$2" ; shift ;;
--disable_port_floating) disable_port_floating="$2" ; shift ;;
--virtual_private) virtual_private="$2" ; shift ;;
--nocrsend) nocrsend="$2" ; shift ;;
--strictcrlpolicy) strictcrlpolicy="$2" ; shift ;;
--crlcheckinterval) crlcheckinterval="$2"; shift ;;
--cachecrls) cachecrls="$2" ; shift ;;
--pkcs11module) pkcs11module="$2"; shift ;;
--pkcs11keepstate) pkcs11keepstate="$2"; shift ;;
--pkcs11proxy) pkcs11proxy="$2"; shift ;;
--dump) dumpdir="$2" ; shift ;;
--opts) popts="$2" ; shift ;;
--stderrlog) stderrlog="$2" ; shift ;;
--wait) plutowait="$2" ; shift ;;
--pre) prepluto="$2" ; shift ;;
--post) postpluto="$2" ; shift ;;
--log) wherelog="$2" ; shift ;;
--pid) pidfile="$2" ; shift ;;
--) shift ; break ;;
-*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
*) break ;;
esac
shift
done
# initially we are in the foreground, with parent looking after logging
# precautions
if test -f $pidfile
then
echo "pluto appears to be running already (\`$pidfile' exists), will not start another"
exit 1
fi
if test ! -e /dev/urandom
then
echo "cannot start Pluto, system lacks \`/dev/urandom'!?!"
exit 1
fi
# sort out options
for d in $plutodebug
do
popts="$popts --debug-$d"
done
case "$uniqueids" in
yes) popts="$popts --uniqueids" ;;
no|'') ;;
*) echo "unknown uniqueids value (not yes/no) \`$IPSECuniqueids'" ;;
esac
case "$nocrsend" in
yes) popts="$popts --nocrsend" ;;
no|'') ;;
*) echo "unknown nocrsend value (not yes/no) \`$IPSECnocrsend'" ;;
esac
case "$strictcrlpolicy" in
yes) popts="$popts --strictcrlpolicy" ;;
no|'') ;;
*) echo "unknown strictcrlpolicy value (not yes/no) \`$IPSECstrictcrlpolicy'" ;;
esac
case "$cachecrls" in
yes) popts="$popts --cachecrls" ;;
no|'') ;;
*) echo "unknown cachecrls value (not yes/no) \`$IPSECcachecrls'" ;;
esac
case "$nat_traversal" in
yes) popts="$popts --nat_traversal" ;;
no|'') ;;
*) echo "unknown nat_traversal value (not yes/no) \`$IPSECnat_traversal'" ;;
esac
[ -n "$keep_alive" ] && popts="$popts --keep_alive $keep_alive"
case "$force_keepalive" in
yes) popts="$popts --force_keepalive" ;;
no|'') ;;
*) echo "unknown force_keepalive value (not yes/no) \`$IPSECforce_keepalive'" ;;
esac
case "$disable_port_floating" in
yes) popts="$popts --disable_port_floating" ;;
no|'') ;;
*) echo "unknown disable_port_floating (not yes/no) \`$disable_port_floating'" ;;
esac
case "$pkcs11keepstate" in
yes) popts="$popts --pkcs11keepstate" ;;
no|'') ;;
*) echo "unknown pkcs11keepstate value (not yes/no) \`$IPSECpkcs11keepstate'" ;;
esac
case "$pkcs11proxy" in
yes) popts="$popts --pkcs11proxy" ;;
no|'') ;;
*) echo "unknown pkcs11proxy value (not yes/no) \`$IPSECpkcs11proxy'" ;;
esac
[ -n "$virtual_private" ] && popts="$popts --virtual_private $virtual_private"
# add crl check interval
if test ${crlcheckinterval:-0} -gt 0
then
popts="$popts --crlcheckinterval $crlcheckinterval"
fi
if test -n "$pkcs11module"
then
popts="$popts --pkcs11module $pkcs11module"
fi
if test -n "$stderrlog"
then
popts="$popts --stderrlog 2>>$stderrlog"
if test -f $stderrlog
then
if test ! -w $stderrlog
then
echo Cannot write to \"$stderrlog\".
exit 1
fi
else
if test ! -w "`dirname $stderrlog`"
then
echo Cannot write to directory to create \"$stderrlog\".
exit 1
fi
fi
echo "Plutorun started on "`date` >$stderrlog
fi
# set up dump directory
if test " $dumpdir" = " "
then
ulimit -c 0 # preclude core dumps
elif test ! -d "$dumpdir"
then
echo "dumpdir \`$dumpdir' does not exist, ignored"
ulimit -c 0 # preclude core dumps
elif cd $dumpdir # put them where desired
then
ulimit -c unlimited # permit them
else
echo "cannot cd to dumpdir \`$dumpdir', ignored"
ulimit -c 0 # preclude them
fi
# execute any preliminaries
if test " $prepluto" != " "
then
$prepluto
st=$?
if test " $st" -ne 0
then
echo "...prepluto command exited with status $st"
fi
fi
IPSEC_SECRETS=${IPSEC_CONFS}/ipsec.secrets
if test ! -f "${IPSEC_SECRETS}"
then
( logger -p authpriv.info -t ipsec__plutorun No file ${IPSEC_SECRETS}, generating key.
ipsec scepclient --out pkcs1 --out cert-self --quiet
echo -e "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n" > ${IPSEC_SECRETS}
chmod 600 ${IPSEC_SECRETS}
echo ": RSA myKey.der" >> ${IPSEC_SECRETS}
# tell pluto to go re-read the file
ipsec auto --rereadsecrets
) &
fi
#
# make sure that the isakmp port is open!
#
if test -f /etc/sysconfig/ipchains
then
if egrep -q 500:500 /etc/sysconfig/ipchains
then
:
else
ipchains -I input 1 -p udp -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 500:500 -j ACCEPT
# if it redhat, then save the rules again.
if [ -f /etc/redhat-release ]
then
sh /etc/rc.d/init.d/ipchains save
fi
fi
fi
# spin off into the background, with our own logging
echo "$verb Pluto subsystem..." | logger -p authpriv.error -t ipsec__plutorun
execdir=${IPSEC_EXECDIR-@IPSEC_EXECDIR@}
libdir=${IPSEC_LIBDIR-@IPSEC_LIBDIR@}
until (
if test -s $info
then
. $info
export defaultroutephys defaultroutevirt defaultrouteaddr defaultroutenexthop
fi
# eval allows $popts to contain redirection and other magic
eval $execdir/pluto --nofork --secretsfile "$IPSEC_SECRETS" --policygroupsdir "${IPSEC_CONFS}/ipsec.d/policies" $popts
status=$?
echo "exit"
echo $status
) | $libdir/_plutoload --wait "$plutowait" --post "$postpluto"
do
status=$?
case "$status" in
13) echo "internal failure in pluto scripts, impossible to carry on"
exit 1
;;
10) echo "pluto apparently already running (?!?), giving up"
exit 1
;;
137) echo "pluto killed by SIGKILL, terminating without restart or unlock"
exit 0
;;
143) echo "pluto killed by SIGTERM, terminating without restart"
# pluto now does its own unlock for this
exit 0
;;
*) st=$status
if $plutorestartoncrash
then
:
else
exit 0
fi
if test $st -gt 128
then
st="$st (signal `expr $st - 128`)"
fi
echo "!pluto failure!: exited with error status $st"
echo "restarting IPsec after pause..."
(
sleep 10
ipsec setup _autorestart
) </dev/null >/dev/null 2>&1 &
exit 1
###sleep 10
###rm -rf $pidfile
#### and go around the loop again
;;
esac
done </dev/null 2>&1 |
logger -s -p $wherelog -t ipsec__plutorun >/dev/null 2>/dev/null &
exit 0
+1
View File
@@ -0,0 +1 @@
_realsetup
+43
View File
@@ -0,0 +1,43 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_realsetup
PROGRAMDIR=${LIBDIR}
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.3 2002/08/02 16:01:34 mcr
# moved user visible programs to $PREFIX/libexec, while moving
# private files to $PREFIX/lib.
#
# Revision 1.2 2002/06/02 22:02:14 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+36
View File
@@ -0,0 +1,36 @@
.TH _REALSETUP 8 "25 Apr 2002"
.\"
.\" RCSID $Id: _realsetup.8,v 1.1 2004/03/15 20:35:27 as Exp $
.\"
.SH NAME
ipsec _realsetup \- internal routine to start FreeS/WAN.
.SH DESCRIPTION
.I _realsetup
is called by the system init scripts to start the FreeS/WAN
system. It starts
.B KLIPS
(the kernel component) and
.B pluto
(the userspace keying component).
.SH "SEE ALSO"
ipsec(8), ipsec__klipsstart(8), ipsec__plutorun(8).
.SH HISTORY
Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
by Michael Richardson. Original program by Henry Spencer.
.\"
.\" $Log: _realsetup.8,v $
.\" Revision 1.1 2004/03/15 20:35:27 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.2 2002/04/29 22:39:31 mcr
.\" added basic man page for all internal commands.
.\"
.\" Revision 1.1 2002/04/26 01:21:43 mcr
.\" while tracking down a missing (not installed) /etc/ipsec.conf,
.\" MCR has decided that it is not okay for each program subdir to have
.\" some subset (determined with -f) of possible files.
.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
.\" Optional PROGRAM.5 files have been added to the makefiles.
.\"
.\"
.\"
+456
View File
@@ -0,0 +1,456 @@
#!/bin/sh
# IPsec startup and shutdown command
# Copyright (C) 1998, 1999, 2001 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: _realsetup.in,v 1.10 2005/09/25 21:30:52 as Exp $
IPSEC_NAME=strongSwan
me='ipsec setup' # for messages
# Misc. paths (some of this should perhaps be overrideable from ipsec.conf).
plutopid=/var/run/pluto.pid
subsyslock=/var/lock/subsys/ipsec
lock=/var/run/ipsec_setup.pid
info=/var/run/ipsec.info
sysflags=/proc/sys/net/ipsec
modules=/proc/modules
ipforward=/proc/sys/net/ipv4/ip_forward
ipsecversion=/proc/net/ipsec_version
kamepfkey=/proc/net/pfkey
# make sure output of (e.g.) ifconfig is in English
unset LANG LANGUAGE LC_ALL LC_MESSAGES
# check we were called properly
if test " $IPSEC_confreadsection" != " setup"
then
echo "$me: $0 must be called by ipsec_setup" >&2
exit 1
fi
# defaults for "config setup" items
IPSECinterfaces=${IPSECinterfaces:-%defaultroute}
if test " $IPSECinterfaces" = " %none" ; then IPSECinterfaces= ; fi
# IPSECforwardcontrol "no"
# IPSECsyslog "daemon.error"
# IPSECklipsdebug "none"
# IPSECplutodebug "none"
# IPSECdumpdir "" (no dump)
# IPSECmanualstart ""
# IPSECpluto "yes"
IPSECplutowait=${IPSECplutowait:-no}
# IPSECprepluto ""
# IPSECpostpluto ""
# IPSECfragicmp "yes"
# IPSEChidetos "yes"
IPSECrp_filter=${IPSECrp_filter:-0}
IPSECuniqueids=${IPSECuniqueids:-yes}
IPSECcrlcheckinterval=${IPSECcrlcheckinterval:-0}
# IPSECpkcs11module ""
# IPSECoverridemtu ""
# Shall we trace?
execute="true"
display="false"
for i in $IPSEC_setupflags
do
case "$i" in
"--showonly") execute="false" ; display=true ;;
"--show") display=true ;;
esac
done
if $display
then
echo " " PATH="$PATH"
fi
perform() {
if $display
then
echo " " "$*"
fi
if $execute
then
eval "$*"
fi
}
# function to set up manually-keyed connections
manualconns() {
if test " $IPSECmanualstart" != " "
then
for tu in $IPSECmanualstart
do
perform ipsec manual --up $tu
done
fi
# search for things to "ipsec manual --up": auto == "manual"
eval `ipsec _confread --varprefix MANUALSTART --search auto manual`
if test " $MANUALSTART_confreadstatus" != " "
then
echo "auto=manual search: $MANUALSTART_confreadstatus"
echo "unable to determine what conns to manual --up; none done"
elif test " $MANUALSTART_confreadnames" != " "
then
for tu in $MANUALSTART_confreadnames
do
perform ipsec manual --up $tu
done
fi
}
# for no-stdout logging:
LOGONLY="logger -p $IPSECsyslog -t ipsec_setup"
# What an ugly string.
# Must be a string, not a function, because it is nested
# within another sequence (for plutorun).
# Luckily there are NO substitutions in it.
KILLKLIPS='ifl=` ifconfig | sed -n -e "/^ipsec/s/ .*//p" ` ;
test "X$ifl" != "X" &&
for i in $ifl ;
do
ifconfig $i down ;
ipsec tncfg --detach --virtual $i ;
done ;
test -r /proc/net/ipsec_klipsdebug && ipsec klipsdebug --none ;
ipsec eroute --clear ;
ipsec spi --clear ;
for alg in aes serpent twofish blowfish sha2 ;
do
lsmod 2>&1 | grep "^ipsec_$alg" > /dev/null && rmmod ipsec_$alg ;
done ;
lsmod 2>&1 | grep "^ipsec" > /dev/null && rmmod ipsec'
if test -f $kamepfkey
then
KILLKLIPS='
if ip xfrm state > /dev/null 2>&1 ;
then
ip xfrm state flush ;
ip xfrm policy flush ;
elif type setkey > /dev/null 2>&1 ;
then
setkey -F ;
setkey -FP ;
fi'
fi
# do it
case "$1" in
start|--start|_autostart)
# First, does it seem to be going already?
perform test ! -f $lock "||" "{" \
echo "\"$IPSEC_NAME IPsec apparently already running, start aborted\"" ";" \
exit 1 ";" \
"}"
# announcement
# (Warning, changes to this log message may affect barf.)
version="`ipsec --version | awk 'NR == 1 { print $(3) }' | sed -e 's/^U\(.*\)\/K(.*/\1/'`"
case "$1" in
start|--start) perform echo "\"Starting $IPSEC_NAME IPsec $version...\"" ;;
_autostart) perform echo "\"Restarting $IPSEC_NAME IPsec $version...\"" ;;
esac
# preliminaries
perform rm -f $lock
for f in /dev/random /dev/urandom
do
perform test -r $f "||" "{" \
echo "\"...unable to start $IPSEC_NAME IPsec, no $f!\"" ";" \
exit 1 ";" \
"}"
done
# the meaning of $$ at a different runtime is questionable!
perform echo '$$' ">" $lock
perform test -s $lock "||" "{" \
echo "\"...unable to create $lock, aborting start!\"" ";" \
rm -f $lock ";" \
exit 1 ";" \
"}"
perform ">" $info
# here we go
perform ipsec _startklips \
--info $info \
--debug "\"$IPSECklipsdebug\"" \
--omtu "\"$IPSECoverridemtu\"" \
--fragicmp "\"$IPSECfragicmp\"" \
--hidetos "\"$IPSEChidetos\"" \
--rpfilter "\"$IPSECrp_filter\"" \
--log "\"$IPSECsyslog\"" \
$IPSECinterfaces "||" \
"{" rm -f $lock ";" exit 1 ";" "}"
perform test -f $ipsecversion "||" \
test -f $kamepfkey "||" "{" \
echo "\"OOPS, should have aborted! Broken shell!\"" ";" \
exit 1 ";" \
"}"
# misc pre-Pluto setup
perform test -d `dirname $subsyslock` "&&" touch $subsyslock
if test " $IPSECforwardcontrol" = " yes"
then
perform grep '"^0"' $ipforward ">" /dev/null "&&" "{" \
echo "\"enabling IP forwarding:\"" "|" $LOGONLY ";" \
echo "\"ipforwardingwas=$fw\"" ">>" $info ";" \
echo 1 ">" $ipforward ";" \
"}"
fi
manualconns
plutorestartoncrash=""
case "$IPSECplutorestartoncrash" in
true|[yY]|yes|restart) plutorestartoncrash="--plutorestartoncrash true";;
false|[nN]|no|die) plutorestartoncrash="--plutorestartoncrash false" ;;
esac
# Pluto
case "$1" in
start|--start) re= ;;
_autostart) re=--re ;;
esac
if test " $IPSECpluto" != " no"
then
perform ipsec _plutorun $re \
--debug "\"$IPSECplutodebug\"" \
--uniqueids "\"$IPSECuniqueids\"" \
--nocrsend "\"$IPSECnocrsend\"" \
--strictcrlpolicy "\"$IPSECstrictcrlpolicy\"" \
--cachecrls "\"$IPSECcachecrls\"" \
--nat_traversal "\"$IPSECnat_traversal\"" \
--keep_alive "\"$IPSECkeep_alive\"" \
--force_keepalive "\"$IPSECforce_keepalive\"" \
--disable_port_floating "\"$IPSECdisable_port_floating\"" \
--virtual_private "\"$IPSECvirtual_private\"" \
--crlcheckinterval "\"$IPSECcrlcheckinterval\"" \
--pkcs11module "\"$IPSECpkcs11module\"" \
--pkcs11keepstate "\"$IPSECpkcs11keepstate\"" \
--pkcs11proxy "\"$IPSECpkcs11proxy\"" \
--dump "\"$IPSECdumpdir\"" \
--opts "\"$IPSECplutoopts\"" \
--stderrlog "\"$IPSECplutostderrlog\"" \
--wait "\"$IPSECplutowait\"" \
--pre "\"$IPSECprepluto\"" \
--post "\"$IPSECpostpluto\"" \
--log "\"$IPSECsyslog\"" $plutorestartoncrash \
--pid "\"$plutopid\"" "||" "{" \
$KILLKLIPS ";" \
rm -f $lock ";" \
exit 1 ";" \
"}"
fi
# done!
perform echo "\"...$IPSEC_NAME IPsec started\"" "|" $LOGONLY
;;
stop|--stop|_autostop) # _autostop is same as stop
# Shut things down.
perform echo "\"Stopping $IPSEC_NAME IPsec...\""
perform \
if test -r $lock ";" \
then \
status=0 ";" \
. $info ";" \
else \
echo "\"stop ordered, but IPsec does not appear to be running!\"" ";" \
echo "\"doing cleanup anyway...\"" ";" \
status=1 ";" \
fi
if test " $IPSECforwardcontrol" = " yes"
then
perform test "\"X\$ipforwardingwas\"" = "\"X0\"" "&&" "{" \
echo "\"disabling IP forwarding:\"" "|" $LOGONLY ";" \
echo 0 ">" $ipforward ";" \
"}"
fi
perform test -f $plutopid "&&" "{" \
if ps -p '`' cat $plutopid '`' ">" /dev/null ";" \
then \
ipsec whack --shutdown "|" grep -v "^002" ";" \
sleep 1 ";" \
if test -s $plutopid ";" \
then \
echo "\"Attempt to shut Pluto down failed! Trying kill:\"" ";" \
kill '`' cat $plutopid '`' ";" \
sleep 5 ";" \
fi ";" \
else \
echo "\"Removing orphaned $plutopid:\"" ";" \
fi ";" \
rm -f $plutopid ";" \
"}"
perform $KILLKLIPS
perform test -d `dirname $subsyslock` "&&" rm -f $subsyslock
perform rm -f $info $lock
perform echo "...$IPSEC_NAME IPsec stopped" "|" $LOGONLY
perform exit \$status
;;
status|--status)
if test " $IPSEC_setupflags" != " "
then
echo "$me $1 does not support $IPSEC_setupflags"
exit 1
fi
if test -f $info
then
hasinfo=yes
fi
if test -f $lock
then
haslock=yes
fi
if test -f $subsyslock
then
hassublock=yes
fi
if test -s $plutopid
then
if ps -p `cat $plutopid` >/dev/null
then
plutokind=normal
elif ps -C pluto >/dev/null
then
plutokind=illicit
fi
elif ps -C pluto >/dev/null
then
plutokind=orphaned
else
plutokind=no
fi
if test -r /proc/net/ipsec_eroute
then
if test " `wc -l </proc/net/ipsec_eroute`" -gt 0
then
eroutes=yes
fi
fi
if test -r $ipsecversion
then
klips=yes
elif test -r $modules
then
klips=maybe
else
klips=none
fi
if test "$haslock"
then
echo "IPsec running"
# might not be a subsystem lock dir, ignore that issue
if test "$plutokind" = "normal" -a "$klips" = "yes" -a "$hasinfo"
then
echo "pluto pid `cat $plutopid`"
exit 0
fi
echo "but..."
if test "$plutokind" != "normal"
then
echo "$plutokind Pluto running!"
fi
if test ! "$hasinfo"
then
echo "$info file missing!"
fi
case $klips in
maybe) echo "KLIPS module is not loaded!" ;;
none) echo "no KLIPS in kernel!" ;;
esac
if test "$eroutes"
then
echo "some eroutes exist"
fi
exit 1
else
echo "IPsec stopped"
if test ! "$hassublock" -a ! "$hasinfo" -a "$plutokind" = "no" \
-a ! "$eroutes"
then
exit 0
fi
echo "but..."
if test "$hassublock"
then
echo "has subsystem lock ($subsyslock)!"
fi
if test "$hasinfo"
then
echo "has $info file!"
fi
if test "$plutokind" != "normal"
then
echo "$plutokind Pluto is running!"
fi
if test "$eroutes"
then
echo "some eroutes exist!"
fi
exit 1
fi
;;
--version)
if test " $IPSEC_setupflags" != " "
then
echo "$me $1 does not support $IPSEC_setupflags"
exit 1
fi
echo "$me $IPSEC_VERSION"
exit 0
;;
--help)
if test " $IPSEC_setupflags" != " "
then
echo "$me $1 does not support $IPSEC_setupflags"
exit 1
fi
echo "Usage: $me {--start|--stop|--restart|--status}"
exit 0
;;
*)
echo "Usage: $me {--start|--stop|--restart|--status}" >&2
exit 2
esac
exit 0
+1
View File
@@ -0,0 +1 @@
_secretcensor
+43
View File
@@ -0,0 +1,43 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_secretcensor
PROGRAMDIR=${LIBDIR}
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.3 2002/08/02 16:01:38 mcr
# moved user visible programs to $PREFIX/libexec, while moving
# private files to $PREFIX/lib.
#
# Revision 1.2 2002/06/02 22:02:14 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+34
View File
@@ -0,0 +1,34 @@
.TH _SECRETCENSOR 8 "25 Apr 2002"
.\"
.\" RCSID $Id: _secretcensor.8,v 1.1 2004/03/15 20:35:27 as Exp $
.\"
.SH NAME
ipsec _secretcensor \- internal routing to sanitize files
.SH DESCRIPTION
.I _secretcensor
is called by
.B ipsec barf
to process the /etc/ipsec.secrets file to remove the private key components
from the file prior to revealing the contents.
.SH "SEE ALSO"
ipsec(8), ipsec_barf(8).
.SH HISTORY
Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
by Michael Richardson. Original program by Henry Spencer.
.\"
.\" $Log: _secretcensor.8,v $
.\" Revision 1.1 2004/03/15 20:35:27 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.2 2002/04/29 22:39:31 mcr
.\" added basic man page for all internal commands.
.\"
.\" Revision 1.1 2002/04/26 01:21:43 mcr
.\" while tracking down a missing (not installed) /etc/ipsec.conf,
.\" MCR has decided that it is not okay for each program subdir to have
.\" some subset (determined with -f) of possible files.
.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
.\" Optional PROGRAM.5 files have been added to the makefiles.
.\"
.\"
.\"
+75
View File
@@ -0,0 +1,75 @@
#! /bin/sh
# implements secret censoring for barf
# Copyright (C) 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: _secretcensor.in,v 1.1 2004/03/15 20:35:27 as Exp $
usage="Usage: $0 [file ...]"
me="ipsec _secretcensor"
for dummy
do
case "$1" in
--help) echo "$usage" ; exit 0 ;;
--version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
--) shift ; break ;;
-*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
*) break ;;
esac
shift
done
awk ' function cool(hot, q, cooled, run) {
# warning: may destroy input line!
q = "'"'"'" # single quote
if (hot ~ q)
return "[cannot be summed]"
if (hot ~ /^0s/)
return "[keyid " substr(hot, 3, 9) "]"
run = "echo " q hot q " | md5sum"
run | getline
close(run)
return "[sums to " substr($1, 1, 4) "...]"
}
/"/ {
i = match($0, /"[^"]+"/)
cold1 = substr($0, 1, i)
cold2 = substr($0, i+RLENGTH-1)
hot = substr($0, i+1, RLENGTH-2)
print cold1 cool(hot) cold2
next
}
/#pubkey=/ {
i = match($0, /^.*#pubkey=/)
i += RLENGTH-1
cold = substr($0, 1, i)
hot = substr($0, i+1)
print cold cool(hot)
next
}
/#IN KEY / {
i = match($0, /^.*[ \t][^ \t]/)
i += RLENGTH-2
cold = substr($0, 1, i)
hot = substr($0, i+1)
print cold cool("0s" hot)
next
}
/^[ \t]+(Modulus|P[a-z]+Exponent|Prime[12]|Exponent[12]|Coefficient):/ {
i = match($0, /^[^:]*:[ \t]*/)
i += RLENGTH-1
cold = substr($0, 1, i)
print cold "[...]"
next
}
{ print }' $*
+1
View File
@@ -0,0 +1 @@
_startklips
+43
View File
@@ -0,0 +1,43 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_startklips
PROGRAMDIR=${LIBDIR}
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.3 2002/08/02 16:01:42 mcr
# moved user visible programs to $PREFIX/libexec, while moving
# private files to $PREFIX/lib.
#
# Revision 1.2 2002/06/02 22:02:14 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+33
View File
@@ -0,0 +1,33 @@
.TH _STARTKLIPS 8 "25 Apr 2002"
.\"
.\" RCSID $Id: _startklips.8,v 1.1 2004/03/15 20:35:27 as Exp $
.\"
.SH NAME
ipsec _startklips \- internal script to bring up kernel components
.SH DESCRIPTION
.I _startklips
brings up the FreeS/WAN kernel component. This involves loading any
required modules, attaching and configuring the ipsecX pseudo-devices and
attaching the pseudo-devices to the physical devices.
.SH "SEE ALSO"
ipsec(8), ipsec_tncfg(8).
.SH HISTORY
Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
by Michael Richardson. Original program by Henry Spencer.
.\"
.\" $Log: _startklips.8,v $
.\" Revision 1.1 2004/03/15 20:35:27 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.2 2002/04/29 22:39:31 mcr
.\" added basic man page for all internal commands.
.\"
.\" Revision 1.1 2002/04/26 01:21:43 mcr
.\" while tracking down a missing (not installed) /etc/ipsec.conf,
.\" MCR has decided that it is not okay for each program subdir to have
.\" some subset (determined with -f) of possible files.
.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
.\" Optional PROGRAM.5 files have been added to the makefiles.
.\"
.\"
.\"
+367
View File
@@ -0,0 +1,367 @@
#!/bin/sh
# KLIPS startup script
# Copyright (C) 1998, 1999, 2001, 2002 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: _startklips.in,v 1.6 2005/05/06 22:11:33 as Exp $
me='ipsec _startklips' # for messages
# KLIPS-related paths
sysflags=/proc/sys/net/ipsec
modules=/proc/modules
# full rp_filter path is $rpfilter1/interface/$rpfilter2
rpfilter1=/proc/sys/net/ipv4/conf
rpfilter2=rp_filter
# %unchanged or setting (0, 1, or 2)
rpfiltercontrol=0
ipsecversion=/proc/net/ipsec_version
moduleplace=/lib/modules/`uname -r`/kernel/net/ipsec
bareversion=`uname -r | sed -e 's/^\(2\.[0-9]\.[1-9][0-9]*-[1-9][0-9]*\(\.[0-9][0-9]*\)*\(\.x\)*\).*$/\1/'`
moduleinstplace=/lib/modules/$bareversion/kernel/net/ipsec
modulename=ipsec.o
klips=true
netkey=/proc/net/pfkey
info=/dev/null
log=daemon.error
for dummy
do
case "$1" in
--log) log="$2" ; shift ;;
--info) info="$2" ; shift ;;
--debug) debug="$2" ; shift ;;
--omtu) omtu="$2" ; shift ;;
--fragicmp) fragicmp="$2" ; shift ;;
--hidetos) hidetos="$2" ; shift ;;
--rpfilter) rpfiltercontrol="$2" ; shift ;;
--) shift ; break ;;
-*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
*) break ;;
esac
shift
done
# some shell functions, to clarify the actual code
# set up a system flag based on a variable
# sysflag value shortname default flagname
sysflag() {
case "$1" in
'') v="$3" ;;
*) v="$1" ;;
esac
if test ! -f $sysflags/$4
then
if test " $v" != " $3"
then
echo "cannot do $2=$v, $sysflags/$4 does not exist"
exit 1
else
return # can't set, but it's the default anyway
fi
fi
case "$v" in
yes|no) ;;
*) echo "unknown (not yes/no) $2 value \`$1'"
exit 1
;;
esac
case "$v" in
yes) echo 1 >$sysflags/$4 ;;
no) echo 0 >$sysflags/$4 ;;
esac
}
# set up a Klips interface
klipsinterface() {
# pull apart the interface spec
virt=`expr $1 : '\([^=]*\)=.*'`
phys=`expr $1 : '[^=]*=\(.*\)'`
case "$virt" in
ipsec[0-9]) ;;
*) echo "invalid interface \`$virt' in \`$1'" ; exit 1 ;;
esac
# figure out ifconfig for interface
addr=
eval `ifconfig $phys |
awk '$1 == "inet" && $2 ~ /^addr:/ && $NF ~ /^Mask:/ {
gsub(/:/, " ", $0)
print "addr=" $3
other = $5
if ($4 == "Bcast")
print "type=broadcast"
else if ($4 == "P-t-P")
print "type=pointopoint"
else if (NF == 5) {
print "type="
other = ""
} else
print "type=unknown"
print "otheraddr=" other
print "mask=" $NF
}'`
if test " $addr" = " "
then
echo "unable to determine address of \`$phys'"
exit 1
fi
if test " $type" = " unknown"
then
echo "\`$phys' is of an unknown type"
exit 1
fi
if test " $omtu" != " "
then
mtu="mtu $omtu"
else
mtu=
fi
echo "KLIPS $virt on $phys $addr/$mask $type $otheraddr $mtu" | logonly
if $klips
then
# attach the interface and bring it up
ipsec tncfg --attach --virtual $virt --physical $phys
ifconfig $virt inet $addr $type $otheraddr netmask $mask $mtu
fi
# if %defaultroute, note the facts
if test " $2" != " "
then
(
echo "defaultroutephys=$phys"
echo "defaultroutevirt=$virt"
echo "defaultrouteaddr=$addr"
if test " $2" != " 0.0.0.0"
then
echo "defaultroutenexthop=$2"
fi
) >>$info
else
echo '#dr: no default route' >>$info
fi
# check for rp_filter trouble
checkif $phys # thought to be a problem only on phys
}
# check an interface for problems
checkif() {
$klips || return 0
rpf=$rpfilter1/$1/$rpfilter2
if test -f $rpf
then
r="`cat $rpf`"
if test " $r" != " 0"
then
case "$r-$rpfiltercontrol" in
0-%unchanged|0-0|1-1|2-2)
# happy state
;;
*-%unchanged)
echo "WARNING: $1 has route filtering turned on; KLIPS may not work ($rpf is $r)"
;;
[012]-[012])
echo "WARNING: changing route filtering on $1 (changing $rpf from $r to $rpfiltercontrol)"
echo "$rpfiltercontrol" >$rpf
;;
[012]-*)
echo "ERROR: unknown rpfilter setting: $rpfiltercontrol"
;;
*)
echo "ERROR: unknown $rpf value $r"
;;
esac
fi
fi
}
# interfaces=%defaultroute: put ipsec0 on top of default route's interface
defaultinterface() {
phys=`netstat -nr |
awk '$1 == "0.0.0.0" && $3 == "0.0.0.0" { print $NF }'`
if test " $phys" = " "
then
echo "no default route, %defaultroute cannot cope!!!"
exit 1
fi
if test `echo " $phys" | wc -l` -gt 1
then
echo "multiple default routes, %defaultroute cannot cope!!!"
exit 1
fi
next=`netstat -nr |
awk '$1 == "0.0.0.0" && $3 == "0.0.0.0" { print $2 }'`
klipsinterface "ipsec0=$phys" $next
}
# log only to syslog, not to stdout/stderr
logonly() {
logger -p $log -t ipsec_setup
}
# sort out which module is appropriate, changing it if necessary
setmodule() {
wantgoo="`ipsec calcgoo /proc/ksyms`"
module=$moduleplace/$modulename
if test -f $module
then
goo="`nm -ao $module | ipsec calcgoo`"
if test " $wantgoo" = " $goo"
then
return # looks right
fi
fi
if test -f $moduleinstplace/$wantgoo
then
echo "insmod failed, but found matching template module $wantgoo."
echo "Copying $moduleinstplace/$wantgoo to $module."
rm -f $module
mkdir -p $moduleplace
cp -p $moduleinstplace/$wantgoo $module
# "depmod -a" gets done by caller
fi
}
# main line
# load module if possible
if test ! -f $ipsecversion && test ! -f $netkey
then
# statically compiled KLIPS not found; try to load the module
insmod ipsec
fi
if test ! -f $ipsecversion && test ! -f $netkey
then
modprobe -v af_key
fi
if test -f $netkey
then
klips=false
if test -f $modules
then
modprobe -qv ah4
modprobe -qv esp4
modprobe -qv ipcomp
modprobe -qv xfrm4_tunnel
modprobe -qv xfrm_user
fi
fi
if test ! -f $ipsecversion && $klips
then
if test -r $modules # kernel does have modules
then
setmodule
unset MODPATH MODULECONF # no user overrides!
depmod -a >/dev/null 2>&1
modprobe -v ipsec
fi
if test ! -f $ipsecversion
then
echo "kernel appears to lack KLIPS"
exit 1
fi
fi
# load all compiled algo modules
if $klips
then
for alg in aes serpent twofish blowfish sha2
do
if test -f $moduleinstplace/alg/ipsec_$alg.o
then
modprobe ipsec_$alg
fi
done
fi
# figure out debugging flags
case "$debug" in
'') debug=none ;;
esac
if test -r /proc/net/ipsec_klipsdebug
then
echo "KLIPS debug \`$debug'" | logonly
case "$debug" in
none) ipsec klipsdebug --none ;;
all) ipsec klipsdebug --all ;;
*) ipsec klipsdebug --none
for d in $debug
do
ipsec klipsdebug --set $d
done
;;
esac
elif $klips
then
if test " $debug" != " none"
then
echo "klipsdebug=\`$debug' ignored, KLIPS lacks debug facilities"
fi
fi
# figure out misc. kernel config
if test -d $sysflags
then
sysflag "$fragicmp" "fragicmp" yes icmp
echo 1 >$sysflags/inbound_policy_check # no debate
sysflag no "no_eroute_pass" no no_eroute_pass # obsolete parm
sysflag no "opportunistic" no opportunistic # obsolete parm
sysflag "$hidetos" "hidetos" yes tos
elif $klips
then
echo "WARNING: cannot adjust KLIPS flags, no $sysflags directory!"
# carry on
fi
if $klips; then
# clear tables out in case dregs have been left over
ipsec eroute --clear
ipsec spi --clear
elif test $netkey
then
if ip xfrm state > /dev/null 2>&1
then
ip xfrm state flush
ip xfrm policy flush
elif type setkey > /dev/null 2>&1
then
setkey -F
setkey -FP
else
echo "WARNING: cannot flush state/policy database -- \`$1'" |
logger -s -p $log -t ipsec_setup
fi
fi
# figure out interfaces
for i
do
case "$i" in
ipsec*=?*) klipsinterface "$i" ;;
%defaultroute) defaultinterface ;;
*) echo "interface \`$i' not understood"
exit 1
;;
esac
done
exit 0
+2
View File
@@ -0,0 +1,2 @@
_updown
_updown.in
+22
View File
@@ -0,0 +1,22 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.3 2006/04/17 06:48:49 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_updown
PROGRAMDIR=${LIBDIR}
include ../Makefile.program
+19
View File
@@ -0,0 +1,19 @@
.TH _UPDOWN 8 "27 Apr 2006"
.\"
.\" RCSID $Id: _updown.8,v 1.2 2006/04/17 06:48:49 as Exp $
.\"
.SH NAME
ipsec _updown \- route and firewall manipulation script
.SH SYNOPSIS
.I _updown
is invoked by pluto when it has brought up a new connection. This script
is used to insert the appropriate routing entries for IPsec operation.
It can also be used to insert and delete dynamic iptables firewall rules.
The interface to the script is documented in the pluto man page.
.SH "SEE ALSO"
ipsec(8), ipsec_pluto(8).
.SH HISTORY
Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
by Michael Richardson. Original program written by Henry Spencer. Extended
for the Linux strongSwan project <http://www.strongswan.org/> by Andreas
Steffen.
+503
View File
@@ -0,0 +1,503 @@
#! /bin/sh
# iproute2 version, default updown script
#
# Copyright (C) 2003-2004 Nigel Meteringham
# Copyright (C) 2003-2004 Tuomo Soini
# Copyright (C) 2002-2004 Michael Richardson
# Copyright (C) 2005-2006 Andreas Steffen <[email protected]>
#
# 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: _updown.in,v 1.2 2006/04/17 15:06:29 as Exp $
# CAUTION: Installing a new version of strongSwan will install a new
# copy of this script, wiping out any custom changes you make. If
# you need changes, make a copy of this under another name, and customize
# that, and use the (left/right)updown parameters in ipsec.conf to make
# strongSwan use yours instead of this default one.
# things that this script gets (from ipsec_pluto(8) man page)
#
# PLUTO_VERSION
# indicates what version of this interface is being
# used. This document describes version 1.1. This
# is upwardly compatible with version 1.0.
#
# PLUTO_VERB
# specifies the name of the operation to be performed
# (prepare-host, prepare-client, up-host, up-client,
# down-host, or down-client). If the address family
# for security gateway to security gateway communica­
# tions is IPv6, then a suffix of -v6 is added to the
# verb.
#
# PLUTO_CONNECTION
# is the name of the connection for which we are
# routing.
#
# PLUTO_NEXT_HOP
# is the next hop to which packets bound for the peer
# must be sent.
#
# PLUTO_INTERFACE
# is the name of the ipsec interface to be used.
#
# PLUTO_REQID
# is the requid of the ESP policy
#
# PLUTO_ME
# is the IP address of our host.
#
# PLUTO_MY_ID
# is the ID of our host.
#
# PLUTO_MY_CLIENT
# is the IP address / count of our client subnet. If
# the client is just the host, this will be the
# host's own IP address / max (where max is 32 for
# IPv4 and 128 for IPv6).
#
# PLUTO_MY_CLIENT_NET
# is the IP address of our client net. If the client
# is just the host, this will be the host's own IP
# address.
#
# PLUTO_MY_CLIENT_MASK
# is the mask for our client net. If the client is
# just the host, this will be 255.255.255.255.
#
# PLUTO_MY_SOURCEIP
# if non-empty, then the source address for the route will be
# set to this IP address.
#
# PLUTO_MY_PROTOCOL
# is the IP protocol that will be transported.
#
# PLUTO_MY_PORT
# is the UDP/TCP port to which the IPsec SA is
# restricted on our side.
#
# PLUTO_PEER
# is the IP address of our peer.
#
# PLUTO_PEER_ID
# is the ID of our peer.
#
# PLUTO_PEER_CA
# is the CA which issued the cert of our peer.
#
# PLUTO_PEER_CLIENT
# is the IP address / count of the peer's client sub­
# net. If the client is just the peer, this will be
# the peer's own IP address / max (where max is 32
# for IPv4 and 128 for IPv6).
#
# PLUTO_PEER_CLIENT_NET
# is the IP address of the peer's client net. If the
# client is just the peer, this will be the peer's
# own IP address.
#
# PLUTO_PEER_CLIENT_MASK
# is the mask for the peer's client net. If the
# client is just the peer, this will be
# 255.255.255.255.
#
# PLUTO_PEER_PROTOCOL
# is the IP protocol that will be transported.
#
# PLUTO_PEER_PORT
# is the UDP/TCP port to which the IPsec SA is
# restricted on the peer side.
#
# uncomment to log VPN connections
VPN_LOGGING=1
#
# tag put in front of each log entry:
TAG=vpn
#
# syslog facility and priority used:
FAC_PRIO=local0.notice
#
# to create a special vpn logging file, put the following line into
# the syslog configuration file /etc/syslog.conf:
#
# local0.notice -/var/log/vpn
#
# check interface version
case "$PLUTO_VERSION" in
1.[0|1]) # Older Pluto?!? Play it safe, script may be using new features.
echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
echo "$0: called by obsolete Pluto?" >&2
exit 2
;;
1.*) ;;
*) echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2
exit 2
;;
esac
# check parameter(s)
case "$1:$*" in
':') # no parameters
;;
iptables:iptables) # due to (left/right)firewall; for default script only
;;
custom:*) # custom parameters (see above CAUTION comment)
;;
*) echo "$0: unknown parameters \`$*'" >&2
exit 2
;;
esac
# utility functions for route manipulation
# Meddling with this stuff should not be necessary and requires great care.
uproute() {
doroute add
ip route flush cache
}
downroute() {
doroute delete
ip route flush cache
}
addsource() {
st=0
if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
then
it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
oops="`eval $it 2>&1`"
st=$?
if test " $oops" = " " -a " $st" != " 0"
then
oops="silent error, exit status $st"
fi
if test " $oops" != " " -o " $st" != " 0"
then
echo "$0: addsource \`$it' failed ($oops)" >&2
fi
fi
return $st
}
doroute() {
st=0
parms="$PLUTO_PEER_CLIENT"
parms2=
if [ -n "$PLUTO_NEXT_HOP" ]
then
parms2="via $PLUTO_NEXT_HOP"
fi
parms2="$parms2 dev $PLUTO_INTERFACE"
if [ -z "$PLUTO_MY_SOURCEIP" ]
then
if [ -f /etc/sysconfig/defaultsource ]
then
. /etc/sysconfig/defaultsource
fi
if [ -f /etc/conf.d/defaultsource ]
then
. /etc/conf.d/defaultsource
fi
if [ -n "$DEFAULTSOURCE" ]
then
PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
fi
fi
parms3=
if test "$1" = "add" -a -n "$PLUTO_MY_SOURCEIP"
then
addsource
parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*}"
fi
case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
"0.0.0.0/0.0.0.0")
# opportunistic encryption work around
# need to provide route that eclipses default, without
# replacing it.
it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
ip route $1 128.0.0.0/1 $parms2 $parms3"
;;
*) it="ip route $1 $parms $parms2 $parms3"
;;
esac
oops="`eval $it 2>&1`"
st=$?
if test " $oops" = " " -a " $st" != " 0"
then
oops="silent error, exit status $st"
fi
if test " $oops" != " " -o " $st" != " 0"
then
echo "$0: doroute \`$it' failed ($oops)" >&2
fi
return $st
}
# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
then
IPSEC_POLICY_IN=""
IPSEC_POLICY_OUT=""
else
IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
fi
# are there port numbers?
if [ "$PLUTO_MY_PORT" != 0 ]
then
S_MY_PORT="--sport $PLUTO_MY_PORT"
D_MY_PORT="--dport $PLUTO_MY_PORT"
fi
if [ "$PLUTO_PEER_PORT" != 0 ]
then
S_PEER_PORT="--sport $PLUTO_PEER_PORT"
D_PEER_PORT="--dport $PLUTO_PEER_PORT"
fi
# the big choice
case "$PLUTO_VERB:$1" in
prepare-host:*|prepare-client:*)
# delete possibly-existing route (preliminary to adding a route)
case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
"0.0.0.0/0.0.0.0")
# need to provide route that eclipses default, without
# replacing it.
parms1="0.0.0.0/1"
parms2="128.0.0.0/1"
it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
;;
*)
parms="$PLUTO_PEER_CLIENT"
it="ip route delete $parms 2>&1"
oops="`ip route delete $parms 2>&1`"
;;
esac
status="$?"
if test " $oops" = " " -a " $status" != " 0"
then
oops="silent error, exit status $status"
fi
case "$oops" in
*'RTNETLINK answers: No such process'*)
# This is what route (currently -- not documented!) gives
# for "could not find such a route".
oops=
status=0
;;
esac
if test " $oops" != " " -o " $status" != " 0"
then
echo "$0: \`$it' failed ($oops)" >&2
fi
exit $status
;;
route-host:*|route-client:*)
# connection to me or my client subnet being routed
uproute
;;
unroute-host:*|unroute-client:*)
# connection to me or my client subnet being unrouted
downroute
;;
up-host:)
# connection to me coming up
# If you are doing a custom version, firewall commands go here.
;;
down-host:)
# connection to me going down
# If you are doing a custom version, firewall commands go here.
;;
up-client:)
# connection to my client subnet coming up
# If you are doing a custom version, firewall commands go here.
;;
down-client:)
# connection to my client subnet going down
# If you are doing a custom version, firewall commands go here.
;;
up-host:iptables)
# connection to me, with (left/right)firewall=yes, coming up
# This is used only by the default updown script, not by your custom
# ones, so do not mess with it; see CAUTION comment up at top.
iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
-d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
#
# log IPsec host connection setup
if [ $VPN_LOGGING ]
then
if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
then
logger -t $TAG -p $FAC_PRIO \
"+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME"
else
logger -t $TAG -p $FAC_PRIO \
"+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
fi
fi
;;
down-host:iptables)
# connection to me, with (left/right)firewall=yes, going down
# This is used only by the default updown script, not by your custom
# ones, so do not mess with it; see CAUTION comment up at top.
iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
-d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
#
# log IPsec host connection teardown
if [ $VPN_LOGGING ]
then
if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
then
logger -t $TAG -p $FAC_PRIO -- \
"- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME"
else
logger -t $TAG -p $FAC_PRIO -- \
"- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
fi
fi
;;
up-client:iptables)
# connection to client subnet, with (left/right)firewall=yes, coming up
# This is used only by the default updown script, not by your custom
# ones, so do not mess with it; see CAUTION comment up at top.
if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
then
iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
-d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT \
$IPSEC_POLICY_OUT -j ACCEPT
iptables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
$IPSEC_POLICY_IN -j ACCEPT
fi
#
# a virtual IP requires an INPUT and OUTPUT rule on the host
# or sometimes host access via the internal IP is needed
if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
then
iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
$IPSEC_POLICY_IN -j ACCEPT
iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
-d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT \
$IPSEC_POLICY_OUT -j ACCEPT
fi
#
# log IPsec client connection setup
if [ $VPN_LOGGING ]
then
if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
then
logger -t $TAG -p $FAC_PRIO \
"+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
else
logger -t $TAG -p $FAC_PRIO \
"+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
fi
fi
;;
down-client:iptables)
# connection to client subnet, with (left/right)firewall=yes, going down
# This is used only by the default updown script, not by your custom
# ones, so do not mess with it; see CAUTION comment up at top.
if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
then
iptables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
-d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT \
$IPSEC_POLICY_OUT -j ACCEPT
iptables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
$IPSEC_POLICY_IN -j ACCEPT
fi
#
# a virtual IP requires an INPUT and OUTPUT rule on the host
# or sometimes host access via the internal IP is needed
if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
then
iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
$IPSEC_POLICY_IN -j ACCEPT
iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
-d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT \
$IPSEC_POLICY_OUT -j ACCEPT
fi
#
# log IPsec client connection teardown
if [ $VPN_LOGGING ]
then
if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
then
logger -t $TAG -p $FAC_PRIO -- \
"- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
else
logger -t $TAG -p $FAC_PRIO -- \
"- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
fi
fi
;;
#
# IPv6
#
prepare-host-v6:*|prepare-client-v6:*)
;;
route-host-v6:*|route-client-v6:*)
# connection to me or my client subnet being routed
#uproute_v6
;;
unroute-host-v6:*|unroute-client-v6:*)
# connection to me or my client subnet being unrouted
#downroute_v6
;;
up-host-v6:*)
# connection to me coming up
# If you are doing a custom version, firewall commands go here.
;;
down-host-v6:*)
# connection to me going down
# If you are doing a custom version, firewall commands go here.
;;
up-client-v6:)
# connection to my client subnet coming up
# If you are doing a custom version, firewall commands go here.
;;
down-client-v6:)
# connection to my client subnet going down
# If you are doing a custom version, firewall commands go here.
;;
*) echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
exit 1
;;
esac
+22
View File
@@ -0,0 +1,22 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2005/04/07 21:34:19 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=_updown_espmark
PROGRAMDIR=${LIBDIR}
include ../Makefile.program
@@ -0,0 +1,18 @@
.TH _UPDOWN_ESPMARK 8 "7 Apr 2005"
.\"
.\" RCSID $Id: _updown_espmark.8,v 1.1 2005/04/07 21:34:19 as Exp $
.\"
.SH NAME
ipsec _updown_espmark \- manages routes and firewall rules
.SH SYNOPSIS
.I _updown_espmark
is invoked by pluto when it has brought up a new connection. This script
is used to insert the appropriate routing and iptables firewall entries for
IPsec operation. The incoming ESP traffic must be marked by a static rule
in the mangle table. The default value for the mark is 50.
The interface to the script is documented in the pluto man page.
.SH "SEE ALSO"
ipsec(8), ipsec_pluto(8).
.SH HISTORY
Man page written for the Linux strongSwan project <http://www.strongswan.org/>
by Andreas Steffen. Original program written by Henry Spencer.
+452
View File
@@ -0,0 +1,452 @@
#! /bin/sh
# iproute2 version, default updown script
#
# Copyright (C) 2003-2004 Nigel Meteringham
# Copyright (C) 2003-2004 Tuomo Soini
# Copyright (C) 2002-2004 Michael Richardson
# Copyright (C) 2005 Andreas Steffen <[email protected]>
#
# 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: _updown_espmark.in,v 1.4 2005/09/14 14:33:05 as Exp $
# CAUTION: Installing a new version of strongSwan will install a new
# copy of this script, wiping out any custom changes you make. If
# you need changes, make a copy of this under another name, and customize
# that, and use the (left/right)updown parameters in ipsec.conf to make
# FreeS/WAN use yours instead of this default one.
# things that this script gets (from ipsec_pluto(8) man page)
#
#
# PLUTO_VERSION
# indicates what version of this interface is being
# used. This document describes version 1.1. This
# is upwardly compatible with version 1.0.
#
# PLUTO_VERB
# specifies the name of the operation to be performed
# (prepare-host, prepare-client, up-host, up-client,
# down-host, or down-client). If the address family
# for security gateway to security gateway communica­
# tions is IPv6, then a suffix of -v6 is added to the
# verb.
#
# PLUTO_CONNECTION
# is the name of the connection for which we are
# routing.
#
# PLUTO_NEXT_HOP
# is the next hop to which packets bound for the peer
# must be sent.
#
# PLUTO_INTERFACE
# is the name of the ipsec interface to be used.
#
# PLUTO_ME
# is the IP address of our host.
#
# PLUTO_MY_ID
# is the ID of our host.
#
# PLUTO_MY_CLIENT
# is the IP address / count of our client subnet. If
# the client is just the host, this will be the
# host's own IP address / max (where max is 32 for
# IPv4 and 128 for IPv6).
#
# PLUTO_MY_CLIENT_NET
# is the IP address of our client net. If the client
# is just the host, this will be the host's own IP
# address.
#
# PLUTO_MY_CLIENT_MASK
# is the mask for our client net. If the client is
# just the host, this will be 255.255.255.255.
#
# PLUTO_MY_SOURCEIP
# if non-empty, then the source address for the route will be
# set to this IP address.
#
# PLUTO_MY_PROTOCOL
# is the IP protocol that will be transported.
#
# PLUTO_MY_PORT
# is the UDP/TCP port to which the IPsec SA is
# restricted on our side.
#
# PLUTO_PEER
# is the IP address of our peer.
#
# PLUTO_PEER_ID
# is the ID of our peer.
#
# PLUTO_PEER_CA
# is the CA which issued the cert of our peer.
#
# PLUTO_PEER_CLIENT
# is the IP address / count of the peer's client sub­
# net. If the client is just the peer, this will be
# the peer's own IP address / max (where max is 32
# for IPv4 and 128 for IPv6).
#
# PLUTO_PEER_CLIENT_NET
# is the IP address of the peer's client net. If the
# client is just the peer, this will be the peer's
# own IP address.
#
# PLUTO_PEER_CLIENT_MASK
# is the mask for the peer's client net. If the
# client is just the peer, this will be
# 255.255.255.255.
#
# PLUTO_PEER_PROTOCOL
# is the IP protocol that will be transported.
#
# PLUTO_PEER_PORT
# is the UDP/TCP port to which the IPsec SA is
# restricted on the peer side.
#
# logging of VPN connections
#
# tag put in front of each log entry:
TAG=vpn
#
# syslog facility and priority used:
FAC_PRIO=local0.notice
#
# to create a special vpn logging file, put the following line into
# the syslog configuration file /etc/syslog.conf:
#
# local0.notice -/var/log/vpn
#
# check interface version
case "$PLUTO_VERSION" in
1.[0]) # Older Pluto?!? Play it safe, script may be using new features.
echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
echo "$0: called by obsolete Pluto?" >&2
exit 2
;;
1.*) ;;
*) echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2
exit 2
;;
esac
# check parameter(s)
case "$1:$*" in
':') # no parameters
;;
ipfwadm:ipfwadm) # due to (left/right)firewall; for default script only
;;
custom:*) # custom parameters (see above CAUTION comment)
;;
*) echo "$0: unknown parameters \`$*'" >&2
exit 2
;;
esac
# utility functions for route manipulation
# Meddling with this stuff should not be necessary and requires great care.
uproute() {
doroute add
ip route flush cache
}
downroute() {
doroute delete
ip route flush cache
}
addsource() {
st=0
if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
then
it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
oops="`eval $it 2>&1`"
st=$?
if test " $oops" = " " -a " $st" != " 0"
then
oops="silent error, exit status $st"
fi
if test " $oops" != " " -o " $st" != " 0"
then
echo "$0: addsource \`$it' failed ($oops)" >&2
fi
fi
return $st
}
doroute() {
st=0
parms="$PLUTO_PEER_CLIENT"
parms2=
if [ -n "$PLUTO_NEXT_HOP" ]
then
parms2="via $PLUTO_NEXT_HOP"
fi
parms2="$parms2 dev $PLUTO_INTERFACE"
if [ -z "$PLUTO_MY_SOURCEIP" ]
then
if [ -f /etc/sysconfig/defaultsource ]
then
. /etc/sysconfig/defaultsource
fi
if [ -f /etc/conf.d/defaultsource ]
then
. /etc/conf.d/defaultsource
fi
if [ -n "$DEFAULTSOURCE" ]
then
PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
fi
fi
parms3=
if test "$1" = "add" -a -n "$PLUTO_MY_SOURCEIP"
then
addsource
parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*}"
fi
case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
"0.0.0.0/0.0.0.0")
# opportunistic encryption work around
# need to provide route that eclipses default, without
# replacing it.
it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
ip route $1 128.0.0.0/1 $parms2 $parms3"
;;
*) it="ip route $1 $parms $parms2 $parms3"
;;
esac
oops="`eval $it 2>&1`"
st=$?
if test " $oops" = " " -a " $st" != " 0"
then
oops="silent error, exit status $st"
fi
if test " $oops" != " " -o " $st" != " 0"
then
echo "$0: doroute \`$it' failed ($oops)" >&2
fi
return $st
}
# define ESP mark
ESP_MARK=50
# add the following static rule to the INPUT chain in the mangle table
# iptables -t mangle -A INPUT -p 50 -j MARK --set-mark 50
# NAT traversal via UDP encapsulation is supported with the rule
# iptables -t mangle -A INPUT -p udp --dport 4500 -j MARK --set-mark 50
# in the presence of KLIPS and ipsecN interfaces do not use ESP mark rules
if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
then
CHECK_MARK=""
else
CHECK_MARK="-m mark --mark $ESP_MARK"
fi
# are there port numbers?
if [ "$PLUTO_MY_PORT" != 0 ]
then
S_MY_PORT="--sport $PLUTO_MY_PORT"
D_MY_PORT="--dport $PLUTO_MY_PORT"
fi
if [ "$PLUTO_PEER_PORT" != 0 ]
then
S_PEER_PORT="--sport $PLUTO_PEER_PORT"
D_PEER_PORT="--dport $PLUTO_PEER_PORT"
fi
# the big choice
case "$PLUTO_VERB:$1" in
prepare-host:*|prepare-client:*)
# delete possibly-existing route (preliminary to adding a route)
case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
"0.0.0.0/0.0.0.0")
# need to provide route that eclipses default, without
# replacing it.
parms1="0.0.0.0/1"
parms2="128.0.0.0/1"
it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
;;
*)
parms="$PLUTO_PEER_CLIENT"
it="ip route delete $parms 2>&1"
oops="`ip route delete $parms 2>&1`"
;;
esac
status="$?"
if test " $oops" = " " -a " $status" != " 0"
then
oops="silent error, exit status $status"
fi
case "$oops" in
*'RTNETLINK answers: No such process'*)
# This is what route (currently -- not documented!) gives
# for "could not find such a route".
oops=
status=0
;;
esac
if test " $oops" != " " -o " $status" != " 0"
then
echo "$0: \`$it' failed ($oops)" >&2
fi
exit $status
;;
route-host:*|route-client:*)
# connection to me or my client subnet being routed
uproute
;;
unroute-host:*|unroute-client:*)
# connection to me or my client subnet being unrouted
downroute
;;
up-host:*)
# connection to me coming up
# If you are doing a custom version, firewall commands go here.
iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_ME $S_MY_PORT \
-d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
#
if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
then
logger -t $TAG -p $FAC_PRIO \
"+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME"
else
logger -t $TAG -p $FAC_PRIO \
"+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
fi
;;
down-host:*)
# connection to me going down
# If you are doing a custom version, firewall commands go here.
# connection to me going down
# If you are doing a custom version, firewall commands go here.
iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_ME $S_MY_PORT \
-d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
#
if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
then
logger -t $TAG -p $FAC_PRIO -- \
"- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME"
else
logger -t $TAG -p $FAC_PRIO -- \
"- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
fi
;;
up-client:)
# connection to my client subnet coming up
# If you are doing a custom version, firewall commands go here.
iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
-d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
iptables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
$CHECK_MARK -j ACCEPT
#
if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
then
logger -t $TAG -p $FAC_PRIO \
"+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
else
logger -t $TAG -p $FAC_PRIO \
"+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
fi
;;
down-client:)
# connection to my client subnet going down
# If you are doing a custom version, firewall commands go here.
iptables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
-d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
iptables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
$CHECK_MARK -j ACCEPT
#
if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
then
logger -t $TAG -p $FAC_PRIO -- \
"- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
else
logger -t $TAG -p $FAC_PRIO -- \
"- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
fi
;;
up-client:ipfwadm)
# connection to client subnet, with (left/right)firewall=yes, coming up
# This is used only by the default updown script, not by your custom
# ones, so do not mess with it; see CAUTION comment up at top.
ipfwadm -F -i accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
-D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
;;
down-client:ipfwadm)
# connection to client subnet, with (left/right)firewall=yes, going down
# This is used only by the default updown script, not by your custom
# ones, so do not mess with it; see CAUTION comment up at top.
ipfwadm -F -d accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
-D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
;;
#
# IPv6
#
prepare-host-v6:*|prepare-client-v6:*)
;;
route-host-v6:*|route-client-v6:*)
# connection to me or my client subnet being routed
#uproute_v6
;;
unroute-host-v6:*|unroute-client-v6:*)
# connection to me or my client subnet being unrouted
#downroute_v6
;;
up-host-v6:*)
# connection to me coming up
# If you are doing a custom version, firewall commands go here.
;;
down-host-v6:*)
# connection to me going down
# If you are doing a custom version, firewall commands go here.
;;
up-client-v6:)
# connection to my client subnet coming up
# If you are doing a custom version, firewall commands go here.
;;
down-client-v6:)
# connection to my client subnet going down
# If you are doing a custom version, firewall commands go here.
;;
*) echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
exit 1
;;
esac
+1
View File
@@ -0,0 +1 @@
auto
+21
View File
@@ -0,0 +1,21 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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
+481
View File
@@ -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.)
+660
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
barf
+38
View File
@@ -0,0 +1,38 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=barf
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.2 2002/06/02 22:02:14 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+84
View File
@@ -0,0 +1,84 @@
.TH IPSEC_BARF 8 "17 March 2002"
.\" RCSID $Id: barf.8,v 1.1 2004/03/15 20:35:27 as Exp $
.SH NAME
ipsec barf \- spew out collected IPsec debugging information
.SH SYNOPSIS
.B ipsec
.B barf
[
.B \-\-short
]
.sp
.SH DESCRIPTION
.I Barf
outputs (on standard output) a collection of debugging information
(contents of files, selections from logs, etc.)
related to the IPsec encryption/authentication system.
It is primarily a convenience for remote debugging,
a single command which packages up (and labels) all information
that might be relevant to diagnosing a problem in IPsec.
.PP
.PP
The
.B \-\-short
option limits the length of
the log portion of
.IR barf 's
output, which can otherwise be extremely voluminous
if debug logging is turned on.
.PP
.I Barf
censors its output,
replacing keys
and secrets with brief checksums to avoid revealing sensitive information.
.PP
Beware that the output of both commands is aimed at humans,
not programs,
and the output format is subject to change without warning.
.PP
.I Barf
has to figure out which files in
.I /var/log
contain the IPsec log messages.
It looks for KLIPS and general log messages first in
.IR messages
and
.IR syslog ,
and for Pluto messages first in
.IR secure ,
.IR auth.log ,
and
.IR debug .
In both cases,
if it does not find what it is looking for in one of those ``likely'' places,
it will resort to a brute-force search of most (non-compressed) files in
.IR /var/log .
.SH FILES
.nf
/proc/net/*
/var/log/*
/etc/ipsec.conf
/etc/ipsec.secrets
.fi
.SH HISTORY
Written for the Linux FreeS/WAN project
<http://www.freeswan.org>
by Henry Spencer.
.SH BUGS
.I Barf
uses heuristics to try to pick relevant material out of the logs,
and relevant messages
which are not labelled with any of the tags that
.I barf
looks for will be lost.
We think we've eliminated the last such case, but one never knows...
.PP
Finding
.I updown
scripts (so they can be included in output) is, in general, difficult.
.I Barf
uses a very simple heuristic that is easily fooled.
.PP
The brute-force search for the right log files can get expensive on
systems with a lot of clutter in
.IR /var/log .
+296
View File
@@ -0,0 +1,296 @@
#! /bin/sh
# dump assorted information of use in debugging
# 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: barf.in,v 1.4 2004/09/23 21:08:23 as Exp $
IPSEC_NAME="strongSwan"
KERNSRC=${KERNSRC-/usr/src/linux}
LOGS=${LOGS-/var/log}
CONFS=${IPSEC_CONFS-/etc}
CONFDDIR=${IPSEC_CONFDDIR-/etc/ipsec.d}
me="ipsec barf"
# kludge to produce no barf output mentioning policygroups if none are present.
# This will not catch ".file" policygroups.
PREPOLICIES=${CONFDDIR}/policies
if [ `ls $PREPOLICIES 2> /dev/null | wc -l` -ne 0 ]
then
POLICIES=$PREPOLICIES
fi
# message patterns that start relevant parts of logs
fstart="Starting $IPSEC_NAME"
pstart='Starting Pluto subsystem'
case "$1" in
--help) echo "Usage: ipsec barf" ; exit 0 ;;
--version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
esac
# make sure output is in English
unset LANG LANGUAGE LC_ALL LC_MESSAGES
# log-location guesser, results in $findlog_file and $findlog_startline
# Fine point: startline is the *last* line containing "string", or
# failing that, the *first* line containing "fallbackstring".
findlog() { # findlog string fallbackstring possiblefile ...
s="$1"
shift
t="$1"
shift
# try the suggested files first
for f in $*
do
if test -r $LOGS/$f -a -f $LOGS/$f && egrep -q "$s" $LOGS/$f
then
# aha, this one has it
findlog_file=$LOGS/$f
findlog_startline=`egrep -n "$s" $LOGS/$f |
sed -n '$s/:.*//p'`
return 0
fi
done
for f in $*
do
if test -r $LOGS/$f -a -f $LOGS/$f && egrep -q "$t" $LOGS/$f
then
# aha, this one has it
findlog_file=$LOGS/$f
findlog_startline=`egrep -n "$t" $LOGS/$f |
sed -n '1s/:.*//p'`
return 0
fi
done
# nope, resort to a search, newest first, of uncompressed logs
for f in `ls -t $LOGS | egrep -v '^mail' | egrep -v '\.(gz|Z)$'`
do
if test -r $LOGS/$f -a ! -d $LOGS/$f && egrep -q "$s" $LOGS/$f
then
# found it
findlog_file=$LOGS/$f
findlog_startline=`egrep -n "$s" $LOGS/$f |
sed -n '$s/:.*//p'`
return 0
fi
done
for f in `ls -t $LOGS | egrep -v '^mail' | egrep -v '\.(gz|Z)$'`
do
if test -r $LOGS/$f -a -f $LOGS/$f && egrep -q "$t" $LOGS/$f
then
# found it
findlog_file=$LOGS/$f
findlog_startline=`egrep -n "$t" $LOGS/$f |
sed -n '1s/:.*//p'`
return 0
fi
done
# echo "$0: unable to find $LOGS/$1 or local equivalent" >&2
findlog_file=/dev/null
findlog_startline=1 # arbitrary
}
# try to guess where logs are
findlog "$fstart" "klips" messages syslog
if test " $findlog_file" = " /dev/null"
then
echo "Unable to find KLIPS messages, typically found in /var/log/messages or equivalent. You may need to run $IPSEC_NAME for the first time; alternatively, your log files have been emptied (ie, logwatch) or we do not understand your logging configuration."
fi
klog=$findlog_file
kline=$findlog_startline
findlog "$pstart" "Pluto" secure auth.log debug
if test " $findlog_file" = " /dev/null"
then
echo "Unable to find Pluto messages, typically found in /var/log/secure or equivalent. You may need to run $IPSEC_NAME for the first time; alternatively, your log files have been emptied (ie, logwatch) or we do not understand your logging configuration."
fi
plog=$findlog_file
pline=$findlog_startline
# /lib/modules examiner
modulegoo() {
set +x
for d in `ls /lib/modules`
do
if test -d /lib/modules/$d
then
f=/lib/modules/$d/$1
if test -f $f
then
nm -g $f | egrep "$2"
else
echo
fi | sed "s;^;$d: ;"
fi
done
set -x
}
# advanced shell deviousness to get dividers into output
_________________________() {
$2 # something to do nothing and not echo anything
}
exec 2>&1 # stderr on stdout, so errors go into main output
hostname ; date
set -x
_________________________ version
ipsec --version
_________________________ proc/version
cat /proc/version
_________________________ proc/net/ipsec_eroute
sort -sg +3 /proc/net/ipsec_eroute || cat /proc/net/ipsec_eroute
_________________________ netstat-rn
netstat -nr
_________________________ proc/net/ipsec_spi
cat /proc/net/ipsec_spi
_________________________ proc/net/ipsec_spigrp
cat /proc/net/ipsec_spigrp
_________________________ proc/net/ipsec_tncfg
cat /proc/net/ipsec_tncfg
_________________________ proc/net/pf_key
cat /proc/net/pf_key
_________________________ proc/net/pf_key-star
( cd /proc/net && egrep '^' pf_key_* )
_________________________ proc/sys/net/ipsec-star
( cd /proc/sys/net/ipsec && egrep '^' * )
_________________________ ipsec/statusall
ipsec auto --statusall
_________________________ ifconfig-a
ifconfig -a
_________________________ mii-tool
if [ -x /sbin/mii-tool ]
then
/sbin/mii-tool -v
elif [ -x /usr/sbin/mii-tool ]
then
/usr/sbin/mii-tool -v
else
mii-tool -v
fi
_________________________ ipsec/directory
ipsec --directory
_________________________ hostname/fqdn
hostname --fqdn
_________________________ hostname/ipaddress
hostname --ip-address
_________________________ uptime
uptime
_________________________ ps
# -i ppid picks up the header
ps alxwf | egrep -i 'ppid|pluto|ipsec|klips'
_________________________ ipsec/showdefaults
ipsec showdefaults
_________________________ ipsec/conf
ipsec _include $CONFS/ipsec.conf | ipsec _keycensor
_________________________ ipsec/secrets
ipsec _include $CONFS/ipsec.secrets | ipsec _secretcensor
_________________________ ipsec/listall
ipsec auto --listall
if [ $POLICIES ]
then
for policy in $POLICIES/*; do base=`basename $policy`;
_________________________ ipsec/policies/$base
cat $policy
done
fi
_________________________ ipsec/ls-libdir
ls -l ${IPSEC_LIBDIR-/usr/local/lib/ipsec}
_________________________ ipsec/ls-execdir
ls -l ${IPSEC_EXECDIR-/usr/local/libexec/ipsec}
_________________________ ipsec/updowns
for f in `ls ${IPSEC_EXECDIR-/usr/local/libexec/ipsec} | egrep updown`
do
cat ${IPSEC_EXECDIR-/usr/local/libexec/ipsec}/$f
done
_________________________ proc/net/dev
cat /proc/net/dev
_________________________ proc/net/route
cat /proc/net/route
_________________________ proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward
_________________________ proc/sys/net/ipv4/conf/star-rp_filter
( cd /proc/sys/net/ipv4/conf && egrep '^' */rp_filter )
_________________________ uname-a
uname -a
_________________________ redhat-release
if test -r /etc/redhat-release
then
cat /etc/redhat-release
fi
_________________________ proc/net/ipsec_version
cat /proc/net/ipsec_version
_________________________ iptables/list
iptables -L -v -n
_________________________ ipchains/list
ipchains -L -v -n
_________________________ ipfwadm/forward
ipfwadm -F -l -n -e
_________________________ ipfwadm/input
ipfwadm -I -l -n -e
_________________________ ipfwadm/output
ipfwadm -O -l -n -e
_________________________ iptables/nat
iptables -t nat -L -v -n
_________________________ ipchains/masq
ipchains -M -L -v -n
_________________________ ipfwadm/masq
ipfwadm -M -l -n -e
_________________________ iptables/mangle
iptables -t mangle -L -v -n
_________________________ proc/modules
cat /proc/modules
_________________________ proc/meminfo
cat /proc/meminfo
_________________________ dev/ipsec-ls
ls -l /dev/ipsec*
_________________________ proc/net/ipsec-ls
ls -l /proc/net/ipsec_*
_________________________ usr/src/linux/.config
if test -f $KERNSRC/.config
then
egrep 'IP|NETLINK' $KERNSRC/.config
fi
_________________________ etc/syslog.conf
cat /etc/syslog.conf
_________________________ etc/resolv.conf
cat /etc/resolv.conf
_________________________ lib/modules-ls
ls -ltr /lib/modules
_________________________ proc/ksyms-netif_rx
egrep netif_rx /proc/ksyms
_________________________ lib/modules-netif_rx
modulegoo kernel/net/ipv4/ipip.o netif_rx
_________________________ kern.debug
if test -f $LOGS/kern.debug
then
tail -100 $LOGS/kern.debug
fi
_________________________ klog
sed -n $kline,'$'p $klog |
egrep -i 'ipsec|klips|pluto' |
case "$1" in
--short) tail -500 ;;
*) cat ;;
esac
_________________________ plog
sed -n $pline,'$'p $plog |
egrep -i 'pluto' |
case "$1" in
--short) tail -500 ;;
*) cat ;;
esac
_________________________ date
date
+1
View File
@@ -0,0 +1 @@
calcgoo
+41
View File
@@ -0,0 +1,41 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=calcgoo
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.1 2002/06/10 04:27:25 mcr
# calcgoo program processes kernel symbol list and generates a
# composite value by xor'ing the programmed symbol.
#
# Revision 1.1 2002/06/10 00:19:44 mcr
# rename "ipsec check" to "ipsec verify"
#
# Revision 1.1 2002/06/08 17:01:25 mcr
# added new program "ipsec check" to do rudamentary testing
# on a newly installed system to see if it is OE ready.
#
#
#
+31
View File
@@ -0,0 +1,31 @@
.TH IPSEC_CALCGOO 8 "8 June 2002"
.\" RCSID $Id: calcgoo.8,v 1.1 2004/03/15 20:35:27 as Exp $
.SH NAME
ipsec calcgoo \- calculate hex value for matching modules and kernels
.SH SYNOPSIS
.B ipsec
.B calcgoo
.SH DESCRIPTION
.I calcgoo
accepts the output of
.B nm -ao
or
.B /proc/ksyms
and extracts a release dependant list of symbols from it. The symbols
are processed to extract the values assigned during the MODVERSIONS
process. This process makes sure that Linux modules are only loaded
on matching kernels.
.P
This routine is used to find an appropriate module to match the currently
running kernel by _startklips.
.SH FILES
.nf
/proc/ksyms
.fi
.SH "SEE ALSO"
ipsec__startklips(8), genksyms(8)
.SH HISTORY
Written for the Linux FreeS/WAN project
<http://www.freeswan.org>
by Michael Richardson.
.SH BUGS
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/perl
$MODULE_GOO_LIST="@MODULE_GOO_LIST@";
@goo = split(/\s+/,$MODULE_GOO_LIST);
$sep="(";
$goore=" ";
#print "GOO: ",join('|',@goo),"\n";
foreach $sym (@goo) {
$goore=${goore}.${sep}.${sym};
$sep="|";
}
$goore=${goore}.")_R(smp_){0,1}([0-9A-F]{8})";
#print "GOORE: $goore\n";
while(<>) {
chomp;
if(/$goore/io) {
$sym=$1;
$goosym=$3;
$bingoo=hex($goosym);
if($2 eq "smp_") {
$bingoo++;
}
#print STDERR "Processing $goosym (from $_)\n";
$bingoo{$sym}=$bingoo;
}
}
$wholegoo=0;
foreach $sym (keys %bingoo) {
$wholegoo=$wholegoo ^ $bingoo{$sym};
}
print sprintf("%08x", $wholegoo)."\n";
# Local variables::
# mode: perl
# End variables::
+220
View File
@@ -0,0 +1,220 @@
# Doxyfile 1.4.1-KDevelop
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = "charon"
PROJECT_NUMBER = 1.0
OUTPUT_DIRECTORY = doc/api
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = YES
INHERIT_DOCS = YES
DISTRIBUTE_GROUP_DOC = NO
TAB_SIZE = 1
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = NO
EXTRACT_LOCAL_METHODS = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = NO
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST = YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ./
FILE_PATTERNS = *.h *.txt
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = .
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = YES
ENUM_VALUES_PER_LINE = 1
GENERATE_TREEVIEW = YES
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = YES
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = LEAK_DETECTIVE
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
+99
View File
@@ -0,0 +1,99 @@
# Copyright (C) 2005 Jan Hutter, Martin Willi
# Hochschule fuer Technik Rapperswil
#
# 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.
#
FREESWANSRCDIR=../..
# include strongswan Makefile, if charon sits in its tree
ifeq ($(shell ls $(FREESWANSRCDIR)/Makefile.inc 2>&1), ../../Makefile.inc)
include ${FREESWANSRCDIR}/Makefile.inc
else
# Defaults if not using strongswan defines
USE_LEAK_DETECTIVE?=false
INSTALL=install
INSTBINFLAGS=-b --suffix=.old
LIBEXECDIR=/usr/local/libexec/ipsec
SHAREDLIBDIR=/usr/local/lib
endif
BUILD_DIR= ./bin/
BINNAMECHARON= $(BUILD_DIR)charon
BINNAMESTROKE= $(BUILD_DIR)stroke
BINNAMETEST= $(BUILD_DIR)run_tests
BINNAMELIB= $(BUILD_DIR)libstrongswan.so
MAIN_DIR= ./
CFLAGS= -Icharon -Ilib -Istroke -fPIC -Wall -g
ifeq ($(USE_LEAK_DETECTIVE),true)
CFLAGS+= -DLEAK_DETECTIVE
endif
# objects is extended by each included Makefile
CHARON_OBJS=
LIB_OBJS=
TEST_OBJS=
all : programs
include $(MAIN_DIR)charon/Makefile.charon
include $(MAIN_DIR)lib/Makefile.lib
include $(MAIN_DIR)stroke/Makefile.stroke
include $(MAIN_DIR)testing/Makefile.testcases
programs : $(BINNAMECHARON) $(BINNAMESTROKE)
test : $(BINNAMETEST)
LD_LIBRARY_PATH=$(BUILD_DIR) $(BINNAMETEST)
run : $(BINNAMECHARON)
LD_LIBRARY_PATH=$(BUILD_DIR) $(BINNAMECHARON)
apidoc :
doxygen Doxyfile
build_dir:
mkdir -p $(BUILD_DIR)
$(BINNAMELIB) : build_dir $(LIB_OBJS)
$(CC) -lpthread -ldl -lgmp -shared $(LIB_OBJS) -o $@
$(BINNAMECHARON) : build_dir $(CHARON_OBJS) $(BINNAMELIB) $(BUILD_DIR)daemon.o
$(CC) -L./bin -lstrongswan $(CHARON_OBJS) $(BUILD_DIR)daemon.o -o $@
$(BINNAMETEST) : build_dir $(CHARON_OBJS) $(TEST_OBJS) $(BINNAMELIB) $(BUILD_DIR)testcases.o
$(CC) -L./bin -lstrongswan $(LDFLAGS) $(CHARON_OBJS) $(TEST_OBJS) $(BUILD_DIR)testcases.o -o $@
$(BINNAMESTROKE) : build_dir $(BINNAMELIB) $(BUILD_DIR)stroke.o
$(CC) $(LDFLAGS) $(CFLAGS) $(BUILD_DIR)stroke.o -o $@
install : $(BINNAMECHARON) $(BINNAMESTROKE)
$(INSTALL) $(INSTBINFLAGS) $(BINNAMECHARON) $(BINNAMESTROKE) $(LIBEXECDIR)
$(INSTALL) $(INSTBINFLAGS) $(BINNAMELIB) $(SHAREDLIBDIR)
install_file_list:
@echo $(LIBEXECDIR)/charon
@echo $(LIBEXECDIR)/stroke
@echo $(SHAREDLIBDIR)/libstrongswan.so
clean :
rm -fR $(BUILD_DIR)
cleanall: clean
distclean: clean
mostlyclean: clean
realclean: clean
+105
View File
@@ -0,0 +1,105 @@
<?xml version = '1.0'?>
<kdevelop>
<general>
<author>Martin Willi</author>
<email>[email protected]</email>
<version>$VERSION$</version>
<projectmanagement>KDevCustomProject</projectmanagement>
<primarylanguage>C</primarylanguage>
<ignoreparts/>
</general>
<kdevcustomproject>
<run>
<mainprogram>Source</mainprogram>
<directoryradio>executable</directoryradio>
</run>
<general>
<activedir/>
</general>
</kdevcustomproject>
<kdevdebugger>
<general>
<dbgshell/>
</general>
</kdevdebugger>
<kdevdoctreeview>
<ignoretocs>
<toc>ada</toc>
<toc>ada_bugs_gcc</toc>
<toc>bash</toc>
<toc>bash_bugs</toc>
<toc>clanlib</toc>
<toc>fortran_bugs_gcc</toc>
<toc>gnome1</toc>
<toc>gnustep</toc>
<toc>gtk</toc>
<toc>gtk_bugs</toc>
<toc>haskell</toc>
<toc>haskell_bugs_ghc</toc>
<toc>java_bugs_gcc</toc>
<toc>java_bugs_sun</toc>
<toc>kde2book</toc>
<toc>libstdc++</toc>
<toc>opengl</toc>
<toc>pascal_bugs_fp</toc>
<toc>php</toc>
<toc>php_bugs</toc>
<toc>perl</toc>
<toc>perl_bugs</toc>
<toc>python</toc>
<toc>python_bugs</toc>
<toc>qt-kdev3</toc>
<toc>ruby</toc>
<toc>ruby_bugs</toc>
<toc>sdl</toc>
<toc>stl</toc>
<toc>sw</toc>
<toc>w3c-dom-level2-html</toc>
<toc>w3c-svg</toc>
<toc>w3c-uaag10</toc>
<toc>wxwidgets_bugs</toc>
</ignoretocs>
<ignoreqt_xml>
<toc>Guide to the Qt Translation Tools</toc>
<toc>Qt Assistant Manual</toc>
<toc>Qt Designer Manual</toc>
<toc>Qt Reference Documentation</toc>
<toc>qmake User Guide</toc>
</ignoreqt_xml>
<ignoredoxygen>
<toc>KDE Libraries (Doxygen)</toc>
</ignoredoxygen>
</kdevdoctreeview>
<kdevfilecreate>
<filetypes/>
<useglobaltypes>
<type ext="c" />
<type ext="h" />
</useglobaltypes>
</kdevfilecreate>
<kdevcppsupport>
<references/>
<codecompletion>
<includeGlobalFunctions>true</includeGlobalFunctions>
<includeTypes>true</includeTypes>
<includeEnums>true</includeEnums>
<includeTypedefs>false</includeTypedefs>
<automaticCodeCompletion>true</automaticCodeCompletion>
<automaticArgumentsHint>true</automaticArgumentsHint>
<automaticHeaderCompletion>true</automaticHeaderCompletion>
<codeCompletionDelay>250</codeCompletionDelay>
<argumentsHintDelay>400</argumentsHintDelay>
<headerCompletionDelay>250</headerCompletionDelay>
</codecompletion>
</kdevcppsupport>
<kdevfileview>
<groups>
<hidenonprojectfiles>false</hidenonprojectfiles>
<hidenonlocation>false</hidenonlocation>
</groups>
<tree>
<hidepatterns>*.o,*.lo,CVS</hidepatterns>
<hidenonprojectfiles>false</hidenonprojectfiles>
</tree>
</kdevfileview>
</kdevelop>
+25
View File
@@ -0,0 +1,25 @@
# Copyright (C) 2006 Martin Willi
# Hochschule fuer Technik Rapperswil
#
# 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.
#
CHARON_DIR= $(MAIN_DIR)charon/
$(BUILD_DIR)daemon.o : $(CHARON_DIR)daemon.c $(CHARON_DIR)daemon.h
$(CC) $(CFLAGS) -c -o $@ $<
include $(CHARON_DIR)network/Makefile.network
include $(CHARON_DIR)config/Makefile.config
include $(CHARON_DIR)encoding/Makefile.encoding
include $(CHARON_DIR)queues/Makefile.queues
include $(CHARON_DIR)sa/Makefile.sa
include $(CHARON_DIR)threads/Makefile.threads
@@ -0,0 +1,32 @@
# Copyright (C) 2005 Jan Hutter, Martin Willi
# Hochschule fuer Technik Rapperswil
#
# 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.
#
CONFIG_DIR= $(CHARON_DIR)config/
CHARON_OBJS+= $(BUILD_DIR)traffic_selector.o
$(BUILD_DIR)traffic_selector.o : $(CONFIG_DIR)traffic_selector.c $(CONFIG_DIR)traffic_selector.h
$(CC) $(CFLAGS) -c -o $@ $<
CHARON_OBJS+= $(BUILD_DIR)proposal.o
$(BUILD_DIR)proposal.o : $(CONFIG_DIR)proposal.c $(CONFIG_DIR)proposal.h
$(CC) $(CFLAGS) -c -o $@ $<
CHARON_OBJS+= $(BUILD_DIR)configuration.o
$(BUILD_DIR)configuration.o : $(CONFIG_DIR)configuration.c $(CONFIG_DIR)configuration.h
$(CC) $(CFLAGS) -c -o $@ $<
include $(CONFIG_DIR)connections/Makefile.connections
include $(CONFIG_DIR)credentials/Makefile.credentials
include $(CONFIG_DIR)policies/Makefile.policies
+112
View File
@@ -0,0 +1,112 @@
/**
* @file configuration.c
*
* @brief Implementation of configuration_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#include <stdlib.h>
#include "configuration.h"
#include <types.h>
/**
* First retransmit timeout in milliseconds.
* Timeout value is increasing in each retransmit round.
*/
#define RETRANSMIT_TIMEOUT 3000
/**
* Timeout in milliseconds after that a half open IKE_SA gets deleted.
*/
#define HALF_OPEN_IKE_SA_TIMEOUT 30000
/**
* Max retransmit count.
* 0 for infinite. The max time a half open IKE_SA is alive is set by
* RETRANSMIT_TIMEOUT.
*/
#define MAX_RETRANSMIT_COUNT 0
typedef struct private_configuration_t private_configuration_t;
/**
* Private data of an configuration_t object.
*/
struct private_configuration_t {
/**
* Public part of configuration_t object.
*/
configuration_t public;
};
/**
* Implementation of configuration_t.get_retransmit_timeout.
*/
static status_t get_retransmit_timeout (private_configuration_t *this, u_int32_t retransmit_count, u_int32_t *timeout)
{
int new_timeout = RETRANSMIT_TIMEOUT, i;
if (retransmit_count > MAX_RETRANSMIT_COUNT && MAX_RETRANSMIT_COUNT != 0)
{
return FAILED;
}
for (i = 0; i < retransmit_count; i++)
{
new_timeout *= 2;
}
*timeout = new_timeout;
return SUCCESS;
}
/**
* Implementation of configuration_t.get_half_open_ike_sa_timeout.
*/
static u_int32_t get_half_open_ike_sa_timeout (private_configuration_t *this)
{
return HALF_OPEN_IKE_SA_TIMEOUT;
}
/**
* Implementation of configuration_t.destroy.
*/
static void destroy(private_configuration_t *this)
{
free(this);
}
/*
* Described in header-file
*/
configuration_t *configuration_create()
{
private_configuration_t *this = malloc_thing(private_configuration_t);
/* public functions */
this->public.destroy = (void(*)(configuration_t*))destroy;
this->public.get_retransmit_timeout = (status_t (*) (configuration_t *, u_int32_t retransmit_count, u_int32_t *timeout))get_retransmit_timeout;
this->public.get_half_open_ike_sa_timeout = (u_int32_t (*) (configuration_t *)) get_half_open_ike_sa_timeout;
return (&this->public);
}
+89
View File
@@ -0,0 +1,89 @@
/**
* @file configuration.h
*
* @brief Interface configuration_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef CONFIGURATION_H_
#define CONFIGURATION_H_
#include <types.h>
typedef struct configuration_t configuration_t;
/**
* @brief The interface for various daemon related configs.
*
* @b Constructors:
* - configuration_create()
*
* @ingroup config
*/
struct configuration_t {
/**
* @brief Returns the retransmit timeout.
*
* The timeout values are managed by the configuration, so
* another backoff algorithm may be implemented here.
*
* @param this calling object
* @param retransmit_count number of times a message was retransmitted so far
* @param[out] timeout the new retransmit timeout in milliseconds
*
* @return
* - FAILED, if the message should not be retransmitted
* - SUCCESS
*/
status_t (*get_retransmit_timeout) (configuration_t *this, u_int32_t retransmit_count, u_int32_t *timeout);
/**
* @brief Returns the timeout for an half open IKE_SA in ms.
*
* Half open means that the IKE_SA is still in one of the following states:
* - INITIATOR_INIT
* - RESPONDER_INIT
* - IKE_SA_INIT_REQUESTED
* - IKE_SA_INIT_RESPONDED
* - IKE_AUTH_REQUESTED
*
* @param this calling object
* @return timeout in milliseconds (ms)
*/
u_int32_t (*get_half_open_ike_sa_timeout) (configuration_t *this);
/**
* @brief Destroys a configuration_t object.
*
* @param this calling object
*/
void (*destroy) (configuration_t *this);
};
/**
* @brief Creates a configuration backend.
*
* @return static_configuration_t object
*
* @ingroup config
*/
configuration_t *configuration_create();
#endif /*CONFIGURATION_H_*/
@@ -0,0 +1,24 @@
# Copyright (C) 2006 Martin Willi
# Hochschule fuer Technik Rapperswil
#
# 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.
#
CONNECTIONS_DIR= $(CONFIG_DIR)connections/
CHARON_OBJS+= $(BUILD_DIR)connection.o
$(BUILD_DIR)connection.o : $(CONNECTIONS_DIR)connection.c $(CONNECTIONS_DIR)connection.h
$(CC) $(CFLAGS) -c -o $@ $<
CHARON_OBJS+= $(BUILD_DIR)local_connection_store.o
$(BUILD_DIR)local_connection_store.o : $(CONNECTIONS_DIR)local_connection_store.c $(CONNECTIONS_DIR)local_connection_store.h
$(CC) $(CFLAGS) -c -o $@ $<
@@ -0,0 +1,367 @@
/**
* @file connection.c
*
* @brief Implementation of connection_t.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#include <string.h>
#include "connection.h"
#include <utils/linked_list.h>
#include <utils/logger.h>
/**
* String mappings for auth_method_t.
*/
mapping_t auth_method_m[] = {
{RSA_DIGITAL_SIGNATURE, "RSA"},
{SHARED_KEY_MESSAGE_INTEGRITY_CODE, "SHARED_KEY"},
{DSS_DIGITAL_SIGNATURE, "DSS"},
{MAPPING_END, NULL}
};
typedef struct private_connection_t private_connection_t;
/**
* Private data of an connection_t object
*/
struct private_connection_t {
/**
* Public part
*/
connection_t public;
/**
* Name of the connection
*/
char *name;
/**
* ID of us
*/
identification_t *my_id;
/**
* ID of remote peer
*/
identification_t *other_id;
/**
* Host information of my host.
*/
host_t *my_host;
/**
* Host information of other host.
*/
host_t *other_host;
/**
* Method to use for own authentication data
*/
auth_method_t auth_method;
/**
* Supported proposals
*/
linked_list_t *proposals;
};
/**
* Implementation of connection_t.get_name.
*/
static char *get_name (private_connection_t *this)
{
return this->name;
}
/**
* Implementation of connection_t.get_my_id.
*/
static identification_t *get_my_id (private_connection_t *this)
{
return this->my_id;
}
/**
* Implementation of connection_t.get_other_id.
*/
static identification_t *get_other_id(private_connection_t *this)
{
return this->other_id;
}
/**
* Implementation of connection_t.update_my_id
*/
static void update_my_id(private_connection_t *this, identification_t *my_id)
{
this->my_id->destroy(this->my_id);
this->my_id = my_id;
}
/**
* Implementation of connection_t.update_other_id
*/
static void update_other_id(private_connection_t *this, identification_t *other_id)
{
this->other_id->destroy(this->other_id);
this->other_id = other_id;
}
/**
* Implementation of connection_t.get_my_host.
*/
static host_t * get_my_host (private_connection_t *this)
{
return this->my_host;
}
/**
* Implementation of connection_t.update_my_host.
*/
static void update_my_host(private_connection_t *this, host_t *my_host)
{
this->my_host->destroy(this->my_host);
this->my_host = my_host;
}
/**
* Implementation of connection_t.update_other_host.
*/
static void update_other_host(private_connection_t *this, host_t *other_host)
{
this->other_host->destroy(this->other_host);
this->other_host = other_host;
}
/**
* Implementation of connection_t.get_other_host.
*/
static host_t * get_other_host (private_connection_t *this)
{
return this->other_host;
}
/**
* Implementation of connection_t.get_proposals.
*/
static linked_list_t* get_proposals (private_connection_t *this)
{
return this->proposals;
}
/**
* Implementation of connection_t.select_proposal.
*/
static proposal_t *select_proposal(private_connection_t *this, linked_list_t *proposals)
{
iterator_t *stored_iter, *supplied_iter;
proposal_t *stored, *supplied, *selected;
stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
supplied_iter = proposals->create_iterator(proposals, TRUE);
/* compare all stored proposals with all supplied. Stored ones are preferred. */
while (stored_iter->has_next(stored_iter))
{
supplied_iter->reset(supplied_iter);
stored_iter->current(stored_iter, (void**)&stored);
while (supplied_iter->has_next(supplied_iter))
{
supplied_iter->current(supplied_iter, (void**)&supplied);
selected = stored->select(stored, supplied);
if (selected)
{
/* they match, return */
stored_iter->destroy(stored_iter);
supplied_iter->destroy(supplied_iter);
return selected;
}
}
}
/* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
stored_iter->destroy(stored_iter);
supplied_iter->destroy(supplied_iter);
return NULL;
}
/**
* Implementation of connection_t.add_proposal.
*/
static void add_proposal (private_connection_t *this, proposal_t *proposal)
{
this->proposals->insert_last(this->proposals, proposal);
}
/**
* Implementation of connection_t.auth_method_t.
*/
static auth_method_t get_auth_method(private_connection_t *this)
{
return this->auth_method;
}
/**
* Implementation of connection_t.get_dh_group.
*/
static diffie_hellman_group_t get_dh_group(private_connection_t *this)
{
iterator_t *iterator;
proposal_t *proposal;
algorithm_t *algo;
iterator = this->proposals->create_iterator(this->proposals, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&proposal);
proposal->get_algorithm(proposal, PROTO_IKE, DIFFIE_HELLMAN_GROUP, &algo);
if (algo)
{
iterator->destroy(iterator);
return algo->algorithm;
}
}
iterator->destroy(iterator);
return MODP_UNDEFINED;
}
/**
* Implementation of connection_t.check_dh_group.
*/
static bool check_dh_group(private_connection_t *this, diffie_hellman_group_t dh_group)
{
iterator_t *prop_iter, *alg_iter;
proposal_t *proposal;
algorithm_t *algo;
prop_iter = this->proposals->create_iterator(this->proposals, TRUE);
while (prop_iter->has_next(prop_iter))
{
prop_iter->current(prop_iter, (void**)&proposal);
alg_iter = proposal->create_algorithm_iterator(proposal, PROTO_IKE, DIFFIE_HELLMAN_GROUP);
while (alg_iter->has_next(alg_iter))
{
alg_iter->current(alg_iter, (void**)&algo);
if (algo->algorithm == dh_group)
{
prop_iter->destroy(prop_iter);
alg_iter->destroy(alg_iter);
return TRUE;
}
}
}
prop_iter->destroy(prop_iter);
alg_iter->destroy(alg_iter);
return FALSE;
}
/**
* Implementation of connection_t.clone.
*/
static connection_t *clone(private_connection_t *this)
{
iterator_t *iterator;
proposal_t *proposal;
private_connection_t *clone = (private_connection_t*)connection_create(
this->name,
this->my_host->clone(this->my_host),
this->other_host->clone(this->other_host),
this->my_id->clone(this->my_id),
this->other_id->clone(this->other_id),
this->auth_method);
/* clone all proposals */
iterator = this->proposals->create_iterator(this->proposals, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&proposal);
proposal = proposal->clone(proposal);
clone->proposals->insert_last(clone->proposals, (void*)proposal);
}
iterator->destroy(iterator);
return &clone->public;
}
/**
* Implementation of connection_t.destroy.
*/
static void destroy (private_connection_t *this)
{
proposal_t *proposal;
while (this->proposals->remove_last(this->proposals, (void**)&proposal) == SUCCESS)
{
proposal->destroy(proposal);
}
this->proposals->destroy(this->proposals);
this->my_host->destroy(this->my_host);
this->other_host->destroy(this->other_host);
this->my_id->destroy(this->my_id);
this->other_id->destroy(this->other_id);
free(this->name);
free(this);
}
/**
* Described in header.
*/
connection_t * connection_create(char *name, host_t *my_host, host_t *other_host, identification_t *my_id, identification_t *other_id, auth_method_t auth_method)
{
private_connection_t *this = malloc_thing(private_connection_t);
/* public functions */
this->public.get_name = (char*(*)(connection_t*))get_name;
this->public.get_my_id = (identification_t*(*)(connection_t*))get_my_id;
this->public.get_other_id = (identification_t*(*)(connection_t*))get_other_id;
this->public.get_my_host = (host_t*(*)(connection_t*))get_my_host;
this->public.update_my_host = (void(*)(connection_t*,host_t*))update_my_host;
this->public.update_other_host = (void(*)(connection_t*,host_t*))update_other_host;
this->public.update_my_id = (void(*)(connection_t*,identification_t*))update_my_id;
this->public.update_other_id = (void(*)(connection_t*,identification_t*))update_other_id;
this->public.get_other_host = (host_t*(*)(connection_t*))get_other_host;
this->public.get_proposals = (linked_list_t*(*)(connection_t*))get_proposals;
this->public.select_proposal = (proposal_t*(*)(connection_t*,linked_list_t*))select_proposal;
this->public.add_proposal = (void(*)(connection_t*, proposal_t*)) add_proposal;
this->public.get_auth_method = (auth_method_t(*)(connection_t*)) get_auth_method;
this->public.get_dh_group = (diffie_hellman_group_t(*)(connection_t*)) get_dh_group;
this->public.check_dh_group = (bool(*)(connection_t*,diffie_hellman_group_t)) check_dh_group;
this->public.clone = (connection_t*(*)(connection_t*))clone;
this->public.destroy = (void(*)(connection_t*))destroy;
/* private variables */
this->name = strdup(name);
this->my_host = my_host;
this->other_host = other_host;
this->my_id = my_id;
this->other_id = other_id;
this->auth_method = auth_method;
this->proposals = linked_list_create();
return (&this->public);
}
@@ -0,0 +1,283 @@
/**
* @file connection.h
*
* @brief Interface of connection_t.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef CONNECTION_H_
#define CONNECTION_H_
#include <types.h>
#include <utils/host.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
#include <config/proposal.h>
#include <crypto/diffie_hellman.h>
typedef enum auth_method_t auth_method_t;
/**
* AUTH Method to use.
*
* @ingroup config
*/
enum auth_method_t {
/**
* Computed as specified in section 2.15 of RFC using
* an RSA private key over a PKCS#1 padded hash.
*/
RSA_DIGITAL_SIGNATURE = 1,
/**
* Computed as specified in section 2.15 of RFC using the
* shared key associated with the identity in the ID payload
* and the negotiated prf function
*/
SHARED_KEY_MESSAGE_INTEGRITY_CODE = 2,
/**
* Computed as specified in section 2.15 of RFC using a
* DSS private key over a SHA-1 hash.
*/
DSS_DIGITAL_SIGNATURE = 3,
};
/**
* string mappings for auth method.
*
* @ingroup config
*/
extern mapping_t auth_method_m[];
typedef struct connection_t connection_t;
/**
* @brief A connection_t defines the rules to set up an IKE_SA.
*
*
* @b Constructors:
* - connection_create()
*
* @ingroup config
*/
struct connection_t {
/**
* @brief Get my ID for this connection.
*
* Object is NOT getting cloned.
*
* @param this calling object
* @return host information as identification_t object
*/
identification_t *(*get_my_id) (connection_t *this);
/**
* @brief Get others ID for this connection.
*
* Object is NOT getting cloned.
*
* @param this calling object
* @return host information as identification_t object
*/
identification_t *(*get_other_id) (connection_t *this);
/**
* @brief Get my address as host_t object.
*
* Object is NOT getting cloned.
*
* @param this calling object
* @return host information as host_t object
*/
host_t *(*get_my_host) (connection_t *this);
/**
* @brief Get others address as host_t object.
*
* Object is NOT getting cloned.
*
* @param this calling object
* @return host information as host_t object
*/
host_t *(*get_other_host) (connection_t *this);
/**
* @brief Update address of my host.
*
* It may be necessary to uptdate own address, as it
* is set to the default route (0.0.0.0) in some cases.
* Old host is destroyed, new one NOT cloned.
*
* @param this calling object
* @param my_host new host to set as my_host
*/
void (*update_my_host) (connection_t *this, host_t *my_host);
/**
* @brief Update address of remote host.
*
* It may be necessary to uptdate remote address, as a
* connection may define %any (0.0.0.0) or a subnet.
* Old host is destroyed, new one NOT cloned.
*
* @param this calling object
* @param my_host new host to set as other_host
*/
void (*update_other_host) (connection_t *this, host_t *other_host);
/**
* @brief Update own ID.
*
* It may be necessary to uptdate own ID, as it
* is set to %any or to e.g. *@strongswan.org in
* some cases.
* Old ID is destroyed, new one NOT cloned.
*
* @param this calling object
* @param my_id new ID to set as my_id
*/
void (*update_my_id) (connection_t *this, identification_t *my_id);
/**
* @brief Update others ID.
*
* It may be necessary to uptdate others ID, as it
* is set to %any or to e.g. *@strongswan.org in
* some cases.
* Old ID is destroyed, new one NOT cloned.
*
* @param this calling object
* @param other_id new ID to set as other_id
*/
void (*update_other_id) (connection_t *this, identification_t *other_id);
/**
* @brief Returns a list of all supported proposals.
*
* Returned list is still owned by connection and MUST NOT
* modified or destroyed.
*
* @param this calling object
* @return list containing all the proposals
*/
linked_list_t *(*get_proposals) (connection_t *this);
/**
* @brief Adds a proposal to the list.
*
* The first added proposal has the highest priority, the last
* added the lowest.
*
* @param this calling object
* @param proposal proposal to add
*/
void (*add_proposal) (connection_t *this, proposal_t *proposal);
/**
* @brief Select a proposed from suggested proposals.
*
* Returned proposal must be destroyed after usage.
*
* @param this calling object
* @param proposals list of proposals to select from
* @return selected proposal, or NULL if none matches.
*/
proposal_t *(*select_proposal) (connection_t *this, linked_list_t *proposals);
/**
* @brief Get the authentication method to use
*
* @param this calling object
* @return authentication method
*/
auth_method_t (*get_auth_method) (connection_t *this);
/**
* @brief Get the connection name.
*
* Name must not be freed, since it points to
* internal data.
*
* @param this calling object
* @return name of the connection
*/
char* (*get_name) (connection_t *this);
/**
* @brief Get the DH group to use for connection initialization.
*
* @param this calling object
* @return dh group to use for initialization
*/
diffie_hellman_group_t (*get_dh_group) (connection_t *this);
/**
* @brief Check if a suggested dh group is acceptable.
*
* If we guess a wrong DH group for IKE_SA_INIT, the other
* peer will send us a offer. But is this acceptable for us?
*
* @param this calling object
* @return TRUE if group acceptable
*/
bool (*check_dh_group) (connection_t *this, diffie_hellman_group_t dh_group);
/**
* @brief Clone a connection_t object.
*
* @param this connection to clone
* @return clone of it
*/
connection_t *(*clone) (connection_t *this);
/**
* @brief Destroys a connection_t object.
*
* @param this calling object
*/
void (*destroy) (connection_t *this);
};
/**
* @brief Creates a connection_t object.
*
* Supplied hosts/IDs become owned by connection, so
* do not modify or destroy them after a call to
* connection_create(). Name gets cloned internally.
*
* @param name connection identifier
* @param my_host host_t representing local address
* @param other_host host_t representing remote address
* @param my_id identification_t for me
* @param other_id identification_t for other
* @param auth_method Authentication method to use for our(!) auth data
* @return connection_t object.
*
* @ingroup config
*/
connection_t * connection_create(char *name,
host_t *my_host, host_t *other_host,
identification_t *my_id,
identification_t *other_id,
auth_method_t auth_method);
#endif /* CONNECTION_H_ */
@@ -0,0 +1,112 @@
/**
* @file connection_store.h
*
* @brief Interface connection_store_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef CONNECTION_STORE_H_
#define CONNECTION_STORE_H_
#include <types.h>
#include <config/connections/connection.h>
typedef struct connection_store_t connection_store_t;
/**
* @brief The interface for a store of connection_t's.
*
* @b Constructors:
* - stroke_create()
*
* @ingroup config
*/
struct connection_store_t {
/**
* @brief Returns a connection definition identified by two IDs.
*
* This call is useful to get a connection which is identified by IDs
* rather than addresses, e.g. for connection setup on user request.
* The returned connection gets created/cloned and therefore must
* be destroyed after usage.
*
* @param this calling object
* @param my_id own ID of connection
* @param other_id others ID of connection
* @return
* - connection_t, if found
* - NULL otherwise
*/
connection_t *(*get_connection_by_ids) (connection_store_t *this, identification_t *my_id, identification_t *other_id);
/**
* @brief Returns a connection definition identified by two hosts.
*
* This call is usefull to get a connection identified by addresses.
* It may be used after kernel request for traffic protection.
* The returned connection gets created/cloned and therefore must
* be destroyed after usage.
*
* @param this calling object
* @param my_id own address of connection
* @param other_id others address of connection
* @return
* - connection_t, if found
* - NULL otherwise
*/
connection_t *(*get_connection_by_hosts) (connection_store_t *this, host_t *my_host, host_t *other_host);
/**
* @brief Returns a connection identified by its name.
*
* This call is usefull to get a connection identified its
* name, as on an connection setup.
*
* @param this calling object
* @param name name of the connection to get
* @return
* - connection_t, if found
* - NULL otherwise
*/
connection_t *(*get_connection_by_name) (connection_store_t *this, char *name);
/**
* @brief Add a connection to the store.
*
* After a successful call, the connection is owned by the store and may
* not be manipulated nor destroyed.
*
* @param this calling object
* @param connection connection to add
* @return
* - SUCCESS, or
* - FAILED
*/
status_t (*add_connection) (connection_store_t *this, connection_t *connection);
/**
* @brief Destroys a connection_store_t object.
*
* @param this calling object
*/
void (*destroy) (connection_store_t *this);
};
#endif /* CONNECTION_STORE_H_ */
@@ -0,0 +1,228 @@
/**
* @file local_connection_store.c
*
* @brief Implementation of local_connection_store_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#include <string.h>
#include "local_connection_store.h"
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
typedef struct private_local_connection_store_t private_local_connection_store_t;
/**
* Private data of an local_connection_store_t object
*/
struct private_local_connection_store_t {
/**
* Public part
*/
local_connection_store_t public;
/**
* stored connection
*/
linked_list_t *connections;
/**
* Assigned logger
*/
logger_t *logger;
};
/**
* Implementation of connection_store_t.get_connection_by_hosts.
*/
static connection_t *get_connection_by_hosts(private_local_connection_store_t *this, host_t *my_host, host_t *other_host)
{
iterator_t *iterator;
connection_t *current, *found = NULL;
this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for hosts %s - %s",
my_host->get_address(my_host), other_host->get_address(other_host));
iterator = this->connections->create_iterator(this->connections, TRUE);
while (iterator->has_next(iterator))
{
host_t *config_my_host, *config_other_host;
iterator->current(iterator, (void**)&current);
config_my_host = current->get_my_host(current);
config_other_host = current->get_other_host(current);
/* first check if ip is equal */
if(config_other_host->ip_equals(config_other_host, other_host))
{
this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote host %s",
config_other_host->get_address(config_other_host));
/* could be right one, check my_host for default route*/
if (config_my_host->is_default_route(config_my_host))
{
found = current->clone(current);
break;
}
/* check now if host informations are the same */
else if (config_my_host->ip_equals(config_my_host,my_host))
{
found = current->clone(current);
break;
}
}
/* Then check for wildcard hosts!
* TODO
* actually its only checked if other host with default route can be found! */
else if (config_other_host->is_default_route(config_other_host))
{
/* could be right one, check my_host for default route*/
if (config_my_host->is_default_route(config_my_host))
{
found = current->clone(current);
break;
}
/* check now if host informations are the same */
else if (config_my_host->ip_equals(config_my_host,my_host))
{
found = current->clone(current);
break;
}
}
}
iterator->destroy(iterator);
/* apply hosts as they are supplied since my_host may be %defaultroute, and other_host may be %any. */
if (found)
{
found->update_my_host(found, my_host->clone(my_host));
found->update_other_host(found, other_host->clone(other_host));
}
return found;
}
/**
* Implementation of connection_store_t.get_connection_by_ids.
*/
static connection_t *get_connection_by_ids(private_local_connection_store_t *this, identification_t *my_id, identification_t *other_id)
{
iterator_t *iterator;
connection_t *current, *found = NULL;
this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for ids %s - %s",
my_id->get_string(my_id), other_id->get_string(other_id));
iterator = this->connections->create_iterator(this->connections, TRUE);
while (iterator->has_next(iterator))
{
identification_t *config_my_id, *config_other_id;
iterator->current(iterator, (void**)&current);
config_my_id = current->get_my_id(current);
config_other_id = current->get_other_id(current);
/* first check if ids are equal
* TODO: Add wildcard checks */
if (config_other_id->equals(config_other_id, other_id) &&
config_my_id->equals(config_my_id, my_id))
{
this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote id %s",
config_other_id->get_string(config_other_id));
found = current->clone(current);
break;
}
}
iterator->destroy(iterator);
return found;
}
/**
* Implementation of connection_store_t.get_connection_by_name.
*/
static connection_t *get_connection_by_name(private_local_connection_store_t *this, char *name)
{
iterator_t *iterator;
connection_t *current, *found = NULL;
iterator = this->connections->create_iterator(this->connections, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&current);
if (strcmp(name, current->get_name(current)) == 0)
{
found = current->clone(current);
break;
}
}
iterator->destroy(iterator);
return found;
}
/**
* Implementation of connection_store_t.add_connection.
*/
static status_t add_connection(private_local_connection_store_t *this, connection_t *connection)
{
this->connections->insert_last(this->connections, connection);
return SUCCESS;
}
/**
* Implementation of connection_store_t.destroy.
*/
static void destroy (private_local_connection_store_t *this)
{
connection_t *connection;
while (this->connections->remove_last(this->connections, (void**)&connection) == SUCCESS)
{
connection->destroy(connection);
}
this->connections->destroy(this->connections);
free(this);
}
/**
* Described in header.
*/
local_connection_store_t * local_connection_store_create()
{
private_local_connection_store_t *this = malloc_thing(private_local_connection_store_t);
this->public.connection_store.get_connection_by_hosts = (connection_t*(*)(connection_store_t*,host_t*,host_t*))get_connection_by_hosts;
this->public.connection_store.get_connection_by_ids = (connection_t*(*)(connection_store_t*,identification_t*,identification_t*))get_connection_by_ids;
this->public.connection_store.get_connection_by_name = (connection_t*(*)(connection_store_t*,char*))get_connection_by_name;
this->public.connection_store.add_connection = (status_t(*)(connection_store_t*,connection_t*))add_connection;
this->public.connection_store.destroy = (void(*)(connection_store_t*))destroy;
/* private variables */
this->connections = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
return (&this->public);
}
@@ -0,0 +1,63 @@
/**
* @file local_connection_store.h
*
* @brief Interface of local_connection_store_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef LOCAL_CONNECTION_H_
#define LOCAL_CONNECTION_H_
#include <types.h>
#include <config/connections/connection_store.h>
typedef struct local_connection_store_t local_connection_store_t;
/**
* @brief A connection_store_t implementation using a simple connection list.
*
* The local_connection_store_t class implements the connection_store_t interface
* as simple as possible. connection_t's are stored in an in-memory list.
*
* @b Constructors:
* - local_connection_store_create()
*
* @todo Make thread-save first
* @todo Add remove_connection method
*
* @ingroup config
*/
struct local_connection_store_t {
/**
* Implements connection_store_t interface
*/
connection_store_t connection_store;
};
/**
* @brief Creates a local_connection_store_t instance.
*
* @return connection store instance.
*
* @ingroup config
*/
local_connection_store_t * local_connection_store_create();
#endif /* LOCAL_CONNECTION_H_ */
@@ -0,0 +1,20 @@
# Copyright (C) 2006 Martin Willi
# Hochschule fuer Technik Rapperswil
#
# 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.
#
CREDENTIALS_DIR= $(CONFIG_DIR)credentials/
CHARON_OBJS+= $(BUILD_DIR)local_credential_store.o
$(BUILD_DIR)local_credential_store.o : $(CREDENTIALS_DIR)local_credential_store.c $(CREDENTIALS_DIR)local_credential_store.h
$(CC) $(CFLAGS) -c -o $@ $<
@@ -0,0 +1,91 @@
/**
* @file credential_store.h
*
* @brief Interface credential_store_t.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef CREDENTIAL_STORE_H_
#define CREDENTIAL_STORE_H_
#include <types.h>
#include <crypto/rsa/rsa_private_key.h>
#include <crypto/rsa/rsa_public_key.h>
#include <utils/identification.h>
typedef struct credential_store_t credential_store_t;
/**
* @brief The interface for a credential_store backend.
*
* @b Constructors:
* - stroke_create()
*
* @ingroup config
*/
struct credential_store_t {
/**
* @brief Returns the preshared secret of a specific ID.
*
* The returned chunk must be destroyed by the caller after usage.
*
* @param this calling object
* @param identification identification_t object identifiying the secret.
* @param[out] preshared_secret the preshared secret will be written there.
* @return
* - NOT_FOUND if no preshared secrets for specific ID could be found
* - SUCCESS
*
* @todo We should use two IDs to query shared secrets, since we want to use different
* keys for different peers...
*/
status_t (*get_shared_secret) (credential_store_t *this, identification_t *identification, chunk_t *preshared_secret);
/**
* @brief Returns the RSA public key of a specific ID.
*
* The returned rsa_public_key_t must be destroyed by the caller after usage.
*
* @param this calling object
* @param identification identification_t object identifiying the key.
* @return public key, or NULL if not found
*/
rsa_public_key_t * (*get_rsa_public_key) (credential_store_t *this, identification_t *identification);
/**
* @brief Returns the RSA private key of a specific ID.
*
* The returned rsa_private_key_t must be destroyed by the caller after usage.
*
* @param this calling object
* @param identification identification_t object identifiying the key
* @return private key, or NULL if not found
*/
rsa_private_key_t *(*get_rsa_private_key) (credential_store_t *this, identification_t *identification);
/**
* @brief Destroys a credential_store_t object.
*
* @param this calling object
*/
void (*destroy) (credential_store_t *this);
};
#endif /*CREDENTIAL_STORE_H_*/
@@ -0,0 +1,315 @@
/**
* @file local_credential_store.c
*
* @brief Implementation of local_credential_store_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#include <sys/stat.h>
#include <dirent.h>
#include "local_credential_store.h"
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <crypto/x509.h>
typedef struct key_entry_t key_entry_t;
/**
* Private key with an associated ID to find it
*/
struct key_entry_t {
/**
* ID, as added
*/
identification_t *id;
/**
* Associated rsa private key
*/
rsa_private_key_t *key;
};
typedef struct private_local_credential_store_t private_local_credential_store_t;
/**
* Private data of an local_credential_store_t object
*/
struct private_local_credential_store_t {
/**
* Public part
*/
local_credential_store_t public;
/**
* list of key_entry_t's with private keys
*/
linked_list_t *private_keys;
/**
* list of x509 certificates with public keys
*/
linked_list_t *certificates;
/**
* Assigned logger
*/
logger_t *logger;
};
/**
* Implementation of credential_store_t.get_shared_secret.
*/
static status_t get_shared_secret(private_local_credential_store_t *this, identification_t *identification, chunk_t *preshared_secret)
{
return FAILED;
}
/**
* Implementation of credential_store_t.get_rsa_public_key.
*/
static rsa_public_key_t * get_rsa_public_key(private_local_credential_store_t *this, identification_t *identification)
{
x509_t *current;
rsa_public_key_t *found = NULL;
iterator_t *iterator;
this->logger->log(this->logger, CONTROL|LEVEL2, "Looking for public key for %s",
identification->get_string(identification));
iterator = this->certificates->create_iterator(this->certificates, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&current);
identification_t *stored = current->get_subject(current);
this->logger->log(this->logger, CONTROL|LEVEL2, "there is one for %s",
stored->get_string(stored));
if (identification->equals(identification, stored))
{
found = current->get_public_key(current);
break;
}
}
iterator->destroy(iterator);
return found;
}
/**
* Implementation of credential_store_t.get_rsa_private_key.
*/
static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t *this, identification_t *identification)
{
rsa_private_key_t *found = NULL;
key_entry_t *current;
iterator_t *iterator;
iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&current);
if (identification->equals(identification, current->id))
{
found = current->key->clone(current->key);
break;
}
}
iterator->destroy(iterator);
return found;
}
/**
* Implements local_credential_store_t.load_private_keys
*/
static void load_certificates(private_local_credential_store_t *this, char *path)
{
struct dirent* entry;
struct stat stb;
DIR* dir;
x509_t *cert;
dir = opendir(path);
if (dir == NULL) {
this->logger->log(this->logger, ERROR, "error opening certificate directory \"%s\"", path);
return;
}
while ((entry = readdir(dir)) != NULL)
{
char file[256];
snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
if (stat(file, &stb) == -1)
{
continue;
}
/* try to parse all regular files */
if (stb.st_mode & S_IFREG)
{
cert = x509_create_from_file(file);
if (cert)
{
this->certificates->insert_last(this->certificates, (void*)cert);
this->logger->log(this->logger, CONTROL|LEVEL1, "loaded certificate \"%s\"", file);
}
else
{
this->logger->log(this->logger, ERROR, "certificate \"%s\" invalid, skipped", file);
}
}
}
closedir(dir);
}
/**
* Query the ID for a private key, by doing a lookup in the certificates
*/
static identification_t *get_id_for_private_key(private_local_credential_store_t *this, rsa_private_key_t *private_key)
{
iterator_t *iterator;
x509_t *cert;
identification_t *found = NULL;
rsa_public_key_t *public_key;
this->logger->log(this->logger, CONTROL|LEVEL2, "Getting ID for a private key...");
iterator = this->certificates->create_iterator(this->certificates, TRUE);
while (!found && iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&cert);
public_key = cert->get_public_key(cert);
if (public_key)
{
if (private_key->belongs_to(private_key, public_key))
{
this->logger->log(this->logger, CONTROL|LEVEL2, "found a match");
found = cert->get_subject(cert);
found = found->clone(found);
}
else
{
this->logger->log(this->logger, CONTROL|LEVEL3, "this one did not match");
}
public_key->destroy(public_key);
}
}
iterator->destroy(iterator);
return found;
}
/**
* Implements local_credential_store_t.load_private_keys
*/
static void load_private_keys(private_local_credential_store_t *this, char *path)
{
struct dirent* entry;
struct stat stb;
DIR* dir;
rsa_private_key_t *key;
dir = opendir(path);
if (dir == NULL) {
this->logger->log(this->logger, ERROR, "error opening private key directory \"%s\"", path);
return;
}
while ((entry = readdir(dir)) != NULL)
{
char file[256];
snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
if (stat(file, &stb) == -1)
{
continue;
}
/* try to parse all regular files */
if (stb.st_mode & S_IFREG)
{
key = rsa_private_key_create_from_file(file, NULL);
if (key)
{
key_entry_t *entry;
identification_t *id = get_id_for_private_key(this, key);
if (!id)
{
this->logger->log(this->logger, ERROR,
"no certificate found for private key \"%s\", skipped", file);
key->destroy(key);
continue;
}
entry = malloc_thing(key_entry_t);
entry->key = key;
entry->id = id;
this->private_keys->insert_last(this->private_keys, (void*)entry);
this->logger->log(this->logger, CONTROL|LEVEL1, "loaded private key \"%s\"", file);
}
else
{
this->logger->log(this->logger, ERROR, "private key \"%s\" invalid, skipped", file);
}
}
}
closedir(dir);
}
/**
* Implementation of credential_store_t.destroy.
*/
static void destroy(private_local_credential_store_t *this)
{
x509_t *certificate;
key_entry_t *key_entry;
while (this->certificates->remove_last(this->certificates, (void**)&certificate) == SUCCESS)
{
certificate->destroy(certificate);
}
this->certificates->destroy(this->certificates);
while (this->private_keys->remove_last(this->private_keys, (void**)&key_entry) == SUCCESS)
{
key_entry->id->destroy(key_entry->id);
key_entry->key->destroy(key_entry->key);
free(key_entry);
}
this->private_keys->destroy(this->private_keys);
free(this);
}
/**
* Described in header.
*/
local_credential_store_t * local_credential_store_create()
{
private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
this->public.credential_store.get_shared_secret = (status_t(*)(credential_store_t*,identification_t*,chunk_t*))get_shared_secret;
this->public.credential_store.get_rsa_private_key = (rsa_private_key_t*(*)(credential_store_t*,identification_t*))get_rsa_private_key;
this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
this->public.load_certificates = (void(*)(local_credential_store_t*,char*))load_certificates;
this->public.load_private_keys = (void(*)(local_credential_store_t*,char*))load_private_keys;
this->public.credential_store.destroy = (void(*)(credential_store_t*))destroy;
/* private variables */
this->private_keys = linked_list_create();
this->certificates = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
return (&this->public);
}
@@ -0,0 +1,84 @@
/**
* @file local_credential_store.h
*
* @brief Interface of local_credential_store_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef LOCAL_CREDENTIAL_H_
#define LOCAL_CREDENTIAL_H_
#include <types.h>
#include <config/credentials/credential_store.h>
typedef struct local_credential_store_t local_credential_store_t;
/**
* @brief A credential_store_t implementation using simple credentail lists.
*
* The local_credential_store_t class implements the credential_store_t interface
* as simple as possible. The credentials are stored in lists, and can be loaded
* from folders.
* Shared secret are not handled yet, so get_shared_secret always returns NOT_FOUND.
*
* @b Constructors:
* - local_credential_store_create()
*
* @ingroup config
*/
struct local_credential_store_t {
/**
* Implements credential_store_t interface
*/
credential_store_t credential_store;
/**
* @brief Loads trusted certificates from a folder.
*
* Currently, all keys must be in binary DER format.
*
* @param this calling object
* @param path directory to load certificates from
*/
void (*load_certificates) (local_credential_store_t *this, char *path);
/**
* @brief Loads RSA private keys from a folder.
*
* Currently, all keys must be unencrypted in binary DER format. Anything
* other gets ignored. Further, a certificate for the specific private
* key must already be loaded to get the ID from.
*
* @param this calling object
* @param path directory to load keys from
*/
void (*load_private_keys) (local_credential_store_t *this, char *path);
};
/**
* @brief Creates a local_credential_store_t instance.
*
* @return credential store instance.
*
* @ingroup config
*/
local_credential_store_t *local_credential_store_create();
#endif /* LOCAL_CREDENTIAL_H_ */
@@ -0,0 +1,24 @@
# Copyright (C) 2006 Martin Willi
# Hochschule fuer Technik Rapperswil
#
# 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.
#
POLICIES_DIR= $(CONFIG_DIR)policies/
CHARON_OBJS+= $(BUILD_DIR)policy.o
$(BUILD_DIR)policy.o : $(POLICIES_DIR)policy.c $(POLICIES_DIR)policy.h
$(CC) $(CFLAGS) -c -o $@ $<
CHARON_OBJS+= $(BUILD_DIR)local_policy_store.o
$(BUILD_DIR)local_policy_store.o : $(POLICIES_DIR)local_policy_store.c $(POLICIES_DIR)local_policy_store.h
$(CC) $(CFLAGS) -c -o $@ $<
@@ -0,0 +1,136 @@
/**
* @file local_policy_store.c
*
* @brief Implementation of local_policy_store_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#include "local_policy_store.h"
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
typedef struct private_local_policy_store_t private_local_policy_store_t;
/**
* Private data of an local_policy_store_t object
*/
struct private_local_policy_store_t {
/**
* Public part
*/
local_policy_store_t public;
/**
* list of policy_t's
*/
linked_list_t *policies;
/**
* Assigned logger
*/
logger_t *logger;
};
/**
* Implementation of policy_store_t.add_policy.
*/
static void add_policy(private_local_policy_store_t *this, policy_t *policy)
{
this->policies->insert_last(this->policies, (void*)policy);
}
/**
* Implementation of policy_store_t.get_policy.
*/
static policy_t *get_policy(private_local_policy_store_t *this, identification_t *my_id, identification_t *other_id)
{
iterator_t *iterator;
policy_t *current, *found = NULL;
this->logger->log(this->logger, CONTROL|LEVEL1, "Looking for policy for IDs %s - %s",
my_id ? my_id->get_string(my_id) : "%any",
other_id->get_string(other_id));
iterator = this->policies->create_iterator(this->policies, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void **)&current);
identification_t *config_my_id = current->get_my_id(current);
identification_t *config_other_id = current->get_other_id(current);
this->logger->log(this->logger, CONTROL|LEVEL2, "Found one for %s - %s",
config_my_id->get_string(config_my_id),
config_other_id->get_string(config_other_id));
/* check other host first */
if (other_id->belongs_to(other_id, config_other_id))
{
/* get it if my_id not specified */
if (my_id->belongs_to(my_id, config_my_id))
{
found = current->clone(current);
break;
}
}
}
iterator->destroy(iterator);
/* apply IDs as they are requsted, since they may be configured as %any or such */
if (found)
{
found->update_my_id(found, my_id->clone(my_id));
found->update_other_id(found, other_id->clone(other_id));
}
return found;
}
/**
* Implementation of policy_store_t.destroy.
*/
static void destroy(private_local_policy_store_t *this)
{
policy_t *policy;
while (this->policies->remove_last(this->policies, (void**)&policy) == SUCCESS)
{
policy->destroy(policy);
}
this->policies->destroy(this->policies);
free(this);
}
/**
* Described in header.
*/
local_policy_store_t *local_policy_store_create()
{
private_local_policy_store_t *this = malloc_thing(private_local_policy_store_t);
this->public.policy_store.add_policy = (void(*)(policy_store_t*,policy_t*))add_policy;
this->public.policy_store.get_policy = (policy_t*(*)(policy_store_t*,identification_t*,identification_t*))get_policy;
this->public.policy_store.destroy = (void(*)(policy_store_t*))destroy;
/* private variables */
this->policies = linked_list_create();
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
return (&this->public);
}
@@ -0,0 +1,60 @@
/**
* @file local_policy_store.h
*
* @brief Interface of local_policy_store_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef LOCAL_POLICY_STORE_H_
#define LOCAL_POLICY_STORE_H_
#include <types.h>
#include <config/policies/policy_store.h>
typedef struct local_policy_store_t local_policy_store_t;
/**
* @brief A policy_store_t implementation using a simple policy lists.
*
* The local_policy_store_t class implements the policy_store_t interface
* as simple as possible. The policies are stored in a in-memory list.
*
* @b Constructors:
* - local_policy_store_create()
*
* @ingroup config
*/
struct local_policy_store_t {
/**
* Implements policy_store_t interface
*/
policy_store_t policy_store;
};
/**
* @brief Creates a local_policy_store_t instance.
*
* @return policy store instance.
*
* @ingroup config
*/
local_policy_store_t *local_policy_store_create();
#endif /* LOCAL_POLICY_STORE_H_ */
@@ -0,0 +1,397 @@
/**
* @file policy.c
*
* @brief Implementation of policy_t.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#include "policy.h"
#include <utils/linked_list.h>
#include <utils/identification.h>
#include <utils/logger.h>
typedef struct private_policy_t private_policy_t;
/**
* Private data of an policy_t object
*/
struct private_policy_t {
/**
* Public part
*/
policy_t public;
/**
* id to use to identify us
*/
identification_t *my_id;
/**
* allowed id for other
*/
identification_t *other_id;
/**
* list for all proposals
*/
linked_list_t *proposals;
/**
* list for traffic selectors for my site
*/
linked_list_t *my_ts;
/**
* list for traffic selectors for others site
*/
linked_list_t *other_ts;
/**
* select_traffic_selectors for both
*/
linked_list_t *(*select_traffic_selectors) (private_policy_t *,linked_list_t*,linked_list_t*);
};
/**
* Implementation of policy_t.get_my_id
*/
static identification_t *get_my_id(private_policy_t *this)
{
return this->my_id;
}
/**
* Implementation of policy_t.get_other_id
*/
static identification_t *get_other_id(private_policy_t *this)
{
return this->other_id;
}
/**
* Implementation of policy_t.update_my_id
*/
static void update_my_id(private_policy_t *this, identification_t *my_id)
{
this->my_id->destroy(this->my_id);
this->my_id = my_id;
}
/**
* Implementation of policy_t.update_other_id
*/
static void update_other_id(private_policy_t *this, identification_t *other_id)
{
this->other_id->destroy(this->other_id);
this->other_id = other_id;
}
/**
* Helper function which does the work for policy_t.update_my_ts and update_other_ts
*/
static void update_ts(linked_list_t* list, host_t *new_host)
{
traffic_selector_t *ts;
iterator_t *iterator;
iterator = list->create_iterator(list, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&ts);
ts->update_address_range(ts, new_host);
}
iterator->destroy(iterator);
}
/**
* Implementation of policy_t.update_my_id
*/
static void update_my_ts(private_policy_t *this, host_t *my_host)
{
update_ts(this->my_ts, my_host);
}
/**
* Implementation of policy_t.update_other_ts
*/
static void update_other_ts(private_policy_t *this, host_t *my_host)
{
update_ts(this->other_ts, my_host);
}
/**
* Implementation of policy_t.get_my_traffic_selectors
*/
static linked_list_t *get_my_traffic_selectors(private_policy_t *this)
{
return this->my_ts;
}
/**
* Implementation of policy_t.get_other_traffic_selectors
*/
static linked_list_t *get_other_traffic_selectors(private_policy_t *this, traffic_selector_t **traffic_selectors[])
{
return this->other_ts;
}
/**
* Implementation of private_policy_t.select_my_traffic_selectors
*/
static linked_list_t *select_my_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
{
return this->select_traffic_selectors(this, this->my_ts, supplied);
}
/**
* Implementation of private_policy_t.select_other_traffic_selectors
*/
static linked_list_t *select_other_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
{
return this->select_traffic_selectors(this, this->other_ts, supplied);
}
/**
* Implementation of private_policy_t.select_traffic_selectors
*/
static linked_list_t *select_traffic_selectors(private_policy_t *this, linked_list_t *stored, linked_list_t *supplied)
{
iterator_t *supplied_iter, *stored_iter;
traffic_selector_t *supplied_ts, *stored_ts, *selected_ts;
linked_list_t *selected = linked_list_create();
stored_iter = stored->create_iterator(stored, TRUE);
supplied_iter = supplied->create_iterator(supplied, TRUE);
/* iterate over all stored selectors */
while (stored_iter->has_next(stored_iter))
{
stored_iter->current(stored_iter, (void**)&stored_ts);
supplied_iter->reset(supplied_iter);
/* iterate over all supplied traffic selectors */
while (supplied_iter->has_next(supplied_iter))
{
supplied_iter->current(supplied_iter, (void**)&supplied_ts);
selected_ts = stored_ts->get_subset(stored_ts, supplied_ts);
if (selected_ts)
{
/* got a match, add to list */
selected->insert_last(selected, (void*)selected_ts);
}
}
}
stored_iter->destroy(stored_iter);
supplied_iter->destroy(supplied_iter);
return selected;
}
/**
* Implementation of policy_t.get_proposal_iterator
*/
static linked_list_t *get_proposals(private_policy_t *this)
{
return this->proposals;
}
/**
* Implementation of policy_t.select_proposal
*/
static proposal_t *select_proposal(private_policy_t *this, linked_list_t *proposals)
{
iterator_t *stored_iter, *supplied_iter;
proposal_t *stored, *supplied, *selected;
stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
supplied_iter = proposals->create_iterator(proposals, TRUE);
/* compare all stored proposals with all supplied. Stored ones are preferred. */
while (stored_iter->has_next(stored_iter))
{
supplied_iter->reset(supplied_iter);
stored_iter->current(stored_iter, (void**)&stored);
while (supplied_iter->has_next(supplied_iter))
{
supplied_iter->current(supplied_iter, (void**)&supplied);
selected = stored->select(stored, supplied);
if (selected)
{
/* they match, return */
stored_iter->destroy(stored_iter);
supplied_iter->destroy(supplied_iter);
return selected;
}
}
}
/* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
stored_iter->destroy(stored_iter);
supplied_iter->destroy(supplied_iter);
return NULL;
}
/**
* Implementation of policy_t.add_my_traffic_selector
*/
static void add_my_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector)
{
this->my_ts->insert_last(this->my_ts, (void*)traffic_selector);
}
/**
* Implementation of policy_t.add_other_traffic_selector
*/
static void add_other_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector)
{
this->other_ts->insert_last(this->other_ts, (void*)traffic_selector);
}
/**
* Implementation of policy_t.add_proposal
*/
static void add_proposal(private_policy_t *this, proposal_t *proposal)
{
this->proposals->insert_last(this->proposals, (void*)proposal);
}
/**
* Implements policy_t.destroy.
*/
static status_t destroy(private_policy_t *this)
{
proposal_t *proposal;
traffic_selector_t *traffic_selector;
/* delete proposals */
while(this->proposals->remove_last(this->proposals, (void**)&proposal) == SUCCESS)
{
proposal->destroy(proposal);
}
this->proposals->destroy(this->proposals);
/* delete traffic selectors */
while(this->my_ts->remove_last(this->my_ts, (void**)&traffic_selector) == SUCCESS)
{
traffic_selector->destroy(traffic_selector);
}
this->my_ts->destroy(this->my_ts);
/* delete traffic selectors */
while(this->other_ts->remove_last(this->other_ts, (void**)&traffic_selector) == SUCCESS)
{
traffic_selector->destroy(traffic_selector);
}
this->other_ts->destroy(this->other_ts);
/* delete ids */
this->my_id->destroy(this->my_id);
this->other_id->destroy(this->other_id);
free(this);
return SUCCESS;
}
/**
* Implements policy_t.clone.
*/
static policy_t *clone(private_policy_t *this)
{
private_policy_t *clone = (private_policy_t*)policy_create(this->my_id->clone(this->my_id),
this->other_id->clone(this->other_id));
iterator_t *iterator;
proposal_t *proposal;
traffic_selector_t *ts;
/* clone all proposals */
iterator = this->proposals->create_iterator(this->proposals, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&proposal);
proposal = proposal->clone(proposal);
clone->proposals->insert_last(clone->proposals, (void*)proposal);
}
iterator->destroy(iterator);
/* clone all local traffic selectors */
iterator = this->my_ts->create_iterator(this->my_ts, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&ts);
ts = ts->clone(ts);
clone->my_ts->insert_last(clone->my_ts, (void*)ts);
}
iterator->destroy(iterator);
/* clone all remote traffic selectors */
iterator = this->other_ts->create_iterator(this->other_ts, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&ts);
ts = ts->clone(ts);
clone->other_ts->insert_last(clone->other_ts, (void*)ts);
}
iterator->destroy(iterator);
return &clone->public;
}
/*
* Described in header-file
*/
policy_t *policy_create(identification_t *my_id, identification_t *other_id)
{
private_policy_t *this = malloc_thing(private_policy_t);
/* public functions */
this->public.get_my_id = (identification_t*(*)(policy_t*))get_my_id;
this->public.get_other_id = (identification_t*(*)(policy_t*))get_other_id;
this->public.update_my_id = (void(*)(policy_t*,identification_t*))update_my_id;
this->public.update_other_id = (void(*)(policy_t*,identification_t*))update_other_id;
this->public.update_my_ts = (void(*)(policy_t*,host_t*))update_my_ts;
this->public.update_other_ts = (void(*)(policy_t*,host_t*))update_other_ts;
this->public.get_my_traffic_selectors = (linked_list_t*(*)(policy_t*))get_my_traffic_selectors;
this->public.select_my_traffic_selectors = (linked_list_t*(*)(policy_t*,linked_list_t*))select_my_traffic_selectors;
this->public.get_other_traffic_selectors = (linked_list_t*(*)(policy_t*))get_other_traffic_selectors;
this->public.select_other_traffic_selectors = (linked_list_t*(*)(policy_t*,linked_list_t*))select_other_traffic_selectors;
this->public.get_proposals = (linked_list_t*(*)(policy_t*))get_proposals;
this->public.select_proposal = (proposal_t*(*)(policy_t*,linked_list_t*))select_proposal;
this->public.add_my_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_my_traffic_selector;
this->public.add_other_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_other_traffic_selector;
this->public.add_proposal = (void(*)(policy_t*,proposal_t*))add_proposal;
this->public.clone = (policy_t*(*)(policy_t*))clone;
this->public.destroy = (void(*)(policy_t*))destroy;
/* apply init values */
this->my_id = my_id;
this->other_id = other_id;
/* init private members*/
this->select_traffic_selectors = select_traffic_selectors;
this->proposals = linked_list_create();
this->my_ts = linked_list_create();
this->other_ts = linked_list_create();
return (&this->public);
}
@@ -0,0 +1,249 @@
/**
* @file policy.h
*
* @brief Interface of policy_t.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef POLICY_H_
#define POLICY_H_
#include <types.h>
#include <utils/identification.h>
#include <config/traffic_selector.h>
#include <config/proposal.h>
#include <encoding/payloads/auth_payload.h>
typedef struct policy_t policy_t;
/**
* @brief A policy_t defines the policies to apply to CHILD_SAs.
*
* The given two IDs identify a policy. These rules define how
* child SAs may be set up and which traffic may be IPsec'ed.
*
* @b Constructors:
* - policy_create()
*
* @ingroup config
*/
struct policy_t {
/**
* @brief Get own id to use for identification.
*
* Returned object is not getting cloned.
*
* @param this calling object
* @return own id
*/
identification_t *(*get_my_id) (policy_t *this);
/**
* @brief Get id of communication partner.
*
* Returned object is not getting cloned.
*
* @param this calling object
* @return other id
*/
identification_t *(*get_other_id) (policy_t *this);
/**
* @brief Update own ID.
*
* It may be necessary to uptdate own ID, as it
* is set to %any or to e.g. *@strongswan.org in
* some cases.
* Old ID is destroyed, new one NOT cloned.
*
* @param this calling object
* @param my_id new ID to set as my_id
*/
void (*update_my_id) (policy_t *this, identification_t *my_id);
/**
* @brief Update others ID.
*
* It may be necessary to uptdate others ID, as it
* is set to %any or to e.g. *@strongswan.org in
* some cases.
* Old ID is destroyed, new one NOT cloned.
*
* @param this calling object
* @param other_id new ID to set as other_id
*/
void (*update_other_id) (policy_t *this, identification_t *other_id);
/**
* @brief Update own address in traffic selectors.
*
* Update own 0.0.0.0 address in traffic selectors
* with supplied one. The size of the subnet will be
* set to /32.
*
* @param this calling object
* @param my_host new address to set in traffic selectors
*/
void (*update_my_ts) (policy_t *this, host_t *my_host);
/**
* @brief Update others address in traffic selectors.
*
* Update remote 0.0.0.0 address in traffic selectors
* with supplied one. The size of the subnet will be
* set to /32.
*
* @param this calling object
* @param other_host new address to set in traffic selectors
*/
void (*update_other_ts) (policy_t *this, host_t *other_host);
/**
* @brief Get configured traffic selectors for our site.
*
* Returns a list with all traffic selectors for the local
* site. List and items MUST NOT be freed nor modified.
*
* @param this calling object
* @return list with traffic selectors
*/
linked_list_t *(*get_my_traffic_selectors) (policy_t *this);
/**
* @brief Get configured traffic selectors for others site.
*
* Returns a list with all traffic selectors for the remote
* site. List and items MUST NOT be freed nor modified.
*
* @param this calling object
* @return list with traffic selectors
*/
linked_list_t *(*get_other_traffic_selectors) (policy_t *this);
/**
* @brief Select traffic selectors from a supplied list for local site.
*
* Resulted list and traffic selectors must be destroyed after usage.
*
* @param this calling object
* @param supplied linked list with traffic selectors
* @return list containing the selected traffic selectors
*/
linked_list_t *(*select_my_traffic_selectors) (policy_t *this, linked_list_t *supplied);
/**
* @brief Select traffic selectors from a supplied list for remote site.
*
* Resulted list and traffic selectors must be destroyed after usage.
*
* @param this calling object
* @param supplied linked list with traffic selectors
* @return list containing the selected traffic selectors
*/
linked_list_t *(*select_other_traffic_selectors) (policy_t *this, linked_list_t *supplied);
/**
* @brief Get the list of internally stored proposals.
*
* Rembember: policy_t does store proposals for AH/ESP,
* IKE proposals are in the connection_t
*
* @warning List and Items are still owned by policy and MUST NOT
* be manipulated or freed!
*
* @param this calling object
* @return lists with proposals
*/
linked_list_t *(*get_proposals) (policy_t *this);
/**
* @brief Select a proposal from a supplied list.
*
* @param this calling object
* @param proposals list from from wich proposals are selected
* @return selected proposal, or NULL if nothing matches
*/
proposal_t *(*select_proposal) (policy_t *this, linked_list_t *proposals);
/**
* @brief Add a traffic selector to the list for local site.
*
* After add, proposal is owned by policy.
*
* @warning Do not add while other threads are reading.
*
* @param this calling object
* @param traffic_selector traffic_selector to add
*/
void (*add_my_traffic_selector) (policy_t *this, traffic_selector_t *traffic_selector);
/**
* @brief Add a traffic selector to the list for remote site.
*
* After add, proposal is owned by policy.
*
* @warning Do not add while other threads are reading.
*
* @param this calling object
* @param traffic_selector traffic_selector to add
*/
void (*add_other_traffic_selector) (policy_t *this, traffic_selector_t *traffic_selector);
/**
* @brief Add a proposal to the list.
*
* The proposals are stored by priority, first added
* is the most prefered.
*
* @warning Do not add while other threads are reading.
*
* @param this calling object
* @param proposal proposal to add
*/
void (*add_proposal) (policy_t *this, proposal_t *proposal);
/**
* @brief Clone a policy.
*
* @param this policy to clone
* @return clone of it
*/
policy_t *(*clone) (policy_t *this);
/**
* @brief Destroys the policy object
*
* @param this calling object
*/
void (*destroy) (policy_t *this);
};
/**
* @brief Create a configuration object for IKE_AUTH and later.
*
* @param my_id identification_t for ourselves
* @param other_id identification_t for the remote guy
* @return policy_t object
*
* @ingroup config
*/
policy_t *policy_create(identification_t *my_id, identification_t *other_id);
#endif /* POLICY_H_ */
+76
View File
@@ -0,0 +1,76 @@
/**
* @file policy_store.h
*
* @brief Interface policy_store_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef POLICY_STORE_H_
#define POLICY_STORE_H_
#include <types.h>
#include <config/policies/policy.h>
typedef struct policy_store_t policy_store_t;
/**
* @brief The interface for a store of policy_t's.
*
* @b Constructors:
* - stroke_create()
*
* @ingroup config
*/
struct policy_store_t {
/**
* @brief Returns a policy identified by two IDs.
*
* The returned policy gets created/cloned and therefore must be
* destroyed by the caller.
*
* @param this calling object
* @param my_id own ID of the policy
* @param other_id others ID of the policy
* @return
* - matching policy_t, if found
* - NULL otherwise
*/
policy_t *(*get_policy) (policy_store_t *this, identification_t *my_id, identification_t *other_id);
/**
* @brief Add a policy to the list.
*
* The policy is owned by the store after the call. Do
* not modify nor free.
*
* @param this calling object
* @param policy policy to add
*/
void (*add_policy) (policy_store_t *this, policy_t *policy);
/**
* @brief Destroys a policy_store_t object.
*
* @param this calling object
*/
void (*destroy) (policy_store_t *this);
};
#endif /*POLICY_STORE_H_*/
+642
View File
@@ -0,0 +1,642 @@
/**
* @file proposal.c
*
* @brief Implementation of proposal_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#include <string.h>
#include "proposal.h"
#include <utils/linked_list.h>
#include <utils/identification.h>
#include <utils/logger.h>
/**
* String mappings for protocol_id_t.
*/
mapping_t protocol_id_m[] = {
{PROTO_NONE, "PROTO_NONE"},
{PROTO_IKE, "PROTO_IKE"},
{PROTO_AH, "PROTO_AH"},
{PROTO_ESP, "PROTO_ESP"},
{MAPPING_END, NULL}
};
/**
* String mappings for transform_type_t.
*/
mapping_t transform_type_m[] = {
{UNDEFINED_TRANSFORM_TYPE, "UNDEFINED_TRANSFORM_TYPE"},
{ENCRYPTION_ALGORITHM, "ENCRYPTION_ALGORITHM"},
{PSEUDO_RANDOM_FUNCTION, "PSEUDO_RANDOM_FUNCTION"},
{INTEGRITY_ALGORITHM, "INTEGRITY_ALGORITHM"},
{DIFFIE_HELLMAN_GROUP, "DIFFIE_HELLMAN_GROUP"},
{EXTENDED_SEQUENCE_NUMBERS, "EXTENDED_SEQUENCE_NUMBERS"},
{MAPPING_END, NULL}
};
/**
* String mappings for extended_sequence_numbers_t.
*/
mapping_t extended_sequence_numbers_m[] = {
{NO_EXT_SEQ_NUMBERS, "NO_EXT_SEQ_NUMBERS"},
{EXT_SEQ_NUMBERS, "EXT_SEQ_NUMBERS"},
{MAPPING_END, NULL}
};
typedef struct protocol_proposal_t protocol_proposal_t;
/**
* substructure which holds all data algos for a specific protocol
*/
struct protocol_proposal_t {
/**
* protocol (ESP or AH)
*/
protocol_id_t protocol;
/**
* priority ordered list of encryption algorithms
*/
linked_list_t *encryption_algos;
/**
* priority ordered list of integrity algorithms
*/
linked_list_t *integrity_algos;
/**
* priority ordered list of pseudo random functions
*/
linked_list_t *prf_algos;
/**
* priority ordered list of dh groups
*/
linked_list_t *dh_groups;
/**
* priority ordered list of extended sequence number flags
*/
linked_list_t *esns;
/**
* senders SPI
*/
chunk_t spi;
};
typedef struct private_proposal_t private_proposal_t;
/**
* Private data of an proposal_t object
*/
struct private_proposal_t {
/**
* Public part
*/
proposal_t public;
/**
* number of this proposal, as used in the payload
*/
u_int8_t number;
/**
* list of protocol_proposal_t's
*/
linked_list_t *protocol_proposals;
};
/**
* Look up a protocol_proposal, or create one if necessary...
*/
static protocol_proposal_t *get_protocol_proposal(private_proposal_t *this, protocol_id_t proto, bool create)
{
protocol_proposal_t *proto_proposal = NULL, *current_proto_proposal;;
iterator_t *iterator;
/* find our protocol in the proposals */
iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&current_proto_proposal);
if (current_proto_proposal->protocol == proto)
{
proto_proposal = current_proto_proposal;
break;
}
}
iterator->destroy(iterator);
if (!proto_proposal && create)
{
/* nope, create a new one */
proto_proposal = malloc_thing(protocol_proposal_t);
proto_proposal->protocol = proto;
proto_proposal->encryption_algos = linked_list_create();
proto_proposal->integrity_algos = linked_list_create();
proto_proposal->prf_algos = linked_list_create();
proto_proposal->dh_groups = linked_list_create();
proto_proposal->esns = linked_list_create();
if (proto == PROTO_IKE)
{
proto_proposal->spi.len = 8;
}
else
{
proto_proposal->spi.len = 4;
}
proto_proposal->spi.ptr = malloc(proto_proposal->spi.len);
/* add to the list */
this->protocol_proposals->insert_last(this->protocol_proposals, (void*)proto_proposal);
}
return proto_proposal;
}
/**
* Add algorithm/keysize to a algorithm list
*/
static void add_algo(linked_list_t *list, u_int8_t algo, size_t key_size)
{
algorithm_t *algo_key = malloc_thing(algorithm_t);
algo_key->algorithm = algo;
algo_key->key_size = key_size;
list->insert_last(list, (void*)algo_key);
}
/**
* Implements proposal_t.add_algorithm
*/
static void add_algorithm(private_proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t algo, size_t key_size)
{
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, TRUE);
switch (type)
{
case ENCRYPTION_ALGORITHM:
add_algo(proto_proposal->encryption_algos, algo, key_size);
break;
case INTEGRITY_ALGORITHM:
add_algo(proto_proposal->integrity_algos, algo, key_size);
break;
case PSEUDO_RANDOM_FUNCTION:
add_algo(proto_proposal->prf_algos, algo, key_size);
break;
case DIFFIE_HELLMAN_GROUP:
add_algo(proto_proposal->dh_groups, algo, 0);
break;
case EXTENDED_SEQUENCE_NUMBERS:
add_algo(proto_proposal->esns, algo, 0);
break;
default:
break;
}
}
/**
* Implements proposal_t.get_algorithm.
*/
static bool get_algorithm(private_proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo)
{
linked_list_t * list;
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
if (proto_proposal == NULL)
{
return FALSE;
}
switch (type)
{
case ENCRYPTION_ALGORITHM:
list = proto_proposal->encryption_algos;
break;
case INTEGRITY_ALGORITHM:
list = proto_proposal->integrity_algos;
break;
case PSEUDO_RANDOM_FUNCTION:
list = proto_proposal->prf_algos;
break;
case DIFFIE_HELLMAN_GROUP:
list = proto_proposal->dh_groups;
break;
case EXTENDED_SEQUENCE_NUMBERS:
list = proto_proposal->esns;
break;
default:
return FALSE;
}
if (list->get_first(list, (void**)algo) != SUCCESS)
{
return FALSE;
}
return TRUE;
}
/**
* Implements proposal_t.create_algorithm_iterator.
*/
static iterator_t *create_algorithm_iterator(private_proposal_t *this, protocol_id_t proto, transform_type_t type)
{
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
if (proto_proposal == NULL)
{
return NULL;
}
switch (type)
{
case ENCRYPTION_ALGORITHM:
return proto_proposal->encryption_algos->create_iterator(proto_proposal->encryption_algos, TRUE);
case INTEGRITY_ALGORITHM:
return proto_proposal->integrity_algos->create_iterator(proto_proposal->integrity_algos, TRUE);
case PSEUDO_RANDOM_FUNCTION:
return proto_proposal->prf_algos->create_iterator(proto_proposal->prf_algos, TRUE);
case DIFFIE_HELLMAN_GROUP:
return proto_proposal->dh_groups->create_iterator(proto_proposal->dh_groups, TRUE);
case EXTENDED_SEQUENCE_NUMBERS:
return proto_proposal->esns->create_iterator(proto_proposal->esns, TRUE);
default:
break;
}
return NULL;
}
/**
* Find a matching alg/keysize in two linked lists
*/
static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add, u_int16_t *alg, size_t *key_size)
{
iterator_t *first_iter, *second_iter;
algorithm_t *first_alg, *second_alg;
/* if in both are zero algorithms specified, we HAVE a match */
if (first->get_count(first) == 0 && second->get_count(second) == 0)
{
*add = FALSE;
return TRUE;
}
first_iter = first->create_iterator(first, TRUE);
second_iter = second->create_iterator(second, TRUE);
/* compare algs, order of algs in "first" is preferred */
while (first_iter->has_next(first_iter))
{
first_iter->current(first_iter, (void**)&first_alg);
second_iter->reset(second_iter);
while (second_iter->has_next(second_iter))
{
second_iter->current(second_iter, (void**)&second_alg);
if (first_alg->algorithm == second_alg->algorithm &&
first_alg->key_size == second_alg->key_size)
{
/* ok, we have an algorithm */
*alg = first_alg->algorithm;
*key_size = first_alg->key_size;
*add = TRUE;
first_iter->destroy(first_iter);
second_iter->destroy(second_iter);
return TRUE;
}
}
}
/* no match in all comparisons */
first_iter->destroy(first_iter);
second_iter->destroy(second_iter);
return FALSE;
}
/**
* Implements proposal_t.select.
*/
static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t *other)
{
proposal_t *selected;
u_int16_t algo;
size_t key_size;
iterator_t *iterator;
protocol_proposal_t *this_prop, *other_prop;
protocol_id_t proto;
bool add;
u_int64_t spi;
/* empty proposal? no match */
if (this->protocol_proposals->get_count(this->protocol_proposals) == 0 ||
other->protocol_proposals->get_count(other->protocol_proposals) == 0)
{
return NULL;
}
/* they MUST have the same amount of protocols */
if (this->protocol_proposals->get_count(this->protocol_proposals) !=
other->protocol_proposals->get_count(other->protocol_proposals))
{
return NULL;
}
selected = proposal_create(this->number);
/* iterate over supplied proposals */
iterator = other->protocol_proposals->create_iterator(other->protocol_proposals, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&other_prop);
/* get the proposal with the same protocol */
proto = other_prop->protocol;
this_prop = get_protocol_proposal(this, proto, FALSE);
if (this_prop == NULL)
{
iterator->destroy(iterator);
selected->destroy(selected);
return NULL;
}
/* select encryption algorithm */
if (select_algo(this_prop->encryption_algos, other_prop->encryption_algos, &add, &algo, &key_size))
{
if (add)
{
selected->add_algorithm(selected, proto, ENCRYPTION_ALGORITHM, algo, key_size);
}
}
else
{
iterator->destroy(iterator);
selected->destroy(selected);
return NULL;
}
/* select integrity algorithm */
if (select_algo(this_prop->integrity_algos, other_prop->integrity_algos, &add, &algo, &key_size))
{
if (add)
{
selected->add_algorithm(selected, proto, INTEGRITY_ALGORITHM, algo, key_size);
}
}
else
{
iterator->destroy(iterator);
selected->destroy(selected);
return NULL;
}
/* select prf algorithm */
if (select_algo(this_prop->prf_algos, other_prop->prf_algos, &add, &algo, &key_size))
{
if (add)
{
selected->add_algorithm(selected, proto, PSEUDO_RANDOM_FUNCTION, algo, key_size);
}
}
else
{
iterator->destroy(iterator);
selected->destroy(selected);
return NULL;
}
/* select a DH-group */
if (select_algo(this_prop->dh_groups, other_prop->dh_groups, &add, &algo, &key_size))
{
if (add)
{
selected->add_algorithm(selected, proto, DIFFIE_HELLMAN_GROUP, algo, 0);
}
}
else
{
iterator->destroy(iterator);
selected->destroy(selected);
return NULL;
}
/* select if we use ESNs */
if (select_algo(this_prop->esns, other_prop->esns, &add, &algo, &key_size))
{
if (add)
{
selected->add_algorithm(selected, proto, EXTENDED_SEQUENCE_NUMBERS, algo, 0);
}
}
else
{
iterator->destroy(iterator);
selected->destroy(selected);
return NULL;
}
}
iterator->destroy(iterator);
/* apply spis from "other" */
spi = other->public.get_spi(&(other->public), PROTO_AH);
if (spi)
{
selected->set_spi(selected, PROTO_AH, spi);
}
spi = other->public.get_spi(&(other->public), PROTO_ESP);
if (spi)
{
selected->set_spi(selected, PROTO_ESP, spi);
}
/* everything matched, return new proposal */
return selected;
}
/**
* Implements proposal_t.get_number.
*/
static u_int8_t get_number(private_proposal_t *this)
{
return this->number;
}
/**
* Implements proposal_t.get_protocols.
*/
static void get_protocols(private_proposal_t *this, protocol_id_t ids[2])
{
iterator_t *iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
u_int i = 0;
ids[0] = PROTO_NONE;
ids[1] = PROTO_NONE;
while (iterator->has_next(iterator))
{
protocol_proposal_t *proto_prop;
iterator->current(iterator, (void**)&proto_prop);
ids[i++] = proto_prop->protocol;
if (i>1)
{
/* should not happen, but who knows */
break;
}
}
iterator->destroy(iterator);
}
/**
* Implements proposal_t.set_spi.
*/
static void set_spi(private_proposal_t *this, protocol_id_t proto, u_int64_t spi)
{
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
if (proto_proposal)
{
if (proto == PROTO_AH || proto == PROTO_ESP)
{
*((u_int32_t*)proto_proposal->spi.ptr) = (u_int32_t)spi;
}
else
{
*((u_int64_t*)proto_proposal->spi.ptr) = spi;
}
}
}
/**
* Implements proposal_t.get_spi.
*/
static u_int64_t get_spi(private_proposal_t *this, protocol_id_t proto)
{
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
if (proto_proposal)
{
if (proto == PROTO_AH || proto == PROTO_ESP)
{
return (u_int64_t)*((u_int32_t*)proto_proposal->spi.ptr);
}
else
{
return *((u_int64_t*)proto_proposal->spi.ptr);
}
}
return 0;
}
/**
* Clone a algorithm list
*/
static void clone_algo_list(linked_list_t *list, linked_list_t *clone_list)
{
algorithm_t *algo, *clone_algo;
iterator_t *iterator = list->create_iterator(list, TRUE);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&algo);
clone_algo = malloc_thing(algorithm_t);
memcpy(clone_algo, algo, sizeof(algorithm_t));
clone_list->insert_last(clone_list, (void*)clone_algo);
}
iterator->destroy(iterator);
}
/**
* Implements proposal_t.clone
*/
static proposal_t *clone(private_proposal_t *this)
{
private_proposal_t *clone = (private_proposal_t*)proposal_create(this->number);
iterator_t *iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
while (iterator->has_next(iterator))
{
protocol_proposal_t *proto_prop, *clone_proto_prop;
iterator->current(iterator, (void**)&proto_prop);
clone_proto_prop = get_protocol_proposal(clone, proto_prop->protocol, TRUE);
memcpy(clone_proto_prop->spi.ptr, proto_prop->spi.ptr, clone_proto_prop->spi.len);
clone_algo_list(proto_prop->encryption_algos, clone_proto_prop->encryption_algos);
clone_algo_list(proto_prop->integrity_algos, clone_proto_prop->integrity_algos);
clone_algo_list(proto_prop->prf_algos, clone_proto_prop->prf_algos);
clone_algo_list(proto_prop->dh_groups, clone_proto_prop->dh_groups);
clone_algo_list(proto_prop->esns, clone_proto_prop->esns);
}
iterator->destroy(iterator);
return &clone->public;
}
/**
* Frees all list items and destroys the list
*/
static void free_algo_list(linked_list_t *list)
{
algorithm_t *algo;
while(list->get_count(list) > 0)
{
list->remove_last(list, (void**)&algo);
free(algo);
}
list->destroy(list);
}
/**
* Implements proposal_t.destroy.
*/
static void destroy(private_proposal_t *this)
{
while(this->protocol_proposals->get_count(this->protocol_proposals) > 0)
{
protocol_proposal_t *proto_prop;
this->protocol_proposals->remove_last(this->protocol_proposals, (void**)&proto_prop);
free_algo_list(proto_prop->encryption_algos);
free_algo_list(proto_prop->integrity_algos);
free_algo_list(proto_prop->prf_algos);
free_algo_list(proto_prop->dh_groups);
free_algo_list(proto_prop->esns);
free(proto_prop->spi.ptr);
free(proto_prop);
}
this->protocol_proposals->destroy(this->protocol_proposals);
free(this);
}
/*
* Describtion in header-file
*/
proposal_t *proposal_create(u_int8_t number)
{
private_proposal_t *this = malloc_thing(private_proposal_t);
this->public.add_algorithm = (void (*)(proposal_t*,protocol_id_t,transform_type_t,u_int16_t,size_t))add_algorithm;
this->public.create_algorithm_iterator = (iterator_t* (*)(proposal_t*,protocol_id_t,transform_type_t))create_algorithm_iterator;
this->public.get_algorithm = (bool (*)(proposal_t*,protocol_id_t,transform_type_t,algorithm_t**))get_algorithm;
this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*))select_proposal;
this->public.get_number = (u_int8_t (*)(proposal_t*))get_number;
this->public.get_protocols = (void(*)(proposal_t *this, protocol_id_t ids[2]))get_protocols;
this->public.set_spi = (void(*)(proposal_t*,protocol_id_t,u_int64_t spi))set_spi;
this->public.get_spi = (u_int64_t(*)(proposal_t*,protocol_id_t))get_spi;
this->public.clone = (proposal_t*(*)(proposal_t*))clone;
this->public.destroy = (void(*)(proposal_t*))destroy;
/* init private members*/
this->number = number;
this->protocol_proposals = linked_list_create();
return (&this->public);
}
+269
View File
@@ -0,0 +1,269 @@
/**
* @file proposal.h
*
* @brief Interface of proposal_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef PROPOSAL_H_
#define PROPOSAL_H_
#include <types.h>
#include <utils/identification.h>
#include <utils/linked_list.h>
#include <utils/host.h>
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
#include <crypto/diffie_hellman.h>
#include <config/traffic_selector.h>
typedef enum protocol_id_t protocol_id_t;
/**
* Protocol ID of a proposal.
*
* @ingroup config
*/
enum protocol_id_t {
PROTO_NONE = 0,
PROTO_IKE = 1,
PROTO_AH = 2,
PROTO_ESP = 3,
};
/**
* String mappings for protocol_id_t.
*
* @ingroup config
*/
extern mapping_t protocol_id_m[];
typedef enum transform_type_t transform_type_t;
/**
* Type of a transform, as in IKEv2 RFC 3.3.2.
*
* @ingroup payloads
*/
enum transform_type_t {
UNDEFINED_TRANSFORM_TYPE = 241,
ENCRYPTION_ALGORITHM = 1,
PSEUDO_RANDOM_FUNCTION = 2,
INTEGRITY_ALGORITHM = 3,
DIFFIE_HELLMAN_GROUP = 4,
EXTENDED_SEQUENCE_NUMBERS = 5
};
/**
* String mappings for transform_type_t.
*
* @ingroup payloads
*/
extern mapping_t transform_type_m[];
typedef enum extended_sequence_numbers_t extended_sequence_numbers_t;
/**
* Extended sequence numbers, as in IKEv2 RFC 3.3.2.
*
* @ingroup payloads
*/
enum extended_sequence_numbers_t {
NO_EXT_SEQ_NUMBERS = 0,
EXT_SEQ_NUMBERS = 1
};
/**
* String mappings for extended_sequence_numbers_t.
*
* @ingroup payloads
*/
extern mapping_t extended_sequence_numbers_m[];
typedef struct algorithm_t algorithm_t;
/**
* Struct used to store different kinds of algorithms. The internal
* lists of algorithms contain such structures.
*/
struct algorithm_t {
/**
* Value from an encryption_algorithm_t/integrity_algorithm_t/...
*/
u_int16_t algorithm;
/**
* the associated key size, or zero if not needed
*/
u_int16_t key_size;
};
typedef struct proposal_t proposal_t;
/**
* @brief Stores a set of algorithms used for an SA.
*
* A proposal stores algorithms for a specific
* protocol. It can store algorithms for more than
* one protocol (e.g. AH and ESP). Then the proposal
* means both protocols must be used.
* A proposal may contain more than one algorithm
* of the same kind. ONE of them can be selected.
*
* @warning This class is NOT thread-save!
*
* @b Constructors:
* - proposal_create()
*
* @ingroup config
*/
struct proposal_t {
/**
* @brief Add an algorithm to the proposal.
*
* The algorithms are stored by priority, first added
* is the most preferred.
* Key size is only needed for encryption algorithms
* with variable key size (such as AES). Must be set
* to zero if key size is not specified.
* The alg parameter accepts encryption_algorithm_t,
* integrity_algorithm_t, dh_group_number_t and
* extended_sequence_numbers_t.
*
* @warning Do not add while other threads are reading.
*
* @param this calling object
* @param proto desired protocol
* @param type kind of algorithm
* @param alg identifier for algorithm
* @param key_size key size to use
*/
void (*add_algorithm) (proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t alg, size_t key_size);
/**
* @brief Get an iterator over algorithms for a specifc protocol/algo type.
*
* @param this calling object
* @param proto desired protocol
* @param type kind of algorithm
* @return iterator over algorithms
*/
iterator_t *(*create_algorithm_iterator) (proposal_t *this, protocol_id_t proto, transform_type_t type);
/**
* @brief Get the algorithm for a type to use.
*
* If there are multiple algorithms, only the first is returned.
* Result is still owned by proposal, do not modify!
*
* @param this calling object
* @param proto desired protocol
* @param type kind of algorithm
* @param[out] algo pointer which receives algorithm and key size
* @return TRUE if algorithm of this kind available
*/
bool (*get_algorithm) (proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo);
/**
* @brief Compare two proposal, and select a matching subset.
*
* If the proposals are for the same protocols (AH/ESP), they are
* compared. If they have at least one algorithm of each type
* in common, a resulting proposal of this kind is created.
*
* @param this calling object
* @param other proposal to compair agains
* @return
* - selected proposal, if possible
* - NULL, if proposals don't match
*/
proposal_t *(*select) (proposal_t *this, proposal_t *other);
/**
* @brief Get the number set on construction.
*
* @param this calling object
* @return number
*/
u_int8_t (*get_number) (proposal_t *this);
/**
* @brief Get the protocol ids in the proposals.
*
* With AH and ESP, there could be two protocols in one
* proposal.
*
* @param this calling object
* @param ids array of protocol ids,
*/
void (*get_protocols) (proposal_t *this, protocol_id_t ids[2]);
/**
* @brief Get the spi for a specific protocol.
*
* @param this calling object
* @param proto AH/ESP
* @return spi for proto
*/
u_int64_t (*get_spi) (proposal_t *this, protocol_id_t proto);
/**
* @brief Set the spi for a specific protocol.
*
* @param this calling object
* @param proto AH/ESP
* @param spi spi to set for proto
*/
void (*set_spi) (proposal_t *this, protocol_id_t proto, u_int64_t spi);
/**
* @brief Clone a proposal.
*
* @param this proposal to clone
* @return clone of it
*/
proposal_t *(*clone) (proposal_t *this);
/**
* @brief Destroys the proposal object.
*
* @param this calling object
*/
void (*destroy) (proposal_t *this);
};
/**
* @brief Create a child proposal for AH and/or ESP.
*
* Since the order of multiple proposals is important for
* key derivation, we must assign them numbers as they
* appear in the raw payload. Numbering starts at 1.
*
* @param number number of the proposal, as in the payload
* @return proposal_t object
*
* @ingroup config
*/
proposal_t *proposal_create(u_int8_t number);
#endif /* PROPOSAL_H_ */
@@ -0,0 +1,425 @@
/**
* @file traffic_selector.c
*
* @brief Implementation of traffic_selector_t.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#include "traffic_selector.h"
#include <utils/linked_list.h>
#include <utils/identification.h>
#include <arpa/inet.h>
#include <string.h>
typedef struct private_traffic_selector_t private_traffic_selector_t;
/**
* Private data of an traffic_selector_t object
*/
struct private_traffic_selector_t {
/**
* Public part
*/
traffic_selector_t public;
/**
* Type of address
*/
ts_type_t type;
/**
* IP protocol (UDP, TCP, ICMP, ...)
*/
u_int8_t protocol;
/**
* begin of address range, host order
*/
union {
u_int32_t from_addr_ipv4;
};
/**
* end of address range, host order
*/
union {
u_int32_t to_addr_ipv4;
};
/**
* begin of port range
*/
u_int16_t from_port;
/**
* end of port range
*/
u_int16_t to_port;
};
/**
* internal generic constructor
*/
static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port);
/**
* implements traffic_selector_t.get_subset
*/
static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_traffic_selector_t *other)
{
if ((this->type == TS_IPV4_ADDR_RANGE) &&
(other->type == TS_IPV4_ADDR_RANGE) &&
(this->protocol == other->protocol))
{
u_int32_t from_addr, to_addr;
u_int16_t from_port, to_port;
private_traffic_selector_t *new_ts;
/* calculate the maximum address range allowed for both */
from_addr = max(this->from_addr_ipv4, other->from_addr_ipv4);
to_addr = min(this->to_addr_ipv4, other->to_addr_ipv4);
if (from_addr > to_addr)
{
/* no match */
return NULL;
}
/* calculate the maximum port range allowed for both */
from_port = max(this->from_port, other->from_port);
to_port = min(this->to_port, other->to_port);
if (from_port > to_port)
{
/* no match */
return NULL;
}
/* got a match, return it */
new_ts = traffic_selector_create(this->protocol, this->type, from_port, to_port);
new_ts->from_addr_ipv4 = from_addr;
new_ts->to_addr_ipv4 = to_addr;
new_ts->type = TS_IPV4_ADDR_RANGE;
return &(new_ts->public);
}
return NULL;
}
/**
* Implements traffic_selector_t.get_from_address.
*/
static chunk_t get_from_address(private_traffic_selector_t *this)
{
chunk_t from_addr = CHUNK_INITIALIZER;
switch (this->type)
{
case TS_IPV4_ADDR_RANGE:
{
u_int32_t network;
from_addr.len = sizeof(network);
from_addr.ptr = malloc(from_addr.len);
/* chunk must contain network order, convert! */
network = htonl(this->from_addr_ipv4);
memcpy(from_addr.ptr, &network, from_addr.len);
break;
}
case TS_IPV6_ADDR_RANGE:
{
break;
}
}
return from_addr;
}
/**
* Implements traffic_selector_t.get_to_address.
*/
static chunk_t get_to_address(private_traffic_selector_t *this)
{
chunk_t to_addr = CHUNK_INITIALIZER;
switch (this->type)
{
case TS_IPV4_ADDR_RANGE:
{
u_int32_t network;
to_addr.len = sizeof(network);
to_addr.ptr = malloc(to_addr.len);
/* chunk must contain network order, convert! */
network = htonl(this->to_addr_ipv4);
memcpy(to_addr.ptr, &network, to_addr.len);
break;
}
case TS_IPV6_ADDR_RANGE:
{
break;
}
}
return to_addr;
}
/**
* Implements traffic_selector_t.get_from_port.
*/
static u_int16_t get_from_port(private_traffic_selector_t *this)
{
return this->from_port;
}
/**
* Implements traffic_selector_t.get_to_port.
*/
static u_int16_t get_to_port(private_traffic_selector_t *this)
{
return this->to_port;
}
/**
* Implements traffic_selector_t.get_type.
*/
static ts_type_t get_type(private_traffic_selector_t *this)
{
return this->type;
}
/**
* Implements traffic_selector_t.get_protocol.
*/
static u_int8_t get_protocol(private_traffic_selector_t *this)
{
return this->protocol;
}
/**
* Implements traffic_selector_t.get_netmask.
*/
static u_int8_t get_netmask(private_traffic_selector_t *this)
{
switch (this->type)
{
case TS_IPV4_ADDR_RANGE:
{
u_int32_t from, to, bit;
from = htonl(this->from_addr_ipv4);
to = htonl(this->to_addr_ipv4);
for (bit = 0; bit < 32; bit++)
{
if ((1<<bit & from) != (1<<bit & to))
{
return bit;
}
}
return 32;
}
case TS_IPV6_ADDR_RANGE:
default:
{
return 0;
}
}
}
/**
* Implements traffic_selector_t.update_address_range.
*/
static void update_address_range(private_traffic_selector_t *this, host_t *host)
{
if (host->get_family(host) == AF_INET &&
this->type == TS_IPV4_ADDR_RANGE)
{
if (this->from_addr_ipv4 == 0)
{
chunk_t from = host->get_address_as_chunk(host);
this->from_addr_ipv4 = ntohl(*((u_int32_t*)from.ptr));
this->to_addr_ipv4 = this->from_addr_ipv4;
chunk_free(&from);
}
}
}
/**
* Implements traffic_selector_t.clone.
*/
static traffic_selector_t *clone(private_traffic_selector_t *this)
{
private_traffic_selector_t *clone = traffic_selector_create(this->protocol, this->type, this->from_port, this->to_port);
clone->type = this->type;
switch (clone->type)
{
case TS_IPV4_ADDR_RANGE:
{
clone->from_addr_ipv4 = this->from_addr_ipv4;
clone->to_addr_ipv4 = this->to_addr_ipv4;
return &(clone->public);
}
case TS_IPV6_ADDR_RANGE:
default:
{
free(this);
return NULL;
}
}
}
/**
* Implements traffic_selector_t.destroy.
*/
static void destroy(private_traffic_selector_t *this)
{
free(this);
}
/*
* see header
*/
traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_type_t type, chunk_t from_addr, int16_t from_port, chunk_t to_addr, u_int16_t to_port)
{
private_traffic_selector_t *this = traffic_selector_create(protocol, type, from_port, to_port);
this->type = type;
switch (type)
{
case TS_IPV4_ADDR_RANGE:
{
if (from_addr.len != 4 || to_addr.len != 4)
{
free(this);
return NULL;
}
/* chunk contains network order, convert! */
this->from_addr_ipv4 = ntohl(*((u_int32_t*)from_addr.ptr));
this->to_addr_ipv4 = ntohl(*((u_int32_t*)to_addr.ptr));
break;
}
case TS_IPV6_ADDR_RANGE:
default:
{
free(this);
return NULL;
}
}
return (&this->public);
}
/*
* see header
*/
traffic_selector_t *traffic_selector_create_from_subnet(host_t *net, u_int8_t netbits)
{
private_traffic_selector_t *this = traffic_selector_create(0, 0, 0, 65535);
switch (net->get_family(net))
{
case AF_INET:
{
chunk_t from;
this->type = TS_IPV4_ADDR_RANGE;
from = net->get_address_as_chunk(net);
this->from_addr_ipv4 = ntohl(*((u_int32_t*)from.ptr));
if (this->from_addr_ipv4 == 0)
{
/* use /32 for 0.0.0.0 */
this->to_addr_ipv4 = 0xFFFFFF;
}
else
{
this->to_addr_ipv4 = this->from_addr_ipv4 | ((1 << (32 - netbits)) - 1);
}
chunk_free(&from);
break;
}
case AF_INET6:
default:
{
free(this);
return NULL;
}
}
return (&this->public);
}
/*
* see header
*/
traffic_selector_t *traffic_selector_create_from_string(u_int8_t protocol, ts_type_t type, char *from_addr, u_int16_t from_port, char *to_addr, u_int16_t to_port)
{
private_traffic_selector_t *this = traffic_selector_create(protocol, type, from_port, to_port);
/* public functions */
this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset;
this->public.destroy = (void(*)(traffic_selector_t*))destroy;
this->type = type;
switch (type)
{
case TS_IPV4_ADDR_RANGE:
{
if (inet_aton(from_addr, (struct in_addr*)&(this->from_addr_ipv4)) == 0)
{
free(this);
return NULL;
}
if (inet_aton(to_addr, (struct in_addr*)&(this->to_addr_ipv4)) == 0)
{
free(this);
return NULL;
}
/* convert to host order, inet_aton has network order */
this->from_addr_ipv4 = ntohl(this->from_addr_ipv4);
this->to_addr_ipv4 = ntohl(this->to_addr_ipv4);
break;
}
case TS_IPV6_ADDR_RANGE:
{
free(this);
return NULL;
}
}
return (&this->public);
}
/*
* see declaration
*/
static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port)
{
private_traffic_selector_t *this = malloc_thing(private_traffic_selector_t);
/* public functions */
this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset;
this->public.get_from_address = (chunk_t(*)(traffic_selector_t*))get_from_address;
this->public.get_to_address = (chunk_t(*)(traffic_selector_t*))get_to_address;
this->public.get_from_port = (u_int16_t(*)(traffic_selector_t*))get_from_port;
this->public.get_to_port = (u_int16_t(*)(traffic_selector_t*))get_to_port;
this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type;
this->public.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol;
this->public.get_netmask = (u_int8_t(*)(traffic_selector_t*))get_netmask;
this->public.update_address_range = (void(*)(traffic_selector_t*,host_t*))update_address_range;
this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone;
this->public.destroy = (void(*)(traffic_selector_t*))destroy;
this->from_port = from_port;
this->to_port = to_port;
this->protocol = protocol;
this->type = type;
return this;
}
@@ -0,0 +1,258 @@
/**
* @file traffic_selector.h
*
* @brief Interface of traffic_selector_t.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef TRAFFIC_SELECTOR_H_
#define TRAFFIC_SELECTOR_H_
#include <types.h>
#include <utils/host.h>
typedef enum ts_type_t ts_type_t;
/**
* Traffic selector types.
*
* @ingroup config
*/
enum ts_type_t {
/**
* A range of IPv4 addresses, represented by two four (4) octet
* values. The first value is the beginning IPv4 address
* (inclusive) and the second value is the ending IPv4 address
* (inclusive). All addresses falling between the two specified
* addresses are considered to be within the list.
*/
TS_IPV4_ADDR_RANGE = 7,
/**
* A range of IPv6 addresses, represented by two sixteen (16)
* octet values. The first value is the beginning IPv6 address
* (inclusive) and the second value is the ending IPv6 address
* (inclusive). All addresses falling between the two specified
* addresses are considered to be within the list.
*/
TS_IPV6_ADDR_RANGE = 8
};
/**
* string mappings for ts_type_t
*/
extern mapping_t ts_type_m[];
typedef struct traffic_selector_t traffic_selector_t;
/**
* @brief Object representing a traffic selector entry.
*
* A traffic selector defines an range of addresses
* and a range of ports. IPv6 is not fully supported yet.
*
* @b Constructors:
* - traffic_selector_create_from_bytes()
* - traffic_selector_create_from_string()
*
* @todo Add IPv6 support
*
* @ingroup config
*/
struct traffic_selector_t {
/**
* @brief Compare two traffic selectors, and create a new one
* which is the largest subset of both (subnet & port).
*
* Resulting traffic_selector is newly created and must be destroyed.
*
* @param this first to compare
* @param other second to compare
* @return
* - created subset of them
* - or NULL if no match between this and other
*/
traffic_selector_t *(*get_subset) (traffic_selector_t *this, traffic_selector_t *other);
/**
* @brief Clone a traffic selector.
*
* @param this traffic selector to clone
* @return clone of it
*/
traffic_selector_t *(*clone) (traffic_selector_t *this);
/**
* @brief Get starting address of this ts as a chunk.
*
* Data is in network order and represents the address.
* Size depends on protocol.
*
* Resulting chunk data is allocated and must be freed!
*
* @param this calling object
* @return chunk containing the address
*/
chunk_t (*get_from_address) (traffic_selector_t *this);
/**
* @brief Get ending address of this ts as a chunk.
*
* Data is in network order and represents the address.
* Size depends on protocol.
*
* Resulting chunk data is allocated and must be freed!
*
* @param this calling object
* @return chunk containing the address
*/
chunk_t (*get_to_address) (traffic_selector_t *this);
/**
* @brief Get starting port of this ts.
*
* Port is in host order, since the parser converts it.
* Size depends on protocol.
*
* @param this calling object
* @return port
*/
u_int16_t (*get_from_port) (traffic_selector_t *this);
/**
* @brief Get ending port of this ts.
*
* Port is in host order, since the parser converts it.
* Size depends on protocol.
*
* @param this calling object
* @return port
*/
u_int16_t (*get_to_port) (traffic_selector_t *this);
/**
* @brief Get the type of the traffic selector.
*
* @param this calling obect
* @return ts_type_t specifying the type
*/
ts_type_t (*get_type) (traffic_selector_t *this);
/**
* @brief Get the protocol id of this ts.
*
* @param this calling obect
* @return protocol id
*/
u_int8_t (*get_protocol) (traffic_selector_t *this);
/**
* @brief Get the netmask of the address range.
*
* Returns the number of bits associated to the subnet.
* (As the "24" in "192.168.0.0/24"). This is approximated
* if the address range is not a complete subnet! Since Linux
* does not support full IP address ranges (yet), we can't do this
* (much) better.
*
* @param this calling obect
* @return netmask as "bits for subnet"
*/
u_int8_t (*get_netmask) (traffic_selector_t *this);
/**
* @brief Update the address of a traffic selector.
*
* Update the address range of a traffic selector,
* if the current address is 0.0.0.0. The new address range
* starts from the supplied address and also ends there
* (which means it is a one-host-address-range ;-).
*
* @param this calling obect
* @param host host_t specifying the address range
*/
void (*update_address_range) (traffic_selector_t *this, host_t* host);
/**
* @brief Destroys the ts object
*
* @param this calling object
*/
void (*destroy) (traffic_selector_t *this);
};
/**
* @brief Create a new traffic selector using human readable params.
*
* @param protocol protocol for this ts, such as TCP or UDP
* @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
* @param from_addr start of address range as string
* @param from_port port number in host order
* @param to_addr end of address range as string
* @param to_port port number in host order
* @return
* - traffic_selector_t object
* - NULL if invalid address strings/protocol
*
* @ingroup config
*/
traffic_selector_t *traffic_selector_create_from_string(u_int8_t protocol, ts_type_t type, char *from_addr, u_int16_t from_port, char *to_addr, u_int16_t to_port);
/**
* @brief Create a new traffic selector using data read from the net.
*
* There exists a mix of network and host order in the params.
* But the parser gives us this data in this format, so we
* don't have to convert twice.
*
* @param protocol protocol for this ts, such as TCP or UDP
* @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
* @param from_address start of address range, network order
* @param from_port port number, host order
* @param to_address end of address range as string, network
* @param to_port port number, host order
* @return
* - traffic_selector_t object
* - NULL if invalid address input/protocol
*
* @ingroup config
*/
traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_type_t type, chunk_t from_address, int16_t from_port, chunk_t to_address, u_int16_t to_port);
/**
* @brief Create a new traffic selector defining a whole subnet.
*
* In most cases, definition of a traffic selector for full subnets
* is sufficient. This constructor creates a traffic selector for
* all protocols, all ports and the address range specified by the
* subnet.
*
* @param net subnet to use
* @param netbits size of the subnet, as used in e.g. 192.168.0.0/24 notation
* @return
* - traffic_selector_t object
* - NULL if address family of net not supported
*
* @ingroup config
*/
traffic_selector_t *traffic_selector_create_from_subnet(host_t *net, u_int8_t netbits);
#endif /* TRAFFIC_SELECTOR_H_ */
+390
View File
@@ -0,0 +1,390 @@
/**
* @file daemon.c
*
* @brief Implementation of daemon_t and main of IKEv2-Daemon.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <execinfo.h>
#include <string.h>
#include "daemon.h"
#include <types.h>
#include <config/connections/local_connection_store.h>
#include <config/credentials/local_credential_store.h>
#include <config/policies/local_policy_store.h>
typedef struct private_daemon_t private_daemon_t;
/**
* Private additions to daemon_t, contains threads and internal functions.
*/
struct private_daemon_t {
/**
* Public members of daemon_t.
*/
daemon_t public;
/**
* A logger_t object assigned for daemon things.
*/
logger_t *logger;
/**
* Signal set used for signal handling.
*/
sigset_t signal_set;
/**
* The thread_id of main-thread.
*/
pthread_t main_thread_id;
/**
* Main loop function.
*
* @param this calling object
*/
void (*run) (private_daemon_t *this);
/**
* Initialize the daemon.
*
* @param this calling object
*/
void (*initialize) (private_daemon_t *this);
/**
* Destroy the daemon.
*
* @param this calling object
*/
void (*destroy) (private_daemon_t *this);
};
/**
* One and only instance of the daemon.
*/
daemon_t *charon;
/**
* Implementation of private_daemon_t.run.
*/
static void run(private_daemon_t *this)
{
/* reselect signals for this thread */
sigemptyset(&(this->signal_set));
sigaddset(&(this->signal_set), SIGINT);
sigaddset(&(this->signal_set), SIGHUP);
sigaddset(&(this->signal_set), SIGTERM);
pthread_sigmask(SIG_BLOCK, &(this->signal_set), 0);
while(TRUE)
{
int signal_number;
int error;
error = sigwait(&(this->signal_set), &signal_number);
if(error)
{
this->logger->log(this->logger, ERROR, "Error %d when waiting for signal", error);
return;
}
switch (signal_number)
{
case SIGHUP:
{
this->logger->log(this->logger, CONTROL, "Signal of type SIGHUP received. Do nothing");
break;
}
case SIGINT:
{
this->logger->log(this->logger, CONTROL, "Signal of type SIGINT received. Exit main loop");
return;
}
case SIGTERM:
this->logger->log(this->logger, CONTROL, "Signal of type SIGTERM received. Exit main loop");
return;
default:
{
this->logger->log(this->logger, CONTROL, "Unknown signal %d received. Do nothing", signal_number);
break;
}
}
}
}
/**
* Implementation of daemon_t.kill.
*/
static void kill_daemon(private_daemon_t *this, char *reason)
{
/* we send SIGTERM, so the daemon can cleanly shut down */
this->logger->log(this->logger, CONTROL, "Killing daemon: %s", reason);
if (this->main_thread_id == pthread_self())
{
/* initialization failed, terminate daemon */
this->destroy(this);
unlink(PID_FILE);
exit(-1);
}
else
{
this->logger->log(this->logger, CONTROL, "sending SIGTERM to ourself", reason);
kill(0, SIGTERM);
/* thread must die, since he produced a ciritcal failure and can't continue */
pthread_exit(NULL);
}
}
/**
* Implementation of private_daemon_t.initialize.
*/
static void initialize(private_daemon_t *this)
{
local_credential_store_t* cred_store;
this->public.configuration = configuration_create();
this->public.socket = socket_create(IKEV2_UDP_PORT);
this->public.ike_sa_manager = ike_sa_manager_create();
this->public.job_queue = job_queue_create();
this->public.event_queue = event_queue_create();
this->public.send_queue = send_queue_create();
this->public.connections = (connection_store_t*)local_connection_store_create();
this->public.policies = (policy_store_t*)local_policy_store_create();
this->public.credentials = (credential_store_t*)(cred_store = local_credential_store_create());
/* load keys & certs */
cred_store->load_certificates(cred_store, CERTIFICATE_DIR);
cred_store->load_private_keys(cred_store, PRIVATE_KEY_DIR);
/* start building threads, we are multi-threaded NOW */
this->public.stroke = stroke_create();
this->public.sender = sender_create();
this->public.receiver = receiver_create();
this->public.scheduler = scheduler_create();
this->public.kernel_interface = kernel_interface_create();
this->public.thread_pool = thread_pool_create(NUMBER_OF_WORKING_THREADS);
}
/**
* Destory all initiated objects
*/
static void destroy(private_daemon_t *this)
{
if (this->public.ike_sa_manager != NULL)
{
this->public.ike_sa_manager->destroy(this->public.ike_sa_manager);
}
if (this->public.kernel_interface != NULL)
{
this->public.kernel_interface->destroy(this->public.kernel_interface);
}
if (this->public.receiver != NULL)
{
this->public.receiver->destroy(this->public.receiver);
}
if (this->public.scheduler != NULL)
{
this->public.scheduler->destroy(this->public.scheduler);
}
if (this->public.sender != NULL)
{
this->public.sender->destroy(this->public.sender);
}
if (this->public.thread_pool != NULL)
{
this->public.thread_pool->destroy(this->public.thread_pool);
}
if (this->public.job_queue != NULL)
{
this->public.job_queue->destroy(this->public.job_queue);
}
if (this->public.event_queue != NULL)
{
this->public.event_queue->destroy(this->public.event_queue);
}
if (this->public.send_queue != NULL)
{
this->public.send_queue->destroy(this->public.send_queue);
}
if (this->public.socket != NULL)
{
this->public.socket->destroy(this->public.socket);
}
if (this->public.configuration != NULL)
{
this->public.configuration->destroy(this->public.configuration);
}
if (this->public.credentials != NULL)
{
this->public.credentials->destroy(this->public.credentials);
}
if (this->public.connections != NULL)
{
this->public.connections->destroy(this->public.connections);
}
if (this->public.policies != NULL)
{
this->public.policies->destroy(this->public.policies);
}
if (this->public.stroke != NULL)
{
this->public.stroke->destroy(this->public.stroke);
}
free(this);
}
void signal_handler(int signal)
{
void *array[20];
size_t size;
char **strings;
size_t i;
logger_t *logger;
size = backtrace(array, 20);
strings = backtrace_symbols(array, size);
logger = logger_manager->get_logger(logger_manager, DAEMON);
logger->log(logger, ERROR, "Thread %u received SIGSEGV. Dumping %d frames from stack:", pthread_self(), size);
for (i = 0; i < size; i++)
{
logger->log(logger, ERROR, " %s", strings[i]);
}
free (strings);
logger->log(logger, ERROR, "Killing ourself hard after SIGSEGV");
kill(getpid(), SIGKILL);
}
/**
* @brief Create the daemon.
*
* @return created daemon_t
*/
private_daemon_t *daemon_create()
{
private_daemon_t *this = malloc_thing(private_daemon_t);
struct sigaction action;
/* assign methods */
this->run = run;
this->destroy = destroy;
this->initialize = initialize;
this->public.kill = (void (*) (daemon_t*,char*))kill_daemon;
/* NULL members for clean destruction */
this->public.socket = NULL;
this->public.ike_sa_manager = NULL;
this->public.job_queue = NULL;
this->public.event_queue = NULL;
this->public.send_queue = NULL;
this->public.configuration = NULL;
this->public.credentials = NULL;
this->public.connections = NULL;
this->public.policies = NULL;
this->public.sender= NULL;
this->public.receiver = NULL;
this->public.scheduler = NULL;
this->public.kernel_interface = NULL;
this->public.thread_pool = NULL;
this->public.stroke = NULL;
this->main_thread_id = pthread_self();
/* setup signal handling for all threads */
sigemptyset(&(this->signal_set));
sigaddset(&(this->signal_set), SIGSEGV);
sigaddset(&(this->signal_set), SIGINT);
sigaddset(&(this->signal_set), SIGHUP);
sigaddset(&(this->signal_set), SIGTERM);
pthread_sigmask(SIG_BLOCK, &(this->signal_set), 0);
/* setup SIGSEGV handler for all threads */
action.sa_handler = signal_handler;
action.sa_mask = this->signal_set;
action.sa_flags = 0;
if (sigaction(SIGSEGV, &action, NULL) == -1)
{
this->logger->log(this->logger, ERROR, "signal handler setup for SIGSEGV failed");
}
return this;
}
/**
* Main function, manages the daemon.
*/
int main(int argc, char *argv[])
{
private_daemon_t *private_charon;
FILE *pid_file;
struct stat stb;
int i;
/* trivial argument parsing */
for (i = 1; i < argc; i++)
{
if (strcmp(argv[i], "--use-syslog") == 0)
{
logger_manager->set_output(logger_manager, ALL_LOGGERS, NULL);
}
}
private_charon = daemon_create();
charon = (daemon_t*)private_charon;
private_charon->logger = logger_manager->get_logger(logger_manager, DAEMON);
/* initialize daemon */
private_charon->initialize(private_charon);
/* check/setup PID file */
if (stat(PID_FILE, &stb) == 0)
{
private_charon->logger->log(private_charon->logger, ERROR,
"charon already running (\""PID_FILE"\" exists)");
private_charon->destroy(private_charon);
exit(-1);
}
pid_file = fopen(PID_FILE, "w");
if (pid_file)
{
fprintf(pid_file, "%d\n", getpid());
fclose(pid_file);
}
/* run daemon */
private_charon->run(private_charon);
/* normal termination, cleanup and exit */
private_charon->destroy(private_charon);
unlink(PID_FILE);
return 0;
}
+324
View File
@@ -0,0 +1,324 @@
/**
* @file daemon.h
*
* @brief Interface of daemon_t.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef DAEMON_H_
#define DAEMON_H_
#include <threads/sender.h>
#include <threads/receiver.h>
#include <threads/scheduler.h>
#include <threads/kernel_interface.h>
#include <threads/thread_pool.h>
#include <threads/stroke_interface.h>
#include <network/socket.h>
#include <sa/ike_sa_manager.h>
#include <queues/send_queue.h>
#include <queues/job_queue.h>
#include <queues/event_queue.h>
#include <utils/logger_manager.h>
#include <config/configuration.h>
#include <config/connections/connection_store.h>
#include <config/policies/policy_store.h>
#include <config/credentials/credential_store.h>
/**
* @defgroup charon charon
*
* @brief IKEv2 keying daemon.
*
* @section Architecture
*
* All IKEv2 stuff is handled in charon. It uses a newer and more flexible
* architecture than pluto. Charon uses a thread-pool, which allows parallel
* execution SA-management. Beside the thread-pool, there are some special purpose
* threads which do their job for the common health of the daemon.
@verbatim
+------+
| E Q |
| v u |---+ +------+ +------+
| e e | | | | | IKE- |
| n u | +-----------+ | |--| SA |
| t e | | | | I M | +------+
+------------+ | - | | Scheduler | | K a |
| receiver | +------+ | | | E n | +------+
+----+-------+ +-----------+ | - a | | IKE- |
| | +------+ | | S g |--| SA |
+-------+--+ +-----| J Q |---+ +------------+ | A e | +------+
-| socket | | o u | | | | - r |
+-------+--+ | b e | | Thread- | | |
| | - u | | Pool | | |
+----+-------+ | e |------| |---| |
| sender | +------+ +------------+ +------+
+----+-------+
| +------+
| | S Q |
| | e u |
| | n e |
+------------| d u |
| - e |
+--+---+
@endverbatim
* The thread-pool is the heart of the architecture. It processes jobs from a
* (fully synchronized) job-queue. Mostly, a job is associated with a specific
* IKE SA. These IKE SAs are synchronized, only one thread can work one an IKE SA.
* This makes it unnecesary to use further synchronisation methods once a IKE SA
* is checked out. The (rather complex) synchronization of IKE SAs is completely
* done in the IKE SA manager.
* The sceduler is responsible for event firing. It waits until a event in the
* (fully synchronized) event-queue is ready for processing and pushes the event
* down to the job-queue. A thread form the pool will pick it up as quick as
* possible. Every thread can queue events or jobs. Furter, an event can place a
* packet in the send-queue. The sender thread waits for those packets and sends
* them over the wire, via the socket. The receiver does exactly the opposite of
* the sender. It waits on the socket, reads in packets an places them on the
* job-queue for further processing by a thread from the pool.
* There are even more threads, not drawn in the upper scheme. The stroke thread
* is responsible for reading and processessing commands from another process. The
* kernel interface thread handles communication from and to the kernel via a
* netlink socket. It waits for kernel events and processes them appropriately.
*/
/**
* @defgroup config config
*
* Classes implementing configuration related things.
*
* @ingroup charon
*/
/**
* @defgroup encoding encoding
*
* Classes used to encode and decode IKEv2 messages.
*
* @ingroup charon
*/
/**
* @defgroup payloads payloads
*
* Classes representing specific IKEv2 payloads.
*
* @ingroup encoding
*/
/**
* @defgroup network network
*
* Classes for network relevant stuff.
*
* @ingroup charon
*/
/**
* @defgroup queues queues
*
* Different kind of queues
* (thread save lists).
*
* @ingroup charon
*/
/**
* @defgroup jobs jobs
*
* Jobs used in job queue and event queue.
*
* @ingroup queues
*/
/**
* @defgroup sa sa
*
* Security associations for IKE and IPSec,
* and some helper classes.
*
* @ingroup charon
*/
/**
* @defgroup states states
*
* Varius states in which an IKE SA can be.
*
* @ingroup sa
*/
/**
* @defgroup threads threads
*
* Threaded classes, which will do their job alone.
*
* @ingroup charon
*/
/**
* Name of the daemon.
*
* @ingroup charon
*/
#define DAEMON_NAME "charon"
/**
* @brief Number of threads in the thread pool.
*
* There are several other threads, this defines
* only the number of threads in thread_pool_t.
*
* @ingroup charon
*/
#define NUMBER_OF_WORKING_THREADS 4
/**
* UDP Port on which the daemon will listen for incoming traffic.
*
* @ingroup charon
*/
#define IKEV2_UDP_PORT 500
/**
* PID file, in which charon stores its process id
*
* @ingroup charon
*/
#define PID_FILE "/var/run/charon.pid"
/**
* Directory of IPsec relevant files
*
* @ingroup charon
*/
#define IPSEC_DIR "/etc/ipsec.d"
/**
* Directory for private keys
*
* @ingroup charon
*/
#define PRIVATE_KEY_DIR IPSEC_DIR "/private"
/**
* Directory for trusted certificates
*
* @ingroup charon
*/
#define CERTIFICATE_DIR IPSEC_DIR "/certs"
typedef struct daemon_t daemon_t;
/**
* @brief Main class of daemon, contains some globals.
*
* @ingroup charon
*/
struct daemon_t {
/**
* A socket_t instance.
*/
socket_t *socket;
/**
* A send_queue_t instance.
*/
send_queue_t *send_queue;
/**
* A job_queue_t instance.
*/
job_queue_t *job_queue;
/**
* A event_queue_t instance.
*/
event_queue_t *event_queue;
/**
* A ike_sa_manager_t instance.
*/
ike_sa_manager_t *ike_sa_manager;
/**
* A configuration_t instance.
*/
configuration_t *configuration;
/**
* A connection_store_t instance.
*/
connection_store_t *connections;
/**
* A policy_store_t instance.
*/
policy_store_t *policies;
/**
* A credential_store_t instance.
*/
credential_store_t *credentials;
/**
* The Sender-Thread.
*/
sender_t *sender;
/**
* The Receiver-Thread.
*/
receiver_t *receiver;
/**
* The Scheduler-Thread.
*/
scheduler_t *scheduler;
/**
* The Thread pool managing the worker threads.
*/
thread_pool_t *thread_pool;
/**
* Kernel Interface to communicate with kernel
*/
kernel_interface_t *kernel_interface;
/**
* IPC interface, as whack in pluto
*/
stroke_t *stroke;
/**
* @brief Shut down the daemon.
*
* @param this the daemon to kill
* @param reason describtion why it will be killed
*/
void (*kill) (daemon_t *this, char *reason);
};
/**
* The one and only instance of the daemon.
*/
extern daemon_t *charon;
#endif /*DAEMON_H_*/
@@ -0,0 +1,30 @@
# Copyright (C) 2005 Jan Hutter, Martin Willi
# Hochschule fuer Technik Rapperswil
#
# 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.
#
ENCODING_DIR= $(CHARON_DIR)encoding/
CHARON_OBJS+= $(BUILD_DIR)generator.o
$(BUILD_DIR)generator.o : $(ENCODING_DIR)generator.c $(ENCODING_DIR)generator.h
$(CC) $(CFLAGS) -c -o $@ $<
CHARON_OBJS+= $(BUILD_DIR)parser.o
$(BUILD_DIR)parser.o : $(ENCODING_DIR)parser.c $(ENCODING_DIR)parser.h
$(CC) $(CFLAGS) -c -o $@ $<
CHARON_OBJS+= $(BUILD_DIR)message.o
$(BUILD_DIR)message.o : $(ENCODING_DIR)message.c $(ENCODING_DIR)message.h
$(CC) $(CFLAGS) -c -o $@ $<
include $(ENCODING_DIR)payloads/Makefile.payloads
File diff suppressed because it is too large Load Diff
+101
View File
@@ -0,0 +1,101 @@
/**
* @file generator.h
*
* @brief Interface of generator_t.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef GENERATOR_H_
#define GENERATOR_H_
#include <types.h>
#include <encoding/payloads/encodings.h>
#include <encoding/payloads/payload.h>
/**
* Generating is done in a data buffer.
* This is thehe start size of this buffer in bytes.
*
* @ingroup enconding
*/
#define GENERATOR_DATA_BUFFER_SIZE 500
/**
* Number of bytes to increase the buffer, if it is to small.
*
* @ingroup enconding
*/
#define GENERATOR_DATA_BUFFER_INCREASE_VALUE 500
typedef struct generator_t generator_t;
/**
* @brief A generator_t class used to generate IKEv2 payloads.
*
* After creation, multiple payloads can be generated with the generate_payload
* method. The generated bytes are appended. After all payloads are added,
* the write_to_chunk method writes out all generated data since
* the creation of the generator. After that, the generator must be destroyed.
* The generater uses a set of encoding rules, which it can get from
* the supplied payload. With this rules, the generater can generate
* the payload and all substructures automatically.
*
* @b Constructor:
* - generator_create()
*
* @ingroup encoding
*/
struct generator_t {
/**
* @brief Generates a specific payload from given payload object.
*
* Remember: Header and substructures are also handled as payloads.
*
* @param this generator_t object
* @param[in] payload interface payload_t implementing object
*/
void (*generate_payload) (generator_t *this,payload_t *payload);
/**
* @brief Writes all generated data of the generator to a chunk.
*
* @param this generator_t object
* @param[out] data chunk to write the data to
*/
void (*write_to_chunk) (generator_t *this,chunk_t *data);
/**
* @brief Destroys a generator_t object.
*
* @param this generator_t object
*/
void (*destroy) (generator_t *this);
};
/**
* @brief Constructor to create a generator.
*
* @return generator_t object.
*
* @ingroup encoding
*/
generator_t *generator_create();
#endif /*GENERATOR_H_*/
File diff suppressed because it is too large Load Diff
+367
View File
@@ -0,0 +1,367 @@
/**
* @file message.h
*
* @brief Interface of message_t.
*
*/
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
#ifndef MESSAGE_H_
#define MESSAGE_H_
#include <types.h>
#include <sa/ike_sa_id.h>
#include <network/packet.h>
#include <encoding/payloads/ike_header.h>
#include <encoding/payloads/notify_payload.h>
#include <utils/linked_list.h>
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
typedef struct message_t message_t;
/**
* @brief This class is used to represent an IKEv2-Message.
*
* The message handles parsing and generation of payloads
* via parser_t/generator_t. Encryption is done transparently
* via the encryption_payload_t. A set of rules for messages
* and payloads does check parsed messages.
*
* @b Constructors:
* - message_create()
* - message_create_from_packet()
* - message_create_notify_reply()
*
* @ingroup encoding
*/
struct message_t {
/**
* @brief Sets the IKE major version of the message.
*
* @param this message_t object
* @param major_version major version to set
*/
void (*set_major_version) (message_t *this,u_int8_t major_version);
/**
* @brief Gets the IKE major version of the message.
*
* @param this message_t object
* @return major version of the message
*/
u_int8_t (*get_major_version) (message_t *this);
/**
* @brief Sets the IKE minor version of the message.
*
* @param this message_t object
* @param minor_version minor version to set
*/
void (*set_minor_version) (message_t *this,u_int8_t minor_version);
/**
* @brief Gets the IKE minor version of the message.
*
* @param this message_t object
* @return minor version of the message
*/
u_int8_t (*get_minor_version) (message_t *this);
/**
* @brief Sets the Message ID of the message.
*
* @param this message_t object
* @param message_id message_id to set
*/
void (*set_message_id) (message_t *this,u_int32_t message_id);
/**
* @brief Gets the Message ID of the message.
*
* @param this message_t object
* @return message_id type of the message
*/
u_int32_t (*get_message_id) (message_t *this);
/**
* @brief Gets the responder SPI of the message.
*
* @param this message_t object
* @return responder spi of the message
*/
u_int64_t (*get_responder_spi) (message_t *this);
/**
* @brief Sets the IKE_SA ID of the message.
*
* @warning ike_sa_id gets cloned internaly and
* so can be destroyed afterwards.
*
* @param this message_t object
* @param ike_sa_id ike_sa_id to set
*/
void (*set_ike_sa_id) (message_t *this,ike_sa_id_t * ike_sa_id);
/**
* @brief Gets the IKE_SA ID of the message.
*
* @warning The returned ike_sa_id is a clone of the internal one.
* So it has to be destroyed by the caller.
*
* @param this message_t object
* @param ike_sa_id pointer to ike_sa_id pointer which will be set
* @return
* - SUCCESS
* - FAILED if no ike_sa_id is set
*/
status_t (*get_ike_sa_id) (message_t *this,ike_sa_id_t **ike_sa_id);
/**
* @brief Sets the exchange type of the message.
*
* @param this message_t object
* @param exchange_type exchange_type to set
*/
void (*set_exchange_type) (message_t *this,exchange_type_t exchange_type);
/**
* @brief Gets the exchange type of the message.
*
* @param this message_t object
* @return exchange type of the message
*/
exchange_type_t (*get_exchange_type) (message_t *this);
/**
* @brief Sets the request flag.
*
* @param this message_t object
* @param original_initiator TRUE if message is a request, FALSE if it is a reply
*/
void (*set_request) (message_t *this,bool request);
/**
* @brief Gets request flag.
*
* @param this message_t object
* @return TRUE if message is a request, FALSE if it is a reply
*/
bool (*get_request) (message_t *this);
/**
* @brief Append a payload to the message.
*
* If the payload must be encrypted is not specified here. Encryption
* of payloads is evaluated via internal rules for the messages and
* is done before generation. The order of payloads may change, since
* all payloads to encrypt are added to the encryption payload, which is
* always the last one.
*
* @param this message_t object
* @param payload payload to append
*/
void (*add_payload) (message_t *this, payload_t *payload);
/**
* @brief Parses header of message.
*
* Begins parisng of a message created via message_create_from_packet().
* The parsing context is stored, so a subsequent call to parse_body()
* will continue the parsing process.
*
* @param this message_t object
* @return
* - SUCCESS if header could be parsed
* - PARSE_ERROR if corrupted/invalid data found
* - FAILED if consistence check of header failed
*/
status_t (*parse_header) (message_t *this);
/**
* @brief Parses body of message.
*
* The body gets not only parsed, but rather it gets verified.
* All payloads are verified if they are allowed to exist in the message
* of this type and if their own structure is ok.
* If there are encrypted payloads, they get decrypted via the supplied
* crypter. Also the message integrity gets verified with the supplied
* signer.
* Crypter/signer can be omitted (by passing NULL) when no encryption
* payload is expected.
*
* @param this message_t object
* @param crypter crypter to decrypt encryption payloads
* @param signer signer to verifiy a message with an encryption payload
* @return
* - SUCCESS if header could be parsed
* - NOT_SUPPORTED if ciritcal unknown payloads found
* - FAILED if message type is not suppported!
* - PARSE_ERROR if corrupted/invalid data found
* - VERIFY_ERROR if verification of some payload failed
* - INVALID_STATE if crypter/signer not supplied, but needed
*/
status_t (*parse_body) (message_t *this, crypter_t *crypter, signer_t *signer);
/**
* @brief Generates the UDP packet of specific message.
*
* Payloads which must be encrypted are generated first and added to
* an encryption payload. This encryption payload will get encrypted via
* the supplied crypter. Then all other payloads and the header get generated.
* After that, the checksum is added to the encryption payload over the full
* message.
* Crypter/signer can be omitted (by passing NULL) when no encryption
* payload is expected.
*
* @param this message_t object
* @param crypter crypter to use when a payload must be encrypted
* @param signer signer to build a mac
* @return
* - SUCCESS if packet could be generated
* - INVALID_STATE if exchange type is currently not set
* - NOT_FOUND if no rules found for message generation
* - INVALID_STATE if crypter/signer not supplied but needed.
*/
status_t (*generate) (message_t *this, crypter_t *crypter, signer_t *signer, packet_t **packet);
/**
* @brief Gets the source host informations.
*
* @warning Returned host_t object is not getting cloned,
* do not destroy nor modify.
*
* @param this message_t object
* @return host_t object representing source host
*/
host_t * (*get_source) (message_t *this);
/**
* @brief Sets the source host informations.
*
* @warning host_t object is not getting cloned and gets destroyed by
* message_t.destroy or next call of message_t.set_source.
*
* @param this message_t object
* @param host host_t object representing source host
*/
void (*set_source) (message_t *this, host_t *host);
/**
* @brief Gets the destination host informations.
*
* @warning Returned host_t object is not getting cloned,
* do not destroy nor modify.
*
* @param this message_t object
* @return host_t object representing destination host
*/
host_t * (*get_destination) (message_t *this);
/**
* @brief Sets the destination host informations.
*
* @warning host_t object is not getting cloned and gets destroyed by
* message_t.destroy or next call of message_t.set_destination.
*
* @param this message_t object
* @param host host_t object representing destination host
*/
void (*set_destination) (message_t *this, host_t *host);
/**
* @brief Returns an iterator on all stored payloads.
*
* @warning Don't insert payloads over this iterator.
* Use add_payload() instead.
*
* @param this message_t object
* @return iterator_t object which has to get destroyd by the caller
*/
iterator_t * (*get_payload_iterator) (message_t *this);
/**
* Returns a clone of the internal stored packet_t object.
*
* @param this message_t object
* @return packet_t object as clone of internal one
*/
packet_t * (*get_packet) (message_t *this);
/**
* Returns a clone of the internal stored packet_t data.
*
* @param this message_t object
* @return clone of the internal stored packet_t data.
*/
chunk_t (*get_packet_data) (message_t *this);
/**
* @brief Destroys a message and all including objects.
*
* @param this message_t object
*/
void (*destroy) (message_t *this);
};
/**
* @brief Creates an message_t object from a incoming UDP Packet.
*
* @warning the given packet_t object is not copied and gets
* destroyed in message_t's destroy call.
*
* @warning Packet is not parsed in here!
*
* - exchange_type is set to NOT_SET
* - original_initiator is set to TRUE
* - is_request is set to TRUE
* Call message_t.parse_header afterwards.
*
* @param packet packet_t object which is assigned to message
* @return message_t object
*
* @ingroup encoding
*/
message_t * message_create_from_packet(packet_t *packet);
/**
* @brief Creates an empty message_t object.
*
* - exchange_type is set to NOT_SET
* - original_initiator is set to TRUE
* - is_request is set to TRUE
*
* @return message_t object
*
* @ingroup encoding
*/
message_t * message_create();
/**
* @brief Creates an message_t object of type reply containing a notify payload.
*
* @return message_t object
*
* @ingroup encoding
*/
message_t *message_create_notify_reply(host_t *source, host_t *destination, exchange_type_t exchange_type, bool original_initiator,ike_sa_id_t *ike_sa_id,notify_message_type_t notify_type);
#endif /*MESSAGE_H_*/

Some files were not shown because too many files have changed in this diff Show More