Annotation of embedaddon/strongswan/src/pt-tls-client/pt-tls-client.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2013-2015 Andreas Steffen
! 3: * HSR Hochschule fuer Technik Rapperswil
! 4: *
! 5: * Copyright (C) 2010-2013 Martin Willi
! 6: * Copyright (C) 2010-2013 revosec AG
! 7: *
! 8: * This program is free software; you can redistribute it and/or modify it
! 9: * under the terms of the GNU General Public License as published by the
! 10: * Free Software Foundation; either version 2 of the License, or (at your
! 11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 12: *
! 13: * This program is distributed in the hope that it will be useful, but
! 14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 16: * for more details.
! 17: */
! 18:
! 19: #include <unistd.h>
! 20: #include <stdio.h>
! 21: #include <sys/types.h>
! 22: #include <getopt.h>
! 23: #include <errno.h>
! 24: #include <string.h>
! 25: #include <stdlib.h>
! 26: #ifdef HAVE_SYSLOG
! 27: #include <syslog.h>
! 28: #endif
! 29:
! 30: #include <pt_tls.h>
! 31: #include <pt_tls_client.h>
! 32: #include <tnc/tnc.h>
! 33: #include <tls.h>
! 34:
! 35: #include <library.h>
! 36: #include <utils/debug.h>
! 37: #include <credentials/sets/mem_cred.h>
! 38: #include <utils/optionsfrom.h>
! 39:
! 40: /**
! 41: * Print usage information
! 42: */
! 43: static void usage(FILE *out)
! 44: {
! 45: fprintf(out,
! 46: "Usage: pt-tls --connect <hostname|address> [--port <port>]\n"
! 47: " [--certid <hex>|--cert <file>]+ [--keyid <hex>|--key <file>]\n"
! 48: " [--key-type rsa|ecdsa] [--client <client-id>]\n"
! 49: " [--secret <password>] [--mutual] [--quiet]\n"
! 50: " [--debug <level>] [--options <filename>]\n");
! 51: }
! 52:
! 53: /**
! 54: * Client routine
! 55: */
! 56: static int client(char *address, uint16_t port, char *identity)
! 57: {
! 58: pt_tls_client_t *assessment;
! 59: tls_t *tnccs;
! 60: identification_t *server_id, *client_id;
! 61: host_t *server_ip, *client_ip;
! 62: status_t status;
! 63:
! 64: server_ip = host_create_from_dns(address, AF_UNSPEC, port);
! 65: if (!server_ip)
! 66: {
! 67: return 1;
! 68: }
! 69:
! 70: client_ip = host_create_any(server_ip->get_family(server_ip));
! 71: if (!client_ip)
! 72: {
! 73: server_ip->destroy(server_ip);
! 74: return 1;
! 75: }
! 76: server_id = identification_create_from_string(address);
! 77: client_id = identification_create_from_string(identity);
! 78:
! 79: tnccs = (tls_t*)tnc->tnccs->create_instance(tnc->tnccs, TNCCS_2_0, FALSE,
! 80: server_id, client_id, server_ip, client_ip,
! 81: TNC_IFT_TLS_2_0, NULL);
! 82: client_ip->destroy(client_ip);
! 83:
! 84: if (!tnccs)
! 85: {
! 86: fprintf(stderr, "loading TNCCS failed: %s\n", PLUGINS);
! 87: server_ip->destroy(server_ip);
! 88: server_id->destroy(server_id);
! 89: client_id->destroy(client_id);
! 90: return 1;
! 91: }
! 92: assessment = pt_tls_client_create(server_ip, server_id, client_id);
! 93: status = assessment->run_assessment(assessment, (tnccs_t*)tnccs);
! 94: assessment->destroy(assessment);
! 95: tnccs->destroy(tnccs);
! 96:
! 97: return (status != SUCCESS);
! 98: }
! 99:
! 100:
! 101: /**
! 102: * In-Memory credential set
! 103: */
! 104: static mem_cred_t *creds;
! 105:
! 106: /**
! 107: * Load certificate from file
! 108: */
! 109: static bool load_certificate(char *certid, char *filename)
! 110: {
! 111: certificate_t *cert;
! 112: chunk_t chunk;
! 113:
! 114: if (certid)
! 115: {
! 116: chunk = chunk_from_hex(chunk_create(certid, strlen(certid)), NULL);
! 117: cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
! 118: BUILD_PKCS11_KEYID, chunk, BUILD_END);
! 119: }
! 120: else
! 121: {
! 122: cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
! 123: BUILD_FROM_FILE, filename, BUILD_END);
! 124: }
! 125: if (!cert)
! 126: {
! 127: DBG1(DBG_TLS, "loading certificate from '%s' failed",
! 128: certid ? certid : filename);
! 129: return FALSE;
! 130: }
! 131: creds->add_cert(creds, TRUE, cert);
! 132: return TRUE;
! 133: }
! 134:
! 135: /**
! 136: * Load private key from file
! 137: */
! 138: static bool load_key(char *keyid, char *filename, key_type_t type)
! 139: {
! 140: private_key_t *key;
! 141: chunk_t chunk;
! 142:
! 143: if (keyid)
! 144: {
! 145: chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
! 146: key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
! 147: BUILD_PKCS11_KEYID, chunk, BUILD_END);
! 148: chunk_free(&chunk);
! 149: }
! 150: else
! 151: {
! 152: key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
! 153: BUILD_FROM_FILE, filename, BUILD_END);
! 154: }
! 155: if (!key)
! 156: {
! 157: DBG1(DBG_TLS, "loading key from '%s' failed", keyid ? keyid : filename);
! 158: return FALSE;
! 159: }
! 160: creds->add_key(creds, key);
! 161: return TRUE;
! 162: }
! 163:
! 164: /**
! 165: * Logging and debug level
! 166: */
! 167: static bool log_to_stderr = TRUE;
! 168: #ifdef HAVE_SYSLOG
! 169: static bool log_to_syslog = TRUE;
! 170: #endif /* HAVE_SYSLOG */
! 171: static level_t default_loglevel = 1;
! 172:
! 173: static void dbg_pt_tls(debug_t group, level_t level, char *fmt, ...)
! 174: {
! 175: va_list args;
! 176:
! 177: if (level <= default_loglevel)
! 178: {
! 179: if (log_to_stderr)
! 180: {
! 181: va_start(args, fmt);
! 182: vfprintf(stderr, fmt, args);
! 183: va_end(args);
! 184: fprintf(stderr, "\n");
! 185: }
! 186: #ifdef HAVE_SYSLOG
! 187: if (log_to_syslog)
! 188: {
! 189: char buffer[8192];
! 190: char *current = buffer, *next;
! 191:
! 192: /* write in memory buffer first */
! 193: va_start(args, fmt);
! 194: vsnprintf(buffer, sizeof(buffer), fmt, args);
! 195: va_end(args);
! 196:
! 197: /* do a syslog with every line */
! 198: while (current)
! 199: {
! 200: next = strchr(current, '\n');
! 201: if (next)
! 202: {
! 203: *(next++) = '\0';
! 204: }
! 205: syslog(LOG_INFO, "%s\n", current);
! 206: current = next;
! 207: }
! 208: }
! 209: #endif /* HAVE_SYSLOG */
! 210: }
! 211: }
! 212:
! 213: /**
! 214: * Initialize logging to stderr/syslog
! 215: */
! 216: static void init_log(const char *program)
! 217: {
! 218: dbg = dbg_pt_tls;
! 219:
! 220: if (log_to_stderr)
! 221: {
! 222: setbuf(stderr, NULL);
! 223: }
! 224: #ifdef HAVE_SYSLOG
! 225: if (log_to_syslog)
! 226: {
! 227: openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
! 228: }
! 229: #endif /* HAVE_SYSLOG */
! 230: }
! 231:
! 232: /**
! 233: * Handles --optionsfrom arguments
! 234: */
! 235: options_t *options;
! 236:
! 237: /**
! 238: * Cleanup
! 239: */
! 240: static void cleanup()
! 241: {
! 242: lib->processor->cancel(lib->processor);
! 243: lib->credmgr->remove_set(lib->credmgr, &creds->set);
! 244: creds->destroy(creds);
! 245: options->destroy(options);
! 246: libtnccs_deinit();
! 247: library_deinit();
! 248: }
! 249:
! 250: /**
! 251: * Initialize library
! 252: */
! 253: static void init()
! 254: {
! 255: plugin_feature_t features[] = {
! 256: PLUGIN_NOOP,
! 257: PLUGIN_PROVIDE(CUSTOM, "pt-tls-client"),
! 258: PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
! 259: };
! 260: library_init(NULL, "pt-tls-client");
! 261: libtnccs_init();
! 262:
! 263: init_log("pt-tls-client");
! 264: options = options_create();
! 265:
! 266: lib->plugins->add_static_features(lib->plugins, "pt-tls-client", features,
! 267: countof(features), TRUE, NULL, NULL);
! 268: if (!lib->plugins->load(lib->plugins,
! 269: lib->settings->get_str(lib->settings, "pt-tls-client.load", PLUGINS)))
! 270: {
! 271: exit(SS_RC_INITIALIZATION_FAILED);
! 272: }
! 273: lib->plugins->status(lib->plugins, LEVEL_CTRL);
! 274:
! 275: creds = mem_cred_create();
! 276: lib->credmgr->add_set(lib->credmgr, &creds->set);
! 277:
! 278: atexit(cleanup);
! 279: }
! 280:
! 281: int main(int argc, char *argv[])
! 282: {
! 283: char *address = NULL, *identity = "%any", *secret = NULL;
! 284: char *keyid = NULL, *key_file = NULL;
! 285: key_type_t key_type = KEY_RSA;
! 286: int port = PT_TLS_PORT;
! 287:
! 288: init();
! 289:
! 290: while (TRUE)
! 291: {
! 292: struct option long_opts[] = {
! 293: {"help", no_argument, NULL, 'h' },
! 294: {"connect", required_argument, NULL, 'c' },
! 295: {"client", required_argument, NULL, 'i' },
! 296: {"secret", required_argument, NULL, 's' },
! 297: {"port", required_argument, NULL, 'p' },
! 298: {"certid", required_argument, NULL, 'X' },
! 299: {"cert", required_argument, NULL, 'x' },
! 300: {"keyid", required_argument, NULL, 'K' },
! 301: {"key", required_argument, NULL, 'k' },
! 302: {"key-type", required_argument, NULL, 't' },
! 303: {"mutual", no_argument, NULL, 'm' },
! 304: {"quiet", no_argument, NULL, 'q' },
! 305: {"debug", required_argument, NULL, 'd' },
! 306: {"options", required_argument, NULL, '+' },
! 307: {"optionsfrom", required_argument, NULL, '+' },
! 308: {0,0,0,0 }
! 309: };
! 310: switch (getopt_long(argc, argv, "hc:i:s:p:x:K:k:t:mqd:+:", long_opts,
! 311: NULL))
! 312: {
! 313: case EOF:
! 314: break;
! 315: case 'h': /* --help */
! 316: usage(stdout);
! 317: return 0;
! 318: case 'X': /* --certid <hex> */
! 319: if (!load_certificate(optarg, NULL))
! 320: {
! 321: return 1;
! 322: }
! 323: continue;
! 324: case 'x': /* --cert <file> */
! 325: if (!load_certificate(NULL, optarg))
! 326: {
! 327: return 1;
! 328: }
! 329: continue;
! 330: case 'K': /* --keyid <hex> */
! 331: keyid = optarg;
! 332: continue;
! 333: case 'k': /* --key <file> */
! 334: key_file = optarg;
! 335: continue;
! 336: case 't': /* --key-type <type> */
! 337: if (strcaseeq(optarg, "ecdsa"))
! 338: {
! 339: key_type = KEY_ECDSA;
! 340: }
! 341: else if (strcaseeq(optarg, "rsa"))
! 342: {
! 343: key_type = KEY_RSA;
! 344: }
! 345: else
! 346: {
! 347: key_type = KEY_ANY;
! 348: }
! 349: continue;
! 350: case 'c': /* --connect <hostname|address> */
! 351: if (address)
! 352: {
! 353: usage(stderr);
! 354: return 1;
! 355: }
! 356: address = optarg;
! 357: continue;
! 358: case 'i': /* --client <client-id> */
! 359: identity = optarg;
! 360: continue;
! 361: case 's': /* --secret <password> */
! 362: secret = optarg;
! 363: continue;
! 364: case 'p': /* --port <port> */
! 365: port = atoi(optarg);
! 366: continue;
! 367: case 'm': /* --mutual */
! 368: lib->settings->set_bool(lib->settings,
! 369: "%s.plugins.tnccs-20.mutual", TRUE, lib->ns);
! 370: continue;
! 371: case 'q': /* --quiet */
! 372: log_to_stderr = FALSE;
! 373: continue;
! 374: case 'd': /* --debug <level> */
! 375: default_loglevel = atoi(optarg);
! 376: continue;
! 377: case '+': /* --optionsfrom <filename> */
! 378: if (!options->from(options, optarg, &argc, &argv, optind))
! 379: {
! 380: return 1;
! 381: }
! 382: continue;
! 383: default:
! 384: usage(stderr);
! 385: return 1;
! 386: }
! 387: break;
! 388: }
! 389: if (!address)
! 390: {
! 391: usage(stderr);
! 392: return 1;
! 393: }
! 394: if ((keyid || key_file) && !load_key(keyid, key_file, key_type))
! 395: {
! 396: return 1;
! 397: }
! 398: if (secret)
! 399: {
! 400: creds->add_shared(creds, shared_key_create(SHARED_EAP,
! 401: chunk_clone(chunk_from_str(secret))),
! 402: identification_create_from_string(identity), NULL);
! 403: }
! 404: return client(address, port, identity);
! 405: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>