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