Optimized PT-TLS data transfer
This commit is contained in:
parent
6aff4b5ce8
commit
e689de6b8c
|
@ -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);
|
||||
writer = bio_writer_create(len);
|
||||
|
||||
header->write_data(header, data);
|
||||
writer->destroy(writer);
|
||||
/* 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;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue