blob: cfe788d27366ce099af82de3ec81d65585d868df [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
2 * SSL data transfer functions between buffers and SOCK_STREAM sockets
3 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#define _GNU_SOURCE
14#include <errno.h>
15#include <fcntl.h>
16#include <stdio.h>
17#include <stdlib.h>
18
19#include <sys/socket.h>
20#include <sys/stat.h>
21#include <sys/types.h>
22
23#include <netinet/tcp.h>
24
25#include <openssl/ssl.h>
26
27#include <common/buffer.h>
28#include <common/compat.h>
29#include <common/config.h>
30#include <common/debug.h>
31#include <common/standard.h>
32#include <common/ticks.h>
33#include <common/time.h>
34
35#include <proto/connection.h>
36#include <proto/fd.h>
37#include <proto/freq_ctr.h>
38#include <proto/frontend.h>
39#include <proto/log.h>
40#include <proto/protocols.h>
41#include <proto/ssl_sock.h>
42#include <proto/task.h>
43
44#include <types/global.h>
45
46
Emeric Brune1f38db2012-09-03 20:36:47 +020047
48void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
49{
50 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
51 (void)ret; /* shut gcc stupid warning */
52
53 if (where & SSL_CB_HANDSHAKE_START) {
54 /* Disable renegotiation (CVE-2009-3555) */
55 if (conn->flags & CO_FL_CONNECTED)
56 conn->flags |= CO_FL_ERROR;
57 }
58}
59
Emeric Brun46591952012-05-18 15:47:34 +020060/*
61 * This function is called if SSL * context is not yet allocated. The function
62 * is designed to be called before any other data-layer operation and sets the
63 * handshake flag on the connection. It is safe to call it multiple times.
64 * It returns 0 on success and -1 in error case.
65 */
66static int ssl_sock_init(struct connection *conn)
67{
68 /* already initialized */
69 if (conn->data_ctx)
70 return 0;
71
72 /* If it is in client mode initiate SSL session
73 in connect state otherwise accept state */
74 if (target_srv(&conn->target)) {
75
76 /* Alloc a new SSL session ctx */
77 conn->data_ctx = SSL_new(target_srv(&conn->target)->ssl_ctx.ctx);
78 if (!conn->data_ctx)
79 return -1;
80
81 SSL_set_connect_state(conn->data_ctx);
82 if (target_srv(&conn->target)->ssl_ctx.reused_sess)
83 SSL_set_session(conn->data_ctx, target_srv(&conn->target)->ssl_ctx.reused_sess);
84
85 /* set fd on SSL session context */
86 SSL_set_fd(conn->data_ctx, conn->t.sock.fd);
87
88 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +020089 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Emeric Brun46591952012-05-18 15:47:34 +020090 return 0;
91 }
92 else if (target_client(&conn->target)) {
93
94 /* Alloc a new SSL session ctx */
95 conn->data_ctx = SSL_new(target_client(&conn->target)->ssl_ctx.ctx);
96 if (!conn->data_ctx)
97 return -1;
98
99 SSL_set_accept_state(conn->data_ctx);
100
101 /* set fd on SSL session context */
102 SSL_set_fd(conn->data_ctx, conn->t.sock.fd);
103
Emeric Brune1f38db2012-09-03 20:36:47 +0200104 /* set connection pointer */
105 SSL_set_app_data(conn->data_ctx, conn);
106
Emeric Brun46591952012-05-18 15:47:34 +0200107 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +0200108 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Emeric Brun46591952012-05-18 15:47:34 +0200109 return 0;
110 }
111 /* don't know how to handle such a target */
112 return -1;
113}
114
115
116/* This is the callback which is used when an SSL handshake is pending. It
117 * updates the FD status if it wants some polling before being called again.
118 * It returns 0 if it fails in a fatal way or needs to poll to go further,
119 * otherwise it returns non-zero and removes itself from the connection's
120 * flags (the bit is provided in <flag> by the caller).
121 */
122int ssl_sock_handshake(struct connection *conn, unsigned int flag)
123{
124 int ret;
125
126 if (!conn->data_ctx)
127 goto out_error;
128
129 ret = SSL_do_handshake(conn->data_ctx);
130 if (ret != 1) {
131 /* handshake did not complete, let's find why */
132 ret = SSL_get_error(conn->data_ctx, ret);
133
134 if (ret == SSL_ERROR_WANT_WRITE) {
135 /* SSL handshake needs to write, L4 connection may not be ready */
136 __conn_sock_stop_recv(conn);
137 __conn_sock_poll_send(conn);
138 return 0;
139 }
140 else if (ret == SSL_ERROR_WANT_READ) {
141 /* SSL handshake needs to read, L4 connection is ready */
142 if (conn->flags & CO_FL_WAIT_L4_CONN)
143 conn->flags &= ~CO_FL_WAIT_L4_CONN;
144 __conn_sock_stop_send(conn);
145 __conn_sock_poll_recv(conn);
146 return 0;
147 }
148 else {
149 /* Fail on all other handshake errors */
150 goto out_error;
151 }
152 }
153
154 /* Handshake succeeded */
155 if (target_srv(&conn->target)) {
156 if (!SSL_session_reused(conn->data_ctx)) {
157 /* check if session was reused, if not store current session on server for reuse */
158 if (target_srv(&conn->target)->ssl_ctx.reused_sess)
159 SSL_SESSION_free(target_srv(&conn->target)->ssl_ctx.reused_sess);
160
161 target_srv(&conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->data_ctx);
162 }
163 }
164
165 /* The connection is now established at both layers, it's time to leave */
166 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
167 return 1;
168
169 out_error:
170 /* Fail on all other handshake errors */
171 conn->flags |= CO_FL_ERROR;
172 conn->flags &= ~flag;
173 return 0;
174}
175
176/* Receive up to <count> bytes from connection <conn>'s socket and store them
177 * into buffer <buf>. The caller must ensure that <count> is always smaller
178 * than the buffer's size. Only one call to recv() is performed, unless the
179 * buffer wraps, in which case a second call may be performed. The connection's
180 * flags are updated with whatever special event is detected (error, read0,
181 * empty). The caller is responsible for taking care of those events and
182 * avoiding the call if inappropriate. The function does not call the
183 * connection's polling update function, so the caller is responsible for this.
184 */
185static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
186{
187 int ret, done = 0;
188 int try = count;
189
190 if (!conn->data_ctx)
191 goto out_error;
192
193 if (conn->flags & CO_FL_HANDSHAKE)
194 /* a handshake was requested */
195 return 0;
196
197 /* compute the maximum block size we can read at once. */
198 if (buffer_empty(buf)) {
199 /* let's realign the buffer to optimize I/O */
200 buf->p = buf->data;
201 }
202 else if (buf->data + buf->o < buf->p &&
203 buf->p + buf->i < buf->data + buf->size) {
204 /* remaining space wraps at the end, with a moving limit */
205 if (try > buf->data + buf->size - (buf->p + buf->i))
206 try = buf->data + buf->size - (buf->p + buf->i);
207 }
208
209 /* read the largest possible block. For this, we perform only one call
210 * to recv() unless the buffer wraps and we exactly fill the first hunk,
211 * in which case we accept to do it once again. A new attempt is made on
212 * EINTR too.
213 */
214 while (try) {
215 ret = SSL_read(conn->data_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +0200216 if (conn->flags & CO_FL_ERROR) {
217 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
218 break;
219 }
Emeric Brun46591952012-05-18 15:47:34 +0200220 if (ret > 0) {
221 buf->i += ret;
222 done += ret;
223 if (ret < try)
224 break;
225 count -= ret;
226 try = count;
227 }
228 else if (ret == 0) {
229 goto read0;
230 }
231 else {
232 ret = SSL_get_error(conn->data_ctx, ret);
233 if (ret == SSL_ERROR_WANT_WRITE) {
234 /* handshake is running, and it needs to poll for a write event */
235 conn->flags |= CO_FL_SSL_WAIT_HS;
236 __conn_sock_poll_send(conn);
237 break;
238 }
239 else if (ret == SSL_ERROR_WANT_READ) {
240 /* we need to poll for retry a read later */
241 __conn_data_poll_recv(conn);
242 break;
243 }
244 /* otherwise it's a real error */
245 goto out_error;
246 }
247 }
248 return done;
249
250 read0:
251 conn_sock_read0(conn);
252 return done;
253 out_error:
254 conn->flags |= CO_FL_ERROR;
255 return done;
256}
257
258
259/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
260 * <flags> may contain MSG_MORE to make the system hold on without sending
261 * data too fast, but this flag is ignored at the moment.
262 * Only one call to send() is performed, unless the buffer wraps, in which case
263 * a second call may be performed. The connection's flags are updated with
264 * whatever special event is detected (error, empty). The caller is responsible
265 * for taking care of those events and avoiding the call if inappropriate. The
266 * function does not call the connection's polling update function, so the caller
267 * is responsible for this.
268 */
269static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
270{
271 int ret, try, done;
272
273 done = 0;
274
275 if (!conn->data_ctx)
276 goto out_error;
277
278 if (conn->flags & CO_FL_HANDSHAKE)
279 /* a handshake was requested */
280 return 0;
281
282 /* send the largest possible block. For this we perform only one call
283 * to send() unless the buffer wraps and we exactly fill the first hunk,
284 * in which case we accept to do it once again.
285 */
286 while (buf->o) {
287 try = buf->o;
288 /* outgoing data may wrap at the end */
289 if (buf->data + try > buf->p)
290 try = buf->data + try - buf->p;
291
292 ret = SSL_write(conn->data_ctx, bo_ptr(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +0200293 if (conn->flags & CO_FL_ERROR) {
294 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
295 break;
296 }
Emeric Brun46591952012-05-18 15:47:34 +0200297 if (ret > 0) {
298 buf->o -= ret;
299 done += ret;
300
301 if (likely(!buffer_len(buf)))
302 /* optimize data alignment in the buffer */
303 buf->p = buf->data;
304
305 /* if the system buffer is full, don't insist */
306 if (ret < try)
307 break;
308 }
309 else {
310 ret = SSL_get_error(conn->data_ctx, ret);
311 if (ret == SSL_ERROR_WANT_WRITE) {
312 /* we need to poll to retry a write later */
313 __conn_data_poll_send(conn);
314 break;
315 }
316 else if (ret == SSL_ERROR_WANT_READ) {
317 /* handshake is running, and
318 it needs to poll for a read event,
319 write polling must be disabled cause
320 we are sure we can't write anything more
321 before handshake re-performed */
322 conn->flags |= CO_FL_SSL_WAIT_HS;
323 __conn_sock_poll_recv(conn);
324 break;
325 }
326 goto out_error;
327 }
328 }
329 return done;
330
331 out_error:
332 conn->flags |= CO_FL_ERROR;
333 return done;
334}
335
336
337static void ssl_sock_close(struct connection *conn) {
338
339 if (conn->data_ctx) {
340 SSL_free(conn->data_ctx);
341 conn->data_ctx = NULL;
342 }
343
344}
345
346/* This function tries to perform a clean shutdown on an SSL connection, and in
347 * any case, flags the connection as reusable if no handshake was in progress.
348 */
349static void ssl_sock_shutw(struct connection *conn, int clean)
350{
351 if (conn->flags & CO_FL_HANDSHAKE)
352 return;
353 /* no handshake was in progress, try a clean ssl shutdown */
354 if (clean)
355 SSL_shutdown(conn->data_ctx);
356
357 /* force flag on ssl to keep session in cache regardless shutdown result */
358 SSL_set_shutdown(conn->data_ctx, SSL_SENT_SHUTDOWN);
359}
360
361
362/* data-layer operations for SSL sockets */
363struct data_ops ssl_sock = {
364 .snd_buf = ssl_sock_from_buf,
365 .rcv_buf = ssl_sock_to_buf,
366 .rcv_pipe = NULL,
367 .snd_pipe = NULL,
368 .shutr = NULL,
369 .shutw = ssl_sock_shutw,
370 .close = ssl_sock_close,
371 .init = ssl_sock_init,
372};
373
374__attribute__((constructor))
375static void __ssl_sock_init(void) {
376 STACK_OF(SSL_COMP)* cm;
377
378 SSL_library_init();
379 cm = SSL_COMP_get_compression_methods();
380 sk_SSL_COMP_zero(cm);
381}
382
383/*
384 * Local variables:
385 * c-indent-level: 8
386 * c-basic-offset: 8
387 * End:
388 */