From: Martin Willi Date: Tue, 26 Mar 2013 14:42:06 +0000 (+0100) Subject: charon-cmd: load certificates and RSA private keys X-Git-Tag: 5.1.0dr1~154^2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2baa7bbedb7d1ffd149fc326dfe28ed81dbcd09f;p=thirdparty%2Fstrongswan.git charon-cmd: load certificates and RSA private keys --- diff --git a/src/charon-cmd/Makefile.am b/src/charon-cmd/Makefile.am index ff360c18c9..2c9f1ba1fb 100644 --- a/src/charon-cmd/Makefile.am +++ b/src/charon-cmd/Makefile.am @@ -3,6 +3,7 @@ sbin_PROGRAMS = charon-cmd charon_cmd_SOURCES = \ cmd/cmd_options.h cmd/cmd_options.c \ cmd/cmd_connection.h cmd/cmd_connection.c \ + cmd/cmd_creds.h cmd/cmd_creds.c \ charon-cmd.c charon-cmd.o : $(top_builddir)/config.status diff --git a/src/charon-cmd/charon-cmd.c b/src/charon-cmd/charon-cmd.c index 90cc8b6fae..4969c96453 100644 --- a/src/charon-cmd/charon-cmd.c +++ b/src/charon-cmd/charon-cmd.c @@ -34,6 +34,7 @@ #include "cmd/cmd_options.h" #include "cmd/cmd_connection.h" +#include "cmd/cmd_creds.h" /** * Loglevel configuration @@ -45,6 +46,11 @@ static level_t levels[DBG_MAX]; */ static cmd_connection_t *conn; +/** + * Credential backend + */ +static cmd_creds_t *creds; + /** * hook in library for debugging messages */ @@ -75,6 +81,14 @@ static void cleanup_conn() DESTROY_IF(conn); } +/** + * Clean up credentials atexit() + */ +static void cleanup_creds() +{ + DESTROY_IF(creds); +} + /** * Run the daemon and handle unix signals */ @@ -253,7 +267,8 @@ static void handle_arguments(int argc, char *argv[]) printf("%s, strongSwan %s\n", "charon-cmd", VERSION); exit(0); default: - if (conn->handle(conn, opt, optarg)) + if (conn->handle(conn, opt, optarg) || + creds->handle(creds, opt, optarg)) { continue; } @@ -300,24 +315,12 @@ int main(int argc, char *argv[]) { levels[group] = LEVEL_CTRL; } - conn = cmd_connection_create(); - atexit(cleanup_conn); - - handle_arguments(argc, argv); + charon->load_loggers(charon, levels, TRUE); if (!lookup_uid_gid()) { exit(SS_RC_INITIALIZATION_FAILED); } - charon->load_loggers(charon, levels, TRUE); - - if (uname(&utsname) != 0) - { - memset(&utsname, 0, sizeof(utsname)); - } - DBG1(DBG_DMN, "Starting charon-cmd IKE client (strongSwan %s, %s %s, %s)", - VERSION, utsname.sysname, utsname.release, utsname.machine); - if (!charon->initialize(charon, lib->settings->get_str(lib->settings, "charon-cmd.load", PLUGINS))) { @@ -328,6 +331,20 @@ int main(int argc, char *argv[]) exit(SS_RC_INITIALIZATION_FAILED); } + conn = cmd_connection_create(); + atexit(cleanup_conn); + creds = cmd_creds_create(); + atexit(cleanup_creds); + + handle_arguments(argc, argv); + + if (uname(&utsname) != 0) + { + memset(&utsname, 0, sizeof(utsname)); + } + DBG1(DBG_DMN, "Starting charon-cmd IKE client (strongSwan %s, %s %s, %s)", + VERSION, utsname.sysname, utsname.release, utsname.machine); + /* add handler for SEGV and ILL, * INT, TERM and HUP are handled by sigwait() in run() */ action.sa_handler = segv_handler; diff --git a/src/charon-cmd/cmd/cmd_creds.c b/src/charon-cmd/cmd/cmd_creds.c new file mode 100644 index 0000000000..45f16522b4 --- /dev/null +++ b/src/charon-cmd/cmd/cmd_creds.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2013 Martin Willi + * Copyright (C) 2013 revosec AG + * + * 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 . + * + * 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 "cmd_creds.h" + +#include +#include + +typedef struct private_cmd_creds_t private_cmd_creds_t; + +/** + * Private data of an cmd_creds_t object. + */ +struct private_cmd_creds_t { + + /** + * Public cmd_creds_t interface. + */ + cmd_creds_t public; + + /** + * Reused in-memory credential set + */ + mem_cred_t *creds; +}; + +/** + * Load a trusted certificate from path + */ +static void load_cert(private_cmd_creds_t *this, char *path) +{ + certificate_t *cert; + + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_FROM_FILE, path, BUILD_END); + if (!cert) + { + DBG1(DBG_CFG, "loading certificate from '%s' failed", path); + exit(1); + } + this->creds->add_cert(this->creds, TRUE, cert); +} + +/** + * Load a private key of given kind from path + */ +static void load_key(private_cmd_creds_t *this, key_type_t type, char *path) +{ + private_key_t *privkey; + + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type, + BUILD_FROM_FILE, path, BUILD_END); + if (!privkey) + { + DBG1(DBG_CFG, "loading %N private key from '%s' failed", + key_type_names, type, path); + exit(1); + } + this->creds->add_key(this->creds, privkey); +} + +METHOD(cmd_creds_t, handle, bool, + private_cmd_creds_t *this, cmd_option_type_t opt, char *arg) +{ + switch (opt) + { + case CMD_OPT_CERT: + load_cert(this, arg); + break; + case CMD_OPT_RSA: + load_key(this, KEY_RSA, arg); + break; + default: + return FALSE; + } + return TRUE; +} + +METHOD(cmd_creds_t, destroy, void, + private_cmd_creds_t *this) +{ + lib->credmgr->remove_set(lib->credmgr, &this->creds->set); + this->creds->destroy(this->creds); + free(this); +} + +/** + * See header + */ +cmd_creds_t *cmd_creds_create() +{ + private_cmd_creds_t *this; + + INIT(this, + .public = { + .handle = _handle, + .destroy = _destroy, + }, + .creds = mem_cred_create(), + ); + + lib->credmgr->add_set(lib->credmgr, &this->creds->set); + + return &this->public; +} diff --git a/src/charon-cmd/cmd/cmd_creds.h b/src/charon-cmd/cmd/cmd_creds.h new file mode 100644 index 0000000000..053e596a52 --- /dev/null +++ b/src/charon-cmd/cmd/cmd_creds.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013 Martin Willi + * Copyright (C) 2013 revosec AG + * + * 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 . + * + * 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 cmd_creds cmd_creds + * @{ @ingroup cmd + */ + +#ifndef CMD_CREDS_H_ +#define CMD_CREDS_H_ + +#include + +#include "cmd_options.h" + +typedef struct cmd_creds_t cmd_creds_t; + +/** + * Credential backend providing certificates, private keys and shared secrets. + */ +struct cmd_creds_t { + + /** + * Handle a command line options related to credentials. + * + * @param opt option to handle + * @param arg option argument + * @return TRUE if option handled + */ + bool (*handle)(cmd_creds_t *this, cmd_option_type_t opt, char *arg); + + /** + * Destroy a cmd_creds_t. + */ + void (*destroy)(cmd_creds_t *this); +}; + +/** + * Create a cmd_creds instance. + */ +cmd_creds_t *cmd_creds_create(); + +#endif /** CMD_CREDS_H_ @}*/ diff --git a/src/charon-cmd/cmd/cmd_options.c b/src/charon-cmd/cmd/cmd_options.c index 899cdd119c..4344bf2372 100644 --- a/src/charon-cmd/cmd/cmd_options.c +++ b/src/charon-cmd/cmd/cmd_options.c @@ -29,4 +29,8 @@ cmd_option_t cmd_options[CMD_OPT_COUNT] = { "DNS name or address to connect to" }, { CMD_OPT_IDENTITY, "identity", required_argument, "identity", "identity the client uses for the IKE exchange" }, + { CMD_OPT_CERT, "cert", required_argument, "path", + "trusted certificate, for authentication or trust chain validation" }, + { CMD_OPT_RSA, "rsa", required_argument, "path", + "RSA private key to use for authentication" }, }; diff --git a/src/charon-cmd/cmd/cmd_options.h b/src/charon-cmd/cmd/cmd_options.h index 81fb54fe13..358108d0b5 100644 --- a/src/charon-cmd/cmd/cmd_options.h +++ b/src/charon-cmd/cmd/cmd_options.h @@ -32,6 +32,8 @@ enum cmd_option_type_t { CMD_OPT_VERSION, CMD_OPT_HOST, CMD_OPT_IDENTITY, + CMD_OPT_CERT, + CMD_OPT_RSA, CMD_OPT_COUNT };