/*++ /* NAME /* tls_stream /* SUMMARY /* VSTREAM over TLS /* SYNOPSIS /* #define TLS_INTERNAL /* #include /* /* void tls_stream_start(stream, context) /* VSTREAM *stream; /* TLS_SESS_STATE *context; /* /* void tls_stream_stop(stream) /* VSTREAM *stream; /* DESCRIPTION /* This module implements the 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 VSTREAM read/write routines /* by dummies that have no side effects, and deletes the /* VSTREAM's reference to the TLS context. /* DIAGNOSTICS /* The tls_stream(3) read/write routines return the non-zero /* number of plaintext bytes read/written if successful; -1 /* after TLS protocol failure, system-call failure, or for any /* reason described under "in addition" below; and zero when /* the remote party closed the connection or sent a TLS shutdown /* request. /* /* Upon return from the tls_stream(3) read/write routines the /* global errno value is non-zero when the requested operation /* did not complete due to system call failure. /* /* In addition, the result value is set to -1, and the global /* errno value is set to ETIMEDOUT, when a network read/write /* request did not complete within the time limit. /* 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 /*--*/ /* System library. */ #include #ifdef USE_TLS /* Utility library. */ #include #include #include /* TLS library. */ #define TLS_INTERNAL #include /* * Interface mis-match compensation. The OpenSSL read/write routines return * unspecified negative values when an operation fails, while the vstream(3) * plaintext timed_read/write() functions follow the convention of UNIX * system calls, and return -1 upon error. The macro below makes OpenSSL * read/write results consistent with the UNIX system-call convention. */ #define NORMALIZED_VSTREAM_RETURN(retval) ((retval) < 0 ? -1 : (retval)) /* 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) msg_panic("%s: no context", myname); ret = tls_bio_read(fd, buf, len, timeout, TLScontext); if (ret > 0 && (TLScontext->log_mask & TLS_LOG_ALLPKTS)) msg_info("Read %ld chars: %.*s", (long) ret, (int) (ret > 40 ? 40 : ret), (char *) buf); return (NORMALIZED_VSTREAM_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"; ssize_t ret; TLS_SESS_STATE *TLScontext; TLScontext = (TLS_SESS_STATE *) context; if (!TLScontext) msg_panic("%s: no context", myname); if (TLScontext->log_mask & TLS_LOG_ALLPKTS) msg_info("Write %ld chars: %.*s", (long) len, (int) (len > 40 ? 40 : len), (char *) buf); ret = tls_bio_write(fd, buf, len, timeout, TLScontext); return (NORMALIZED_VSTREAM_RETURN(ret)); } /* tls_stream_start - start VSTREAM over TLS */ void tls_stream_start(VSTREAM *stream, TLS_SESS_STATE *context) { vstream_control(stream, CA_VSTREAM_CTL_READ_FN(tls_timed_read), CA_VSTREAM_CTL_WRITE_FN(tls_timed_write), CA_VSTREAM_CTL_CONTEXT(context), CA_VSTREAM_CTL_END); } /* tls_stream_stop - stop VSTREAM over TLS */ void tls_stream_stop(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. */ vstream_control(stream, CA_VSTREAM_CTL_READ_FN(dummy_read), CA_VSTREAM_CTL_WRITE_FN(dummy_write), CA_VSTREAM_CTL_CONTEXT((void *) 0), CA_VSTREAM_CTL_END); } #endif