/**
* Load end entitity certificate
*/
-static void load_end_certificate(const char *filename, identification_t **idp, logger_t *logger)
+static x509_t* load_end_certificate(const char *filename, identification_t **idp, logger_t *logger)
{
char path[PATH_BUF];
x509_t *cert;
id = subject;
*idp = id->clone(id);
}
- charon->credentials->add_certificate(charon->credentials, cert);
+ return charon->credentials->add_certificate(charon->credentials, cert);
}
+ return NULL;
}
/**
{
connection_t *connection;
policy_t *policy;
- identification_t *my_id, *other_id, *my_ca, *other_ca;
+ identification_t *my_id, *other_id;
+ identification_t *my_ca = NULL;
+ identification_t *other_ca = NULL;
+ bool my_ca_same = FALSE;
+ bool other_ca_same =FALSE;
host_t *my_host, *other_host, *my_subnet, *other_subnet;
proposal_t *proposal;
traffic_selector_t *my_ts, *other_ts;
return;
}
+ if (charon->socket->is_listening_on(charon->socket, other_host))
+ {
+ stroke_end_t tmp_end;
+ host_t *tmp_host;
+
+ this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "left is other host, swapping ends");
+
+ tmp_host = my_host;
+ my_host = other_host;
+ other_host = tmp_host;
+
+ tmp_end = msg->add_conn.me;
+ msg->add_conn.me = msg->add_conn.other;
+ msg->add_conn.other = tmp_end;
+ }
+ else if (!charon->socket->is_listening_on(charon->socket, my_host))
+ {
+ this->stroke_logger->log(this->stroke_logger, ERROR, "left nor right host is our side, aborting");
+
+ my_host->destroy(my_host);
+ other_host->destroy(other_host);
+ return;
+ }
+
my_id = identification_create_from_string(msg->add_conn.me.id ?
msg->add_conn.me.id : msg->add_conn.me.address);
if (my_id == NULL)
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);
other_ts = traffic_selector_create_from_subnet(other_subnet, msg->add_conn.other.subnet ?
msg->add_conn.other.subnet_mask : 32);
other_subnet->destroy(other_subnet);
-
- if (charon->socket->is_listening_on(charon->socket, other_host))
+
+ if (msg->add_conn.me.ca)
{
- this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "left is other host, switching");
-
- host_t *tmp_host;
- identification_t *tmp_id, *tmp_ca;
- traffic_selector_t *tmp_ts;
- char *tmp_cert;
-
- tmp_host = my_host;
- my_host = other_host;
- other_host = tmp_host;
+ if (streq(msg->add_conn.me.ca, "%same"))
+ {
+ my_ca_same = TRUE;
+ }
+ else
+ {
+ my_ca = identification_create_from_string(msg->add_conn.me.ca);
+ }
+ }
+ if (msg->add_conn.other.ca)
+ {
+ if (streq(msg->add_conn.other.ca, "%same"))
+ {
+ other_ca_same = TRUE;
+ }
+ else
+ {
+ other_ca = identification_create_from_string(msg->add_conn.other.ca);
+ }
+ }
+ if (msg->add_conn.me.cert)
+ {
+ x509_t *cert = load_end_certificate(msg->add_conn.me.cert, &my_id, this->stroke_logger);
- tmp_id = my_id;
- my_id = other_id;
- other_id = tmp_id;
+ if (my_ca == NULL && !my_ca_same && cert)
+ {
+ identification_t *issuer = cert->get_issuer(cert);
- tmp_ca = my_ca;
- my_ca = other_ca;
- other_ca = tmp_ca;
+ my_ca = issuer->clone(issuer);
+ }
+ }
+ if (msg->add_conn.other.cert)
+ {
+ x509_t *cert = load_end_certificate(msg->add_conn.other.cert, &other_id, this->stroke_logger);
- tmp_ts = my_ts;
- my_ts = other_ts;
- other_ts = tmp_ts;
+ if (other_ca == NULL && !other_ca_same && cert)
+ {
+ identification_t *issuer = cert->get_issuer(cert);
- tmp_cert = msg->add_conn.me.cert;
- msg->add_conn.me.cert = msg->add_conn.other.cert;
- msg->add_conn.other.cert = tmp_cert;
+ other_ca = issuer->clone(issuer);
+ }
}
- else if (charon->socket->is_listening_on(charon->socket, my_host))
+ if (other_ca_same && my_ca)
{
- this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "left is own host, not switching");
+ other_ca = my_ca->clone(my_ca);
}
- else
+ else if (my_ca_same && other_ca)
{
- this->stroke_logger->log(this->stroke_logger, ERROR, "left nor right host is our, aborting");
-
- my_host->destroy(my_host);
- other_host->destroy(other_host);
- my_id->destroy(my_id);
- other_id->destroy(other_id);
- my_ts->destroy(my_ts);
- other_ts->destroy(other_ts);
- return;
+ my_ca = other_ca->clone(other_ca);
}
-
- if (msg->add_conn.me.cert)
+ if (my_ca == NULL)
{
- load_end_certificate(msg->add_conn.me.cert, &my_id, this->stroke_logger);
+ my_ca = identification_create_from_string("%any");
}
- if (msg->add_conn.other.cert)
+ if (other_ca == NULL)
{
- load_end_certificate(msg->add_conn.other.cert, &other_id, this->stroke_logger);
+ other_ca = identification_create_from_string("%any");
}
-
+ this->logger->log(this->logger, CONTROL|LEVEL1, " my ca: '%s'", my_ca->get_string(my_ca));
+ this->logger->log(this->logger, CONTROL|LEVEL1, " other ca:'%s'", other_ca->get_string(other_ca));
+
connection = connection_create(msg->add_conn.name, msg->add_conn.ikev2,
my_host, other_host,
RSA_DIGITAL_SIGNATURE);
/**
* list various information
*/
-static void stroke_list(private_stroke_t *this, stroke_msg_t *msg, bool utc)
+static void stroke_list(private_stroke_t *this, stroke_msg_t *msg)
{
- if (msg->type == STR_LIST_CERTS)
+ if (msg->list.flags & LIST_CERTS)
+ {
+ charon->credentials->log_certificates(charon->credentials, this->stroke_logger, msg->list.utc);
+ }
+ if (msg->list.flags & LIST_CACERTS)
{
- charon->credentials->log_certificates(charon->credentials, this->stroke_logger, utc);
- charon->credentials->log_ca_certificates(charon->credentials, this->stroke_logger, utc);
+ charon->credentials->log_ca_certificates(charon->credentials, this->stroke_logger, msg->list.utc);
}
}
case STR_LOGLEVEL:
stroke_loglevel(this, msg);
break;
- case STR_LIST_CERTS:
- stroke_list(this, msg, FALSE);
+ case STR_LIST:
+ stroke_list(this, msg);
break;
default:
this->logger->log(this->logger, ERROR, "received invalid stroke");
#include <types.h>
#include "stroke.h"
+#include "stroke_keywords.h"
+
+struct stroke_token {
+ char *name;
+ stroke_keyword_t kw;
+};
static char* push_string(stroke_msg_t *msg, char *string)
{
return send_stroke_msg(&msg);
}
-static int show_status(char *mode, char *connection)
+static int show_status(stroke_keyword_t kw, char *connection)
{
stroke_msg_t msg;
- if (strcmp(mode, "statusall") == 0)
- msg.type = STR_STATUS_ALL;
- else
- msg.type = STR_STATUS;
-
+ msg.type = (kw == STROKE_STATUS)? STR_STATUS:STR_STATUS_ALL;
msg.length = offsetof(stroke_msg_t, buffer);
msg.status.name = push_string(&msg, connection);
return send_stroke_msg(&msg);
}
-static int list_certs(void)
+static int list_flags[] = {
+ LIST_CERTS,
+ LIST_CACERTS,
+ LIST_CRLS,
+ LIST_ALL
+};
+
+static int list(stroke_keyword_t kw, bool utc)
{
stroke_msg_t msg;
- msg.type = STR_LIST_CERTS;
+ msg.type = STR_LIST;
msg.length = offsetof(stroke_msg_t, buffer);
+ msg.list.utc = utc;
+ msg.list.flags = list_flags[kw - STROKE_LIST_FIRST];
return send_stroke_msg(&msg);
}
int main(int argc, char *argv[])
{
+ const stroke_token_t *token;
int res = 0;
- char *op;
-
+
if (argc < 2)
{
exit_usage(NULL);
}
- op = argv[1];
+ token = in_word_set(argv[1], strlen(argv[1]));
- if (streq(op, "status") || streq(op, "statusall"))
- {
- res = show_status(op, argc > 2 ? argv[2] : NULL);
- }
- else if (streq(op, "listcerts") || streq(op, "listall"))
- {
- res = list_certs();
- }
- else if (streq(op, "up"))
- {
- if (argc < 3)
- {
- exit_usage("\"up\" needs a connection name");
- }
- res = initiate_connection(argv[2]);
- }
- else if (streq(op, "down"))
+ if (token == NULL)
{
- if (argc < 3)
- {
- exit_usage("\"down\" needs a connection name");
- }
- res = terminate_connection(argv[2]);
+ exit_usage("unknown keyword");
}
- else if (streq(op, "add"))
- {
- if (argc < 11)
- {
- exit_usage("\"add\" needs more parameters...");
- }
- res = add_connection(argv[2],
- argv[3], argv[4],
- argv[5], argv[6],
- argv[7], argv[8],
- atoi(argv[9]), atoi(argv[10]));
- }
- else if (streq(op, "delete"))
- {
- if (argc < 3)
- {
- exit_usage("\"delete\" needs a connection name");
- }
- res = del_connection(argv[2]);
- }
- else if (streq(op, "logtype"))
- {
- if (argc < 5)
- {
- exit_usage("\"logtype\" needs more parameters...");
- }
- res = set_logtype(argv[2], argv[3], atoi(argv[4]));
- }
- else if (streq(op, "loglevel"))
- {
- if (argc < 4)
- {
- exit_usage("\"logtype\" needs more parameters...");
- }
- res = set_loglevel(argv[2], atoi(argv[3]));
- }
- else
+
+ switch (token->kw)
{
- exit_usage(NULL);
+ case STROKE_ADD:
+ if (argc < 11)
+ {
+ exit_usage("\"add\" needs more parameters...");
+ }
+ res = add_connection(argv[2],
+ argv[3], argv[4],
+ argv[5], argv[6],
+ argv[7], argv[8],
+ atoi(argv[9]), atoi(argv[10]));
+ break;
+ case STROKE_DELETE:
+ case STROKE_DEL:
+ if (argc < 3)
+ {
+ exit_usage("\"delete\" needs a connection name");
+ }
+ res = del_connection(argv[2]);
+ break;
+ case STROKE_UP:
+ if (argc < 3)
+ {
+ exit_usage("\"up\" needs a connection name");
+ }
+ res = initiate_connection(argv[2]);
+ break;
+ case STROKE_DOWN:
+ if (argc < 3)
+ {
+ exit_usage("\"down\" needs a connection name");
+ }
+ res = terminate_connection(argv[2]);
+ break;
+ case STROKE_LOGTYPE:
+ if (argc < 5)
+ {
+ exit_usage("\"logtype\" needs more parameters...");
+ }
+ res = set_logtype(argv[2], argv[3], atoi(argv[4]));
+ break;
+ case STROKE_LOGLEVEL:
+ if (argc < 4)
+ {
+ exit_usage("\"logtype\" needs more parameters...");
+ }
+ res = set_loglevel(argv[2], atoi(argv[3]));
+ break;
+ case STROKE_STATUS:
+ case STROKE_STATUSALL:
+ res = show_status(token->kw, argc > 2 ? argv[2] : NULL);
+ break;
+ case STROKE_LIST_CERTS:
+ case STROKE_LIST_CACERTS:
+ case STROKE_LIST_CRLS:
+ case STROKE_LIST_ALL:
+ res = list(token->kw, argc > 2 && streq(argv[2], "--utc"));
+ break;
+ default:
+ exit_usage(NULL);
}
-
return res;
}