This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
# ipsec starter Makefile
|
||||
# Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
|
||||
#
|
||||
# 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.14 2006/02/17 19:34:02 as Exp $
|
||||
|
||||
FREESWANSRCDIR?=$(shell cd ../..; pwd)
|
||||
include ${FREESWANSRCDIR}/Makefile.inc
|
||||
|
||||
LD=$(CC)
|
||||
RM=rm
|
||||
LEX=flex
|
||||
BISON=bison
|
||||
GPERF=gperf
|
||||
|
||||
FREESWANDIR=../..
|
||||
FREESWANLIB=$(FREESWANDIR)/lib/libfreeswan/libfreeswan.a
|
||||
PLUTODIR=../pluto
|
||||
OPENACDIR=../openac
|
||||
|
||||
DEFINES+= -DVIRTUAL_IP -DDEBUG
|
||||
|
||||
# This compile option activates the leak detective
|
||||
ifeq ($(USE_LEAK_DETECTIVE),true)
|
||||
DEFINES+= -DLEAK_DETECTIVE
|
||||
endif
|
||||
|
||||
# Enable charon support
|
||||
ifeq ($(USE_IKEV2),true)
|
||||
DEFINES+= -DIKEV2
|
||||
endif
|
||||
|
||||
INCLUDES=-I${FREESWANDIR}/linux/include
|
||||
CFLAGS=$(DEFINES) $(INCLUDES) -Wall
|
||||
CFLAGS+=-DIPSEC_EXECDIR=\"${FINALLIBEXECDIR}\" -DIPSEC_CONFDDIR=\"${FINALCONFDDIR}\"
|
||||
CFLAGS+=-DIPSEC_CONFDIR=\"${FINALCONFDIR}\"
|
||||
LDFLAGS=
|
||||
|
||||
PLUTO_OBJS=defs.o
|
||||
|
||||
OBJS=starter.o parser.tab.o lex.yy.o keywords.o args.o invokepluto.o \
|
||||
starterwhack.o netkey.o interfaces.o exec.o cmp.o confread.o \
|
||||
loglite.o ${PLUTO_OBJS}
|
||||
|
||||
# Build charon-only objs
|
||||
ifeq ($(USE_IKEV2),true)
|
||||
OBJS+= invokecharon.o starterstroke.o
|
||||
endif
|
||||
|
||||
DISTSRC=$(OBJS:.o=.c)
|
||||
DISTSRC+=cmp.h confread.h confwrite.h exec.h files.h interfaces.h netkey.h
|
||||
DISTSRC+=parser.h args.h invokepluto.h starterwhack.h keywords.h keywords.txt
|
||||
|
||||
LIBS=$(FREESWANLIB)
|
||||
|
||||
PROGRAM=starter
|
||||
|
||||
include ../Makefile.program
|
||||
|
||||
all: starter
|
||||
|
||||
starter: $(OBJS) $(FREESWANLIB)
|
||||
$(LD) $(LDFLAGS) -o starter $(OBJS) $(LIBS)
|
||||
|
||||
lex.yy.c: parser.tab.c parser.l parser.y parser.h
|
||||
$(LEX) parser.l
|
||||
|
||||
parser.tab.c: parser.l parser.y parser.h
|
||||
$(BISON) -v -d parser.y
|
||||
|
||||
keywords.c: keywords.txt keywords.h
|
||||
$(GPERF) -C -G -t < keywords.txt > keywords.c
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
loglite.o : $(OPENACDIR)/loglite.c $(PLUTODIR)/log.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
# pluto library
|
||||
|
||||
defs.o : $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean::
|
||||
$(RM) -f starter $(OBJS) parser.tab.* lex.yy.*
|
||||
|
||||
# Stolen from pluto/Makefile
|
||||
|
||||
gatherdeps:
|
||||
@ls | grep '\.c$$' | sed -e 's/\(.*\)\.c$$/\1.o: \1.c/'
|
||||
@echo
|
||||
@ls | grep '\.c$$' | xargs grep '^#[ ]*include[ ]*"' | \
|
||||
sed -e 's/\.c:#[ ]*include[ ]*"/.o: /' -e 's/".*//'
|
||||
|
||||
# Dependencies generated by "make gatherdeps":
|
||||
|
||||
aargs.o: args.c
|
||||
cmp.o: cmp.c
|
||||
confread.o: confread.c
|
||||
exec.o: exec.c
|
||||
interfaces.o: interfaces.c
|
||||
invokecharon.o: invokecharon.c
|
||||
invokepluto.o: invokepluto.c
|
||||
keywords.o: keywords.c
|
||||
lex.yy.o: lex.yy.c
|
||||
netkey.o: netkey.c
|
||||
parser.tab.o: parser.tab.c
|
||||
starter.o: starter.c
|
||||
starterstroke.o: starterstroke.c
|
||||
starterwhack.o: starterwhack.c
|
||||
|
||||
args.o: ../pluto/constants.h
|
||||
args.o: ../pluto/defs.h
|
||||
args.o: ../pluto/log.h
|
||||
args.o: keywords.h
|
||||
args.o: parser.h
|
||||
args.o: confread.h
|
||||
args.o: args.h
|
||||
cmp.o: ../pluto/constants.h
|
||||
cmp.o: ../pluto/defs.h
|
||||
cmp.o: confread.h
|
||||
cmp.o: args.h
|
||||
cmp.o: interfaces.h
|
||||
cmp.o: cmp.h
|
||||
confread.o: ../pluto/constants.h
|
||||
confread.o: ../pluto/defs.h
|
||||
confread.o: ../pluto/log.h
|
||||
confread.o: keywords.h
|
||||
confread.o: parser.h
|
||||
confread.o: confread.h
|
||||
confread.o: args.h
|
||||
confread.o: interfaces.h
|
||||
exec.o: ../pluto/constants.h
|
||||
exec.o: ../pluto/defs.h
|
||||
exec.o: ../pluto/log.h
|
||||
exec.o: exec.h
|
||||
interfaces.o: ../pluto/constants.h
|
||||
interfaces.o: ../pluto/defs.h
|
||||
interfaces.o: ../pluto/log.h
|
||||
interfaces.o: interfaces.h
|
||||
interfaces.o: exec.h
|
||||
interfaces.o: files.h
|
||||
invokecharon.o: ../pluto/constants.h
|
||||
invokecharon.o: ../pluto/defs.h
|
||||
invokecharon.o: ../pluto/log.h
|
||||
invokecharon.o: confread.h
|
||||
invokecharon.o: invokecharon.h
|
||||
invokecharon.o: files.h
|
||||
invokepluto.o: ../pluto/constants.h
|
||||
invokepluto.o: ../pluto/defs.h
|
||||
invokepluto.o: ../pluto/log.h
|
||||
invokepluto.o: confread.h
|
||||
invokepluto.o: invokepluto.h
|
||||
invokepluto.o: files.h
|
||||
invokepluto.o: starterwhack.h
|
||||
keywords.o: keywords.h
|
||||
lex.yy.o: parser.tab.h
|
||||
netkey.o: ../pluto/constants.h
|
||||
netkey.o: ../pluto/defs.h
|
||||
netkey.o: ../pluto/log.h
|
||||
netkey.o: files.h
|
||||
parser.tab.o: ../pluto/constants.h
|
||||
parser.tab.o: ../pluto/defs.h
|
||||
parser.tab.o: ../pluto/log.h
|
||||
parser.tab.o: parser.h
|
||||
starter.o: ../pluto/constants.h
|
||||
starter.o: ../pluto/defs.h
|
||||
starter.o: ../pluto/log.h
|
||||
starter.o: confread.h
|
||||
starter.o: files.h
|
||||
starter.o: starterwhack.h
|
||||
starter.o: invokepluto.h
|
||||
starter.o: invokecharon.h
|
||||
starter.o: netkey.h
|
||||
starter.o: cmp.h
|
||||
starter.o: interfaces.h
|
||||
starterstroke.o: ../pluto/constants.h
|
||||
starterstroke.o: ../pluto/defs.h
|
||||
starterstroke.o: ../pluto/log.h
|
||||
starterstroke.o: ../charon/stroke/stroke.h
|
||||
starterstroke.o: starterstroke.h
|
||||
starterstroke.o: confread.h
|
||||
starterstroke.o: files.h
|
||||
starterwhack.o: ../pluto/constants.h
|
||||
starterwhack.o: ../pluto/defs.h
|
||||
starterwhack.o: ../pluto/log.h
|
||||
starterwhack.o: ../pluto/whack.h
|
||||
starterwhack.o: starterwhack.h
|
||||
starterwhack.o: confread.h
|
||||
starterwhack.o: files.h
|
||||
@@ -0,0 +1,104 @@
|
||||
|
||||
IPsec Starter -- Version 0.2 [Contributed by Arkoon Network Security]
|
||||
============================ [ http://www.arkoon.net/]
|
||||
|
||||
IPsec Starter is aimed to replace all the scripts which are used to
|
||||
start and stop strongSwan and to do that in a quicker and a smarter way.
|
||||
|
||||
IPsec Starter can also reload the configuration file (kill --HUP or periodicaly)
|
||||
and apply the changes.
|
||||
|
||||
Usage:
|
||||
starter [--debug] [--auto_update <x seconds>]
|
||||
--debug: enable debugging output
|
||||
--no_fork: all msg (including pluto) are sent to the console
|
||||
--auto_update: reload the config file (like kill -HUP) every x seconds
|
||||
and determine any configuration changes
|
||||
|
||||
FEATURES
|
||||
--------
|
||||
|
||||
o Load and unload KLIPS (ipsec.o kernel module)
|
||||
|
||||
o Load modules of the native Linux 2.6 IPsec stack
|
||||
|
||||
o Launch and monitor pluto
|
||||
|
||||
o Add, initiate, route and del connections
|
||||
|
||||
o Attach and detach interfaces according to config file
|
||||
|
||||
o kill -HUP can be used to reload the config file. New connections will be
|
||||
added, old ones will be removed and modified ones will be reloaded.
|
||||
Interfaces/Klips/Pluto will be reloaded if necessary.
|
||||
|
||||
o Full support of the %defaultroute wildcard parameter.
|
||||
|
||||
o save own pid in /var/run/starter
|
||||
|
||||
o Upon reloading, dynamic DNS addr will be resolved and reloaded. Use
|
||||
--auto_update to periodicaly check dynamic DNS changes.
|
||||
|
||||
o kill -USR1 can be used to reload all connections (delete then add and
|
||||
route/initiate)
|
||||
|
||||
o /var/run/dynip/xxxx can be used to use a virtual interface name in
|
||||
ipsec.conf. By example, when adsl can be ppp0, ppp1, ... :
|
||||
ipsec.conf: interfaces="ipsec0=adsl"
|
||||
And use /etc/ppp/ip-up to create /var/run/dynip/adsl
|
||||
/var/run/dynip/adsl: IP_PHYS=ppp0
|
||||
|
||||
o %auto can be used to automaticaly name the connections
|
||||
|
||||
o kill -TERM can be used to stop FS. pluto will be stopped and KLIPS unloaded
|
||||
(if it has been loaded).
|
||||
|
||||
o Can be used to start strongSwan and load lots of connections in a few
|
||||
seconds.
|
||||
|
||||
TODO
|
||||
----
|
||||
|
||||
o handle wildcards in include lines -- use glob() fct
|
||||
ex: include /etc/ipsec.*.conf
|
||||
|
||||
o handle duplicates keywords and sections
|
||||
|
||||
o 'also' keyword not supported
|
||||
|
||||
o manually keyed connections
|
||||
|
||||
o IPv6
|
||||
|
||||
o Documentation
|
||||
|
||||
|
||||
CHANGES
|
||||
-------
|
||||
|
||||
o Version 0.1 -- 2002.01.14 -- First public release
|
||||
|
||||
o Version 0.2 -- 2002.09.04 -- Various enhancements
|
||||
FreeS/WAN 1.98b, x509 0.9.14, algo 0.8.0
|
||||
|
||||
o Version 0.2d -- 2004.01.13 -- Adaptions for Openswan 1.0.0
|
||||
by Stephan Scholz <[email protected]>
|
||||
|
||||
o Version 0.2e -- 2004.10.14 -- Added support for change of interface address
|
||||
by Stephan Scholz <[email protected]>
|
||||
|
||||
o Version 0.2s -- 2005-12-02 -- Ported to strongSwan
|
||||
by Stephan Scholz <[email protected]>
|
||||
|
||||
o Version 0.2x -- 2006-01-02 -- Added missing strongSwan keywords
|
||||
Full support of the native Linux 2.6 IPsec stack
|
||||
Full support of %defaultroute
|
||||
Improved parsing of keywords using perfect hash
|
||||
function generated by gperf.
|
||||
by Andreas Steffen <[email protected]>
|
||||
|
||||
THANKS
|
||||
------
|
||||
|
||||
o Nathan Angelacos - include fix
|
||||
|
||||
@@ -0,0 +1,624 @@
|
||||
/* automatic handling of confread struct arguments
|
||||
* Copyright (C) 2006 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil, Switzerland
|
||||
*
|
||||
* 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: args.c,v 1.9 2006/04/17 10:32:36 as Exp $
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
|
||||
#include "keywords.h"
|
||||
#include "parser.h"
|
||||
#include "confread.h"
|
||||
#include "args.h"
|
||||
|
||||
/* argument types */
|
||||
|
||||
typedef enum {
|
||||
ARG_NONE,
|
||||
ARG_ENUM,
|
||||
ARG_UINT,
|
||||
ARG_TIME,
|
||||
ARG_ULNG,
|
||||
ARG_PCNT,
|
||||
ARG_STR,
|
||||
ARG_LST,
|
||||
ARG_MISC
|
||||
} arg_t;
|
||||
|
||||
/* various keyword lists */
|
||||
|
||||
static const char *LST_bool[] = {
|
||||
"no",
|
||||
"yes",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *LST_sendcert[] = {
|
||||
"always",
|
||||
"ifasked",
|
||||
"never",
|
||||
"yes",
|
||||
"no",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *LST_dpd_action[] = {
|
||||
"none",
|
||||
"clear",
|
||||
"hold",
|
||||
"restart",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *LST_startup[] = {
|
||||
"ignore",
|
||||
"add",
|
||||
"route",
|
||||
"start",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *LST_packetdefault[] = {
|
||||
"drop",
|
||||
"reject",
|
||||
"pass",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *LST_keyexchange[] = {
|
||||
"ike",
|
||||
#ifdef IKEV2
|
||||
"ikev1",
|
||||
"ikev2",
|
||||
#endif /* IKEV2 */
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *LST_pfsgroup[] = {
|
||||
"modp1024",
|
||||
"modp1536",
|
||||
"modp2048",
|
||||
"modp3072",
|
||||
"modp4096",
|
||||
"modp6144",
|
||||
"modp8192",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *LST_plutodebug[] = {
|
||||
"none",
|
||||
"all",
|
||||
"raw",
|
||||
"crypt",
|
||||
"parsing",
|
||||
"emitting",
|
||||
"control",
|
||||
"lifecycle",
|
||||
"klips",
|
||||
"dns",
|
||||
"natt",
|
||||
"oppo",
|
||||
"controlmore",
|
||||
"private",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *LST_klipsdebug[] = {
|
||||
"tunnel",
|
||||
"tunnel-xmit",
|
||||
"pfkey",
|
||||
"xform",
|
||||
"eroute",
|
||||
"spi",
|
||||
"radij",
|
||||
"esp",
|
||||
"ah",
|
||||
"ipcomp",
|
||||
"verbose",
|
||||
"all",
|
||||
"none",
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
arg_t type;
|
||||
size_t offset;
|
||||
const char **list;
|
||||
} token_info_t;
|
||||
|
||||
static const token_info_t token_info[] =
|
||||
{
|
||||
/* config setup keywords */
|
||||
{ ARG_LST, offsetof(starter_config_t, setup.interfaces), NULL },
|
||||
{ ARG_STR, offsetof(starter_config_t, setup.dumpdir), NULL },
|
||||
|
||||
/* pluto keywords */
|
||||
{ ARG_LST, offsetof(starter_config_t, setup.plutodebug), LST_plutodebug },
|
||||
{ ARG_STR, offsetof(starter_config_t, setup.prepluto), NULL },
|
||||
{ ARG_STR, offsetof(starter_config_t, setup.postpluto), NULL },
|
||||
{ ARG_ENUM, offsetof(starter_config_t, setup.uniqueids), LST_bool },
|
||||
{ ARG_UINT, offsetof(starter_config_t, setup.overridemtu), NULL },
|
||||
{ ARG_TIME, offsetof(starter_config_t, setup.crlcheckinterval), NULL },
|
||||
{ ARG_ENUM, offsetof(starter_config_t, setup.cachecrls), LST_bool },
|
||||
{ ARG_ENUM, offsetof(starter_config_t, setup.strictcrlpolicy), LST_bool },
|
||||
{ ARG_ENUM, offsetof(starter_config_t, setup.nocrsend), LST_bool },
|
||||
{ ARG_ENUM, offsetof(starter_config_t, setup.nat_traversal), LST_bool },
|
||||
{ ARG_TIME, offsetof(starter_config_t, setup.keep_alive), NULL },
|
||||
{ ARG_STR, offsetof(starter_config_t, setup.virtual_private), NULL },
|
||||
{ ARG_STR, offsetof(starter_config_t, setup.pkcs11module), NULL },
|
||||
{ ARG_ENUM, offsetof(starter_config_t, setup.pkcs11keepstate), LST_bool },
|
||||
{ ARG_ENUM, offsetof(starter_config_t, setup.pkcs11proxy), LST_bool },
|
||||
|
||||
/* KLIPS keywords */
|
||||
{ ARG_LST, offsetof(starter_config_t, setup.klipsdebug), LST_klipsdebug },
|
||||
{ ARG_ENUM, offsetof(starter_config_t, setup.fragicmp), LST_bool },
|
||||
{ ARG_STR, offsetof(starter_config_t, setup.packetdefault), LST_packetdefault },
|
||||
{ ARG_ENUM, offsetof(starter_config_t, setup.hidetos), LST_bool },
|
||||
|
||||
/* conn section keywords */
|
||||
{ ARG_STR, offsetof(starter_conn_t, name), NULL },
|
||||
{ ARG_ENUM, offsetof(starter_conn_t, startup), LST_startup },
|
||||
{ ARG_ENUM, offsetof(starter_conn_t, keyexchange), LST_keyexchange },
|
||||
{ ARG_MISC, 0, NULL /* KW_TYPE */ },
|
||||
{ ARG_MISC, 0, NULL /* KW_PFS */ },
|
||||
{ ARG_MISC, 0, NULL /* KW_COMPRESS */ },
|
||||
{ ARG_MISC, 0, NULL /* KW_AUTH */ },
|
||||
{ ARG_MISC, 0, NULL /* KW_AUTHBY */ },
|
||||
{ ARG_TIME, offsetof(starter_conn_t, sa_ike_life_seconds), NULL },
|
||||
{ ARG_TIME, offsetof(starter_conn_t, sa_ipsec_life_seconds), NULL },
|
||||
{ ARG_TIME, offsetof(starter_conn_t, sa_rekey_margin), NULL },
|
||||
{ ARG_ULNG, offsetof(starter_conn_t, sa_keying_tries), NULL },
|
||||
{ ARG_PCNT, offsetof(starter_conn_t, sa_rekey_fuzz), NULL },
|
||||
{ ARG_MISC, 0, NULL /* KW_REKEY */ },
|
||||
{ ARG_STR, offsetof(starter_conn_t, ike), NULL },
|
||||
{ ARG_STR, offsetof(starter_conn_t, esp), NULL },
|
||||
{ ARG_STR, offsetof(starter_conn_t, pfsgroup), LST_pfsgroup },
|
||||
{ ARG_TIME, offsetof(starter_conn_t, dpd_delay), NULL },
|
||||
{ ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL },
|
||||
{ ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action },
|
||||
|
||||
/* ca section keywords */
|
||||
{ ARG_STR, offsetof(starter_ca_t, name), NULL },
|
||||
{ ARG_ENUM, offsetof(starter_ca_t, startup), LST_startup },
|
||||
{ ARG_STR, offsetof(starter_ca_t, cacert), NULL },
|
||||
{ ARG_STR, offsetof(starter_ca_t, ldaphost), NULL },
|
||||
{ ARG_STR, offsetof(starter_ca_t, ldapbase), NULL },
|
||||
{ ARG_STR, offsetof(starter_ca_t, crluri), NULL },
|
||||
{ ARG_STR, offsetof(starter_ca_t, crluri2), NULL },
|
||||
{ ARG_STR, offsetof(starter_ca_t, ocspuri), NULL },
|
||||
|
||||
/* end keywords */
|
||||
{ ARG_MISC, 0, NULL /* KW_HOST */ },
|
||||
{ ARG_MISC, 0, NULL /* KW_NEXTHOP */ },
|
||||
{ ARG_MISC, 0, NULL /* KW_SUBNET */ },
|
||||
{ ARG_MISC, 0, NULL /* KW_SUBNETWITHIN */ },
|
||||
{ ARG_MISC, 0, NULL /* KW_PROTOPORT */ },
|
||||
{ ARG_MISC, 0, NULL /* KW_SOURCEIP */ },
|
||||
{ ARG_ENUM, offsetof(starter_end_t, firewall), LST_bool },
|
||||
{ ARG_ENUM, offsetof(starter_end_t, hostaccess), LST_bool },
|
||||
{ ARG_STR, offsetof(starter_end_t, updown), NULL },
|
||||
{ ARG_STR, offsetof(starter_end_t, id), NULL },
|
||||
{ ARG_STR, offsetof(starter_end_t, rsakey), NULL },
|
||||
{ ARG_STR, offsetof(starter_end_t, cert), NULL },
|
||||
{ ARG_ENUM, offsetof(starter_end_t, sendcert), LST_sendcert },
|
||||
{ ARG_STR, offsetof(starter_end_t, ca), NULL },
|
||||
{ ARG_STR, offsetof(starter_end_t, groups), NULL },
|
||||
{ ARG_STR, offsetof(starter_end_t, iface), NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
free_list(char **list)
|
||||
{
|
||||
char **s;
|
||||
|
||||
for (s = list; *s; s++)
|
||||
pfree(*s);
|
||||
pfree(list);
|
||||
}
|
||||
|
||||
char **
|
||||
new_list(char *value)
|
||||
{
|
||||
char *val, *b, *e, *end, **ret;
|
||||
int count;
|
||||
|
||||
val = value ? clone_str(value, "list value") : NULL;
|
||||
if (!val)
|
||||
return NULL;
|
||||
end = val + strlen(val);
|
||||
for (b = val, count = 0; b < end;)
|
||||
{
|
||||
for (e = b; ((*e != ' ') && (*e != '\0')); e++);
|
||||
*e = '\0';
|
||||
if (e != b)
|
||||
count++;
|
||||
b = e + 1;
|
||||
}
|
||||
if (count == 0)
|
||||
{
|
||||
pfree(val);
|
||||
return NULL;
|
||||
}
|
||||
ret = (char **)alloc_bytes((count+1) * sizeof(char *), "list");
|
||||
|
||||
for (b = val, count = 0; b < end; )
|
||||
{
|
||||
for (e = b; (*e != '\0'); e++);
|
||||
if (e != b)
|
||||
ret[count++] = clone_str(b, "list value");
|
||||
b = e + 1;
|
||||
}
|
||||
ret[count] = NULL;
|
||||
pfree(val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* assigns an argument value to a struct field
|
||||
*/
|
||||
bool
|
||||
assign_arg(kw_token_t token, kw_token_t first, kw_list_t *kw, char *base
|
||||
, bool *assigned)
|
||||
{
|
||||
char *p = base + token_info[token].offset;
|
||||
const char **list = token_info[token].list;
|
||||
|
||||
int index = -1; /* used for enumeration arguments */
|
||||
|
||||
lset_t *seen = (lset_t *)base; /* seen flags are at the top of the struct */
|
||||
lset_t f = LELEM(token - first); /* compute flag position of argument */
|
||||
|
||||
*assigned = FALSE;
|
||||
|
||||
DBG(DBG_CONTROLMORE,
|
||||
DBG_log(" %s=%s", kw->entry->name, kw->value)
|
||||
)
|
||||
|
||||
if (*seen & f)
|
||||
{
|
||||
plog("# duplicate '%s' option", kw->entry->name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* set flag that this argument has been seen */
|
||||
*seen |= f;
|
||||
|
||||
/* is there a keyword list? */
|
||||
if (list != NULL && token_info[token].type != ARG_LST)
|
||||
{
|
||||
bool match = FALSE;
|
||||
|
||||
while (*list != NULL && !match)
|
||||
{
|
||||
index++;
|
||||
match = streq(kw->value, *list++);
|
||||
}
|
||||
if (!match)
|
||||
{
|
||||
plog("# bad value: %s=%s", kw->entry->name, kw->value);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
switch (token_info[token].type)
|
||||
{
|
||||
case ARG_NONE:
|
||||
plog("# option '%s' not supported yet", kw->entry->name);
|
||||
return FALSE;
|
||||
case ARG_ENUM:
|
||||
{
|
||||
int *i = (int *)p;
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
plog("# bad enumeration value: %s=%s (%d)"
|
||||
, kw->entry->name, kw->value, index);
|
||||
return FALSE;
|
||||
}
|
||||
*i = index;
|
||||
}
|
||||
break;
|
||||
|
||||
case ARG_UINT:
|
||||
{
|
||||
char *endptr;
|
||||
u_int *u = (u_int *)p;
|
||||
|
||||
*u = strtoul(kw->value, &endptr, 10);
|
||||
|
||||
if (*endptr != '\0')
|
||||
{
|
||||
plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ARG_ULNG:
|
||||
case ARG_PCNT:
|
||||
{
|
||||
char *endptr;
|
||||
unsigned long *l = (unsigned long *)p;
|
||||
|
||||
*l = strtoul(kw->value, &endptr, 10);
|
||||
|
||||
if (token_info[token].type == ARG_ULNG)
|
||||
{
|
||||
if (*endptr != '\0')
|
||||
{
|
||||
plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*endptr != '%') || (endptr[1] != '\0') || endptr == kw->value)
|
||||
{
|
||||
plog("# bad percent value: %s=%s", kw->entry->name, kw->value);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case ARG_TIME:
|
||||
{
|
||||
char *endptr;
|
||||
time_t *t = (time_t *)p;
|
||||
|
||||
*t = strtoul(kw->value, &endptr, 10);
|
||||
|
||||
/* time in seconds? */
|
||||
if (*endptr == '\0' || (*endptr == 's' && endptr[1] == '\0'))
|
||||
break;
|
||||
|
||||
if (endptr[1] == '\0')
|
||||
{
|
||||
if (*endptr == 'm') /* time in minutes? */
|
||||
{
|
||||
*t *= 60;
|
||||
break;
|
||||
}
|
||||
if (*endptr == 'h') /* time in hours? */
|
||||
{
|
||||
*t *= 3600;
|
||||
break;
|
||||
}
|
||||
if (*endptr == 'd') /* time in days? */
|
||||
{
|
||||
*t *= 3600*24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
plog("# bad duration value: %s=%s", kw->entry->name, kw->value);
|
||||
return FALSE;
|
||||
}
|
||||
case ARG_STR:
|
||||
{
|
||||
char **cp = (char **)p;
|
||||
|
||||
/* free any existing string */
|
||||
pfreeany(*cp);
|
||||
|
||||
/* assign the new string */
|
||||
*cp = clone_str(kw->value, "str_value");
|
||||
}
|
||||
break;
|
||||
case ARG_LST:
|
||||
{
|
||||
char ***listp = (char ***)p;
|
||||
|
||||
/* free any existing list */
|
||||
if (*listp != NULL)
|
||||
free_list(*listp);
|
||||
|
||||
/* create a new list and assign values */
|
||||
*listp = new_list(kw->value);
|
||||
|
||||
/* is there a keyword list? */
|
||||
if (list != NULL)
|
||||
{
|
||||
char ** lst;
|
||||
|
||||
for (lst = *listp; lst && *lst; lst++)
|
||||
{
|
||||
bool match = FALSE;
|
||||
|
||||
list = token_info[token].list;
|
||||
|
||||
while (*list != NULL && !match)
|
||||
{
|
||||
match = streq(*lst, *list++);
|
||||
}
|
||||
if (!match)
|
||||
{
|
||||
plog("# bad value: %s=%s", kw->entry->name, *lst);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*assigned = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* frees all dynamically allocated arguments in a struct
|
||||
*/
|
||||
void
|
||||
free_args(kw_token_t first, kw_token_t last, char *base)
|
||||
{
|
||||
kw_token_t token;
|
||||
|
||||
for (token = first; token <= last; token++)
|
||||
{
|
||||
char *p = base + token_info[token].offset;
|
||||
|
||||
switch (token_info[token].type)
|
||||
{
|
||||
case ARG_STR:
|
||||
{
|
||||
char **cp = (char **)p;
|
||||
|
||||
pfreeany(*cp);
|
||||
*cp = NULL;
|
||||
}
|
||||
break;
|
||||
case ARG_LST:
|
||||
{
|
||||
char ***listp = (char ***)p;
|
||||
|
||||
if (*listp != NULL)
|
||||
{
|
||||
free_list(*listp);
|
||||
*listp = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* clone all dynamically allocated arguments in a struct
|
||||
*/
|
||||
void
|
||||
clone_args(kw_token_t first, kw_token_t last, char *base1, char *base2)
|
||||
{
|
||||
kw_token_t token;
|
||||
|
||||
for (token = first; token <= last; token++)
|
||||
{
|
||||
if (token_info[token].type == ARG_STR)
|
||||
{
|
||||
char **cp1 = (char **)(base1 + token_info[token].offset);
|
||||
char **cp2 = (char **)(base2 + token_info[token].offset);
|
||||
|
||||
*cp1 = clone_str(*cp2, "cloned str");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
cmp_list(char **list1, char **list2)
|
||||
{
|
||||
if ((list1 == NULL) && (list2 == NULL))
|
||||
return TRUE;
|
||||
if ((list1 == NULL) || (list2 == NULL))
|
||||
return FALSE;
|
||||
|
||||
for ( ; *list1 && *list2; list1++, list2++)
|
||||
{
|
||||
if (strcmp(*list1,*list2) != 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((*list1 != NULL) || (*list2 != NULL))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* compare all arguments in a struct
|
||||
*/
|
||||
bool
|
||||
cmp_args(kw_token_t first, kw_token_t last, char *base1, char *base2)
|
||||
{
|
||||
kw_token_t token;
|
||||
|
||||
for (token = first; token <= last; token++)
|
||||
{
|
||||
char *p1 = base1 + token_info[token].offset;
|
||||
char *p2 = base2 + token_info[token].offset;
|
||||
|
||||
switch (token_info[token].type)
|
||||
{
|
||||
case ARG_ENUM:
|
||||
{
|
||||
int *i1 = (int *)p1;
|
||||
int *i2 = (int *)p2;
|
||||
|
||||
if (*i1 != *i2)
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case ARG_UINT:
|
||||
{
|
||||
u_int *u1 = (u_int *)p1;
|
||||
u_int *u2 = (u_int *)p2;
|
||||
|
||||
if (*u1 != *u2)
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case ARG_ULNG:
|
||||
case ARG_PCNT:
|
||||
{
|
||||
unsigned long *l1 = (unsigned long *)p1;
|
||||
unsigned long *l2 = (unsigned long *)p2;
|
||||
|
||||
if (*l1 != *l2)
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case ARG_TIME:
|
||||
{
|
||||
time_t *t1 = (time_t *)p1;
|
||||
time_t *t2 = (time_t *)p2;
|
||||
|
||||
if (*t1 != *t2)
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case ARG_STR:
|
||||
{
|
||||
char **cp1 = (char **)p1;
|
||||
char **cp2 = (char **)p2;
|
||||
|
||||
if (*cp1 == NULL && *cp2 == NULL)
|
||||
break;
|
||||
if (*cp1 == NULL || *cp2 == NULL || strcmp(*cp1, *cp2) != 0)
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case ARG_LST:
|
||||
{
|
||||
char ***listp1 = (char ***)p1;
|
||||
char ***listp2 = (char ***)p2;
|
||||
|
||||
if (!cmp_list(*listp1, *listp2))
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/* automatic handling of confread struct arguments
|
||||
* Copyright (C) 2006 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil, Switzerland
|
||||
*
|
||||
* 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: args.h,v 1.3 2006/01/13 18:02:02 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _ARGS_H_
|
||||
#define _ARGS_H_
|
||||
|
||||
#include "keywords.h"
|
||||
#include "parser.h"
|
||||
|
||||
extern char **new_list(char *value);
|
||||
extern bool assign_arg(kw_token_t token, kw_token_t first, kw_list_t *kw
|
||||
, char *base, bool *assigned);
|
||||
extern void free_args(kw_token_t first, kw_token_t last, char *base);
|
||||
extern void clone_args(kw_token_t first, kw_token_t last, char *base1
|
||||
, char *base2);
|
||||
extern bool cmp_args(kw_token_t first, kw_token_t last, char *base1
|
||||
, char *base2);
|
||||
|
||||
#endif /* _ARGS_H_ */
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/* strongSwan IPsec starter comparison functions
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: cmp.c,v 1.12 2006/01/13 18:03:25 as Exp $
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
|
||||
#include "confread.h"
|
||||
#include "args.h"
|
||||
#include "interfaces.h"
|
||||
#include "cmp.h"
|
||||
|
||||
#define VARCMP(obj) if (c1->obj != c2->obj) return FALSE
|
||||
#define ADDCMP(obj) if (!sameaddr(&c1->obj,&c2->obj)) return FALSE
|
||||
#define SUBCMP(obj) if (!samesubnet(&c1->obj,&c2->obj)) return FALSE
|
||||
|
||||
static bool
|
||||
starter_cmp_end(starter_end_t *c1, starter_end_t *c2)
|
||||
{
|
||||
if ((c1 == NULL) || (c2 == NULL))
|
||||
return FALSE;
|
||||
|
||||
ADDCMP(addr);
|
||||
ADDCMP(nexthop);
|
||||
ADDCMP(srcip);
|
||||
SUBCMP(subnet);
|
||||
VARCMP(has_client);
|
||||
VARCMP(has_client_wildcard);
|
||||
VARCMP(has_port_wildcard);
|
||||
VARCMP(has_srcip);
|
||||
VARCMP(modecfg);
|
||||
VARCMP(port);
|
||||
VARCMP(protocol);
|
||||
|
||||
return cmp_args(KW_END_FIRST, KW_END_LAST, (char *)c1, (char *)c2);
|
||||
}
|
||||
|
||||
bool
|
||||
starter_cmp_conn(starter_conn_t *c1, starter_conn_t *c2)
|
||||
{
|
||||
if ((c1 == NULL) || (c2 == NULL))
|
||||
return FALSE;
|
||||
|
||||
VARCMP(policy);
|
||||
VARCMP(addr_family);
|
||||
VARCMP(tunnel_addr_family);
|
||||
|
||||
if (!starter_cmp_end(&c1->left, &c2->left))
|
||||
return FALSE;
|
||||
if (!starter_cmp_end(&c1->right, &c2->right))
|
||||
return FALSE;
|
||||
|
||||
return cmp_args(KW_CONN_NAME, KW_CONN_LAST, (char *)c1, (char *)c2);
|
||||
}
|
||||
|
||||
bool
|
||||
starter_cmp_ca(starter_ca_t *c1, starter_ca_t *c2)
|
||||
{
|
||||
if (c1 == NULL || c2 == NULL)
|
||||
return FALSE;
|
||||
|
||||
return cmp_args(KW_CA_NAME, KW_CA_LAST, (char *)c1, (char *)c2);
|
||||
}
|
||||
|
||||
bool
|
||||
starter_cmp_klips(starter_config_t *c1, starter_config_t *c2)
|
||||
{
|
||||
if ((c1 == NULL) || (c2 == NULL))
|
||||
return FALSE;
|
||||
|
||||
return cmp_args(KW_KLIPS_FIRST, KW_KLIPS_LAST, (char *)c1, (char *)c2);
|
||||
}
|
||||
|
||||
bool
|
||||
starter_cmp_pluto(starter_config_t *c1, starter_config_t *c2)
|
||||
{
|
||||
if ((c1 == NULL) || (c2 == NULL))
|
||||
return FALSE;
|
||||
|
||||
return cmp_args(KW_PLUTO_FIRST, KW_PLUTO_LAST, (char *)c1, (char *)c2);
|
||||
}
|
||||
|
||||
bool
|
||||
starter_cmp_defaultroute(defaultroute_t *d1, defaultroute_t *d2)
|
||||
{
|
||||
if ((d1 == NULL) || (d2 == NULL))
|
||||
return FALSE;
|
||||
return memcmp(d1, d2, sizeof(defaultroute_t)) == 0;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/* strongSwan IPsec starter comparison functions
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: cmp.h,v 1.4 2006/01/06 20:24:41 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_CMP_H_
|
||||
#define _STARTER_CMP_H_
|
||||
|
||||
#include "interfaces.h"
|
||||
|
||||
extern bool starter_cmp_conn(starter_conn_t *c1, starter_conn_t *c2);
|
||||
extern bool starter_cmp_ca(starter_ca_t *c1, starter_ca_t *c2);
|
||||
extern bool starter_cmp_klips(starter_config_t *c1, starter_config_t *c2);
|
||||
extern bool starter_cmp_pluto(starter_config_t *c1, starter_config_t *c2);
|
||||
extern bool starter_cmp_defaultroute(defaultroute_t *d1, defaultroute_t *d2);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,861 @@
|
||||
/* strongSwan IPsec config file parser
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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.c,v 1.37 2006/04/17 19:35:07 as Exp $
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
|
||||
#include "keywords.h"
|
||||
#include "parser.h"
|
||||
#include "confread.h"
|
||||
#include "args.h"
|
||||
#include "interfaces.h"
|
||||
|
||||
static const char ike_defaults[] = "3des-sha, 3des-md5";
|
||||
static const char esp_defaults[] = "3des-sha1, 3des-md5";
|
||||
|
||||
static const char firewall_defaults[] = "ipsec _updown iptables";
|
||||
|
||||
static void
|
||||
default_values(starter_config_t *cfg)
|
||||
{
|
||||
if (cfg == NULL)
|
||||
return;
|
||||
|
||||
memset(cfg, 0, sizeof(struct starter_config));
|
||||
|
||||
/* is there enough space for all seen flags? */
|
||||
assert(KW_SETUP_LAST - KW_SETUP_FIRST <
|
||||
sizeof(cfg->setup.seen) * BITS_PER_BYTE);
|
||||
assert(KW_CONN_LAST - KW_CONN_FIRST <
|
||||
sizeof(cfg->conn_default.seen) * BITS_PER_BYTE);
|
||||
assert(KW_END_LAST - KW_END_FIRST <
|
||||
sizeof(cfg->conn_default.right.seen) * BITS_PER_BYTE);
|
||||
assert(KW_CA_LAST - KW_CA_FIRST <
|
||||
sizeof(cfg->ca_default.seen) * BITS_PER_BYTE);
|
||||
|
||||
cfg->setup.seen = LEMPTY;
|
||||
cfg->setup.fragicmp = TRUE;
|
||||
cfg->setup.hidetos = TRUE;
|
||||
cfg->setup.uniqueids = TRUE;
|
||||
cfg->setup.interfaces = new_list("%defaultroute");
|
||||
|
||||
cfg->conn_default.seen = LEMPTY;
|
||||
cfg->conn_default.startup = STARTUP_NO;
|
||||
cfg->conn_default.state = STATE_IGNORE;
|
||||
cfg->conn_default.policy = POLICY_ENCRYPT | POLICY_TUNNEL | POLICY_RSASIG
|
||||
| POLICY_PFS;
|
||||
|
||||
cfg->conn_default.ike = clone_str(ike_defaults, "ike_defaults");
|
||||
cfg->conn_default.esp = clone_str(esp_defaults, "esp_defaults");
|
||||
cfg->conn_default.sa_ike_life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT;
|
||||
cfg->conn_default.sa_ipsec_life_seconds = PLUTO_SA_LIFE_DURATION_DEFAULT;
|
||||
cfg->conn_default.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT;
|
||||
cfg->conn_default.sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT;
|
||||
cfg->conn_default.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT;
|
||||
cfg->conn_default.addr_family = AF_INET;
|
||||
cfg->conn_default.tunnel_addr_family = AF_INET;
|
||||
|
||||
cfg->conn_default.left.seen = LEMPTY;
|
||||
cfg->conn_default.right.seen = LEMPTY;
|
||||
|
||||
anyaddr(AF_INET, &cfg->conn_default.left.addr);
|
||||
anyaddr(AF_INET, &cfg->conn_default.left.nexthop);
|
||||
anyaddr(AF_INET, &cfg->conn_default.left.srcip);
|
||||
anyaddr(AF_INET, &cfg->conn_default.right.addr);
|
||||
anyaddr(AF_INET, &cfg->conn_default.right.nexthop);
|
||||
anyaddr(AF_INET, &cfg->conn_default.right.srcip);
|
||||
|
||||
cfg->ca_default.seen = LEMPTY;
|
||||
}
|
||||
|
||||
#define KW_POLICY_FLAG(sy, sn, fl) \
|
||||
if (streq(kw->value, sy)) { conn->policy |= fl; } \
|
||||
else if (streq(kw->value, sn)) { conn->policy &= ~fl; } \
|
||||
else { plog("# bad policy value: %s=%s", kw->entry->name, kw->value); cfg->err++; }
|
||||
|
||||
static void
|
||||
load_setup(starter_config_t *cfg, config_parsed_t *cfgp)
|
||||
{
|
||||
kw_list_t *kw;
|
||||
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Loading config setup")
|
||||
)
|
||||
|
||||
for (kw = cfgp->config_setup; kw; kw = kw->next)
|
||||
{
|
||||
bool assigned = FALSE;
|
||||
|
||||
kw_token_t token = kw->entry->token;
|
||||
|
||||
if (token < KW_SETUP_FIRST || token > KW_SETUP_LAST)
|
||||
{
|
||||
plog("# unsupported keyword '%s' in config setup", kw->entry->name);
|
||||
cfg->err++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!assign_arg(token, KW_SETUP_FIRST, kw, (char *)cfg, &assigned))
|
||||
{
|
||||
plog(" bad argument value in config setup");
|
||||
cfg->err++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
|
||||
, kw_list_t *kw, char *conn_name, starter_config_t *cfg)
|
||||
{
|
||||
err_t ugh = NULL;
|
||||
bool assigned = FALSE;
|
||||
int has_port_wildcard; /* set if port is %any */
|
||||
|
||||
char *name = kw->entry->name;
|
||||
char *value = kw->value;
|
||||
|
||||
if (!assign_arg(token, KW_END_FIRST, kw, (char *)end, &assigned))
|
||||
goto err;
|
||||
|
||||
if (token == KW_SENDCERT)
|
||||
{
|
||||
if (end->sendcert == CERT_YES_SEND)
|
||||
end->sendcert = CERT_ALWAYS_SEND;
|
||||
else if (end->sendcert == CERT_NO_SEND)
|
||||
end->sendcert = CERT_NEVER_SEND;
|
||||
}
|
||||
|
||||
if (assigned)
|
||||
return;
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case KW_HOST:
|
||||
if (streq(value, "%defaultroute"))
|
||||
{
|
||||
if (cfg->defaultroute.defined)
|
||||
{
|
||||
end->addr = cfg->defaultroute.addr;
|
||||
end->nexthop = cfg->defaultroute.nexthop;
|
||||
}
|
||||
else
|
||||
{
|
||||
plog("# default route not known: %s=%s", name, value);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else if (streq(value,"%any"))
|
||||
{
|
||||
anyaddr(conn->addr_family, &end->addr);
|
||||
}
|
||||
else if (value[0] == '%')
|
||||
{
|
||||
if (end->iface)
|
||||
pfree(end->iface);
|
||||
end->iface = clone_str(value+1, "iface");
|
||||
if (starter_iface_find(end->iface, conn->addr_family, &end->addr,
|
||||
&end->nexthop) == -1)
|
||||
{
|
||||
conn->state = STATE_INVALID;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ugh = ttoaddr(value, 0, conn->addr_family, &end->addr);
|
||||
if (ugh != NULL)
|
||||
{
|
||||
plog("# bad addr: %s=%s [%s]", name, value, ugh);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KW_NEXTHOP:
|
||||
if (streq(value, "%defaultroute"))
|
||||
{
|
||||
if (cfg->defaultroute.defined)
|
||||
end->nexthop = cfg->defaultroute.nexthop;
|
||||
else
|
||||
{
|
||||
plog("# default route not known: %s=%s", name, value);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else if (streq(value, "%direct"))
|
||||
ugh = anyaddr(conn->addr_family, &end->nexthop);
|
||||
else
|
||||
ugh = ttoaddr(value, 0, conn->addr_family, &end->nexthop);
|
||||
|
||||
if (ugh != NULL)
|
||||
{
|
||||
plog("# bad addr: %s=%s [%s]", name, value, ugh);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case KW_SUBNET:
|
||||
if ((strlen(value) >= 6 && strncmp(value,"vhost:",6) == 0)
|
||||
|| (strlen(value) >= 5 && strncmp(value,"vnet:",5) == 0))
|
||||
{
|
||||
end->virt = clone_str(value, "virt");
|
||||
}
|
||||
else
|
||||
{
|
||||
end->has_client = TRUE;
|
||||
ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &end->subnet);
|
||||
if (ugh != NULL)
|
||||
{
|
||||
plog("# bad subnet: %s=%s [%s]", name, value, ugh);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KW_SUBNETWITHIN:
|
||||
end->has_client = TRUE;
|
||||
end->has_client_wildcard = TRUE;
|
||||
ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &end->subnet);
|
||||
break;
|
||||
case KW_PROTOPORT:
|
||||
ugh = ttoprotoport(value, 0, &end->protocol, &end->port, &has_port_wildcard);
|
||||
end->has_port_wildcard = has_port_wildcard;
|
||||
break;
|
||||
case KW_SOURCEIP:
|
||||
if (streq(value, "%modeconfig") || streq(value, "%modecfg"))
|
||||
{
|
||||
end->modecfg = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ugh = ttoaddr(value, 0, conn->addr_family, &end->srcip);
|
||||
if (ugh != NULL)
|
||||
{
|
||||
plog("# bad addr: %s=%s [%s]", name, value, ugh);
|
||||
goto err;
|
||||
}
|
||||
end->has_srcip = TRUE;
|
||||
}
|
||||
conn->policy |= POLICY_TUNNEL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
err:
|
||||
plog(" bad argument value in conn '%s'", conn_name);
|
||||
cfg->err++;
|
||||
}
|
||||
|
||||
/*
|
||||
* handles left|rightfirewall and left|rightupdown parameters
|
||||
*/
|
||||
static void
|
||||
handle_firewall( const char *label, starter_end_t *end, starter_config_t *cfg)
|
||||
{
|
||||
if (end->firewall && (end->seen & LELEM(KW_FIREWALL - KW_END_FIRST)))
|
||||
{
|
||||
if (end->updown != NULL)
|
||||
{
|
||||
plog("# cannot have both %sfirewall and %supdown", label, label);
|
||||
cfg->err++;
|
||||
}
|
||||
else
|
||||
{
|
||||
end->updown = clone_str(firewall_defaults, "firewall_defaults");
|
||||
end->firewall = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse a conn section
|
||||
*/
|
||||
static void
|
||||
load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
|
||||
{
|
||||
char *conn_name = (conn->name == NULL)? "%default":conn->name;
|
||||
|
||||
for ( ; kw; kw = kw->next)
|
||||
{
|
||||
bool assigned = FALSE;
|
||||
|
||||
kw_token_t token = kw->entry->token;
|
||||
|
||||
if (token >= KW_LEFT_FIRST && token <= KW_LEFT_LAST)
|
||||
{
|
||||
kw_end(conn, &conn->left, token - KW_LEFT_FIRST + KW_END_FIRST
|
||||
, kw, conn_name, cfg);
|
||||
continue;
|
||||
}
|
||||
else if (token >= KW_RIGHT_FIRST && token <= KW_RIGHT_LAST)
|
||||
{
|
||||
kw_end(conn, &conn->right, token - KW_RIGHT_FIRST + KW_END_FIRST
|
||||
, kw, conn_name, cfg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token == KW_AUTO)
|
||||
{
|
||||
token = KW_CONN_SETUP;
|
||||
}
|
||||
else if (token == KW_ALSO)
|
||||
{
|
||||
if (cfg->parse_also)
|
||||
{
|
||||
also_t *also = alloc_thing(also_t, "also_t");
|
||||
|
||||
also->name = clone_str(kw->value, "also");
|
||||
also->next = conn->also;
|
||||
conn->also = also;
|
||||
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log(" also=%s", kw->value)
|
||||
)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token < KW_CONN_FIRST || token > KW_CONN_LAST)
|
||||
{
|
||||
plog("# unsupported keyword '%s' in conn '%s'"
|
||||
, kw->entry->name, conn_name);
|
||||
cfg->err++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!assign_arg(token, KW_CONN_FIRST, kw, (char *)conn, &assigned))
|
||||
{
|
||||
plog(" bad argument value in conn '%s'", conn_name);
|
||||
cfg->err++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assigned)
|
||||
continue;
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case KW_TYPE:
|
||||
conn->policy &= ~(POLICY_TUNNEL | POLICY_SHUNT_MASK);
|
||||
if (streq(kw->value, "tunnel"))
|
||||
conn->policy |= POLICY_TUNNEL;
|
||||
else if (streq(kw->value, "passthrough") || streq(kw->value, "pass"))
|
||||
conn->policy |= POLICY_SHUNT_PASS;
|
||||
else if (streq(kw->value, "drop"))
|
||||
conn->policy |= POLICY_SHUNT_DROP;
|
||||
else if (streq(kw->value, "reject"))
|
||||
conn->policy |= POLICY_SHUNT_REJECT;
|
||||
else if (strcmp(kw->value, "transport") != 0)
|
||||
{
|
||||
plog("# bad policy value: %s=%s", kw->entry->name, kw->value);
|
||||
cfg->err++;
|
||||
}
|
||||
break;
|
||||
case KW_PFS:
|
||||
KW_POLICY_FLAG("yes", "no", POLICY_PFS)
|
||||
break;
|
||||
case KW_COMPRESS:
|
||||
KW_POLICY_FLAG("yes", "no", POLICY_COMPRESS)
|
||||
break;
|
||||
case KW_AUTH:
|
||||
KW_POLICY_FLAG("ah", "esp", POLICY_AUTHENTICATE)
|
||||
break;
|
||||
case KW_AUTHBY:
|
||||
conn->policy &= ~(POLICY_RSASIG | POLICY_PSK | POLICY_ENCRYPT);
|
||||
|
||||
if (strcmp(kw->value, "never") != 0)
|
||||
{
|
||||
char *value = kw->value;
|
||||
char *second = strchr(kw->value, '|');
|
||||
|
||||
if (second != NULL)
|
||||
*second = '\0';
|
||||
|
||||
/* also handles the cases secret|rsasig and rsasig|secret */
|
||||
for (;;)
|
||||
{
|
||||
if (streq(value, "rsasig"))
|
||||
conn->policy |= POLICY_RSASIG | POLICY_ENCRYPT;
|
||||
else if (streq(value, "secret"))
|
||||
conn->policy |= POLICY_PSK | POLICY_ENCRYPT;
|
||||
else
|
||||
{
|
||||
plog("# bad policy value: %s=%s", kw->entry->name, kw->value);
|
||||
cfg->err++;
|
||||
break;
|
||||
}
|
||||
if (second == NULL)
|
||||
break;
|
||||
value = second;
|
||||
second = NULL; /* traverse the loop no more than twice */
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KW_REKEY:
|
||||
KW_POLICY_FLAG("no", "yes", POLICY_DONT_REKEY)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
handle_firewall("left", &conn->left, cfg);
|
||||
handle_firewall("right", &conn->right, cfg);
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize a conn object with the default conn
|
||||
*/
|
||||
static void
|
||||
conn_default(char *name, starter_conn_t *conn, starter_conn_t *def)
|
||||
{
|
||||
memcpy(conn, def, sizeof(starter_conn_t));
|
||||
conn->name = clone_str(name, "conn name");
|
||||
|
||||
clone_args(KW_CONN_FIRST, KW_CONN_LAST
|
||||
, (char *)conn, (char *)def);
|
||||
clone_args(KW_END_FIRST, KW_END_LAST
|
||||
, (char *)&conn->left, (char *)&def->left);
|
||||
clone_args(KW_END_FIRST, KW_END_LAST
|
||||
, (char *)&conn->right, (char *)&def->right);
|
||||
}
|
||||
|
||||
/*
|
||||
* parse a ca section
|
||||
*/
|
||||
static void
|
||||
load_ca(starter_ca_t *ca, kw_list_t *kw, starter_config_t *cfg)
|
||||
{
|
||||
char *ca_name = (ca->name == NULL)? "%default":ca->name;
|
||||
|
||||
for ( ; kw; kw = kw->next)
|
||||
{
|
||||
bool assigned = FALSE;
|
||||
|
||||
kw_token_t token = kw->entry->token;
|
||||
|
||||
if (token == KW_AUTO)
|
||||
{
|
||||
token = KW_CA_SETUP;
|
||||
}
|
||||
else if (token == KW_ALSO)
|
||||
{
|
||||
if (cfg->parse_also)
|
||||
{
|
||||
also_t *also = alloc_thing(also_t, "also_t");
|
||||
|
||||
also->name = clone_str(kw->value, "also");
|
||||
also->next = ca->also;
|
||||
ca->also = also;
|
||||
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log(" also=%s", kw->value)
|
||||
)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token < KW_CA_FIRST || token > KW_CA_LAST)
|
||||
{
|
||||
plog("# unsupported keyword '%s' in ca '%s'"
|
||||
, kw->entry->name, ca_name);
|
||||
cfg->err++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!assign_arg(token, KW_CA_FIRST, kw, (char *)ca, &assigned))
|
||||
{
|
||||
plog(" bad argument value in ca '%s'", ca_name);
|
||||
cfg->err++;
|
||||
}
|
||||
}
|
||||
|
||||
/* treat 'route' and 'start' as 'add' */
|
||||
if (ca->startup != STARTUP_NO)
|
||||
ca->startup = STARTUP_ADD;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize a ca object with the default ca
|
||||
*/
|
||||
static void
|
||||
ca_default(char *name, starter_ca_t *ca, starter_ca_t *def)
|
||||
{
|
||||
memcpy(ca, def, sizeof(starter_ca_t));
|
||||
ca->name = clone_str(name, "ca name");
|
||||
|
||||
clone_args(KW_CA_FIRST, KW_CA_LAST, (char *)ca, (char *)def);
|
||||
}
|
||||
|
||||
static kw_list_t*
|
||||
find_also_conn(const char* name, starter_conn_t *conn, starter_config_t *cfg);
|
||||
|
||||
static void
|
||||
load_also_conns(starter_conn_t *conn, also_t *also, starter_config_t *cfg)
|
||||
{
|
||||
while (also != NULL)
|
||||
{
|
||||
kw_list_t *kw = find_also_conn(also->name, conn, cfg);
|
||||
|
||||
if (kw == NULL)
|
||||
{
|
||||
plog(" conn '%s' cannot include '%s'", conn->name, also->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("conn '%s' includes '%s'", conn->name, also->name)
|
||||
)
|
||||
/* only load if no error occurred in the first round */
|
||||
if (cfg->err == 0)
|
||||
load_conn(conn, kw, cfg);
|
||||
}
|
||||
also = also->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* find a conn included by also
|
||||
*/
|
||||
static kw_list_t*
|
||||
find_also_conn(const char* name, starter_conn_t *conn, starter_config_t *cfg)
|
||||
{
|
||||
starter_conn_t *c = cfg->conn_first;
|
||||
|
||||
while (c != NULL)
|
||||
{
|
||||
if (streq(name, c->name))
|
||||
{
|
||||
if (conn->visit == c->visit)
|
||||
{
|
||||
plog("# detected also loop");
|
||||
cfg->err++;
|
||||
return NULL;
|
||||
}
|
||||
c->visit = conn->visit;
|
||||
load_also_conns(conn, c->also, cfg);
|
||||
return c->kw;
|
||||
}
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
plog("# also '%s' not found", name);
|
||||
cfg->err++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static kw_list_t*
|
||||
find_also_ca(const char* name, starter_ca_t *ca, starter_config_t *cfg);
|
||||
|
||||
static void
|
||||
load_also_cas(starter_ca_t *ca, also_t *also, starter_config_t *cfg)
|
||||
{
|
||||
while (also != NULL)
|
||||
{
|
||||
kw_list_t *kw = find_also_ca(also->name, ca, cfg);
|
||||
|
||||
if (kw == NULL)
|
||||
{
|
||||
plog(" ca '%s' cannot include '%s'", ca->name, also->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("ca '%s' includes '%s'", ca->name, also->name)
|
||||
)
|
||||
/* only load if no error occurred in the first round */
|
||||
if (cfg->err == 0)
|
||||
load_ca(ca, kw, cfg);
|
||||
}
|
||||
also = also->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* find a ca included by also
|
||||
*/
|
||||
static kw_list_t*
|
||||
find_also_ca(const char* name, starter_ca_t *ca, starter_config_t *cfg)
|
||||
{
|
||||
starter_ca_t *c = cfg->ca_first;
|
||||
|
||||
while (c != NULL)
|
||||
{
|
||||
if (streq(name, c->name))
|
||||
{
|
||||
if (ca->visit == c->visit)
|
||||
{
|
||||
plog("# detected also loop");
|
||||
cfg->err++;
|
||||
return NULL;
|
||||
}
|
||||
c->visit = ca->visit;
|
||||
load_also_cas(ca, c->also, cfg);
|
||||
return c->kw;
|
||||
}
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
plog("# also '%s' not found", name);
|
||||
cfg->err++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* load and parse an IPsec configuration file
|
||||
*/
|
||||
starter_config_t *
|
||||
confread_load(const char *file)
|
||||
{
|
||||
starter_config_t *cfg = NULL;
|
||||
config_parsed_t *cfgp;
|
||||
section_list_t *sconn, *sca;
|
||||
starter_conn_t *conn;
|
||||
starter_ca_t *ca;
|
||||
|
||||
u_int visit = 0;
|
||||
|
||||
/* load IPSec configuration file */
|
||||
cfgp = parser_load_conf(file);
|
||||
if (!cfgp)
|
||||
return NULL;
|
||||
|
||||
cfg = (starter_config_t *)alloc_thing(starter_config_t, "starter_config_t");
|
||||
|
||||
/* set default values */
|
||||
default_values(cfg);
|
||||
|
||||
/* determine default route */
|
||||
get_defaultroute(&cfg->defaultroute);
|
||||
|
||||
/* load config setup section */
|
||||
load_setup(cfg, cfgp);
|
||||
|
||||
/* in the first round parse also statements */
|
||||
cfg->parse_also = TRUE;
|
||||
|
||||
/* find %default ca section */
|
||||
for (sca = cfgp->ca_first; sca; sca = sca->next)
|
||||
{
|
||||
if (streq(sca->name, "%default"))
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Loading ca %%default")
|
||||
)
|
||||
load_ca(&cfg->ca_default, sca->kw, cfg);
|
||||
}
|
||||
}
|
||||
|
||||
/* parameters defined in ca %default sections can be overloads */
|
||||
cfg->ca_default.seen = LEMPTY;
|
||||
|
||||
/* load other ca sections */
|
||||
for (sca = cfgp->ca_first; sca; sca = sca->next)
|
||||
{
|
||||
/* skip %default ca section */
|
||||
if (streq(sca->name, "%default"))
|
||||
continue;
|
||||
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Loading ca '%s'", sca->name)
|
||||
)
|
||||
ca = (starter_ca_t *)alloc_thing(starter_ca_t, "starter_ca_t");
|
||||
|
||||
ca_default(sca->name, ca, &cfg->ca_default);
|
||||
ca->kw = sca->kw;
|
||||
ca->next = NULL;
|
||||
|
||||
if (cfg->ca_last)
|
||||
cfg->ca_last->next = ca;
|
||||
cfg->ca_last = ca;
|
||||
if (!cfg->ca_first)
|
||||
cfg->ca_first = ca;
|
||||
|
||||
load_ca(ca, ca->kw, cfg);
|
||||
}
|
||||
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
also_t *also = ca->also;
|
||||
|
||||
while (also != NULL)
|
||||
{
|
||||
kw_list_t *kw = find_also_ca(also->name, cfg->ca_first, cfg);
|
||||
|
||||
load_ca(ca, kw, cfg);
|
||||
also = also->next;
|
||||
}
|
||||
|
||||
if (ca->startup != STARTUP_NO)
|
||||
ca->state = STATE_TO_ADD;
|
||||
}
|
||||
|
||||
/* find %default conn sections */
|
||||
for (sconn = cfgp->conn_first; sconn; sconn = sconn->next)
|
||||
{
|
||||
if (streq(sconn->name, "%default"))
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Loading conn %%default")
|
||||
)
|
||||
load_conn(&cfg->conn_default, sconn->kw, cfg);
|
||||
}
|
||||
}
|
||||
|
||||
/* parameter defined in conn %default sections can be overloaded */
|
||||
cfg->conn_default.seen = LEMPTY;
|
||||
cfg->conn_default.right.seen = LEMPTY;
|
||||
cfg->conn_default.left.seen = LEMPTY;
|
||||
|
||||
/* load other conn sections */
|
||||
for (sconn = cfgp->conn_first; sconn; sconn = sconn->next)
|
||||
{
|
||||
/* skip %default conn section */
|
||||
if (streq(sconn->name, "%default"))
|
||||
continue;
|
||||
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Loading conn '%s'", sconn->name)
|
||||
)
|
||||
conn = (starter_conn_t *)alloc_thing(starter_conn_t, "starter_conn_t");
|
||||
|
||||
conn_default(sconn->name, conn, &cfg->conn_default);
|
||||
conn->kw = sconn->kw;
|
||||
conn->next = NULL;
|
||||
|
||||
if (cfg->conn_last)
|
||||
cfg->conn_last->next = conn;
|
||||
cfg->conn_last = conn;
|
||||
if (!cfg->conn_first)
|
||||
cfg->conn_first = conn;
|
||||
|
||||
load_conn(conn, conn->kw, cfg);
|
||||
}
|
||||
|
||||
/* in the second round do not parse also statements */
|
||||
cfg->parse_also = FALSE;
|
||||
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
ca->visit = ++visit;
|
||||
load_also_cas(ca, ca->also, cfg);
|
||||
|
||||
if (ca->startup != STARTUP_NO)
|
||||
ca->state = STATE_TO_ADD;
|
||||
}
|
||||
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
{
|
||||
conn->visit = ++visit;
|
||||
load_also_conns(conn, conn->also, cfg);
|
||||
|
||||
if (conn->startup != STARTUP_NO)
|
||||
conn->state = STATE_TO_ADD;
|
||||
}
|
||||
|
||||
parser_free_conf(cfgp);
|
||||
|
||||
if (cfg->err)
|
||||
{
|
||||
plog("### %d parsing error%s ###", cfg->err, (cfg->err > 1)?"s":"");
|
||||
confread_free(cfg);
|
||||
cfg = NULL;
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
/*
|
||||
* free the memory used by also_t objects
|
||||
*/
|
||||
static void
|
||||
free_also(also_t *head)
|
||||
{
|
||||
while (head != NULL)
|
||||
{
|
||||
also_t *also = head;
|
||||
|
||||
head = also->next;
|
||||
pfree(also->name);
|
||||
pfree(also);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* free the memory used by a starter_conn_t object
|
||||
*/
|
||||
static void
|
||||
confread_free_conn(starter_conn_t *conn)
|
||||
{
|
||||
free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left);
|
||||
free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->right);
|
||||
free_args(KW_CONN_NAME, KW_CONN_LAST, (char *)conn);
|
||||
free_also(conn->also);
|
||||
}
|
||||
|
||||
/*
|
||||
* free the memory used by a starter_ca_t object
|
||||
*/
|
||||
static void
|
||||
confread_free_ca(starter_ca_t *ca)
|
||||
{
|
||||
free_args(KW_CA_NAME, KW_CA_LAST, (char *)ca);
|
||||
free_also(ca->also);
|
||||
}
|
||||
|
||||
/*
|
||||
* free the memory used by a starter_config_t object
|
||||
*/
|
||||
void
|
||||
confread_free(starter_config_t *cfg)
|
||||
{
|
||||
starter_conn_t *conn = cfg->conn_first;
|
||||
starter_ca_t *ca = cfg->ca_first;
|
||||
|
||||
free_args(KW_SETUP_FIRST, KW_SETUP_LAST, (char *)cfg);
|
||||
|
||||
confread_free_conn(&cfg->conn_default);
|
||||
|
||||
while (conn != NULL)
|
||||
{
|
||||
starter_conn_t *conn_aux = conn;
|
||||
|
||||
conn = conn->next;
|
||||
confread_free_conn(conn_aux);
|
||||
pfree(conn_aux);
|
||||
}
|
||||
|
||||
confread_free_ca(&cfg->ca_default);
|
||||
|
||||
while (ca != NULL)
|
||||
{
|
||||
starter_ca_t *ca_aux = ca;
|
||||
|
||||
ca = ca->next;
|
||||
confread_free_ca(ca_aux);
|
||||
pfree(ca_aux);
|
||||
}
|
||||
|
||||
pfree(cfg);
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/* strongSwan IPsec config file parser
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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.h,v 1.23 2006/04/17 10:32:36 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _IPSEC_CONFREAD_H_
|
||||
#define _IPSEC_CONFREAD_H_
|
||||
|
||||
#ifndef _FREESWAN_H
|
||||
#include <freeswan.h>
|
||||
#include "../pluto/constants.h"
|
||||
#endif
|
||||
|
||||
#include "parser.h"
|
||||
#include "interfaces.h"
|
||||
|
||||
typedef enum {
|
||||
STARTUP_NO,
|
||||
STARTUP_ADD,
|
||||
STARTUP_ROUTE,
|
||||
STARTUP_START
|
||||
} startup_t;
|
||||
|
||||
typedef enum {
|
||||
STATE_IGNORE,
|
||||
STATE_TO_ADD,
|
||||
STATE_ADDED,
|
||||
STATE_REPLACED,
|
||||
STATE_INVALID
|
||||
} starter_state_t;
|
||||
|
||||
typedef struct starter_end starter_end_t;
|
||||
|
||||
struct starter_end {
|
||||
lset_t seen;
|
||||
char *id;
|
||||
char *rsakey;
|
||||
char *cert;
|
||||
char *ca;
|
||||
char *groups;
|
||||
char *iface;
|
||||
ip_address addr;
|
||||
ip_address nexthop;
|
||||
ip_address srcip;
|
||||
ip_subnet subnet;
|
||||
bool has_client;
|
||||
bool has_client_wildcard;
|
||||
bool has_port_wildcard;
|
||||
bool has_srcip;
|
||||
bool modecfg;
|
||||
certpolicy_t sendcert;
|
||||
bool firewall;
|
||||
bool hostaccess;
|
||||
char *updown;
|
||||
u_int16_t port;
|
||||
u_int8_t protocol;
|
||||
#ifdef VIRTUAL_IP
|
||||
char *virt;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct also also_t;
|
||||
|
||||
struct also {
|
||||
char *name;
|
||||
bool included;
|
||||
also_t *next;
|
||||
};
|
||||
|
||||
typedef struct starter_conn starter_conn_t;
|
||||
|
||||
struct starter_conn {
|
||||
lset_t seen;
|
||||
char *name;
|
||||
also_t *also;
|
||||
kw_list_t *kw;
|
||||
u_int visit;
|
||||
startup_t startup;
|
||||
starter_state_t state;
|
||||
|
||||
int keyexchange;
|
||||
lset_t policy;
|
||||
time_t sa_ike_life_seconds;
|
||||
time_t sa_ipsec_life_seconds;
|
||||
time_t sa_rekey_margin;
|
||||
unsigned long sa_keying_tries;
|
||||
unsigned long sa_rekey_fuzz;
|
||||
sa_family_t addr_family;
|
||||
sa_family_t tunnel_addr_family;
|
||||
|
||||
starter_end_t left, right;
|
||||
|
||||
unsigned long id;
|
||||
|
||||
char *esp;
|
||||
char *ike;
|
||||
char *pfsgroup;
|
||||
|
||||
time_t dpd_delay;
|
||||
time_t dpd_timeout;
|
||||
dpd_action_t dpd_action;
|
||||
int dpd_count;
|
||||
|
||||
starter_conn_t *next;
|
||||
};
|
||||
|
||||
typedef struct starter_ca starter_ca_t;
|
||||
|
||||
struct starter_ca {
|
||||
lset_t seen;
|
||||
char *name;
|
||||
also_t *also;
|
||||
kw_list_t *kw;
|
||||
u_int visit;
|
||||
startup_t startup;
|
||||
starter_state_t state;
|
||||
|
||||
char *cacert;
|
||||
char *ldaphost;
|
||||
char *ldapbase;
|
||||
char *crluri;
|
||||
char *crluri2;
|
||||
char *ocspuri;
|
||||
|
||||
bool strict;
|
||||
|
||||
starter_ca_t *next;
|
||||
};
|
||||
|
||||
typedef struct starter_config starter_config_t;
|
||||
|
||||
struct starter_config {
|
||||
struct {
|
||||
lset_t seen;
|
||||
char **interfaces;
|
||||
char *dumpdir;
|
||||
|
||||
/* pluto keywords */
|
||||
char **plutodebug;
|
||||
char *prepluto;
|
||||
char *postpluto;
|
||||
bool uniqueids;
|
||||
u_int overridemtu;
|
||||
u_int crlcheckinterval;
|
||||
bool cachecrls;
|
||||
bool strictcrlpolicy;
|
||||
bool nocrsend;
|
||||
bool nat_traversal;
|
||||
u_int keep_alive;
|
||||
char *virtual_private;
|
||||
char *pkcs11module;
|
||||
bool pkcs11keepstate;
|
||||
bool pkcs11proxy;
|
||||
|
||||
/* KLIPS keywords */
|
||||
char **klipsdebug;
|
||||
bool fragicmp;
|
||||
char *packetdefault;
|
||||
bool hidetos;
|
||||
} setup;
|
||||
|
||||
/* information about the default route */
|
||||
defaultroute_t defaultroute;
|
||||
|
||||
/* number of encountered parsing errors */
|
||||
u_int err;
|
||||
|
||||
/* do we parse also statements */
|
||||
bool parse_also;
|
||||
|
||||
/* ca %default */
|
||||
starter_ca_t ca_default;
|
||||
|
||||
/* connections list (without %default) */
|
||||
starter_ca_t *ca_first, *ca_last;
|
||||
|
||||
/* conn %default */
|
||||
starter_conn_t conn_default;
|
||||
|
||||
/* connections list (without %default) */
|
||||
starter_conn_t *conn_first, *conn_last;
|
||||
};
|
||||
|
||||
extern starter_config_t *confread_load(const char *file);
|
||||
extern void confread_free(starter_config_t *cfg);
|
||||
|
||||
#endif /* _IPSEC_CONFREAD_H_ */
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/* strongSwan IPsec exec helper function
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: exec.c,v 1.4 2006/01/04 23:30:24 as Exp $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
|
||||
#include "exec.h"
|
||||
|
||||
#define BUF_SIZE 2048
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* o log stdout with LOG_LEVEL_INFO and stderr with LOG_LEVEL_ERR
|
||||
*/
|
||||
|
||||
int
|
||||
starter_exec(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
static char buf[BUF_SIZE];
|
||||
int r;
|
||||
|
||||
va_start (args, fmt);
|
||||
vsnprintf(buf, BUF_SIZE-1, fmt, args);
|
||||
buf[BUF_SIZE - 1] = '\0';
|
||||
va_end(args);
|
||||
r = system(buf);
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("starter_exec(%s) = %d", buf, r)
|
||||
)
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/* strongSwan IPsec starter exec helper function
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: exec.h,v 1.2 2005/12/28 10:20:32 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_EXEC_H_
|
||||
#define _STARTER_EXEC_H_
|
||||
|
||||
extern int starter_exec (const char *fmt, ...);
|
||||
|
||||
#endif /* _STARTER_EXEC_H_ */
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/* strongSwan file locations
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: files.h,v 1.5 2006/02/04 18:52:58 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_FILES_H_
|
||||
#define _STARTER_FILES_H_
|
||||
|
||||
#ifndef DEFAULT_CTLBASE
|
||||
#define DEFAULT_CTLBASE "/var/run/pluto"
|
||||
#endif
|
||||
#define CTL_SUFFIX ".ctl"
|
||||
#define PID_SUFFIX ".pid"
|
||||
|
||||
#define MY_PID_FILE "/var/run/starter.pid"
|
||||
|
||||
#define DEV_RANDOM "/dev/random"
|
||||
#define DEV_URANDOM "/dev/urandom"
|
||||
|
||||
#define PROC_NETKEY "/proc/net/pfkey"
|
||||
#define PROC_IPSECVERSION "/proc/net/ipsec_version"
|
||||
#define PROC_SYSFLAGS "/proc/sys/net/ipsec"
|
||||
#define PROC_MODULES "/proc/modules"
|
||||
|
||||
#define CONFIG_FILE IPSEC_CONFDIR"/ipsec.conf"
|
||||
#define SECRETS_FILE IPSEC_CONFDIR"/ipsec.secrets"
|
||||
|
||||
#define PLUTO_CMD IPSEC_EXECDIR"/pluto"
|
||||
#define PLUTO_CTL_FILE DEFAULT_CTLBASE CTL_SUFFIX
|
||||
#define PLUTO_PID_FILE DEFAULT_CTLBASE PID_SUFFIX
|
||||
|
||||
#ifdef IKEV2
|
||||
#define CHARON_CMD IPSEC_EXECDIR"/charon"
|
||||
#define CHARON_BASE "/var/run/charon"
|
||||
#define CHARON_CTL_FILE CHARON_BASE CTL_SUFFIX
|
||||
#define CHARON_PID_FILE CHARON_BASE PID_SUFFIX
|
||||
#endif /* IKEV2 */
|
||||
|
||||
#define DYNIP_DIR "/var/run/dynip"
|
||||
#define INFO_FILE "/var/run/ipsec.info"
|
||||
|
||||
#endif /* _STARTER_FILES_H_ */
|
||||
|
||||
@@ -0,0 +1,595 @@
|
||||
/* strongSwan IPsec interfaces management
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: interfaces.c,v 1.15 2006/02/05 10:51:55 as Exp $
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/if.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
#include <freeswan/ipsec_tunnel.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
|
||||
#include "interfaces.h"
|
||||
#include "exec.h"
|
||||
#include "files.h"
|
||||
|
||||
#define MIN(a,b) ( ((a)>(b)) ? (b) : (a) )
|
||||
|
||||
#define N_IPSEC_IF 4
|
||||
|
||||
struct st_ipsec_if {
|
||||
char name[IFNAMSIZ];
|
||||
char phys[IFNAMSIZ];
|
||||
int up;
|
||||
};
|
||||
|
||||
static struct st_ipsec_if _ipsec_if[N_IPSEC_IF];
|
||||
|
||||
static char *
|
||||
_find_physical_iface(int sock, char *iface)
|
||||
{
|
||||
static char _if[IFNAMSIZ];
|
||||
char *b;
|
||||
struct ifreq req;
|
||||
FILE *fd;
|
||||
char line[BUF_LEN];
|
||||
|
||||
strncpy(req.ifr_name, iface, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &req)==0)
|
||||
{
|
||||
if (req.ifr_flags & IFF_UP)
|
||||
{
|
||||
strncpy(_if, iface, IFNAMSIZ);
|
||||
return _if;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If there is a file named /var/run/dynip/<iface>, look if we
|
||||
* can get interface name from there (IP_PHYS)
|
||||
*/
|
||||
b = (char *)alloc_bytes(strlen(DYNIP_DIR) + strlen(iface) + 10, "iface");
|
||||
if (b)
|
||||
{
|
||||
sprintf(b, "%s/%s", DYNIP_DIR, iface);
|
||||
fd = fopen(b, "r");
|
||||
pfree(b);
|
||||
if (fd)
|
||||
{
|
||||
memset(_if, 0, sizeof(_if));
|
||||
memset(line, 0, sizeof(line));
|
||||
while (fgets(line, sizeof(line), fd) != 0)
|
||||
{
|
||||
if ((strncmp(line,"IP_PHYS=\"", 9) == 0)
|
||||
&& (line[strlen(line) - 2] == '"')
|
||||
&& (line[strlen(line) - 1] == '\n'))
|
||||
{
|
||||
strncpy(_if, line + 9, MIN(strlen(line) - 11, IFNAMSIZ));
|
||||
break;
|
||||
}
|
||||
else if ((strncmp(line,"IP_PHYS=", 8) == 0)
|
||||
&& (line[8] != '"')
|
||||
&& (line[strlen(line) - 1] == '\n'))
|
||||
{
|
||||
strncpy(_if, line + 8, MIN(strlen(line) - 9, IFNAMSIZ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
if (*_if)
|
||||
{
|
||||
strncpy(req.ifr_name, _if, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &req) == 0)
|
||||
{
|
||||
if (req.ifr_flags & IFF_UP)
|
||||
return _if;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
starter_iface_find(char *iface, int af, ip_address *dst, ip_address *nh)
|
||||
{
|
||||
char *phys;
|
||||
struct ifreq req;
|
||||
struct sockaddr_in *sa = (struct sockaddr_in *)(&req.ifr_addr);
|
||||
int sock;
|
||||
|
||||
if (!iface)
|
||||
return -1;
|
||||
|
||||
sock = socket(af, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
|
||||
phys = _find_physical_iface(sock, iface);
|
||||
if (!phys)
|
||||
goto failed;
|
||||
|
||||
strncpy(req.ifr_name, phys, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &req)!=0)
|
||||
goto failed;
|
||||
if (!(req.ifr_flags & IFF_UP))
|
||||
goto failed;
|
||||
|
||||
if ((req.ifr_flags & IFF_POINTOPOINT)
|
||||
&& nh
|
||||
&& ioctl(sock, SIOCGIFDSTADDR, &req) == 0)
|
||||
{
|
||||
if (sa->sin_family == af)
|
||||
initaddr((const void *)&sa->sin_addr, sizeof(struct in_addr), af, nh);
|
||||
}
|
||||
if ((dst) && (ioctl(sock, SIOCGIFADDR, &req) == 0))
|
||||
{
|
||||
if (sa->sin_family == af)
|
||||
initaddr((const void *)&sa->sin_addr, sizeof(struct in_addr), af, dst);
|
||||
}
|
||||
close(sock);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
valid_str(char *str, unsigned int *pn, char **pphys
|
||||
, defaultroute_t *defaultroute)
|
||||
{
|
||||
if (streq(str, "%defaultroute"))
|
||||
{
|
||||
if (!defaultroute->defined)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*pn = 0;
|
||||
*pphys = defaultroute->iface;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(str) < 8
|
||||
|| str[0] != 'i' || str[1] != 'p' || str[2] !='s' || str[3] != 'e'
|
||||
|| str[4] != 'c' || str[5] < '0' || str[5] > '9' || str[6] != '=')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*pn = str[5] - '0';
|
||||
*pphys = &(str[7]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
_iface_up (int sock, struct st_ipsec_if *iface, char *phys
|
||||
, unsigned int mtu, bool nat_t)
|
||||
{
|
||||
struct ifreq req;
|
||||
struct ipsectunnelconf *shc=(struct ipsectunnelconf *)&req.ifr_data;
|
||||
short phys_flags;
|
||||
int ret = 0;
|
||||
/* [email protected]: for network mask 32 bit
|
||||
struct sockaddr_in *inp;
|
||||
*/
|
||||
|
||||
strncpy(req.ifr_name, phys, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &req) !=0 )
|
||||
return ret;
|
||||
phys_flags = req.ifr_flags;
|
||||
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &req) != 0)
|
||||
return ret;
|
||||
|
||||
if ((!(req.ifr_flags & IFF_UP)) || (!iface->up))
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("attaching interface %s to %s", iface->name, phys)
|
||||
)
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if ((*iface->phys) && (strcmp(iface->phys, phys) != 0 ))
|
||||
{
|
||||
/* tncfg --detach if phys has changed */
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
ioctl(sock, IPSEC_DEL_DEV, &req);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
/* tncfg --attach */
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
strncpy(shc->cf_name, phys, sizeof(shc->cf_name));
|
||||
ioctl(sock, IPSEC_SET_DEV, &req);
|
||||
|
||||
/* set ipsec addr = phys addr */
|
||||
strncpy(req.ifr_name, phys, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFADDR, &req) == 0)
|
||||
{
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
ioctl(sock, SIOCSIFADDR, &req);
|
||||
}
|
||||
|
||||
/* set ipsec mask = phys mask */
|
||||
strncpy(req.ifr_name, phys, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFNETMASK, &req) == 0)
|
||||
{
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
/* [email protected]: changed netmask to 32 bit
|
||||
* in order to prevent network routes from being created
|
||||
|
||||
inp = (struct sockaddr_in *)&req.ifr_addr;
|
||||
inp->sin_addr.s_addr = 0xFFFFFFFFL;
|
||||
|
||||
*/
|
||||
ioctl(sock, SIOCSIFNETMASK, &req);
|
||||
}
|
||||
|
||||
/* set other flags & addr */
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &req)==0)
|
||||
{
|
||||
/* removed by [email protected] (caused trouble with DSL/ppp0) */
|
||||
/* if (phys_flags & IFF_POINTOPOINT)
|
||||
{
|
||||
req.ifr_flags |= IFF_POINTOPOINT;
|
||||
req.ifr_flags &= ~IFF_BROADCAST;
|
||||
ioctl(sock, SIOCSIFFLAGS, &req);
|
||||
strncpy(req.ifr_name, phys, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFDSTADDR, &req) == 0)
|
||||
{
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
ioctl(sock, SIOCSIFDSTADDR, &req);
|
||||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
if (phys_flags & IFF_BROADCAST)
|
||||
{
|
||||
req.ifr_flags &= ~IFF_POINTOPOINT;
|
||||
req.ifr_flags |= IFF_BROADCAST;
|
||||
ioctl(sock, SIOCSIFFLAGS, &req);
|
||||
strncpy(req.ifr_name, phys, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFBRDADDR, &req) == 0)
|
||||
{
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
ioctl(sock, SIOCSIFBRDADDR, &req);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
req.ifr_flags &= ~IFF_POINTOPOINT;
|
||||
req.ifr_flags &= ~IFF_BROADCAST;
|
||||
ioctl(sock, SIOCSIFFLAGS, &req);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* guess MTU = phys interface MTU - ESP Overhead
|
||||
*
|
||||
* ESP overhead : 10+16+7+2+12=57 -> 60 by security
|
||||
* NAT-T overhead : 20
|
||||
*/
|
||||
if (mtu == 0)
|
||||
{
|
||||
strncpy(req.ifr_name, phys, IFNAMSIZ);
|
||||
ioctl(sock, SIOCGIFMTU, &req);
|
||||
mtu = req.ifr_mtu - 60;
|
||||
if (nat_t)
|
||||
mtu -= 20;
|
||||
}
|
||||
/* set MTU */
|
||||
if (mtu)
|
||||
{
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
req.ifr_mtu = mtu;
|
||||
ioctl(sock, SIOCSIFMTU, &req);
|
||||
}
|
||||
|
||||
/* ipsec interface UP */
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &req) == 0)
|
||||
{
|
||||
req.ifr_flags |= IFF_UP;
|
||||
ioctl(sock, SIOCSIFFLAGS, &req);
|
||||
}
|
||||
|
||||
iface->up = 1;
|
||||
strncpy(iface->phys, phys, IFNAMSIZ);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
_iface_down(int sock, struct st_ipsec_if *iface)
|
||||
{
|
||||
struct ifreq req;
|
||||
int ret = 0;
|
||||
|
||||
iface->up = 0;
|
||||
|
||||
strncpy(req.ifr_name, iface->name, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &req)!=0)
|
||||
return ret;
|
||||
|
||||
if (req.ifr_flags & IFF_UP)
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("shutting down interface %s/%s", iface->name, iface->phys)
|
||||
)
|
||||
req.ifr_flags &= ~IFF_UP;
|
||||
ioctl(sock, SIOCSIFFLAGS, &req);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
/* unset addr */
|
||||
memset(&req.ifr_addr, 0, sizeof(req.ifr_addr));
|
||||
req.ifr_addr.sa_family = AF_INET;
|
||||
ioctl(sock, SIOCSIFADDR, &req);
|
||||
|
||||
/* tncfg --detach */
|
||||
ioctl(sock, IPSEC_DEL_DEV, &req);
|
||||
|
||||
memset(iface->phys, 0, sizeof(iface->phys));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
starter_ifaces_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(_ipsec_if, 0, sizeof(_ipsec_if));
|
||||
for (i = 0; i < N_IPSEC_IF; i++)
|
||||
snprintf(_ipsec_if[i].name, IFNAMSIZ, "ipsec%d", i);
|
||||
}
|
||||
|
||||
void
|
||||
starter_ifaces_clear (void)
|
||||
{
|
||||
int sock;
|
||||
unsigned int i;
|
||||
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < N_IPSEC_IF; i++)
|
||||
_iface_down (sock, &(_ipsec_if[i]));
|
||||
}
|
||||
|
||||
int
|
||||
starter_ifaces_load(char **ifaces, unsigned int omtu, bool nat_t
|
||||
, defaultroute_t *defaultroute)
|
||||
{
|
||||
char *tmp_phys, *phys;
|
||||
int n;
|
||||
char **i;
|
||||
int sock;
|
||||
int j, found;
|
||||
int ret = 0;
|
||||
struct ifreq physreq, ipsecreq; // re-attach interface
|
||||
struct sockaddr_in *inp1, *inp2; // re-attach interface
|
||||
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("starter_ifaces_load()")
|
||||
)
|
||||
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
|
||||
for (j = 0; j < N_IPSEC_IF; j++)
|
||||
{
|
||||
found = 0;
|
||||
|
||||
for (i = ifaces; i && *i; i++)
|
||||
{
|
||||
if (valid_str(*i, &n, &tmp_phys, defaultroute)
|
||||
&& tmp_phys
|
||||
&& n >= 0
|
||||
&& n < N_IPSEC_IF)
|
||||
{
|
||||
if (n==j)
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
plog( "ignoring duplicate entry for interface ipsec%d", j);
|
||||
}
|
||||
else
|
||||
{
|
||||
found++;
|
||||
phys = _find_physical_iface(sock, tmp_phys);
|
||||
|
||||
/* Re-attach ipsec interface if IP address changes
|
||||
* [email protected]
|
||||
*/
|
||||
if (phys)
|
||||
{
|
||||
memset ((void*)&physreq, 0, sizeof(physreq));
|
||||
memset ((void*)&ipsecreq, 0, sizeof(ipsecreq));
|
||||
strncpy(physreq.ifr_name, phys, IFNAMSIZ);
|
||||
sprintf(ipsecreq.ifr_name, "ipsec%d", j);
|
||||
ioctl(sock, SIOCGIFADDR, &physreq);
|
||||
ioctl(sock, SIOCGIFADDR, &ipsecreq);
|
||||
inp1 = (struct sockaddr_in *)&physreq.ifr_addr;
|
||||
inp2 = (struct sockaddr_in *)&ipsecreq.ifr_addr;
|
||||
if (inp1->sin_addr.s_addr != inp2->sin_addr.s_addr)
|
||||
{
|
||||
plog("IP address of physical interface changed "
|
||||
"-> reinit of ipsec interface");
|
||||
_iface_down (sock, &(_ipsec_if[n]));
|
||||
}
|
||||
ret += _iface_up (sock, &(_ipsec_if[n]), phys, omtu, nat_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += _iface_down (sock, &(_ipsec_if[n]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (j == 0)
|
||||
{
|
||||
/* Only log in the first loop */
|
||||
plog("ignoring invalid interface '%s'", *i);
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
ret += _iface_down (sock, &(_ipsec_if[j]));
|
||||
}
|
||||
|
||||
close(sock);
|
||||
return ret; /* = number of changes - 'whack --listen' if > 0 */
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize a defaultroute_t struct
|
||||
*/
|
||||
static void
|
||||
init_defaultroute(defaultroute_t *defaultroute)
|
||||
{
|
||||
memset(defaultroute, 0, sizeof(defaultroute_t));
|
||||
}
|
||||
|
||||
/*
|
||||
* discover the default route via /proc/net/route
|
||||
*/
|
||||
void
|
||||
get_defaultroute(defaultroute_t *defaultroute)
|
||||
{
|
||||
FILE *fd;
|
||||
char line[BUF_LEN];
|
||||
bool first = TRUE;
|
||||
|
||||
init_defaultroute(defaultroute);
|
||||
|
||||
fd = fopen("/proc/net/route", "r");
|
||||
|
||||
if (!fd)
|
||||
{
|
||||
plog("could not open 'proc/net/route'");
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof(line), fd) != 0)
|
||||
{
|
||||
char iface[11];
|
||||
char destination[9];
|
||||
char gateway[11];
|
||||
char flags[5];
|
||||
char mask[9];
|
||||
|
||||
int refcnt;
|
||||
int use;
|
||||
int metric;
|
||||
int items;
|
||||
|
||||
/* proc/net/route returns IP addresses in host order */
|
||||
strcpy(gateway, "0h");
|
||||
|
||||
/* skip the header line */
|
||||
if (first)
|
||||
{
|
||||
first = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* parsing a single line of proc/net/route */
|
||||
items = sscanf(line, "%10s\t%8s\t%8s\t%5s\t%d\t%d\t%d\t%8s\t"
|
||||
, iface, destination, gateway+2, flags, &refcnt, &use, &metric, mask);
|
||||
if (items < 8)
|
||||
{
|
||||
plog("parsing error while scanning /proc/net/route");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check for defaultroute (destination 0.0.0.0 and mask 0.0.0.0) */
|
||||
if (streq(destination, "00000000") && streq(mask, "00000000"))
|
||||
{
|
||||
if (defaultroute->defined)
|
||||
{
|
||||
plog("multiple default routes - cannot cope with %%defaultroute!!!");
|
||||
defaultroute->defined = FALSE;
|
||||
fclose(fd);
|
||||
return;
|
||||
}
|
||||
ttoaddr(gateway, strlen(gateway), AF_INET, &defaultroute->nexthop);
|
||||
strncpy(defaultroute->iface, iface, IFNAMSIZ);
|
||||
defaultroute->defined = TRUE;
|
||||
}
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
if (!defaultroute->defined)
|
||||
{
|
||||
plog("no default route - cannot cope with %%defaultroute!!!");
|
||||
}
|
||||
else
|
||||
{
|
||||
char addr_buf[20], nexthop_buf[20];
|
||||
struct ifreq physreq;
|
||||
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
/* determine IP address of iface */
|
||||
if (sock < 0)
|
||||
{
|
||||
plog("could not open SOCK_DGRAM socket");
|
||||
defaultroute->defined = FALSE;
|
||||
return;
|
||||
}
|
||||
memset ((void*)&physreq, 0, sizeof(physreq));
|
||||
strncpy(physreq.ifr_name, defaultroute->iface, IFNAMSIZ);
|
||||
ioctl(sock, SIOCGIFADDR, &physreq);
|
||||
close(sock);
|
||||
defaultroute->addr.u.v4 = *((struct sockaddr_in *)&physreq.ifr_addr);
|
||||
|
||||
addrtot(&defaultroute->addr, 0, addr_buf, sizeof(addr_buf));
|
||||
addrtot(&defaultroute->nexthop, 0, nexthop_buf, sizeof(nexthop_buf));
|
||||
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Default route found: iface=%s, addr=%s, nexthop=%s"
|
||||
, defaultroute->iface, addr_buf, nexthop_buf)
|
||||
)
|
||||
|
||||
/* for backwards-compatibility with the awk shell scripts
|
||||
* store the defaultroute in /var/run/ipsec.info
|
||||
*/
|
||||
fd = fopen(INFO_FILE, "w");
|
||||
|
||||
if (fd)
|
||||
{
|
||||
fprintf(fd, "defaultroutephys=%s\n", defaultroute->iface );
|
||||
fprintf(fd, "defaultroutevirt=ipsec0\n");
|
||||
fprintf(fd, "defaultrouteaddr=%s\n", addr_buf);
|
||||
fprintf(fd, "defaultroutenexthop=%s\n", nexthop_buf);
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/* strongSwan IPsec interfaces management
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: interfaces.h,v 1.6 2006/01/06 20:24:07 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_INTERFACES_H_
|
||||
#define _STARTER_INTERFACES_H_
|
||||
|
||||
#include <linux/if.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
|
||||
typedef struct {
|
||||
bool defined;
|
||||
char iface[IFNAMSIZ];
|
||||
ip_address addr;
|
||||
ip_address nexthop;
|
||||
} defaultroute_t;
|
||||
|
||||
extern void starter_ifaces_init (void);
|
||||
extern int starter_iface_find(char *iface, int af, ip_address *dst
|
||||
, ip_address *nh);
|
||||
extern int starter_ifaces_load (char **ifaces, unsigned int omtu, bool nat_t
|
||||
, defaultroute_t *defaultroute);
|
||||
extern void starter_ifaces_clear (void);
|
||||
extern void get_defaultroute(defaultroute_t *defaultroute);
|
||||
|
||||
|
||||
#endif /* _STARTER_INTERFACES_H_ */
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/* strongSwan charon launcher
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
* Copyright (C) 2006 Martin Willi - Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Ported from invokepluto.c to fit charons needs.
|
||||
*
|
||||
* 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: invokecharon.c $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
|
||||
#include "confread.h"
|
||||
#include "invokecharon.h"
|
||||
#include "files.h"
|
||||
|
||||
static int _charon_pid = 0;
|
||||
static int _stop_requested;
|
||||
|
||||
pid_t
|
||||
starter_charon_pid(void)
|
||||
{
|
||||
return _charon_pid;
|
||||
}
|
||||
|
||||
void
|
||||
starter_charon_sigchild(pid_t pid)
|
||||
{
|
||||
if (pid == _charon_pid)
|
||||
{
|
||||
_charon_pid = 0;
|
||||
if (!_stop_requested)
|
||||
{
|
||||
plog("charon has died -- restart scheduled (%dsec)"
|
||||
, CHARON_RESTART_DELAY);
|
||||
alarm(CHARON_RESTART_DELAY); // restart in 5 sec
|
||||
}
|
||||
unlink(CHARON_PID_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
starter_stop_charon (void)
|
||||
{
|
||||
pid_t pid;
|
||||
int i;
|
||||
|
||||
pid = _charon_pid;
|
||||
if (pid)
|
||||
{
|
||||
_stop_requested = 1;
|
||||
|
||||
/* be more and more aggressive */
|
||||
for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
kill(pid, SIGINT);
|
||||
else if (i < 10)
|
||||
kill(pid, SIGTERM);
|
||||
else
|
||||
kill(pid, SIGKILL);
|
||||
usleep(20000);
|
||||
}
|
||||
if (_charon_pid == 0)
|
||||
return 0;
|
||||
plog("starter_stop_charon(): can't stop charon !!!");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
plog("stater_stop_charon(): charon is not started...");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
starter_start_charon (starter_config_t *cfg, bool debug)
|
||||
{
|
||||
int pid, i;
|
||||
struct stat stb;
|
||||
int argc = 1;
|
||||
char *arg[] = {
|
||||
CHARON_CMD, NULL, NULL,
|
||||
};
|
||||
|
||||
if (!debug)
|
||||
{
|
||||
arg[argc++] = "--use-syslog";
|
||||
}
|
||||
|
||||
if (_charon_pid)
|
||||
{
|
||||
plog("starter_start_charon(): charon already started...");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
unlink(CHARON_CTL_FILE);
|
||||
_stop_requested = 0;
|
||||
|
||||
pid = fork();
|
||||
switch (pid)
|
||||
{
|
||||
case -1:
|
||||
plog("can't fork(): %s", strerror(errno));
|
||||
return -1;
|
||||
case 0:
|
||||
/* child */
|
||||
setsid();
|
||||
sigprocmask(SIG_SETMASK, 0, NULL);
|
||||
execv(arg[0], arg);
|
||||
plog("can't execv(%s,...): %s", arg[0], strerror(errno));
|
||||
exit(1);
|
||||
default:
|
||||
/* father */
|
||||
_charon_pid = pid;
|
||||
for (i = 0; i < 50 && _charon_pid; i++)
|
||||
{
|
||||
/* wait for charon */
|
||||
usleep(20000);
|
||||
if (stat(CHARON_PID_FILE, &stb) == 0)
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("charon (%d) started", _charon_pid)
|
||||
)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (_charon_pid)
|
||||
{
|
||||
/* If charon is started but with no ctl file, stop it */
|
||||
plog("charon too long to start... - kill kill");
|
||||
for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
kill(pid, SIGINT);
|
||||
else if (i < 10)
|
||||
kill(pid, SIGTERM);
|
||||
else
|
||||
kill(pid, SIGKILL);
|
||||
usleep(20000);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plog("charon refused to be started");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/* strongSwan charon launcher
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
* Copyright (C) 2006 Martin Willi - Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Ported from invokepluto.h to fit charons needs.
|
||||
*
|
||||
* 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: invokecharon.h $
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_CHARON_H_
|
||||
#define _STARTER_CHARON_H_
|
||||
|
||||
#define CHARON_RESTART_DELAY 5
|
||||
|
||||
extern void starter_charon_sigchild (pid_t pid);
|
||||
extern pid_t starter_charon_pid (void);
|
||||
extern int starter_stop_charon (void);
|
||||
extern int starter_start_charon(struct starter_config *cfg, bool debug);
|
||||
|
||||
#endif /* _STARTER_CHARON_H_ */
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
/* strongSwan Pluto launcher
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: invokepluto.c,v 1.12 2006/02/17 21:41:50 as Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
|
||||
#include "confread.h"
|
||||
#include "invokepluto.h"
|
||||
#include "files.h"
|
||||
#include "starterwhack.h"
|
||||
#
|
||||
static int _pluto_pid = 0;
|
||||
static int _stop_requested;
|
||||
|
||||
pid_t
|
||||
starter_pluto_pid(void)
|
||||
{
|
||||
return _pluto_pid;
|
||||
}
|
||||
|
||||
void
|
||||
starter_pluto_sigchild(pid_t pid)
|
||||
{
|
||||
if (pid == _pluto_pid)
|
||||
{
|
||||
_pluto_pid = 0;
|
||||
if (!_stop_requested)
|
||||
{
|
||||
plog("pluto has died -- restart scheduled (%dsec)"
|
||||
, PLUTO_RESTART_DELAY);
|
||||
alarm(PLUTO_RESTART_DELAY); // restart in 5 sec
|
||||
}
|
||||
unlink(PLUTO_PID_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
starter_stop_pluto (void)
|
||||
{
|
||||
pid_t pid;
|
||||
int i;
|
||||
|
||||
pid = _pluto_pid;
|
||||
if (pid)
|
||||
{
|
||||
_stop_requested = 1;
|
||||
if (starter_whack_shutdown() == 0)
|
||||
{
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
usleep(20000);
|
||||
if (_pluto_pid == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* be more and more aggressive */
|
||||
for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
|
||||
{
|
||||
if (i < 10)
|
||||
kill(pid, SIGTERM);
|
||||
else
|
||||
kill(pid, SIGKILL);
|
||||
usleep(20000);
|
||||
}
|
||||
if (_pluto_pid == 0)
|
||||
return 0;
|
||||
plog("starter_stop_pluto(): can't stop pluto !!!");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
plog("stater_stop_pluto(): pluto is not started...");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define ADD_DEBUG(v) { \
|
||||
for (l = cfg->setup.plutodebug; l && *l; l++) if (streq(*l, v)) \
|
||||
arg[argc++] = "--debug-" v; \
|
||||
}
|
||||
|
||||
int
|
||||
starter_start_pluto (starter_config_t *cfg, bool debug)
|
||||
{
|
||||
int i;
|
||||
struct stat stb;
|
||||
pid_t pid;
|
||||
char **l;
|
||||
int argc = 2;
|
||||
char *arg[] = {
|
||||
PLUTO_CMD, "--nofork"
|
||||
, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
printf ("starter_start_pluto entered\n");
|
||||
|
||||
if (debug)
|
||||
{
|
||||
arg[argc++] = "--stderrlog";
|
||||
}
|
||||
if (cfg->setup.uniqueids)
|
||||
{
|
||||
arg[argc++] = "--uniqueids";
|
||||
}
|
||||
ADD_DEBUG("none")
|
||||
ADD_DEBUG("all")
|
||||
ADD_DEBUG("raw")
|
||||
ADD_DEBUG("crypt")
|
||||
ADD_DEBUG("parsing")
|
||||
ADD_DEBUG("emitting")
|
||||
ADD_DEBUG("control")
|
||||
ADD_DEBUG("lifecycle")
|
||||
ADD_DEBUG("klips")
|
||||
ADD_DEBUG("dns")
|
||||
ADD_DEBUG("natt")
|
||||
ADD_DEBUG("oppo")
|
||||
ADD_DEBUG("controlmore")
|
||||
ADD_DEBUG("private")
|
||||
if (cfg->setup.crlcheckinterval > 0)
|
||||
{
|
||||
static char buf1[15];
|
||||
|
||||
arg[argc++] = "--crlcheckinterval";
|
||||
snprintf(buf1, sizeof(buf1), "%u", cfg->setup.crlcheckinterval);
|
||||
arg[argc++] = buf1;
|
||||
}
|
||||
if (cfg->setup.cachecrls)
|
||||
{
|
||||
arg[argc++] = "--cachecrls";
|
||||
}
|
||||
if (cfg->setup.strictcrlpolicy)
|
||||
{
|
||||
arg[argc++] = "--strictcrlpolicy";
|
||||
}
|
||||
if (cfg->setup.nocrsend)
|
||||
{
|
||||
arg[argc++] = "--nocrsend";
|
||||
}
|
||||
if (cfg->setup.nat_traversal)
|
||||
{
|
||||
arg[argc++] = "--nat_traversal";
|
||||
}
|
||||
if (cfg->setup.keep_alive)
|
||||
{
|
||||
static char buf2[15];
|
||||
|
||||
arg[argc++] = "--keep_alive";
|
||||
snprintf(buf2, sizeof(buf2), "%u", cfg->setup.keep_alive);
|
||||
arg[argc++] = buf2;
|
||||
}
|
||||
#ifdef VIRTUAL_IP
|
||||
if (cfg->setup.virtual_private)
|
||||
{
|
||||
arg[argc++] = "--virtual_private";
|
||||
arg[argc++] = cfg->setup.virtual_private;
|
||||
}
|
||||
#endif
|
||||
if (cfg->setup.pkcs11module)
|
||||
{
|
||||
arg[argc++] = "--pkcs11module";
|
||||
arg[argc++] = cfg->setup.pkcs11module;
|
||||
}
|
||||
if (cfg->setup.pkcs11keepstate)
|
||||
{
|
||||
arg[argc++] = "--pkcs11keepstate";
|
||||
}
|
||||
if (cfg->setup.pkcs11proxy)
|
||||
{
|
||||
arg[argc++] = "--pkcs11proxy";
|
||||
}
|
||||
|
||||
if (_pluto_pid)
|
||||
{
|
||||
plog("starter_start_pluto(): pluto already started...");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
unlink(PLUTO_CTL_FILE);
|
||||
_stop_requested = 0;
|
||||
|
||||
if (cfg->setup.prepluto)
|
||||
system(cfg->setup.prepluto);
|
||||
|
||||
/* if ipsec.secrets file is missing then generate RSA default key pair */
|
||||
if (stat(SECRETS_FILE, &stb) != 0)
|
||||
{
|
||||
mode_t oldmask;
|
||||
FILE *f;
|
||||
|
||||
plog("no %s file, generating RSA key", SECRETS_FILE);
|
||||
system("ipsec scepclient --out pkcs1 --out cert-self --quiet");
|
||||
|
||||
/* ipsec.secrets is root readable only */
|
||||
oldmask = umask(0066);
|
||||
|
||||
f = fopen(SECRETS_FILE, "w");
|
||||
if (f)
|
||||
{
|
||||
fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
|
||||
fprintf(f, "\n");
|
||||
fprintf(f, ": RSA myKey.der\n");
|
||||
fclose(f);
|
||||
}
|
||||
umask(oldmask);
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
switch (pid)
|
||||
{
|
||||
case -1:
|
||||
plog("can't fork(): %s", strerror(errno));
|
||||
return -1;
|
||||
case 0:
|
||||
/* child */
|
||||
setsid();
|
||||
sigprocmask(SIG_SETMASK, 0, NULL);
|
||||
execv(arg[0], arg);
|
||||
plog("can't execv(%s,...): %s", arg[0], strerror(errno));
|
||||
exit(1);
|
||||
default:
|
||||
/* father */
|
||||
_pluto_pid = pid;
|
||||
for (i = 0; i < 50 && _pluto_pid; i++)
|
||||
{
|
||||
/* wait for pluto */
|
||||
usleep(20000);
|
||||
if (stat(PLUTO_CTL_FILE, &stb) == 0)
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("pluto (%d) started", _pluto_pid)
|
||||
)
|
||||
if (cfg->setup.postpluto)
|
||||
system(cfg->setup.postpluto);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (_pluto_pid)
|
||||
{
|
||||
/* If pluto is started but with no ctl file, stop it */
|
||||
plog("pluto too long to start... - kill kill");
|
||||
for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
|
||||
{
|
||||
if (i < 10)
|
||||
kill(pid, SIGTERM);
|
||||
else
|
||||
kill(pid, SIGKILL);
|
||||
usleep(20000);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plog("pluto refused to be started");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/* strongSwan pluto launcher
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: invokepluto.h,v 1.3 2006/01/04 23:30:24 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_PLUTO_H_
|
||||
#define _STARTER_PLUTO_H_
|
||||
|
||||
#define PLUTO_RESTART_DELAY 5
|
||||
|
||||
extern void starter_pluto_sigchild (pid_t pid);
|
||||
extern pid_t starter_pluto_pid (void);
|
||||
extern int starter_stop_pluto (void);
|
||||
extern int starter_start_pluto (struct starter_config *cfg, bool debug);
|
||||
|
||||
#endif /* _STARTER_PLUTO_H_ */
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
/* C code produced by gperf version 3.0.1 */
|
||||
/* Command-line: gperf -C -G -t */
|
||||
/* Computed positions: -k'3,$' */
|
||||
|
||||
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
|
||||
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
|
||||
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
|
||||
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
|
||||
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
|
||||
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
|
||||
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
|
||||
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
|
||||
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
|
||||
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
|
||||
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
|
||||
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
|
||||
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
|
||||
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
|
||||
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
|
||||
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
|
||||
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
|
||||
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
|
||||
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
|
||||
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
|
||||
/* The character set is not based on ISO-646. */
|
||||
error "gperf generated tables don't work with this execution character set. Please report a bug to <[email protected]>."
|
||||
#endif
|
||||
|
||||
|
||||
/* strongSwan keywords
|
||||
* Copyright (C) 2005 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil, Switzerland
|
||||
*
|
||||
* 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: keywords.c,v 1.7 2006/04/17 10:32:48 as Exp $
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "keywords.h"
|
||||
|
||||
struct kw_entry {
|
||||
char *name;
|
||||
kw_token_t token;
|
||||
};
|
||||
|
||||
#define TOTAL_KEYWORDS 77
|
||||
#define MIN_WORD_LENGTH 3
|
||||
#define MAX_WORD_LENGTH 17
|
||||
#define MIN_HASH_VALUE 9
|
||||
#define MAX_HASH_VALUE 146
|
||||
/* maximum key range = 138, duplicates = 0 */
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
inline
|
||||
#endif
|
||||
#endif
|
||||
static unsigned int
|
||||
hash (str, len)
|
||||
register const char *str;
|
||||
register unsigned int len;
|
||||
{
|
||||
static const unsigned char asso_values[] =
|
||||
{
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
15, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 85, 147, 40,
|
||||
25, 25, 0, 10, 5, 80, 147, 35, 60, 35,
|
||||
60, 55, 10, 147, 15, 20, 5, 65, 147, 147,
|
||||
147, 35, 0, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
|
||||
147, 147, 147, 147, 147, 147
|
||||
};
|
||||
return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[len - 1]];
|
||||
}
|
||||
|
||||
static const struct kw_entry wordlist[] =
|
||||
{
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{"left", KW_LEFT},
|
||||
{""}, {""}, {""},
|
||||
{"leftcert", KW_LEFTCERT,},
|
||||
{"auth", KW_AUTH},
|
||||
{"leftsubnet", KW_LEFTSUBNET},
|
||||
{""},
|
||||
{"leftsendcert", KW_LEFTSENDCERT},
|
||||
{"leftprotoport", KW_LEFTPROTOPORT},
|
||||
{""},
|
||||
{"right", KW_RIGHT},
|
||||
{"leftnexthop", KW_LEFTNEXTHOP},
|
||||
{"leftsourceip", KW_LEFTSOURCEIP},
|
||||
{"esp", KW_ESP},
|
||||
{"rightcert", KW_RIGHTCERT},
|
||||
{""},
|
||||
{"rightsubnet", KW_RIGHTSUBNET},
|
||||
{""},
|
||||
{"rightsendcert", KW_RIGHTSENDCERT},
|
||||
{"rightprotoport", KW_RIGHTPROTOPORT},
|
||||
{"leftgroups", KW_LEFTGROUPS},
|
||||
{"leftid", KW_LEFTID},
|
||||
{"rightnexthop", KW_RIGHTNEXTHOP},
|
||||
{"rightsourceip", KW_RIGHTSOURCEIP},
|
||||
{"lefthostaccess", KW_LEFTHOSTACCESS},
|
||||
{"interfaces", KW_INTERFACES},
|
||||
{""}, {""},
|
||||
{"pfsgroup", KW_PFSGROUP},
|
||||
{"type", KW_TYPE},
|
||||
{"dpdtimeout", KW_DPDTIMEOUT},
|
||||
{"rightgroups", KW_RIGHTGROUPS},
|
||||
{"rightid", KW_RIGHTID},
|
||||
{"pfs", KW_PFS},
|
||||
{"rekeyfuzz", KW_REKEYFUZZ},
|
||||
{"righthostaccess", KW_RIGHTHOSTACCESS},
|
||||
{"authby", KW_AUTHBY},
|
||||
{""},
|
||||
{"leftrsasigkey", KW_LEFTRSASIGKEY},
|
||||
{""}, {""},
|
||||
{"cacert", KW_CACERT},
|
||||
{"hidetos", KW_HIDETOS},
|
||||
{"ike", KW_IKE},
|
||||
{""},
|
||||
{"virtual_private", KW_VIRTUAL_PRIVATE},
|
||||
{""},
|
||||
{"dumpdir", KW_DUMPDIR},
|
||||
{"packetdefault", KW_PACKETDEFAULT},
|
||||
{"rightrsasigkey", KW_RIGHTRSASIGKEY},
|
||||
{"keep_alive", KW_KEEP_ALIVE},
|
||||
{"ikelifetime", KW_IKELIFETIME},
|
||||
{""},
|
||||
{"compress", KW_COMPRESS},
|
||||
{"auto", KW_AUTO},
|
||||
{"strictcrlpolicy", KW_STRICTCRLPOLICY},
|
||||
{"keyingtries", KW_KEYINGTRIES},
|
||||
{"keylife", KW_KEYLIFE},
|
||||
{"dpddelay", KW_DPDDELAY},
|
||||
{"cachecrls", KW_CACHECRLS},
|
||||
{"leftupdown", KW_LEFTUPDOWN},
|
||||
{"keyexchange", KW_KEYEXCHANGE},
|
||||
{"leftfirewall", KW_LEFTFIREWALL},
|
||||
{"nocrsend", KW_NOCRSEND},
|
||||
{""},
|
||||
{"rekey", KW_REKEY},
|
||||
{"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
|
||||
{"pkcs11module", KW_PKCS11MODULE},
|
||||
{"nat_traversal", KW_NAT_TRAVERSAL},
|
||||
{"also", KW_ALSO},
|
||||
{"pkcs11keepstate", KW_PKCS11KEEPSTATE},
|
||||
{"rightupdown", KW_RIGHTUPDOWN},
|
||||
{"crluri2", KW_CRLURI2},
|
||||
{"rightfirewall", KW_RIGHTFIREWALL},
|
||||
{"postpluto", KW_POSTPLUTO},
|
||||
{"plutodebug", KW_PLUTODEBUG},
|
||||
{"pkcs11proxy", KW_PKCS11PROXY},
|
||||
{"rightsubnetwithin", KW_RIGHTSUBNETWITHIN},
|
||||
{"prepluto", KW_PREPLUTO},
|
||||
{""}, {""},
|
||||
{"leftca", KW_LEFTCA},
|
||||
{""}, {""},
|
||||
{"dpdaction", KW_DPDACTION},
|
||||
{""}, {""}, {""},
|
||||
{"ldaphost", KW_LDAPHOST},
|
||||
{""},
|
||||
{"klipsdebug", KW_KLIPSDEBUG},
|
||||
{"overridemtu", KW_OVERRIDEMTU},
|
||||
{"rightca", KW_RIGHTCA},
|
||||
{"fragicmp", KW_FRAGICMP},
|
||||
{""}, {""},
|
||||
{"rekeymargin", KW_REKEYMARGIN},
|
||||
{"ocspuri", KW_OCSPURI},
|
||||
{""},
|
||||
{"uniqueids", KW_UNIQUEIDS},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{"ldapbase", KW_LDAPBASE},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{"crlcheckinterval", KW_CRLCHECKINTERVAL},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{"crluri", KW_CRLURI}
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#endif
|
||||
const struct kw_entry *
|
||||
in_word_set (str, len)
|
||||
register const char *str;
|
||||
register unsigned int len;
|
||||
{
|
||||
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
|
||||
{
|
||||
register int key = hash (str, len);
|
||||
|
||||
if (key <= MAX_HASH_VALUE && key >= 0)
|
||||
{
|
||||
register const char *s = wordlist[key].name;
|
||||
|
||||
if (*str == *s && !strcmp (str + 1, s + 1))
|
||||
return &wordlist[key];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/* strongSwan keywords
|
||||
* Copyright (C) 2005 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil, Switzerland
|
||||
*
|
||||
* 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: keywords.h,v 1.8 2006/04/17 10:30:27 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _KEYWORDS_H_
|
||||
#define _KEYWORDS_H_
|
||||
|
||||
typedef enum {
|
||||
/* config setup keywords */
|
||||
KW_INTERFACES,
|
||||
KW_DUMPDIR,
|
||||
|
||||
/* pluto keywords */
|
||||
KW_PLUTODEBUG,
|
||||
KW_PREPLUTO,
|
||||
KW_POSTPLUTO,
|
||||
KW_UNIQUEIDS,
|
||||
KW_OVERRIDEMTU,
|
||||
KW_CRLCHECKINTERVAL,
|
||||
KW_CACHECRLS,
|
||||
KW_STRICTCRLPOLICY,
|
||||
KW_NOCRSEND,
|
||||
KW_NAT_TRAVERSAL,
|
||||
KW_KEEP_ALIVE,
|
||||
KW_VIRTUAL_PRIVATE,
|
||||
KW_PKCS11MODULE,
|
||||
KW_PKCS11KEEPSTATE,
|
||||
KW_PKCS11PROXY,
|
||||
|
||||
#define KW_PLUTO_FIRST KW_PLUTODEBUG
|
||||
#define KW_PLUTO_LAST KW_PKCS11PROXY
|
||||
|
||||
/* KLIPS keywords */
|
||||
KW_KLIPSDEBUG,
|
||||
KW_FRAGICMP,
|
||||
KW_PACKETDEFAULT,
|
||||
KW_HIDETOS,
|
||||
|
||||
#define KW_KLIPS_FIRST KW_KLIPSDEBUG
|
||||
#define KW_KLIPS_LAST KW_HIDETOS
|
||||
|
||||
#define KW_SETUP_FIRST KW_INTERFACES
|
||||
#define KW_SETUP_LAST KW_HIDETOS
|
||||
|
||||
/* conn section keywords */
|
||||
KW_CONN_NAME,
|
||||
KW_CONN_SETUP,
|
||||
KW_KEYEXCHANGE,
|
||||
KW_TYPE,
|
||||
KW_PFS,
|
||||
KW_COMPRESS,
|
||||
KW_AUTH,
|
||||
KW_AUTHBY,
|
||||
KW_IKELIFETIME,
|
||||
KW_KEYLIFE,
|
||||
KW_REKEYMARGIN,
|
||||
KW_KEYINGTRIES,
|
||||
KW_REKEYFUZZ,
|
||||
KW_REKEY,
|
||||
KW_IKE,
|
||||
KW_ESP,
|
||||
KW_PFSGROUP,
|
||||
KW_DPDDELAY,
|
||||
KW_DPDTIMEOUT,
|
||||
KW_DPDACTION,
|
||||
|
||||
#define KW_CONN_FIRST KW_CONN_SETUP
|
||||
#define KW_CONN_LAST KW_DPDACTION
|
||||
|
||||
/* ca section keywords */
|
||||
KW_CA_NAME,
|
||||
KW_CA_SETUP,
|
||||
KW_CACERT,
|
||||
KW_LDAPHOST,
|
||||
KW_LDAPBASE,
|
||||
KW_CRLURI,
|
||||
KW_CRLURI2,
|
||||
KW_OCSPURI,
|
||||
|
||||
#define KW_CA_FIRST KW_CA_SETUP
|
||||
#define KW_CA_LAST KW_OCSPURI
|
||||
|
||||
/* end keywords */
|
||||
KW_HOST,
|
||||
KW_NEXTHOP,
|
||||
KW_SUBNET,
|
||||
KW_SUBNETWITHIN,
|
||||
KW_PROTOPORT,
|
||||
KW_SOURCEIP,
|
||||
KW_FIREWALL,
|
||||
KW_HOSTACCESS,
|
||||
KW_UPDOWN,
|
||||
KW_ID,
|
||||
KW_RSASIGKEY,
|
||||
KW_CERT,
|
||||
KW_SENDCERT,
|
||||
KW_CA,
|
||||
KW_GROUPS,
|
||||
KW_IFACE,
|
||||
|
||||
#define KW_END_FIRST KW_HOST
|
||||
#define KW_END_LAST KW_IFACE
|
||||
|
||||
/* left end keywords */
|
||||
KW_LEFT,
|
||||
KW_LEFTNEXTHOP,
|
||||
KW_LEFTSUBNET,
|
||||
KW_LEFTSUBNETWITHIN,
|
||||
KW_LEFTPROTOPORT,
|
||||
KW_LEFTSOURCEIP,
|
||||
KW_LEFTFIREWALL,
|
||||
KW_LEFTHOSTACCESS,
|
||||
KW_LEFTUPDOWN,
|
||||
KW_LEFTID,
|
||||
KW_LEFTRSASIGKEY,
|
||||
KW_LEFTCERT,
|
||||
KW_LEFTSENDCERT,
|
||||
KW_LEFTCA,
|
||||
KW_LEFTGROUPS,
|
||||
|
||||
#define KW_LEFT_FIRST KW_LEFT
|
||||
#define KW_LEFT_LAST KW_LEFTGROUPS
|
||||
|
||||
/* right end keywords */
|
||||
KW_RIGHT,
|
||||
KW_RIGHTNEXTHOP,
|
||||
KW_RIGHTSUBNET,
|
||||
KW_RIGHTSUBNETWITHIN,
|
||||
KW_RIGHTPROTOPORT,
|
||||
KW_RIGHTSOURCEIP,
|
||||
KW_RIGHTFIREWALL,
|
||||
KW_RIGHTHOSTACCESS,
|
||||
KW_RIGHTUPDOWN,
|
||||
KW_RIGHTID,
|
||||
KW_RIGHTRSASIGKEY,
|
||||
KW_RIGHTCERT,
|
||||
KW_RIGHTSENDCERT,
|
||||
KW_RIGHTCA,
|
||||
KW_RIGHTGROUPS,
|
||||
|
||||
#define KW_RIGHT_FIRST KW_RIGHT
|
||||
#define KW_RIGHT_LAST KW_RIGHTGROUPS
|
||||
|
||||
/* general section keywords */
|
||||
KW_ALSO,
|
||||
KW_AUTO
|
||||
|
||||
} kw_token_t;
|
||||
|
||||
#endif /* _KEYWORDS_H_ */
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
%{
|
||||
/* strongSwan keywords
|
||||
* Copyright (C) 2005 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil, Switzerland
|
||||
*
|
||||
* 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: keywords.txt,v 1.6 2006/04/17 10:30:27 as Exp $
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "keywords.h"
|
||||
|
||||
%}
|
||||
struct kw_entry {
|
||||
char *name;
|
||||
kw_token_t token;
|
||||
};
|
||||
%%
|
||||
interfaces, KW_INTERFACES
|
||||
klipsdebug, KW_KLIPSDEBUG
|
||||
plutodebug, KW_PLUTODEBUG
|
||||
dumpdir, KW_DUMPDIR
|
||||
prepluto, KW_PREPLUTO
|
||||
postpluto, KW_POSTPLUTO
|
||||
fragicmp, KW_FRAGICMP
|
||||
packetdefault, KW_PACKETDEFAULT
|
||||
hidetos, KW_HIDETOS
|
||||
uniqueids, KW_UNIQUEIDS
|
||||
overridemtu, KW_OVERRIDEMTU
|
||||
crlcheckinterval, KW_CRLCHECKINTERVAL
|
||||
cachecrls, KW_CACHECRLS
|
||||
strictcrlpolicy, KW_STRICTCRLPOLICY
|
||||
nocrsend, KW_NOCRSEND
|
||||
nat_traversal, KW_NAT_TRAVERSAL
|
||||
keep_alive, KW_KEEP_ALIVE
|
||||
virtual_private, KW_VIRTUAL_PRIVATE
|
||||
pkcs11module, KW_PKCS11MODULE
|
||||
pkcs11keepstate, KW_PKCS11KEEPSTATE
|
||||
pkcs11proxy, KW_PKCS11PROXY
|
||||
keyexchange, KW_KEYEXCHANGE
|
||||
type, KW_TYPE
|
||||
pfs, KW_PFS
|
||||
compress, KW_COMPRESS
|
||||
auth, KW_AUTH
|
||||
authby, KW_AUTHBY
|
||||
keylife, KW_KEYLIFE
|
||||
rekeymargin, KW_REKEYMARGIN
|
||||
ikelifetime, KW_IKELIFETIME
|
||||
keyingtries, KW_KEYINGTRIES
|
||||
rekeyfuzz, KW_REKEYFUZZ
|
||||
rekey, KW_REKEY
|
||||
esp, KW_ESP
|
||||
ike, KW_IKE
|
||||
pfsgroup, KW_PFSGROUP
|
||||
dpddelay, KW_DPDDELAY
|
||||
dpdtimeout, KW_DPDTIMEOUT
|
||||
dpdaction, KW_DPDACTION
|
||||
cacert, KW_CACERT
|
||||
ldaphost, KW_LDAPHOST
|
||||
ldapbase, KW_LDAPBASE
|
||||
crluri, KW_CRLURI
|
||||
crluri2, KW_CRLURI2
|
||||
ocspuri, KW_OCSPURI
|
||||
left, KW_LEFT
|
||||
leftnexthop, KW_LEFTNEXTHOP
|
||||
leftsubnet, KW_LEFTSUBNET
|
||||
leftsubnetwithin, KW_LEFTSUBNETWITHIN
|
||||
leftprotoport, KW_LEFTPROTOPORT
|
||||
leftsourceip, KW_LEFTSOURCEIP
|
||||
leftfirewall, KW_LEFTFIREWALL
|
||||
lefthostaccess, KW_LEFTHOSTACCESS
|
||||
leftupdown, KW_LEFTUPDOWN
|
||||
leftid, KW_LEFTID
|
||||
leftrsasigkey, KW_LEFTRSASIGKEY
|
||||
leftcert, KW_LEFTCERT,
|
||||
leftsendcert, KW_LEFTSENDCERT
|
||||
leftca, KW_LEFTCA
|
||||
leftgroups, KW_LEFTGROUPS
|
||||
right, KW_RIGHT
|
||||
rightnexthop, KW_RIGHTNEXTHOP
|
||||
rightsubnet, KW_RIGHTSUBNET
|
||||
rightsubnetwithin, KW_RIGHTSUBNETWITHIN
|
||||
rightprotoport, KW_RIGHTPROTOPORT
|
||||
rightsourceip, KW_RIGHTSOURCEIP
|
||||
rightfirewall, KW_RIGHTFIREWALL
|
||||
righthostaccess, KW_RIGHTHOSTACCESS
|
||||
rightupdown, KW_RIGHTUPDOWN
|
||||
rightid, KW_RIGHTID
|
||||
rightrsasigkey, KW_RIGHTRSASIGKEY
|
||||
rightcert, KW_RIGHTCERT
|
||||
rightsendcert, KW_RIGHTSENDCERT
|
||||
rightca, KW_RIGHTCA
|
||||
rightgroups, KW_RIGHTGROUPS
|
||||
also, KW_ALSO
|
||||
auto, KW_AUTO
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,85 @@
|
||||
/* strongSwan netkey starter
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: netkey.c,v 1.4 2006/02/15 18:33:57 as Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
|
||||
#include "files.h"
|
||||
|
||||
bool
|
||||
starter_netkey_init(void)
|
||||
{
|
||||
struct stat stb;
|
||||
|
||||
if (stat(PROC_NETKEY, &stb) != 0)
|
||||
{
|
||||
/* af_key module makes the netkey proc interface visible */
|
||||
if (stat(PROC_MODULES, &stb) == 0)
|
||||
{
|
||||
system("modprobe -qv af_key");
|
||||
}
|
||||
|
||||
/* now test again */
|
||||
if (stat(PROC_NETKEY, &stb) != 0)
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("kernel appears to lack the native netkey IPsec stack")
|
||||
)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure that all required IPsec modules are loaded */
|
||||
if (stat(PROC_MODULES, &stb) == 0)
|
||||
{
|
||||
system("modprobe -qv ah4");
|
||||
system("modprobe -qv esp4");
|
||||
system("modprobe -qv ipcomp");
|
||||
system("modprobe -qv xfrm4_tunnel");
|
||||
system("modprobe -qv xfrm_user");
|
||||
}
|
||||
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Found netkey IPsec stack")
|
||||
)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
starter_netkey_cleanup(void)
|
||||
{
|
||||
if (system("ip xfrm state > /dev/null 2>&1") == 0)
|
||||
{
|
||||
system("ip xfrm state flush");
|
||||
system("ip xfrm policy flush");
|
||||
}
|
||||
else if (system("type setkey > /dev/null 2>&1") == 0)
|
||||
{
|
||||
system("setkey -F");
|
||||
system("setkey -FP");
|
||||
}
|
||||
else
|
||||
{
|
||||
plog("WARNING: cannot flush IPsec state/policy database");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/* strongSwan netkey initialization and cleanup
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: netkey.h,v 1.1 2005/12/30 19:03:15 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_NETKEY_H_
|
||||
#define _STARTER_NETKEY_H_
|
||||
|
||||
extern bool starter_netkey_init (void);
|
||||
extern void starter_netkey_cleanup (void);
|
||||
|
||||
#endif /* _STARTER_NETKEY_H_ */
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/* strongSwan config file parser
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: parser.h,v 1.5 2006/01/17 23:43:36 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _IPSEC_PARSER_H_
|
||||
#define _IPSEC_PARSER_H_
|
||||
|
||||
#include "keywords.h"
|
||||
|
||||
typedef struct kw_entry kw_entry_t;
|
||||
|
||||
struct kw_entry {
|
||||
char *name;
|
||||
kw_token_t token;
|
||||
};
|
||||
|
||||
typedef struct kw_list kw_list_t;
|
||||
|
||||
struct kw_list {
|
||||
kw_entry_t *entry;
|
||||
char *value;
|
||||
kw_list_t *next;
|
||||
};
|
||||
|
||||
typedef struct section_list section_list_t;
|
||||
|
||||
struct section_list {
|
||||
char *name;
|
||||
kw_list_t *kw;
|
||||
section_list_t *next;
|
||||
};
|
||||
|
||||
typedef struct config_parsed config_parsed_t;
|
||||
|
||||
struct config_parsed {
|
||||
kw_list_t *config_setup;
|
||||
section_list_t *conn_first, *conn_last;
|
||||
section_list_t *ca_first, *ca_last;
|
||||
};
|
||||
|
||||
config_parsed_t *parser_load_conf (const char *file);
|
||||
void parser_free_conf (config_parsed_t *cfg);
|
||||
|
||||
#endif /* _IPSEC_PARSER_H_ */
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
%{
|
||||
/* FreeS/WAN config file parser (parser.l)
|
||||
* Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: parser.l,v 1.5 2006/03/28 22:32:33 as Exp $
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <glob.h>
|
||||
|
||||
#include "parser.tab.h"
|
||||
|
||||
#define MAX_INCLUDE_DEPTH 20
|
||||
|
||||
#define YY_NO_UNPUT
|
||||
extern void yyerror(const char *);
|
||||
extern int yylex (void);
|
||||
|
||||
static struct {
|
||||
int stack_ptr;
|
||||
YY_BUFFER_STATE stack[MAX_INCLUDE_DEPTH];
|
||||
FILE *file[MAX_INCLUDE_DEPTH];
|
||||
unsigned int line[MAX_INCLUDE_DEPTH];
|
||||
char *filename[MAX_INCLUDE_DEPTH];
|
||||
} __parser_y_private;
|
||||
|
||||
void _parser_y_error(char *b, int size, const char *s);
|
||||
void _parser_y_init (const char *f);
|
||||
void _parser_y_fini (void);
|
||||
int _parser_y_include (const char *filename);
|
||||
|
||||
void _parser_y_error(char *b, int size, const char *s)
|
||||
{
|
||||
extern char *yytext; // was: char yytext[];
|
||||
|
||||
snprintf(b, size, "%s:%d: %s [%s]",
|
||||
__parser_y_private.filename[__parser_y_private.stack_ptr],
|
||||
__parser_y_private.line[__parser_y_private.stack_ptr],
|
||||
s, yytext);
|
||||
}
|
||||
|
||||
void _parser_y_init (const char *f)
|
||||
{
|
||||
memset(&__parser_y_private, 0, sizeof(__parser_y_private));
|
||||
__parser_y_private.line[0] = 1;
|
||||
__parser_y_private.filename[0] = strdup(f);
|
||||
}
|
||||
|
||||
void _parser_y_fini (void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < MAX_INCLUDE_DEPTH; i++)
|
||||
{
|
||||
if (__parser_y_private.filename[i])
|
||||
free(__parser_y_private.filename[i]);
|
||||
if (__parser_y_private.file[i])
|
||||
fclose(__parser_y_private.file[i]);
|
||||
}
|
||||
memset(&__parser_y_private, 0, sizeof(__parser_y_private));
|
||||
}
|
||||
|
||||
int _parser_y_include (const char *filename)
|
||||
{
|
||||
glob_t files;
|
||||
int i, ret;
|
||||
|
||||
ret = glob(filename, GLOB_ERR, NULL, &files);
|
||||
if (ret)
|
||||
{
|
||||
const char *err;
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case GLOB_NOSPACE:
|
||||
err = "include files ran out of memory";
|
||||
break;
|
||||
case GLOB_ABORTED:
|
||||
err = "include files aborted due to read error";
|
||||
break;
|
||||
case GLOB_NOMATCH:
|
||||
err = "include files found no matches";
|
||||
break;
|
||||
default:
|
||||
err = "unknown include files error";
|
||||
}
|
||||
yyerror(err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < files.gl_pathc; i++)
|
||||
{
|
||||
FILE *f;
|
||||
unsigned int p = __parser_y_private.stack_ptr + 1;
|
||||
|
||||
if (p >= MAX_INCLUDE_DEPTH)
|
||||
{
|
||||
yyerror("max inclusion depth reached");
|
||||
return 1;
|
||||
}
|
||||
|
||||
f = fopen(files.gl_pathv[i], "r");
|
||||
if (!f)
|
||||
{
|
||||
yyerror("can't open include filename");
|
||||
continue;
|
||||
}
|
||||
|
||||
__parser_y_private.stack_ptr++;
|
||||
__parser_y_private.file[p] = f;
|
||||
__parser_y_private.stack[p] = YY_CURRENT_BUFFER;
|
||||
__parser_y_private.line[p] = 1;
|
||||
__parser_y_private.filename[p] = strdup(files.gl_pathv[i]);
|
||||
|
||||
yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
|
||||
}
|
||||
globfree(&files);
|
||||
return 0;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
<<EOF>> {
|
||||
if (__parser_y_private.filename[__parser_y_private.stack_ptr]) {
|
||||
free(__parser_y_private.filename[__parser_y_private.stack_ptr]);
|
||||
__parser_y_private.filename[__parser_y_private.stack_ptr] = NULL;
|
||||
}
|
||||
if (__parser_y_private.file[__parser_y_private.stack_ptr]) {
|
||||
fclose(__parser_y_private.file[__parser_y_private.stack_ptr]);
|
||||
__parser_y_private.file[__parser_y_private.stack_ptr] = NULL;
|
||||
yy_delete_buffer (YY_CURRENT_BUFFER);
|
||||
yy_switch_to_buffer
|
||||
(__parser_y_private.stack[__parser_y_private.stack_ptr]);
|
||||
}
|
||||
if (--__parser_y_private.stack_ptr < 0) {
|
||||
yyterminate();
|
||||
}
|
||||
}
|
||||
|
||||
^[\t ]+ return FIRST_SPACES;
|
||||
|
||||
[\t ]+ /* ignore spaces in line */ ;
|
||||
|
||||
= return EQUAL;
|
||||
|
||||
\n|#.*\n {
|
||||
__parser_y_private.line[__parser_y_private.stack_ptr]++;
|
||||
return EOL;
|
||||
}
|
||||
|
||||
config return CONFIG;
|
||||
setup return SETUP;
|
||||
conn return CONN;
|
||||
ca return CA;
|
||||
include return INCLUDE;
|
||||
version return VERSION;
|
||||
|
||||
[^\"= \t\n]+ {
|
||||
yylval.s = strdup(yytext);
|
||||
return STRING;
|
||||
}
|
||||
|
||||
\"[^\"\n]*\" {
|
||||
yylval.s = strdup(yytext+1);
|
||||
if (yylval.s) yylval.s[strlen(yylval.s)-1]='\0';
|
||||
return STRING;
|
||||
}
|
||||
|
||||
. yyerror(yytext);
|
||||
|
||||
%%
|
||||
|
||||
int yywrap(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
Grammar
|
||||
|
||||
0 $accept: config_file $end
|
||||
|
||||
1 config_file: config_file section_or_include
|
||||
2 | /* empty */
|
||||
|
||||
3 section_or_include: VERSION STRING EOL
|
||||
|
||||
4 @1: /* empty */
|
||||
|
||||
5 section_or_include: CONFIG SETUP EOL @1 kw_section
|
||||
|
||||
6 @2: /* empty */
|
||||
|
||||
7 section_or_include: CONN STRING EOL @2 kw_section
|
||||
|
||||
8 @3: /* empty */
|
||||
|
||||
9 section_or_include: CA STRING EOL @3 kw_section
|
||||
|
||||
10 @4: /* empty */
|
||||
|
||||
11 section_or_include: INCLUDE STRING @4 EOL
|
||||
12 | EOL
|
||||
|
||||
13 kw_section: FIRST_SPACES statement_kw EOL kw_section
|
||||
14 | /* empty */
|
||||
|
||||
15 statement_kw: STRING EQUAL STRING
|
||||
16 | STRING EQUAL
|
||||
17 | /* empty */
|
||||
|
||||
|
||||
Terminals, with rules where they appear
|
||||
|
||||
$end (0) 0
|
||||
error (256)
|
||||
EQUAL (258) 15 16
|
||||
FIRST_SPACES (259) 13
|
||||
EOL (260) 3 5 7 9 11 12 13
|
||||
CONFIG (261) 5
|
||||
SETUP (262) 5
|
||||
CONN (263) 7
|
||||
CA (264) 9
|
||||
INCLUDE (265) 11
|
||||
VERSION (266) 3
|
||||
STRING (267) 3 7 9 11 15 16
|
||||
|
||||
|
||||
Nonterminals, with rules where they appear
|
||||
|
||||
$accept (13)
|
||||
on left: 0
|
||||
config_file (14)
|
||||
on left: 1 2, on right: 0 1
|
||||
section_or_include (15)
|
||||
on left: 3 5 7 9 11 12, on right: 1
|
||||
@1 (16)
|
||||
on left: 4, on right: 5
|
||||
@2 (17)
|
||||
on left: 6, on right: 7
|
||||
@3 (18)
|
||||
on left: 8, on right: 9
|
||||
@4 (19)
|
||||
on left: 10, on right: 11
|
||||
kw_section (20)
|
||||
on left: 13 14, on right: 5 7 9 13
|
||||
statement_kw (21)
|
||||
on left: 15 16 17, on right: 13
|
||||
|
||||
|
||||
state 0
|
||||
|
||||
0 $accept: . config_file $end
|
||||
|
||||
$default reduce using rule 2 (config_file)
|
||||
|
||||
config_file go to state 1
|
||||
|
||||
|
||||
state 1
|
||||
|
||||
0 $accept: config_file . $end
|
||||
1 config_file: config_file . section_or_include
|
||||
|
||||
$end shift, and go to state 2
|
||||
EOL shift, and go to state 3
|
||||
CONFIG shift, and go to state 4
|
||||
CONN shift, and go to state 5
|
||||
CA shift, and go to state 6
|
||||
INCLUDE shift, and go to state 7
|
||||
VERSION shift, and go to state 8
|
||||
|
||||
section_or_include go to state 9
|
||||
|
||||
|
||||
state 2
|
||||
|
||||
0 $accept: config_file $end .
|
||||
|
||||
$default accept
|
||||
|
||||
|
||||
state 3
|
||||
|
||||
12 section_or_include: EOL .
|
||||
|
||||
$default reduce using rule 12 (section_or_include)
|
||||
|
||||
|
||||
state 4
|
||||
|
||||
5 section_or_include: CONFIG . SETUP EOL @1 kw_section
|
||||
|
||||
SETUP shift, and go to state 10
|
||||
|
||||
|
||||
state 5
|
||||
|
||||
7 section_or_include: CONN . STRING EOL @2 kw_section
|
||||
|
||||
STRING shift, and go to state 11
|
||||
|
||||
|
||||
state 6
|
||||
|
||||
9 section_or_include: CA . STRING EOL @3 kw_section
|
||||
|
||||
STRING shift, and go to state 12
|
||||
|
||||
|
||||
state 7
|
||||
|
||||
11 section_or_include: INCLUDE . STRING @4 EOL
|
||||
|
||||
STRING shift, and go to state 13
|
||||
|
||||
|
||||
state 8
|
||||
|
||||
3 section_or_include: VERSION . STRING EOL
|
||||
|
||||
STRING shift, and go to state 14
|
||||
|
||||
|
||||
state 9
|
||||
|
||||
1 config_file: config_file section_or_include .
|
||||
|
||||
$default reduce using rule 1 (config_file)
|
||||
|
||||
|
||||
state 10
|
||||
|
||||
5 section_or_include: CONFIG SETUP . EOL @1 kw_section
|
||||
|
||||
EOL shift, and go to state 15
|
||||
|
||||
|
||||
state 11
|
||||
|
||||
7 section_or_include: CONN STRING . EOL @2 kw_section
|
||||
|
||||
EOL shift, and go to state 16
|
||||
|
||||
|
||||
state 12
|
||||
|
||||
9 section_or_include: CA STRING . EOL @3 kw_section
|
||||
|
||||
EOL shift, and go to state 17
|
||||
|
||||
|
||||
state 13
|
||||
|
||||
11 section_or_include: INCLUDE STRING . @4 EOL
|
||||
|
||||
$default reduce using rule 10 (@4)
|
||||
|
||||
@4 go to state 18
|
||||
|
||||
|
||||
state 14
|
||||
|
||||
3 section_or_include: VERSION STRING . EOL
|
||||
|
||||
EOL shift, and go to state 19
|
||||
|
||||
|
||||
state 15
|
||||
|
||||
5 section_or_include: CONFIG SETUP EOL . @1 kw_section
|
||||
|
||||
$default reduce using rule 4 (@1)
|
||||
|
||||
@1 go to state 20
|
||||
|
||||
|
||||
state 16
|
||||
|
||||
7 section_or_include: CONN STRING EOL . @2 kw_section
|
||||
|
||||
$default reduce using rule 6 (@2)
|
||||
|
||||
@2 go to state 21
|
||||
|
||||
|
||||
state 17
|
||||
|
||||
9 section_or_include: CA STRING EOL . @3 kw_section
|
||||
|
||||
$default reduce using rule 8 (@3)
|
||||
|
||||
@3 go to state 22
|
||||
|
||||
|
||||
state 18
|
||||
|
||||
11 section_or_include: INCLUDE STRING @4 . EOL
|
||||
|
||||
EOL shift, and go to state 23
|
||||
|
||||
|
||||
state 19
|
||||
|
||||
3 section_or_include: VERSION STRING EOL .
|
||||
|
||||
$default reduce using rule 3 (section_or_include)
|
||||
|
||||
|
||||
state 20
|
||||
|
||||
5 section_or_include: CONFIG SETUP EOL @1 . kw_section
|
||||
|
||||
FIRST_SPACES shift, and go to state 24
|
||||
|
||||
$default reduce using rule 14 (kw_section)
|
||||
|
||||
kw_section go to state 25
|
||||
|
||||
|
||||
state 21
|
||||
|
||||
7 section_or_include: CONN STRING EOL @2 . kw_section
|
||||
|
||||
FIRST_SPACES shift, and go to state 24
|
||||
|
||||
$default reduce using rule 14 (kw_section)
|
||||
|
||||
kw_section go to state 26
|
||||
|
||||
|
||||
state 22
|
||||
|
||||
9 section_or_include: CA STRING EOL @3 . kw_section
|
||||
|
||||
FIRST_SPACES shift, and go to state 24
|
||||
|
||||
$default reduce using rule 14 (kw_section)
|
||||
|
||||
kw_section go to state 27
|
||||
|
||||
|
||||
state 23
|
||||
|
||||
11 section_or_include: INCLUDE STRING @4 EOL .
|
||||
|
||||
$default reduce using rule 11 (section_or_include)
|
||||
|
||||
|
||||
state 24
|
||||
|
||||
13 kw_section: FIRST_SPACES . statement_kw EOL kw_section
|
||||
|
||||
STRING shift, and go to state 28
|
||||
|
||||
$default reduce using rule 17 (statement_kw)
|
||||
|
||||
statement_kw go to state 29
|
||||
|
||||
|
||||
state 25
|
||||
|
||||
5 section_or_include: CONFIG SETUP EOL @1 kw_section .
|
||||
|
||||
$default reduce using rule 5 (section_or_include)
|
||||
|
||||
|
||||
state 26
|
||||
|
||||
7 section_or_include: CONN STRING EOL @2 kw_section .
|
||||
|
||||
$default reduce using rule 7 (section_or_include)
|
||||
|
||||
|
||||
state 27
|
||||
|
||||
9 section_or_include: CA STRING EOL @3 kw_section .
|
||||
|
||||
$default reduce using rule 9 (section_or_include)
|
||||
|
||||
|
||||
state 28
|
||||
|
||||
15 statement_kw: STRING . EQUAL STRING
|
||||
16 | STRING . EQUAL
|
||||
|
||||
EQUAL shift, and go to state 30
|
||||
|
||||
|
||||
state 29
|
||||
|
||||
13 kw_section: FIRST_SPACES statement_kw . EOL kw_section
|
||||
|
||||
EOL shift, and go to state 31
|
||||
|
||||
|
||||
state 30
|
||||
|
||||
15 statement_kw: STRING EQUAL . STRING
|
||||
16 | STRING EQUAL .
|
||||
|
||||
STRING shift, and go to state 32
|
||||
|
||||
$default reduce using rule 16 (statement_kw)
|
||||
|
||||
|
||||
state 31
|
||||
|
||||
13 kw_section: FIRST_SPACES statement_kw EOL . kw_section
|
||||
|
||||
FIRST_SPACES shift, and go to state 24
|
||||
|
||||
$default reduce using rule 14 (kw_section)
|
||||
|
||||
kw_section go to state 33
|
||||
|
||||
|
||||
state 32
|
||||
|
||||
15 statement_kw: STRING EQUAL STRING .
|
||||
|
||||
$default reduce using rule 15 (statement_kw)
|
||||
|
||||
|
||||
state 33
|
||||
|
||||
13 kw_section: FIRST_SPACES statement_kw EOL kw_section .
|
||||
|
||||
$default reduce using rule 13 (kw_section)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
/* A Bison parser, made by GNU Bison 2.1. */
|
||||
|
||||
/* Skeleton parser for Yacc-like parsing with Bison,
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
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, or (at your option)
|
||||
any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, when this file is copied by Bison into a
|
||||
Bison output file, you may use that output file without restriction.
|
||||
This special exception was added by the Free Software Foundation
|
||||
in version 1.24 of Bison. */
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
EQUAL = 258,
|
||||
FIRST_SPACES = 259,
|
||||
EOL = 260,
|
||||
CONFIG = 261,
|
||||
SETUP = 262,
|
||||
CONN = 263,
|
||||
CA = 264,
|
||||
INCLUDE = 265,
|
||||
VERSION = 266,
|
||||
STRING = 267
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define EQUAL 258
|
||||
#define FIRST_SPACES 259
|
||||
#define EOL 260
|
||||
#define CONFIG 261
|
||||
#define SETUP 262
|
||||
#define CONN 263
|
||||
#define CA 264
|
||||
#define INCLUDE 265
|
||||
#define VERSION 266
|
||||
#define STRING 267
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
||||
#line 56 "parser.y"
|
||||
typedef union YYSTYPE { char *s; } YYSTYPE;
|
||||
/* Line 1447 of yacc.c. */
|
||||
#line 64 "parser.tab.h"
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
%{
|
||||
/* strongSwan config file parser (parser.y)
|
||||
* Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: parser.y,v 1.6 2006/01/17 23:43:36 as Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
#include "parser.h"
|
||||
|
||||
#define YYERROR_VERBOSE
|
||||
#define ERRSTRING_LEN 256
|
||||
|
||||
/**
|
||||
* Bison
|
||||
*/
|
||||
static char parser_errstring[ERRSTRING_LEN+1];
|
||||
|
||||
extern void yyerror(const char *s);
|
||||
extern int yylex (void);
|
||||
extern void _parser_y_error(char *b, int size, const char *s);
|
||||
|
||||
/**
|
||||
* Static Globals
|
||||
*/
|
||||
static int _save_errors_;
|
||||
static config_parsed_t *_parser_cfg;
|
||||
static kw_list_t **_parser_kw, *_parser_kw_last;
|
||||
static char errbuf[ERRSTRING_LEN+1];
|
||||
|
||||
/**
|
||||
* Gperf
|
||||
*/
|
||||
extern kw_entry_t *in_word_set (char *str, unsigned int len);
|
||||
|
||||
%}
|
||||
|
||||
%union { char *s; };
|
||||
%token EQUAL FIRST_SPACES EOL CONFIG SETUP CONN CA INCLUDE VERSION
|
||||
%token <s> STRING
|
||||
|
||||
%%
|
||||
|
||||
/*
|
||||
* Config file
|
||||
*/
|
||||
|
||||
config_file:
|
||||
config_file section_or_include
|
||||
| /* NULL */
|
||||
;
|
||||
|
||||
section_or_include:
|
||||
VERSION STRING EOL
|
||||
{
|
||||
free($2);
|
||||
}
|
||||
| CONFIG SETUP EOL
|
||||
{
|
||||
_parser_kw = &(_parser_cfg->config_setup);
|
||||
_parser_kw_last = NULL;
|
||||
} kw_section
|
||||
| CONN STRING EOL
|
||||
{
|
||||
section_list_t *section = (section_list_t *)alloc_thing(section_list_t
|
||||
, "section_list_t");
|
||||
|
||||
section->name = clone_str($2, "conn section name");
|
||||
section->kw = NULL;
|
||||
section->next = NULL;
|
||||
_parser_kw = &(section->kw);
|
||||
if (!_parser_cfg->conn_first)
|
||||
_parser_cfg->conn_first = section;
|
||||
if (_parser_cfg->conn_last)
|
||||
_parser_cfg->conn_last->next = section;
|
||||
_parser_cfg->conn_last = section;
|
||||
_parser_kw_last = NULL;
|
||||
free($2);
|
||||
} kw_section
|
||||
| CA STRING EOL
|
||||
{
|
||||
section_list_t *section = (section_list_t *)alloc_thing(section_list_t
|
||||
, "section_list_t");
|
||||
section->name = clone_str($2, "ca section name");
|
||||
section->kw = NULL;
|
||||
section->next = NULL;
|
||||
_parser_kw = &(section->kw);
|
||||
if (!_parser_cfg->ca_first)
|
||||
_parser_cfg->ca_first = section;
|
||||
if (_parser_cfg->ca_last)
|
||||
_parser_cfg->ca_last->next = section;
|
||||
_parser_cfg->ca_last = section;
|
||||
_parser_kw_last = NULL;
|
||||
free($2);
|
||||
} kw_section
|
||||
| INCLUDE STRING
|
||||
{
|
||||
extern void _parser_y_include (const char *f);
|
||||
_parser_y_include($2);
|
||||
free($2);
|
||||
} EOL
|
||||
| EOL
|
||||
;
|
||||
|
||||
kw_section:
|
||||
FIRST_SPACES statement_kw EOL kw_section
|
||||
|
|
||||
;
|
||||
|
||||
statement_kw:
|
||||
STRING EQUAL STRING
|
||||
{
|
||||
kw_list_t *new;
|
||||
kw_entry_t *entry = in_word_set($1, strlen($1));
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", $1);
|
||||
yyerror(errbuf);
|
||||
}
|
||||
else if (_parser_kw)
|
||||
{
|
||||
new = (kw_list_t *)alloc_thing(kw_list_t, "kw_list_t");
|
||||
new->entry = entry;
|
||||
new->value = clone_str($3, "kw_list value");
|
||||
new->next = NULL;
|
||||
if (_parser_kw_last)
|
||||
_parser_kw_last->next = new;
|
||||
_parser_kw_last = new;
|
||||
if (!*_parser_kw)
|
||||
*_parser_kw = new;
|
||||
}
|
||||
free($1);
|
||||
free($3);
|
||||
}
|
||||
| STRING EQUAL
|
||||
{
|
||||
free($1);
|
||||
}
|
||||
|
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
yyerror(const char *s)
|
||||
{
|
||||
if (_save_errors_)
|
||||
_parser_y_error(parser_errstring, ERRSTRING_LEN, s);
|
||||
}
|
||||
|
||||
config_parsed_t *
|
||||
parser_load_conf(const char *file)
|
||||
{
|
||||
config_parsed_t *cfg = NULL;
|
||||
int err = 0;
|
||||
FILE *f;
|
||||
|
||||
extern void _parser_y_init (const char *f);
|
||||
extern FILE *yyin;
|
||||
|
||||
memset(parser_errstring, 0, ERRSTRING_LEN+1);
|
||||
|
||||
cfg = (config_parsed_t *)alloc_thing(config_parsed_t, "config_parsed_t");
|
||||
if (cfg)
|
||||
{
|
||||
memset(cfg, 0, sizeof(config_parsed_t));
|
||||
f = fopen(file, "r");
|
||||
if (f)
|
||||
{
|
||||
yyin = f;
|
||||
_parser_y_init(file);
|
||||
_save_errors_ = 1;
|
||||
_parser_cfg = cfg;
|
||||
|
||||
if (yyparse() !=0 )
|
||||
{
|
||||
if (parser_errstring[0] == '\0')
|
||||
{
|
||||
snprintf(parser_errstring, ERRSTRING_LEN, "Unknown error...");
|
||||
}
|
||||
_save_errors_ = 0;
|
||||
while (yyparse() != 0);
|
||||
err++;
|
||||
}
|
||||
else if (parser_errstring[0] != '\0')
|
||||
{
|
||||
err++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Config valid
|
||||
*/
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", file);
|
||||
err++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
|
||||
err++;
|
||||
}
|
||||
|
||||
if (err)
|
||||
{
|
||||
plog("%s", parser_errstring);
|
||||
|
||||
if (cfg)
|
||||
parser_free_conf(cfg);
|
||||
cfg = NULL;
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
static void
|
||||
parser_free_kwlist(kw_list_t *list)
|
||||
{
|
||||
kw_list_t *elt;
|
||||
|
||||
while (list)
|
||||
{
|
||||
elt = list;
|
||||
list = list->next;
|
||||
if (elt->value)
|
||||
pfree(elt->value);
|
||||
pfree(elt);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parser_free_conf(config_parsed_t *cfg)
|
||||
{
|
||||
section_list_t *sec;
|
||||
if (cfg)
|
||||
{
|
||||
parser_free_kwlist(cfg->config_setup);
|
||||
while (cfg->conn_first)
|
||||
{
|
||||
sec = cfg->conn_first;
|
||||
cfg->conn_first = cfg->conn_first->next;
|
||||
if (sec->name)
|
||||
pfree(sec->name);
|
||||
parser_free_kwlist(sec->kw);
|
||||
pfree(sec);
|
||||
}
|
||||
while (cfg->ca_first)
|
||||
{
|
||||
sec = cfg->ca_first;
|
||||
cfg->ca_first = cfg->ca_first->next;
|
||||
if (sec->name)
|
||||
pfree(sec->name);
|
||||
parser_free_kwlist(sec->kw);
|
||||
pfree(sec);
|
||||
}
|
||||
pfree(cfg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,610 @@
|
||||
/* strongSwan IPsec starter
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: starter.c,v 1.23 2006/02/15 18:37:46 as Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
|
||||
#include "confread.h"
|
||||
#include "files.h"
|
||||
#include "starterwhack.h"
|
||||
#include "invokepluto.h"
|
||||
#include "invokecharon.h"
|
||||
#include "netkey.h"
|
||||
#include "cmp.h"
|
||||
#include "interfaces.h"
|
||||
|
||||
#define FLAG_ACTION_START_PLUTO 0x01
|
||||
#define FLAG_ACTION_UPDATE 0x02
|
||||
#define FLAG_ACTION_RELOAD 0x04
|
||||
#define FLAG_ACTION_QUIT 0x08
|
||||
#define FLAG_ACTION_LISTEN 0x10
|
||||
#ifdef IKEV2
|
||||
#define FLAG_ACTION_START_CHARON 0x20
|
||||
#endif /* IKEV2 */
|
||||
|
||||
static unsigned int _action_ = 0;
|
||||
|
||||
static void
|
||||
fsig(int signal)
|
||||
{
|
||||
switch (signal)
|
||||
{
|
||||
case SIGCHLD:
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
char *name = NULL;
|
||||
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
||||
{
|
||||
if (pid == starter_pluto_pid())
|
||||
name = " (Pluto)";
|
||||
#ifdef IKEV2
|
||||
if (pid == starter_charon_pid())
|
||||
name = " (Charon)";
|
||||
#endif /* IKEV2 */
|
||||
if (WIFSIGNALED(status))
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("child %d%s has been killed by sig %d\n",
|
||||
pid, name?name:"", WTERMSIG(status))
|
||||
)
|
||||
else if (WIFSTOPPED(status))
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("child %d%s has been stopped by sig %d\n",
|
||||
pid, name?name:"", WSTOPSIG(status))
|
||||
)
|
||||
else if (WIFEXITED(status))
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("child %d%s has quit (exit code %d)\n",
|
||||
pid, name?name:"", WEXITSTATUS(status))
|
||||
)
|
||||
else
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("child %d%s has quit", pid, name?name:"")
|
||||
)
|
||||
|
||||
if (pid == starter_pluto_pid())
|
||||
starter_pluto_sigchild(pid);
|
||||
#ifdef IKEV2
|
||||
if (pid == starter_charon_pid())
|
||||
starter_charon_sigchild(pid);
|
||||
#endif /* IKEV2 */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SIGPIPE:
|
||||
/** ignore **/
|
||||
break;
|
||||
|
||||
case SIGALRM:
|
||||
_action_ |= FLAG_ACTION_START_PLUTO;
|
||||
#ifdef IKEV2
|
||||
_action_ |= FLAG_ACTION_START_CHARON;
|
||||
#endif /* IKEV2 */
|
||||
break;
|
||||
|
||||
case SIGHUP:
|
||||
_action_ |= FLAG_ACTION_UPDATE;
|
||||
break;
|
||||
|
||||
case SIGTERM:
|
||||
case SIGQUIT:
|
||||
case SIGINT:
|
||||
_action_ |= FLAG_ACTION_QUIT;
|
||||
break;
|
||||
|
||||
case SIGUSR1:
|
||||
_action_ |= FLAG_ACTION_RELOAD;
|
||||
_action_ |= FLAG_ACTION_UPDATE;
|
||||
break;
|
||||
|
||||
default:
|
||||
plog("fsig(): unknown signal %d -- investigate", signal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
usage(char *name)
|
||||
{
|
||||
fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>] "
|
||||
"[--debug|--debug-more|--debug-all]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
starter_config_t *cfg = NULL;
|
||||
starter_config_t *new_cfg;
|
||||
starter_conn_t *conn, *conn2;
|
||||
starter_ca_t *ca, *ca2;
|
||||
|
||||
struct stat stb;
|
||||
|
||||
char *err = NULL;
|
||||
int i;
|
||||
int id = 1;
|
||||
struct timeval tv;
|
||||
unsigned long auto_update = 0;
|
||||
time_t last_reload;
|
||||
bool no_fork = FALSE;
|
||||
|
||||
/* global variables defined in log.h */
|
||||
log_to_stderr = TRUE;
|
||||
base_debugging = DBG_NONE;
|
||||
|
||||
/* parse command line */
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (streq(argv[i], "--debug"))
|
||||
{
|
||||
base_debugging |= DBG_CONTROL;
|
||||
}
|
||||
else if (streq(argv[i], "--debug-more"))
|
||||
{
|
||||
base_debugging |= DBG_CONTROLMORE;
|
||||
}
|
||||
else if (streq(argv[i], "--debug-all"))
|
||||
{
|
||||
base_debugging |= DBG_ALL;
|
||||
}
|
||||
else if (streq(argv[i], "--nofork"))
|
||||
{
|
||||
no_fork = TRUE;
|
||||
}
|
||||
else if (streq(argv[i], "--auto-update") && i+1 < argc)
|
||||
{
|
||||
auto_update = atoi(argv[++i]);
|
||||
if (!auto_update)
|
||||
usage(argv[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Init */
|
||||
init_log("ipsec_starter");
|
||||
cur_debugging = base_debugging;
|
||||
|
||||
signal(SIGHUP, fsig);
|
||||
signal(SIGCHLD, fsig);
|
||||
signal(SIGPIPE, fsig);
|
||||
signal(SIGINT, fsig);
|
||||
signal(SIGTERM, fsig);
|
||||
signal(SIGQUIT, fsig);
|
||||
signal(SIGALRM, fsig);
|
||||
signal(SIGUSR1, fsig);
|
||||
|
||||
|
||||
plog("Starting strongSwan IPsec %s [starter]...", ipsec_version_code());
|
||||
|
||||
/* verify that we can start */
|
||||
if (getuid() != 0)
|
||||
{
|
||||
plog("permission denied (must be superuser)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (stat(PLUTO_PID_FILE, &stb) == 0)
|
||||
{
|
||||
plog("pluto is already running (%s exists) -- skipping pluto start", PLUTO_PID_FILE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_action_ |= FLAG_ACTION_START_PLUTO;
|
||||
}
|
||||
#ifdef IKEV2
|
||||
if (stat(CHARON_PID_FILE, &stb) == 0)
|
||||
{
|
||||
plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_action_ |= FLAG_ACTION_START_CHARON;
|
||||
}
|
||||
#endif /* IKEV2 */
|
||||
if (stat(DEV_RANDOM, &stb) != 0)
|
||||
{
|
||||
plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (stat(DEV_URANDOM, &stb)!= 0)
|
||||
{
|
||||
plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cfg = confread_load(CONFIG_FILE);
|
||||
if (!cfg)
|
||||
{
|
||||
plog("unable to start strongSwan -- errors in config");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* determine if we have a native netkey IPsec stack */
|
||||
if (!starter_netkey_init())
|
||||
{
|
||||
plog("nor netkey IPSec stack detected");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
last_reload = time(NULL);
|
||||
|
||||
if (stat(MY_PID_FILE, &stb) == 0)
|
||||
{
|
||||
plog("starter is already running (%s exists) -- no fork done", MY_PID_FILE);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* fork if we're not debugging stuff */
|
||||
if (!no_fork)
|
||||
{
|
||||
log_to_stderr = FALSE;
|
||||
|
||||
switch (fork())
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
int fnull = open("/dev/null", O_RDWR);
|
||||
|
||||
if (fnull >= 0)
|
||||
{
|
||||
dup2(fnull, STDIN_FILENO);
|
||||
dup2(fnull, STDOUT_FILENO);
|
||||
dup2(fnull, STDERR_FILENO);
|
||||
close(fnull);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case -1:
|
||||
plog("can't fork: %s", strerror(errno));
|
||||
break;
|
||||
default:
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* save pid file in /var/run/starter.pid */
|
||||
{
|
||||
FILE *fd = fopen(MY_PID_FILE, "w");
|
||||
|
||||
if (fd)
|
||||
{
|
||||
fprintf(fd, "%u\n", getpid());
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
* Stop pluto/charon (if started) and exit
|
||||
*/
|
||||
if (_action_ & FLAG_ACTION_QUIT)
|
||||
{
|
||||
if (starter_pluto_pid())
|
||||
starter_stop_pluto();
|
||||
#ifdef IKEV2
|
||||
if (starter_charon_pid())
|
||||
starter_stop_charon();
|
||||
#endif IKEV2
|
||||
starter_netkey_cleanup();
|
||||
confread_free(cfg);
|
||||
unlink(MY_PID_FILE);
|
||||
unlink(INFO_FILE);
|
||||
#ifdef LEAK_DETECTIVE
|
||||
report_leaks();
|
||||
#endif /* LEAK_DETECTIVE */
|
||||
close_log();
|
||||
plog("ipsec starter stopped");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete all connections. Will be added below
|
||||
*/
|
||||
if (_action_ & FLAG_ACTION_RELOAD)
|
||||
{
|
||||
if (starter_pluto_pid())
|
||||
{
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
{
|
||||
if (conn->state == STATE_ADDED)
|
||||
{
|
||||
starter_whack_del_conn(conn);
|
||||
#ifdef IKEV2
|
||||
starter_stroke_del_conn(conn);
|
||||
#endif /* IKEV2 */
|
||||
conn->state = STATE_TO_ADD;
|
||||
}
|
||||
}
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
if (ca->state == STATE_ADDED)
|
||||
{
|
||||
starter_whack_del_ca(ca);
|
||||
ca->state = STATE_TO_ADD;
|
||||
}
|
||||
}
|
||||
}
|
||||
_action_ &= ~FLAG_ACTION_RELOAD;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update configuration
|
||||
*/
|
||||
if (_action_ & FLAG_ACTION_UPDATE)
|
||||
{
|
||||
err = NULL;
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Reloading config...")
|
||||
)
|
||||
new_cfg = confread_load(CONFIG_FILE);
|
||||
|
||||
if (new_cfg)
|
||||
{
|
||||
/* Switch to new config. New conn will be loaded below */
|
||||
if (!starter_cmp_defaultroute(&new_cfg->defaultroute
|
||||
, &cfg->defaultroute))
|
||||
{
|
||||
_action_ |= FLAG_ACTION_LISTEN;
|
||||
}
|
||||
|
||||
if (!starter_cmp_pluto(cfg, new_cfg))
|
||||
{
|
||||
plog("Pluto has changed");
|
||||
if (starter_pluto_pid())
|
||||
starter_stop_pluto();
|
||||
_action_ &= ~FLAG_ACTION_LISTEN;
|
||||
_action_ |= FLAG_ACTION_START_PLUTO;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Only reload conn and ca sections if pluto is not killed */
|
||||
|
||||
/* Look for new connections that are already loaded */
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
{
|
||||
if (conn->state == STATE_ADDED)
|
||||
{
|
||||
for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
|
||||
{
|
||||
if (conn2->state == STATE_TO_ADD
|
||||
&& starter_cmp_conn(conn, conn2))
|
||||
{
|
||||
conn->state = STATE_REPLACED;
|
||||
conn2->state = STATE_ADDED;
|
||||
conn2->id = conn->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove conn sections that have become unused */
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
{
|
||||
if (conn->state == STATE_ADDED)
|
||||
starter_whack_del_conn(conn);
|
||||
#ifdef IKEV2
|
||||
starter_stroke_del_conn(conn);
|
||||
#endif /* IKEV2 */
|
||||
}
|
||||
|
||||
/* Look for new ca sections that are already loaded */
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
if (ca->state == STATE_ADDED)
|
||||
{
|
||||
for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
|
||||
{
|
||||
if (ca2->state == STATE_TO_ADD
|
||||
&& starter_cmp_ca(ca, ca2))
|
||||
{
|
||||
ca->state = STATE_REPLACED;
|
||||
ca2->state = STATE_ADDED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove ca sections that have become unused */
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
if (ca->state == STATE_ADDED)
|
||||
starter_whack_del_ca(ca);
|
||||
}
|
||||
}
|
||||
confread_free(cfg);
|
||||
cfg = new_cfg;
|
||||
}
|
||||
else
|
||||
{
|
||||
plog("can't reload config file: %s -- keeping old one");
|
||||
}
|
||||
_action_ &= ~FLAG_ACTION_UPDATE;
|
||||
last_reload = time(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start pluto
|
||||
*/
|
||||
if (_action_ & FLAG_ACTION_START_PLUTO)
|
||||
{
|
||||
if (starter_pluto_pid() == 0)
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Attempting to start pluto...")
|
||||
)
|
||||
|
||||
if (starter_start_pluto(cfg, no_fork) == 0)
|
||||
{
|
||||
starter_whack_listen();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* schedule next try */
|
||||
alarm(PLUTO_RESTART_DELAY);
|
||||
}
|
||||
}
|
||||
_action_ &= ~FLAG_ACTION_START_PLUTO;
|
||||
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
if (ca->state == STATE_ADDED)
|
||||
ca->state = STATE_TO_ADD;
|
||||
}
|
||||
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
{
|
||||
if (conn->state == STATE_ADDED)
|
||||
conn->state = STATE_TO_ADD;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IKEV2
|
||||
/*
|
||||
* Start charon
|
||||
*/
|
||||
if (_action_ & FLAG_ACTION_START_CHARON)
|
||||
{
|
||||
if (starter_charon_pid() == 0)
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Attempting to start charon...")
|
||||
)
|
||||
if (starter_start_charon(cfg, no_fork) != 0)
|
||||
{
|
||||
/* schedule next try */
|
||||
alarm(PLUTO_RESTART_DELAY);
|
||||
}
|
||||
}
|
||||
_action_ &= ~FLAG_ACTION_START_CHARON;
|
||||
}
|
||||
#endif /* IKEV2 */
|
||||
|
||||
/*
|
||||
* Tell pluto to reread its interfaces
|
||||
*/
|
||||
if (_action_ & FLAG_ACTION_LISTEN)
|
||||
{
|
||||
starter_whack_listen();
|
||||
_action_ &= ~FLAG_ACTION_LISTEN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add stale conn and ca sections
|
||||
*/
|
||||
if (starter_pluto_pid() != 0)
|
||||
{
|
||||
for (ca = cfg->ca_first; ca; ca = ca->next)
|
||||
{
|
||||
if (ca->state == STATE_TO_ADD)
|
||||
{
|
||||
starter_whack_add_ca(ca);
|
||||
ca->state = STATE_ADDED;
|
||||
}
|
||||
}
|
||||
|
||||
for (conn = cfg->conn_first; conn; conn = conn->next)
|
||||
{
|
||||
if (conn->state == STATE_TO_ADD)
|
||||
{
|
||||
if (conn->id == 0)
|
||||
{
|
||||
/* affect new unique id */
|
||||
conn->id = id++;
|
||||
}
|
||||
starter_whack_add_conn(conn);
|
||||
#ifdef IKEV2
|
||||
starter_stroke_add_conn(conn);
|
||||
#endif /* IKEV2 */
|
||||
conn->state = STATE_ADDED;
|
||||
if (conn->startup == STARTUP_START)
|
||||
{
|
||||
#ifdef IKEV2
|
||||
if (conn->keyexchange == 2)
|
||||
{
|
||||
starter_stroke_initiate_conn(conn);
|
||||
}
|
||||
else
|
||||
#endif /* IKEV2 */
|
||||
{
|
||||
starter_whack_initiate_conn(conn);
|
||||
}
|
||||
}
|
||||
else if (conn->startup == STARTUP_ROUTE)
|
||||
{
|
||||
#ifdef IKEV2
|
||||
if (conn->keyexchange == 2)
|
||||
{
|
||||
starter_stroke_route_conn(conn);
|
||||
}
|
||||
else
|
||||
#endif /* IKEV2 */
|
||||
{
|
||||
starter_whack_route_conn(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If auto_update activated, when to stop select
|
||||
*/
|
||||
if (auto_update)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
tv.tv_sec = (now < last_reload + auto_update)
|
||||
? (last_reload + auto_update-now) : 0;
|
||||
tv.tv_usec = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for something to happen
|
||||
*/
|
||||
if (select(0, NULL, NULL, NULL, auto_update ? &tv : NULL) == 0)
|
||||
{
|
||||
/* timeout -> auto_update */
|
||||
_action_ |= FLAG_ACTION_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/* Stroke for charon is the counterpart to whack from pluto
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id: starterstroke.c $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
|
||||
#include "../charon/stroke/stroke.h"
|
||||
|
||||
#include "starterstroke.h"
|
||||
#include "confread.h"
|
||||
#include "files.h"
|
||||
|
||||
static char* push_string(stroke_msg_t **strm, char *string)
|
||||
{
|
||||
stroke_msg_t *stroke_msg;
|
||||
size_t string_length;
|
||||
|
||||
if (string == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
stroke_msg = *strm;
|
||||
string_length = strlen(string) + 1;
|
||||
stroke_msg->length += string_length;
|
||||
|
||||
stroke_msg = realloc(stroke_msg, stroke_msg->length);
|
||||
strcpy((char*)stroke_msg + stroke_msg->length - string_length, string);
|
||||
|
||||
*strm = stroke_msg;
|
||||
return (char*)(u_int)stroke_msg->length - string_length;
|
||||
}
|
||||
|
||||
static int
|
||||
send_stroke_msg (stroke_msg_t *msg)
|
||||
{
|
||||
struct sockaddr_un ctl_addr = { AF_UNIX, CHARON_CTL_FILE };
|
||||
int sock;
|
||||
|
||||
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
plog("socket() failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (connect(sock, (struct sockaddr *)&ctl_addr,
|
||||
offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
|
||||
{
|
||||
plog("connect(charon_ctl) failed: %s", strerror(errno));
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* send message */
|
||||
if (write(sock, msg, msg->length) != msg->length)
|
||||
{
|
||||
plog("write(charon_ctl) failed: %s", strerror(errno));
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
connection_name(starter_conn_t *conn)
|
||||
{
|
||||
/* if connection name is '%auto', create a new name like conn_xxxxx */
|
||||
static char buf[32];
|
||||
|
||||
if (streq(conn->name, "%auto"))
|
||||
{
|
||||
sprintf(buf, "conn_%ld", conn->id);
|
||||
return buf;
|
||||
}
|
||||
return conn->name;
|
||||
}
|
||||
|
||||
|
||||
int starter_stroke_add_conn(starter_conn_t *conn)
|
||||
{
|
||||
stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
|
||||
int res;
|
||||
|
||||
msg->length = sizeof(stroke_msg_t);
|
||||
msg->type = STR_ADD_CONN;
|
||||
|
||||
msg->add_conn.name = push_string(&msg, connection_name(conn));
|
||||
|
||||
msg->add_conn.me.id = push_string(&msg, conn->left.id);
|
||||
msg->add_conn.me.cert = push_string(&msg, conn->left.cert);
|
||||
msg->add_conn.me.address = push_string(&msg, inet_ntoa(conn->left.addr.u.v4.sin_addr));
|
||||
msg->add_conn.me.subnet = push_string(&msg, inet_ntoa(conn->left.subnet.addr.u.v4.sin_addr));
|
||||
msg->add_conn.me.subnet_mask = conn->left.subnet.maskbits;
|
||||
|
||||
msg->add_conn.other.id = push_string(&msg, conn->right.id);
|
||||
msg->add_conn.other.cert = push_string(&msg, conn->right.cert);
|
||||
msg->add_conn.other.address = push_string(&msg, inet_ntoa(conn->right.addr.u.v4.sin_addr));
|
||||
msg->add_conn.other.subnet = push_string(&msg, inet_ntoa(conn->right.subnet.addr.u.v4.sin_addr));
|
||||
msg->add_conn.other.subnet_mask = conn->right.subnet.maskbits;
|
||||
|
||||
res = send_stroke_msg(msg);
|
||||
free(msg);
|
||||
return res;
|
||||
}
|
||||
|
||||
int starter_stroke_del_conn(starter_conn_t *conn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int starter_stroke_route_conn(starter_conn_t *conn)
|
||||
{
|
||||
stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
|
||||
int res;
|
||||
|
||||
msg->length = sizeof(stroke_msg_t);
|
||||
msg->type = STR_INSTALL;
|
||||
msg->install.name = push_string(&msg, connection_name(conn));
|
||||
res = send_stroke_msg(msg);
|
||||
free(msg);
|
||||
return res;
|
||||
}
|
||||
|
||||
int starter_stroke_initiate_conn(starter_conn_t *conn)
|
||||
{
|
||||
stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
|
||||
int res;
|
||||
|
||||
msg->length = sizeof(stroke_msg_t);
|
||||
msg->type = STR_INITIATE;
|
||||
msg->initiate.name = push_string(&msg, connection_name(conn));
|
||||
res = send_stroke_msg(msg);
|
||||
free(msg);
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/* Stroke for charon is the counterpart to whack from pluto
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id: starterstroke.h $
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_STROKE_H_
|
||||
#define _STARTER_STROKE_H_
|
||||
|
||||
#include "confread.h"
|
||||
|
||||
extern int starter_stroke_add_conn(starter_conn_t *conn);
|
||||
extern int starter_stroke_del_conn(starter_conn_t *conn);
|
||||
extern int starter_stroke_route_conn(starter_conn_t *conn);
|
||||
extern int starter_stroke_initiate_conn(starter_conn_t *conn);
|
||||
|
||||
#endif /* _STARTER_STROKE_H_ */
|
||||
@@ -0,0 +1,371 @@
|
||||
/* strongSwan whack functions to communicate with pluto (whack.c)
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: starterwhack.c,v 1.17 2006/04/17 10:32:36 as Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
#include "../pluto/whack.h"
|
||||
|
||||
#include "starterwhack.h"
|
||||
#include "confread.h"
|
||||
#include "files.h"
|
||||
|
||||
static int
|
||||
pack_str (char **p, char **next, char **roof)
|
||||
{
|
||||
const char *s = (*p==NULL) ? "" : *p; /* note: NULL becomes ""! */
|
||||
size_t len = strlen(s) + 1;
|
||||
|
||||
if ((*roof - *next) < len)
|
||||
{
|
||||
return 0; /* not enough space */
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(*next, s);
|
||||
*next += len;
|
||||
*p = NULL; /* don't send pointers on the wire! */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
send_whack_msg (whack_message_t *msg)
|
||||
{
|
||||
struct sockaddr_un ctl_addr = { AF_UNIX, PLUTO_CTL_FILE };
|
||||
int sock;
|
||||
ssize_t len;
|
||||
char *str_next, *str_roof;
|
||||
|
||||
/* pack strings */
|
||||
str_next = (char *)msg->string;
|
||||
str_roof = (char *)&msg->string[sizeof(msg->string)];
|
||||
|
||||
if (!pack_str(&msg->name, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.id, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.cert, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.ca, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.groups, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->left.updown, &str_next, &str_roof)
|
||||
#ifdef VIRTUAL_IP
|
||||
|| !pack_str(&msg->left.virt, &str_next, &str_roof)
|
||||
#endif
|
||||
|| !pack_str(&msg->right.id, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.cert, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.ca, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.groups, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->right.updown, &str_next, &str_roof)
|
||||
#ifdef VIRTUAL_IP
|
||||
|| !pack_str(&msg->right.virt, &str_next, &str_roof)
|
||||
#endif
|
||||
|| !pack_str(&msg->keyid, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->myid, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->cacert, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->ldaphost, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->ldapbase, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->crluri, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->crluri2, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->ocspuri, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->ike, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->esp, &str_next, &str_roof)
|
||||
|| !pack_str(&msg->sc_data, &str_next, &str_roof)
|
||||
|| (str_roof - str_next < msg->keyval.len))
|
||||
{
|
||||
plog("send_wack_msg(): can't pack strings");
|
||||
return -1;
|
||||
}
|
||||
if (msg->keyval.ptr)
|
||||
memcpy(str_next, msg->keyval.ptr, msg->keyval.len);
|
||||
msg->keyval.ptr = NULL;
|
||||
str_next += msg->keyval.len;
|
||||
len = str_next - (char *)msg;
|
||||
|
||||
/* connect to pluto ctl */
|
||||
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
plog("socket() failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (connect(sock, (struct sockaddr *)&ctl_addr,
|
||||
offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
|
||||
{
|
||||
plog("connect(pluto_ctl) failed: %s", strerror(errno));
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* send message */
|
||||
if (write(sock, msg, len) != len)
|
||||
{
|
||||
plog("write(pluto_ctl) failed: %s", strerror(errno));
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: read reply */
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
init_whack_msg(whack_message_t *msg)
|
||||
{
|
||||
memset(msg, 0, sizeof(whack_message_t));
|
||||
msg->magic = WHACK_MAGIC;
|
||||
}
|
||||
|
||||
static char *
|
||||
connection_name(starter_conn_t *conn)
|
||||
{
|
||||
/* if connection name is '%auto', create a new name like conn_xxxxx */
|
||||
static char buf[32];
|
||||
|
||||
if (streq(conn->name, "%auto"))
|
||||
{
|
||||
sprintf(buf, "conn_%ld", conn->id);
|
||||
return buf;
|
||||
}
|
||||
return conn->name;
|
||||
}
|
||||
|
||||
static void
|
||||
set_whack_end(whack_end_t *w, starter_end_t *end)
|
||||
{
|
||||
w->id = end->id;
|
||||
w->cert = end->cert;
|
||||
w->ca = end->ca;
|
||||
w->groups = end->groups;
|
||||
w->host_addr = end->addr;
|
||||
w->host_nexthop = end->nexthop;
|
||||
w->host_srcip = end->srcip;
|
||||
|
||||
if (end->has_client)
|
||||
w->client = end->subnet;
|
||||
else
|
||||
w->client.addr.u.v4.sin_family = AF_INET;
|
||||
|
||||
w->has_client = end->has_client;
|
||||
w->has_client_wildcard = end->has_client_wildcard;
|
||||
w->has_port_wildcard = end->has_port_wildcard;
|
||||
w->has_srcip = end->has_srcip;
|
||||
w->modecfg = end->modecfg;
|
||||
w->hostaccess = end->hostaccess;
|
||||
w->sendcert = end->sendcert;
|
||||
w->updown = end->updown;
|
||||
w->host_port = IKE_UDP_PORT;
|
||||
w->port = end->port;
|
||||
w->protocol = end->protocol;
|
||||
w->virt = end->virt;
|
||||
|
||||
if (w->port != 0)
|
||||
{
|
||||
int port = htons(w->port);
|
||||
|
||||
setportof(port, &w->host_addr);
|
||||
setportof(port, &w->client.addr);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
starter_whack_add_pubkey (starter_conn_t *conn, starter_end_t *end
|
||||
, const char *lr)
|
||||
{
|
||||
const char *err;
|
||||
static char keyspace[1024 + 4];
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
|
||||
msg.whack_key = TRUE;
|
||||
msg.pubkey_alg = PUBKEY_ALG_RSA;
|
||||
if (end->id && end->rsakey)
|
||||
{
|
||||
/* special values to ignore */
|
||||
if (streq(end->rsakey, "")
|
||||
|| streq(end->rsakey, "%none")
|
||||
|| streq(end->rsakey, "%cert")
|
||||
|| streq(end->rsakey, "0x00"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
msg.keyid = end->id;
|
||||
err = atobytes(end->rsakey, 0, keyspace, sizeof(keyspace), &msg.keyval.len);
|
||||
if (err)
|
||||
{
|
||||
plog("conn %s/%s: rsakey malformed [%s]", connection_name(conn), lr, err);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.keyval.ptr = keyspace;
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
starter_whack_add_conn(starter_conn_t *conn)
|
||||
{
|
||||
whack_message_t msg;
|
||||
int r;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
|
||||
msg.whack_connection = TRUE;
|
||||
msg.name = connection_name(conn);
|
||||
|
||||
msg.addr_family = conn->addr_family;
|
||||
msg.tunnel_addr_family = conn->tunnel_addr_family;
|
||||
msg.sa_ike_life_seconds = conn->sa_ike_life_seconds;
|
||||
msg.sa_ipsec_life_seconds = conn->sa_ipsec_life_seconds;
|
||||
msg.sa_rekey_margin = conn->sa_rekey_margin;
|
||||
msg.sa_rekey_fuzz = conn->sa_rekey_fuzz;
|
||||
msg.sa_keying_tries = conn->sa_keying_tries;
|
||||
msg.policy = conn->policy;
|
||||
|
||||
set_whack_end(&msg.left, &conn->left);
|
||||
set_whack_end(&msg.right, &conn->right);
|
||||
|
||||
msg.esp = conn->esp;
|
||||
msg.ike = conn->ike;
|
||||
msg.pfsgroup = conn->pfsgroup;
|
||||
|
||||
/* taken from pluto/whack.c */
|
||||
if (msg.pfsgroup)
|
||||
{
|
||||
char esp_buf[256];
|
||||
|
||||
snprintf(esp_buf, sizeof (esp_buf), "%s;%s"
|
||||
, msg.esp ? msg.esp : ""
|
||||
, msg.pfsgroup ? msg.pfsgroup : "");
|
||||
msg.esp = esp_buf;
|
||||
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("Setting --esp=%s", msg.esp)
|
||||
)
|
||||
}
|
||||
msg.dpd_delay = conn->dpd_delay;
|
||||
msg.dpd_timeout = conn->dpd_timeout;
|
||||
msg.dpd_action = conn->dpd_action;
|
||||
/* msg.dpd_count = conn->dpd_count; not supported yet by strongSwan */
|
||||
|
||||
r = send_whack_msg(&msg);
|
||||
|
||||
if (r == 0 && (conn->policy & POLICY_RSASIG))
|
||||
{
|
||||
r += starter_whack_add_pubkey (conn, &conn->left, "left");
|
||||
r += starter_whack_add_pubkey (conn, &conn->right, "right");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
starter_whack_del_conn(starter_conn_t *conn)
|
||||
{
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
msg.whack_delete = TRUE;
|
||||
msg.name = connection_name(conn);
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int
|
||||
starter_whack_route_conn(starter_conn_t *conn)
|
||||
{
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
msg.whack_route = TRUE;
|
||||
msg.name = connection_name(conn);
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int
|
||||
starter_whack_initiate_conn(starter_conn_t *conn)
|
||||
{
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
msg.whack_initiate = TRUE;
|
||||
msg.whack_async = TRUE;
|
||||
msg.name = connection_name(conn);
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int
|
||||
starter_whack_listen(void)
|
||||
{
|
||||
whack_message_t msg;
|
||||
init_whack_msg(&msg);
|
||||
msg.whack_listen = TRUE;
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int starter_whack_shutdown(void)
|
||||
{
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
msg.whack_shutdown = TRUE;
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int
|
||||
starter_whack_add_ca(starter_ca_t *ca)
|
||||
{
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
|
||||
msg.whack_ca = TRUE;
|
||||
msg.name = ca->name;
|
||||
msg.cacert = ca->cacert;
|
||||
msg.ldaphost = ca->ldaphost;
|
||||
msg.ldapbase = ca->ldapbase;
|
||||
msg.crluri = ca->crluri;
|
||||
msg.crluri2 = ca->crluri2;
|
||||
msg.ocspuri = ca->ocspuri;
|
||||
msg.whack_strict = ca->strict;
|
||||
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
|
||||
int
|
||||
starter_whack_del_ca(starter_ca_t *ca)
|
||||
{
|
||||
whack_message_t msg;
|
||||
|
||||
init_whack_msg(&msg);
|
||||
|
||||
msg.whack_delete = TRUE;
|
||||
msg.whack_ca = TRUE;
|
||||
msg.name = ca->name;
|
||||
|
||||
return send_whack_msg(&msg);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* FreeS/WAN whack functions to communicate with pluto (whack.h)
|
||||
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* 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: starterwhack.h,v 1.6 2006/01/03 18:37:03 as Exp $
|
||||
*/
|
||||
|
||||
#ifndef _STARTER_WHACK_H_
|
||||
#define _STARTER_WHACK_H_
|
||||
|
||||
#include "confread.h"
|
||||
|
||||
extern int starter_whack_add_conn(starter_conn_t *conn);
|
||||
extern int starter_whack_del_conn(starter_conn_t *conn);
|
||||
extern int starter_whack_route_conn(starter_conn_t *conn);
|
||||
extern int starter_whack_initiate_conn(starter_conn_t *conn);
|
||||
extern int starter_whack_listen(void);
|
||||
extern int starter_whack_shutdown(void);
|
||||
extern int starter_whack_add_ca(starter_ca_t *ca);
|
||||
extern int starter_whack_del_ca(starter_ca_t *ca);
|
||||
|
||||
#endif /* _STARTER_WHACK_H_ */
|
||||
|
||||
Reference in New Issue
Block a user