diff options
Diffstat (limited to 'src/swanctl/commands')
-rw-r--r-- | src/swanctl/commands/list_algs.c | 104 | ||||
-rw-r--r-- | src/swanctl/commands/list_certs.c | 603 | ||||
-rw-r--r-- | src/swanctl/commands/list_sas.c | 13 | ||||
-rw-r--r-- | src/swanctl/commands/load_conns.c | 9 | ||||
-rw-r--r-- | src/swanctl/commands/load_creds.c | 47 | ||||
-rw-r--r-- | src/swanctl/commands/redirect.c | 132 | ||||
-rw-r--r-- | src/swanctl/commands/stats.c | 12 |
7 files changed, 395 insertions, 525 deletions
diff --git a/src/swanctl/commands/list_algs.c b/src/swanctl/commands/list_algs.c new file mode 100644 index 000000000..616e6ff75 --- /dev/null +++ b/src/swanctl/commands/list_algs.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2015 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. + */ + +#include "command.h" + +#include <errno.h> + +CALLBACK(algs, int, + void *null, vici_res_t *res, char *name, void *value, int len) +{ + if (chunk_printable(chunk_create(value, len), NULL, ' ')) + { + printf(" %s[%.*s]\n", name, len, value); + } + return 0; +} + +CALLBACK(types, int, + void *null, vici_res_t *res, char *name) +{ + printf("%s:\n", name); + return vici_parse_cb(res, NULL, algs, NULL, NULL); +} + +static int algorithms(vici_conn_t *conn) +{ + vici_req_t *req; + vici_res_t *res; + char *arg; + command_format_options_t format = COMMAND_FORMAT_NONE; + int ret; + + while (TRUE) + { + switch (command_getopt(&arg)) + { + case 'h': + return command_usage(NULL); + case 'P': + format |= COMMAND_FORMAT_PRETTY; + /* fall through to raw */ + case 'r': + format |= COMMAND_FORMAT_RAW; + continue; + case EOF: + break; + default: + return command_usage("invalid --list-algs option"); + } + break; + } + + req = vici_begin("get-algorithms"); + res = vici_submit(req, conn); + if (!res) + { + ret = errno; + fprintf(stderr, "get-algorithms request failed: %s\n", strerror(errno)); + return ret; + } + if (format & COMMAND_FORMAT_RAW) + { + vici_dump(res, "get-algorithms reply", format & COMMAND_FORMAT_PRETTY, + stdout); + } + else + { + if (vici_parse_cb(res, types, NULL, NULL, NULL) != 0) + { + fprintf(stderr, "parsing get-algorithms reply failed: %s\n", + strerror(errno)); + } + } + vici_free_res(res); + return 0; +} + +/** + * Register the command. + */ +static void __attribute__ ((constructor))reg() +{ + command_register((command_t) { + algorithms, 'g', "list-algs", "show loaded algorithms", + {"[--raw|--pretty]"}, + { + {"help", 'h', 0, "show usage information"}, + {"raw", 'r', 0, "dump raw response message"}, + {"pretty", 'P', 0, "dump raw response message in pretty print"}, + } + }); +} diff --git a/src/swanctl/commands/list_certs.c b/src/swanctl/commands/list_certs.c index 167f8d848..e9c964771 100644 --- a/src/swanctl/commands/list_certs.c +++ b/src/swanctl/commands/list_certs.c @@ -24,14 +24,17 @@ #include <asn1/asn1.h> #include <asn1/oid.h> #include <credentials/certificates/certificate.h> -#include <credentials/certificates/x509.h> -#include <credentials/certificates/crl.h> -#include <credentials/certificates/ac.h> +#include <credentials/certificates/certificate_printer.h> #include <selectors/traffic_selector.h> #include "command.h" /** + * Static certificate printer object + */ +static certificate_printer_t *cert_printer = NULL; + +/** * Print PEM encoding of a certificate */ static void print_pem(certificate_t *cert) @@ -49,541 +52,99 @@ static void print_pem(certificate_t *cert) } } -/** - * Print public key information - */ -static void print_pubkey(public_key_t *key, bool has_privkey) -{ - chunk_t chunk; - - printf("pubkey: %N %d bits", key_type_names, key->get_type(key), - key->get_keysize(key)); - if (has_privkey) - { - printf(", has private key"); - } - printf("\n"); - if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &chunk)) - { - printf("keyid: %#B\n", &chunk); - } - if (key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &chunk)) - { - printf("subjkey: %#B\n", &chunk); - } -} - -/** - * Print X509 specific certificate information - */ -static void print_x509(x509_t *x509) +CALLBACK(list_cb, void, + command_format_options_t *format, char *name, vici_res_t *res) { - enumerator_t *enumerator; - identification_t *id; - traffic_selector_t *block; - chunk_t chunk; - bool first; - char *uri; - int len, explicit, inhibit; - x509_flag_t flags; - x509_cdp_t *cdp; - x509_cert_policy_t *policy; - x509_policy_mapping_t *mapping; - - chunk = chunk_skip_zero(x509->get_serial(x509)); - printf("serial: %#B\n", &chunk); - - first = TRUE; - enumerator = x509->create_subjectAltName_enumerator(x509); - while (enumerator->enumerate(enumerator, &id)) - { - if (first) - { - printf("altNames: "); - first = FALSE; - } - else - { - printf(", "); - } - printf("%Y", id); - } - if (!first) - { - printf("\n"); - } - enumerator->destroy(enumerator); - - flags = x509->get_flags(x509); - printf("flags: "); - if (flags & X509_CA) - { - printf("CA "); - } - if (flags & X509_CRL_SIGN) - { - printf("CRLSign "); - } - if (flags & X509_AA) - { - printf("AA "); - } - if (flags & X509_OCSP_SIGNER) - { - printf("OCSP "); - } - if (flags & X509_AA) - { - printf("AA "); - } - if (flags & X509_SERVER_AUTH) - { - printf("serverAuth "); - } - if (flags & X509_CLIENT_AUTH) - { - printf("clientAuth "); - } - if (flags & X509_IKE_INTERMEDIATE) - { - printf("iKEIntermediate "); - } - if (flags & X509_SELF_SIGNED) - { - printf("self-signed "); - } - printf("\n"); - - first = TRUE; - enumerator = x509->create_crl_uri_enumerator(x509); - while (enumerator->enumerate(enumerator, &cdp)) - { - if (first) - { - printf("CRL URIs: %s", cdp->uri); - first = FALSE; - } - else - { - printf(" %s", cdp->uri); - } - if (cdp->issuer) - { - printf(" (CRL issuer: %Y)", cdp->issuer); - } - printf("\n"); - } - enumerator->destroy(enumerator); - - first = TRUE; - enumerator = x509->create_ocsp_uri_enumerator(x509); - while (enumerator->enumerate(enumerator, &uri)) - { - if (first) - { - printf("OCSP URIs: %s\n", uri); - first = FALSE; - } - else - { - printf(" %s\n", uri); - } - } - enumerator->destroy(enumerator); - - len = x509->get_constraint(x509, X509_PATH_LEN); - if (len != X509_NO_CONSTRAINT) - { - printf("pathlen: %d\n", len); - } - - first = TRUE; - enumerator = x509->create_name_constraint_enumerator(x509, TRUE); - while (enumerator->enumerate(enumerator, &id)) - { - if (first) - { - printf("Permitted NameConstraints:\n"); - first = FALSE; - } - printf(" %Y\n", id); - } - enumerator->destroy(enumerator); - first = TRUE; - enumerator = x509->create_name_constraint_enumerator(x509, FALSE); - while (enumerator->enumerate(enumerator, &id)) - { - if (first) - { - printf("Excluded NameConstraints:\n"); - first = FALSE; - } - printf(" %Y\n", id); - } - enumerator->destroy(enumerator); - - first = TRUE; - enumerator = x509->create_cert_policy_enumerator(x509); - while (enumerator->enumerate(enumerator, &policy)) - { - char *oid; - - if (first) - { - printf("CertificatePolicies:\n"); - first = FALSE; - } - oid = asn1_oid_to_string(policy->oid); - if (oid) - { - printf(" %s\n", oid); - free(oid); - } - else - { - printf(" %#B\n", &policy->oid); - } - if (policy->cps_uri) - { - printf(" CPS: %s\n", policy->cps_uri); - } - if (policy->unotice_text) - { - printf(" Notice: %s\n", policy->unotice_text); - - } - } - enumerator->destroy(enumerator); - - first = TRUE; - enumerator = x509->create_policy_mapping_enumerator(x509); - while (enumerator->enumerate(enumerator, &mapping)) - { - char *issuer_oid, *subject_oid; - - if (first) - { - printf("PolicyMappings:\n"); - first = FALSE; - } - issuer_oid = asn1_oid_to_string(mapping->issuer); - subject_oid = asn1_oid_to_string(mapping->subject); - printf(" %s => %s\n", issuer_oid, subject_oid); - free(issuer_oid); - free(subject_oid); - } - enumerator->destroy(enumerator); - - explicit = x509->get_constraint(x509, X509_REQUIRE_EXPLICIT_POLICY); - inhibit = x509->get_constraint(x509, X509_INHIBIT_POLICY_MAPPING); - len = x509->get_constraint(x509, X509_INHIBIT_ANY_POLICY); + certificate_t *cert; + certificate_type_t type; + x509_flag_t flag = X509_NONE; + identification_t *subject = NULL; + time_t not_before = UNDEFINED_TIME; + time_t not_after = UNDEFINED_TIME; + chunk_t t_ch; + bool has_privkey; + char *str; + void *buf; + int len; - if (explicit != X509_NO_CONSTRAINT || inhibit != X509_NO_CONSTRAINT || - len != X509_NO_CONSTRAINT) + if (*format & COMMAND_FORMAT_RAW) { - printf("PolicyConstraints:\n"); - if (explicit != X509_NO_CONSTRAINT) - { - printf(" requireExplicitPolicy: %d\n", explicit); - } - if (inhibit != X509_NO_CONSTRAINT) - { - printf(" inhibitPolicyMapping: %d\n", inhibit); - } - if (len != X509_NO_CONSTRAINT) - { - printf(" inhibitAnyPolicy: %d\n", len); - } + vici_dump(res, "list-cert event", *format & COMMAND_FORMAT_PRETTY, + stdout); + return; } - chunk = x509->get_authKeyIdentifier(x509); - if (chunk.ptr) + buf = vici_find(res, &len, "data"); + if (!buf) { - printf("authkeyId: %#B\n", &chunk); + fprintf(stderr, "received incomplete certificate data\n"); + return; } + has_privkey = streq(vici_find_str(res, "no", "has_privkey"), "yes"); - chunk = x509->get_subjectKeyIdentifier(x509); - if (chunk.ptr) + str = vici_find_str(res, "ANY", "type"); + if (!enum_from_name(certificate_type_names, str, &type) || type == CERT_ANY) { - printf("subjkeyId: %#B\n", &chunk); + fprintf(stderr, "unsupported certificate type '%s'\n", str); + return; } - if (x509->get_flags(x509) & X509_IP_ADDR_BLOCKS) + if (type == CERT_X509) { - first = TRUE; - printf("addresses: "); - enumerator = x509->create_ipAddrBlock_enumerator(x509); - while (enumerator->enumerate(enumerator, &block)) + str = vici_find_str(res, "ANY", "flag"); + if (!enum_from_name(x509_flag_names, str, &flag) || flag == X509_ANY) { - if (first) - { - first = FALSE; - } - else - { - printf(", "); - } - printf("%R", block); + fprintf(stderr, "unsupported certificate flag '%s'\n", str); + return; } - enumerator->destroy(enumerator); - printf("\n"); } -} - -/** - * Print CRL specific information - */ -static void print_crl(crl_t *crl) -{ - enumerator_t *enumerator; - time_t ts; - crl_reason_t reason; - chunk_t chunk; - int count = 0; - bool first; - char buf[64]; - struct tm tm; - x509_cdp_t *cdp; - - chunk = chunk_skip_zero(crl->get_serial(crl)); - printf("serial: %#B\n", &chunk); - - if (crl->is_delta_crl(crl, &chunk)) - { - chunk = chunk_skip_zero(chunk); - printf("delta CRL: for serial %#B\n", &chunk); - } - chunk = crl->get_authKeyIdentifier(crl); - printf("authKeyId: %#B\n", &chunk); - - first = TRUE; - enumerator = crl->create_delta_crl_uri_enumerator(crl); - while (enumerator->enumerate(enumerator, &cdp)) + if (type == CERT_TRUSTED_PUBKEY) { - if (first) + str = vici_find_str(res, NULL, "subject"); + if (str) { - printf("freshest: %s", cdp->uri); - first = FALSE; + subject = identification_create_from_string(str); } - else + str = vici_find_str(res, NULL, "not-before"); + if (str) { - printf(" %s", cdp->uri); + t_ch = chunk_from_str(str); + not_before = asn1_to_time(&t_ch, ASN1_GENERALIZEDTIME); } - if (cdp->issuer) + str = vici_find_str(res, NULL, "not-after"); + if (str) { - printf(" (CRL issuer: %Y)", cdp->issuer); + t_ch = chunk_from_str(str); + not_after = asn1_to_time(&t_ch, ASN1_GENERALIZEDTIME); } - printf("\n"); + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, type, + BUILD_BLOB_ASN1_DER, chunk_create(buf, len), + BUILD_NOT_BEFORE_TIME, not_before, + BUILD_NOT_AFTER_TIME, not_after, + BUILD_SUBJECT, subject, BUILD_END); + DESTROY_IF(subject); } - enumerator->destroy(enumerator); - - enumerator = crl->create_enumerator(crl); - while (enumerator->enumerate(enumerator, &chunk, &ts, &reason)) - { - count++; - } - enumerator->destroy(enumerator); - - printf("%d revoked certificate%s%s\n", count, - count == 1 ? "" : "s", count ? ":" : ""); - enumerator = crl->create_enumerator(crl); - while (enumerator->enumerate(enumerator, &chunk, &ts, &reason)) - { - chunk = chunk_skip_zero(chunk); - localtime_r(&ts, &tm); - strftime(buf, sizeof(buf), "%F %T", &tm); - printf(" %#B: %s, %N\n", &chunk, buf, crl_reason_names, reason); - count++; - } - enumerator->destroy(enumerator); -} - -/** - * Print AC specific information - */ -static void print_ac(ac_t *ac) -{ - ac_group_type_t type; - identification_t *id; - enumerator_t *groups; - chunk_t chunk; - bool first = TRUE; - - chunk = chunk_skip_zero(ac->get_serial(ac)); - printf("serial: %#B\n", &chunk); - - id = ac->get_holderIssuer(ac); - if (id) - { - printf("hissuer: \"%Y\"\n", id); - } - chunk = chunk_skip_zero(ac->get_holderSerial(ac)); - if (chunk.ptr) + else { - printf("hserial: %#B\n", &chunk); + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, type, + BUILD_BLOB_ASN1_DER, chunk_create(buf, len), + BUILD_END); } - groups = ac->create_group_enumerator(ac); - while (groups->enumerate(groups, &type, &chunk)) + if (cert) { - int oid; - char *str; - - if (first) + if (*format & COMMAND_FORMAT_PEM) { - printf("groups: "); - first = FALSE; + print_pem(cert); } else { - printf(" "); - } - switch (type) - { - case AC_GROUP_TYPE_STRING: - printf("%.*s", (int)chunk.len, chunk.ptr); - break; - case AC_GROUP_TYPE_OID: - oid = asn1_known_oid(chunk); - if (oid == OID_UNKNOWN) - { - str = asn1_oid_to_string(chunk); - if (str) - { - printf("%s", str); - free(str); - } - else - { - printf("OID:%#B", &chunk); - } - } - else - { - printf("%s", oid_names[oid].name); - } - break; - case AC_GROUP_TYPE_OCTETS: - printf("%#B", &chunk); - break; + cert_printer->print_caption(cert_printer, type, flag); + cert_printer->print(cert_printer, cert, has_privkey); } - printf("\n"); - } - groups->destroy(groups); - - chunk = ac->get_authKeyIdentifier(ac); - if (chunk.ptr) - { - printf("authkey: %#B\n", &chunk); - } -} - -/** - * Print certificate information - */ -static void print_cert(certificate_t *cert, bool has_privkey) -{ - time_t now, notAfter, notBefore; - public_key_t *key; - - now = time(NULL); - - printf("cert: %N\n", certificate_type_names, cert->get_type(cert)); - if (cert->get_type(cert) != CERT_X509_CRL) - { - printf("subject: \"%Y\"\n", cert->get_subject(cert)); - } - printf("issuer: \"%Y\"\n", cert->get_issuer(cert)); - - cert->get_validity(cert, &now, ¬Before, ¬After); - printf("validity: not before %T, ", ¬Before, FALSE); - if (now < notBefore) - { - printf("not valid yet (valid in %V)\n", &now, ¬Before); + cert->destroy(cert); } else { - printf("ok\n"); - } - printf(" not after %T, ", ¬After, FALSE); - if (now > notAfter) - { - printf("expired (%V ago)\n", &now, ¬After); - } - else - { - printf("ok (expires in %V)\n", &now, ¬After); - } - - switch (cert->get_type(cert)) - { - case CERT_X509: - print_x509((x509_t*)cert); - break; - case CERT_X509_CRL: - print_crl((crl_t*)cert); - break; - case CERT_X509_AC: - print_ac((ac_t*)cert); - break; - default: - fprintf(stderr, "parsing certificate subtype %N not implemented\n", - certificate_type_names, cert->get_type(cert)); - break; - } - key = cert->get_public_key(cert); - if (key) - { - print_pubkey(key, has_privkey); - key->destroy(key); - } - printf("\n"); -} - -CALLBACK(list_cb, void, - command_format_options_t *format, char *name, vici_res_t *res) -{ - if (*format & COMMAND_FORMAT_RAW) - { - vici_dump(res, "list-cert event", *format & COMMAND_FORMAT_PRETTY, - stdout); - } - else - { - certificate_type_t type; - certificate_t *cert; - void *buf; - int len; - bool has_privkey; - - buf = vici_find(res, &len, "data"); - has_privkey = streq(vici_find_str(res, "no", "has_privkey"), "yes"); - if (enum_from_name(certificate_type_names, - vici_find_str(res, "ANY", "type"), &type) && - type != CERT_ANY && buf) - { - cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, type, - BUILD_BLOB_ASN1_DER, chunk_create(buf, len), - BUILD_END); - if (cert) - { - if (*format & COMMAND_FORMAT_PEM) - { - print_pem(cert); - } - else - { - print_cert(cert, has_privkey); - } - cert->destroy(cert); - } - else - { - fprintf(stderr, "parsing certificate failed\n"); - } - } - else - { - fprintf(stderr, "received incomplete certificate data\n"); - } + fprintf(stderr, "parsing certificate failed\n"); } } @@ -592,7 +153,8 @@ static int list_certs(vici_conn_t *conn) vici_req_t *req; vici_res_t *res; command_format_options_t format = COMMAND_FORMAT_NONE; - char *arg, *subject = NULL, *type = NULL; + char *arg, *subject = NULL, *type = NULL, *flag = NULL; + bool detailed = TRUE, utc = FALSE; int ret; while (TRUE) @@ -607,6 +169,9 @@ static int list_certs(vici_conn_t *conn) case 't': type = arg; continue; + case 'f': + flag = arg; + continue; case 'p': format |= COMMAND_FORMAT_PEM; continue; @@ -616,6 +181,12 @@ static int list_certs(vici_conn_t *conn) case 'r': format |= COMMAND_FORMAT_RAW; continue; + case 'S': + detailed = FALSE; + continue; + case 'U': + utc = TRUE; + continue; case EOF: break; default: @@ -631,19 +202,28 @@ static int list_certs(vici_conn_t *conn) return ret; } req = vici_begin("list-certs"); + if (type) { vici_add_key_valuef(req, "type", "%s", type); } + if (flag) + { + vici_add_key_valuef(req, "flag", "%s", flag); + } if (subject) { vici_add_key_valuef(req, "subject", "%s", subject); } + cert_printer = certificate_printer_create(stdout, detailed, utc); + res = vici_submit(req, conn); if (!res) { ret = errno; fprintf(stderr, "list-certs request failed: %s\n", strerror(errno)); + cert_printer->destroy(cert_printer); + cert_printer = NULL; return ret; } if (format & COMMAND_FORMAT_RAW) @@ -652,6 +232,9 @@ static int list_certs(vici_conn_t *conn) stdout); } vici_free_res(res); + + cert_printer->destroy(cert_printer); + cert_printer = NULL; return 0; } @@ -662,15 +245,19 @@ static void __attribute__ ((constructor))reg() { command_register((command_t) { list_certs, 'x', "list-certs", "list stored certificates", - {"[--subject <dn/san>] [--type X509|X509_AC|X509_CRL] [--pem] " - "[--raw|--pretty]"}, + {"[--subject <dn/san>] [--pem]", + "[--type x509|x509_ac|x509_crl|ocsp_response|pubkey]", + "[--flag none|ca|aa|ocsp|any] [--raw|--pretty|--short|--utc]"}, { {"help", 'h', 0, "show usage information"}, {"subject", 's', 1, "filter by certificate subject"}, {"type", 't', 1, "filter by certificate type"}, + {"flag", 'f', 1, "filter by X.509 certificate flag"}, {"pem", 'p', 0, "print PEM encoding of certificate"}, {"raw", 'r', 0, "dump raw response message"}, {"pretty", 'P', 0, "dump raw response message in pretty print"}, + {"short", 'S', 0, "omit some certificate details"}, + {"utc", 'U', 0, "use UTC for time fields"}, } }); } diff --git a/src/swanctl/commands/list_sas.c b/src/swanctl/commands/list_sas.c index 93dd7ed85..fd080227d 100644 --- a/src/swanctl/commands/list_sas.c +++ b/src/swanctl/commands/list_sas.c @@ -2,6 +2,9 @@ * Copyright (C) 2014 Martin Willi * Copyright (C) 2014 revosec AG * + * Copyright (C) 2016 Andreas Steffen + * HSR 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 @@ -198,16 +201,18 @@ CALLBACK(ike_sa, int, ike->get(ike, "state"), ike->get(ike, "version"), ike->get(ike, "initiator-spi"), ike->get(ike, "responder-spi")); - printf(" local '%s' @ %s", - ike->get(ike, "local-id"), ike->get(ike, "local-host")); + printf(" local '%s' @ %s[%s]", + ike->get(ike, "local-id"), ike->get(ike, "local-host"), + ike->get(ike, "local-port")); if (ike->get(ike, "local-vips")) { printf(" [%s]", ike->get(ike, "local-vips")); } printf("\n"); - printf(" remote '%s' @ %s", - ike->get(ike, "remote-id"), ike->get(ike, "remote-host")); + printf(" remote '%s' @ %s[%s]", + ike->get(ike, "remote-id"), ike->get(ike, "remote-host"), + ike->get(ike, "remote-port")); if (ike->get(ike, "remote-eap-id")) { printf(" EAP: '%s'", ike->get(ike, "remote-eap-id")); diff --git a/src/swanctl/commands/load_conns.c b/src/swanctl/commands/load_conns.c index 6ee8b8785..bbc700d5c 100644 --- a/src/swanctl/commands/load_conns.c +++ b/src/swanctl/commands/load_conns.c @@ -59,6 +59,7 @@ static bool is_file_list_key(char *key) char *keys[] = { "certs", "cacerts", + "pubkeys" }; int i; @@ -112,12 +113,18 @@ static bool add_file_list_key(vici_req_t *req, char *key, char *value) SWANCTL_X509DIR, DIRECTORY_SEPARATOR, token); token = buf; } - if (streq(key, "cacerts")) + else if (streq(key, "cacerts")) { snprintf(buf, sizeof(buf), "%s%s%s", SWANCTL_X509CADIR, DIRECTORY_SEPARATOR, token); token = buf; } + else if (streq(key, "pubkeys")) + { + snprintf(buf, sizeof(buf), "%s%s%s", + SWANCTL_PUBKEYDIR, DIRECTORY_SEPARATOR, token); + token = buf; + } } map = chunk_map(token, FALSE); diff --git a/src/swanctl/commands/load_creds.c b/src/swanctl/commands/load_creds.c index d2ebc22eb..4647934f7 100644 --- a/src/swanctl/commands/load_creds.c +++ b/src/swanctl/commands/load_creds.c @@ -2,6 +2,9 @@ * Copyright (C) 2014 Martin Willi * Copyright (C) 2014 revosec AG * + * Copyright (C) 2015 Andreas Steffen + * HSR 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 @@ -27,11 +30,14 @@ #include <credentials/sets/callback_cred.h> #include <credentials/containers/pkcs12.h> +#include <vici_cert_info.h> + /** * Load a single certificate over vici */ static bool load_cert(vici_conn_t *conn, command_format_options_t format, - char *dir, char *type, chunk_t data) + char *dir, certificate_type_t type, x509_flag_t flag, + chunk_t data) { vici_req_t *req; vici_res_t *res; @@ -39,7 +45,11 @@ static bool load_cert(vici_conn_t *conn, command_format_options_t format, req = vici_begin("load-cert"); - vici_add_key_valuef(req, "type", "%s", type); + vici_add_key_valuef(req, "type", "%N", certificate_type_names, type); + if (type == CERT_X509) + { + vici_add_key_valuef(req, "flag", "%N", x509_flag_names, flag); + } vici_add_key_value(req, "data", data.ptr, data.len); res = vici_submit(req, conn); @@ -61,7 +71,7 @@ static bool load_cert(vici_conn_t *conn, command_format_options_t format, } else { - printf("loaded %s certificate from '%s'\n", type, dir); + printf("loaded certificate from '%s'\n", dir); } vici_free_res(res); return ret; @@ -71,13 +81,17 @@ static bool load_cert(vici_conn_t *conn, command_format_options_t format, * Load certficiates from a directory */ static void load_certs(vici_conn_t *conn, command_format_options_t format, - char *type, char *dir) + char *type_str, char *dir) { enumerator_t *enumerator; + certificate_type_t type; + x509_flag_t flag; struct stat st; chunk_t *map; char *path; + vici_cert_info_from_str(type_str, &type, &flag); + enumerator = enumerator_create_directory(dir); if (enumerator) { @@ -88,7 +102,7 @@ static void load_certs(vici_conn_t *conn, command_format_options_t format, map = chunk_map(path, FALSE); if (map) { - load_cert(conn, format, path, type, *map); + load_cert(conn, format, path, type, flag, *map); chunk_unmap(map); } else @@ -171,6 +185,9 @@ static bool load_key_anytype(vici_conn_t *conn, command_format_options_t format, case KEY_ECDSA: loaded = load_key(conn, format, path, "ecdsa", encoding); break; + case KEY_BLISS: + loaded = load_key(conn, format, path, "bliss", encoding); + break; default: fprintf(stderr, "unsupported key type in '%s'\n", path); break; @@ -237,6 +254,7 @@ static bool determine_credtype(char *type, credential_type_t *credtype, { "pkcs8", CRED_PRIVATE_KEY, KEY_ANY, }, { "rsa", CRED_PRIVATE_KEY, KEY_RSA, }, { "ecdsa", CRED_PRIVATE_KEY, KEY_ECDSA, }, + { "bliss", CRED_PRIVATE_KEY, KEY_BLISS, }, { "pkcs12", CRED_CONTAINER, CONTAINER_PKCS12, }, }; int i; @@ -439,7 +457,8 @@ static bool load_pkcs12(vici_conn_t *conn, command_format_options_t format, loaded = FALSE; if (cert->get_encoding(cert, CERT_ASN1_DER, &encoding)) { - loaded = load_cert(conn, format, path, "x509", encoding); + loaded = load_cert(conn, format, path, CERT_X509, X509_NONE, + encoding); if (loaded) { fprintf(stderr, " %Y\n", cert->get_subject(cert)); @@ -548,6 +567,7 @@ static bool load_secret(vici_conn_t *conn, settings_t *cfg, "ike", "rsa", "ecdsa", + "bliss", "pkcs8", "pkcs12", }; @@ -672,14 +692,17 @@ int load_creds_cfg(vici_conn_t *conn, command_format_options_t format, } } - load_certs(conn, format, "x509", SWANCTL_X509DIR); - load_certs(conn, format, "x509ca", SWANCTL_X509CADIR); - load_certs(conn, format, "x509aa", SWANCTL_X509AADIR); - load_certs(conn, format, "x509crl", SWANCTL_X509CRLDIR); - load_certs(conn, format, "x509ac", SWANCTL_X509ACDIR); + load_certs(conn, format, "x509", SWANCTL_X509DIR); + load_certs(conn, format, "x509ca", SWANCTL_X509CADIR); + load_certs(conn, format, "x509ocsp", SWANCTL_X509OCSPDIR); + load_certs(conn, format, "x509aa", SWANCTL_X509AADIR); + load_certs(conn, format, "x509ac", SWANCTL_X509ACDIR); + load_certs(conn, format, "x509crl", SWANCTL_X509CRLDIR); + load_certs(conn, format, "pubkey", SWANCTL_PUBKEYDIR); - load_keys(conn, format, noprompt, cfg, "rsa", SWANCTL_RSADIR); + load_keys(conn, format, noprompt, cfg, "rsa", SWANCTL_RSADIR); load_keys(conn, format, noprompt, cfg, "ecdsa", SWANCTL_ECDSADIR); + load_keys(conn, format, noprompt, cfg, "bliss", SWANCTL_BLISSDIR); load_keys(conn, format, noprompt, cfg, "pkcs8", SWANCTL_PKCS8DIR); load_containers(conn, format, noprompt, cfg, "pkcs12", SWANCTL_PKCS12DIR); diff --git a/src/swanctl/commands/redirect.c b/src/swanctl/commands/redirect.c new file mode 100644 index 000000000..6edb936e6 --- /dev/null +++ b/src/swanctl/commands/redirect.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2015 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. + */ + +#include "command.h" + +#include <errno.h> + +static int redirect(vici_conn_t *conn) +{ + vici_req_t *req; + vici_res_t *res; + command_format_options_t format = COMMAND_FORMAT_NONE; + char *arg, *peer_ip = NULL, *peer_id = NULL, *ike = NULL, *gateway = NULL; + int ret = 0, ike_id = 0; + + while (TRUE) + { + switch (command_getopt(&arg)) + { + case 'h': + return command_usage(NULL); + case 'P': + format |= COMMAND_FORMAT_PRETTY; + /* fall through to raw */ + case 'r': + format |= COMMAND_FORMAT_RAW; + continue; + case 'i': + ike = arg; + continue; + case 'I': + ike_id = atoi(arg); + continue; + case 'p': + peer_ip = arg; + continue; + case 'd': + peer_id = arg; + continue; + case 'g': + gateway = arg; + continue; + case EOF: + break; + default: + return command_usage("invalid --redirect option"); + } + break; + } + req = vici_begin("redirect"); + if (ike) + { + vici_add_key_valuef(req, "ike", "%s", ike); + } + if (ike_id) + { + vici_add_key_valuef(req, "ike-id", "%d", ike_id); + } + if (peer_ip) + { + vici_add_key_valuef(req, "peer-ip", "%s", peer_ip); + } + if (peer_id) + { + vici_add_key_valuef(req, "peer-id", "%s", peer_id); + } + if (gateway) + { + vici_add_key_valuef(req, "gateway", "%s", gateway); + } + res = vici_submit(req, conn); + if (!res) + { + ret = errno; + fprintf(stderr, "redirect request failed: %s\n", strerror(errno)); + return ret; + } + if (format & COMMAND_FORMAT_RAW) + { + vici_dump(res, "redirect reply", format & COMMAND_FORMAT_PRETTY, + stdout); + } + else + { + if (streq(vici_find_str(res, "no", "success"), "yes")) + { + printf("redirect completed successfully\n"); + } + else + { + fprintf(stderr, "redirect failed: %s\n", + vici_find_str(res, "", "errmsg")); + ret = 1; + } + } + vici_free_res(res); + return ret; +} + +/** + * Register the command. + */ +static void __attribute__ ((constructor))reg() +{ + command_register((command_t) { + redirect, 'd', "redirect", "redirect an IKE_SA", + {"--ike <name> | --ike-id <id> | --peer-ip <ip|subnet|range>", + "--peer-id <id|wildcards> | --gateway <ip|fqdn> [--raw|--pretty]"}, + { + {"help", 'h', 0, "show usage information"}, + {"ike", 'i', 1, "redirect by IKE_SA name"}, + {"ike-id", 'I', 1, "redirect by IKE_SA unique identifier"}, + {"peer-ip", 'p', 1, "redirect by client IP"}, + {"peer-id", 'd', 1, "redirect by IKE_SA name"}, + {"gateway", 'g', 1, "target gateway (IP or FQDN)"}, + {"raw", 'r', 0, "dump raw response message"}, + {"pretty", 'P', 0, "dump raw response message in pretty print"}, + } + }); +} diff --git a/src/swanctl/commands/stats.c b/src/swanctl/commands/stats.c index a28ca83ba..e734c66ff 100644 --- a/src/swanctl/commands/stats.c +++ b/src/swanctl/commands/stats.c @@ -15,8 +15,17 @@ #include "command.h" +#include <collections/hashtable.h> + #include <errno.h> +CALLBACK(list, int, + hashtable_t *sa, vici_res_t *res, char *name, void *value, int len) +{ + printf(" %.*s", len, value); + return 0; +} + static int stats(vici_conn_t *conn) { vici_req_t *req; @@ -98,6 +107,9 @@ static int stats(vici_conn_t *conn) vici_find_str(res, "", "mallinfo.used"), vici_find_str(res, "", "mallinfo.free")); } + printf("loaded plugins:"); + vici_parse_cb(res, NULL, NULL, list, NULL); + printf("\n"); } vici_free_res(res); return 0; |