Mercurial > hg > waaad
changeset 129:f185f65e213f
Changed transport prototype for security extensions
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Mon, 18 Aug 2008 18:28:22 +0900 |
parents | 21a5b37c6f35 |
children | 641999eb7a1d |
files | extensions/sec_nosec/sns_recv_unprotect.c extensions/sec_nosec/sns_send_protect.c extensions/sec_tls_gnutls/gnutls_sctp_wrapper.h include/waaad/security-api.h |
diffstat | 4 files changed, 110 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/extensions/sec_nosec/sns_recv_unprotect.c Mon Aug 18 14:54:40 2008 +0900 +++ b/extensions/sec_nosec/sns_recv_unprotect.c Mon Aug 18 18:28:22 2008 +0900 @@ -39,26 +39,55 @@ #include "sec_nosec.h" +static int sns_recv_unprotect_tcp (sec_session_t * session, void ** data, size_t *length); +static int sns_recv_unprotect_sctp(sec_session_t * session, void ** data, size_t *length); + /* We just receive the buffer "as is" on the connection object, and rebuild a message (boundaries are lost with TCP) * Note that we may be cancelled in any of the recv call. */ int sns_recv_unprotect (sec_session_t * session, void ** ext_session, void ** data, size_t *length) { + ssize_t ret = 0; + + TRACE_ENTRY("%p %p %p %p", session, ext_session, data, length); + + if (!session || !session->conn || !data || !length) { + TRACE_DEBUG(INFO, "Invalid argument"); + return EINVAL; + } + + switch (session->proto) { + case IPPROTO_TCP: + ret = sns_recv_unprotect_tcp(session, data, length); + break; + + case IPPROTO_SCTP: + ret = sns_recv_unprotect_sctp(session, data, length); + break; + + default: + TRACE_DEBUG(INFO, "Invalid proto"); + return EINVAL; + } + + if (ret != 0) { + TRACE_DEBUG(INFO, "sns_recv_unprotect_<proto> failed: %s", strerror(ret)); + } + + return ret; +} + +/* Receive from a TCP connection: rebuild the message boundaries */ +static int sns_recv_unprotect_tcp (sec_session_t * session, void ** data, size_t *length) +{ unsigned char header[4]; unsigned char * newmsg; ssize_t ret = 0; size_t received = 0; - TRACE_ENTRY("%p %p %p %p", session, ext_session, data, length); - - if (!session || !session->recv_data || !data || !length) { - TRACE_DEBUG(INFO, "Invalid argument"); - return EINVAL; - } - /* First, receive only a message header. */ while (received < sizeof(header)) { - ret = (*session->recv_data) (session->conn, &header[received], sizeof(header) - received); + ret = (*session->cbs.tcp.recv_data) (session->conn, &header[received], sizeof(header) - received); if (ret == 0) { /* Shutdown in progress */ TRACE_DEBUG(INFO, "The recv_data function returned 0"); @@ -94,7 +123,7 @@ memcpy(newmsg, header, sizeof(header)); while (received < *length) { pthread_cleanup_push(free, newmsg); /* In case we are canceled, clean the partialy built buffer */ - ret = (*session->recv_data) (session->conn, newmsg + received, (*length) - received); + ret = (*session->cbs.tcp.recv_data) (session->conn, newmsg + received, (*length) - received); pthread_cleanup_pop(0); if (ret == 0) { @@ -118,3 +147,27 @@ return 0; } + +/* Receive from a SCTP connection: the message boundaries are preserved, so we have very few to do here */ +static int sns_recv_unprotect_sctp (sec_session_t * session, void ** data, size_t *length) +{ + ssize_t ret = 0; + int stream = 0; + + ret = (*session->cbs.sctp.recv_data) (session->conn, &stream, data, length); + if (ret == 0) { + /* Shutdown in progress */ + TRACE_DEBUG(INFO, "The recv_data function returned 0"); + return ENOTCONN; + } + if (ret < 0) { + /* Error */ + ret = errno; + TRACE_DEBUG(INFO, "The recv_data function failed: %s", strerror(ret)); + return ret; + } + + TRACE_DEBUG(FULL, "Received a message of %d bytes on stream %d", *length, stream); + return 0; +} +
--- a/extensions/sec_nosec/sns_send_protect.c Mon Aug 18 14:54:40 2008 +0900 +++ b/extensions/sec_nosec/sns_send_protect.c Mon Aug 18 18:28:22 2008 +0900 @@ -45,16 +45,30 @@ { ssize_t ret = 0; size_t sent = 0; + int stream = -1; TRACE_ENTRY("%p %p %p %d", session, ext_session, data, length); - if (!session || !session->send_data) { + if (!session || !session->conn) { TRACE_DEBUG(INFO, "Invalid argument"); return EINVAL; } while (sent < length) { - ret = (*session->send_data) (session->conn, ((char *)data) + sent, length - sent); + switch (session->proto) { + case IPPROTO_TCP: + ret = (*session->cbs.tcp.send_data) (session->conn, ((char *)data) + sent, length - sent); + break; + + case IPPROTO_SCTP: + ret = (*session->cbs.sctp.send_data) (session->conn, &stream, ((char *)data) + sent, length - sent); + break; + + default: + TRACE_DEBUG(INFO, "Invalid proto"); + return EINVAL; + } + if (ret == -1) { ret = errno; TRACE_DEBUG(INFO, "The send_data callback failed: %s", strerror(ret));
--- a/extensions/sec_tls_gnutls/gnutls_sctp_wrapper.h Mon Aug 18 14:54:40 2008 +0900 +++ b/extensions/sec_tls_gnutls/gnutls_sctp_wrapper.h Mon Aug 18 18:28:22 2008 +0900 @@ -167,7 +167,7 @@ * socket : The socket on which to receive the next message. * event : if an event is received, it is stored here. * streamid: if relevant, the stream id on which data or event is received. - * data : a buffer continaing the received data. + * data : a buffer containing the received data. * len : the size of the data buffer * init : the initial size of the buffer *
--- a/include/waaad/security-api.h Mon Aug 18 14:54:40 2008 +0900 +++ b/include/waaad/security-api.h Mon Aug 18 18:28:22 2008 +0900 @@ -98,14 +98,30 @@ /* The following type represents a "connection" object (for example, a socket) */ typedef void sec_conn_t; -/* This is the prototype of the function that the daemon uses to send data on a connection (TCP or SCTP) */ +/* This is the prototype of the function that the daemon uses to send data on a TCP */ +/* This function may be blocking. */ /* The parameters and return values are the same as the send() function defined in POSIX. */ -typedef ssize_t (*sec_send_data_fct_t) (sec_conn_t *, void *, size_t); +typedef ssize_t (*sec_send_tcp_cb) (sec_conn_t *, void *, size_t); -/* This is the prototype of the function that the daemon uses to receive data from a connection (TCP or SCTP). +/* This is the prototype of the function that the daemon uses to receive data from a TCP connection. * This function may be blocking. */ /* The parameters and return values are the same as the recv() function defined in POSIX. */ -typedef ssize_t (*sec_recv_data_fct_t) (sec_conn_t *, void *, size_t); +typedef ssize_t (*sec_recv_tcp_cb) (sec_conn_t *, void *, size_t); + +/* This is the prototype of the function that the daemon uses to send data on an SCTP connection */ +/* The second parameter is the stream id on which the message is sent. + -1 means autorotate the streams, in which case the value is updated to the actual stream it was sent to. + otherwise the value is unchanged. */ +typedef ssize_t (*sec_send_sctp_cb) (sec_conn_t *, int *, void *, size_t); + +/* This is the prototype of the function that the daemon uses to receive data from an SCTP connection. + * This function may be blocking. */ +/* The first argument is a connection handle. + * the second argument receives the stream id of a message on return. + * the third argument is the data on return. it must be freed after use. + * the last argument is the length of data. + */ +typedef ssize_t (*sec_recv_sctp_cb) (sec_conn_t *, int *, void **, size_t*); /* The following enum represents the possible states of a peer with regards to the security module (PSS = peer security state) */ typedef enum { @@ -121,8 +137,17 @@ /* The next 3 fields are valid only in the PSS_INITIAL and PSS_CONNECTED states */ sec_conn_t *conn; /* The connection for sending/receiving to/from this peer */ - sec_send_data_fct_t send_data; /* The callback function to send data to the peer */ - sec_recv_data_fct_t recv_data; /* The callback function to receive data from the peer */ + int proto; /* IPPROTO_TCP or IPPROTO_SCTP */ + union { + struct { + sec_send_tcp_cb send_data; /* The callback function to send data to the peer */ + sec_recv_tcp_cb recv_data; /* The callback function to receive data from the peer */ + } tcp; + struct { + sec_send_sctp_cb send_data; /* The callback function to send data to the peer */ + sec_recv_sctp_cb recv_data; /* The callback function to receive data from the peer */ + } sctp; + } cbs; } sec_session_t;