Cross Reference: /dovecot/src/lib-ssl-iostream/ostream-openssl.c
ostream-openssl.c revision 2454dfa32c93c20a8522c6ed42fe057baaac9f9a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2009-2017 Dovecot authors, see the included COPYING file */
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen#include "lib.h"
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen#include "buffer.h"
0536ccb51d41e3078c3a9fa33e509fb4b2420f95Timo Sirainen#include "ostream-private.h"
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen#include "iostream-openssl.h"
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainenstruct ssl_ostream {
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen struct ostream_private ostream;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen struct ssl_iostream *ssl_io;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen buffer_t *buffer;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen};
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenstatic void
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Siraineno_stream_ssl_close(struct iostream_private *stream, bool close_parent)
52d19b57c2411bb1c60f8248ea5c8c1a1cfc1b4fTimo Sirainen{
52d19b57c2411bb1c60f8248ea5c8c1a1cfc1b4fTimo Sirainen struct ssl_ostream *sstream = (struct ssl_ostream *)stream;
52d19b57c2411bb1c60f8248ea5c8c1a1cfc1b4fTimo Sirainen
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen if (close_parent)
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen o_stream_close(sstream->ssl_io->plain_output);
52d19b57c2411bb1c60f8248ea5c8c1a1cfc1b4fTimo Sirainen}
52d19b57c2411bb1c60f8248ea5c8c1a1cfc1b4fTimo Sirainen
52d19b57c2411bb1c60f8248ea5c8c1a1cfc1b4fTimo Sirainenstatic void o_stream_ssl_destroy(struct iostream_private *stream)
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen{
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen struct ssl_ostream *sstream = (struct ssl_ostream *)stream;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen sstream->ssl_io->ssl_output = NULL;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen ssl_iostream_unref(&sstream->ssl_io);
4b794181a01c04d1dd33c9a8339ddbc826106408Timo Sirainen if (sstream->buffer != NULL)
4b794181a01c04d1dd33c9a8339ddbc826106408Timo Sirainen buffer_free(&sstream->buffer);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen}
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainenstatic size_t
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Siraineno_stream_ssl_buffer(struct ssl_ostream *sstream, const struct const_iovec *iov,
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen unsigned int iov_count, size_t bytes_sent)
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen{
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen size_t avail, skip_left, size;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen unsigned int i;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen if (sstream->buffer == NULL)
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen sstream->buffer = buffer_create_dynamic(default_pool, 4096);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen skip_left = bytes_sent;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen for (i = 0; i < iov_count; i++) {
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen if (skip_left < iov[i].iov_len)
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen break;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen skip_left -= iov[i].iov_len;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen }
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
1c3e5f6b1afaf119335e3892b0a5ca76a37acebdTimo Sirainen if (sstream->ostream.max_buffer_size == 0) {
1c3e5f6b1afaf119335e3892b0a5ca76a37acebdTimo Sirainen /* we're requeted to use whatever space is available in
1c3e5f6b1afaf119335e3892b0a5ca76a37acebdTimo Sirainen the buffer */
8b48c53a81bdc67f267ffbcc45ba9860cb49e977Timo Sirainen avail = buffer_get_writable_size(sstream->buffer) - sstream->buffer->used;
1c3e5f6b1afaf119335e3892b0a5ca76a37acebdTimo Sirainen } else {
1c3e5f6b1afaf119335e3892b0a5ca76a37acebdTimo Sirainen avail = sstream->ostream.max_buffer_size > sstream->buffer->used ?
1c3e5f6b1afaf119335e3892b0a5ca76a37acebdTimo Sirainen sstream->ostream.max_buffer_size - sstream->buffer->used : 0;
1c3e5f6b1afaf119335e3892b0a5ca76a37acebdTimo Sirainen }
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen if (i < iov_count && skip_left > 0) {
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen size = I_MIN(iov[i].iov_len - skip_left, avail);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen buffer_append(sstream->buffer,
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen CONST_PTR_OFFSET(iov[i].iov_base, skip_left),
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen size);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen bytes_sent += size;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen avail -= size;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen if (size != iov[i].iov_len)
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen i = iov_count;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen }
ed41ec8aa0efaa50954fd16cb44c86c8350dadccTimo Sirainen if (avail > 0)
ed41ec8aa0efaa50954fd16cb44c86c8350dadccTimo Sirainen o_stream_set_flush_pending(sstream->ssl_io->plain_output, TRUE);
ed41ec8aa0efaa50954fd16cb44c86c8350dadccTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen for (; i < iov_count; i++) {
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen size = I_MIN(iov[i].iov_len, avail);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen buffer_append(sstream->buffer, iov[i].iov_base, size);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen bytes_sent += size;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen avail -= size;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen if (size != iov[i].iov_len)
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen break;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen }
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen sstream->ostream.ostream.offset += bytes_sent;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen return bytes_sent;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen}
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainenstatic int o_stream_ssl_flush_buffer(struct ssl_ostream *sstream)
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen{
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen size_t pos = 0;
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen int ret = 1;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen while (pos < sstream->buffer->used) {
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen /* we're writing plaintext data to OpenSSL, which it encrypts
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen and writes to bio_int's buffer. ssl_iostream_bio_sync()
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen reads it from there and adds to plain_output stream. */
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen ret = SSL_write(sstream->ssl_io->ssl,
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen CONST_PTR_OFFSET(sstream->buffer->data, pos),
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen sstream->buffer->used - pos);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen if (ret <= 0) {
3faa1040e5a3f9f35ffad29110216094ab2f5880Timo Sirainen ret = openssl_iostream_handle_write_error(sstream->ssl_io,
3faa1040e5a3f9f35ffad29110216094ab2f5880Timo Sirainen ret, "SSL_write");
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen if (ret < 0) {
1c6f6f5bef70f16546b3bc8f4cd5f93f373e82a2Timo Sirainen io_stream_set_error(&sstream->ostream.iostream,
1c6f6f5bef70f16546b3bc8f4cd5f93f373e82a2Timo Sirainen "%s", sstream->ssl_io->last_error);
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen sstream->ostream.ostream.stream_errno = errno;
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen break;
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen }
ed41ec8aa0efaa50954fd16cb44c86c8350dadccTimo Sirainen if (ret == 0)
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen break;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen } else {
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen pos += ret;
3faa1040e5a3f9f35ffad29110216094ab2f5880Timo Sirainen (void)openssl_iostream_bio_sync(sstream->ssl_io);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen }
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen }
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen buffer_delete(sstream->buffer, 0, pos);
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen return ret <= 0 ? ret : 1;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen}
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainenstatic int o_stream_ssl_flush(struct ostream_private *stream)
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen{
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen struct ssl_ostream *sstream = (struct ssl_ostream *)stream;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen int ret;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
3faa1040e5a3f9f35ffad29110216094ab2f5880Timo Sirainen if ((ret = openssl_iostream_more(sstream->ssl_io)) < 0) {
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen /* handshake failed */
1c6f6f5bef70f16546b3bc8f4cd5f93f373e82a2Timo Sirainen io_stream_set_error(&stream->iostream, "%s",
1c6f6f5bef70f16546b3bc8f4cd5f93f373e82a2Timo Sirainen sstream->ssl_io->last_error);
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen stream->ostream.stream_errno = errno;
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen } else if (ret > 0 && sstream->buffer != NULL &&
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen sstream->buffer->used > 0) {
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen /* we can try to send some of our buffered data */
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen ret = o_stream_ssl_flush_buffer(sstream);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen }
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen if (ret == 0 && sstream->ssl_io->want_read) {
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen /* we need to read more data until we can continue. */
96f071012c4afc923890009398e8e5a59a693c58Timo Sirainen o_stream_set_flush_pending(sstream->ssl_io->plain_output,
96f071012c4afc923890009398e8e5a59a693c58Timo Sirainen FALSE);
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen sstream->ssl_io->ostream_flush_waiting_input = TRUE;
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen ret = 1;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen }
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen return ret;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen}
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainenstatic ssize_t
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Siraineno_stream_ssl_sendv(struct ostream_private *stream,
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen const struct const_iovec *iov, unsigned int iov_count)
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen{
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen struct ssl_ostream *sstream = (struct ssl_ostream *)stream;
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen size_t bytes_sent = 0;
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen bytes_sent = o_stream_ssl_buffer(sstream, iov, iov_count, bytes_sent);
b1faf5924b03c6863d37f828b6dfb67f91dafec8Timo Sirainen if (sstream->ssl_io->handshaked &&
b1faf5924b03c6863d37f828b6dfb67f91dafec8Timo Sirainen sstream->buffer->used == bytes_sent) {
b1faf5924b03c6863d37f828b6dfb67f91dafec8Timo Sirainen /* buffer was empty before calling this. try to write it
b1faf5924b03c6863d37f828b6dfb67f91dafec8Timo Sirainen immediately. */
b1faf5924b03c6863d37f828b6dfb67f91dafec8Timo Sirainen if (o_stream_ssl_flush_buffer(sstream) < 0)
b1faf5924b03c6863d37f828b6dfb67f91dafec8Timo Sirainen return -1;
b1faf5924b03c6863d37f828b6dfb67f91dafec8Timo Sirainen }
b1faf5924b03c6863d37f828b6dfb67f91dafec8Timo Sirainen return bytes_sent;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen}
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
71da447014454c84828d9dface77219875554d7dTimo Sirainenstatic void o_stream_ssl_switch_ioloop(struct ostream_private *stream)
71da447014454c84828d9dface77219875554d7dTimo Sirainen{
71da447014454c84828d9dface77219875554d7dTimo Sirainen struct ssl_ostream *sstream = (struct ssl_ostream *)stream;
71da447014454c84828d9dface77219875554d7dTimo Sirainen
71da447014454c84828d9dface77219875554d7dTimo Sirainen o_stream_switch_ioloop(sstream->ssl_io->plain_output);
71da447014454c84828d9dface77219875554d7dTimo Sirainen}
71da447014454c84828d9dface77219875554d7dTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainenstatic int plain_flush_callback(struct ssl_ostream *sstream)
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen{
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen struct ostream *ostream = &sstream->ostream.ostream;
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen int ret, ret2;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen /* try to actually flush the pending data */
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen if ((ret = o_stream_flush(sstream->ssl_io->plain_output)) < 0)
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen return -1;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen /* we may be able to copy more data, try it */
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen o_stream_ref(ostream);
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen if (sstream->ostream.callback != NULL)
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen ret2 = sstream->ostream.callback(sstream->ostream.context);
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen else
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen ret2 = o_stream_flush(&sstream->ostream.ostream);
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen if (ret2 == 0)
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen o_stream_set_flush_pending(sstream->ssl_io->plain_output, TRUE);
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen o_stream_unref(&ostream);
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen if (ret2 < 0)
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen return -1;
21fed972adb354b92771eefad27f8ac8cbd5dd45Timo Sirainen return ret > 0 && ret2 > 0 ? 1 : 0;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen}
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
31df48d66a9a2327f6de41796e6819543c4494e1Timo Sirainenstatic size_t o_stream_ssl_get_used_size(const struct ostream_private *stream)
31df48d66a9a2327f6de41796e6819543c4494e1Timo Sirainen{
31df48d66a9a2327f6de41796e6819543c4494e1Timo Sirainen struct ssl_ostream *sstream = (struct ssl_ostream *)stream;
31df48d66a9a2327f6de41796e6819543c4494e1Timo Sirainen
31df48d66a9a2327f6de41796e6819543c4494e1Timo Sirainen return o_stream_get_buffer_used_size(sstream->ssl_io->plain_output);
31df48d66a9a2327f6de41796e6819543c4494e1Timo Sirainen}
31df48d66a9a2327f6de41796e6819543c4494e1Timo Sirainen
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainenstatic void
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Siraineno_stream_ssl_flush_pending(struct ostream_private *_stream, bool set)
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen{
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen struct ssl_ostream *sstream = (struct ssl_ostream *)_stream;
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen o_stream_set_flush_pending(sstream->ssl_io->plain_output, set);
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen}
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainenstatic void o_stream_ssl_set_max_buffer_size(struct iostream_private *_stream,
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen size_t max_size)
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen{
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen struct ssl_ostream *sstream = (struct ssl_ostream *)_stream;
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen sstream->ostream.max_buffer_size = max_size;
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen o_stream_set_max_buffer_size(sstream->ssl_io->plain_output, max_size);
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen}
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen
3faa1040e5a3f9f35ffad29110216094ab2f5880Timo Sirainenstruct ostream *openssl_o_stream_create_ssl(struct ssl_iostream *ssl_io)
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen{
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen struct ssl_ostream *sstream;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen ssl_io->refcount++;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen sstream = i_new(struct ssl_ostream, 1);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen sstream->ssl_io = ssl_io;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen sstream->ostream.max_buffer_size =
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen ssl_io->plain_output->real_stream->max_buffer_size;
52d19b57c2411bb1c60f8248ea5c8c1a1cfc1b4fTimo Sirainen sstream->ostream.iostream.close = o_stream_ssl_close;
52d19b57c2411bb1c60f8248ea5c8c1a1cfc1b4fTimo Sirainen sstream->ostream.iostream.destroy = o_stream_ssl_destroy;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen sstream->ostream.sendv = o_stream_ssl_sendv;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen sstream->ostream.flush = o_stream_ssl_flush;
71da447014454c84828d9dface77219875554d7dTimo Sirainen sstream->ostream.switch_ioloop = o_stream_ssl_switch_ioloop;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
31df48d66a9a2327f6de41796e6819543c4494e1Timo Sirainen sstream->ostream.get_used_size = o_stream_ssl_get_used_size;
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen sstream->ostream.flush_pending = o_stream_ssl_flush_pending;
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen sstream->ostream.iostream.set_max_buffer_size =
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen o_stream_ssl_set_max_buffer_size;
c239a1de4ad80639335c3ea4564537ca441eb76aTimo Sirainen
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen sstream->ostream.callback = ssl_io->plain_output->real_stream->callback;
ce8cd19ccf52b19f14d4ea9c8b29bd94c0e48e4dTimo Sirainen sstream->ostream.context = ssl_io->plain_output->real_stream->context;
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen o_stream_set_flush_callback(ssl_io->plain_output,
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen plain_flush_callback, sstream);
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen
8b247780e911909a9fdc47f69ce6d1478902ad98Timo Sirainen return o_stream_create(&sstream->ostream, NULL,
8b247780e911909a9fdc47f69ce6d1478902ad98Timo Sirainen o_stream_get_fd(ssl_io->plain_output));
e98de01b5644c88b6053e2921eb5e9a506fe263fTimo Sirainen}