diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2006-06-12 08:43:46 +0000 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2006-06-12 08:43:46 +0000 |
commit | 5347233204f7631609c5a2bc2f4fd65f6ed6773c (patch) | |
tree | 8544572ea1eeee8871bb285cf41ff9f0c6825eb0 | |
parent | 299dbc604f48ed5a44029600b01d77477ecc1fd4 (diff) | |
download | strongswan-5347233204f7631609c5a2bc2f4fd65f6ed6773c.tar.bz2 strongswan-5347233204f7631609c5a2bc2f4fd65f6ed6773c.tar.xz |
support for stroke listcerts|listcacerts|listall and left|rightca=
-rwxr-xr-x | src/charon/threads/stroke_interface.c | 146 | ||||
-rw-r--r-- | src/starter/starterstroke.c | 2 | ||||
-rw-r--r-- | src/stroke/Makefile.am | 6 | ||||
-rw-r--r-- | src/stroke/stroke.c | 157 | ||||
-rw-r--r-- | src/stroke/stroke.h | 19 |
5 files changed, 200 insertions, 130 deletions
diff --git a/src/charon/threads/stroke_interface.c b/src/charon/threads/stroke_interface.c index 2ca9a0a4a..a98d4761a 100755 --- a/src/charon/threads/stroke_interface.c +++ b/src/charon/threads/stroke_interface.c @@ -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, 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; @@ -147,8 +147,9 @@ static void load_end_certificate(const char *filename, identification_t **idp, l id = subject; *idp = id->clone(id); } - charon->credentials->add_certificate(charon->credentials, cert); + return charon->credentials->add_certificate(charon->credentials, cert); } + return NULL; } /** @@ -158,7 +159,11 @@ 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, *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; @@ -194,6 +199,30 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg) 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) @@ -240,10 +269,6 @@ 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); @@ -251,62 +276,70 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg) 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); @@ -492,12 +525,15 @@ static void stroke_status(private_stroke_t *this, stroke_msg_t *msg) /** * 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); } } @@ -694,8 +730,8 @@ static void stroke_receive(private_stroke_t *this) 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"); diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c index b4f85b360..25a66a0f3 100644 --- a/src/starter/starterstroke.c +++ b/src/starter/starterstroke.c @@ -110,7 +110,7 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta { 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->ca = push_string(msg, conn_end->ca); 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; diff --git a/src/stroke/Makefile.am b/src/stroke/Makefile.am index 0de0134de..761c3b861 100644 --- a/src/stroke/Makefile.am +++ b/src/stroke/Makefile.am @@ -1,4 +1,8 @@ ipsec_PROGRAMS = stroke -stroke_SOURCES = stroke.c stroke.h +stroke_SOURCES = stroke.c stroke.h stroke_keywords.c stroke_keywords.h INCLUDES = -I$(top_srcdir)/src/libstrongswan +EXTRA_DIST = stroke_keywords.txt + +stroke_keywords.c: stroke_keywords.txt stroke_keywords.h + $(GPERF) -C -G -t < stroke_keywords.txt > stroke_keywords.c diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c index d5357222f..b8b0cc093 100644 --- a/src/stroke/stroke.c +++ b/src/stroke/stroke.c @@ -27,6 +27,12 @@ #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) { @@ -156,26 +162,31 @@ static int terminate_connection(char *name) 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); } @@ -250,80 +261,82 @@ static void exit_usage(char *error) 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; } diff --git a/src/stroke/stroke.h b/src/stroke/stroke.h index e9bdedd0e..0544ca8bf 100644 --- a/src/stroke/stroke.h +++ b/src/stroke/stroke.h @@ -30,6 +30,15 @@ #define STROKE_BUF_LEN 2048 +/** + * Definition of the LIST flags + */ +#define LIST_NONE 0x0000 /* don't list anything */ +#define LIST_CERTS 0x0001 /* list all host/user certs */ +#define LIST_CACERTS 0x0002 /* list all ca certs */ +#define LIST_CRLS 0x0004 /* list all crls */ +#define LIST_ALL 0x0007 /* all list options */ + typedef struct stroke_end_t stroke_end_t; struct stroke_end_t { @@ -72,7 +81,7 @@ struct stroke_msg_t { /* set the verbosity of a logging context */ STR_LOGLEVEL, /* show list of locally loaded certificates */ - STR_LIST_CERTS + STR_LIST /* more to come */ } type; @@ -96,16 +105,24 @@ struct stroke_msg_t { stroke_end_t me, other; } add_conn; + /* data for STR_LOGTYPE */ struct { char *context; char *type; int enable; } logtype; + /* data for STR_LOGLEVEL */ struct { char *context; int level; } loglevel; + + /* data for STR_LIST */ + struct { + u_int flags; + bool utc; + } list; }; char buffer[STROKE_BUF_LEN]; }; |