summaryrefslogtreecommitdiff
path: root/src/pluto
diff options
context:
space:
mode:
Diffstat (limited to 'src/pluto')
-rw-r--r--src/pluto/Makefile.am6
-rw-r--r--src/pluto/Makefile.in20
-rw-r--r--src/pluto/ac.c27
-rw-r--r--src/pluto/alg_info.c3
-rw-r--r--src/pluto/ca.c4
-rw-r--r--src/pluto/connections.c55
-rw-r--r--src/pluto/connections.h1
-rw-r--r--src/pluto/constants.c10
-rw-r--r--src/pluto/constants.h7
-rw-r--r--src/pluto/crypto.c34
-rw-r--r--src/pluto/demux.h1
-rw-r--r--src/pluto/fetch.c11
-rw-r--r--src/pluto/ipsec_doi.c44
-rw-r--r--src/pluto/kernel.c1
-rw-r--r--src/pluto/kernel_alg.c4
-rw-r--r--src/pluto/kernel_netlink.c2
-rw-r--r--src/pluto/lex.c2
-rw-r--r--src/pluto/log.c6
-rw-r--r--src/pluto/modecfg.c69
-rw-r--r--src/pluto/pkcs7.c88
-rw-r--r--src/pluto/plutomain.c15
-rw-r--r--src/pluto/rcv_whack.c46
-rw-r--r--src/pluto/timer.c2
-rw-r--r--src/pluto/vendor.c131
-rw-r--r--src/pluto/vendor.h64
-rw-r--r--src/pluto/whack_attribute.c365
-rw-r--r--src/pluto/whack_attribute.h111
-rw-r--r--src/pluto/x509.c4
28 files changed, 837 insertions, 296 deletions
diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am
index b83e4be33..a264e642e 100644
--- a/src/pluto/Makefile.am
+++ b/src/pluto/Makefile.am
@@ -46,6 +46,7 @@ state.c state.h \
timer.c timer.h \
vendor.c vendor.h \
virtual.c virtual.h \
+whack_attribute.c whack_attribute.h \
xauth.c xauth.h \
x509.c x509.h \
builder.c builder.h \
@@ -53,13 +54,17 @@ rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
_pluto_adns_SOURCES = adns.c adns.h
+plutomain.o : $(top_builddir)/config.status
+
LIBSTRONGSWANDIR=$(top_builddir)/src/libstrongswan
LIBFREESWANDIR=$(top_builddir)/src/libfreeswan
+LIBHYDRADIR=$(top_builddir)/src/libhydra
INCLUDES = \
-I${linux_headers} \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/whack
AM_CFLAGS = \
@@ -75,6 +80,7 @@ AM_CFLAGS = \
pluto_LDADD = \
$(LIBSTRONGSWANDIR)/libstrongswan.la \
$(LIBFREESWANDIR)/libfreeswan.a \
+$(LIBHYDRADIR)/libhydra.la \
-lresolv $(PTHREADLIB) $(DLLIB)
_pluto_adns_LDADD = \
diff --git a/src/pluto/Makefile.in b/src/pluto/Makefile.in
index c93756c44..47be9acf7 100644
--- a/src/pluto/Makefile.in
+++ b/src/pluto/Makefile.in
@@ -94,12 +94,13 @@ am_pluto_OBJECTS = ac.$(OBJEXT) alg_info.$(OBJEXT) ca.$(OBJEXT) \
pkcs7.$(OBJEXT) plutomain.$(OBJEXT) rcv_whack.$(OBJEXT) \
server.$(OBJEXT) smartcard.$(OBJEXT) spdb.$(OBJEXT) \
state.$(OBJEXT) timer.$(OBJEXT) vendor.$(OBJEXT) \
- virtual.$(OBJEXT) xauth.$(OBJEXT) x509.$(OBJEXT) \
- builder.$(OBJEXT)
+ virtual.$(OBJEXT) whack_attribute.$(OBJEXT) xauth.$(OBJEXT) \
+ x509.$(OBJEXT) builder.$(OBJEXT)
pluto_OBJECTS = $(am_pluto_OBJECTS)
pluto_DEPENDENCIES = $(LIBSTRONGSWANDIR)/libstrongswan.la \
- $(LIBFREESWANDIR)/libfreeswan.a $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+ $(LIBFREESWANDIR)/libfreeswan.a $(LIBHYDRADIR)/libhydra.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -263,6 +264,7 @@ ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libdir = @libdir@
libexecdir = @libexecdir@
+libhydra_plugins = @libhydra_plugins@
libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
@@ -339,6 +341,7 @@ state.c state.h \
timer.c timer.h \
vendor.c vendor.h \
virtual.c virtual.h \
+whack_attribute.c whack_attribute.h \
xauth.c xauth.h \
x509.c x509.h \
builder.c builder.h \
@@ -347,10 +350,12 @@ rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
_pluto_adns_SOURCES = adns.c adns.h
LIBSTRONGSWANDIR = $(top_builddir)/src/libstrongswan
LIBFREESWANDIR = $(top_builddir)/src/libfreeswan
+LIBHYDRADIR = $(top_builddir)/src/libhydra
INCLUDES = \
-I${linux_headers} \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/whack
AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \
@@ -362,8 +367,8 @@ AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \
$(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_4) $(am__append_5) $(am__append_7)
pluto_LDADD = $(LIBSTRONGSWANDIR)/libstrongswan.la \
- $(LIBFREESWANDIR)/libfreeswan.a -lresolv $(PTHREADLIB) \
- $(DLLIB) $(am__append_6)
+ $(LIBFREESWANDIR)/libfreeswan.a $(LIBHYDRADIR)/libhydra.la \
+ -lresolv $(PTHREADLIB) $(DLLIB) $(am__append_6)
_pluto_adns_LDADD = \
$(LIBFREESWANDIR)/libfreeswan.a \
-lresolv $(DLLIB)
@@ -501,6 +506,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vendor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virtual.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whack_attribute.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xauth.Po@am__quote@
@@ -826,6 +832,8 @@ uninstall-man: uninstall-man5 uninstall-man8
uninstall-man8
+plutomain.o : $(top_builddir)/config.status
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/src/pluto/ac.c b/src/pluto/ac.c
index d8b16112f..3ee05d213 100644
--- a/src/pluto/ac.c
+++ b/src/pluto/ac.c
@@ -88,16 +88,17 @@ bool ac_verify_cert(certificate_t *cert, bool strict)
cert_t *aacert;
time_t notBefore, valid_until;
- DBG1("holder: '%Y'", subject);
- DBG1("issuer: '%Y'", issuer);
+ DBG1(DBG_LIB, "holder: '%Y'", subject);
+ DBG1(DBG_LIB, "issuer: '%Y'", issuer);
if (!cert->get_validity(cert, NULL, NULL, &valid_until))
{
- DBG1("attribute certificate is invalid (valid from %T to %T)",
+ DBG1(DBG_LIB, "attribute certificate is invalid (valid from %T to %T)",
&notBefore, FALSE, &valid_until, FALSE);
return FALSE;
}
- DBG1("attribute certificate is valid until %T", &valid_until, FALSE);
+ DBG1(DBG_LIB, "attribute certificate is valid until %T", &valid_until,
+ FALSE);
lock_authcert_list("verify_x509acert");
aacert = get_authcert(issuer, authKeyID, X509_AA);
@@ -105,17 +106,17 @@ bool ac_verify_cert(certificate_t *cert, bool strict)
if (aacert == NULL)
{
- DBG1("issuer aacert not found");
+ DBG1(DBG_LIB, "issuer aacert not found");
return FALSE;
}
- DBG2("issuer aacert found");
+ DBG2(DBG_LIB, "issuer aacert found");
if (!cert->issued_by(cert, aacert->cert))
{
- DBG1("attribute certificate signature is invalid");
+ DBG1(DBG_LIB, "attribute certificate signature is invalid");
return FALSE;
}
- DBG1("attribute certificate signature is valid");
+ DBG1(DBG_LIB, "attribute certificate signature is valid");
return verify_x509cert(aacert, strict, &valid_until);
}
@@ -175,8 +176,8 @@ bool match_group_membership(ietf_attributes_t *peer_attributes, char *conn,
}
match = conn_attributes->matches(conn_attributes, peer_attributes);
- DBG1("%s: peer with attributes '%s' is %sa member of the groups '%s'",
- conn, peer_attributes->get_string(peer_attributes),
+ DBG1(DBG_LIB, "%s: peer with attributes '%s' is %sa member of the "
+ "groups '%s'", conn, peer_attributes->get_string(peer_attributes),
match ? "" : "not ", conn_attributes->get_string(conn_attributes));
return match;
@@ -191,7 +192,7 @@ void ac_load_certs(void)
struct stat st;
char *file;
- DBG1("loading attribute certificates from '%s'", A_CERT_PATH);
+ DBG1(DBG_LIB, "loading attribute certificates from '%s'", A_CERT_PATH);
enumerator = enumerator_create_directory(A_CERT_PATH);
if (!enumerator)
@@ -212,7 +213,7 @@ void ac_load_certs(void)
BUILD_FROM_FILE, file, BUILD_END);
if (cert)
{
- DBG1(" loaded attribute certificate from '%s'", file);
+ DBG1(DBG_LIB, " loaded attribute certificate from '%s'", file);
ac_add_cert(cert);
}
}
@@ -266,7 +267,7 @@ void ac_list_certs(bool utc)
whack_log(RC_COMMENT, " hserial: %#B", &holderSerial);
}
- groups = ac->get_groups(ac);
+ groups = ac->get_groups(ac);
if (groups)
{
whack_log(RC_COMMENT, " groups: %s", groups->get_string(groups));
diff --git a/src/pluto/alg_info.c b/src/pluto/alg_info.c
index edecf14c6..32fd46ef4 100644
--- a/src/pluto/alg_info.c
+++ b/src/pluto/alg_info.c
@@ -139,6 +139,7 @@ static bool is_authenticated_encryption(int ealg_id)
case ESP_AES_GCM_8:
case ESP_AES_GCM_12:
case ESP_AES_GCM_16:
+ case ESP_AES_GMAC:
return TRUE;
}
return FALSE;
@@ -474,7 +475,7 @@ struct alg_info_ike *alg_info_ike_create_from_str(char *alg_str)
if (alg_info_parse_str((struct alg_info *)alg_info_ike, alg_str) == SUCCESS)
{
- alg_info_ike->ref_cnt = 1;
+ alg_info_ike->ref_cnt = 1;
return alg_info_ike;
}
else
diff --git a/src/pluto/ca.c b/src/pluto/ca.c
index e25e7f6f5..2654774fa 100644
--- a/src/pluto/ca.c
+++ b/src/pluto/ca.c
@@ -293,12 +293,12 @@ void load_authcerts(char *type, char *path, x509_flag_t auth_flags)
struct stat st;
char *file;
- DBG1("loading %s certificates from '%s'", type, path);
+ DBG1(DBG_LIB, "loading %s certificates from '%s'", type, path);
enumerator = enumerator_create_directory(path);
if (!enumerator)
{
- DBG1(" reading directory '%s' failed");
+ DBG1(DBG_LIB, " reading directory '%s' failed", path);
return;
}
diff --git a/src/pluto/connections.c b/src/pluto/connections.c
index fece34eec..dd193042a 100644
--- a/src/pluto/connections.c
+++ b/src/pluto/connections.c
@@ -30,6 +30,7 @@
#include <freeswan.h>
#include "kameipsec.h"
+#include <hydra.h>
#include <credentials/certificates/ac.h>
#include <credentials/keys/private_key.h>
@@ -61,6 +62,7 @@
#include "kernel_alg.h"
#include "nat_traversal.h"
#include "virtual.h"
+#include "whack_attribute.h"
static void flush_pending_by_connection(connection_t *c); /* forward */
@@ -104,7 +106,7 @@ bool his_id_was_instantiated(const connection_t *c)
{
identification_t *host;
bool equal;
-
+
host = identification_create_from_sockaddr((sockaddr_t*)&c->spd.that.host_addr);
equal = host->equals(host, c->spd.that.id);
host->destroy(host);
@@ -113,7 +115,7 @@ bool his_id_was_instantiated(const connection_t *c)
else
{
return TRUE;
- }
+ }
}
/**
@@ -369,11 +371,16 @@ void delete_connection(connection_t *c, bool relations)
host_t *vip;
vip = host_create_from_sockaddr((sockaddr_t*)&c->spd.that.host_srcip);
- lib->attributes->release_address(lib->attributes, c->spd.that.pool,
- vip, c->spd.that.id);
+ hydra->attributes->release_address(hydra->attributes, c->spd.that.pool,
+ vip, c->spd.that.id);
vip->destroy(vip);
}
+ if (c->kind != CK_GOING_AWAY)
+ {
+ whack_attr->del_pool(whack_attr, c->name);
+ }
+
/* free internal data */
#ifdef DEBUG
cur_debugging = old_cur_debugging;
@@ -683,7 +690,7 @@ size_t format_end(char *buf, size_t buf_len, const struct end *this,
}
/* id */
- snprintf(host_id, sizeof(host_id), "[%Y]", this->id);
+ snprintf(host_id, sizeof(host_id), "[%Y]", this->id);
/* [---hop] */
hop[0] = '\0';
@@ -769,7 +776,7 @@ static void load_end_certificate(char *filename, struct end *dst)
cert_t *cert = NULL;
certificate_t *certificate;
bool cached_cert = FALSE;
-
+
/* initialize end certificate */
dst->cert = NULL;
@@ -853,10 +860,11 @@ static void load_end_certificate(char *filename, struct end *dst)
}
static bool extract_end(struct end *dst, const whack_end_t *src,
- const char *which)
+ const char *name, bool is_left)
{
bool same_ca = FALSE;
+ dst->is_left = is_left;
dst->id = identification_create_from_string(src->id);
dst->ca = NULL;
@@ -1117,15 +1125,14 @@ void add_connection(const whack_message_t *wm)
c->tunnel_addr_family = wm->tunnel_addr_family;
c->requested_ca = NULL;
+ same_leftca = extract_end(&c->spd.this, &wm->left, wm->name, TRUE);
+ same_rightca = extract_end(&c->spd.that, &wm->right, wm->name, FALSE);
- same_leftca = extract_end(&c->spd.this, &wm->left, "left");
- same_rightca = extract_end(&c->spd.that, &wm->right, "right");
-
- if (same_rightca)
+ if (same_rightca && c->spd.this.ca)
{
c->spd.that.ca = c->spd.this.ca->clone(c->spd.this.ca);
}
- else if (same_leftca)
+ else if (same_leftca && c->spd.that.ca)
{
c->spd.this.ca = c->spd.that.ca->clone(c->spd.that.ca);
}
@@ -1196,6 +1203,17 @@ void add_connection(const whack_message_t *wm)
(void)orient(c);
+ /* if rightsourceip defines a subnet then create an in-memory pool */
+ if (whack_attr->add_pool(whack_attr, c->name,
+ c->spd.this.is_left ? &wm->right : &wm->left))
+ {
+ c->spd.that.pool = clone_str(c->name);
+ c->spd.that.modecfg = TRUE;
+ c->spd.that.has_client = FALSE;
+ /* reset the host_srcip so that it gets assigned in modecfg */
+ anyaddr(AF_INET, &c->spd.that.host_srcip);
+ }
+
if (c->ikev1)
{
connect_to_host_pair(c);
@@ -1794,7 +1812,7 @@ connection_t *build_outgoing_opportunistic_connection(struct gw_info *gw,
else
{
chunk_t encoding = gw->gw_id->get_encoding(gw->gw_id);
- id_type_t type = gw->gw_id->get_type(gw->gw_id);
+ id_type_t type = gw->gw_id->get_type(gw->gw_id);
ip_address ip_addr;
initaddr(encoding.ptr, encoding.len,
@@ -2758,7 +2776,7 @@ static void initiate_opportunistic_body(struct find_oppo_bundle *b,
addrtot(&b->peer_client, 0, pcb, sizeof(pcb));
loglog(RC_OPPOFAILURE,
"no suitable connection for opportunism "
- "between %s and %s with %Y as peer",
+ "between %s and %s with %Y as peer",
ocb, pcb, ac->gateways_from_dns->gw_id);
#ifdef KLIPS
@@ -3379,7 +3397,7 @@ connection_t *refine_host_connection(const struct state *st,
id_match_t match_level = peer_id->matches(peer_id, d->spd.that.id);
bool matching_id = match_level > ID_MATCH_NONE;
-
+
bool matching_auth = (d->policy & auth_policy) != LEMPTY;
bool matching_trust = trusted_ca(peer_ca
@@ -3580,7 +3598,7 @@ static connection_t *fc_try(const connection_t *c, struct host_pair *hp,
policy_prio_t best_prio = BOTTOM_PRIO;
id_match_t match_level;
int pathlen;
-
+
const bool peer_net_is_host = subnetisaddr(peer_net, &c->spd.that.host_addr);
@@ -3675,7 +3693,8 @@ static connection_t *fc_try(const connection_t *c, struct host_pair *hp,
}
else
{
- if (!peer_net_is_host)
+ if (!peer_net_is_host && !(sr->that.modecfg && c->spd.that.modecfg &&
+ subnetisaddr(peer_net, &c->spd.that.host_srcip)))
{
continue;
}
@@ -3843,7 +3862,7 @@ void get_peer_ca_and_groups(connection_t *c,
if (cert && ac_verify_cert(cert, strict_crl_policy))
{
ac_t *ac = (ac_t*)cert;
-
+
*peer_attributes = ac->get_groups(ac);
}
else
diff --git a/src/pluto/connections.h b/src/pluto/connections.h
index ee2e00da6..66aea1541 100644
--- a/src/pluto/connections.h
+++ b/src/pluto/connections.h
@@ -137,6 +137,7 @@ struct end {
host_srcip;
ip_subnet client;
+ bool is_left;
bool key_from_DNS_on_demand;
bool has_client;
bool has_client_wildcard;
diff --git a/src/pluto/constants.c b/src/pluto/constants.c
index 6f991fd69..63a37009b 100644
--- a/src/pluto/constants.c
+++ b/src/pluto/constants.c
@@ -392,7 +392,8 @@ static const char *const esp_transform_name[] = {
"AES_GCM_12",
"AES_GCM_16",
"SEED_CBC",
- "CAMELLIA_CBC"
+ "CAMELLIA_CBC",
+ "AES_GMAC"
};
static const char *const esp_transform_name_high[] = {
@@ -404,7 +405,7 @@ enum_names esp_transform_names_high =
{ ESP_SERPENT, ESP_TWOFISH, esp_transform_name_high, NULL };
enum_names esp_transform_names =
- { ESP_DES_IV64, ESP_CAMELLIA, esp_transform_name, &esp_transform_names_high };
+ { ESP_DES_IV64, ESP_AES_GMAC, esp_transform_name, &esp_transform_names_high };
/* IPCOMP transform values */
@@ -919,12 +920,15 @@ static const char *const oakley_group_name_rfc4753[] = {
};
static const char *const oakley_group_name_rfc5114[] = {
+ "MODP_1024_160",
+ "MODP_2048_224",
+ "MODP_2048_256",
"ECP_192",
"ECP_224"
};
enum_names oakley_group_names_rfc5114 =
- { ECP_192_BIT, ECP_224_BIT,
+ { MODP_1024_160, ECP_224_BIT,
oakley_group_name_rfc5114, NULL };
enum_names oakley_group_names_rfc4753 =
diff --git a/src/pluto/constants.h b/src/pluto/constants.h
index 8c574ebc5..e9567c07a 100644
--- a/src/pluto/constants.h
+++ b/src/pluto/constants.h
@@ -125,10 +125,10 @@ extern const char sparse_end[];
#define MAX_DIGEST_LEN HASH_SIZE_SHA512
/* RFC 2404 "HMAC-SHA-1-96" section 3 */
-#define HMAC_SHA1_KEY_LEN HASH_SIZE_SHA1
+#define HMAC_SHA1_KEY_LEN HASH_SIZE_SHA1
/* RFC 2403 "HMAC-MD5-96" section 3 */
-#define HMAC_MD5_KEY_LEN HASH_SIZE_MD5
+#define HMAC_MD5_KEY_LEN HASH_SIZE_MD5
#define IKE_UDP_PORT 500
@@ -150,7 +150,7 @@ enum ipsec_authentication_algo {
AH_AES_128_GMAC = 11,
AH_AES_192_GMAC = 12,
AH_AES_256_GMAC = 13,
- AH_SHA2_256_96 = 252
+ AH_SHA2_256_96 = 252
};
extern enum_names ah_transform_names;
@@ -184,6 +184,7 @@ enum ipsec_cipher_algo {
ESP_AES_GCM_16 = 20,
ESP_SEED_CBC = 21,
ESP_CAMELLIA = 22,
+ ESP_AES_GMAC = 23,
ESP_SERPENT = 252,
ESP_TWOFISH = 253
};
diff --git a/src/pluto/crypto.c b/src/pluto/crypto.c
index 2113cecbc..a62e7632d 100644
--- a/src/pluto/crypto.c
+++ b/src/pluto/crypto.c
@@ -237,6 +237,27 @@ static struct dh_desc dh_desc_ecp_521 = {
ke_size: 2*528 / BITS_PER_BYTE
};
+static struct dh_desc dh_desc_modp_1024_160 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_1024_160,
+ algo_next: NULL,
+ ke_size: 1024 / BITS_PER_BYTE
+};
+
+static struct dh_desc dh_desc_modp_2048_224 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_2048_224,
+ algo_next: NULL,
+ ke_size: 2048 / BITS_PER_BYTE
+};
+
+static struct dh_desc dh_desc_modp_2048_256 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_2048_256,
+ algo_next: NULL,
+ ke_size: 2048 / BITS_PER_BYTE
+};
+
static struct dh_desc dh_desc_ecp_192 = {
algo_type: IKE_ALG_DH_GROUP,
algo_id: ECP_192_BIT,
@@ -370,6 +391,15 @@ bool init_crypto(void)
case ECP_521_BIT:
desc = &dh_desc_ecp_521;
break;
+ case MODP_1024_160:
+ desc = &dh_desc_modp_1024_160;
+ break;
+ case MODP_2048_224:
+ desc = &dh_desc_modp_2048_224;
+ break;
+ case MODP_2048_256:
+ desc = &dh_desc_modp_2048_256;
+ break;
case ECP_192_BIT:
desc = &dh_desc_ecp_192;
break;
@@ -580,9 +610,11 @@ int esp_from_encryption_algorithm(encryption_algorithm_t alg)
return ESP_AES_GCM_16;
case ENCR_CAMELLIA_CBC:
return ESP_CAMELLIA;
+ case ENCR_NULL_AUTH_AES_GMAC:
+ return ESP_AES_GMAC;
case ENCR_SERPENT_CBC:
return ESP_SERPENT;
- case ENCR_TWOFISH_CBC:
+ case ENCR_TWOFISH_CBC:
return ESP_TWOFISH;
default:
return 0;
diff --git a/src/pluto/demux.h b/src/pluto/demux.h
index 4faf6e532..2161bbd02 100644
--- a/src/pluto/demux.h
+++ b/src/pluto/demux.h
@@ -61,6 +61,7 @@ struct msg_digest {
notification_t note; /* reason for failure */
bool dpd; /* peer supports RFC 3706 DPD */
bool openpgp; /* peer supports OpenPGP certificates */
+ bool ms_nt5; /* peer is a windows 2000+ host */
# define PAYLIMIT 40
struct payload_digest
diff --git a/src/pluto/fetch.c b/src/pluto/fetch.c
index 6172165bd..1d2d13371 100644
--- a/src/pluto/fetch.c
+++ b/src/pluto/fetch.c
@@ -266,10 +266,10 @@ x509crl_t* fetch_crl(char *url)
x509crl_t *crl;
chunk_t blob;
- DBG1(" fetching crl from '%s' ...", url);
+ DBG1(DBG_LIB, " fetching crl from '%s' ...", url);
if (lib->fetcher->fetch(lib->fetcher, url, &blob, FETCH_END) != SUCCESS)
{
- DBG1("crl fetching failed");
+ DBG1(DBG_LIB, "crl fetching failed");
return FALSE;
}
crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL,
@@ -277,7 +277,8 @@ x509crl_t* fetch_crl(char *url)
free(blob.ptr);
if (!crl)
{
- DBG1("crl fetched successfully but data coded in unknown format");
+ DBG1(DBG_LIB, "crl fetched successfully but data coded in unknown "
+ "format");
}
return crl;
}
@@ -395,7 +396,7 @@ static void fetch_ocsp_status(ocsp_location_t* location)
chunk_t request = build_ocsp_request(location);
chunk_t response = chunk_empty;
- DBG1(" requesting ocsp status from '%s' ...", location->uri);
+ DBG1(DBG_LIB, " requesting ocsp status from '%s' ...", location->uri);
if (lib->fetcher->fetch(lib->fetcher, location->uri, &response,
FETCH_REQUEST_DATA, request,
FETCH_REQUEST_TYPE, "application/ocsp-request",
@@ -405,7 +406,7 @@ static void fetch_ocsp_status(ocsp_location_t* location)
}
else
{
- DBG1("ocsp request to %s failed", location->uri);
+ DBG1(DBG_LIB, "ocsp request to %s failed", location->uri);
}
free(request.ptr);
diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c
index 1f8917d79..34c42e294 100644
--- a/src/pluto/ipsec_doi.c
+++ b/src/pluto/ipsec_doi.c
@@ -702,6 +702,8 @@ void accept_delete(struct state *st, struct msg_digest *md,
struct payload_digest *p)
{
struct isakmp_delete *d = &(p->payload.delete);
+ identification_t *this_id, *that_id;
+ ip_address peer_addr;
size_t sizespi;
int i;
@@ -759,6 +761,15 @@ void accept_delete(struct state *st, struct msg_digest *md,
return;
}
+ if (d->isad_protoid == PROTO_ISAKMP)
+ {
+ struct end *this = &st->st_connection->spd.this;
+ struct end *that = &st->st_connection->spd.that;
+ this_id = this->id->clone(this->id);
+ that_id = that->id->clone(that->id);
+ peer_addr = st->st_connection->spd.that.host_addr;
+ }
+
for (i = 0; i < d->isad_nospi; i++)
{
u_char *spi = p->pbs.cur + (i * sizespi);
@@ -770,7 +781,7 @@ void accept_delete(struct state *st, struct msg_digest *md,
*/
struct state *dst = find_state(spi /*iCookie*/
, spi+COOKIE_SIZE /*rCookie*/
- , &st->st_connection->spd.that.host_addr
+ , &peer_addr
, MAINMODE_MSGID);
if (dst == NULL)
@@ -778,7 +789,8 @@ void accept_delete(struct state *st, struct msg_digest *md,
loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
"ISAKMP SA not found (maybe expired)");
}
- else if (!same_peer_ids(st->st_connection, dst->st_connection, NULL))
+ else if (! this_id->equals(this_id, dst->st_connection->spd.this.id) ||
+ ! that_id->equals(that_id, dst->st_connection->spd.that.id))
{
/* we've not authenticated the relevant identities */
loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
@@ -876,6 +888,12 @@ void accept_delete(struct state *st, struct msg_digest *md,
}
}
}
+
+ if (d->isad_protoid == PROTO_ISAKMP)
+ {
+ this_id->destroy(this_id);
+ that_id->destroy(that_id);
+ }
}
/* The whole message must be a multiple of 4 octets.
@@ -2753,6 +2771,7 @@ static void compute_proto_keymat(struct state *st, u_int8_t protoid,
case ESP_AES_GCM_12:
case ESP_AES_GCM_16:
case ESP_AES_CTR:
+ case ESP_AES_GMAC:
needed_len += 4;
break;
default:
@@ -3620,7 +3639,7 @@ stf_status main_inR2_outI3(struct msg_digest *md)
if (send_cert)
{
bool success;
- chunk_t cert_encoding;
+ chunk_t cert_encoding;
pb_stream cert_pbs;
struct isakmp_cert cert_hd;
@@ -3634,7 +3653,7 @@ stf_status main_inR2_outI3(struct msg_digest *md)
cert_encoding = mycert->cert->get_encoding(mycert->cert);
success = out_chunk(cert_encoding, &cert_pbs, "CERT");
free(cert_encoding.ptr);
- if (!success)
+ if (!success)
{
return STF_INTERNAL_ERROR;
}
@@ -4076,7 +4095,7 @@ main_inI3_outR3_tail(struct msg_digest *md
success = out_chunk(cert_encoding, &cert_pbs, "CERT");
free(cert_encoding.ptr);
if (!success)
- {
+ {
return STF_INTERNAL_ERROR;
}
close_output_pbs(&cert_pbs);
@@ -4871,6 +4890,21 @@ static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b,
*/
p = rw_instantiate(p, &c->spd.that.host_addr, md->sender_port
, his_net, c->spd.that.id);
+
+ /* inherit any virtual IP assigned by a Mode Config exchange */
+ if (p->spd.that.modecfg && c->spd.that.modecfg &&
+ subnetisaddr(his_net, &c->spd.that.host_srcip))
+ {
+ char srcip[ADDRTOT_BUF];
+
+ DBG(DBG_CONTROL,
+ addrtot(&c->spd.that.host_srcip, 0, srcip, sizeof(srcip));
+ DBG_log("inheriting virtual IP source address %s from ModeCfg", srcip)
+ )
+ p->spd.that.host_srcip = c->spd.that.host_srcip;
+ p->spd.that.client = c->spd.that.client;
+ p->spd.that.has_client = TRUE;
+ }
}
}
#ifdef DEBUG
diff --git a/src/pluto/kernel.c b/src/pluto/kernel.c
index fe4655d3f..ee22fb55e 100644
--- a/src/pluto/kernel.c
+++ b/src/pluto/kernel.c
@@ -1993,6 +1993,7 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
case ESP_AES_GCM_12:
case ESP_AES_GCM_16:
case ESP_AES_CTR:
+ case ESP_AES_GMAC:
key_len += 4;
break;
default:
diff --git a/src/pluto/kernel_alg.c b/src/pluto/kernel_alg.c
index bf67315e6..7c2855edc 100644
--- a/src/pluto/kernel_alg.c
+++ b/src/pluto/kernel_alg.c
@@ -395,6 +395,10 @@ void kernel_alg_register_pfkey(const struct sadb_msg *msg_buf, int buflen)
kernel_alg_add(satype, supp_exttype, &alg);
}
}
+
+ /* also register AES_GMAC */
+ alg.sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC;
+ kernel_alg_add(satype, supp_exttype, &alg);
}
/* if SHA2_256 is registered then also register SHA2_256_96 */
if (satype == SADB_SATYPE_ESP &&
diff --git a/src/pluto/kernel_netlink.c b/src/pluto/kernel_netlink.c
index 289714b50..75d0c98d3 100644
--- a/src/pluto/kernel_netlink.c
+++ b/src/pluto/kernel_netlink.c
@@ -112,6 +112,7 @@ static sparse_names ealg_list = {
{ SADB_X_EALG_AES_GCM_ICV8, "rfc4106(gcm(aes))" },
{ SADB_X_EALG_AES_GCM_ICV12, "rfc4106(gcm(aes))" },
{ SADB_X_EALG_AES_GCM_ICV16, "rfc4106(gcm(aes))" },
+ { SADB_X_EALG_NULL_AES_GMAC, "rfc4543(gcm(aes))" },
{ SADB_X_EALG_CAMELLIACBC, "cbc(camellia)" },
{ SADB_X_EALG_SERPENTCBC, "serpent" },
{ SADB_X_EALG_TWOFISHCBC, "twofish" },
@@ -687,6 +688,7 @@ static bool netlink_add_sa(const struct kernel_sa *sa, bool replace)
break;
case SADB_X_EALG_AES_CCM_ICV16:
case SADB_X_EALG_AES_GCM_ICV16:
+ case SADB_X_EALG_NULL_AES_GMAC:
icv_size += 32;
/* FALL */
case SADB_X_EALG_AES_CCM_ICV12:
diff --git a/src/pluto/lex.c b/src/pluto/lex.c
index f48d24a54..d5ebdaba9 100644
--- a/src/pluto/lex.c
+++ b/src/pluto/lex.c
@@ -205,7 +205,7 @@ flushline(const char *m)
{
if (m != NULL)
loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s", flp->filename, flp->lino, m);
- do ; while (shift());
+ do {} while (shift());
return FALSE;
}
}
diff --git a/src/pluto/log.c b/src/pluto/log.c
index 2f3536ff3..444ac2220 100644
--- a/src/pluto/log.c
+++ b/src/pluto/log.c
@@ -40,7 +40,8 @@
#include "connections.h"
#include "myid.h"
#include "kernel.h"
-#include "whack.h" /* needs connections.h */
+#include "whack.h"
+#include "whack_attribute.h"
#include "timer.h"
/* close one per-peer log */
@@ -85,7 +86,7 @@ u_int16_t cur_from_port; /* host order */
/**
* pluto dbg function for libstrongswan
*/
-static void pluto_dbg(int level, char *fmt, ...)
+static void pluto_dbg(debug_t group, level_t level, char *fmt, ...)
{
int priority = LOG_INFO;
int debug_level;
@@ -856,6 +857,7 @@ void show_status(bool all, const char *name)
show_myid_status();
show_loaded_plugins();
show_debug_status();
+ show_pools(name);
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
}
show_connections_status(all, name);
diff --git a/src/pluto/modecfg.c b/src/pluto/modecfg.c
index 03ec7f41f..0c4f2bd6b 100644
--- a/src/pluto/modecfg.c
+++ b/src/pluto/modecfg.c
@@ -26,6 +26,7 @@
#include <freeswan.h>
#include <library.h>
+#include <hydra.h>
#include <attributes/attributes.h>
#include <crypto/prfs/prf.h>
@@ -119,7 +120,7 @@ static void init_internal_addr(internal_addr_t *ia)
static void get_internal_addr(connection_t *c, host_t *requested_vip,
internal_addr_t *ia)
{
- int i, dns_idx = 0, nbns_idx = 0;
+ int dns_idx = 0, nbns_idx = 0;
enumerator_t *enumerator;
configuration_attribute_type_t type;
chunk_t value;
@@ -129,13 +130,13 @@ static void get_internal_addr(connection_t *c, host_t *requested_vip,
{
if (c->spd.that.pool)
{
- vip = lib->attributes->acquire_address(lib->attributes,
+ vip = hydra->attributes->acquire_address(hydra->attributes,
c->spd.that.pool, c->spd.that.id,
requested_vip);
if (vip)
{
chunk_t addr = vip->get_address(vip);
-
+
plog("assigning virtual IP %H to peer", vip);
initaddr(addr.ptr, addr.len, vip->get_family(vip), &ia->ipaddr);
@@ -150,7 +151,7 @@ static void get_internal_addr(connection_t *c, host_t *requested_vip,
{
ia->ipaddr = c->spd.that.host_srcip;
vip = host_create_from_sockaddr((sockaddr_t*)&ia->ipaddr);
- plog("assigning virtual IP %H to peer", vip);
+ plog("assigning virtual IP %H to peer", vip);
}
if (!isanyaddr(&ia->ipaddr)) /* We got an IP address, send it */
@@ -164,67 +165,15 @@ static void get_internal_addr(connection_t *c, host_t *requested_vip,
| LELEM(INTERNAL_IP4_NETMASK);
}
- /* assign DNS servers from strongswan.conf */
- for (i = 1; i <= DNS_SERVER_MAX; i++)
- {
- char dns_key[16], *dns_str;
-
- snprintf(dns_key, sizeof(dns_key), "pluto.dns%d", i);
- dns_str = lib->settings->get_str(lib->settings, dns_key, NULL);
- if (dns_str)
- {
- err_t ugh;
- sa_family_t family = strchr(dns_str, ':') ? AF_INET6 : AF_INET;
-
- ugh = ttoaddr(dns_str, 0, family, &ia->dns[dns_idx]);
- if (ugh)
- {
- plog("error in DNS server address: %s", ugh);
- continue;
- }
- plog("assigning DNS server %s to peer", dns_str);
-
- /* differentiate between IP4 and IP6 in modecfg_build_msg() */
- ia->attr_set |= LELEM(INTERNAL_IP4_DNS);
- dns_idx++;
- }
- }
-
- /* assign NBNS servers from strongswan.conf */
- for (i = 1; i <= NBNS_SERVER_MAX; i++)
- {
- char nbns_key[16], *nbns_str;
-
- snprintf(nbns_key, sizeof(nbns_key), "pluto.nbns%d", i);
- nbns_str = lib->settings->get_str(lib->settings, nbns_key, NULL);
- if (nbns_str)
- {
- err_t ugh;
- sa_family_t family = strchr(nbns_str, ':') ? AF_INET6 : AF_INET;
-
- ugh = ttoaddr(nbns_str, 0, family, &ia->nbns[nbns_idx]);
- if (ugh)
- {
- plog("error in NBNS server address: %s", ugh);
- continue;
- }
- plog("assigning NBNS server %s to peer", nbns_str);
-
- /* differentiate between IP4 and IP6 in modecfg_build_msg() */
- ia->attr_set |= LELEM(INTERNAL_IP4_NBNS);
- nbns_idx++;
- }
- }
-
/* assign attributes from registered providers */
- enumerator = lib->attributes->create_responder_enumerator(lib->attributes,
+ enumerator = hydra->attributes->create_responder_enumerator(hydra->attributes,
c->spd.that.id, vip);
while (enumerator->enumerate(enumerator, &type, &value))
{
err_t ugh;
host_t *server;
sa_family_t family = AF_INET;
-
+
switch (type)
{
case INTERNAL_IP6_DNS:
@@ -257,7 +206,7 @@ static void get_internal_addr(connection_t *c, host_t *requested_vip,
/* fallthrough */
case INTERNAL_IP4_NBNS:
if (nbns_idx >= NBNS_SERVER_MAX)
- {
+ {
plog("exceeded the maximum number of %d NBNS servers",
NBNS_SERVER_MAX);
break;
@@ -279,7 +228,7 @@ static void get_internal_addr(connection_t *c, host_t *requested_vip,
default:
break;
- }
+ }
}
enumerator->destroy(enumerator);
DESTROY_IF(vip);
diff --git a/src/pluto/pkcs7.c b/src/pluto/pkcs7.c
index 733dd2623..b24ef1a8c 100644
--- a/src/pluto/pkcs7.c
+++ b/src/pluto/pkcs7.c
@@ -146,7 +146,7 @@ bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0, contentInfo_t *cInfo)
if (cInfo->type < OID_PKCS7_DATA
|| cInfo->type > OID_PKCS7_ENCRYPTED_DATA)
{
- DBG1("unknown pkcs7 content type");
+ DBG1(DBG_LIB, "unknown pkcs7 content type");
goto end;
}
}
@@ -187,7 +187,7 @@ bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
}
if (cInfo.type != OID_PKCS7_SIGNED_DATA)
{
- DBG1("pkcs7 content type is not signedData");
+ DBG1(DBG_LIB, "pkcs7 content type is not signedData");
return FALSE;
}
@@ -202,7 +202,7 @@ bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
{
case PKCS7_SIGNED_VERSION:
version = object.len ? (int)*object.ptr : 0;
- DBG2(" v%d", version);
+ DBG2(DBG_LIB, " v%d", version);
break;
case PKCS7_DIGEST_ALG:
digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
@@ -217,7 +217,7 @@ bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
{
certificate_t *cert;
- DBG2(" parsing pkcs7-wrapped certificate");
+ DBG2(DBG_LIB, " parsing pkcs7-wrapped certificate");
cert = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509,
BUILD_BLOB_ASN1_DER, object,
@@ -230,17 +230,17 @@ bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
break;
case PKCS7_SIGNER_INFO:
signerInfos++;
- DBG2(" signer #%d", signerInfos);
+ DBG2(DBG_LIB, " signer #%d", signerInfos);
break;
case PKCS7_SIGNER_INFO_VERSION:
version = object.len ? (int)*object.ptr : 0;
- DBG2(" v%d", version);
+ DBG2(DBG_LIB, " v%d", version);
break;
case PKCS7_SIGNED_ISSUER:
{
identification_t *issuer = identification_create_from_encoding(
ID_DER_ASN1_DN, object);
- DBG2(" \"%Y\"", issuer);
+ DBG2(DBG_LIB, " \"%Y\"", issuer);
issuer->destroy(issuer);
break;
}
@@ -277,27 +277,27 @@ bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
scheme = signature_scheme_from_oid(digest_alg);
if (scheme == SIGN_UNKNOWN)
{
- DBG1("unsupported signature scheme");
+ DBG1(DBG_LIB, "unsupported signature scheme");
return FALSE;
}
if (signerInfos == 0)
{
- DBG1("no signerInfo object found");
+ DBG1(DBG_LIB, "no signerInfo object found");
return FALSE;
}
else if (signerInfos > 1)
{
- DBG1("more than one signerInfo object found");
+ DBG1(DBG_LIB, "more than one signerInfo object found");
return FALSE;
}
if (attributes->ptr == NULL)
{
- DBG1("no authenticatedAttributes object found");
+ DBG1(DBG_LIB, "no authenticatedAttributes object found");
return FALSE;
}
if (enc_alg != OID_RSA_ENCRYPTION)
{
- DBG1("only RSA digest encryption supported");
+ DBG1(DBG_LIB, "only RSA digest encryption supported");
return FALSE;
}
@@ -305,16 +305,16 @@ bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
key = cacert->get_public_key(cacert);
if (key == NULL)
{
- DBG1("no public key found in CA certificate");
+ DBG1(DBG_LIB, "no public key found in CA certificate");
return FALSE;
}
if (key->verify(key, scheme, *attributes, encrypted_digest))
{
- DBG2("signature is valid");
+ DBG2(DBG_LIB, "signature is valid");
}
else
{
- DBG1("invalid signature");
+ DBG1(DBG_LIB, "invalid signature");
success = FALSE;
}
key->destroy(key);
@@ -352,7 +352,7 @@ bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
}
if (cInfo.type != OID_PKCS7_ENVELOPED_DATA)
{
- DBG1("pkcs7 content type is not envelopedData");
+ DBG1(DBG_LIB, "pkcs7 content type is not envelopedData");
goto failed;
}
@@ -367,19 +367,19 @@ bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
{
case PKCS7_ENVELOPED_VERSION:
version = object.len ? (int)*object.ptr : 0;
- DBG2(" v%d", version);
+ DBG2(DBG_LIB, " v%d", version);
if (version != 0)
{
- DBG1("envelopedData version is not 0");
+ DBG1(DBG_LIB, "envelopedData version is not 0");
goto end;
}
break;
case PKCS7_RECIPIENT_INFO_VERSION:
version = object.len ? (int)*object.ptr : 0;
- DBG2(" v%d", version);
+ DBG2(DBG_LIB, " v%d", version);
if (version != 0)
{
- DBG1("recipient info version is not 0");
+ DBG1(DBG_LIB, "recipient info version is not 0");
goto end;
}
break;
@@ -387,14 +387,14 @@ bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
{
identification_t *issuer = identification_create_from_encoding(
ID_DER_ASN1_DN, object);
- DBG2(" \"%Y\"", issuer);
+ DBG2(DBG_LIB, " \"%Y\"", issuer);
issuer->destroy(issuer);
break;
}
case PKCS7_SERIAL_NUMBER:
if (!chunk_equals(serialNumber, object))
{
- DBG1("serial numbers do not match");
+ DBG1(DBG_LIB, "serial numbers do not match");
goto end;
}
break;
@@ -402,22 +402,22 @@ bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
if (enc_alg != OID_RSA_ENCRYPTION)
{
- DBG1("only rsa encryption supported");
+ DBG1(DBG_LIB, "only rsa encryption supported");
goto end;
}
break;
case PKCS7_ENCRYPTED_KEY:
if (!key->decrypt(key, object, &symmetric_key))
{
- DBG1("symmetric key could not be decrypted with rsa");
+ DBG1(DBG_LIB, "symmetric key could not be decrypted with rsa");
goto end;
}
- DBG4("symmetric key %B", &symmetric_key);
+ DBG4(DBG_LIB, "symmetric key %B", &symmetric_key);
break;
case PKCS7_CONTENT_TYPE:
if (asn1_known_oid(object) != OID_PKCS7_DATA)
{
- DBG1("encrypted content not of type pkcs7 data");
+ DBG1(DBG_LIB, "encrypted content not of type pkcs7 data");
goto end;
}
break;
@@ -426,12 +426,12 @@ bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
if (content_enc_alg == OID_UNKNOWN)
{
- DBG1("unknown content encryption algorithm");
+ DBG1(DBG_LIB, "unknown content encryption algorithm");
goto end;
}
if (!asn1_parse_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
{
- DBG1("IV could not be parsed");
+ DBG1(DBG_LIB, "IV could not be parsed");
goto end;
}
break;
@@ -459,28 +459,28 @@ end:
alg = encryption_algorithm_from_oid(content_enc_alg, &key_size);
if (alg == ENCR_UNDEFINED)
{
- DBG1("unsupported content encryption algorithm");
+ DBG1(DBG_LIB, "unsupported content encryption algorithm");
goto failed;
}
crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
if (crypter == NULL)
{
- DBG1("crypter %N not available", encryption_algorithm_names, alg);
+ DBG1(DBG_LIB, "crypter %N not available", encryption_algorithm_names, alg);
goto failed;
}
if (symmetric_key.len != crypter->get_key_size(crypter))
{
- DBG1("symmetric key length %d is wrong", symmetric_key.len);
+ DBG1(DBG_LIB, "symmetric key length %d is wrong", symmetric_key.len);
goto failed;
}
if (iv.len != crypter->get_block_size(crypter))
{
- DBG1("IV length %d is wrong", iv.len);
+ DBG1(DBG_LIB, "IV length %d is wrong", iv.len);
goto failed;
}
crypter->set_key(crypter, symmetric_key);
crypter->decrypt(crypter, encrypted_content, iv, data);
- DBG4("decrypted content with padding: %B", data);
+ DBG4(DBG_LIB, "decrypted content with padding: %B", data);
}
/* remove the padding */
@@ -491,7 +491,7 @@ end:
if (padding > data->len)
{
- DBG1("padding greater than data length");
+ DBG1(DBG_LIB, "padding greater than data length");
goto failed;
}
data->len -= padding;
@@ -500,7 +500,7 @@ end:
{
if (*pos-- != pattern)
{
- DBG1("wrong padding pattern");
+ DBG1(DBG_LIB, "wrong padding pattern");
goto failed;
}
}
@@ -631,7 +631,7 @@ chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes,
, asn1_wrap(ASN1_SET, "m", signerInfo));
cInfo = pkcs7_build_contentInfo(&signedData);
- DBG3("signedData %B", &cInfo);
+ DBG3(DBG_LIB, "signedData %B", &cInfo);
free(pkcs7Data.content.ptr);
free(signedData.content.ptr);
@@ -653,7 +653,7 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg
alg_key_size/BITS_PER_BYTE);
if (crypter == NULL)
{
- DBG1("crypter for %N not available", encryption_algorithm_names, alg);
+ DBG1(DBG_LIB, "crypter for %N not available", encryption_algorithm_names, alg);
return chunk_empty;
}
@@ -663,12 +663,12 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg
rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
rng->allocate_bytes(rng, crypter->get_key_size(crypter), &symmetricKey);
- DBG4("symmetric encryption key %B", &symmetricKey);
+ DBG4(DBG_LIB, "symmetric encryption key %B", &symmetricKey);
rng->destroy(rng);
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
rng->allocate_bytes(rng, crypter->get_block_size(crypter), &iv);
- DBG4("initialization vector: %B", &iv);
+ DBG4(DBG_LIB, "initialization vector: %B", &iv);
rng->destroy(rng);
}
@@ -680,7 +680,7 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg
in.len = data.len + padding;
in.ptr = malloc(in.len);
- DBG2("padding %u bytes of data to multiple block size of %u bytes",
+ DBG2(DBG_LIB, "padding %u bytes of data to multiple block size of %u bytes",
data.len, in.len);
/* copy data */
@@ -688,14 +688,14 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg
/* append padding */
memset(in.ptr + data.len, padding, padding);
}
- DBG3("padded unencrypted data %B", &in);
+ DBG3(DBG_LIB, "padded unencrypted data %B", &in);
/* symmetric encryption of data object */
crypter->set_key(crypter, symmetricKey);
crypter->encrypt(crypter, in, iv, &out);
crypter->destroy(crypter);
chunk_clear(&in);
- DBG3("encrypted data %B", &out);
+ DBG3(DBG_LIB, "encrypted data %B", &out);
/* protect symmetric key by public key encryption */
{
@@ -703,7 +703,7 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg
if (key == NULL)
{
- DBG1("public key not found in encryption certificate");
+ DBG1(DBG_LIB, "public key not found in encryption certificate");
chunk_clear(&symmetricKey);
chunk_free(&iv);
chunk_free(&out);
@@ -744,7 +744,7 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg
, encryptedContentInfo);
cInfo = pkcs7_build_contentInfo(&envelopedData);
- DBG3("envelopedData %B", &cInfo);
+ DBG3(DBG_LIB, "envelopedData %B", &cInfo);
chunk_free(&envelopedData.content);
chunk_free(&iv);
diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c
index 8b922df8c..aa04594bc 100644
--- a/src/pluto/plutomain.c
+++ b/src/pluto/plutomain.c
@@ -38,6 +38,7 @@
#include <freeswan.h>
+#include <hydra.h>
#include <library.h>
#include <debug.h>
#include <utils/enumerator.h>
@@ -74,6 +75,7 @@
#include "timer.h"
#include "vendor.h"
#include "builder.h"
+#include "whack_attribute.h"
static void usage(const char *mess)
{
@@ -242,7 +244,7 @@ static void print_plugins()
len += snprintf(&buf[len], BUF_LEN-len, "%s ", plugin);
}
enumerator->destroy(enumerator);
- DBG1("loaded plugins: %s", buf);
+ DBG1(DBG_DMN, "loaded plugins: %s", buf);
}
int main(int argc, char **argv)
@@ -273,6 +275,12 @@ int main(int argc, char **argv)
library_deinit();
exit(SS_RC_DAEMON_INTEGRITY);
}
+ if (!libhydra_init("pluto"))
+ {
+ libhydra_deinit();
+ library_deinit();
+ exit(SS_RC_INITIALIZATION_FAILED);
+ }
options = options_create();
/* handle arguments */
@@ -648,6 +656,7 @@ int main(int argc, char **argv)
{
plog("integrity tests enabled:");
plog("lib 'libstrongswan': passed file and segment integrity tests");
+ plog("lib 'libhydra': passed file and segment integrity tests");
plog("daemon 'pluto': passed file integrity test");
}
@@ -676,6 +685,7 @@ int main(int argc, char **argv)
init_myid();
fetch_initialize();
ac_initialize();
+ whack_attribute_initialize();
/* drop unneeded capabilities and change UID/GID */
prctl(PR_SET_KEEPCAPS, 1);
@@ -750,6 +760,7 @@ void exit_pluto(int status)
free_preshared_secrets();
free_remembered_public_keys();
delete_every_connection();
+ whack_attribute_finalize(); /* free in-memory pools */
fetch_finalize(); /* stop fetching thread */
free_crl_fetch(); /* free chain of crl fetch requests */
free_ocsp_fetch(); /* free chain of ocsp fetch requests */
@@ -770,6 +781,8 @@ void exit_pluto(int status)
free_builder();
delete_lock();
options->destroy(options);
+ lib->plugins->unload(lib->plugins);
+ libhydra_deinit();
library_deinit();
close_log();
exit(status);
diff --git a/src/pluto/rcv_whack.c b/src/pluto/rcv_whack.c
index 826a1aa6e..bf5ccb10c 100644
--- a/src/pluto/rcv_whack.c
+++ b/src/pluto/rcv_whack.c
@@ -57,6 +57,7 @@
#include "myid.h"
#include "kernel_alg.h"
#include "ike_alg.h"
+#include "whack_attribute.h"
/* helper variables and function to decode strings from whack message */
@@ -326,6 +327,8 @@ void whack_handle(int whackctlfd)
|| !unpack_str(&msg.ike) /* string 24 */
|| !unpack_str(&msg.esp) /* string 25 */
|| !unpack_str(&msg.sc_data) /* string 26 */
+ || !unpack_str(&msg.whack_lease_ip) /* string 27 */
+ || !unpack_str(&msg.whack_lease_id) /* string 28 */
|| str_roof - next_str != (ptrdiff_t)msg.keyval.len) /* check chunk */
{
ugh = "message from whack contains bad string";
@@ -376,7 +379,9 @@ void whack_handle(int whackctlfd)
}
if (msg.whack_myid)
+ {
set_myid(MYID_SPECIFIED, msg.myid);
+ }
/* Deleting combined with adding a connection works as replace.
* To make this more useful, in only this combination,
@@ -385,9 +390,13 @@ void whack_handle(int whackctlfd)
if (msg.whack_delete)
{
if (msg.whack_ca)
+ {
find_ca_info_by_name(msg.name, TRUE);
+ }
else
+ {
delete_connections_by_name(msg.name, !msg.whack_connection);
+ }
}
if (msg.whack_deletestate)
@@ -406,13 +415,19 @@ void whack_handle(int whackctlfd)
}
if (msg.whack_crash)
+ {
delete_states_by_peer(&msg.whack_crash_peer);
+ }
if (msg.whack_connection)
+ {
add_connection(&msg);
+ }
if (msg.whack_ca && msg.cacert != NULL)
+ {
add_ca_info(&msg);
+ }
/* process "listen" before any operation that could require it */
if (msg.whack_listen)
@@ -469,7 +484,12 @@ void whack_handle(int whackctlfd)
free_ocsp_cache();
}
- if (msg.whack_list & LIST_PUBKEYS)
+ if (msg.whack_leases)
+ {
+ list_leases(msg.name, msg.whack_lease_ip, msg.whack_lease_id);
+ }
+
+ if (msg.whack_list & LIST_PUBKEYS)
{
list_public_keys(msg.whack_utc);
}
@@ -552,12 +572,18 @@ void whack_handle(int whackctlfd)
{
set_cur_connection(c);
if (!oriented(*c))
+ {
whack_log(RC_ORIENT
, "we have no ipsecN interface for either end of this connection");
+ }
else if (c->policy & POLICY_GROUP)
+ {
route_group(c);
+ }
else if (!trap_connection(c))
+ {
whack_log(RC_ROUTE, "could not route");
+ }
reset_cur_connection();
}
}
@@ -584,14 +610,22 @@ void whack_handle(int whackctlfd)
for (sr = &c->spd; sr != NULL; sr = sr->next)
{
if (sr->routing >= RT_ROUTED_TUNNEL)
+ {
fail++;
+ }
}
if (fail > 0)
+ {
whack_log(RC_RTBUSY, "cannot unroute: route busy");
+ }
else if (c->policy & POLICY_GROUP)
+ {
unroute_group(c);
+ }
else
+ {
unroute_connection(c);
+ }
reset_cur_connection();
}
}
@@ -618,11 +652,15 @@ void whack_handle(int whackctlfd)
if (msg.whack_oppo_initiate)
{
if (!listening)
+ {
whack_log(RC_DEAF, "need --listen before opportunistic initiation");
+ }
else
+ {
initiate_opportunistic(&msg.oppo_my_client, &msg.oppo_peer_client, 0
, FALSE
, msg.whack_async? NULL_FD : dup_any(whackfd));
+ }
}
if (msg.whack_terminate)
@@ -639,7 +677,9 @@ void whack_handle(int whackctlfd)
}
if (msg.whack_status)
+ {
show_status(msg.whack_statusall, msg.name);
+ }
if (msg.whack_shutdown)
{
@@ -650,10 +690,14 @@ void whack_handle(int whackctlfd)
if (msg.whack_sc_op != SC_OP_NONE)
{
if (pkcs11_proxy)
+ {
scx_op_via_whack(msg.sc_data, msg.inbase, msg.outbase
, msg.whack_sc_op, msg.keyid, whackfd);
+ }
else
+ {
plog("pkcs11 access to smartcard not allowed (set pkcs11proxy=yes)");
+ }
}
whack_log_fd = NULL_FD;
diff --git a/src/pluto/timer.c b/src/pluto/timer.c
index 74806a40c..b112d67f6 100644
--- a/src/pluto/timer.c
+++ b/src/pluto/timer.c
@@ -48,7 +48,7 @@ time_t now(void)
{
static time_t delta = 0
, last_time = 0;
- time_t n = time((time_t)NULL);
+ time_t n = time(NULL);
passert(n != (time_t)-1);
if (last_time > n)
diff --git a/src/pluto/vendor.c b/src/pluto/vendor.c
index 7d3c96c87..99cfc5734 100644
--- a/src/pluto/vendor.c
+++ b/src/pluto/vendor.c
@@ -198,6 +198,7 @@ static struct vid_struct _vid_tab[] = {
* strongSwan
*/
DEC_MD5_VID(STRONGSWAN, "strongSwan")
+
DEC_MD5_VID(STRONGSWAN_4_3_5, "strongSwan 4.3.5")
DEC_MD5_VID(STRONGSWAN_4_3_4, "strongSwan 4.3.4")
DEC_MD5_VID(STRONGSWAN_4_3_3, "strongSwan 4.3.3")
@@ -234,14 +235,6 @@ static struct vid_struct _vid_tab[] = {
DEC_MD5_VID(STRONGSWAN_4_1_2, "strongSwan 4.1.2")
DEC_MD5_VID(STRONGSWAN_4_1_1, "strongSwan 4.1.1")
DEC_MD5_VID(STRONGSWAN_4_1_0, "strongSwan 4.1.0")
- DEC_MD5_VID(STRONGSWAN_4_0_7, "strongSwan 4.0.7")
- DEC_MD5_VID(STRONGSWAN_4_0_6, "strongSwan 4.0.6")
- DEC_MD5_VID(STRONGSWAN_4_0_5, "strongSwan 4.0.5")
- DEC_MD5_VID(STRONGSWAN_4_0_4, "strongSwan 4.0.4")
- DEC_MD5_VID(STRONGSWAN_4_0_3, "strongSwan 4.0.3")
- DEC_MD5_VID(STRONGSWAN_4_0_2, "strongSwan 4.0.2")
- DEC_MD5_VID(STRONGSWAN_4_0_1, "strongSwan 4.0.1")
- DEC_MD5_VID(STRONGSWAN_4_0_0, "strongSwan 4.0.0")
DEC_MD5_VID(STRONGSWAN_2_8_11,"strongSwan 2.8.11")
DEC_MD5_VID(STRONGSWAN_2_8_10,"strongSwan 2.8.10")
@@ -255,34 +248,6 @@ static struct vid_struct _vid_tab[] = {
DEC_MD5_VID(STRONGSWAN_2_8_2, "strongSwan 2.8.2")
DEC_MD5_VID(STRONGSWAN_2_8_1, "strongSwan 2.8.1")
DEC_MD5_VID(STRONGSWAN_2_8_0, "strongSwan 2.8.0")
- DEC_MD5_VID(STRONGSWAN_2_7_3, "strongSwan 2.7.3")
- DEC_MD5_VID(STRONGSWAN_2_7_2, "strongSwan 2.7.2")
- DEC_MD5_VID(STRONGSWAN_2_7_1, "strongSwan 2.7.1")
- 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")
- DEC_MD5_VID(STRONGSWAN_2_6_1, "strongSwan 2.6.1")
- DEC_MD5_VID(STRONGSWAN_2_6_0, "strongSwan 2.6.0")
- DEC_MD5_VID(STRONGSWAN_2_5_7, "strongSwan 2.5.7")
- DEC_MD5_VID(STRONGSWAN_2_5_6, "strongSwan 2.5.6")
- DEC_MD5_VID(STRONGSWAN_2_5_5, "strongSwan 2.5.5")
- DEC_MD5_VID(STRONGSWAN_2_5_4, "strongSwan 2.5.4")
- DEC_MD5_VID(STRONGSWAN_2_5_3, "strongSwan 2.5.3")
- DEC_MD5_VID(STRONGSWAN_2_5_2, "strongSwan 2.5.2")
- DEC_MD5_VID(STRONGSWAN_2_5_1, "strongSwan 2.5.1")
- DEC_MD5_VID(STRONGSWAN_2_5_0, "strongSwan 2.5.0")
- DEC_MD5_VID(STRONGSWAN_2_4_4, "strongSwan 2.4.4")
- DEC_MD5_VID(STRONGSWAN_2_4_3, "strongSwan 2.4.3")
- DEC_MD5_VID(STRONGSWAN_2_4_2, "strongSwan 2.4.2")
- DEC_MD5_VID(STRONGSWAN_2_4_1, "strongSwan 2.4.1")
- DEC_MD5_VID(STRONGSWAN_2_4_0, "strongSwan 2.4.0")
- DEC_MD5_VID(STRONGSWAN_2_3_2, "strongSwan 2.3.2")
- DEC_MD5_VID(STRONGSWAN_2_3_1, "strongSwan 2.3.1")
- DEC_MD5_VID(STRONGSWAN_2_3_0, "strongSwan 2.3.0")
- DEC_MD5_VID(STRONGSWAN_2_2_2, "strongSwan 2.2.2")
- DEC_MD5_VID(STRONGSWAN_2_2_1, "strongSwan 2.2.1")
- DEC_MD5_VID(STRONGSWAN_2_2_0, "strongSwan 2.2.0")
/* NAT-Traversal */
@@ -375,51 +340,63 @@ static void handle_known_vendorid (struct msg_digest *md, const char *vidstr,
bool vid_useful = FALSE;
size_t i, j;
- switch (vid->id) {
- /* Remote side supports OpenPGP certificates */
- case VID_OPENPGP:
- md->openpgp = TRUE;
- vid_useful = TRUE;
- break;
+ switch (vid->id)
+ {
+ /* Remote side is a strongSwan host */
+ case VID_STRONGSWAN:
+ vid_useful = TRUE;
+ break;
+
+ /* Remote side supports OpenPGP certificates */
+ case VID_OPENPGP:
+ md->openpgp = TRUE;
+ vid_useful = TRUE;
+ break;
- /*
- * Use most recent supported NAT-Traversal method and ignore the
- * other ones (implementations will send all supported methods but
- * only one will be used)
- *
- * Note: most recent == higher id in vendor.h
- */
- case VID_NATT_IETF_00:
- if (!nat_traversal_support_non_ike)
+ /* Remote side is a Windows 2000+ host */
+ case VID_MS_NT5:
+ md->ms_nt5 = TRUE;
+ vid_useful = TRUE;
break;
- if ((nat_traversal_enabled) && (!md->nat_traversal_vid))
- {
- md->nat_traversal_vid = vid->id;
+
+ /*
+ * Use most recent supported NAT-Traversal method and ignore the
+ * other ones (implementations will send all supported methods but
+ * only one will be used)
+ *
+ * Note: most recent == higher id in vendor.h
+ */
+ case VID_NATT_IETF_00:
+ if (!nat_traversal_support_non_ike)
+ break;
+ if ((nat_traversal_enabled) && (!md->nat_traversal_vid))
+ {
+ md->nat_traversal_vid = vid->id;
+ vid_useful = TRUE;
+ }
+ break;
+ case VID_NATT_IETF_02:
+ case VID_NATT_IETF_02_N:
+ case VID_NATT_IETF_03:
+ case VID_NATT_RFC:
+ if (nat_traversal_support_port_floating
+ && md->nat_traversal_vid < vid->id)
+ {
+ md->nat_traversal_vid = vid->id;
+ vid_useful = TRUE;
+ }
+ break;
+
+ /* Remote side would like to do DPD with us on this connection */
+ case VID_MISC_DPD:
+ md->dpd = TRUE;
vid_useful = TRUE;
- }
- break;
- case VID_NATT_IETF_02:
- case VID_NATT_IETF_02_N:
- case VID_NATT_IETF_03:
- case VID_NATT_RFC:
- if (nat_traversal_support_port_floating
- && md->nat_traversal_vid < vid->id)
- {
- md->nat_traversal_vid = vid->id;
+ break;
+ case VID_MISC_XAUTH:
vid_useful = TRUE;
- }
- break;
-
- /* Remote side would like to do DPD with us on this connection */
- case VID_MISC_DPD:
- md->dpd = TRUE;
- vid_useful = TRUE;
- break;
- case VID_MISC_XAUTH:
- vid_useful = TRUE;
- break;
- default:
- break;
+ break;
+ default:
+ break;
}
if (vid->flags & VID_SUBSTRING_DUMPHEXA)
diff --git a/src/pluto/vendor.h b/src/pluto/vendor.h
index 3df1a8196..ac6b0d420 100644
--- a/src/pluto/vendor.h
+++ b/src/pluto/vendor.h
@@ -53,56 +53,21 @@ enum known_vendorid {
VID_VISTA_AUTHIP2 = 34,
VID_VISTA_AUTHIP3 = 35,
- VID_STRONGSWAN = 37,
- VID_STRONGSWAN_2_2_0 = 38,
- VID_STRONGSWAN_2_2_1 = 39,
- VID_STRONGSWAN_2_2_2 = 40,
- VID_STRONGSWAN_2_3_0 = 41,
- VID_STRONGSWAN_2_3_1 = 42,
- VID_STRONGSWAN_2_3_2 = 43,
- VID_STRONGSWAN_2_4_0 = 44,
- VID_STRONGSWAN_2_4_1 = 45,
- VID_STRONGSWAN_2_4_2 = 46,
- VID_STRONGSWAN_2_4_3 = 47,
- VID_STRONGSWAN_2_4_4 = 48,
- VID_STRONGSWAN_2_5_0 = 49,
- VID_STRONGSWAN_2_5_1 = 50,
- VID_STRONGSWAN_2_5_2 = 51,
- VID_STRONGSWAN_2_5_3 = 52,
- VID_STRONGSWAN_2_5_4 = 53,
- VID_STRONGSWAN_2_5_5 = 54,
- VID_STRONGSWAN_2_5_6 = 55,
- VID_STRONGSWAN_2_5_7 = 56,
- VID_STRONGSWAN_2_6_0 = 57,
- VID_STRONGSWAN_2_6_1 = 58,
- VID_STRONGSWAN_2_6_2 = 59,
- VID_STRONGSWAN_2_6_3 = 60,
- VID_STRONGSWAN_2_6_4 = 61,
- VID_STRONGSWAN_2_7_0 = 62,
- VID_STRONGSWAN_2_7_1 = 63,
- VID_STRONGSWAN_2_7_2 = 64,
- VID_STRONGSWAN_2_7_3 = 65,
- VID_STRONGSWAN_2_8_0 = 66,
- VID_STRONGSWAN_2_8_1 = 67,
- VID_STRONGSWAN_2_8_2 = 68,
- VID_STRONGSWAN_2_8_3 = 69,
- VID_STRONGSWAN_2_8_4 = 70,
- VID_STRONGSWAN_2_8_5 = 71,
- VID_STRONGSWAN_2_8_6 = 72,
- VID_STRONGSWAN_2_8_7 = 73,
- VID_STRONGSWAN_2_8_8 = 74,
- VID_STRONGSWAN_2_8_9 = 75,
- VID_STRONGSWAN_2_8_10 = 76,
- VID_STRONGSWAN_2_8_11 = 77,
+ VID_STRONGSWAN = 36,
+
+ VID_STRONGSWAN_2_8_0 = 37,
+ VID_STRONGSWAN_2_8_1 = 38,
+ VID_STRONGSWAN_2_8_2 = 39,
+ VID_STRONGSWAN_2_8_3 = 40,
+ VID_STRONGSWAN_2_8_4 = 41,
+ VID_STRONGSWAN_2_8_5 = 42,
+ VID_STRONGSWAN_2_8_6 = 43,
+ VID_STRONGSWAN_2_8_7 = 44,
+ VID_STRONGSWAN_2_8_8 = 45,
+ VID_STRONGSWAN_2_8_9 = 46,
+ VID_STRONGSWAN_2_8_10 = 47,
+ VID_STRONGSWAN_2_8_11 = 48,
- VID_STRONGSWAN_4_0_0 = 80,
- VID_STRONGSWAN_4_0_1 = 81,
- VID_STRONGSWAN_4_0_2 = 82,
- VID_STRONGSWAN_4_0_3 = 83,
- VID_STRONGSWAN_4_0_4 = 84,
- VID_STRONGSWAN_4_0_5 = 85,
- VID_STRONGSWAN_4_0_6 = 86,
- VID_STRONGSWAN_4_0_7 = 87,
VID_STRONGSWAN_4_1_0 = 88,
VID_STRONGSWAN_4_1_1 = 89,
VID_STRONGSWAN_4_1_2 = 90,
@@ -115,7 +80,6 @@ enum known_vendorid {
VID_STRONGSWAN_4_1_9 = 97,
VID_STRONGSWAN_4_1_10 = 98,
VID_STRONGSWAN_4_1_11 = 99,
-
VID_STRONGSWAN_4_2_0 =100,
VID_STRONGSWAN_4_2_1 =101,
VID_STRONGSWAN_4_2_2 =102,
diff --git a/src/pluto/whack_attribute.c b/src/pluto/whack_attribute.c
new file mode 100644
index 000000000..6a12f0c09
--- /dev/null
+++ b/src/pluto/whack_attribute.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "whack_attribute.h"
+
+#include "log.h"
+
+/* these are defined as constants in constant.h but redefined as enum values in
+ * attributes/attributes.h */
+#undef INTERNAL_IP4_SERVER
+#undef INTERNAL_IP6_SERVER
+
+#include <hydra.h>
+#include <attributes/mem_pool.h>
+#include <utils/linked_list.h>
+#include <threading/rwlock.h>
+
+typedef struct private_whack_attribute_t private_whack_attribute_t;
+
+/**
+ * private data of whack_attribute
+ */
+struct private_whack_attribute_t {
+
+ /**
+ * public functions
+ */
+ whack_attribute_t public;
+
+ /**
+ * list of pools, contains mem_pool_t
+ */
+ linked_list_t *pools;
+
+ /**
+ * rwlock to lock access to pools
+ */
+ rwlock_t *lock;
+};
+
+/**
+ * global object
+ */
+whack_attribute_t *whack_attr;
+
+/**
+ * compare pools by name
+ */
+static bool pool_match(mem_pool_t *current, char *name)
+{
+ return name && streq(name, current->get_name(current));
+}
+
+/**
+ * find a pool by name
+ */
+static mem_pool_t *find_pool(private_whack_attribute_t *this, char *name)
+{
+ mem_pool_t *found;
+ if (this->pools->find_first(this->pools, (linked_list_match_t)pool_match,
+ (void**)&found, name) == SUCCESS)
+ {
+ return found;
+ }
+ return NULL;
+}
+
+METHOD(attribute_provider_t, acquire_address, host_t*,
+ private_whack_attribute_t *this, char *name, identification_t *id,
+ host_t *requested)
+{
+ mem_pool_t *pool;
+ host_t *addr = NULL;
+ this->lock->read_lock(this->lock);
+ pool = find_pool(this, name);
+ if (pool)
+ {
+ addr = pool->acquire_address(pool, id, requested);
+ }
+ this->lock->unlock(this->lock);
+ return addr;
+}
+
+METHOD(attribute_provider_t, release_address, bool,
+ private_whack_attribute_t *this, char *name, host_t *address,
+ identification_t *id)
+{
+ mem_pool_t *pool;
+ bool found = FALSE;
+ this->lock->read_lock(this->lock);
+ pool = find_pool(this, name);
+ if (pool)
+ {
+ found = pool->release_address(pool, address, id);
+ }
+ this->lock->unlock(this->lock);
+ return found;
+}
+
+METHOD(whack_attribute_t, add_pool, bool,
+ private_whack_attribute_t *this, const char *name,
+ const whack_end_t *right)
+{
+ mem_pool_t *pool;
+ host_t *base = NULL;
+ u_int32_t bits = 0;
+
+ /* named pool */
+ if (right->sourceip_mask <= 0)
+ {
+ return FALSE;
+ }
+
+ /* if %config, add an empty pool, otherwise */
+ if (right->sourceip)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("adding virtual IP address pool '%s': %s/%d",
+ name, right->sourceip, right->sourceip_mask);
+ );
+ base = host_create_from_string(right->sourceip, 0);
+ if (!base)
+ {
+ loglog(RC_LOG_SERIOUS, "virtual IP address invalid, discarded");
+ return FALSE;
+ }
+ bits = right->sourceip_mask;
+ }
+ pool = mem_pool_create((char*)name, base, bits);
+ DESTROY_IF(base);
+
+ this->lock->write_lock(this->lock);
+ this->pools->insert_last(this->pools, pool);
+ this->lock->unlock(this->lock);
+ return TRUE;
+}
+
+METHOD(whack_attribute_t, del_pool, void,
+ private_whack_attribute_t *this, char *name)
+{
+ enumerator_t *enumerator;
+ mem_pool_t *pool;
+
+ this->lock->write_lock(this->lock);
+ enumerator = this->pools->create_enumerator(this->pools);
+ while (enumerator->enumerate(enumerator, &pool))
+ {
+ if (streq(name, pool->get_name(pool)))
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("deleting virtual IP address pool '%s'", name)
+ );
+ this->pools->remove_at(this->pools, enumerator);
+ pool->destroy(pool);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+}
+
+/**
+ * Pool enumerator filter function, converts pool_t to name, size, ...
+ */
+static bool pool_filter(void *lock, mem_pool_t **poolp, const char **name,
+ void *d1, u_int *size, void *d2, u_int *online,
+ void *d3, u_int *offline)
+{
+ mem_pool_t *pool = *poolp;
+ *name = pool->get_name(pool);
+ *size = pool->get_size(pool);
+ *online = pool->get_online(pool);
+ *offline = pool->get_offline(pool);
+ return TRUE;
+}
+
+METHOD(whack_attribute_t, create_pool_enumerator, enumerator_t*,
+ private_whack_attribute_t *this)
+{
+ this->lock->read_lock(this->lock);
+ return enumerator_create_filter(this->pools->create_enumerator(this->pools),
+ (void*)pool_filter,
+ this->lock, (void*)this->lock->unlock);
+}
+
+METHOD(whack_attribute_t, create_lease_enumerator, enumerator_t*,
+ private_whack_attribute_t *this, char *name)
+{
+ mem_pool_t *pool;
+ this->lock->read_lock(this->lock);
+ pool = find_pool(this, name);
+ if (!pool)
+ {
+ this->lock->unlock(this->lock);
+ return NULL;
+ }
+ return enumerator_create_cleaner(pool->create_lease_enumerator(pool),
+ (void*)this->lock->unlock, this->lock);
+}
+
+/**
+ * see header file
+ */
+void whack_attribute_finalize()
+{
+ private_whack_attribute_t *this;
+
+ if (whack_attr)
+ {
+ this = (private_whack_attribute_t*)whack_attr;
+ hydra->attributes->remove_provider(hydra->attributes,
+ &this->public.provider);
+ this->lock->destroy(this->lock);
+ this->pools->destroy_offset(this->pools, offsetof(mem_pool_t, destroy));
+ free(this);
+ }
+}
+
+/**
+ * see header file
+ */
+void whack_attribute_initialize()
+{
+ private_whack_attribute_t *this;
+
+ INIT(this,
+ .public = {
+ .provider = {
+ .acquire_address = _acquire_address,
+ .release_address = _release_address,
+ .create_attribute_enumerator = enumerator_create_empty,
+ },
+ .add_pool = _add_pool,
+ .del_pool = _del_pool,
+ .create_pool_enumerator = _create_pool_enumerator,
+ .create_lease_enumerator = _create_lease_enumerator,
+ },
+ .pools = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+
+ hydra->attributes->add_provider(hydra->attributes, &this->public.provider);
+
+ whack_attr = &this->public;
+}
+
+/**
+ * list leases of a single pool
+ */
+static void pool_leases(char *pool, host_t *address,
+ identification_t *identification,
+ u_int size, u_int online, u_int offline)
+{
+
+ enumerator_t *enumerator;
+ identification_t *id;
+ host_t *lease;
+ bool on, found = FALSE;
+
+ whack_log(RC_COMMENT, "Leases in pool '%s', usage: %lu/%lu, %lu online",
+ pool, online + offline, size, online);
+ enumerator = whack_attr->create_lease_enumerator(whack_attr, pool);
+ while (enumerator && enumerator->enumerate(enumerator, &id, &lease, &on))
+ {
+ if ((!address && !identification) ||
+ (address && address->ip_equals(address, lease)) ||
+ (identification && identification->equals(identification, id)))
+ {
+ whack_log(RC_COMMENT, " %15H %s '%Y'",
+ lease, on ? "online" : "offline", id);
+ found = TRUE;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!found)
+ {
+ whack_log(RC_COMMENT, " no matching leases found");
+ }
+}
+
+/**
+ * see header file
+ */
+void list_leases(char *name, char *addr, char *id)
+{
+ identification_t *identification = NULL;
+ host_t *address = NULL;
+ bool found = FALSE;
+ enumerator_t *enumerator;
+ u_int size, online, offline;
+ char *pool;
+
+ if (addr)
+ {
+ address = host_create_from_string(addr, 0);
+ }
+ if (id)
+ {
+ identification = identification_create_from_string(id);
+ }
+
+ enumerator = whack_attr->create_pool_enumerator(whack_attr);
+ while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline))
+ {
+ if (!name || streq(name, pool))
+ {
+ pool_leases(pool, address, identification, size, online, offline);
+ found = TRUE;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!found)
+ {
+ if (name)
+ {
+ whack_log(RC_COMMENT, "pool '%s' not found", name);
+ }
+ else
+ {
+ whack_log(RC_COMMENT, "no pools found");
+ }
+ }
+ DESTROY_IF(identification);
+ DESTROY_IF(address);
+}
+
+/**
+ * see header file
+ */
+void show_pools(const char *name)
+{
+ enumerator_t *enumerator;
+ u_int size, online, offline;
+ char *pool;
+ bool first = TRUE;
+
+ enumerator = whack_attr->create_pool_enumerator(whack_attr);
+ while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline))
+ {
+ if (name && !streq(name, pool))
+ {
+ continue;
+ }
+ if (first)
+ {
+ first = FALSE;
+ whack_log(RC_COMMENT, "Virtual IP pools (size/online/offline):");
+ }
+ whack_log(RC_COMMENT, "\"%s\": %u/%u/%u", pool, size, online, offline);
+ }
+ enumerator->destroy(enumerator);
+}
diff --git a/src/pluto/whack_attribute.h b/src/pluto/whack_attribute.h
new file mode 100644
index 000000000..58441b973
--- /dev/null
+++ b/src/pluto/whack_attribute.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * 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.
+ */
+
+/**
+ * @defgroup whack_attribute
+ * @{ @ingroup pluto
+ */
+
+#ifndef WHACK_ATTRIBUTE_H_
+#define WHACK_ATTRIBUTE_H_
+
+#include <whack.h>
+#include <attributes/attribute_provider.h>
+
+typedef struct whack_attribute_t whack_attribute_t;
+
+/**
+ * Whack attribute provider (basically an in-memory IP address pool)
+ */
+struct whack_attribute_t {
+
+ /**
+ * Implements attribute provider interface
+ */
+ attribute_provider_t provider;
+
+ /**
+ * Add a virtual IP address pool.
+ *
+ * @param name name of the pool
+ * @param right "right" end of whack message
+ * @return TRUE, if the pool was successfully added
+ */
+ bool (*add_pool)(whack_attribute_t *this, const char *name,
+ const whack_end_t *right);
+
+ /**
+ * Remove a virtual IP address pool.
+ *
+ * @param name name of the pool
+ */
+ void (*del_pool)(whack_attribute_t *this, char *name);
+
+ /**
+ * Create an enumerator over installed pools.
+ *
+ * Enumerator enumerates over
+ * char *pool, u_int size, u_int offline, u_int online.
+ *
+ * @return enumerator
+ */
+ enumerator_t* (*create_pool_enumerator)(whack_attribute_t *this);
+
+ /**
+ * Create an enumerator over the leases of a pool.
+ *
+ * Enumerator enumerates over
+ * identification_t *id, host_t *address, bool online
+ *
+ * @param name name of the pool to enumerate
+ * @return enumerator, NULL if pool not found
+ */
+ enumerator_t* (*create_lease_enumerator)(whack_attribute_t *this,
+ char *name);
+};
+
+/**
+ * Global object to manage pools. Set between calls to
+ * whack_attribute_initialize() and whack_attribute_finalize().
+ */
+extern whack_attribute_t *whack_attr;
+
+/**
+ * Initialize the whack attribute provider
+ */
+void whack_attribute_initialize();
+
+/**
+ * Finalize the whack attribute provider
+ */
+void whack_attribute_finalize();
+
+/**
+ * List the leases matching the given parameters.
+ *
+ * @param name name of the pool, NULL for all pools
+ * @param addr ip address of the lease to list, NULL to ignore
+ * @param id id of the lease to list, NULL to ignore
+ */
+void list_leases(char *name, char *addr, char *id);
+
+/**
+ * List either all pools or the pool with a given name
+ *
+ * @param name name of the pool, NULL for all pools
+ */
+void show_pools(const char *name);
+
+#endif /** WHACK_ATTRIBUTE_H_ @}*/
diff --git a/src/pluto/x509.c b/src/pluto/x509.c
index d8e887955..0a29830ea 100644
--- a/src/pluto/x509.c
+++ b/src/pluto/x509.c
@@ -419,11 +419,11 @@ void list_x509cert_chain(const char *caption, cert_t* cert,
check_expiry(notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
key = certificate->get_public_key(certificate);
- if (key);
+ if (key)
{
whack_log(RC_COMMENT, " pubkey: %N %4d bits%s",
key_type_names, key->get_type(key),
- key->get_keysize(key) * BITS_PER_BYTE,
+ key->get_keysize(key) * BITS_PER_BYTE,
cert->smartcard ? ", on smartcard" :
(has_private_key(cert)? ", has private key" : ""));