acl/lib_tls/tls/tls_stream.c
2014-11-19 00:25:21 +08:00

139 lines
3.8 KiB
C

/*++
* NAME
* tls_stream
* SUMMARY
* ACL_VSTREAM over TLS
* SYNOPSIS
* #include <tls.h>
* #include <tls_private.h>
*
* void tls_stream_start(stream, context)
* ACL_VSTREAM *stream;
* TLS_SESS_STATE *context;
*
* void tls_stream_stop(stream)
* ACL_VSTREAM *stream;
* DESCRIPTION
* This module implements the ACL_VSTREAM over TLS support user interface.
* The hard work is done elsewhere.
*
* tls_stream_start() enables TLS on the named stream. All read
* and write operations are directed through the TLS library,
* using the state information specified with the context argument.
*
* tls_stream_stop() replaces the ACL_VSTREAM read/write routines
* by dummies that have no side effects, and deletes the
* ACL_VSTREAM's reference to the TLS context.
* SEE ALSO
* dummy_read(3), placebo read routine
* dummy_write(3), placebo write routine
* LICENSE
* .ad
* .fi
* This software is free. You can do with it whatever you want.
* The original author kindly requests that you acknowledge
* the use of his software.
* AUTHOR(S)
* Based on code that was originally written by:
* Lutz Jaenicke
* BTU Cottbus
* Allgemeine Elektrotechnik
* Universitaetsplatz 3-4
* D-03044 Cottbus, Germany
*
* Updated by:
* Wietse Venema
* IBM T.J. Watson Research
* P.O. Box 704
* Yorktown Heights, NY 10598, USA
*--*/
#include "StdAfx.h"
#ifdef USE_TLS
/* TLS library. */
#include "tls.h"
#include "tls_private.h"
/* tls_timed_read - read content from stream, then TLS decapsulate */
static ssize_t tls_timed_read(int fd, void *buf, size_t len,
int timeout, void *context)
{
const char *myname = "tls_timed_read";
ssize_t ret;
TLS_SESS_STATE *TLScontext;
TLScontext = (TLS_SESS_STATE *) context;
if (!TLScontext)
acl_msg_panic("%s: no context", myname);
ret = tls_bio_read(fd, buf, (int) len, timeout, TLScontext);
if (ret > 0 && TLScontext->log_level >= 4)
acl_msg_info("Read %ld chars: %.*s",
(long) ret, (int) (ret > 40 ? 40 : ret), (char *) buf);
return (ret);
}
/* tls_timed_write - TLS encapsulate content, then write to stream */
static ssize_t tls_timed_write(int fd, void *buf, size_t len,
int timeout, void *context)
{
const char *myname = "tls_timed_write";
TLS_SESS_STATE *TLScontext;
TLScontext = (TLS_SESS_STATE *) context;
if (!TLScontext)
acl_msg_panic("%s: no context, buf(%s), len(%d)", myname, (char*) buf, (int) len);
if (TLScontext->log_level >= 4)
acl_msg_info("Write %ld chars: %.*s",
(long) len, (int) (len > 40 ? 40 : len), (char *) buf);
return (tls_bio_write(fd, buf, (int) len, timeout, TLScontext));
}
/* tls_stream_start - start ACL_VSTREAM over TLS */
void tls_stream_start(ACL_VSTREAM *stream, TLS_SESS_STATE *context)
{
acl_vstream_ctl(stream,
ACL_VSTREAM_CTL_READ_FN, tls_timed_read,
ACL_VSTREAM_CTL_WRITE_FN, tls_timed_write,
ACL_VSTREAM_CTL_CTX, (void *) context,
ACL_VSTREAM_CTL_END);
}
static ssize_t dummy_read(int fd acl_unused, void *buf acl_unused,
size_t len acl_unused, int timeout acl_unused, void *context acl_unused)
{
return (ACL_VSTREAM_EOF);
}
static ssize_t dummy_write(int fd acl_unused, void *buf acl_unused,
size_t len acl_unused, int timeout acl_unused, void *context acl_unused)
{
return (ACL_VSTREAM_EOF);
}
/* tls_stream_stop - stop ACL_VSTREAM over TLS */
void tls_stream_stop(ACL_VSTREAM *stream)
{
/*
* Prevent data leakage after TLS is turned off. The Postfix/TLS patch
* provided null function pointers; we use dummy routines that make less
* noise when used.
*/
acl_vstream_ctl(stream,
ACL_VSTREAM_CTL_READ_FN, dummy_read,
ACL_VSTREAM_CTL_WRITE_FN, dummy_write,
ACL_VSTREAM_CTL_CONTEXT, (void *) 0,
ACL_VSTREAM_CTL_END);
}
#endif