- applied patch from andreas

- pem loading
	- secrets file parsing
	- ikev2 testcase
	- some other additions here and there
This commit is contained in:
Martin Willi 2006-05-04 07:55:42 +00:00
parent 8744148f55
commit 9820c0e208
41 changed files with 1236 additions and 844 deletions

15
CHANGES
View File

@ -1,3 +1,18 @@
strongswan-4.0.0
----------------
- initial support of the IKEv2 protocol. Connections in
ipsec.conf designated by keyexchange=ikev2 are negotiated
by the new IKEv2 charon keying daemon whereas those marked
by keyexchange=ikev1 or the default keyexchange=ike are
handled thy the IKEv1 pluto keying daemon. Currently only
a limited subset of functions are available with IKEv2
(Default AES encryption, authentication based on locally
imported X.509 certificates, unencrypted private RSA keys
in PKCS#1 file format, limited functionality of the ipsec
status command).
strongswan-2.7.0
----------------

106
INSTALL
View File

@ -1,5 +1,5 @@
---------------------------
strongSwan - Installation
strongSwan - Installation
---------------------------
@ -11,9 +11,7 @@ Contents
2.1 libcurl
2.2 OpenLDAP
2.3 PKCS#11 smartcard library modules
3. Building strongSwan with a Linux 2.4 kernel
4. Updating strongSwan with a Linux 2.4 kernel
5. Building strongSwan with a Linux 2.6 kernel
3. Building and running strongSwan with a Linux 2.6 kernel
1. Required packages
@ -125,9 +123,9 @@ Contents
in "Makefile.inc"
# Uncomment this line if using OpenSC <= 0.9.6
PKCS11_DEFAULT_LIB=\"/usr/lib/pkcs11/opensc-pkcs11.so\"
# PKCS11_DEFAULT_LIB=\"/usr/lib/pkcs11/opensc-pkcs11.so\"
# Uncomment tis line if using OpenSC >= 0.10.0
#PKCS11_DEFAULT_LIB=\"usr/lib/opensc-pkcs11.so\"
PKCS11_DEFAULT_LIB=\"usr/lib/opensc-pkcs11.so\"
This default path to the easily-obtainable OpenSC library module can be
simply overridden during run-time by specifying an alternative path in
@ -141,80 +139,9 @@ Contents
USE="smartcard usb -pam -X" emerge strongswan
3. Building strongSwan with a Linux 2.4 kernel
-------------------------------------------
* Building strongSwan with a Linux 2.4 kernel requires the presence of the
matching kernel sources referenced via the symbolic link /usr/src/linux.
The use of the vanilla kernel sources from ftp.kernel.org is strongly
recommended.
Before building strongSwan you must have compiled the kernel sources at
least once:
make menuconfig; make dep; make bzImage; make modules
* Now change into the strongswan-2.x.x source directory.
First uncomment any desired compile options in "programs/pluto/Makefile"
(see section 2. Optional packages).
Then in the top source directory type
make menumod
This command applies an ESP_IN_UDP encapsulation patch which is required
for NAT-Traversal to the kernel sources.
In the "Networking options" menu set
<M> IP Security Protocol (strongSwan IPsec)
in order to build KLIPS as a loadable kernel module "ipsec.o". Do not
forget to save the modified configuration file when leaving "menumod".
The strongSwan userland programs are now automatically built and
installed, whereas the ipsec.o kernel module and the crypto modules
are only built and must be installed with the command
make minstall
* If you intend to use the NAT-Traversal feature then you must compile the
patched kernel sources again by executing
make bzImage
and then install and boot the modified kernel.
* Next add your connections to "/etc/ipsec.conf" and start strongSwan with
ipsec setup start
4. Updating strongSwan with a Linux 2.4 kernel
-------------------------------------------
* If you have already successfully installed strongSwan and want to update
to a newer version then the following shortcut can be taken:
First uncomment any desired compile options in "programs/pluto/Makefile"
(see section 2. Optional packages).
Then in the strongwan-2.x.x top directory type
make programs; make install
followed by
make module; make minstall
* You can then start the updated strongSwan version with
ipsec setup restart
5. Building strongSwan with a Linux 2.6 kernel
-------------------------------------------
3. Building and running strongSwan with a Linux 2.6 kernel
-------------------------------------------------------
* Because the Linux 2.6 kernel comes with a built-in native IPsec stack,
you won't need to build the strongSwan kernel modules. Please make sure
@ -225,25 +152,30 @@ Contents
o esp4
o ipcomp
o xfrm_user
o xfrm_tunnel
Also the built-in kernel Cryptoapi modules with selected encryption and
hash algorithms should be available.
* First uncomment any desired compile options in "programs/pluto/Makefile"
(see section 2. Optional packages).
* First select any desired compile options in "Makefile.inc" (see section 2.
Optional packages). Then in the strongwan-4.x.x top directory type
Then in the strongwan-2.x.x top directory type
make programs
make
followed by
make install
* Next add your connections to "etc/ipsec.conf" and start strongSwan with
* Next add your connections to "/etc/ipsec.conf" and your secrets to
"/etc/ipsec.secrets". Connections that are to be negotiated by the new
IKEv2 charon keying daemon should be designated by "keyexchange=ikev2" and
those by the IKEv1 pluto keying daemon either by "keyexchange=ikev1" or
the default "keyexchange=ike".
ipsec setup start
* At last start strongSwan with
ipsec start
-----------------------------------------------------------------------------
This file is RCSID $Id: INSTALL,v 1.8 2006/01/22 16:22:23 as Exp $
This file is RCSID $Id: INSTALL,v 1.9 2006/05/01 16:02:37 as Exp $

View File

@ -2650,7 +2650,7 @@ and can be used when the following prerequisites are fulfilled:
- Linux 2.4.x kernel, KLIPS IPsec stack, and arbitrary iptables version.
Filtering of tunneled traffic is based on ipsecN interfaces.
- Linux 2.4.16 kernel or newer, native NETKEY IPsec stack, and
- Linux 2.6.16 kernel or newer, native NETKEY IPsec stack, and
iptables-1.3.5 or newer. Filtering of tunneled traffic is based on
IPsec policy matching rules.

View File

@ -22,13 +22,16 @@
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include "local_credential_store.h"
#include <utils/lexparser.h>
#include <utils/linked_list.h>
#include <utils/logger_manager.h>
#include <crypto/x509.h>
#define PATH_BUF 256
typedef struct key_entry_t key_entry_t;
@ -138,9 +141,9 @@ static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t *
}
/**
* Implements local_credential_store_t.load_private_keys
* Implements local_credential_store_t.load_certificates
*/
static void load_certificates(private_local_credential_store_t *this, char *path)
static void load_certificates(private_local_credential_store_t *this, const char *path)
{
struct dirent* entry;
struct stat stb;
@ -154,7 +157,8 @@ static void load_certificates(private_local_credential_store_t *this, char *path
}
while ((entry = readdir(dir)) != NULL)
{
char file[256];
char file[PATH_BUF];
snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
if (stat(file, &stb) == -1)
@ -168,7 +172,6 @@ static void load_certificates(private_local_credential_store_t *this, char *path
if (cert)
{
this->certificates->insert_last(this->certificates, (void*)cert);
this->logger->log(this->logger, CONTROL|LEVEL1, "loaded certificate \"%s\"", file);
}
else
{
@ -218,55 +221,118 @@ static identification_t *get_id_for_private_key(private_local_credential_store_t
/**
* Implements local_credential_store_t.load_private_keys
*/
static void load_private_keys(private_local_credential_store_t *this, char *path)
static void load_private_keys(private_local_credential_store_t *this, const char *secretsfile, const char *defaultpath)
{
struct dirent* entry;
struct stat stb;
DIR* dir;
rsa_private_key_t *key;
dir = opendir(path);
if (dir == NULL) {
this->logger->log(this->logger, ERROR, "error opening private key directory \"%s\"", path);
return;
}
while ((entry = readdir(dir)) != NULL)
FILE *fd = fopen(secretsfile, "r");
if (fd)
{
char file[256];
snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
if (stat(file, &stb) == -1)
int bytes;
int line_nr = 0;
chunk_t chunk, src, line;
this->logger->log(this->logger, CONTROL, "loading secrets from \"%s\"", secretsfile);
fseek(fd, 0, SEEK_END);
chunk.len = ftell(fd);
rewind(fd);
chunk.ptr = malloc(chunk.len);
bytes = fread(chunk.ptr, 1, chunk.len, fd);
fclose(fd);
src = chunk;
while (fetchline(&src, &line))
{
continue;
}
/* try to parse all regular files */
if (stb.st_mode & S_IFREG)
{
key = rsa_private_key_create_from_file(file, NULL);
if (key)
chunk_t ids, token;
line_nr++;
if (!eat_whitespace(&line))
{
key_entry_t *entry;
identification_t *id = get_id_for_private_key(this, key);
if (!id)
continue;
}
if (!extract_token(&ids, ':', &line))
{
this->logger->log(this->logger, ERROR, "line %d: missing ':' separator", line_nr);
goto error;
}
if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
{
this->logger->log(this->logger, ERROR, "line %d: missing token", line_nr);
goto error;
}
if (match("RSA", &token))
{
char path[PATH_BUF];
chunk_t filename;
err_t ugh = extract_value(&filename, &line);
if (ugh != NULL)
{
this->logger->log(this->logger, ERROR,
"no certificate found for private key \"%s\", skipped", file);
key->destroy(key);
continue;
this->logger->log(this->logger, ERROR, "line %d: %s", line_nr, ugh);
goto error;
}
entry = malloc_thing(key_entry_t);
entry->key = key;
entry->id = id;
this->private_keys->insert_last(this->private_keys, (void*)entry);
this->logger->log(this->logger, CONTROL|LEVEL1, "loaded private key \"%s\"", file);
if (filename.len == 0)
{
this->logger->log(this->logger, ERROR,
"line %d: empty filename", line_nr);
goto error;
}
if (*filename.ptr == '/')
{
/* absolute path name */
snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
}
else
{
/* relative path name */
snprintf(path, sizeof(path), "%s/%.*s", defaultpath, filename.len, filename.ptr);
}
rsa_private_key_t *key = rsa_private_key_create_from_file(path, NULL);
if (key)
{
key_entry_t *entry;
identification_t *id = get_id_for_private_key(this, key);
if (!id)
{
this->logger->log(this->logger, ERROR,
"no certificate found for private key \"%s\", skipped", path);
key->destroy(key);
continue;
}
entry = malloc_thing(key_entry_t);
entry->key = key;
entry->id = id;
this->private_keys->insert_last(this->private_keys, (void*)entry);
}
}
else if (match("PSK", &token))
{
}
else if (match("PIN", &token))
{
}
else
{
this->logger->log(this->logger, ERROR, "private key \"%s\" invalid, skipped", file);
this->logger->log(this->logger, ERROR,
"line %d: token must be either RSA, PSK, or PIN",
line_nr, token.len);
goto error;
}
}
error:
free(chunk.ptr);
}
else
{
this->logger->log(this->logger, ERROR, "could not open file '%s'", secretsfile);
}
closedir(dir);
}
/**
@ -302,8 +368,8 @@ local_credential_store_t * local_credential_store_create()
this->public.credential_store.get_shared_secret = (status_t(*)(credential_store_t*,identification_t*,chunk_t*))get_shared_secret;
this->public.credential_store.get_rsa_private_key = (rsa_private_key_t*(*)(credential_store_t*,identification_t*))get_rsa_private_key;
this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
this->public.load_certificates = (void(*)(local_credential_store_t*,char*))load_certificates;
this->public.load_private_keys = (void(*)(local_credential_store_t*,char*))load_private_keys;
this->public.load_certificates = (void(*)(local_credential_store_t*,const char*))load_certificates;
this->public.load_private_keys = (void(*)(local_credential_store_t*,const char*, const char*))load_private_keys;
this->public.credential_store.destroy = (void(*)(credential_store_t*))destroy;
/* private variables */

View File

@ -57,7 +57,7 @@ struct local_credential_store_t {
* @param this calling object
* @param path directory to load certificates from
*/
void (*load_certificates) (local_credential_store_t *this, char *path);
void (*load_certificates) (local_credential_store_t *this, const char *path);
/**
* @brief Loads RSA private keys from a folder.
@ -66,10 +66,11 @@ struct local_credential_store_t {
* other gets ignored. Further, a certificate for the specific private
* key must already be loaded to get the ID from.
*
* @param this calling object
* @param path directory to load keys from
* @param this calling object
* @param secretsfile file where secrets are stored
* @param defaultpath default directory for private keys
*/
void (*load_private_keys) (local_credential_store_t *this, char *path);
void (*load_private_keys) (local_credential_store_t *this, const char *secretsfile, const char *defaultpath);
};
/**

View File

@ -179,7 +179,7 @@ static void initialize(private_daemon_t *this)
/* load keys & certs */
cred_store->load_certificates(cred_store, CERTIFICATE_DIR);
cred_store->load_private_keys(cred_store, PRIVATE_KEY_DIR);
cred_store->load_private_keys(cred_store, SECRETS_FILE, PRIVATE_KEY_DIR);
/* start building threads, we are multi-threaded NOW */

View File

@ -202,12 +202,19 @@
*/
#define PID_FILE "/var/run/charon.pid"
/**
* Configuration directory
*
* @ingroup charon
*/
#define CONFIG_DIR "/etc"
/**
* Directory of IPsec relevant files
*
* @ingroup charon
*/
#define IPSEC_DIR "/etc/ipsec.d"
#define IPSEC_DIR CONFIG_DIR "/ipsec.d"
/**
* Directory for private keys
@ -223,6 +230,12 @@
*/
#define CERTIFICATE_DIR IPSEC_DIR "/certs"
/**
* Secrets files
*
* @ingroup charon
*/
#define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
typedef struct daemon_t daemon_t;

View File

@ -241,8 +241,8 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
my_id = my_id->clone(my_id);
cert->destroy(cert);
this->logger->log(this->logger, CONTROL,
"defined a valid certificate, using its ID \"%s\"",
my_id->get_string(my_id));
"valid certificate with ID \"%s\"",
my_id->get_string(my_id));
}
}
if (msg->add_conn.other.cert)
@ -257,8 +257,8 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
other_id = other_id->clone(other_id);
cert->destroy(cert);
this->logger->log(this->logger, CONTROL,
"defined a valid certificate, using its ID \"%s\"",
other_id->get_string(other_id));
"valid certificate with ID \"%s\"",
other_id->get_string(other_id));
}
}
@ -308,7 +308,7 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
connection = charon->connections->get_connection_by_name(charon->connections, msg->initiate.name);
if (connection == NULL)
{
this->stroke_logger->log(this->stroke_logger, ERROR, "could not find a connection named \"%s\"", msg->initiate.name);
this->stroke_logger->log(this->stroke_logger, ERROR, "no connection named \"%s\"", msg->initiate.name);
}
else
{

View File

@ -21,8 +21,6 @@
#include <utils/logger_manager.h>
static logger_t *logger;
/* Names of the months */
static const char* months[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
@ -87,7 +85,18 @@ static const asn1Object_t algorithmIdentifierObjects[] = {
#define ALGORITHM_ID_PARAMETERS 2
#define ALGORITHM_ID_ROOF 3
/*
static logger_t *logger = NULL;
/**
* initializes the ASN.1 logger
*/
static void asn1_init_logger()
{
if (logger == NULL)
logger = logger_manager->get_logger(logger_manager, ASN1);
}
/**
* return the ASN.1 encoded algorithm identifier
*/
chunk_t asn1_algorithmIdentifier(int oid)
@ -109,7 +118,7 @@ chunk_t asn1_algorithmIdentifier(int oid)
}
}
/*
/**
* If the oid is listed in the oid_names table then the corresponding
* position in the oid_names table is returned otherwise -1 is returned
*/
@ -141,7 +150,7 @@ int known_oid(chunk_t object)
return -1;
}
/*
/**
* Decodes the length in bytes of an ASN.1 object
*/
u_int asn1_length(chunk_t *blob)
@ -188,7 +197,7 @@ u_int asn1_length(chunk_t *blob)
return len;
}
/*
/**
* determines if a character string is of type ASN.1 printableString
*/
bool is_printablestring(chunk_t str)
@ -205,9 +214,9 @@ bool is_printablestring(chunk_t str)
return TRUE;
}
/*
/**
* Display a date either in local or UTC time
* TODO: Does not seem to be thread save
* TODO: Does not seem to be thread safe
*/
char* timetoa(const time_t *time, bool utc)
{
@ -225,7 +234,7 @@ char* timetoa(const time_t *time, bool utc)
return buf;
}
/*
/**
* Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
*/
time_t asn1totime(const chunk_t *utctime, asn1_t type)
@ -300,19 +309,20 @@ time_t asn1totime(const chunk_t *utctime, asn1_t type)
return mktime(&t) - timezone - tz_offset;
}
/*
/**
* Initializes the internal context of the ASN.1 parser
*/
void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit)
{
logger = logger_manager->get_logger(logger_manager, ASN1);
asn1_init_logger();
ctx->blobs[0] = blob;
ctx->level0 = level0;
ctx->implicit = implicit;
memset(ctx->loopAddr, '\0', sizeof(ctx->loopAddr));
}
/*
/**
* print the value of an ASN.1 simple object
*/
static void debug_asn1_simple_object(chunk_t object, asn1_t type)
@ -348,7 +358,7 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type)
logger->log_chunk(logger, RAW|LEVEL1, "", object);
}
/*
/**
* Parses and extracts the next ASN.1 object
*/
bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx)
@ -479,7 +489,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
return TRUE;
}
/*
/**
* parse an ASN.1 simple type
*/
bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name)
@ -515,7 +525,7 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c
return TRUE;
}
/*
/**
* extracts an algorithmIdentifier
*/
int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
@ -558,6 +568,8 @@ bool is_asn1(chunk_t blob)
u_int len;
u_char tag = *blob.ptr;
asn1_init_logger();
if (tag != ASN1_SEQUENCE && tag != ASN1_SET)
{
logger->log(logger, ERROR|LEVEL2, " file content is not binary ASN.1");
@ -572,7 +584,7 @@ bool is_asn1(chunk_t blob)
return TRUE;
}
/*
/**
* codes ASN.1 lengths up to a size of 16'777'215 bytes
*/
void code_asn1_length(size_t length, chunk_t *code)
@ -605,7 +617,7 @@ void code_asn1_length(size_t length, chunk_t *code)
}
}
/*
/**
* build an empty asn.1 object with tag and length fields already filled in
*/
u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen)
@ -634,7 +646,7 @@ u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen)
return pos;
}
/*
/**
* build a simple ASN.1 object
*/
chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
@ -648,7 +660,8 @@ chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
return object;
}
/* Build an ASN.1 object from a variable number of individual chunks.
/**
* Build an ASN.1 object from a variable number of individual chunks.
* Depending on the mode, chunks either are moved ('m') or copied ('c').
*/
chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
@ -696,7 +709,7 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
return construct;
}
/*
/**
* convert a MP integer into a DER coded ASN.1 object
*/
chunk_t asn1_integer_from_mpz(const mpz_t value)
@ -709,7 +722,7 @@ chunk_t asn1_integer_from_mpz(const mpz_t value)
return asn1_wrap(ASN1_INTEGER, "m", n);
}
/*
/**
* convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
*/
chunk_t timetoasn1(const time_t *time, asn1_t type)

View File

@ -1,6 +1,5 @@
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur
*
* 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
@ -21,14 +20,27 @@
#include <stddef.h>
#include <sys/types.h>
#include "asn1.h"
#include "pem.h"
#include "ttodata.h"
#include <utils/lexparser.h>
#include <utils/logger_manager.h>
#include <crypto/hashers/hasher.h>
#include <crypto/crypters/crypter.h>
static logger_t *logger = NULL;
/*
/**
* initializes the PEM logger
*/
static void pem_init_logger()
{
if (logger == NULL)
logger = logger_manager->get_logger(logger_manager, ASN1);
}
/**
* check the presence of a pattern in a character string
*/
static bool present(const char* pattern, chunk_t* ch)
@ -44,15 +56,7 @@ static bool present(const char* pattern, chunk_t* ch)
return FALSE;
}
/*
* compare string with chunk
*/
static bool match(const char *pattern, const chunk_t *ch)
{
return ch->len == strlen(pattern) && strncmp(pattern, ch->ptr, ch->len) == 0;
}
/*
/**
* find a boundary of the form -----tag name-----
*/
static bool find_boundary(const char* tag, chunk_t *line)
@ -73,6 +77,8 @@ static bool find_boundary(const char* tag, chunk_t *line)
{
if (present("-----", line))
{
logger->log(logger, CONTROL|LEVEL2,
" -----%s %.*s-----", tag, (int)name.len, name.ptr);
return TRUE;
}
line->ptr++; line->len--; name.len++;
@ -80,93 +86,16 @@ static bool find_boundary(const char* tag, chunk_t *line)
return FALSE;
}
/*
* eat whitespace
*/
static void eat_whitespace(chunk_t *src)
{
while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
{
src->ptr++; src->len--;
}
}
/*
* extracts a token ending with a given termination symbol
*/
static bool extract_token(chunk_t *token, char termination, chunk_t *src)
{
u_char *eot = memchr(src->ptr, termination, src->len);
/* initialize empty token */
*token = CHUNK_INITIALIZER;
if (eot == NULL) /* termination symbol not found */
{
return FALSE;
}
/* extract token */
token->ptr = src->ptr;
token->len = (u_int)(eot - src->ptr);
/* advance src pointer after termination symbol */
src->ptr = eot + 1;
src->len -= (token->len + 1);
return TRUE;
}
/*
* extracts a name: value pair from the PEM header
*/
static bool extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
{
/* extract name */
if (!extract_token(name,':', line))
{
return FALSE;
}
eat_whitespace(line);
/* extract value */
*value = *line;
return TRUE;
}
/*
* fetches a new line terminated by \n or \r\n
*/
static bool fetchline(chunk_t *src, chunk_t *line)
{
if (src->len == 0) /* end of src reached */
return FALSE;
if (extract_token(line, '\n', src))
{
if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
line->len--; /* remove optional \r */
}
else /*last line ends without newline */
{
*line = *src;
src->ptr += src->len;
src->len = 0;
}
return TRUE;
}
/*
* decrypts a DES-EDE-CBC encrypted data block
*/
static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase)
static err_t pem_decrypt(chunk_t *blob, chunk_t *iv, const char *passphrase)
{
hasher_t *hasher;
crypter_t *crypter;
chunk_t hash;
chunk_t decrypted;
chunk_t pass = {passphrase, strlen(passphrase)};
chunk_t pass = {(char*)passphrase, strlen(passphrase)};
chunk_t key = {alloca(24), 24};
u_int8_t padding, *last_padding_pos, *first_padding_pos;
@ -203,11 +132,11 @@ static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase)
while (--last_padding_pos > first_padding_pos)
{
if (*last_padding_pos != padding)
return FALSE;
return "invalid passphrase";
}
/* remove padding */
blob->len -= padding;
return TRUE;
return NULL;
}
/* Converts a PEM encoded file into its binary form
@ -215,7 +144,7 @@ static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase)
* RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
* RFC 934 Message Encapsulation, January 1985
*/
status_t pemtobin(chunk_t *blob, char *pass)
err_t pem_to_bin(chunk_t *blob, const char *passphrase, bool *pgp)
{
typedef enum {
PEM_PRE = 0,
@ -244,6 +173,8 @@ status_t pemtobin(chunk_t *blob, char *pass)
iv.ptr = iv_buf;
iv.len = 0;
pem_init_logger();
while (fetchline(&src, &line))
{
if (state == PEM_PRE)
@ -277,8 +208,9 @@ status_t pemtobin(chunk_t *blob, char *pass)
continue;
}
/* we are looking for a name: value pair */
if (!extract_parameter(&name, &value, &line))
/* we are looking for a parameter: value pair */
logger->log(logger, CONTROL|LEVEL2, " %.*s", (int)line.len, line.ptr);
if (!extract_parameter_value(&name, &value, &line))
continue;
if (match("Proc-Type", &name) && *value.ptr == '4')
@ -294,12 +226,12 @@ status_t pemtobin(chunk_t *blob, char *pass)
/* we support DES-EDE3-CBC encrypted files, only */
if (!match("DES-EDE3-CBC", &dek))
return NOT_SUPPORTED;
return "encryption algorithm not supported";
eat_whitespace(&value);
ugh = ttodata(value.ptr, value.len, 16, iv.ptr, 16, &len);
if (ugh)
return PARSE_ERROR;
return "error in IV";
iv.len = len;
}
@ -316,6 +248,17 @@ status_t pemtobin(chunk_t *blob, char *pass)
data = line;
}
/* check for PGP armor checksum */
if (*data.ptr == '=')
{
*pgp = TRUE;
data.ptr++;
data.len--;
logger->log(logger, CONTROL|LEVEL2, " Armor checksum: %.*s",
(int)data.len, data.ptr);
continue;
}
ugh = ttodata(data.ptr, data.len, 64, dst.ptr, blob->len - dst.len, &len);
if (ugh)
{
@ -334,10 +277,68 @@ status_t pemtobin(chunk_t *blob, char *pass)
blob->len = dst.len;
if (state != PEM_POST)
return PARSE_ERROR;
return "file coded in unknown format, discarded";
if (encrypted)
return pem_decrypt(blob, &iv, pass);
else
return SUCCESS;
return (encrypted)? pem_decrypt(blob, &iv, passphrase) : NULL;
}
/* load a coded key or certificate file with autodetection
* of binary DER or base64 PEM ASN.1 formats and armored PGP format
*/
bool pem_asn1_load_file(const char *filename, const char *passphrase,
const char *type, chunk_t *blob, bool *pgp)
{
err_t ugh = NULL;
FILE *fd = fopen(filename, "r");
pem_init_logger();
if (fd)
{
int bytes;
fseek(fd, 0, SEEK_END );
blob->len = ftell(fd);
rewind(fd);
blob->ptr = malloc(blob->len);
bytes = fread(blob->ptr, 1, blob->len, fd);
fclose(fd);
logger->log(logger, CONTROL, "loaded %s file '%s' (%d bytes)", type, filename, bytes);
*pgp = FALSE;
/* try DER format */
if (is_asn1(*blob))
{
logger->log(logger, CONTROL|LEVEL1, " file coded in DER format");
return TRUE;
}
/* try PEM format */
ugh = pem_to_bin(blob, passphrase, pgp);
if (ugh == NULL)
{
if (*pgp)
{
logger->log(logger, CONTROL|LEVEL1, " file coded in armored PGP format");
return TRUE;
}
if (is_asn1(*blob))
{
logger->log(logger, CONTROL|LEVEL1, " file coded in PEM format");
return TRUE;
}
ugh = "file coded in unknown format, discarded";
}
/* a conversion error has occured */
logger->log(logger, ERROR, " %s", ugh);
chunk_free(blob);
}
else
{
logger->log(logger, ERROR, "could not open %s file '%s'", type, filename);
}
return FALSE;
}

View File

@ -1,6 +1,5 @@
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur
*
* 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
@ -20,6 +19,9 @@
#include <types.h>
status_t pemtobin(chunk_t *blob, char *pass);
err_t pem_to_bin(chunk_t *blob, const char *passphrase, bool *pgp);
bool pem_asn1_load_file(const char *filename, const char *passphrase,
const char *type, chunk_t *blob, bool *pgp);
#endif /*PEM_H_*/

View File

@ -22,8 +22,6 @@
#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/
#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */
typedef const char *err_t; /* error message, or NULL for success */
err_t ttodata(const char *src, size_t srclen, int base, char *buf, size_t buflen, size_t *needed);

View File

@ -29,6 +29,7 @@
#include <daemon.h>
#include <asn1/asn1.h>
#include <asn1/pem.h>
/*
* Oids for hash algorithms are defined in
@ -736,37 +737,17 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
/*
* see header
* TODO: PEM files
*/
rsa_private_key_t *rsa_private_key_create_from_file(char *filename, char *passphrase)
{
chunk_t chunk;
struct stat stb;
FILE *file;
char *buffer;
if (stat(filename, &stb) == -1)
{
bool pgp = FALSE;
chunk_t chunk = CHUNK_INITIALIZER;
rsa_private_key_t *key = NULL;
if (!pem_asn1_load_file(filename, passphrase, "private key", &chunk, &pgp))
return NULL;
}
buffer = alloca(stb.st_size);
file = fopen(filename, "r");
if (file == NULL)
{
return NULL;
}
if (fread(buffer, stb.st_size, 1, file) != 1)
{
fclose(file);
return NULL;
}
fclose(file);
chunk.ptr = buffer;
chunk.len = stb.st_size;
return rsa_private_key_create_from_chunk(chunk);
key = rsa_private_key_create_from_chunk(chunk);
free(chunk.ptr);
return key;
}

View File

@ -28,13 +28,11 @@
#include "x509.h"
#include <daemon.h>
#include <asn1/asn1.h>
#include <asn1/oid.h>
#include <asn1/asn1.h>
#include <asn1/pem.h>
#include <utils/logger_manager.h>
typedef const char *err_t; /* error message, or NULL for success */
#define BUF_LEN 512
#define RSA_MIN_OCTETS (512 / 8)
#define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 512 bits"
@ -905,33 +903,14 @@ x509_t *x509_create_from_chunk(chunk_t chunk)
*/
x509_t *x509_create_from_file(char *filename)
{
struct stat stb;
FILE *file;
char *buffer;
chunk_t chunk;
if (stat(filename, &stb) == -1)
{
bool pgp = FALSE;
chunk_t chunk = CHUNK_INITIALIZER;
x509_t *cert = NULL;
if (!pem_asn1_load_file(filename, "", "certificate", &chunk, &pgp))
return NULL;
}
buffer = alloca(stb.st_size);
file = fopen(filename, "r");
if (file == NULL)
{
return NULL;
}
if (fread(buffer, stb.st_size, 1, file) == -1)
{
fclose(file);
return NULL;
}
fclose(file);
chunk.ptr = buffer;
chunk.len = stb.st_size;
return x509_create_from_chunk(chunk);
cert = x509_create_from_chunk(chunk);
free(chunk.ptr);
return cert;
}

View File

@ -37,6 +37,11 @@ typedef int bool;
#define FALSE 0
#define TRUE 1
/**
* error message, or NULL for success
*/
typedef const char *err_t;
typedef enum status_t status_t;
/**

View File

@ -18,10 +18,14 @@ LIB_OBJS+= $(BUILD_DIR)leak_detective.o
$(BUILD_DIR)leak_detective.o : $(UTILS_DIR)leak_detective.c $(UTILS_DIR)leak_detective.h
$(CC) $(CFLAGS) -c -o $@ $<
LIB_OBJS+= $(BUILD_DIR)lexparser.o
$(BUILD_DIR)lexparser.o : $(UTILS_DIR)lexparser.c $(UTILS_DIR)lexparser.h
$(CC) $(CFLAGS) -c -o $@ $<
LIB_OBJS+= $(BUILD_DIR)linked_list.o
$(BUILD_DIR)linked_list.o : $(UTILS_DIR)linked_list.c $(UTILS_DIR)linked_list.h
$(CC) $(CFLAGS) -c -o $@ $<
LIB_OBJS+= $(BUILD_DIR)logger.o
$(BUILD_DIR)logger.o : $(UTILS_DIR)logger.c $(UTILS_DIR)logger.h
$(CC) $(CFLAGS) -c -o $@ $<

View File

@ -0,0 +1,135 @@
/**
* @file lexparser.c
*
* @brief lexical parser for text-based configuration files
*
*/
/*
* Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <string.h>
#include "lexparser.h"
/**
* eat whitespace
*/
bool eat_whitespace(chunk_t *src)
{
while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
{
src->ptr++; src->len--;
}
return src->len > 0 && *src->ptr != '#';
}
/**
* compare string with chunk
*/
bool match(const char *pattern, const chunk_t *ch)
{
return ch->len == strlen(pattern) && strncmp(pattern, ch->ptr, ch->len) == 0;
}
/**
* extracts a token ending with a given termination symbol
*/
bool extract_token(chunk_t *token, const char termination, chunk_t *src)
{
u_char *eot = memchr(src->ptr, termination, src->len);
/* initialize empty token */
*token = CHUNK_INITIALIZER;
if (eot == NULL) /* termination symbol not found */
{
return FALSE;
}
/* extract token */
token->ptr = src->ptr;
token->len = (u_int)(eot - src->ptr);
/* advance src pointer after termination symbol */
src->ptr = eot + 1;
src->len -= (token->len + 1);
return TRUE;
}
/**
* fetches a new line terminated by \n or \r\n
*/
bool fetchline(chunk_t *src, chunk_t *line)
{
if (src->len == 0) /* end of src reached */
return FALSE;
if (extract_token(line, '\n', src))
{
if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
line->len--; /* remove optional \r */
}
else /*last line ends without newline */
{
*line = *src;
src->ptr += src->len;
src->len = 0;
}
return TRUE;
}
err_t extract_value(chunk_t *value, chunk_t *line)
{
char delimiter = ' ';
if (!eat_whitespace(line))
{
return "missing value";
}
if (*line->ptr == '\'' || *line->ptr == '"')
{
delimiter = *line->ptr;
line->ptr++; line->len--;
}
if (!extract_token(value, delimiter, line))
{
if (delimiter == ' ')
{
*value = *line;
}
else
{
return "missing second delimiter";
}
}
return NULL;
}
/**
* extracts a parameter: value pair
*/
err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line)
{
/* extract name */
if (!extract_token(name,':', line))
{
return "missing ':'";
}
/* extract value */
return extract_value(value, line);
}

View File

@ -0,0 +1,57 @@
/**
* @file lexparser.h
*
* @brief lexical parser for text-based configuration files
*
*/
/*
* Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <types.h>
/**
* @brief Eats whitespace
*/
bool eat_whitespace(chunk_t *src);
/**
* @brief Compare null-terminated pattern with chunk
*/
bool match(const char *pattern, const chunk_t *ch);
/**
* @brief Extracts a token ending with a given termination symbol
*/
bool extract_token(chunk_t *token, const char termination, chunk_t *src);
/**
* @brief Fetches a new text line terminated by \n or \r\n
*/
bool fetchline(chunk_t *src, chunk_t *line);
/**
* @brief Extracts a value that might be single or double quoted
*/
err_t extract_value(chunk_t *value, chunk_t *line);
/**
* @brief extracts a name: value pair from a text line
*/
err_t extract_name_value(chunk_t *name, chunk_t *value, chunk_t *line);
/**
* @brief extracts a parameter: value from a text line
*/
err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line);

View File

@ -132,11 +132,15 @@ static void prepend_prefix(private_logger_t *this, log_level_t loglevel, const c
*/
static int get_priority(log_level_t loglevel)
{
if (loglevel & ERROR)
{
return LOG_AUTHPRIV|LOG_ERR;
}
if (loglevel & AUDIT)
{
return LOG_AUTHPRIV|LOG_INFO;
}
return LOG_DAEMON|LOG_DEBUG;
return LOG_AUTHPRIV|LOG_DEBUG;
}
/**

View File

@ -239,19 +239,21 @@ static void exit_usage(char *error)
int main(int argc, char *argv[])
{
int res;
char *op;
if (argc < 2)
{
exit_usage(NULL);
}
if (strcmp(argv[1], "status") == 0 ||
strcmp(argv[1], "statusall") == 0)
op = argv[1];
if (strcmp(op, "status") == 0 ||
strcmp(op, "statusall") == 0)
{
res = show_status(argv[1], argc > 2 ? argv[2] : NULL);
res = show_status(op, argc > 2 ? argv[2] : NULL);
}
else if (strcmp(argv[1], "up") == 0)
else if (strcmp(op, "up") == 0)
{
if (argc < 3)
{
@ -259,7 +261,7 @@ int main(int argc, char *argv[])
}
res = initiate_connection(argv[2]);
}
else if (strcmp(argv[1], "down") == 0)
else if (strcmp(op, "down") == 0)
{
if (argc < 3)
{
@ -267,7 +269,7 @@ int main(int argc, char *argv[])
}
res = terminate_connection(argv[2]);
}
else if (strcmp(argv[1], "add") == 0)
else if (strcmp(op, "add") == 0)
{
if (argc < 11)
{
@ -279,7 +281,7 @@ int main(int argc, char *argv[])
argv[7], argv[8],
atoi(argv[9]), atoi(argv[10]));
}
else if (strcmp(argv[1], "logtype") == 0)
else if (strcmp(op, "logtype") == 0)
{
if (argc < 5)
{
@ -287,7 +289,7 @@ int main(int argc, char *argv[])
}
res = set_logtype(argv[2], argv[3], atoi(argv[4]));
}
else if (strcmp(argv[1], "loglevel") == 0)
else if (strcmp(op, "loglevel") == 0)
{
if (argc < 4)
{

View File

@ -1 +1,2 @@
distributed by Andreas Steffen <andreas.steffen@strongswan.org>
distributed by the Institute of Internet Technologies and Applications
University of Applied Sciences Rapperswil, Switzerland (ITA-HSR)

View File

@ -1,6 +1,7 @@
#! /bin/sh
# prefix command to run stuff from our programs directory
# Copyright (C) 1998-2002 Henry Spencer.
# Copyright (C) 2006 Andreas Steffen
#
# 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
@ -26,6 +27,7 @@ IPSEC_DIR="$IPSEC_LIBDIR"
export IPSEC_DIR IPSEC_CONFS IPSEC_LIBDIR IPSEC_EXECDIR
IPSEC_STARTER_PID="/var/run/starter.pid"
IPSEC_PLUTO_PID="/var/run/pluto.pid"
IPSEC_CHARON_PID="/var/run/charon.pid"
# standardize PATH, and export it for everything else's benefit
@ -123,10 +125,13 @@ case "$1" in
;;
down)
shift
$IPSEC_EXECDIR/whack --name "$1" --terminate
if test -e $IPSEC_PLUTO_PID
then
$IPSEC_EXECDIR/whack --name "$1" --terminate
fi
if test -e $IPSEC_CHARON_PID
then
$IPSEC_EXECDIR/stroke down "$1"
$IPSEC_EXECDIR/stroke down "$1"
fi
exit 0
;;
@ -138,16 +143,22 @@ rereadcacerts|rereadaacerts|rereadocspcerts|\
rereadacerts|rereadcrls|rereadall)
op="$1"
shift
$IPSEC_EXECDIR/whack "$@" "--$op"
if test -e $IPSEC_CHARON_PID
if test -e $IPSEC_PLUTO_PID
then
$IPSEC_EXECDIR/stroke "$op"
fi
$IPSEC_EXECDIR/whack "$@" "--$op"
fi
#if test -e $IPSEC_CHARON_PID
#then
# $IPSEC_EXECDIR/stroke "$op"
#fi
exit 0
;;
ready)
shift
$IPSEC_EXECDIR/whack --listen
if test -e $IPSEC_PLUTO_PID
then
$IPSEC_EXECDIR/whack --listen
fi
exit 0
;;
reload)
@ -170,19 +181,28 @@ restart)
route|unroute)
op="$1"
shift
$IPSEC_EXECDIR/whack --name "$1" "--$op"
if test -e $IPSEC_PLUTO_PID
then
$IPSEC_EXECDIR/whack --name "$1" "--$op"
fi
exit 0
;;
scencrypt|scdecrypt)
op="$1"
shift
$IPSEC_EXECDIR/whack "--$op" "$@"
if test -e $IPSEC_PLUTO_PID
then
$IPSEC_EXECDIR/whack "--$op" "$@"
fi
exit 0
;;
secrets)
$IPSEC_EXECDIR/whack --rereadsecrets
exit 0
;;
if test -e $IPSEC_PLUTO_PID
then
$IPSEC_EXECDIR/whack --rereadsecrets
fi
exit 0
;;
start)
shift
exec $IPSEC_EXECDIR/starter "$@"
@ -192,17 +212,23 @@ status|statusall)
shift
if test $# -eq 0
then
$IPSEC_EXECDIR/whack "--$op"
if test -e $IPSEC_CHARON_PID
then
$IPSEC_EXECDIR/stroke "$op"
fi
if test -e $IPSEC_PLUTO_PID
then
$IPSEC_EXECDIR/whack "--$op"
fi
if test -e $IPSEC_CHARON_PID
then
$IPSEC_EXECDIR/stroke "$op"
fi
else
$IPSEC_EXECDIR/whack --name "$1" "--$op"
if test -e $IPSEC_CHARON_PID
then
$IPSEC_EXECDIR/stroke "$op" "$1"
fi
if test -e $IPSEC_PLUTO_PID
then
$IPSEC_EXECDIR/whack --name "$1" "--$op"
fi
if test -e $IPSEC_CHARON_PID
then
$IPSEC_EXECDIR/stroke "$op" "$1"
fi
fi
exit 0
;;
@ -218,7 +244,10 @@ stop)
;;
up)
shift
$IPSEC_EXECDIR/whack --name "$1" --initiate
if test -e $IPSEC_PLUTO_PID
then
$IPSEC_EXECDIR/whack --name "$1" --initiate
fi
if test -e $IPSEC_CHARON_PID
then
$IPSEC_EXECDIR/stroke up "$1"
@ -228,10 +257,10 @@ up)
update)
if test -e $IPSEC_STARTER_PID
then
echo "Updating strongSwan IPsec configuration..." >&2
kill -s HUP `cat $IPSEC_STARTER_PID`
echo "Updating strongSwan IPsec configuration..." >&2
kill -s HUP `cat $IPSEC_STARTER_PID`
else
echo "ipsec starter is not running" >&2
echo "ipsec starter is not running" >&2
fi
exit 0
;;
@ -241,7 +270,7 @@ version|--version)
echo "See \`ipsec --copyright' for copyright information."
if [ -f $IPSEC_LIBDIR/distro.txt ]
then
cat $IPSEC_LIBDIR/distro.txt
cat $IPSEC_LIBDIR/distro.txt
fi
exit 0
;;

View File

@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* RCSID $Id: connections.c,v 1.42 2006/04/22 21:59:20 as Exp $
* RCSID $Id: connections.c,v 1.43 2006/04/29 18:16:02 as Exp $
*/
#include <string.h>
@ -4022,7 +4022,7 @@ show_connections_status(bool all, const char *name)
/* sort it! */
qsort(array, count, sizeof(struct connection *), connection_compare_qsort);
for (i=0; i<count; i++)
for (i = 0; i < count; i++)
{
const char *ifn;
char instance[1 + 10 + 1];
@ -4076,7 +4076,7 @@ show_connections_status(bool all, const char *name)
if (c->spd.that.groups != NULL)
{
char buf[BUF_LEN];
format_groups(c->spd.that.groups, buf, BUF_LEN);
whack_log(RC_COMMENT
, "\"%s\"%s: groups: %s"
@ -4097,7 +4097,7 @@ show_connections_status(bool all, const char *name)
, (unsigned long) c->sa_keying_tries);
/* show DPD parameters if defined */
if (c->dpd_action != DPD_ACTION_NONE)
whack_log(RC_COMMENT
, "\"%s\"%s: dpd_action: %s;"
@ -4141,6 +4141,9 @@ show_connections_status(bool all, const char *name)
kernel_alg_show_connection(c, instance);
}
}
if (count > 0)
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
pfree(array);
}

View File

@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* RCSID $Id: kernel.c,v 1.25 2006/04/17 14:58:09 as Exp $
* RCSID $Id: kernel.c,v 1.26 2006/04/29 18:16:02 as Exp $
*/
#include <stddef.h>
@ -934,6 +934,8 @@ show_shunt_status(void)
, ourst, ourport, hist, hisport, sat, bs->transport_proto
, prio, bs->why);
}
if (bare_shunts != NULL)
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
}
/* Setup an IPsec route entry.

View File

@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* RCSID $Id: log.c,v 1.7 2005/07/11 18:33:45 as Exp $
* RCSID $Id: log.c,v 1.8 2006/04/29 18:16:02 as Exp $
*/
#include <stdio.h>
@ -770,13 +770,11 @@ show_status(bool all, const char *name)
show_ifaces_status();
show_myid_status();
show_debug_status();
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
}
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
show_connections_status(all, name);
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
show_states_status(name);
#ifdef KLIPS
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
show_shunt_status();
#endif
}

View File

@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* RCSID $Id: state.c,v 1.12 2006/04/03 15:49:36 as Exp $
* RCSID $Id: state.c,v 1.13 2006/04/29 18:16:02 as Exp $
*/
#include <stdio.h>
@ -902,6 +902,8 @@ show_states_status(const char *name)
if (IS_PHASE1(st->st_state))
show_pending_phase2(st->st_connection->host_pair, st);
}
if (count > 0)
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
/* free the array */
pfree(array);

View File

@ -198,7 +198,8 @@ static struct vid_struct _vid_tab[] = {
/*
* strongSwan
*/
DEC_MD5_VID(STRONGSWAN, "strongSwan 2.7.0")
DEC_MD5_VID(STRONGSWAN, "strongSwan 4.0.0")
DEC_MD5_VID(STRONGSWAN_2_7_0, "strongSwan 2.7.0")
DEC_MD5_VID(STRONGSWAN_2_6_4, "strongSwan 2.6.4")
DEC_MD5_VID(STRONGSWAN_2_6_3, "strongSwan 2.6.3")
DEC_MD5_VID(STRONGSWAN_2_6_2, "strongSwan 2.6.2")

View File

@ -76,6 +76,7 @@ enum known_vendorid {
VID_STRONGSWAN_2_6_2 = 55,
VID_STRONGSWAN_2_6_3 = 56,
VID_STRONGSWAN_2_6_4 = 57,
VID_STRONGSWAN_2_7_0 = 58,
/* 101 - 200 : NAT-Traversal */
VID_NATT_STENBERG_01 =101,

View File

@ -40,6 +40,12 @@ typedef enum {
STATE_INVALID
} starter_state_t;
typedef enum {
KEY_EXCHANGE_IKE,
KEY_EXCHANGE_IKEV1,
KEY_EXCHANGE_IKEV2
} keyexchange_t;
typedef struct starter_end starter_end_t;
struct starter_end {
@ -89,7 +95,7 @@ struct starter_conn {
startup_t startup;
starter_state_t state;
int keyexchange;
keyexchange_t keyexchange;
lset_t policy;
time_t sa_ike_life_seconds;
time_t sa_ipsec_life_seconds;

File diff suppressed because it is too large Load Diff

View File

@ -374,6 +374,9 @@ do
eval HOSTLOGIN=root@\$ip_${host}
ssh $HOSTLOGIN grep pluto /var/log/auth.log \
> $TESTRESULTDIR/${host}.auth.log
echo >> $TESTRESULTDIR/${host}.auth.log
ssh $HOSTLOGIN grep charon /var/log/auth.log \
>> $TESTRESULTDIR/${host}.auth.log
done

View File

@ -128,6 +128,7 @@ echo "export USERCOMPILE=\'-DRANDOM_DEVICE=\\\"/dev/urandom\\\"\'" >> $INSTALLSH
echo "cd /root/${STRONGSWANVERSION}" >> $INSTALLSHELL
echo "make programs" >> $INSTALLSHELL
echo "make install" >> $INSTALLSHELL
echo "ldconfig" >> $INSTALLSHELL
cecho-n " * Compiling $STRONGSWANVERSION within the root file system as chroot.."
chroot $LOOPDIR /bin/bash /install.sh >> $LOGFILE 2>&1

View File

@ -0,0 +1,6 @@
A connection between the subnets behind the gateways <b>moon</b> and <b>sun</b> is set up.
The authentication is based on <b>X.509 certificates</b>. Upon the successful
establishment of the IPsec tunnel, <b>leftfirewall=yes</b> automatically
inserts iptables-based firewall rules that let pass the tunneled traffic.
In order to test both tunnel and firewall, client <b>alice</b> behind gateway <b>moon</b>
pings client <b>bob</b> located behind gateway <b>sun</b>.

View File

@ -0,0 +1,5 @@
moon::ipsec statusall::net-net.*IKE_SA_ESTABLISHED::YES
sun::ipsec statusall::net-net.*IKE_SA_ESTABLISHED::YES
alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_seq=1::YES
sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES

View File

@ -0,0 +1,13 @@
# /etc/ipsec.conf - strongSwan IPsec configuration file
version 2.0 # conforms to second version of ipsec.conf specification
conn net-net
left=192.168.0.1
leftcert=moonCert.pem
leftsubnet=10.1.0.0/16
right=192.168.0.2
rightcert=sunCert.pem
rightsubnet=10.2.0.0/16
keyexchange=ikev2
auto=add

View File

@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIECzCCAvOgAwIBAgIBAjANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJDSDEZ
MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
b290IENBMB4XDTA0MDkxMDExMTU1M1oXDTA5MDkwOTExMTU1M1owRTELMAkGA1UE
BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMTEnN1bi5z
dHJvbmdzd2FuLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOQ8
foB9h5BZ92gA5JkQTJNuoF6FAzoq91Gh7To27/g74p01+SUnsSaBfPmNfGp4avdS
Ewy2dWMA/7uj0Dbe8MEKssNztp0JQubp2s7n8mrrQLGsqB6YAS09l75XDjS3yqTC
AtH1kD4zAl/j/AyeQBuLR4CyJEmC/rqD3/a+pr42CaljuFBgBRpCTUpU4mlslZSe
zv9wu61PwTFxb8VDlBHUd/lwkXThKgU3uEhWRxLahpSldEGmiTTmx30k/XbOMF2n
HObEHt5EY9uWRGGbj81ZRWiNk0dNtbpneUHv/NvdWLc591M8cEGEQdWW2XTVbL2G
N67q8hdzGgIvb7QJPMcCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAwCwYDVR0PBAQD
AgOoMB0GA1UdDgQWBBQ9xLkyCBbyQmRet0vvV1Fg6z5q2DBtBgNVHSMEZjBkgBRd
p91wBlEyfue2bbO15eBg6i5N76FJpEcwRTELMAkGA1UEBhMCQ0gxGTAXBgNVBAoT
EExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMTEnN0cm9uZ1N3YW4gUm9vdCBDQYIB
ADAdBgNVHREEFjAUghJzdW4uc3Ryb25nc3dhbi5vcmcwOQYDVR0fBDIwMDAuoCyg
KoYoaHR0cDovL2NybC5zdHJvbmdzd2FuLm9yZy9zdHJvbmdzd2FuLmNybDANBgkq
hkiG9w0BAQQFAAOCAQEAGQQroiAa0SwwhJprGd7OM+rfBJAGbsa3DPzFCfHX1R7i
ZyDs9aph1DK+IgUa377Ev1U7oB0EldpmOoJJugCjtNLfpW3t1RXBERL/QfpO2+VP
Wt3SfZ0Oq48jiqB1MVLMZRPCICZEQjT4sJ3HYs5ZuucuvoxeMx3rQ4HxUtHtMD3S
5JNMwFFiOXAjyIyrTlb7YuRJTT5hE+Rms8GUQ5Xnt7zKZ7yfoSLFzy0/cLFPdQvE
JA7w8crODCZpDgEKVHVyUWuyt1O46N3ydUfDcnKJoQ9HWHm3xCbDex5MHTnvm1lk
Stx71CGM7TE6VPy028UlrSw0JqEwCVwstei2cMzwgA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,13 @@
# /etc/ipsec.conf - strongSwan IPsec configuration file
version 2.0 # conforms to second version of ipsec.conf specification
conn net-net
left=192.168.0.2
leftcert=sunCert.pem
leftsubnet=10.2.0.0/16
right=192.168.0.1
rightcert=moonCert.pem
rightsubnet=10.1.0.0/16
keyexchange=ikev2
auto=add

View File

@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEDTCCAvWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJDSDEZ
MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
b290IENBMB4XDTA0MDkxMDExMTcyNVoXDTA5MDkwOTExMTcyNVowRjELMAkGA1UE
BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xHDAaBgNVBAMTE21vb24u
c3Ryb25nc3dhbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv
ri4QmsCnG0N7bxqeUZTQhcmZ/iyN4RsmHwFsiOc06xpnZ7Fbx9gzi/OswU6KGL+F
f9PfvOY36bDTZU8V2QaL30RQUXz3JlG+jUyP9zjqlhsvVYS/cImvqgo3uUkQ0YCD
v2SafTlaQfBOaPFElNEP/H2YSiyB6X80IcHsOMYpskVqPY8785FehjF+pxuyRCK+
9HXmd+iWdnC09u4qgKRa3L0IamU3q1/BK/afkHK2IAIN4YgM7GzepHVD0f7Exf9U
esJEeh4hDZwSjcMzdybrY9XBxzGqLGPOF128jr+5weUZiBW+RzeBw/gsK1nSPeuX
Od2lPJjTGj+6V3YK6qibAgMBAAGjggEFMIIBATAJBgNVHRMEAjAAMAsGA1UdDwQE
AwIDqDAdBgNVHQ4EFgQU5eQQh2wqxL6thUlCpt52WDA6n8EwbQYDVR0jBGYwZIAU
XafdcAZRMn7ntm2zteXgYOouTe+hSaRHMEUxCzAJBgNVBAYTAkNIMRkwFwYDVQQK
ExBMaW51eCBzdHJvbmdTd2FuMRswGQYDVQQDExJzdHJvbmdTd2FuIFJvb3QgQ0GC
AQAwHgYDVR0RBBcwFYITbW9vbi5zdHJvbmdzd2FuLm9yZzA5BgNVHR8EMjAwMC6g
LKAqhihodHRwOi8vY3JsLnN0cm9uZ3N3YW4ub3JnL3N0cm9uZ3N3YW4uY3JsMA0G
CSqGSIb3DQEBBAUAA4IBAQAvLykhZnqldrsMcbYB36WzWKk+hOihr5dU3fv8Z4ec
tsa3gzxXSefDCxGoezVJ4QXdpdNxxFn31A+r1gxKyGI5JL6EyWz6Y462zp9lE7nW
EIC4ldJwxAXqzDEMcJphO29hApyU9TWsWDa4kL5AKtLFLwH3/Uv/jAzAy+qXIO8h
wLtB+wcmhSo8OFY9kX/cyhht7eb7yD/r2e3wVBOCRk7jePe4yWhN8NJAKwfrEd1K
iGq15ymdmeomhplHRsLZwA2VsCspUNZ/eXjG21s3nEoxcCOcQUz3Q7q4ZgBTZoCW
kAc6FQ5zxoZrmzNWFqzb06jmUVlt7baGtdjT7rEt+dcp
-----END CERTIFICATE-----

View File

@ -0,0 +1,4 @@
moon::ipsec stop
sun::ipsec stop
moon::rm /etc/ipsec.d/certs/*
sun::rm /etc/ipsec.d/certs/*

View File

@ -0,0 +1,7 @@
moon::echo 1 > /proc/sys/net/ipv4/ip_forward
sun::echo 1 > /proc/sys/net/ipv4/ip_forward
moon::ipsec start
sun::ipsec start
moon::sleep 1
moon::ipsec up net-net
moon::sleep 1

View File

@ -0,0 +1,21 @@
#!/bin/bash
#
# This configuration file provides information on the
# UML instances used for this test
# All UML instances that are required for this test
#
UMLHOSTS="alice moon winnetou sun bob"
# Corresponding block diagram
#
DIAGRAM="a-m-w-s-b.png"
# UML instances on which tcpdump is to be started
#
TCPDUMPHOSTS="sun"
# UML instances on which IPsec is started
# Used for IPsec logging purposes
#
IPSECHOSTS="moon sun"