X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Ftls.c;h=f5f0623a3cd1bebbf598c3e068bc08d5ac00180c;hb=5450f5e38d6dd94600c7c35fedf7f9ccea3e7adb;hp=dd3aba84383909d7d22b1a4c34f70677ebf82ad9;hpb=d8c9f888b827130e16a9856ffd39075898aef87a;p=bacula%2Fbacula diff --git a/bacula/src/lib/tls.c b/bacula/src/lib/tls.c index dd3aba8438..f5f0623a3c 100644 --- a/bacula/src/lib/tls.c +++ b/bacula/src/lib/tls.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2005-2007 Free Software Foundation Europe e.V. + Copyright (C) 2005-2008 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Bacula® is a registered trademark of John Walker. + Bacula® is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. @@ -51,7 +51,6 @@ #include "bacula.h" #include -extern time_t watchdog_time; #ifdef HAVE_TLS /* Is TLS enabled? */ @@ -90,9 +89,9 @@ static int openssl_verify_peer(int ok, X509_STORE_CTX *store) X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256); X509_NAME_oneline(X509_get_subject_name(cert), subject, 256); - Jmsg5(get_jcr_from_tid(), M_ERROR, 0, _("Error with certificate at depth: %d, issuer = %s," - " subject = %s, ERR=%d:%s\n"), depth, issuer, - subject, err, X509_verify_cert_error_string(err)); + Jmsg5(NULL, M_ERROR, 0, _("Error with certificate at depth: %d, issuer = %s," + " subject = %s, ERR=%d:%s\n"), depth, issuer, + subject, err, X509_verify_cert_error_string(err)); } @@ -153,7 +152,7 @@ TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir, } } else if (verify_peer) { /* At least one CA is required for peer verification */ - Jmsg0(get_jcr_from_tid(), M_ERROR, 0, _("Either a certificate file or a directory must be" + Jmsg0(NULL, M_ERROR, 0, _("Either a certificate file or a directory must be" " specified as a verification store\n")); goto err; } @@ -199,7 +198,7 @@ TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir, } if (SSL_CTX_set_cipher_list(ctx->openssl, TLS_DEFAULT_CIPHERS) != 1) { - Jmsg0(get_jcr_from_tid(), M_ERROR, 0, + Jmsg0(NULL, M_ERROR, 0, _("Error setting cipher list, no valid ciphers available\n")); goto err; } @@ -249,7 +248,7 @@ bool get_tls_enable(TLS_CONTEXT *ctx) * Returns: true on success * false on failure */ -bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list) +bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list) { SSL *ssl = tls->openssl; X509 *cert; @@ -259,7 +258,7 @@ bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list) /* Check if peer provided a certificate */ if (!(cert = SSL_get_peer_certificate(ssl))) { - Jmsg0(get_jcr_from_tid(), M_ERROR, 0, _("Peer failed to present a TLS certificate\n")); + Qmsg0(jcr, M_ERROR, 0, _("Peer failed to present a TLS certificate\n")); return false; } @@ -288,7 +287,7 @@ bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list) * Returns: true on success * false on failure */ -bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host) +bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host) { SSL *ssl = tls->openssl; X509 *cert; @@ -301,7 +300,7 @@ bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host) /* Check if peer provided a certificate */ if (!(cert = SSL_get_peer_certificate(ssl))) { - Jmsg1(get_jcr_from_tid(), M_ERROR, 0, + Qmsg1(jcr, M_ERROR, 0, _("Peer %s failed to present a TLS certificate\n"), host); return false; } @@ -488,7 +487,7 @@ static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server) tv.tv_sec = 10; tv.tv_usec = 0; /* Block until we can read */ - select(fdmax, &fdset, NULL, &fdset, &tv); + select(fdmax, &fdset, NULL, NULL, &tv); break; case SSL_ERROR_WANT_WRITE: /* If we timeout of a select, this will be unset */ @@ -497,10 +496,10 @@ static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server) tv.tv_sec = 10; tv.tv_usec = 0; /* Block until we can write */ - select(fdmax, NULL, &fdset, &fdset, &tv); + select(fdmax, NULL, &fdset, NULL, &tv); break; default: - /* Socket Error Occured */ + /* Socket Error Occurred */ openssl_post_errors(M_ERROR, _("Connect failure")); stat = false; goto cleanup; @@ -552,26 +551,21 @@ void tls_bsock_shutdown(BSOCK *bsock) * The first time to initiate the shutdown handshake, and the second to * receive the peer's reply. * - * However, it is valid to close the SSL connection after the initial - * shutdown notification is sent to the peer, without waiting for the - * peer's reply, as long as you do not plan to re-use that particular - * SSL connection object. - * - * Because we do not re-use SSL connection objects, I do not bother - * calling SSL_shutdown a second time. - * * In addition, if the underlying socket is blocking, SSL_shutdown() * will not return until the current stage of the shutdown process has * completed or an error has occured. By setting the socket blocking * we can avoid the ugly for()/switch()/select() loop. */ int err; - int flags; /* Set socket blocking for shutdown */ - flags = bsock->set_blocking(); + bsock->set_blocking(); err = SSL_shutdown(bsock->tls->openssl); + if (err == 0) { + /* Complete shutdown */ + err = SSL_shutdown(bsock->tls->openssl); + } switch (SSL_get_error(bsock->tls->openssl, err)) { case SSL_ERROR_NONE: @@ -581,13 +575,10 @@ void tls_bsock_shutdown(BSOCK *bsock) openssl_post_errors(M_ERROR, _("TLS shutdown failure.")); break; default: - /* Socket Error Occured */ + /* Socket Error Occurred */ openssl_post_errors(M_ERROR, _("TLS shutdown failure.")); break; } - - /* Restore saved flags */ - bsock->restore_blocking(flags); } /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */ @@ -630,13 +621,21 @@ static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, b break; case SSL_ERROR_WANT_READ: + /* If we timeout on a select, this will be unset */ + FD_SET((unsigned)bsock->m_fd, &fdset); + tv.tv_sec = 10; + tv.tv_usec = 0; + /* Block until we can read */ + select(fdmax, &fdset, NULL, NULL, &tv); + break; + case SSL_ERROR_WANT_WRITE: /* If we timeout on a select, this will be unset */ FD_SET((unsigned)bsock->m_fd, &fdset); tv.tv_sec = 10; tv.tv_usec = 0; - /* Block until we can read or write */ - select(fdmax, NULL, &fdset, &fdset, &tv); + /* Block until we can write */ + select(fdmax, NULL, &fdset, NULL, &tv); break; case SSL_ERROR_ZERO_RETURN: