]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/tls.c
More devlock work
[bacula/bacula] / bacula / src / lib / tls.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2005-2010 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * tls.c TLS support functions
30  *
31  * Author: Landon Fuller <landonf@threerings.net>
32  *
33  * This file was contributed to the Bacula project by Landon Fuller
34  * and Three Rings Design, Inc.
35  *
36  * Three Rings Design, Inc. has been granted a perpetual, worldwide,
37  * non-exclusive, no-charge, royalty-free, irrevocable copyright
38  * license to reproduce, prepare derivative works of, publicly
39  * display, publicly perform, sublicense, and distribute the original
40  * work contributed by Three Rings Design, Inc. and its employees to
41  * the Bacula project in source or object form.
42  *
43  * If you wish to license contributions from Three Rings Design, Inc,
44  * under an alternate open source license please contact
45  * Landon Fuller <landonf@threerings.net>.
46  */
47
48
49 #include "bacula.h"
50 #include <assert.h>
51
52
53 #ifdef HAVE_TLS /* Is TLS enabled? */
54
55 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
56
57 /* No anonymous ciphers, no <128 bit ciphers, no export ciphers, no MD5 ciphers */
58 #define TLS_DEFAULT_CIPHERS "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
59
60 /* TLS Context Structure */
61 struct TLS_Context {
62    SSL_CTX *openssl;
63    CRYPTO_PEM_PASSWD_CB *pem_callback;
64    const void *pem_userdata;
65    bool tls_enable;
66    bool tls_require;
67 };
68
69 struct TLS_Connection {
70    SSL *openssl;
71 };
72
73 /*
74  * OpenSSL certificate verification callback.
75  * OpenSSL has already performed internal certificate verification.
76  * We just report any errors that occured.
77  */
78 static int openssl_verify_peer(int ok, X509_STORE_CTX *store)
79 {
80    if (!ok) {
81       X509 *cert = X509_STORE_CTX_get_current_cert(store);
82       int depth = X509_STORE_CTX_get_error_depth(store);
83       int err = X509_STORE_CTX_get_error(store);
84       char issuer[256];
85       char subject[256];
86
87       X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256);
88       X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
89
90       Jmsg5(NULL, M_ERROR, 0, _("Error with certificate at depth: %d, issuer = %s,"
91             " subject = %s, ERR=%d:%s\n"), depth, issuer,
92               subject, err, X509_verify_cert_error_string(err));
93
94    }
95
96    return ok;
97 }
98
99 /* Dispatch user PEM encryption callbacks */
100 static int tls_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata)
101 {
102    TLS_CONTEXT *ctx = (TLS_CONTEXT *)userdata;
103    return (ctx->pem_callback(buf, size, ctx->pem_userdata));
104 }
105
106 /*
107  * Create a new TLS_CONTEXT instance.
108  *  Returns: Pointer to TLS_CONTEXT instance on success
109  *           NULL on failure;
110  */
111 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
112                              const char *certfile, const char *keyfile,
113                              CRYPTO_PEM_PASSWD_CB *pem_callback,
114                              const void *pem_userdata, const char *dhfile,
115                              bool verify_peer)
116 {
117    TLS_CONTEXT *ctx;
118    BIO *bio;
119    DH *dh;
120
121    ctx = (TLS_CONTEXT *)malloc(sizeof(TLS_CONTEXT));
122
123    /* Allocate our OpenSSL TLSv1 Context */
124    ctx->openssl = SSL_CTX_new(TLSv1_method());
125
126    if (!ctx->openssl) {
127       openssl_post_errors(M_ERROR, _("Error initializing SSL context"));
128       goto err;
129    }
130
131    /* Set up pem encryption callback */
132    if (pem_callback) {
133       ctx->pem_callback = pem_callback;
134       ctx->pem_userdata = pem_userdata;
135    } else {
136       ctx->pem_callback = crypto_default_pem_callback;
137       ctx->pem_userdata = NULL;
138    }
139    SSL_CTX_set_default_passwd_cb(ctx->openssl, tls_pem_callback_dispatch);
140    SSL_CTX_set_default_passwd_cb_userdata(ctx->openssl, (void *) ctx);
141
142    /*
143     * Set certificate verification paths. This requires that at least one
144     * value be non-NULL
145     */
146    if (ca_certfile || ca_certdir) {
147       if (!SSL_CTX_load_verify_locations(ctx->openssl, ca_certfile, ca_certdir)) {
148          openssl_post_errors(M_ERROR, _("Error loading certificate verification stores"));
149          goto err;
150       }
151    } else if (verify_peer) {
152       /* At least one CA is required for peer verification */
153       Jmsg0(NULL, M_ERROR, 0, _("Either a certificate file or a directory must be"
154                          " specified as a verification store\n"));
155       goto err;
156    }
157
158    /*
159     * Load our certificate file, if available. This file may also contain a
160     * private key, though this usage is somewhat unusual.
161     */
162    if (certfile) {
163       if (!SSL_CTX_use_certificate_chain_file(ctx->openssl, certfile)) {
164          openssl_post_errors(M_ERROR, _("Error loading certificate file"));
165          goto err;
166       }
167    }
168
169    /* Load our private key. */
170    if (keyfile) {
171       if (!SSL_CTX_use_PrivateKey_file(ctx->openssl, keyfile, SSL_FILETYPE_PEM)) {
172          openssl_post_errors(M_ERROR, _("Error loading private key"));
173          goto err;
174       }
175    }
176
177    /* Load Diffie-Hellman Parameters. */
178    if (dhfile) {
179       if (!(bio = BIO_new_file(dhfile, "r"))) {
180          openssl_post_errors(M_ERROR, _("Unable to open DH parameters file"));
181          goto err;
182       }
183       dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
184       BIO_free(bio);
185       if (!dh) {
186          openssl_post_errors(M_ERROR, _("Unable to load DH parameters from specified file"));
187          goto err;
188       }
189       if (!SSL_CTX_set_tmp_dh(ctx->openssl, dh)) {
190          openssl_post_errors(M_ERROR, _("Failed to set TLS Diffie-Hellman parameters"));
191          DH_free(dh);
192          goto err;
193       }
194       /* Enable Single-Use DH for Ephemeral Keying */
195       SSL_CTX_set_options(ctx->openssl, SSL_OP_SINGLE_DH_USE);
196    }
197
198    if (SSL_CTX_set_cipher_list(ctx->openssl, TLS_DEFAULT_CIPHERS) != 1) {
199       Jmsg0(NULL, M_ERROR, 0,
200              _("Error setting cipher list, no valid ciphers available\n"));
201       goto err;
202    }
203
204    /* Verify Peer Certificate */
205    if (verify_peer) {
206       /* SSL_VERIFY_FAIL_IF_NO_PEER_CERT has no effect in client mode */
207       SSL_CTX_set_verify(ctx->openssl,
208                          SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
209                          openssl_verify_peer);
210    }
211
212    return ctx;
213
214 err:
215    /* Clean up after ourselves */
216    if(ctx->openssl) {
217       SSL_CTX_free(ctx->openssl);
218    }
219    free(ctx);
220    return NULL;
221 }
222
223 /*
224  * Free TLS_CONTEXT instance
225  */
226 void free_tls_context(TLS_CONTEXT *ctx)
227 {
228    SSL_CTX_free(ctx->openssl);
229    free(ctx);
230 }
231
232 bool get_tls_require(TLS_CONTEXT *ctx) 
233 {
234    return ctx->tls_require;
235 }
236
237 bool get_tls_enable(TLS_CONTEXT *ctx) 
238 {
239    return ctx->tls_enable;
240 }
241
242
243 /*
244  * Verifies a list of common names against the certificate
245  * commonName attribute.
246  *  Returns: true on success
247  *           false on failure
248  */
249 bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list)
250 {
251    SSL *ssl = tls->openssl;
252    X509 *cert;
253    X509_NAME *subject;
254    bool auth_success = false;
255    char data[256];
256
257    /* Check if peer provided a certificate */
258    if (!(cert = SSL_get_peer_certificate(ssl))) {
259       Qmsg0(jcr, M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
260       return false;
261    }
262
263    if ((subject = X509_get_subject_name(cert)) != NULL) {
264       if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
265          char *cn;
266          /* NULL terminate data */
267          data[255] = 0;
268
269          /* Try all the CNs in the list */
270          foreach_alist(cn, verify_list) {
271             if (strcasecmp(data, cn) == 0) {
272                auth_success = true;
273             }
274          }
275       }
276    }
277
278    X509_free(cert);
279    return auth_success;
280 }
281
282 /*
283  * Verifies a peer's hostname against the subjectAltName and commonName
284  * attributes.
285  *  Returns: true on success
286  *           false on failure
287  */
288 bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host)
289 {
290    SSL *ssl = tls->openssl;
291    X509 *cert;
292    X509_NAME *subject;
293    bool auth_success = false;
294    int extensions;
295    int i, j;
296
297    int cnLastPos = -1;
298    X509_NAME_ENTRY *neCN;
299    ASN1_STRING *asn1CN;
300
301    /* Check if peer provided a certificate */
302    if (!(cert = SSL_get_peer_certificate(ssl))) {
303       Qmsg1(jcr, M_ERROR, 0, 
304             _("Peer %s failed to present a TLS certificate\n"), host);
305       return false;
306    }
307
308    /* Check subjectAltName extensions first */
309    if ((extensions = X509_get_ext_count(cert)) > 0) {
310       for (i = 0; i < extensions; i++) {
311          X509_EXTENSION *ext;
312          const char *extname;
313
314          ext = X509_get_ext(cert, i);
315          extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
316
317          if (strcmp(extname, "subjectAltName") == 0) {
318             X509V3_EXT_METHOD *method;
319             STACK_OF(CONF_VALUE) *val;
320             CONF_VALUE *nval;
321             void *extstr = NULL;
322 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
323             const unsigned char *ext_value_data;
324 #else
325             unsigned char *ext_value_data;
326 #endif
327
328             /* Get x509 extension method structure */
329             if (!(method = X509V3_EXT_get(ext))) {
330                break;
331             }
332
333             ext_value_data = ext->value->data;
334
335 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
336             if (method->it) {
337                /* New style ASN1 */
338
339                /* Decode ASN1 item in data */
340                extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
341                                       ASN1_ITEM_ptr(method->it));
342             } else {
343                /* Old style ASN1 */
344
345                /* Decode ASN1 item in data */
346                extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
347             }
348
349 #else
350             extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
351 #endif
352
353             /* Iterate through to find the dNSName field(s) */
354             val = method->i2v(method, extstr, NULL);
355
356             /* dNSName shortname is "DNS" */
357             for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
358                nval = sk_CONF_VALUE_value(val, j);
359                if (strcmp(nval->name, "DNS") == 0) {
360                   if (strcasecmp(nval->value, host) == 0) {
361                      auth_success = true;
362                      goto success;
363                   }
364                }
365             }
366          }
367       }
368    }
369
370    /* Try verifying against the subject name */
371    if (!auth_success) {
372       if ((subject = X509_get_subject_name(cert)) != NULL) {
373          /* Loop through all CNs */
374          for (;;) {
375             cnLastPos = X509_NAME_get_index_by_NID(subject, NID_commonName, cnLastPos);
376             if (cnLastPos == -1) {
377                break;
378             }
379             neCN = X509_NAME_get_entry(subject, cnLastPos);
380             asn1CN = X509_NAME_ENTRY_get_data(neCN);
381             if (strcasecmp((const char*)asn1CN->data, host) == 0) {
382                auth_success = true;
383                break;
384             }
385          }
386       }
387    }
388
389 success:
390    X509_free(cert);
391
392    return auth_success;
393 }
394
395 /*
396  * Create a new TLS_CONNECTION instance.
397  *
398  * Returns: Pointer to TLS_CONNECTION instance on success
399  *          NULL on failure;
400  */
401 TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd)
402 {
403    BIO *bio;
404
405    /*
406     * Create a new BIO and assign the fd.
407     * The caller will remain responsible for closing the associated fd
408     */
409    bio = BIO_new(BIO_s_socket());
410    if (!bio) {
411       /* Not likely, but never say never */
412       openssl_post_errors(M_ERROR, _("Error creating file descriptor-based BIO"));
413       return NULL; /* Nothing allocated, nothing to clean up */
414    }
415    BIO_set_fd(bio, fd, BIO_NOCLOSE);
416
417    /* Allocate our new tls connection */
418    TLS_CONNECTION *tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION));
419
420    /* Create the SSL object and attach the socket BIO */
421    if ((tls->openssl = SSL_new(ctx->openssl)) == NULL) {
422       /* Not likely, but never say never */
423       openssl_post_errors(M_ERROR, _("Error creating new SSL object"));
424       goto err;
425    }
426
427    SSL_set_bio(tls->openssl, bio, bio);
428
429    /* Non-blocking partial writes */
430    SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
431
432    return tls;
433
434 err:
435    /* Clean up */
436    BIO_free(bio);
437    SSL_free(tls->openssl);
438    free(tls);
439    return NULL;
440 }
441
442 /*
443  * Free TLS_CONNECTION instance
444  */
445 void free_tls_connection(TLS_CONNECTION *tls)
446 {
447    SSL_free(tls->openssl);
448    free(tls);
449 }
450
451 /* Does all the manual labor for tls_bsock_accept() and tls_bsock_connect() */
452 static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server)
453 {
454    TLS_CONNECTION *tls = bsock->tls;
455    int err;
456    int fdmax, flags;
457    int stat = true;
458    fd_set fdset;
459    struct timeval tv;
460
461    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
462    FD_ZERO(&fdset);
463    fdmax = bsock->m_fd + 1;
464
465    /* Ensure that socket is non-blocking */
466    flags = bsock->set_nonblocking();
467
468    /* start timer */
469    bsock->timer_start = watchdog_time;
470    bsock->clear_timed_out();
471
472    for (;;) { 
473       if (server) {
474          err = SSL_accept(tls->openssl);
475       } else {
476          err = SSL_connect(tls->openssl);
477       }
478
479       /* Handle errors */
480       switch (SSL_get_error(tls->openssl, err)) {
481       case SSL_ERROR_NONE:
482          stat = true;
483          goto cleanup;
484       case SSL_ERROR_ZERO_RETURN:
485          /* TLS connection was cleanly shut down */
486          openssl_post_errors(M_ERROR, _("Connect failure"));
487          stat = false;
488          goto cleanup;
489       case SSL_ERROR_WANT_READ:
490          /* If we timeout of a select, this will be unset */
491          FD_SET((unsigned) bsock->m_fd, &fdset);
492          /* Set our timeout */
493          tv.tv_sec = 10;
494          tv.tv_usec = 0;
495          /* Block until we can read */
496          select(fdmax, &fdset, NULL, NULL, &tv);
497          break;
498       case SSL_ERROR_WANT_WRITE:
499          /* If we timeout of a select, this will be unset */
500          FD_SET((unsigned) bsock->m_fd, &fdset);
501          /* Set our timeout */
502          tv.tv_sec = 10;
503          tv.tv_usec = 0;
504          /* Block until we can write */
505          select(fdmax, NULL, &fdset, NULL, &tv);
506          break;
507       default:
508          /* Socket Error Occurred */
509          openssl_post_errors(M_ERROR, _("Connect failure"));
510          stat = false;
511          goto cleanup;
512       }
513
514       if (bsock->is_timed_out()) {
515          goto cleanup;
516       }
517    }
518
519 cleanup:
520    /* Restore saved flags */
521    bsock->restore_blocking(flags);
522    /* Clear timer */
523    bsock->timer_start = 0;
524
525    return stat;
526 }
527
528 /*
529  * Initiates a TLS connection with the server.
530  *  Returns: true on success
531  *           false on failure
532  */
533 bool tls_bsock_connect(BSOCK *bsock)
534 {
535    /* SSL_connect(bsock->tls) */
536    return openssl_bsock_session_start(bsock, false);
537 }
538
539 /*
540  * Listens for a TLS connection from a client.
541  *  Returns: true on success
542  *           false on failure
543  */
544 bool tls_bsock_accept(BSOCK *bsock)
545 {
546    /* SSL_accept(bsock->tls) */
547    return openssl_bsock_session_start(bsock, true);
548 }
549
550 /*
551  * Shutdown TLS_CONNECTION instance
552  */
553 void tls_bsock_shutdown(BSOCK *bsock)
554 {
555    /*
556     * SSL_shutdown must be called twice to fully complete the process -
557     * The first time to initiate the shutdown handshake, and the second to
558     * receive the peer's reply.
559     *
560     * In addition, if the underlying socket is blocking, SSL_shutdown()
561     * will not return until the current stage of the shutdown process has
562     * completed or an error has occured. By setting the socket blocking
563     * we can avoid the ugly for()/switch()/select() loop.
564     */
565    int err;
566
567    btimer_t *tid;
568
569    /* Set socket blocking for shutdown */
570    bsock->set_blocking();
571
572    tid = start_bsock_timer(bsock, 60 * 2);
573    err = SSL_shutdown(bsock->tls->openssl);
574    stop_bsock_timer(tid);
575    if (err == 0) {
576       /* Complete shutdown */
577       tid = start_bsock_timer(bsock, 60 * 2);
578       err = SSL_shutdown(bsock->tls->openssl);
579       stop_bsock_timer(tid);
580    }
581
582
583    switch (SSL_get_error(bsock->tls->openssl, err)) {
584    case SSL_ERROR_NONE:
585       break;
586    case SSL_ERROR_ZERO_RETURN:
587       /* TLS connection was shut down on us via a TLS protocol-level closure */
588       openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
589       break;
590    default:
591       /* Socket Error Occurred */
592       openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
593       break;
594    }
595 }
596
597 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
598 static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write)
599 {
600    TLS_CONNECTION *tls = bsock->tls;
601    int fdmax, flags;
602    fd_set fdset;
603    struct timeval tv;
604    int nleft = 0;
605    int nwritten = 0;
606
607    /* Zero the fdset, we'll set our fd prior to each invocation of select() */
608    FD_ZERO(&fdset);
609    fdmax = bsock->m_fd + 1;
610
611    /* Ensure that socket is non-blocking */
612    flags = bsock->set_nonblocking();
613
614    /* start timer */
615    bsock->timer_start = watchdog_time;
616    bsock->clear_timed_out();
617
618    nleft = nbytes;
619
620    while (nleft > 0) { 
621       if (write) {
622          nwritten = SSL_write(tls->openssl, ptr, nleft);
623       } else {
624          nwritten = SSL_read(tls->openssl, ptr, nleft);
625       }
626
627       /* Handle errors */
628       switch (SSL_get_error(tls->openssl, nwritten)) {
629       case SSL_ERROR_NONE:
630          nleft -= nwritten;
631          if (nleft) {
632             ptr += nwritten;
633          }
634          break;
635
636       case SSL_ERROR_WANT_READ:
637          /* If we timeout on a select, this will be unset */
638          FD_SET((unsigned)bsock->m_fd, &fdset);
639          tv.tv_sec = 10;
640          tv.tv_usec = 0;
641          /* Block until we can read */
642          select(fdmax, &fdset, NULL, NULL, &tv);
643          break;
644
645       case SSL_ERROR_WANT_WRITE:
646          /* If we timeout on a select, this will be unset */
647          FD_SET((unsigned)bsock->m_fd, &fdset);
648          tv.tv_sec = 10;
649          tv.tv_usec = 0;
650          /* Block until we can write */
651          select(fdmax, NULL, &fdset, NULL, &tv);
652          break;
653
654       case SSL_ERROR_ZERO_RETURN:
655          /* TLS connection was cleanly shut down */
656          /* Fall through wanted */
657       default:
658          /* Socket Error Occured */
659          openssl_post_errors(M_ERROR, _("TLS read/write failure."));
660          goto cleanup;
661       }
662
663       /* Everything done? */
664       if (nleft == 0) {
665          goto cleanup;
666       }
667
668       /* Timeout/Termination, let's take what we can get */
669       if (bsock->is_timed_out() || bsock->is_terminated()) {
670          goto cleanup;
671       }
672    }
673
674 cleanup:
675    /* Restore saved flags */
676    bsock->restore_blocking(flags);
677
678    /* Clear timer */
679    bsock->timer_start = 0;
680    return nbytes - nleft;
681 }
682
683
684 int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) 
685 {
686    /* SSL_write(bsock->tls->openssl, ptr, nbytes) */
687    return openssl_bsock_readwrite(bsock, ptr, nbytes, true);
688 }
689
690 int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) 
691 {
692    /* SSL_read(bsock->tls->openssl, ptr, nbytes) */
693    return openssl_bsock_readwrite(bsock, ptr, nbytes, false);
694 }
695
696 #else /* HAVE_OPENSSL */
697 # error No TLS implementation available.
698 #endif /* !HAVE_OPENSSL */
699
700
701 #else     /* TLS NOT enabled, dummy routines substituted */
702
703
704 /* Dummy routines */
705 TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
706                              const char *certfile, const char *keyfile,
707                              CRYPTO_PEM_PASSWD_CB *pem_callback,
708                              const void *pem_userdata, const char *dhfile,
709                              bool verify_peer)
710 {
711    return NULL;
712 }
713 void free_tls_context(TLS_CONTEXT *ctx) { }
714
715 void tls_bsock_shutdown(BSOCK *bsock) { }
716
717 void free_tls_connection(TLS_CONNECTION *tls) { }
718
719 bool get_tls_require(TLS_CONTEXT *ctx) 
720 {
721    return false;
722 }
723
724 bool get_tls_enable(TLS_CONTEXT *ctx) 
725 {
726    return false;
727 }
728
729 #endif /* HAVE_TLS */