]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/tls.c
Check for job_canceled() in fd_plugin code
[bacula/bacula] / bacula / src / lib / tls.c
index 54a3f88b10924fd0005dbf01e188ce7a7861909f..f5f0623a3cd1bebbf598c3e068bc08d5ac00180c 100644 (file)
@@ -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 <assert.h>
 
-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;
    }
@@ -462,7 +461,7 @@ static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server)
 
    /* start timer */
    bsock->timer_start = watchdog_time;
-   bsock->set_timed_out(false);
+   bsock->clear_timed_out();
 
    for (;;) { 
       if (server) {
@@ -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() */
@@ -609,7 +600,7 @@ static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, b
 
    /* start timer */
    bsock->timer_start = watchdog_time;
-   bsock->set_timed_out(false);
+   bsock->clear_timed_out();
 
    nleft = nbytes;
 
@@ -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: