1 /*
2 * Part of Very Secure FTPd
3 * Licence: GPL v2. Note that this code interfaces with with the OpenSSL
4 * libraries, so please read LICENSE where I give explicit permission to link
5 * against the OpenSSL libraries.
6 * Author: Chris Evans
7 * ssl.c
8 *
9 * Routines to handle a SSL/TLS-based implementation of RFC 2228, i.e.
10 * encryption.
11 */
12
13 #include "ssl.h"
14 #include "session.h"
15 #include "ftpcodes.h"
16 #include "ftpcmdio.h"
17 #include "defs.h"
18 #include "str.h"
19 #include "sysutil.h"
20 #include "tunables.h"
21 #include "utility.h"
22 #include "builddefs.h"
23 #include "logging.h"
24
25 #ifdef VSF_BUILD_SSL
26
27 #include <openssl/ssl.h>
28 #include <openssl/err.h>
29 #include <openssl/rand.h>
30 #include <openssl/bio.h>
31 #include <errno.h>
32 #include <limits.h>
33
34 static char* get_ssl_error();
35 static SSL* get_ssl(struct vsf_session* p_sess, int fd);
36 static int ssl_session_init(struct vsf_session* p_sess);
37 static void setup_bio_callbacks();
38 static long bio_callback(
39 BIO* p_bio, int oper, const char* p_arg, int argi, long argl, long retval);
40 static int ssl_verify_callback(int verify_ok, X509_STORE_CTX* p_ctx);
41 static int ssl_cert_digest(
42 SSL* p_ssl, struct vsf_session* p_sess, struct mystr* p_str);
43 static void maybe_log_shutdown_state(struct vsf_session* p_sess);
44 static void maybe_log_ssl_error_state(struct vsf_session* p_sess, int ret);
45 static int ssl_read_common(struct vsf_session* p_sess,
46 SSL* p_ssl,
47 char* p_buf,
48 unsigned int len,
49 int (*p_ssl_func)(SSL*, void*, int));
50
51 static int ssl_inited;
52 static struct mystr debug_str;
53
54 void
ssl_init(struct vsf_session * p_sess)55 ssl_init(struct vsf_session* p_sess)
56 {
57 if (!ssl_inited)
58 {
59 SSL_CTX* p_ctx;
60 long options;
61 int verify_option = 0;
62 SSL_library_init();
63 p_ctx = SSL_CTX_new(SSLv23_server_method());
64 if (p_ctx == NULL)
65 {
66 die("SSL: could not allocate SSL context");
67 }
68 options = SSL_OP_ALL;
69 if (!tunable_sslv2)
70 {
71 options |= SSL_OP_NO_SSLv2;
72 }
73 if (!tunable_sslv3)
74 {
75 options |= SSL_OP_NO_SSLv3;
76 }
77 if (!tunable_tlsv1)
78 {
79 options |= SSL_OP_NO_TLSv1;
80 }
81 SSL_CTX_set_options(p_ctx, options);
82 if (tunable_rsa_cert_file)
83 {
84 const char* p_key = tunable_rsa_private_key_file;
85 if (!p_key)
86 {
87 p_key = tunable_rsa_cert_file;
88 }
89 if (SSL_CTX_use_certificate_chain_file(p_ctx, tunable_rsa_cert_file) != 1)
90 {
91 die("SSL: cannot load RSA certificate");
92 }
93 if (SSL_CTX_use_PrivateKey_file(p_ctx, p_key, X509_FILETYPE_PEM) != 1)
94 {
95 die("SSL: cannot load RSA private key");
96 }
97 }
98 if (tunable_dsa_cert_file)
99 {
100 const char* p_key = tunable_dsa_private_key_file;
101 if (!p_key)
102 {
103 p_key = tunable_dsa_cert_file;
104 }
105 if (SSL_CTX_use_certificate_chain_file(p_ctx, tunable_dsa_cert_file) != 1)
106 {
107 die("SSL: cannot load DSA certificate");
108 }
109 if (SSL_CTX_use_PrivateKey_file(p_ctx, p_key, X509_FILETYPE_PEM) != 1)
110 {
111 die("SSL: cannot load DSA private key");
112 }
113 }
114 if (tunable_ssl_ciphers &&
115 SSL_CTX_set_cipher_list(p_ctx, tunable_ssl_ciphers) != 1)
116 {
117 die("SSL: could not set cipher list");
118 }
119 if (RAND_status() != 1)
120 {
121 die("SSL: RNG is not seeded");
122 }
123 {
124 EC_KEY* key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
125 if (key == NULL)
126 {
127 die("SSL: failed to get curve p256");
128 }
129 SSL_CTX_set_tmp_ecdh(p_ctx, key);
130 EC_KEY_free(key);
131 }
132 if (tunable_ssl_request_cert)
133 {
134 verify_option |= SSL_VERIFY_PEER;
135 }
136 if (tunable_require_cert)
137 {
138 verify_option |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
139 }
140 if (verify_option)
141 {
142 SSL_CTX_set_verify(p_ctx, verify_option, ssl_verify_callback);
143 if (tunable_ca_certs_file)
144 {
145 STACK_OF(X509_NAME)* p_names;
146 if (!SSL_CTX_load_verify_locations(p_ctx, tunable_ca_certs_file, NULL))
147 {
148 die("SSL: could not load verify file");
149 }
150 p_names = SSL_load_client_CA_file(tunable_ca_certs_file);
151 if (!p_names)
152 {
153 die("SSL: could not load client certs file");
154 }
155 SSL_CTX_set_client_CA_list(p_ctx, p_names);
156 }
157 }
158 {
159 static const char* p_ctx_id = "vsftpd";
160 SSL_CTX_set_session_id_context(p_ctx, (void*) p_ctx_id,
161 vsf_sysutil_strlen(p_ctx_id));
162 }
163 if (tunable_require_ssl_reuse)
164 {
165 /* Ensure cached session doesn't expire */
166 SSL_CTX_set_timeout(p_ctx, INT_MAX);
167 }
168 p_sess->p_ssl_ctx = p_ctx;
169 ssl_inited = 1;
170 }
171 }
172
173 void
ssl_control_handshake(struct vsf_session * p_sess)174 ssl_control_handshake(struct vsf_session* p_sess)
175 {
176 if (!ssl_session_init(p_sess))
177 {
178 struct mystr err_str = INIT_MYSTR;
179 str_alloc_text(&err_str, "Negotiation failed: ");
180 /* Technically, we shouldn't leak such detailed error messages. */
181 str_append_text(&err_str, get_ssl_error());
182 vsf_cmdio_write_str(p_sess, FTP_TLS_FAIL, &err_str);
183 vsf_sysutil_exit(1);
184 }
185 p_sess->control_use_ssl = 1;
186 }
187
188 void
handle_auth(struct vsf_session * p_sess)189 handle_auth(struct vsf_session* p_sess)
190 {
191 str_upper(&p_sess->ftp_arg_str);
192 if (str_equal_text(&p_sess->ftp_arg_str, "TLS") ||
193 str_equal_text(&p_sess->ftp_arg_str, "TLS-C") ||
194 str_equal_text(&p_sess->ftp_arg_str, "SSL") ||
195 str_equal_text(&p_sess->ftp_arg_str, "TLS-P"))
196 {
197 vsf_cmdio_write(p_sess, FTP_AUTHOK, "Proceed with negotiation.");
198 ssl_control_handshake(p_sess);
199 if (str_equal_text(&p_sess->ftp_arg_str, "SSL") ||
200 str_equal_text(&p_sess->ftp_arg_str, "TLS-P"))
201 {
202 p_sess->data_use_ssl = 1;
203 }
204 }
205 else
206 {
207 vsf_cmdio_write(p_sess, FTP_BADAUTH, "Unknown AUTH type.");
208 }
209 }
210
211 void
handle_pbsz(struct vsf_session * p_sess)212 handle_pbsz(struct vsf_session* p_sess)
213 {
214 if (!p_sess->control_use_ssl)
215 {
216 vsf_cmdio_write(p_sess, FTP_BADPBSZ, "PBSZ needs a secure connection.");
217 }
218 else
219 {
220 vsf_cmdio_write(p_sess, FTP_PBSZOK, "PBSZ set to 0.");
221 }
222 }
223
224 void
handle_prot(struct vsf_session * p_sess)225 handle_prot(struct vsf_session* p_sess)
226 {
227 str_upper(&p_sess->ftp_arg_str);
228 if (!p_sess->control_use_ssl)
229 {
230 vsf_cmdio_write(p_sess, FTP_BADPROT, "PROT needs a secure connection.");
231 }
232 else if (str_equal_text(&p_sess->ftp_arg_str, "C"))
233 {
234 p_sess->data_use_ssl = 0;
235 vsf_cmdio_write(p_sess, FTP_PROTOK, "PROT now Clear.");
236 }
237 else if (str_equal_text(&p_sess->ftp_arg_str, "P"))
238 {
239 p_sess->data_use_ssl = 1;
240 vsf_cmdio_write(p_sess, FTP_PROTOK, "PROT now Private.");
241 }
242 else if (str_equal_text(&p_sess->ftp_arg_str, "S") ||
243 str_equal_text(&p_sess->ftp_arg_str, "E"))
244 {
245 vsf_cmdio_write(p_sess, FTP_NOHANDLEPROT, "PROT not supported.");
246 }
247 else
248 {
249 vsf_cmdio_write(p_sess, FTP_NOSUCHPROT, "PROT not recognized.");
250 }
251 }
252
253 int
ssl_read(struct vsf_session * p_sess,void * p_ssl,char * p_buf,unsigned int len)254 ssl_read(struct vsf_session* p_sess, void* p_ssl, char* p_buf, unsigned int len)
255 {
256 return ssl_read_common(p_sess, (SSL*) p_ssl, p_buf, len, SSL_read);
257 }
258
259 int
ssl_peek(struct vsf_session * p_sess,void * p_ssl,char * p_buf,unsigned int len)260 ssl_peek(struct vsf_session* p_sess, void* p_ssl, char* p_buf, unsigned int len)
261 {
262 return ssl_read_common(p_sess, (SSL*) p_ssl, p_buf, len, SSL_peek);
263 }
264
265 static int
ssl_read_common(struct vsf_session * p_sess,SSL * p_void_ssl,char * p_buf,unsigned int len,int (* p_ssl_func)(SSL *,void *,int))266 ssl_read_common(struct vsf_session* p_sess,
267 SSL* p_void_ssl,
268 char* p_buf,
269 unsigned int len,
270 int (*p_ssl_func)(SSL*, void*, int))
271 {
272 int retval;
273 int err;
274 SSL* p_ssl = (SSL*) p_void_ssl;
275 do
276 {
277 retval = (*p_ssl_func)(p_ssl, p_buf, len);
278 err = SSL_get_error(p_ssl, retval);
279 }
280 while (retval < 0 && (err == SSL_ERROR_WANT_READ ||
281 err == SSL_ERROR_WANT_WRITE));
282 /* If we hit an EOF, make sure it was from the peer, not injected by the
283 * attacker.
284 */
285 if (retval == 0 && SSL_get_shutdown(p_ssl) != SSL_RECEIVED_SHUTDOWN)
286 {
287 if (p_ssl == p_sess->p_control_ssl)
288 {
289 str_alloc_text(&debug_str, "Control");
290 }
291 else
292 {
293 str_alloc_text(&debug_str, "DATA");
294 }
295 str_append_text(&debug_str, " connection terminated without SSL shutdown.");
296 if (p_ssl != p_sess->p_control_ssl)
297 {
298 str_append_text(&debug_str,
299 " Buggy client! Integrity of upload cannot be asserted.");
300 }
301 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
302 if (tunable_strict_ssl_read_eof)
303 {
304 return -1;
305 }
306 }
307 return retval;
308 }
309
310 int
ssl_write(void * p_ssl,const char * p_buf,unsigned int len)311 ssl_write(void* p_ssl, const char* p_buf, unsigned int len)
312 {
313 int retval;
314 int err;
315 do
316 {
317 retval = SSL_write((SSL*) p_ssl, p_buf, len);
318 err = SSL_get_error((SSL*) p_ssl, retval);
319 }
320 while (retval < 0 && (err == SSL_ERROR_WANT_READ ||
321 err == SSL_ERROR_WANT_WRITE));
322 return retval;
323 }
324
325 int
ssl_write_str(void * p_ssl,const struct mystr * p_str)326 ssl_write_str(void* p_ssl, const struct mystr* p_str)
327 {
328 unsigned int len = str_getlen(p_str);
329 int ret = SSL_write((SSL*) p_ssl, str_getbuf(p_str), len);
330 if ((unsigned int) ret != len)
331 {
332 return -1;
333 }
334 return 0;
335 }
336
337 int
ssl_read_into_str(struct vsf_session * p_sess,void * p_ssl,struct mystr * p_str)338 ssl_read_into_str(struct vsf_session* p_sess, void* p_ssl, struct mystr* p_str)
339 {
340 unsigned int len = str_getlen(p_str);
341 int ret = ssl_read(p_sess, p_ssl, (char*) str_getbuf(p_str), len);
342 if (ret >= 0)
343 {
344 str_trunc(p_str, (unsigned int) ret);
345 }
346 else
347 {
348 str_empty(p_str);
349 }
350 return ret;
351 }
352
353 static void
maybe_log_shutdown_state(struct vsf_session * p_sess)354 maybe_log_shutdown_state(struct vsf_session* p_sess)
355 {
356 if (tunable_debug_ssl)
357 {
358 int ret = SSL_get_shutdown(p_sess->p_data_ssl);
359 str_alloc_text(&debug_str, "SSL shutdown state is: ");
360 if (ret == 0)
361 {
362 str_append_text(&debug_str, "NONE");
363 }
364 else if (ret == SSL_SENT_SHUTDOWN)
365 {
366 str_append_text(&debug_str, "SSL_SENT_SHUTDOWN");
367 }
368 else if (ret == SSL_RECEIVED_SHUTDOWN)
369 {
370 str_append_text(&debug_str, "SSL_RECEIVED_SHUTDOWN");
371 }
372 else
373 {
374 str_append_ulong(&debug_str, ret);
375 }
376 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
377 }
378 }
379
380 static void
maybe_log_ssl_error_state(struct vsf_session * p_sess,int ret)381 maybe_log_ssl_error_state(struct vsf_session* p_sess, int ret)
382 {
383 if (tunable_debug_ssl)
384 {
385 str_alloc_text(&debug_str, "SSL ret: ");
386 str_append_ulong(&debug_str, ret);
387 str_append_text(&debug_str, ", SSL error: ");
388 str_append_text(&debug_str, get_ssl_error());
389 str_append_text(&debug_str, ", errno: ");
390 str_append_ulong(&debug_str, errno);
391 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
392 }
393 }
394
395 int
ssl_data_close(struct vsf_session * p_sess)396 ssl_data_close(struct vsf_session* p_sess)
397 {
398 int success = 1;
399 SSL* p_ssl = p_sess->p_data_ssl;
400 if (p_ssl)
401 {
402 int ret;
403 maybe_log_shutdown_state(p_sess);
404
405 /* Disable Nagle algorithm. We want the shutdown packet to be sent
406 * immediately, there's nothing coming after.
407 */
408 vsf_sysutil_set_nodelay(SSL_get_fd(p_ssl));
409
410 /* This is a mess. Ideally, when we're the sender, we'd like to get to the
411 * SSL_RECEIVED_SHUTDOWN state to get a cryptographic guarantee that the
412 * peer received all the data and shut the connection down cleanly. It
413 * doesn't matter hugely apart from logging, but it's a nagging detail.
414 * Unfortunately, no FTP client I found was able to get sends into that
415 * state, so the best we can do is issue SSL_shutdown but not check the
416 * errors / returns. At least this enables the receiver to be sure of the
417 * integrity of the send in terms of unwanted truncation.
418 */
419 ret = SSL_shutdown(p_ssl);
420 maybe_log_shutdown_state(p_sess);
421 if (ret == 0)
422 {
423 ret = SSL_shutdown(p_ssl);
424 maybe_log_shutdown_state(p_sess);
425 if (ret != 1)
426 {
427 if (tunable_strict_ssl_write_shutdown)
428 {
429 success = 0;
430 }
431 maybe_log_shutdown_state(p_sess);
432 maybe_log_ssl_error_state(p_sess, ret);
433 }
434 }
435 else if (ret < 0)
436 {
437 if (tunable_strict_ssl_write_shutdown)
438 {
439 success = 0;
440 }
441 maybe_log_ssl_error_state(p_sess, ret);
442 }
443 SSL_free(p_ssl);
444 p_sess->p_data_ssl = NULL;
445 }
446 return success;
447 }
448
449 int
ssl_accept(struct vsf_session * p_sess,int fd)450 ssl_accept(struct vsf_session* p_sess, int fd)
451 {
452 /* SECURITY: data SSL connections don't have any auth on them as part of the
453 * protocol. If a client sends an unfortunately optional client cert then
454 * we can check for a match between the control and data connections.
455 */
456 SSL* p_ssl;
457 int reused;
458 if (p_sess->p_data_ssl != NULL)
459 {
460 die("p_data_ssl should be NULL.");
461 }
462 p_ssl = get_ssl(p_sess, fd);
463 if (p_ssl == NULL)
464 {
465 return 0;
466 }
467 p_sess->p_data_ssl = p_ssl;
468 setup_bio_callbacks(p_ssl);
469 reused = SSL_session_reused(p_ssl);
470 if (tunable_require_ssl_reuse && !reused)
471 {
472 str_alloc_text(&debug_str, "No SSL session reuse on data channel.");
473 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
474 ssl_data_close(p_sess);
475 return 0;
476 }
477 if (str_getlen(&p_sess->control_cert_digest) > 0)
478 {
479 static struct mystr data_cert_digest;
480 if (!ssl_cert_digest(p_ssl, p_sess, &data_cert_digest))
481 {
482 str_alloc_text(&debug_str, "Missing cert on data channel.");
483 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
484 ssl_data_close(p_sess);
485 return 0;
486 }
487 if (str_strcmp(&p_sess->control_cert_digest, &data_cert_digest))
488 {
489 str_alloc_text(&debug_str, "DIFFERENT cert on data channel.");
490 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
491 ssl_data_close(p_sess);
492 return 0;
493 }
494 if (tunable_debug_ssl)
495 {
496 str_alloc_text(&debug_str, "Matching cert on data channel.");
497 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
498 }
499 }
500 return 1;
501 }
502
503 void
ssl_comm_channel_init(struct vsf_session * p_sess)504 ssl_comm_channel_init(struct vsf_session* p_sess)
505 {
506 const struct vsf_sysutil_socketpair_retval retval =
507 vsf_sysutil_unix_stream_socketpair();
508 if (p_sess->ssl_consumer_fd != -1)
509 {
510 bug("ssl_consumer_fd active");
511 }
512 if (p_sess->ssl_slave_fd != -1)
513 {
514 bug("ssl_slave_fd active");
515 }
516 p_sess->ssl_consumer_fd = retval.socket_one;
517 p_sess->ssl_slave_fd = retval.socket_two;
518 }
519
520 void
ssl_comm_channel_set_consumer_context(struct vsf_session * p_sess)521 ssl_comm_channel_set_consumer_context(struct vsf_session* p_sess)
522 {
523 if (p_sess->ssl_slave_fd == -1)
524 {
525 bug("ssl_slave_fd already closed");
526 }
527 vsf_sysutil_close(p_sess->ssl_slave_fd);
528 p_sess->ssl_slave_fd = -1;
529 }
530
531 void
ssl_comm_channel_set_producer_context(struct vsf_session * p_sess)532 ssl_comm_channel_set_producer_context(struct vsf_session* p_sess)
533 {
534 if (p_sess->ssl_consumer_fd == -1)
535 {
536 bug("ssl_consumer_fd already closed");
537 }
538 vsf_sysutil_close(p_sess->ssl_consumer_fd);
539 p_sess->ssl_consumer_fd = -1;
540 }
541
542 static SSL*
get_ssl(struct vsf_session * p_sess,int fd)543 get_ssl(struct vsf_session* p_sess, int fd)
544 {
545 SSL* p_ssl = SSL_new(p_sess->p_ssl_ctx);
546 if (p_ssl == NULL)
547 {
548 if (tunable_debug_ssl)
549 {
550 str_alloc_text(&debug_str, "SSL_new failed");
551 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
552 }
553 return NULL;
554 }
555 if (!SSL_set_fd(p_ssl, fd))
556 {
557 if (tunable_debug_ssl)
558 {
559 str_alloc_text(&debug_str, "SSL_set_fd failed");
560 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
561 }
562 SSL_free(p_ssl);
563 return NULL;
564 }
565 if (SSL_accept(p_ssl) != 1)
566 {
567 const char* p_err = get_ssl_error();
568 if (tunable_debug_ssl)
569 {
570 str_alloc_text(&debug_str, "SSL_accept failed: ");
571 str_append_text(&debug_str, p_err);
572 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
573 }
574 /* The RFC is quite clear that we can just close the control channel
575 * here.
576 */
577 die(p_err);
578 }
579 if (tunable_debug_ssl)
580 {
581 const char* p_ssl_version = SSL_get_cipher_version(p_ssl);
582 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
583 const SSL_CIPHER* p_ssl_cipher = SSL_get_current_cipher(p_ssl);
584 #else
585 SSL_CIPHER* p_ssl_cipher = SSL_get_current_cipher(p_ssl);
586 #endif
587 const char* p_cipher_name = SSL_CIPHER_get_name(p_ssl_cipher);
588 X509* p_ssl_cert = SSL_get_peer_certificate(p_ssl);
589 int reused = SSL_session_reused(p_ssl);
590 str_alloc_text(&debug_str, "SSL version: ");
591 str_append_text(&debug_str, p_ssl_version);
592 str_append_text(&debug_str, ", SSL cipher: ");
593 str_append_text(&debug_str, p_cipher_name);
594 if (reused)
595 {
596 str_append_text(&debug_str, ", reused");
597 }
598 else
599 {
600 str_append_text(&debug_str, ", not reused");
601 }
602 if (p_ssl_cert != NULL)
603 {
604 str_append_text(&debug_str, ", CERT PRESENTED");
605 X509_free(p_ssl_cert);
606 }
607 else
608 {
609 str_append_text(&debug_str, ", no cert");
610 }
611 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
612 }
613 return p_ssl;
614 }
615
616 static int
ssl_session_init(struct vsf_session * p_sess)617 ssl_session_init(struct vsf_session* p_sess)
618 {
619 SSL* p_ssl = get_ssl(p_sess, VSFTP_COMMAND_FD);
620 if (p_ssl == NULL)
621 {
622 return 0;
623 }
624 p_sess->p_control_ssl = p_ssl;
625 (void) ssl_cert_digest(p_ssl, p_sess, &p_sess->control_cert_digest);
626 setup_bio_callbacks(p_ssl);
627 return 1;
628 }
629
630 static int
ssl_cert_digest(SSL * p_ssl,struct vsf_session * p_sess,struct mystr * p_str)631 ssl_cert_digest(SSL* p_ssl, struct vsf_session* p_sess, struct mystr* p_str)
632 {
633 X509* p_cert = SSL_get_peer_certificate(p_ssl);
634 unsigned int num_bytes = 0;
635 if (p_cert == NULL)
636 {
637 return 0;
638 }
639 str_reserve(p_str, EVP_MAX_MD_SIZE);
640 str_empty(p_str);
641 str_rpad(p_str, EVP_MAX_MD_SIZE);
642 if (!X509_digest(p_cert, EVP_sha256(), (unsigned char*) str_getbuf(p_str),
643 &num_bytes))
644 {
645 die("X509_digest failed");
646 }
647 X509_free(p_cert);
648 if (tunable_debug_ssl)
649 {
650 unsigned int i;
651 str_alloc_text(&debug_str, "Cert digest:");
652 for (i = 0; i < num_bytes; ++i)
653 {
654 str_append_char(&debug_str, ' ');
655 str_append_ulong(
656 &debug_str, (unsigned long) (unsigned char) str_get_char_at(p_str, i));
657 }
658 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
659 }
660 str_trunc(p_str, num_bytes);
661 return 1;
662 }
663
664 static char*
get_ssl_error()665 get_ssl_error()
666 {
667 SSL_load_error_strings();
668 return ERR_error_string(ERR_get_error(), NULL);
669 }
670
setup_bio_callbacks(SSL * p_ssl)671 static void setup_bio_callbacks(SSL* p_ssl)
672 {
673 BIO* p_bio = SSL_get_rbio(p_ssl);
674 BIO_set_callback(p_bio, bio_callback);
675 p_bio = SSL_get_wbio(p_ssl);
676 BIO_set_callback(p_bio, bio_callback);
677 }
678
679 static long
bio_callback(BIO * p_bio,int oper,const char * p_arg,int argi,long argl,long ret)680 bio_callback(
681 BIO* p_bio, int oper, const char* p_arg, int argi, long argl, long ret)
682 {
683 int retval = 0;
684 int fd = 0;
685 (void) p_arg;
686 (void) argi;
687 (void) argl;
688 if (oper == (BIO_CB_READ | BIO_CB_RETURN) ||
689 oper == (BIO_CB_WRITE | BIO_CB_RETURN))
690 {
691 retval = (int) ret;
692 fd = BIO_get_fd(p_bio, NULL);
693 }
694 vsf_sysutil_check_pending_actions(kVSFSysUtilIO, retval, fd);
695 return ret;
696 }
697
698 static int
ssl_verify_callback(int verify_ok,X509_STORE_CTX * p_ctx)699 ssl_verify_callback(int verify_ok, X509_STORE_CTX* p_ctx)
700 {
701 (void) p_ctx;
702 if (tunable_validate_cert)
703 {
704 return verify_ok;
705 }
706 return 1;
707 }
708
709 void
ssl_add_entropy(struct vsf_session * p_sess)710 ssl_add_entropy(struct vsf_session* p_sess)
711 {
712 /* Although each child does seem to have its different pool of entropy, I
713 * don't trust the interaction of OpenSSL's opaque RAND API and fork(). So
714 * throw a bit more in (only works on systems with /dev/urandom for now).
715 */
716 int ret = RAND_load_file("/dev/urandom", 16);
717 if (ret != 16)
718 {
719 str_alloc_text(&debug_str, "Couldn't add extra OpenSSL entropy: ");
720 str_append_ulong(&debug_str, (unsigned long) ret);
721 vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
722 }
723 }
724
725 #else /* VSF_BUILD_SSL */
726
727 void
ssl_init(struct vsf_session * p_sess)728 ssl_init(struct vsf_session* p_sess)
729 {
730 (void) p_sess;
731 die("SSL: ssl_enable is set but SSL support not compiled in");
732 }
733
734 void
ssl_control_handshake(struct vsf_session * p_sess)735 ssl_control_handshake(struct vsf_session* p_sess)
736 {
737 (void) p_sess;
738 }
739
740 void
handle_auth(struct vsf_session * p_sess)741 handle_auth(struct vsf_session* p_sess)
742 {
743 (void) p_sess;
744 }
745
746 void
handle_pbsz(struct vsf_session * p_sess)747 handle_pbsz(struct vsf_session* p_sess)
748 {
749 (void) p_sess;
750 }
751
752 void
handle_prot(struct vsf_session * p_sess)753 handle_prot(struct vsf_session* p_sess)
754 {
755 (void) p_sess;
756 }
757
758 int
ssl_read(struct vsf_session * p_sess,void * p_ssl,char * p_buf,unsigned int len)759 ssl_read(struct vsf_session* p_sess, void* p_ssl, char* p_buf, unsigned int len)
760 {
761 (void) p_sess;
762 (void) p_ssl;
763 (void) p_buf;
764 (void) len;
765 return -1;
766 }
767
768 int
ssl_peek(struct vsf_session * p_sess,void * p_ssl,char * p_buf,unsigned int len)769 ssl_peek(struct vsf_session* p_sess, void* p_ssl, char* p_buf, unsigned int len)
770 {
771 (void) p_sess;
772 (void) p_ssl;
773 (void) p_buf;
774 (void) len;
775 return -1;
776 }
777
778 int
ssl_write(void * p_ssl,const char * p_buf,unsigned int len)779 ssl_write(void* p_ssl, const char* p_buf, unsigned int len)
780 {
781 (void) p_ssl;
782 (void) p_buf;
783 (void) len;
784 return -1;
785 }
786
787 int
ssl_write_str(void * p_ssl,const struct mystr * p_str)788 ssl_write_str(void* p_ssl, const struct mystr* p_str)
789 {
790 (void) p_ssl;
791 (void) p_str;
792 return -1;
793 }
794
795 int
ssl_accept(struct vsf_session * p_sess,int fd)796 ssl_accept(struct vsf_session* p_sess, int fd)
797 {
798 (void) p_sess;
799 (void) fd;
800 return -1;
801 }
802
803 int
ssl_data_close(struct vsf_session * p_sess)804 ssl_data_close(struct vsf_session* p_sess)
805 {
806 (void) p_sess;
807 return 1;
808 }
809
810 void
ssl_comm_channel_init(struct vsf_session * p_sess)811 ssl_comm_channel_init(struct vsf_session* p_sess)
812 {
813 (void) p_sess;
814 }
815
816 void
ssl_comm_channel_set_consumer_context(struct vsf_session * p_sess)817 ssl_comm_channel_set_consumer_context(struct vsf_session* p_sess)
818 {
819 (void) p_sess;
820 }
821
822 void
ssl_comm_channel_set_producer_context(struct vsf_session * p_sess)823 ssl_comm_channel_set_producer_context(struct vsf_session* p_sess)
824 {
825 (void) p_sess;
826 }
827
828 void
ssl_add_entropy(struct vsf_session * p_sess)829 ssl_add_entropy(struct vsf_session* p_sess)
830 {
831 (void) p_sess;
832 }
833
834 int
ssl_read_into_str(struct vsf_session * p_sess,void * p_ssl,struct mystr * p_str)835 ssl_read_into_str(struct vsf_session* p_sess, void* p_ssl, struct mystr* p_str)
836 {
837 (void) p_sess;
838 (void) p_ssl;
839 (void) p_str;
840 return -1;
841 }
842
843 #endif /* VSF_BUILD_SSL */
844
845