1/*++ 2/* NAME 3/* tls_stream 4/* SUMMARY 5/* VSTREAM over TLS 6/* SYNOPSIS 7/* #define TLS_INTERNAL 8/* #include <tls.h> 9/* 10/* void tls_stream_start(stream, context) 11/* VSTREAM *stream; 12/* TLS_SESS_STATE *context; 13/* 14/* void tls_stream_stop(stream) 15/* VSTREAM *stream; 16/* DESCRIPTION 17/* This module implements the VSTREAM over TLS support user interface. 18/* The hard work is done elsewhere. 19/* 20/* tls_stream_start() enables TLS on the named stream. All read 21/* and write operations are directed through the TLS library, 22/* using the state information specified with the context argument. 23/* 24/* tls_stream_stop() replaces the VSTREAM read/write routines 25/* by dummies that have no side effects, and deletes the 26/* VSTREAM's reference to the TLS context. 27/* DIAGNOSTICS 28/* The tls_stream(3) read/write routines return the non-zero 29/* number of plaintext bytes read/written if successful; -1 30/* after TLS protocol failure, system-call failure, or for any 31/* reason described under "in addition" below; and zero when 32/* the remote party closed the connection or sent a TLS shutdown 33/* request. 34/* 35/* Upon return from the tls_stream(3) read/write routines the 36/* global errno value is non-zero when the requested operation 37/* did not complete due to system call failure. 38/* 39/* In addition, the result value is set to -1, and the global 40/* errno value is set to ETIMEDOUT, when a network read/write 41/* request did not complete within the time limit. 42/* SEE ALSO 43/* dummy_read(3), placebo read routine 44/* dummy_write(3), placebo write routine 45/* LICENSE 46/* .ad 47/* .fi 48/* This software is free. You can do with it whatever you want. 49/* The original author kindly requests that you acknowledge 50/* the use of his software. 51/* AUTHOR(S) 52/* Based on code that was originally written by: 53/* Lutz Jaenicke 54/* BTU Cottbus 55/* Allgemeine Elektrotechnik 56/* Universitaetsplatz 3-4 57/* D-03044 Cottbus, Germany 58/* 59/* Updated by: 60/* Wietse Venema 61/* IBM T.J. Watson Research 62/* P.O. Box 704 63/* Yorktown Heights, NY 10598, USA 64/*--*/ 65 66/* System library. */ 67 68#include <sys_defs.h> 69 70#ifdef USE_TLS 71 72/* Utility library. */ 73 74#include <iostuff.h> 75#include <vstream.h> 76#include <msg.h> 77 78/* TLS library. */ 79 80#define TLS_INTERNAL 81#include <tls.h> 82 83 /* 84 * Interface mis-match compensation. The OpenSSL read/write routines return 85 * unspecified negative values when an operation fails, while the vstream(3) 86 * plaintext timed_read/write() functions follow the convention of UNIX 87 * system calls, and return -1 upon error. The macro below makes OpenSSL 88 * read/write results consistent with the UNIX system-call convention. 89 */ 90#define NORMALIZED_VSTREAM_RETURN(retval) ((retval) < 0 ? -1 : (retval)) 91 92/* tls_timed_read - read content from stream, then TLS decapsulate */ 93 94static ssize_t tls_timed_read(int fd, void *buf, size_t len, int timeout, 95 void *context) 96{ 97 const char *myname = "tls_timed_read"; 98 ssize_t ret; 99 TLS_SESS_STATE *TLScontext; 100 101 TLScontext = (TLS_SESS_STATE *) context; 102 if (!TLScontext) 103 msg_panic("%s: no context", myname); 104 105 ret = tls_bio_read(fd, buf, len, timeout, TLScontext); 106 if (ret > 0 && (TLScontext->log_mask & TLS_LOG_ALLPKTS)) 107 msg_info("Read %ld chars: %.*s", 108 (long) ret, (int) (ret > 40 ? 40 : ret), (char *) buf); 109 return (NORMALIZED_VSTREAM_RETURN(ret)); 110} 111 112/* tls_timed_write - TLS encapsulate content, then write to stream */ 113 114static ssize_t tls_timed_write(int fd, void *buf, size_t len, int timeout, 115 void *context) 116{ 117 const char *myname = "tls_timed_write"; 118 ssize_t ret; 119 TLS_SESS_STATE *TLScontext; 120 121 TLScontext = (TLS_SESS_STATE *) context; 122 if (!TLScontext) 123 msg_panic("%s: no context", myname); 124 125 if (TLScontext->log_mask & TLS_LOG_ALLPKTS) 126 msg_info("Write %ld chars: %.*s", 127 (long) len, (int) (len > 40 ? 40 : len), (char *) buf); 128 ret = tls_bio_write(fd, buf, len, timeout, TLScontext); 129 return (NORMALIZED_VSTREAM_RETURN(ret)); 130} 131 132/* tls_stream_start - start VSTREAM over TLS */ 133 134void tls_stream_start(VSTREAM *stream, TLS_SESS_STATE *context) 135{ 136 vstream_control(stream, 137 VSTREAM_CTL_READ_FN, tls_timed_read, 138 VSTREAM_CTL_WRITE_FN, tls_timed_write, 139 VSTREAM_CTL_CONTEXT, (void *) context, 140 VSTREAM_CTL_END); 141} 142 143/* tls_stream_stop - stop VSTREAM over TLS */ 144 145void tls_stream_stop(VSTREAM *stream) 146{ 147 148 /* 149 * Prevent data leakage after TLS is turned off. The Postfix/TLS patch 150 * provided null function pointers; we use dummy routines that make less 151 * noise when used. 152 */ 153 vstream_control(stream, 154 VSTREAM_CTL_READ_FN, dummy_read, 155 VSTREAM_CTL_WRITE_FN, dummy_write, 156 VSTREAM_CTL_CONTEXT, (void *) 0, 157 VSTREAM_CTL_END); 158} 159 160#endif 161