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