Annotation of embedaddon/strongswan/src/libtnccs/plugins/tnccs_11/tnccs_11.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2010-2015 Andreas Steffen
! 3: * HSR Hochschule fuer Technik Rapperswil
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "tnccs_11.h"
! 17: #include "batch/tnccs_batch.h"
! 18: #include "messages/tnccs_msg.h"
! 19: #include "messages/imc_imv_msg.h"
! 20: #include "messages/tnccs_error_msg.h"
! 21: #include "messages/tnccs_preferred_language_msg.h"
! 22: #include "messages/tnccs_reason_strings_msg.h"
! 23: #include "messages/tnccs_recommendation_msg.h"
! 24:
! 25: #include <tncif_names.h>
! 26: #include <tncif_pa_subtypes.h>
! 27:
! 28: #include <tnc/tnc.h>
! 29: #include <tnc/imc/imc_manager.h>
! 30: #include <tnc/imv/imv_manager.h>
! 31: #include <tnc/tnccs/tnccs.h>
! 32: #include <tnc/tnccs/tnccs_manager.h>
! 33:
! 34: #include <utils/debug.h>
! 35: #include <threading/mutex.h>
! 36:
! 37: typedef struct private_tnccs_11_t private_tnccs_11_t;
! 38:
! 39: /**
! 40: * Private data of a tnccs_11_t object.
! 41: */
! 42: struct private_tnccs_11_t {
! 43:
! 44: /**
! 45: * Public tnccs_t interface.
! 46: */
! 47: tnccs_t public;
! 48:
! 49: /**
! 50: * TNCC if TRUE, TNCS if FALSE
! 51: */
! 52: bool is_server;
! 53:
! 54: /**
! 55: * Server identity
! 56: */
! 57: identification_t *server_id;
! 58:
! 59: /**
! 60: * Client identity
! 61: */
! 62: identification_t *peer_id;
! 63:
! 64: /**
! 65: * Server IP address
! 66: */
! 67: host_t *server_ip;
! 68:
! 69: /**
! 70: * Client IP address
! 71: */
! 72: host_t *peer_ip;
! 73:
! 74: /**
! 75: * Underlying TNC IF-T transport protocol
! 76: */
! 77: tnc_ift_type_t transport;
! 78:
! 79: /**
! 80: * Type of TNC client authentication
! 81: */
! 82: uint32_t auth_type;
! 83:
! 84: /**
! 85: * Connection ID assigned to this TNCCS connection
! 86: */
! 87: TNC_ConnectionID connection_id;
! 88:
! 89: /**
! 90: * Last TNCCS batch ID
! 91: */
! 92: int batch_id;
! 93:
! 94: /**
! 95: * TNCCS batch being constructed
! 96: */
! 97: tnccs_batch_t *batch;
! 98:
! 99: /**
! 100: * Maximum PA-TNC message size
! 101: */
! 102: size_t max_msg_len;
! 103:
! 104: /**
! 105: * Mutex locking the batch in construction
! 106: */
! 107: mutex_t *mutex;
! 108:
! 109: /**
! 110: * Flag set while processing
! 111: */
! 112: bool fatal_error;
! 113:
! 114: /**
! 115: * Flag set by TNCCS-Recommendation message
! 116: */
! 117: bool delete_state;
! 118:
! 119: /**
! 120: * SendMessage() by IMC/IMV only allowed if flag is set
! 121: */
! 122: bool send_msg;
! 123:
! 124: /**
! 125: * Flag set by IMC/IMV RequestHandshakeRetry() function
! 126: */
! 127: bool request_handshake_retry;
! 128:
! 129: /**
! 130: * Set of IMV recommendations (TNC Server only)
! 131: */
! 132: recommendations_t *recs;
! 133:
! 134: /**
! 135: * Callback function to communicate recommendation (TNC Server only)
! 136: */
! 137: tnccs_cb_t callback;
! 138:
! 139: /**
! 140: * reference count
! 141: */
! 142: refcount_t ref;
! 143:
! 144: };
! 145:
! 146: METHOD(tnccs_t, send_msg, TNC_Result,
! 147: private_tnccs_11_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
! 148: TNC_UInt32 msg_flags,
! 149: TNC_BufferReference msg,
! 150: TNC_UInt32 msg_len,
! 151: TNC_VendorID msg_vid,
! 152: TNC_MessageSubtype msg_subtype)
! 153: {
! 154: tnccs_msg_t *tnccs_msg;
! 155: TNC_MessageType msg_type;
! 156: enum_name_t *pa_subtype_names;
! 157:
! 158: if (!this->send_msg)
! 159: {
! 160: DBG1(DBG_TNC, "%s %u not allowed to call SendMessage()",
! 161: this->is_server ? "IMV" : "IMC",
! 162: this->is_server ? imv_id : imc_id);
! 163: return TNC_RESULT_ILLEGAL_OPERATION;
! 164: }
! 165: if (msg_vid > TNC_VENDORID_ANY || msg_subtype > TNC_SUBTYPE_ANY)
! 166: {
! 167: return TNC_RESULT_NO_LONG_MESSAGE_TYPES;
! 168: }
! 169: msg_type = (msg_vid << 8) | msg_subtype;
! 170:
! 171: pa_subtype_names = get_pa_subtype_names(msg_vid);
! 172: if (pa_subtype_names)
! 173: {
! 174: DBG2(DBG_TNC, "creating IMC-IMV message type '%N/%N' 0x%06x/0x%02x",
! 175: pen_names, msg_vid, pa_subtype_names, msg_subtype,
! 176: msg_vid, msg_subtype);
! 177: }
! 178: else
! 179: {
! 180: DBG2(DBG_TNC, "creating IMC-IMV message type '%N' 0x%06x/0x%02x",
! 181: pen_names, msg_vid, msg_vid, msg_subtype);
! 182: }
! 183: tnccs_msg = imc_imv_msg_create(msg_type, chunk_create(msg, msg_len));
! 184:
! 185: /* adding an IMC-IMV Message to TNCCS batch */
! 186: this->mutex->lock(this->mutex);
! 187: if (!this->batch)
! 188: {
! 189: this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
! 190: }
! 191: this->batch->add_msg(this->batch, tnccs_msg);
! 192: this->mutex->unlock(this->mutex);
! 193: return TNC_RESULT_SUCCESS;
! 194: }
! 195:
! 196: /**
! 197: * Handle a single TNCCS message according to its type
! 198: */
! 199: static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg)
! 200: {
! 201: switch (msg->get_type(msg))
! 202: {
! 203: case IMC_IMV_MSG:
! 204: {
! 205: imc_imv_msg_t *imc_imv_msg;
! 206: TNC_MessageType msg_type;
! 207: chunk_t msg_body;
! 208: uint32_t msg_vid, msg_subtype;
! 209: enum_name_t *pa_subtype_names;
! 210:
! 211: imc_imv_msg = (imc_imv_msg_t*)msg;
! 212: msg_type = imc_imv_msg->get_msg_type(imc_imv_msg);
! 213: msg_body = imc_imv_msg->get_msg_body(imc_imv_msg);
! 214: msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY;
! 215: msg_subtype = msg_type & TNC_SUBTYPE_ANY;
! 216:
! 217: pa_subtype_names = get_pa_subtype_names(msg_vid);
! 218: if (pa_subtype_names)
! 219: {
! 220: DBG2(DBG_TNC, "handling IMC-IMV message type '%N/%N' 0x%06x/0x%02x",
! 221: pen_names, msg_vid, pa_subtype_names, msg_subtype,
! 222: msg_vid, msg_subtype);
! 223: }
! 224: else
! 225: {
! 226: DBG2(DBG_TNC, "handling IMC-IMV message type '%N' 0x%06x/0x%02x",
! 227: pen_names, msg_vid, msg_vid, msg_subtype);
! 228: }
! 229:
! 230: this->send_msg = TRUE;
! 231: if (this->is_server)
! 232: {
! 233: tnc->imvs->receive_message(tnc->imvs, this->connection_id,
! 234: FALSE, msg_body.ptr, msg_body.len,
! 235: msg_vid, msg_subtype, 0, TNC_IMVID_ANY);
! 236: }
! 237: else
! 238: {
! 239: tnc->imcs->receive_message(tnc->imcs, this->connection_id,
! 240: FALSE, msg_body.ptr, msg_body.len,
! 241: msg_vid, msg_subtype, 0, TNC_IMCID_ANY);
! 242: }
! 243: this->send_msg = FALSE;
! 244: break;
! 245: }
! 246: case TNCCS_MSG_RECOMMENDATION:
! 247: {
! 248: tnccs_recommendation_msg_t *rec_msg;
! 249: TNC_IMV_Action_Recommendation rec;
! 250: TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE;
! 251:
! 252: rec_msg = (tnccs_recommendation_msg_t*)msg;
! 253: rec = rec_msg->get_recommendation(rec_msg);
! 254: if (this->is_server)
! 255: {
! 256: DBG1(DBG_TNC, "ignoring NCCS-Recommendation message from "
! 257: " TNC client");
! 258: break;
! 259: }
! 260: DBG1(DBG_TNC, "TNC recommendation is '%N'",
! 261: TNC_IMV_Action_Recommendation_names, rec);
! 262: switch (rec)
! 263: {
! 264: case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
! 265: state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
! 266: break;
! 267: case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
! 268: state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
! 269: break;
! 270: case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
! 271: default:
! 272: state = TNC_CONNECTION_STATE_ACCESS_NONE;
! 273: }
! 274: tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
! 275: state);
! 276: this->delete_state = TRUE;
! 277: break;
! 278: }
! 279: case TNCCS_MSG_ERROR:
! 280: {
! 281: tnccs_error_msg_t *err_msg;
! 282: tnccs_error_type_t error_type;
! 283: char *error_msg;
! 284:
! 285: err_msg = (tnccs_error_msg_t*)msg;
! 286: error_msg = err_msg->get_message(err_msg, &error_type);
! 287: DBG1(DBG_TNC, "received '%N' TNCCS-Error: %s",
! 288: tnccs_error_type_names, error_type, error_msg);
! 289:
! 290: /* we assume that all errors are fatal */
! 291: this->fatal_error = TRUE;
! 292: break;
! 293: }
! 294: case TNCCS_MSG_PREFERRED_LANGUAGE:
! 295: {
! 296: tnccs_preferred_language_msg_t *lang_msg;
! 297: char *lang;
! 298:
! 299: lang_msg = (tnccs_preferred_language_msg_t*)msg;
! 300: lang = lang_msg->get_preferred_language(lang_msg);
! 301:
! 302: DBG2(DBG_TNC, "setting preferred language to '%s'", lang);
! 303: this->recs->set_preferred_language(this->recs,
! 304: chunk_create(lang, strlen(lang)));
! 305: break;
! 306: }
! 307: case TNCCS_MSG_REASON_STRINGS:
! 308: {
! 309: tnccs_reason_strings_msg_t *reason_msg;
! 310: chunk_t reason_string, reason_lang;
! 311:
! 312: reason_msg = (tnccs_reason_strings_msg_t*)msg;
! 313: reason_string = reason_msg->get_reason(reason_msg, &reason_lang);
! 314: DBG2(DBG_TNC, "reason string is '%.*s'", (int)reason_string.len,
! 315: reason_string.ptr);
! 316: DBG2(DBG_TNC, "language code is '%.*s'", (int)reason_lang.len,
! 317: reason_lang.ptr);
! 318: break;
! 319: }
! 320: default:
! 321: break;
! 322: }
! 323: }
! 324:
! 325: METHOD(tls_t, process, status_t,
! 326: private_tnccs_11_t *this, void *buf, size_t buflen)
! 327: {
! 328: chunk_t data;
! 329: tnccs_batch_t *batch;
! 330: tnccs_msg_t *msg;
! 331: enumerator_t *enumerator;
! 332: status_t status;
! 333:
! 334: if (this->is_server && !this->connection_id)
! 335: {
! 336: this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
! 337: TNCCS_1_1, (tnccs_t*)this, _send_msg,
! 338: &this->request_handshake_retry,
! 339: this->max_msg_len, &this->recs);
! 340: if (!this->connection_id)
! 341: {
! 342: return FAILED;
! 343: }
! 344: tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
! 345: TNC_CONNECTION_STATE_CREATE);
! 346: tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
! 347: TNC_CONNECTION_STATE_HANDSHAKE);
! 348: }
! 349:
! 350: data = chunk_create(buf, buflen);
! 351: DBG1(DBG_TNC, "received TNCCS Batch (%u bytes) for Connection ID %u",
! 352: data.len, this->connection_id);
! 353: DBG3(DBG_TNC, "%.*s", (int)data.len, data.ptr);
! 354: batch = tnccs_batch_create_from_data(this->is_server, ++this->batch_id, data);
! 355: status = batch->process(batch);
! 356:
! 357: if (status == FAILED)
! 358: {
! 359: this->fatal_error = TRUE;
! 360: this->mutex->lock(this->mutex);
! 361: if (this->batch)
! 362: {
! 363: DBG1(DBG_TNC, "cancelling TNCCS batch");
! 364: this->batch->destroy(this->batch);
! 365: this->batch_id--;
! 366: }
! 367: this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
! 368:
! 369: /* add error messages to outbound batch */
! 370: enumerator = batch->create_error_enumerator(batch);
! 371: while (enumerator->enumerate(enumerator, &msg))
! 372: {
! 373: this->batch->add_msg(this->batch, msg->get_ref(msg));
! 374: }
! 375: enumerator->destroy(enumerator);
! 376: this->mutex->unlock(this->mutex);
! 377: }
! 378: else
! 379: {
! 380: enumerator = batch->create_msg_enumerator(batch);
! 381: while (enumerator->enumerate(enumerator, &msg))
! 382: {
! 383: handle_message(this, msg);
! 384: }
! 385: enumerator->destroy(enumerator);
! 386:
! 387: /* received any TNCCS-Error messages */
! 388: if (this->fatal_error)
! 389: {
! 390: DBG1(DBG_TNC, "a fatal TNCCS-Error occurred, terminating connection");
! 391: batch->destroy(batch);
! 392: return FAILED;
! 393: }
! 394:
! 395: this->send_msg = TRUE;
! 396: if (this->is_server)
! 397: {
! 398: tnc->imvs->batch_ending(tnc->imvs, this->connection_id);
! 399: }
! 400: else
! 401: {
! 402: tnc->imcs->batch_ending(tnc->imcs, this->connection_id);
! 403: }
! 404: this->send_msg = FALSE;
! 405: }
! 406: batch->destroy(batch);
! 407:
! 408: return NEED_MORE;
! 409: }
! 410:
! 411: /**
! 412: * Add a recommendation message if a final recommendation is available
! 413: */
! 414: static void check_and_build_recommendation(private_tnccs_11_t *this)
! 415: {
! 416: TNC_IMV_Action_Recommendation rec;
! 417: TNC_IMV_Evaluation_Result eval;
! 418: TNC_IMVID id;
! 419: chunk_t reason, language;
! 420: enumerator_t *enumerator;
! 421: tnccs_msg_t *msg;
! 422:
! 423: if (!this->recs->have_recommendation(this->recs, &rec, &eval))
! 424: {
! 425: tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id);
! 426: }
! 427: if (this->recs->have_recommendation(this->recs, &rec, &eval))
! 428: {
! 429: if (!this->batch)
! 430: {
! 431: this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
! 432: }
! 433:
! 434: msg = tnccs_recommendation_msg_create(rec);
! 435: this->batch->add_msg(this->batch, msg);
! 436:
! 437: /* currently we just send the first Reason String */
! 438: enumerator = this->recs->create_reason_enumerator(this->recs);
! 439: if (enumerator->enumerate(enumerator, &id, &reason, &language))
! 440: {
! 441: msg = tnccs_reason_strings_msg_create(reason, language);
! 442: this->batch->add_msg(this->batch, msg);
! 443: }
! 444: enumerator->destroy(enumerator);
! 445:
! 446: /* we have reached the final state */
! 447: this->delete_state = TRUE;
! 448: }
! 449: }
! 450:
! 451: METHOD(tls_t, build, status_t,
! 452: private_tnccs_11_t *this, void *buf, size_t *buflen, size_t *msglen)
! 453: {
! 454: status_t status;
! 455:
! 456: /* Initialize the connection */
! 457: if (!this->is_server && !this->connection_id)
! 458: {
! 459: tnccs_msg_t *msg;
! 460: char *pref_lang;
! 461:
! 462: this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
! 463: TNCCS_1_1, (tnccs_t*)this, _send_msg,
! 464: &this->request_handshake_retry,
! 465: this->max_msg_len, NULL);
! 466: if (!this->connection_id)
! 467: {
! 468: return FAILED;
! 469: }
! 470:
! 471: /* Create TNCCS-PreferredLanguage message */
! 472: pref_lang = tnc->imcs->get_preferred_language(tnc->imcs);
! 473: msg = tnccs_preferred_language_msg_create(pref_lang);
! 474: this->mutex->lock(this->mutex);
! 475: this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
! 476: this->batch->add_msg(this->batch, msg);
! 477: this->mutex->unlock(this->mutex);
! 478:
! 479: tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
! 480: TNC_CONNECTION_STATE_CREATE);
! 481: tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
! 482: TNC_CONNECTION_STATE_HANDSHAKE);
! 483: this->send_msg = TRUE;
! 484: tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
! 485: this->send_msg = FALSE;
! 486: }
! 487:
! 488: /* Do not allow any asynchronous IMCs or IMVs to add additional messages */
! 489: this->mutex->lock(this->mutex);
! 490:
! 491: if (this->recs && !this->delete_state &&
! 492: (!this->batch || this->fatal_error))
! 493: {
! 494: check_and_build_recommendation(this);
! 495: }
! 496:
! 497: if (this->batch)
! 498: {
! 499: chunk_t data;
! 500:
! 501: this->batch->build(this->batch);
! 502: data = this->batch->get_encoding(this->batch);
! 503: DBG1(DBG_TNC, "sending TNCCS Batch (%d bytes) for Connection ID %u",
! 504: data.len, this->connection_id);
! 505: DBG3(DBG_TNC, "%.*s", (int)data.len, data.ptr);
! 506: *msglen = 0;
! 507:
! 508: if (data.len > *buflen)
! 509: {
! 510: DBG1(DBG_TNC, "fragmentation of TNCCS batch not supported yet");
! 511: }
! 512: else
! 513: {
! 514: *buflen = data.len;
! 515: }
! 516: memcpy(buf, data.ptr, *buflen);
! 517: this->batch->destroy(this->batch);
! 518: this->batch = NULL;
! 519: status = ALREADY_DONE;
! 520: }
! 521: else
! 522: {
! 523: DBG1(DBG_TNC, "no TNCCS Batch to send");
! 524: status = INVALID_STATE;
! 525: }
! 526: this->mutex->unlock(this->mutex);
! 527:
! 528: return status;
! 529: }
! 530:
! 531: METHOD(tls_t, is_server, bool,
! 532: private_tnccs_11_t *this)
! 533: {
! 534: return this->is_server;
! 535: }
! 536:
! 537: METHOD(tls_t, get_server_id, identification_t*,
! 538: private_tnccs_11_t *this)
! 539: {
! 540: return this->server_id;
! 541: }
! 542:
! 543: METHOD(tls_t, set_peer_id, void,
! 544: private_tnccs_11_t *this, identification_t *id)
! 545: {
! 546: DESTROY_IF(this->peer_id);
! 547: this->peer_id = id->clone(id);
! 548: }
! 549:
! 550: METHOD(tls_t, get_peer_id, identification_t*,
! 551: private_tnccs_11_t *this)
! 552: {
! 553: return this->peer_id;
! 554: }
! 555:
! 556: METHOD(tls_t, get_purpose, tls_purpose_t,
! 557: private_tnccs_11_t *this)
! 558: {
! 559: return TLS_PURPOSE_EAP_TNC;
! 560: }
! 561:
! 562: METHOD(tls_t, is_complete, bool,
! 563: private_tnccs_11_t *this)
! 564: {
! 565: TNC_IMV_Action_Recommendation rec;
! 566: TNC_IMV_Evaluation_Result eval;
! 567:
! 568: if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
! 569: {
! 570: return this->callback ? this->callback(rec, eval) : TRUE;
! 571: }
! 572: else
! 573: {
! 574: return FALSE;
! 575: }
! 576: }
! 577:
! 578: METHOD(tls_t, get_eap_msk, chunk_t,
! 579: private_tnccs_11_t *this)
! 580: {
! 581: return chunk_empty;
! 582: }
! 583:
! 584: METHOD(tls_t, destroy, void,
! 585: private_tnccs_11_t *this)
! 586: {
! 587: if (ref_put(&this->ref))
! 588: {
! 589: tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
! 590: this->is_server);
! 591: this->server_id->destroy(this->server_id);
! 592: this->peer_id->destroy(this->peer_id);
! 593: this->server_ip->destroy(this->server_ip);
! 594: this->peer_ip->destroy(this->peer_ip);
! 595: this->mutex->destroy(this->mutex);
! 596: DESTROY_IF(this->batch);
! 597: free(this);
! 598: }
! 599: }
! 600:
! 601: METHOD(tnccs_t, get_server_ip, host_t*,
! 602: private_tnccs_11_t *this)
! 603: {
! 604: return this->server_ip;
! 605: }
! 606:
! 607: METHOD(tnccs_t, get_peer_ip, host_t*,
! 608: private_tnccs_11_t *this)
! 609: {
! 610: return this->peer_ip;
! 611: }
! 612:
! 613: METHOD(tnccs_t, get_transport, tnc_ift_type_t,
! 614: private_tnccs_11_t *this)
! 615: {
! 616: return this->transport;
! 617: }
! 618:
! 619: METHOD(tnccs_t, set_transport, void,
! 620: private_tnccs_11_t *this, tnc_ift_type_t transport)
! 621: {
! 622: this->transport = transport;
! 623: }
! 624:
! 625: METHOD(tnccs_t, get_auth_type, uint32_t,
! 626: private_tnccs_11_t *this)
! 627: {
! 628: return this->auth_type;
! 629: }
! 630:
! 631: METHOD(tnccs_t, set_auth_type, void,
! 632: private_tnccs_11_t *this, uint32_t auth_type)
! 633: {
! 634: this->auth_type = auth_type;
! 635: }
! 636:
! 637: METHOD(tnccs_t, get_pdp_server, chunk_t,
! 638: private_tnccs_11_t *this, uint16_t *port)
! 639: {
! 640: *port = 0;
! 641:
! 642: return chunk_empty;
! 643: }
! 644:
! 645: METHOD(tnccs_t, get_ref, tnccs_t*,
! 646: private_tnccs_11_t *this)
! 647: {
! 648: ref_get(&this->ref);
! 649: return &this->public;
! 650: }
! 651:
! 652: /**
! 653: * See header
! 654: */
! 655: tnccs_t* tnccs_11_create(bool is_server, identification_t *server_id,
! 656: identification_t *peer_id, host_t *server_ip,
! 657: host_t *peer_ip, tnc_ift_type_t transport,
! 658: tnccs_cb_t cb)
! 659: {
! 660: private_tnccs_11_t *this;
! 661:
! 662: INIT(this,
! 663: .public = {
! 664: .tls = {
! 665: .process = _process,
! 666: .build = _build,
! 667: .is_server = _is_server,
! 668: .get_server_id = _get_server_id,
! 669: .set_peer_id = _set_peer_id,
! 670: .get_peer_id = _get_peer_id,
! 671: .get_purpose = _get_purpose,
! 672: .is_complete = _is_complete,
! 673: .get_eap_msk = _get_eap_msk,
! 674: .destroy = _destroy,
! 675: },
! 676: .get_server_ip = _get_server_ip,
! 677: .get_peer_ip = _get_peer_ip,
! 678: .get_transport = _get_transport,
! 679: .set_transport = _set_transport,
! 680: .get_auth_type = _get_auth_type,
! 681: .set_auth_type = _set_auth_type,
! 682: .get_pdp_server = _get_pdp_server,
! 683: .get_ref = _get_ref,
! 684: },
! 685: .is_server = is_server,
! 686: .server_id = server_id->clone(server_id),
! 687: .peer_id = peer_id->clone(peer_id),
! 688: .server_ip = server_ip->clone(server_ip),
! 689: .peer_ip = peer_ip->clone(peer_ip),
! 690: .transport = transport,
! 691: .callback = cb,
! 692: .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
! 693: .max_msg_len = lib->settings->get_int(lib->settings,
! 694: "%s.plugins.tnccs-11.max_message_size", 45000, lib->ns),
! 695: .ref = 1,
! 696: );
! 697:
! 698: return &this->public;
! 699: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>