Postfix3.3.1
tls_stream.c
[詳解]
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 
94 static 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 
114 static 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 
134 void tls_stream_start(VSTREAM *stream, TLS_SESS_STATE *context)
135 {
136  vstream_control(stream,
137  CA_VSTREAM_CTL_READ_FN(tls_timed_read),
138  CA_VSTREAM_CTL_WRITE_FN(tls_timed_write),
139  CA_VSTREAM_CTL_CONTEXT(context),
141 }
142 
143 /* tls_stream_stop - stop VSTREAM over TLS */
144 
145 void 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,
156  CA_VSTREAM_CTL_CONTEXT((void *) 0),
158 }
159 
160 #endif
#define CA_VSTREAM_CTL_READ_FN(v)
Definition: vstream.h:156
ssize_t dummy_read(int fd, void *unused_buf, size_t len, int unused_timeout, void *unused_context)
Definition: dummy_read.c:55
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define CA_VSTREAM_CTL_CONTEXT(v)
Definition: vstream.h:165
ssize_t dummy_write(int fd, void *unused_buf, size_t len, int unused_timeout, void *unused_context)
Definition: dummy_write.c:55
#define CA_VSTREAM_CTL_END
Definition: vstream.h:155
#define CA_VSTREAM_CTL_WRITE_FN(v)
Definition: vstream.h:157
void vstream_control(VSTREAM *stream, int name,...)
Definition: vstream.c:1372
void msg_info(const char *fmt,...)
Definition: msg.c:199