added support for leftsendcert= and left|rightca= parameters

This commit is contained in:
Andreas Steffen 2006-06-09 05:50:41 +00:00
parent ac427e3677
commit b7f9ca5837
8 changed files with 114 additions and 30 deletions

View File

@ -56,6 +56,16 @@ struct private_policy_t {
*/
identification_t *other_id;
/**
* we have a cert issued by this CA
*/
identification_t *my_ca;
/**
* we require the other end to have a cert issued by this CA
*/
identification_t *other_ca;
/**
* list for all proposals
*/
@ -267,6 +277,15 @@ static proposal_t *select_proposal(private_policy_t *this, linked_list_t *propos
return NULL;
}
/**
* Implementation of policy_t.add_authorities
*/
static void add_authorities(private_policy_t *this, identification_t *my_ca, identification_t *other_ca)
{
this->my_ca = my_ca;
this->other_ca = other_ca;
}
/**
* Implementation of policy_t.add_my_traffic_selector
*/
@ -320,6 +339,10 @@ static policy_t *clone(private_policy_t *this)
proposal_t *proposal;
traffic_selector_t *ts;
/* clone the certification authorities */
clone->my_ca = this->my_ca->clone(this->my_ca);
clone->other_ca = this->other_ca->clone(this->other_ca);
/* clone all proposals */
iterator = this->proposals->create_iterator(this->proposals, TRUE);
while (iterator->has_next(iterator))
@ -383,6 +406,10 @@ static status_t destroy(private_policy_t *this)
}
this->other_ts->destroy(this->other_ts);
/* delete certification authorities */
this->my_ca->destroy(this->my_ca);
this->other_ca->destroy(this->other_ca);
/* delete ids */
this->my_id->destroy(this->my_id);
this->other_id->destroy(this->other_id);
@ -416,17 +443,20 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
this->public.add_my_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_my_traffic_selector;
this->public.add_other_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_other_traffic_selector;
this->public.add_proposal = (void(*)(policy_t*,proposal_t*))add_proposal;
this->public.add_authorities = (void(*)(policy_t*,identification_t*, identification_t*))add_authorities;
this->public.get_soft_lifetime = (u_int32_t (*) (policy_t *))get_soft_lifetime;
this->public.get_hard_lifetime = (u_int32_t (*) (policy_t *))get_hard_lifetime;
this->public.clone = (policy_t*(*)(policy_t*))clone;
this->public.destroy = (void(*)(policy_t*))destroy;
/* apply init values */
this->name = strdup(name);
this->my_id = my_id;
this->other_id = other_id;
this->name = strdup(name);
/* init private members*/
/* initialize private members*/
this->my_ca = NULL;
this->other_ca = NULL;
this->select_traffic_selectors = select_traffic_selectors;
this->proposals = linked_list_create();
this->my_ts = linked_list_create();

View File

@ -229,6 +229,15 @@ struct policy_t {
*/
void (*add_proposal) (policy_t *this, proposal_t *proposal);
/**
* @brief Add certification authorities
*
* @param this calling object
* @param my_ca issuer of my certificate
* @param other_ca required issuer of the peer's certificate
*/
void (*add_authorities) (policy_t *this, identification_t *my_ca, identification_t *other_ca);
/**
* @brief Get the lifetime of a policy, before rekeying starts.
*

View File

@ -73,7 +73,7 @@ struct private_stroke_t {
int socket;
/**
* Thread which reads from the socket
* Thread which reads from the ocket
*/
pthread_t assigned_thread;
@ -112,7 +112,7 @@ static void pop_string(stroke_msg_t *msg, char **string)
/**
* Load end entitity certificate
*/
static void load_end_certificate(const char *filename, identification_t **idp)
static void load_end_certificate(const char *filename, identification_t **idp, logger_t *logger)
{
char path[PATH_BUF];
x509_t *cert;
@ -135,6 +135,12 @@ static void load_end_certificate(const char *filename, identification_t **idp)
identification_t *id = *idp;
identification_t *subject = cert->get_subject(cert);
err_t ugh = cert->is_valid(cert, NULL);
if (ugh != NULL)
{
logger->log(logger, ERROR, "warning: certificate %s", ugh);
}
if (!id->equals(id, subject) && !cert->equals_subjectAltName(cert, id))
{
id->destroy(id);
@ -152,7 +158,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
{
connection_t *connection;
policy_t *policy;
identification_t *my_id, *other_id;
identification_t *my_id, *other_id, *my_ca, *other_ca;
host_t *my_host, *other_host, *my_subnet, *other_subnet;
proposal_t *proposal;
traffic_selector_t *my_ts, *other_ts;
@ -160,12 +166,14 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
pop_string(msg, &msg->add_conn.name);
pop_string(msg, &msg->add_conn.me.address);
pop_string(msg, &msg->add_conn.other.address);
pop_string(msg, &msg->add_conn.me.subnet);
pop_string(msg, &msg->add_conn.other.subnet);
pop_string(msg, &msg->add_conn.me.id);
pop_string(msg, &msg->add_conn.other.id);
pop_string(msg, &msg->add_conn.me.cert);
pop_string(msg, &msg->add_conn.other.cert);
pop_string(msg, &msg->add_conn.me.subnet);
pop_string(msg, &msg->add_conn.other.subnet);
pop_string(msg, &msg->add_conn.me.ca);
pop_string(msg, &msg->add_conn.other.ca);
this->logger->log(this->logger, CONTROL, "received stroke: add connection \"%s\"", msg->add_conn.name);
@ -232,6 +240,10 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
return;
}
/* TODO check for %same */
my_ca = identification_create_from_string(msg->add_conn.me.ca);
other_ca = identification_create_from_string(msg->add_conn.other.ca);
my_ts = traffic_selector_create_from_subnet(my_subnet, msg->add_conn.me.subnet ?
msg->add_conn.me.subnet_mask : 32);
my_subnet->destroy(my_subnet);
@ -245,7 +257,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "left is other host, switching");
host_t *tmp_host;
identification_t *tmp_id;
identification_t *tmp_id, *tmp_ca;
traffic_selector_t *tmp_ts;
char *tmp_cert;
@ -257,6 +269,10 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
my_id = other_id;
other_id = tmp_id;
tmp_ca = my_ca;
my_ca = other_ca;
other_ca = tmp_ca;
tmp_ts = my_ts;
my_ts = other_ts;
other_ts = tmp_ts;
@ -284,11 +300,11 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
if (msg->add_conn.me.cert)
{
load_end_certificate(msg->add_conn.me.cert, &my_id);
load_end_certificate(msg->add_conn.me.cert, &my_id, this->stroke_logger);
}
if (msg->add_conn.other.cert)
{
load_end_certificate(msg->add_conn.other.cert, &other_id);
load_end_certificate(msg->add_conn.other.cert, &other_id, this->stroke_logger);
}
connection = connection_create(msg->add_conn.name, msg->add_conn.ikev2,
@ -323,6 +339,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
policy->add_proposal(policy, proposal);
policy->add_my_traffic_selector(policy, my_ts);
policy->add_other_traffic_selector(policy, other_ts);
policy->add_authorities(policy, my_ca, other_ca);
/* add to global policy list */
charon->policies->add_policy(charon->policies, policy);

View File

@ -110,6 +110,18 @@ enum status_t {
};
/**
* Certificate sending policy
*/
typedef enum certpolicy {
CERT_ALWAYS_SEND = 0,
CERT_SEND_IF_ASKED = 1,
CERT_NEVER_SEND = 2,
CERT_YES_SEND = 3, /* synonym for CERT_ALWAYS_SEND */
CERT_NO_SEND = 4 /* synonym for CERT_NEVER_SEND */
} certpolicy_t;
/**
* String mappings for type status_t.
*/

View File

@ -82,6 +82,9 @@ static void default_values(starter_config_t *cfg)
cfg->conn_default.left.seen = LEMPTY;
cfg->conn_default.right.seen = LEMPTY;
cfg->conn_default.left.sendcert = CERT_SEND_IF_ASKED;
cfg->conn_default.right.sendcert = CERT_SEND_IF_ASKED;
anyaddr(AF_INET, &cfg->conn_default.left.addr);
anyaddr(AF_INET, &cfg->conn_default.left.nexthop);
anyaddr(AF_INET, &cfg->conn_default.left.srcip);

View File

@ -106,6 +106,17 @@ static char* connection_name(starter_conn_t *conn)
return conn->name;
}
static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, starter_end_t *conn_end)
{
msg_end->id = push_string(msg, conn_end->id);
msg_end->cert = push_string(msg, conn_end->cert);
msg_end->cert = push_string(msg, conn_end->cert);
msg_end->address = push_string(msg, inet_ntoa(conn_end->addr.u.v4.sin_addr));
msg_end->subnet = push_string(msg, inet_ntoa(conn_end->subnet.addr.u.v4.sin_addr));
msg_end->subnet_mask = conn_end->subnet.maskbits;
msg_end->sendcert = conn_end->sendcert;
}
int starter_stroke_add_conn(starter_conn_t *conn)
{
stroke_msg_t msg;
@ -115,17 +126,8 @@ int starter_stroke_add_conn(starter_conn_t *conn)
msg.add_conn.ikev2 = conn->keyexchange == KEY_EXCHANGE_IKEV2;
msg.add_conn.name = push_string(&msg, connection_name(conn));
msg.add_conn.me.id = push_string(&msg, conn->left.id);
msg.add_conn.me.cert = push_string(&msg, conn->left.cert);
msg.add_conn.me.address = push_string(&msg, inet_ntoa(conn->left.addr.u.v4.sin_addr));
msg.add_conn.me.subnet = push_string(&msg, inet_ntoa(conn->left.subnet.addr.u.v4.sin_addr));
msg.add_conn.me.subnet_mask = conn->left.subnet.maskbits;
msg.add_conn.other.id = push_string(&msg, conn->right.id);
msg.add_conn.other.cert = push_string(&msg, conn->right.cert);
msg.add_conn.other.address = push_string(&msg, inet_ntoa(conn->right.addr.u.v4.sin_addr));
msg.add_conn.other.subnet = push_string(&msg, inet_ntoa(conn->right.subnet.addr.u.v4.sin_addr));
msg.add_conn.other.subnet_mask = conn->right.subnet.maskbits;
starter_stroke_add_end(&msg, &msg.add_conn.me, &conn->right);
starter_stroke_add_end(&msg, &msg.add_conn.other, &conn->left);
return send_stroke_msg(&msg);
}

View File

@ -24,6 +24,8 @@
#include <stdio.h>
#include <linux/stddef.h>
#include <types.h>
#include "stroke.h"
#define streq(a, b) (strcmp((a), (b)) == 0) /* clearer shorthand */
@ -106,12 +108,16 @@ static int add_connection(char *name,
msg.add_conn.me.subnet = push_string(&msg, my_net);
msg.add_conn.me.subnet_mask = my_netmask;
msg.add_conn.me.cert = NULL;
msg.add_conn.me.ca = NULL;
msg.add_conn.me.sendcert = CERT_SEND_IF_ASKED;
msg.add_conn.other.id = push_string(&msg, other_id);
msg.add_conn.other.address = push_string(&msg, other_addr);
msg.add_conn.other.subnet = push_string(&msg, other_net);
msg.add_conn.other.subnet_mask = other_netmask;
msg.add_conn.other.cert = NULL;
msg.add_conn.other.ca = NULL;
msg.add_conn.other.sendcert = CERT_SEND_IF_ASKED;
return send_stroke_msg(&msg);
}

View File

@ -30,6 +30,18 @@
#define STROKE_BUF_LEN 2048
typedef struct stroke_end_t stroke_end_t;
struct stroke_end_t {
char *id;
char *cert;
char *ca;
char *address;
char *subnet;
int subnet_mask;
certpolicy_t sendcert;
};
typedef struct stroke_msg_t stroke_msg_t;
/**
@ -73,15 +85,8 @@ struct stroke_msg_t {
/* data for STR_ADD_CONN */
struct {
char *name;
/* is this connection handled by charon? */
int ikev2;
struct {
char *id;
char *cert;
char *address;
char *subnet;
int subnet_mask;
} me, other;
bool ikev2;
stroke_end_t me, other;
} add_conn;
struct {