2014-11-19 00:25:21 +08:00
|
|
|
/*++
|
|
|
|
* 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
|