Return to pt-tls-client.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / pt-tls-client |
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: }