diff options
-rw-r--r-- | src/libpttls/pt_tls.c | 37 | ||||
-rw-r--r-- | src/libpttls/pt_tls.h | 11 | ||||
-rw-r--r-- | src/libpttls/pt_tls_client.c | 70 | ||||
-rw-r--r-- | src/libpttls/pt_tls_server.c | 116 |
4 files changed, 107 insertions, 127 deletions
diff --git a/src/libpttls/pt_tls.c b/src/libpttls/pt_tls.c index b59ef7c89..3c1f874d7 100644 --- a/src/libpttls/pt_tls.c +++ b/src/libpttls/pt_tls.c @@ -134,31 +134,32 @@ bio_reader_t* pt_tls_read(tls_socket_t *tls, u_int32_t *vendor, /** * Prepend a PT-TLS header to a writer, send data, destroy writer */ -bool pt_tls_write(tls_socket_t *tls, bio_writer_t *writer, - pt_tls_message_type_t type, u_int32_t identifier) +bool pt_tls_write(tls_socket_t *tls, pt_tls_message_type_t type, + u_int32_t identifier, chunk_t data) { - bio_writer_t *header; + bio_writer_t *writer; + chunk_t out; ssize_t len; - chunk_t data; - data = writer->get_buf(writer); len = PT_TLS_HEADER_LEN + data.len; - header = bio_writer_create(len); - header->write_uint8(header, 0); - header->write_uint24(header, 0); - header->write_uint32(header, type); - header->write_uint32(header, len); - header->write_uint32(header, identifier); - - header->write_data(header, data); - writer->destroy(writer); + writer = bio_writer_create(len); + + /* write PT-TLS header */ + writer->write_uint8 (writer, 0); + writer->write_uint24(writer, 0); + writer->write_uint32(writer, type); + writer->write_uint32(writer, len); + writer->write_uint32(writer, identifier); + + /* write PT-TLS body */ + writer->write_data(writer, data); DBG2(DBG_TNC, "sending PT-TLS message #%d of type '%N' (%d bytes)", identifier, pt_tls_message_type_names, type, len); - data = header->get_buf(header); - len = tls->write(tls, data.ptr, data.len); - header->destroy(header); + out = writer->get_buf(writer); + len = tls->write(tls, out.ptr, out.len); + writer->destroy(writer); - return len == data.len; + return len == out.len; } diff --git a/src/libpttls/pt_tls.h b/src/libpttls/pt_tls.h index f7ea75b27..dd3d25055 100644 --- a/src/libpttls/pt_tls.h +++ b/src/libpttls/pt_tls.h @@ -38,6 +38,11 @@ #define PT_TLS_HEADER_LEN 16 /** + * Maximum size of a PT-TLS message + */ +#define PT_TLS_MAX_MESSAGE_LEN 8 * TLS_MAX_FRAGMENT_LEN - PT_TLS_HEADER_LEN + +/** * Default PT-TLS port */ #define PT_TLS_PORT 271 @@ -107,13 +112,13 @@ bio_reader_t* pt_tls_read(tls_socket_t *tls, u_int32_t *vendor, * Prepend a PT-TLS header to a writer, send data, destroy writer. * * @param tls TLS socket to write to - * @param writer prepared Message value to write * @param type Message Type to write * @param identifier Message Identifier to write + * @param data Message value to write * @return TRUE if data written successfully */ -bool pt_tls_write(tls_socket_t *tls, bio_writer_t *writer, - pt_tls_message_type_t type, u_int32_t identifier); +bool pt_tls_write(tls_socket_t *tls, pt_tls_message_type_t type, + u_int32_t identifier, chunk_t data); /** * @} diff --git a/src/libpttls/pt_tls_client.c b/src/libpttls/pt_tls_client.c index 6df32356b..01a84cd14 100644 --- a/src/libpttls/pt_tls_client.c +++ b/src/libpttls/pt_tls_client.c @@ -102,6 +102,7 @@ static bool negotiate_version(private_pt_tls_client_t *this) bio_reader_t *reader; u_int32_t type, vendor, identifier, reserved; u_int8_t version; + bool res; DBG1(DBG_TNC, "sending offer for PT-TLS version %d", PT_TLS_VERSION); @@ -110,8 +111,10 @@ static bool negotiate_version(private_pt_tls_client_t *this) writer->write_uint8(writer, PT_TLS_VERSION); writer->write_uint8(writer, PT_TLS_VERSION); writer->write_uint8(writer, PT_TLS_VERSION); - if (!pt_tls_write(this->tls, writer, PT_TLS_VERSION_REQUEST, - this->identifier++)) + res = pt_tls_write(this->tls, PT_TLS_VERSION_REQUEST, this->identifier++, + writer->get_buf(writer)); + writer->destroy(writer); + if (!res) { return FALSE; } @@ -144,6 +147,7 @@ static status_t do_sasl(private_pt_tls_client_t *this, sasl_mechanism_t *sasl) bio_reader_t *reader; bio_writer_t *writer; chunk_t data; + bool res; writer = bio_writer_create(32); writer->write_data8(writer, chunk_from_str(sasl->get_name(sasl))); @@ -164,8 +168,10 @@ static status_t do_sasl(private_pt_tls_client_t *this, sasl_mechanism_t *sasl) writer->destroy(writer); return FAILED; } - if (!pt_tls_write(this->tls, writer, PT_TLS_SASL_MECH_SELECTION, - this->identifier++)) + res = pt_tls_write(this->tls, PT_TLS_SASL_MECH_SELECTION, + this->identifier++, writer->get_buf(writer)); + writer->destroy(writer); + if (!res) { return FAILED; } @@ -253,8 +259,10 @@ static status_t do_sasl(private_pt_tls_client_t *this, sasl_mechanism_t *sasl) writer->destroy(writer); return FAILED; } - if (!pt_tls_write(this->tls, writer, PT_TLS_SASL_AUTH_DATA, - this->identifier++)) + res = pt_tls_write(this->tls, PT_TLS_SASL_AUTH_DATA, + this->identifier++, writer->get_buf(writer)); + writer->destroy(writer); + if (!res) { return FAILED; } @@ -351,44 +359,30 @@ static bool assess(private_pt_tls_client_t *this, tls_t *tnccs) { while (TRUE) { - bio_writer_t *writer; + size_t msglen; + size_t buflen = PT_TLS_MAX_MESSAGE_LEN; + char buf[buflen]; bio_reader_t *reader; u_int32_t vendor, type, identifier; chunk_t data; - writer = bio_writer_create(32); - while (TRUE) + switch (tnccs->build(tnccs, buf, &buflen, &msglen)) { - char buf[2048]; - size_t buflen, msglen; - - buflen = sizeof(buf); - switch (tnccs->build(tnccs, buf, &buflen, &msglen)) - { - case SUCCESS: - writer->destroy(writer); - return tnccs->is_complete(tnccs); - case FAILED: - default: - writer->destroy(writer); + case SUCCESS: + return tnccs->is_complete(tnccs); + case ALREADY_DONE: + data = chunk_create(buf, buflen); + if (!pt_tls_write(this->tls, PT_TLS_PB_TNC_BATCH, + this->identifier++, data)) + { return FALSE; - case INVALID_STATE: - writer->destroy(writer); - break; - case NEED_MORE: - writer->write_data(writer, chunk_create(buf, buflen)); - continue; - case ALREADY_DONE: - writer->write_data(writer, chunk_create(buf, buflen)); - if (!pt_tls_write(this->tls, writer, PT_TLS_PB_TNC_BATCH, - this->identifier++)) - { - return FALSE; - } - writer = bio_writer_create(32); - continue; - } - break; + } + break; + case INVALID_STATE: + break; + case FAILED: + default: + return FALSE; } reader = pt_tls_read(this->tls, &vendor, &type, &identifier); diff --git a/src/libpttls/pt_tls_server.c b/src/libpttls/pt_tls_server.c index 32b50739e..69dcdc08b 100644 --- a/src/libpttls/pt_tls_server.c +++ b/src/libpttls/pt_tls_server.c @@ -73,6 +73,7 @@ static bool negotiate_version(private_pt_tls_server_t *this) bio_writer_t *writer; u_int32_t vendor, type, identifier; u_int8_t reserved, vmin, vmax, vpref; + bool res; reader = pt_tls_read(this->tls, &vendor, &type, &identifier); if (!reader) @@ -100,9 +101,10 @@ static bool negotiate_version(private_pt_tls_server_t *this) writer = bio_writer_create(4); writer->write_uint24(writer, 0); writer->write_uint8(writer, PT_TLS_VERSION); - - return pt_tls_write(this->tls, writer, PT_TLS_VERSION_RESPONSE, - this->identifier++); + res = pt_tls_write(this->tls, PT_TLS_VERSION_RESPONSE, + this->identifier++, writer->get_buf(writer)); + writer->destroy(writer); + return res; } /** @@ -114,6 +116,7 @@ static status_t process_sasl(private_pt_tls_server_t *this, bio_writer_t *writer; identification_t *client; tnccs_t *tnccs; + bool res; switch (sasl->process(sasl, data)) { @@ -135,12 +138,10 @@ static status_t process_sasl(private_pt_tls_server_t *this, } writer = bio_writer_create(1); writer->write_uint8(writer, PT_TLS_SASL_RESULT_SUCCESS); - if (pt_tls_write(this->tls, writer, PT_TLS_SASL_RESULT, - this->identifier++)) - { - return SUCCESS; - } - return FAILED; + res = pt_tls_write(this->tls, PT_TLS_SASL_RESULT, + this->identifier++, writer->get_buf(writer)); + writer->destroy(writer); + return res ? SUCCESS : FAILED; case FAILED: default: DBG1(DBG_TNC, "SASL %s authentication failed", @@ -148,8 +149,8 @@ static status_t process_sasl(private_pt_tls_server_t *this, writer = bio_writer_create(1); /* sending abort does not allow the client to retry */ writer->write_uint8(writer, PT_TLS_SASL_RESULT_ABORT); - pt_tls_write(this->tls, writer, PT_TLS_SASL_RESULT, - this->identifier++); + pt_tls_write(this->tls, PT_TLS_SASL_RESULT, + this->identifier++, writer->get_buf(writer)); return FAILED; } } @@ -189,19 +190,15 @@ static status_t write_sasl(private_pt_tls_server_t *this, { bio_writer_t *writer; chunk_t chunk; + bool res; switch (sasl->build(sasl, &chunk)) { case NEED_MORE: - writer = bio_writer_create(chunk.len); - writer->write_data(writer, chunk); + res = pt_tls_write(this->tls, PT_TLS_SASL_AUTH_DATA, + this->identifier++, chunk); free(chunk.ptr); - if (pt_tls_write(this->tls, writer, PT_TLS_SASL_AUTH_DATA, - this->identifier++)) - { - return NEED_MORE; - } - return FAILED; + return res ? NEED_MORE : FAILED; case SUCCESS: DBG1(DBG_TNC, "SASL %s authentication successful", sasl->get_name(sasl)); @@ -209,21 +206,18 @@ static status_t write_sasl(private_pt_tls_server_t *this, writer->write_uint8(writer, PT_TLS_SASL_RESULT_SUCCESS); writer->write_data(writer, chunk); free(chunk.ptr); - if (pt_tls_write(this->tls, writer, PT_TLS_SASL_RESULT, - this->identifier++)) - { - return SUCCESS; - } - return FAILED; + res = pt_tls_write(this->tls, PT_TLS_SASL_RESULT, + this->identifier++, writer->get_buf(writer)); + writer->destroy(writer); + return res ? SUCCESS : FAILED; case FAILED: default: DBG1(DBG_TNC, "SASL %s authentication failed", sasl->get_name(sasl)); - writer = bio_writer_create(1); /* sending abort does not allow the client to retry */ - writer->write_uint8(writer, PT_TLS_SASL_RESULT_ABORT); - pt_tls_write(this->tls, writer, PT_TLS_SASL_RESULT, - this->identifier++); + chunk = chunk_from_chars(PT_TLS_SASL_RESULT_ABORT); + pt_tls_write(this->tls, PT_TLS_SASL_RESULT, + this->identifier++, chunk); return FAILED; } } @@ -236,6 +230,7 @@ static bool send_sasl_mechs(private_pt_tls_server_t *this) enumerator_t *enumerator; bio_writer_t *writer = NULL; char *name; + bool res; enumerator = sasl_mechanism_create_enumerator(TRUE); while (enumerator->enumerate(enumerator, &name)) @@ -253,8 +248,10 @@ static bool send_sasl_mechs(private_pt_tls_server_t *this) { /* no mechanisms available? */ return FALSE; } - return pt_tls_write(this->tls, writer, PT_TLS_SASL_MECHS, - this->identifier++); + res = pt_tls_write(this->tls, PT_TLS_SASL_MECHS, + this->identifier++, writer->get_buf(writer)); + writer->destroy(writer); + return res; } /** @@ -394,11 +391,8 @@ static bool authenticate(private_pt_tls_server_t *this) if (do_sasl(this)) { /* complete SASL with emtpy mechanism list */ - bio_writer_t *writer; - - writer = bio_writer_create(0); - return pt_tls_write(this->tls, writer, PT_TLS_SASL_MECHS, - this->identifier++); + return pt_tls_write(this->tls, PT_TLS_SASL_MECHS, this->identifier++, + chunk_empty); } return FALSE; } @@ -410,44 +404,30 @@ static bool assess(private_pt_tls_server_t *this, tls_t *tnccs) { while (TRUE) { - bio_writer_t *writer; + size_t msglen; + size_t buflen = PT_TLS_MAX_MESSAGE_LEN; + char buf[buflen]; bio_reader_t *reader; u_int32_t vendor, type, identifier; chunk_t data; - writer = bio_writer_create(32); - while (TRUE) + switch (tnccs->build(tnccs, buf, &buflen, &msglen)) { - char buf[2048]; - size_t buflen, msglen; - - buflen = sizeof(buf); - switch (tnccs->build(tnccs, buf, &buflen, &msglen)) - { - case SUCCESS: - writer->destroy(writer); - return tnccs->is_complete(tnccs); - case FAILED: - default: - writer->destroy(writer); + case SUCCESS: + return tnccs->is_complete(tnccs); + case ALREADY_DONE: + data = chunk_create(buf, buflen); + if (!pt_tls_write(this->tls, PT_TLS_PB_TNC_BATCH, + this->identifier++, data)) + { return FALSE; - case INVALID_STATE: - writer->destroy(writer); - break; - case NEED_MORE: - writer->write_data(writer, chunk_create(buf, buflen)); - continue; - case ALREADY_DONE: - writer->write_data(writer, chunk_create(buf, buflen)); - if (!pt_tls_write(this->tls, writer, PT_TLS_PB_TNC_BATCH, - this->identifier++)) - { - return FALSE; - } - writer = bio_writer_create(32); - continue; - } - break; + } + break; + case INVALID_STATE: + break; + case FAILED: + default: + return FALSE; } reader = pt_tls_read(this->tls, &vendor, &type, &identifier); |