This commit is contained in:
Martin Willi
2006-04-28 10:51:19 +00:00
parent 51c3484a9f
commit 1029d84d23
514 changed files with 2 additions and 2 deletions
+200
View File
@@ -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
+104
View File
@@ -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
+624
View File
@@ -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;
}
+34
View File
@@ -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_ */
+105
View File
@@ -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;
}
+29
View File
@@ -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
+861
View File
@@ -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);
}
+199
View File
@@ -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_ */
+54
View File
@@ -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;
}
+23
View File
@@ -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_ */
+54
View File
@@ -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_ */
+595
View File
@@ -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;
}
+41
View File
@@ -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_ */
+174
View File
@@ -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;
}
+31
View File
@@ -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_ */
+286
View File
@@ -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;
}
+28
View File
@@ -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_ */
+235
View File
@@ -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;
}
+164
View File
@@ -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_ */
+105
View File
@@ -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
+1966
View File
File diff suppressed because it is too large Load Diff
+85
View File
@@ -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");
}
}
+24
View File
@@ -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_ */
+57
View File
@@ -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_ */
+190
View File
@@ -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;
}
+351
View File
@@ -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
+72
View File
@@ -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;
+283
View File
@@ -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);
}
}
View File
+610
View File
@@ -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;
}
+161
View File
@@ -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;
}
+27
View File
@@ -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_ */
+371
View File
@@ -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);
}
+32
View File
@@ -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_ */