diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2013-09-17 21:57:08 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2013-09-17 21:57:08 +0200 |
commit | 2c4d772a79420b5fb606545be5f74e920c32464c (patch) | |
tree | 7be87d95f7853e4dd042bde9a7fa6edc23a8288d /src | |
parent | ddfc58960080f5fe3f447aa5ff8c235f67efad98 (diff) | |
download | strongswan-2c4d772a79420b5fb606545be5f74e920c32464c.tar.bz2 strongswan-2c4d772a79420b5fb606545be5f74e920c32464c.tar.xz |
Implemented TCG/PB-PDP_Referral message
Diffstat (limited to 'src')
5 files changed, 153 insertions, 13 deletions
diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c index 7fa1857cb..31cee9e2b 100644 --- a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c @@ -69,6 +69,11 @@ struct private_tnc_pdp_t { eap_type_t type; /** + * PT-TLS port of the server + */ + u_int16_t pt_tls_port; + + /** * PT-TLS IPv4 socket */ int pt_tls_ipv4; @@ -798,6 +803,8 @@ tnc_pdp_t *tnc_pdp_create(void) destroy(this); return NULL; } + this->pt_tls_port = pt_tls_port; + if (this->pt_tls_ipv4) { lib->watcher->add(lib->watcher, this->pt_tls_ipv4, WATCHER_READ, @@ -807,6 +814,7 @@ tnc_pdp_t *tnc_pdp_create(void) { DBG1(DBG_NET, "could not open IPv4 PT-TLS socket, IPv4 disabled"); } + if (this->pt_tls_ipv6) { lib->watcher->add(lib->watcher, this->pt_tls_ipv6, WATCHER_READ, @@ -816,6 +824,10 @@ tnc_pdp_t *tnc_pdp_create(void) { DBG1(DBG_NET, "could not open IPv6 PT-TLS socket, IPv6 disabled"); } + + /* register PT-TLS service */ + lib->set(lib, "pt-tls-server", this->server); + lib->set(lib, "pt-tls-port", &this->pt_tls_port); } /* Create IPv4 and IPv6 RADIUS listening sockets */ diff --git a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c index 6dacfc6af..ef0faf2c1 100644 --- a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c +++ b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c @@ -396,7 +396,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) msg_type_names = pb_tnc_msg_type_names; msg_infos = pb_tnc_msg_infos; } - else if (vendor_id == PEN_IETF && msg_type <= PB_TCG_MSG_ROOF) + else if (vendor_id == PEN_TCG && msg_type <= PB_TCG_MSG_ROOF) { msg_type_names = pb_tnc_tcg_msg_type_names; msg_infos = pb_tnc_tcg_msg_infos; @@ -414,16 +414,16 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) if (noskip_flag) { - DBG1(DBG_TNC, "reject PB-TNC message (Vendor ID 0x%06x / " - "Type 0x%08x)", vendor_id, msg_type); + DBG1(DBG_TNC, "reject PB-TNC message 0x%06x/0x%08x)", + vendor_id, msg_type); msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset); goto fatal; } else { - DBG1(DBG_TNC, "ignore PB-TNC message (Vendor ID 0x%06x / " - "Type 0x%08x)", vendor_id, msg_type); + DBG1(DBG_TNC, "ignore PB-TNC message 0x%06x/0x%08x)", + vendor_id, msg_type); this->offset += msg_len; return SUCCESS; } diff --git a/src/libtnccs/plugins/tnccs_20/messages/tcg/pb_pdp_referral_msg.c b/src/libtnccs/plugins/tnccs_20/messages/tcg/pb_pdp_referral_msg.c index f8c78b680..1c8538e6b 100644 --- a/src/libtnccs/plugins/tnccs_20/messages/tcg/pb_pdp_referral_msg.c +++ b/src/libtnccs/plugins/tnccs_20/messages/tcg/pb_pdp_referral_msg.c @@ -79,6 +79,11 @@ typedef struct private_pb_pdp_referral_msg_t private_pb_pdp_referral_msg_t; * */ +# define PDP_REFERRAL_HEADER_SIZE 8 +# define PDP_REFERRAL_ID_HEADER_SIZE 4 +# define PDP_REFERRAL_RESERVED 0x00 +# define PDP_REFERRAL_PROTOCOL 0x00 + /** * Private data of a pb_pdp_referral_msg_t object. * @@ -105,6 +110,21 @@ struct private_pb_pdp_referral_msg_t { chunk_t identifier; /** + * PDP FQDN Identifier + */ + chunk_t fqdn; + + /** + * PT protocol the PDP is using + */ + u_int8_t protocol; + + /** + * PT port the PDP is using + */ + u_int16_t port; + + /** * Encoded message */ chunk_t encoding; @@ -131,10 +151,11 @@ METHOD(pb_tnc_msg_t, build, void, { return; } - writer = bio_writer_create(64); - writer->write_uint32(writer, this->identifier_type.vendor_id); + writer = bio_writer_create(PDP_REFERRAL_HEADER_SIZE + this->identifier.len); + writer->write_uint8 (writer, PDP_REFERRAL_RESERVED); + writer->write_uint24(writer, this->identifier_type.vendor_id); writer->write_uint32(writer, this->identifier_type.type); - writer->write_data(writer, this->identifier); + writer->write_data (writer, this->identifier); this->encoding = writer->get_buf(writer); this->encoding = chunk_clone(this->encoding); @@ -146,7 +167,6 @@ METHOD(pb_tnc_msg_t, process, status_t, { bio_reader_t *reader; u_int8_t reserved; - status_t status = SUCCESS; *offset = 0; @@ -160,11 +180,25 @@ METHOD(pb_tnc_msg_t, process, status_t, this->identifier = chunk_clone(this->identifier); reader->destroy(reader); - if (this->identifier_type.vendor_id == PEN_TCG) + if (this->identifier_type.vendor_id == PEN_TCG && + this->identifier_type.type == PB_PDP_ID_FQDN) { - /* TODO parse PDP Identifier Types */ + reader = bio_reader_create(this->identifier); + *offset += PDP_REFERRAL_HEADER_SIZE; + + if (this->identifier.len <= PDP_REFERRAL_ID_HEADER_SIZE) + { + reader->destroy(reader); + return FAILED; + } + reader->read_uint8 (reader, &reserved); + reader->read_uint8 (reader, &this->protocol); + reader->read_uint16(reader, &this->port); + reader->read_data (reader, reader->remaining(reader), &this->fqdn); + this->fqdn = chunk_clone(this->fqdn); + reader->destroy(reader); } - return status; + return SUCCESS; } METHOD(pb_tnc_msg_t, destroy, void, @@ -172,6 +206,7 @@ METHOD(pb_tnc_msg_t, destroy, void, { free(this->encoding.ptr); free(this->identifier.ptr); + free(this->fqdn.ptr); free(this); } @@ -187,6 +222,20 @@ METHOD(pb_pdp_referral_msg_t, get_identifier, chunk_t, return this->identifier; } +METHOD(pb_pdp_referral_msg_t, get_fqdn, chunk_t, + private_pb_pdp_referral_msg_t *this, u_int8_t *protocol, u_int16_t *port) +{ + if (protocol) + { + *protocol = this->protocol; + } + if (port) + { + *port = this->port; + } + return this->fqdn; +} + /** * See header */ @@ -218,6 +267,27 @@ pb_tnc_msg_t* pb_pdp_referral_msg_create(pen_type_t identifier_type, /** * See header */ +pb_tnc_msg_t* pb_pdp_referral_msg_create_from_fqdn(chunk_t fqdn, u_int16_t port) +{ + pb_tnc_msg_t *msg; + bio_writer_t *writer; + pen_type_t type = { PEN_TCG, PB_PDP_ID_FQDN }; + + writer = bio_writer_create(PDP_REFERRAL_ID_HEADER_SIZE + fqdn.len); + writer->write_uint8 (writer, PDP_REFERRAL_RESERVED); + writer->write_uint8 (writer, PDP_REFERRAL_PROTOCOL); + writer->write_uint16(writer, port); + writer->write_data (writer, fqdn); + + msg = pb_pdp_referral_msg_create(type, writer->get_buf(writer)); + writer->destroy(writer); + + return msg; +} + +/** + * See header + */ pb_tnc_msg_t *pb_pdp_referral_msg_create_from_data(chunk_t data) { private_pb_pdp_referral_msg_t *this; @@ -233,6 +303,7 @@ pb_tnc_msg_t *pb_pdp_referral_msg_create_from_data(chunk_t data) }, .get_identifier_type = _get_identifier_type, .get_identifier = _get_identifier, + .get_fqdn = _get_fqdn, }, .type = { PEN_TCG, PB_TCG_MSG_PDP_REFERRAL }, .encoding = chunk_clone(data), diff --git a/src/libtnccs/plugins/tnccs_20/messages/tcg/pb_pdp_referral_msg.h b/src/libtnccs/plugins/tnccs_20/messages/tcg/pb_pdp_referral_msg.h index a472557ca..b225f3381 100644 --- a/src/libtnccs/plugins/tnccs_20/messages/tcg/pb_pdp_referral_msg.h +++ b/src/libtnccs/plugins/tnccs_20/messages/tcg/pb_pdp_referral_msg.h @@ -67,6 +67,16 @@ struct pb_pdp_referral_msg_t { */ chunk_t (*get_identifier)(pb_pdp_referral_msg_t *this); + /** + * Get the PDP Identifier Value + * + * @param protocol PT transport protocol + * @param port PT port the PDP is listening on + * @return Fully Qualified Domain Name of PDP + */ + chunk_t (*get_fqdn)(pb_pdp_referral_msg_t *this, u_int8_t *protocol, + u_int16_t *port); + }; /** @@ -79,6 +89,14 @@ pb_tnc_msg_t* pb_pdp_referral_msg_create(pen_type_t identifier_type, chunk_t identifier); /** + * Create a PB-PDP-Referral message of TCG Type PDP FQDN Identifier + * + * @param fqdn Fully Qualified Domain Name of PDP + * @param port PT-TLS port the PDP is listening on + */ +pb_tnc_msg_t* pb_pdp_referral_msg_create_from_fqdn(chunk_t fqdn, u_int16_t port); + +/** * Create an unprocessed PB-PDP-Referral message from raw data * * @param data PB-PDP-Referral message data diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20.c b/src/libtnccs/plugins/tnccs_20/tnccs_20.c index 6759c92a3..b5b1cebd9 100644 --- a/src/libtnccs/plugins/tnccs_20/tnccs_20.c +++ b/src/libtnccs/plugins/tnccs_20/tnccs_20.c @@ -24,6 +24,7 @@ #include "messages/ietf/pb_remediation_parameters_msg.h" #include "messages/ietf/pb_reason_string_msg.h" #include "messages/ietf/pb_language_preference_msg.h" +#include "messages/tcg/pb_pdp_referral_msg.h" #include "state_machine/pb_tnc_state_machine.h" #include <tncif_names.h> @@ -452,8 +453,31 @@ static void handle_tcg_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg) switch (msg_type.type) { case PB_TCG_MSG_PDP_REFERRAL: - /* TODO handle PDP Referral */ + { + pb_pdp_referral_msg_t *pdp_msg; + pen_type_t pdp_id_type; + chunk_t pdp_server; + u_int8_t pdp_protocol; + u_int16_t pdp_port; + + pdp_msg = (pb_pdp_referral_msg_t*)msg; + pdp_id_type = pdp_msg->get_identifier_type(pdp_msg); + + if (pdp_id_type.vendor_id == PEN_TCG && + pdp_id_type.type == PB_PDP_ID_FQDN) + { + pdp_server = pdp_msg->get_fqdn(pdp_msg, &pdp_protocol, + &pdp_port); + if (pdp_protocol != 0) + { + DBG1(DBG_TNC, "unsupported PDP transport protocol"); + break; + } + DBG1(DBG_TNC, "PDP server '%.*s' is listening on port %u", + pdp_server.len, pdp_server.ptr, pdp_port); + } break; + } default: break; } @@ -510,6 +534,8 @@ METHOD(tls_t, process, status_t, pb_tnc_batch_t *batch; pb_tnc_msg_t *msg; enumerator_t *enumerator; + identification_t *pdp_server; + u_int16_t *pdp_port; status_t status; if (this->is_server && !this->connection_id) @@ -526,6 +552,19 @@ METHOD(tls_t, process, status_t, TNC_CONNECTION_STATE_CREATE); tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE); + + /* Send a PB-TNC TCG PDP Referral message if PDP is known */ + pdp_server = (identification_t*)lib->get(lib, "pt-tls-server"); + pdp_port = (u_int16_t*)lib->get(lib, "pt-tls-port"); + + if ((this->transport == TNC_IFT_EAP_1_1 || + this->transport == TNC_IFT_EAP_2_0) && pdp_server && pdp_port) + { + msg = pb_pdp_referral_msg_create_from_fqdn( + pdp_server->get_encoding(pdp_server), *pdp_port); + this->messages->insert_last(this->messages, msg); + } + } data = chunk_create(buf, buflen); |