123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- /*
- * Copyright (C) 2012 Martin Willi
- * Copyright (C) 2012 revosec AG
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
- #include "pt_tls.h"
- #include <utils/debug.h>
- #include <pen/pen.h>
- /**
- * Described in header.
- */
- void libpttls_init(void)
- {
- /* empty */
- }
- /*
- * PT-TNC Message format:
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Reserved | Message Type Vendor ID |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Message Type |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Message Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Message Identifier |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Message Value (e.g. PB-TNC Batch) . . . |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- ENUM(pt_tls_message_type_names, PT_TLS_EXPERIMENTAL, PT_TLS_ERROR,
- "Experimental",
- "Version Request",
- "Version Response",
- "SASL Mechanisms",
- "SASL Mechanism Selection",
- "SASL Authentication Data",
- "SASL Result",
- "PB-TNC Batch",
- "PT-TLS Error"
- );
- ENUM(pt_tls_sasl_result_names, PT_TLS_SASL_RESULT_SUCCESS,
- PT_TLS_SASL_RESULT_MECH_FAILURE,
- "Success",
- "Failure",
- "Abort",
- "Mechanism Failure"
- );
- /**
- * Read a chunk of data from TLS, returning a reader for it
- */
- static bio_reader_t* read_tls(tls_socket_t *tls, size_t len)
- {
- ssize_t got, total = 0;
- char *buf;
- buf = malloc(len);
- while (total < len)
- {
- got = tls->read(tls, buf + total, len - total, TRUE);
- if (got <= 0)
- {
- free(buf);
- return NULL;
- }
- total += got;
- }
- return bio_reader_create_own(chunk_create(buf, len));
- }
- /**
- * Read a PT-TLS message, return header data
- */
- bio_reader_t* pt_tls_read(tls_socket_t *tls, uint32_t *vendor,
- uint32_t *type, uint32_t *identifier)
- {
- bio_reader_t *reader;
- uint32_t len;
- uint8_t reserved;
- reader = read_tls(tls, PT_TLS_HEADER_LEN);
- if (!reader)
- {
- return NULL;
- }
- if (!reader->read_uint8(reader, &reserved) ||
- !reader->read_uint24(reader, vendor) ||
- !reader->read_uint32(reader, type) ||
- !reader->read_uint32(reader, &len) ||
- !reader->read_uint32(reader, identifier))
- {
- reader->destroy(reader);
- return NULL;
- }
- reader->destroy(reader);
- if (len < PT_TLS_HEADER_LEN)
- {
- DBG1(DBG_TNC, "received short PT-TLS header (%d bytes)", len);
- return NULL;
- }
- if (*vendor == PEN_IETF)
- {
- DBG2(DBG_TNC, "received PT-TLS message #%d of type '%N' (%d bytes)",
- *identifier, pt_tls_message_type_names, *type, len);
- }
- else
- {
- DBG2(DBG_TNC, "received PT-TLS message #%d of unknown type "
- "0x%06x/0x%08x (%d bytes)",
- *identifier, *vendor, *type, len);
- }
- return read_tls(tls, len - PT_TLS_HEADER_LEN);
- }
- /**
- * Prepend a PT-TLS header to a writer, send data, destroy writer
- */
- bool pt_tls_write(tls_socket_t *tls, pt_tls_message_type_t type,
- uint32_t identifier, chunk_t data)
- {
- bio_writer_t *writer;
- chunk_t out;
- ssize_t len;
- len = PT_TLS_HEADER_LEN + data.len;
- 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);
- out = writer->get_buf(writer);
- len = tls->write(tls, out.ptr, out.len);
- writer->destroy(writer);
- return len == out.len;
- }
|