/*++ * NAME * tls_stream * SUMMARY * ACL_VSTREAM over TLS * SYNOPSIS * #include * #include * * 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