]> git.sur5r.net Git - bacula/bacula/commitdiff
Implement a security enhancement: TLS authentication but no
authorKern Sibbald <kern@sibbald.com>
Tue, 11 Dec 2007 22:04:34 +0000 (22:04 +0000)
committerKern Sibbald <kern@sibbald.com>
Tue, 11 Dec 2007 22:04:34 +0000 (22:04 +0000)
     encryption. Enabled by setting 'TLS Authentication = yes'.
     Note when this is on, TLS encryption is turned OFF

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6040 91ce42f0-d328-0410-95d8-f526ca767f89

26 files changed:
bacula/src/console/authenticate.c
bacula/src/console/console.c
bacula/src/console/console_conf.c
bacula/src/console/console_conf.h
bacula/src/dird/authenticate.c
bacula/src/dird/dird.c
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/filed/authenticate.c
bacula/src/filed/filed.c
bacula/src/filed/filed_conf.c
bacula/src/filed/filed_conf.h
bacula/src/lib/bnet.c
bacula/src/lib/bsock.c
bacula/src/lib/bsock.h
bacula/src/lib/openssl.c
bacula/src/lib/tls.c
bacula/src/qt-console/bat_conf.cpp
bacula/src/qt-console/bat_conf.h
bacula/src/qt-console/console/authenticate.cpp
bacula/src/qt-console/main.cpp
bacula/src/stored/authenticate.c
bacula/src/stored/stored.c
bacula/src/stored/stored_conf.c
bacula/src/stored/stored_conf.h
bacula/technotes-2.3

index 5887cbb3b41d2b8e892f1a067e8626705435ece8..abea3cff4a074dfba3fa6cd82239574e76d0f20e 100644 (file)
@@ -62,6 +62,8 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
    BSOCK *dir = jcr->dir_bsock;
    int tls_local_need = BNET_TLS_NONE;
    int tls_remote_need = BNET_TLS_NONE;
+   bool tls_needed;
+   bool tls_authenticate;
    int compatible = true;
    char bashed_name[MAX_NAME_LENGTH];
    char *password;
@@ -82,7 +84,11 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
             tls_local_need = BNET_TLS_OK;
          }
       }
-
+      if (cons->tls_authenticate) {
+         tls_local_need = BNET_TLS_REQUIRED;
+      }
+      tls_authenticate = cons->tls_authenticate;
+      tls_needed = cons->tls_enable || cons->tls_authenticate;
       tls_ctx = cons->tls_ctx;
    } else {
       bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name));
@@ -96,6 +102,11 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
          }
       }
 
+      if (director->tls_authenticate) {
+         tls_local_need = BNET_TLS_REQUIRED;
+      }
+      tls_authenticate = director->tls_authenticate;
+      tls_needed = director->tls_enable || director->tls_authenticate;
       tls_ctx = director->tls_ctx;
    }
 
@@ -124,13 +135,14 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
    }
 
    /* Is TLS Enabled? */
-   if (have_tls) {
-      if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
-         /* Engage TLS! Full Speed Ahead! */
-         if (!bnet_tls_client(tls_ctx, dir, NULL)) {
-            sendit(_("TLS negotiation failed\n"));
-            goto bail_out;
-         }
+   if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
+      /* Engage TLS! Full Speed Ahead! */
+      if (!bnet_tls_client(tls_ctx, dir, NULL)) {
+         sendit(_("TLS negotiation failed\n"));
+         goto bail_out;
+      }
+      if (tls_authenticate) {           /* Authenticate only? */
+         dir->free_tls();               /* yes, shutdown tls */
       }
    }
 
index 0f57d173c4af6ff5898f10d3ab559b5dcd7e8ed1..9b88aa801e9ad557c0e32ba7c0785d13bcfd9f46 100644 (file)
@@ -822,6 +822,7 @@ static int check_resources()
 {
    bool OK = true;
    DIRRES *director;
+   bool tls_needed;
 
    LockRes();
 
@@ -839,8 +840,9 @@ static int check_resources()
             continue;
          }
       }
+      tls_needed = director->tls_enable || director->tls_authenticate;
 
-      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable) {
+      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed) {
          Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
                              " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
                              " At least one CA certificate store is required.\n"),
@@ -868,8 +870,8 @@ static int check_resources()
             continue;
          }
       }
-
-      if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable) {
+      tls_needed = cons->tls_enable || cons->tls_authenticate;
+      if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && tls_needed) {
          Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
                              " or \"TLS CA Certificate Dir\" are defined for Console \"%s\" in %s.\n"),
                              cons->hdr.name, configfile);
index 2ce66bbca83ec0d257443eda8ba51f803f5d6b61..1bdda9357e7ee6fb43a27e40d51e1f0aea2d109a 100644 (file)
@@ -88,8 +88,9 @@ static RES_ITEM cons_items[] = {
    {"rcfile",         store_dir,      ITEM(res_cons.rc_file), 0, 0, 0},
    {"historyfile",    store_dir,      ITEM(res_cons.hist_file), 0, 0, 0},
    {"password",       store_password, ITEM(res_cons.password), 0, ITEM_REQUIRED, 0},
-   {"tlsenable",      store_bit,     ITEM(res_cons.tls_enable), 1, 0, 0},
-   {"tlsrequire",     store_bit,     ITEM(res_cons.tls_require), 1, 0, 0},
+   {"tlsauthenticate",store_bool,    ITEM(res_cons.tls_authenticate), 0, 0, 0},
+   {"tlsenable",      store_bool,    ITEM(res_cons.tls_enable), 0, 0, 0},
+   {"tlsrequire",     store_bool,    ITEM(res_cons.tls_require), 0, 0, 0},
    {"tlscacertificatefile", store_dir, ITEM(res_cons.tls_ca_certfile), 0, 0, 0},
    {"tlscacertificatedir", store_dir,  ITEM(res_cons.tls_ca_certdir), 0, 0, 0},
    {"tlscertificate", store_dir,       ITEM(res_cons.tls_certfile), 0, 0, 0},
@@ -107,8 +108,9 @@ static RES_ITEM dir_items[] = {
    {"dirport",        store_int,       ITEM(res_dir.DIRport),  0, ITEM_DEFAULT, 9101},
    {"address",        store_str,       ITEM(res_dir.address),  0, 0, 0},
    {"password",       store_password,  ITEM(res_dir.password), 0, ITEM_REQUIRED, 0},
-   {"tlsenable",      store_bit,     ITEM(res_dir.tls_enable), 1, 0, 0},
-   {"tlsrequire",     store_bit,     ITEM(res_dir.tls_require), 1, 0, 0},
+   {"tlsauthenticate",store_bool,    ITEM(res_dir.tls_enable), 0, 0, 0},
+   {"tlsenable",      store_bool,    ITEM(res_dir.tls_enable), 0, 0, 0},
+   {"tlsrequire",     store_bool,    ITEM(res_dir.tls_require), 0, 0, 0},
    {"tlscacertificatefile", store_dir, ITEM(res_dir.tls_ca_certfile), 0, 0, 0},
    {"tlscacertificatedir", store_dir,  ITEM(res_dir.tls_ca_certdir), 0, 0, 0},
    {"tlscertificate", store_dir,       ITEM(res_dir.tls_certfile), 0, 0, 0},
index b129cb27ae7d06691c3b707e72ca6a32d7c8f7d3..3dda499599b25776c7c1fad541df0acdecbf88df 100644 (file)
@@ -64,8 +64,9 @@ struct CONRES {
    char *rc_file;                     /* startup file */
    char *hist_file;                   /* command history file */
    char *password;                    /* UA server password */
-   int tls_enable;                    /* Enable TLS on all connections */
-   int tls_require;                   /* Require TLS on all connections */
+   bool tls_authenticate;             /* Authenticate with TLS */
+   bool tls_enable;                   /* Enable TLS on all connections */
+   bool tls_require;                  /* Require TLS on all connections */
    char *tls_ca_certfile;             /* TLS CA Certificate File */
    char *tls_ca_certdir;              /* TLS CA Certificate Directory */
    char *tls_certfile;                /* TLS Client Certificate File */
@@ -82,8 +83,9 @@ struct DIRRES {
    int   DIRport;                     /* UA server port */
    char *address;                     /* UA server address */
    char *password;                    /* UA server password */
-   int tls_enable;                    /* Enable TLS */
-   int tls_require;                   /* Require TLS */
+   bool tls_authenticate;             /* Authenticate with TLS */
+   bool tls_enable;                   /* Enable TLS */
+   bool tls_require;                  /* Require TLS */
    char *tls_ca_certfile;             /* TLS CA Certificate File */
    char *tls_ca_certdir;              /* TLS CA Certificate Directory */
    char *tls_certfile;                /* TLS Client Certificate File */
index 1bbb84e3d29f3b5a489d7ae4c7a0585f91f48955..61c9ccfe854b8ade8c5f3c6c272359975e861394 100644 (file)
@@ -41,6 +41,8 @@
 #include "bacula.h"
 #include "dird.h"
 
+static const int dbglvl = 50;
+
 extern DIRRES *director;
 
 /* Commands sent to Storage daemon and File daemon and received
@@ -77,7 +79,7 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store)
    btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
    if (!sd->fsend(hello, dirname)) {
       stop_bsock_timer(tid);
-      Dmsg1(50, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
+      Dmsg1(dbglvl, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
       Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
       return 0;
    }
@@ -91,19 +93,23 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store)
      }
    }
 
+   if (store->tls_authenticate) {
+      tls_local_need = BNET_TLS_REQUIRED;
+   }
+
    auth_success = cram_md5_respond(sd, store->password, &tls_remote_need, &compatible);
    if (auth_success) {
       auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible);
       if (!auth_success) {
-         Dmsg1(50, "cram_challenge failed for %s\n", sd->who());
+         Dmsg1(dbglvl, "cram_challenge failed for %s\n", sd->who());
       }
    } else {
-      Dmsg1(50, "cram_respond failed for %s\n", sd->who());
+      Dmsg1(dbglvl, "cram_respond failed for %s\n", sd->who());
    }
 
    if (!auth_success) {
       stop_bsock_timer(tid);
-      Dmsg0(50, _("Director and Storage daemon passwords or names not the same.\n"));
+      Dmsg0(dbglvl, _("Director and Storage daemon passwords or names not the same.\n"));
       Jmsg2(jcr, M_FATAL, 0,
             _("Director unable to authenticate with Storage daemon at \"%s:%d\". Possible causes:\n"
             "Passwords or names not the same or\n"
@@ -137,6 +143,9 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store)
             sd->host(), sd->port());
          return 0;
       }
+      if (store->tls_authenticate) {       /* authentication only? */
+         sd->free_tls();                   /* yes, stop tls */
+      }
    }
 
    Dmsg1(116, ">stored: %s", sd->msg);
@@ -149,7 +158,7 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store)
    Dmsg1(110, "<stored: %s", sd->msg);
    stop_bsock_timer(tid);
    if (strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
-      Dmsg0(50, _("Storage daemon rejected Hello command\n"));
+      Dmsg0(dbglvl, _("Storage daemon rejected Hello command\n"));
       Jmsg2(jcr, M_FATAL, 0, _("Storage daemon at \"%s:%d\" rejected Hello command\n"),
          sd->host(), sd->port());
       return 0;
@@ -183,7 +192,7 @@ int authenticate_file_daemon(JCR *jcr)
            fd->host(), fd->port(), fd->bstrerror());
       return 0;
    }
-   Dmsg1(50, "Sent: %s", fd->msg);
+   Dmsg1(dbglvl, "Sent: %s", fd->msg);
 
    /* TLS Requirement */
    if (client->tls_enable) {
@@ -194,18 +203,22 @@ int authenticate_file_daemon(JCR *jcr)
      }
    }
 
+   if (client->tls_authenticate) {
+      tls_local_need = BNET_TLS_REQUIRED;
+   }
+
    auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
    if (auth_success) {
       auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
       if (!auth_success) {
-         Dmsg1(50, "cram_auth failed for %s\n", fd->who());
+         Dmsg1(dbglvl, "cram_auth failed for %s\n", fd->who());
       }
    } else {
-      Dmsg1(50, "cram_get_auth failed for %s\n", fd->who());
+      Dmsg1(dbglvl, "cram_get_auth failed for %s\n", fd->who());
    }
    if (!auth_success) {
       stop_bsock_timer(tid);
-      Dmsg0(50, _("Director and File daemon passwords or names not the same.\n"));
+      Dmsg0(dbglvl, _("Director and File daemon passwords or names not the same.\n"));
       Jmsg(jcr, M_FATAL, 0,
             _("Unable to authenticate with File daemon at \"%s:%d\". Possible causes:\n"
             "Passwords or names not the same or\n"
@@ -242,12 +255,15 @@ int authenticate_file_daemon(JCR *jcr)
               fd->host(), fd->port());
          return 0;
       }
+      if (client->tls_authenticate) {        /* tls authentication only? */
+         fd->free_tls();                     /* yes, shutdown tls */
+      }
    }
 
    Dmsg1(116, ">filed: %s", fd->msg);
    if (fd->recv() <= 0) {
       stop_bsock_timer(tid);
-      Dmsg1(50, _("Bad response from File daemon to Hello command: ERR=%s\n"),
+      Dmsg1(dbglvl, _("Bad response from File daemon to Hello command: ERR=%s\n"),
          bnet_strerror(fd));
       Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon at \"%s:%d\" to Hello command: ERR=%s\n"),
          fd->host(), fd->port(), fd->bstrerror());
@@ -256,7 +272,7 @@ int authenticate_file_daemon(JCR *jcr)
    Dmsg1(110, "<stored: %s", fd->msg);
    stop_bsock_timer(tid);
    if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
-      Dmsg0(50, _("File daemon rejected Hello command\n"));
+      Dmsg0(dbglvl, _("File daemon rejected Hello command\n"));
       Jmsg(jcr, M_FATAL, 0, _("File daemon at \"%s:%d\" rejected Hello command\n"),
            fd->host(), fd->port());
       return 0;
@@ -272,6 +288,8 @@ int authenticate_user_agent(UAContext *uac)
    char name[MAX_NAME_LENGTH];
    int tls_local_need = BNET_TLS_NONE;
    int tls_remote_need = BNET_TLS_NONE;
+   bool need_tls;
+   bool tls_authenticate;
    int compatible = true;
    CONRES *cons = NULL;
    BSOCK *ua = uac->UA_sock;
@@ -303,6 +321,13 @@ int authenticate_user_agent(UAContext *uac)
          }
       }
 
+      tls_authenticate = director->tls_authenticate;
+      need_tls = director->tls_enable || tls_authenticate;
+
+      if (tls_authenticate) {
+         tls_local_need = BNET_TLS_REQUIRED;
+      }
+
       if (director->tls_verify_peer) {
          verify_list = director->tls_allowed_cns;
       }
@@ -323,6 +348,13 @@ int authenticate_user_agent(UAContext *uac)
             }
          }
 
+         tls_authenticate = cons->tls_authenticate;
+         need_tls = cons->tls_enable || tls_authenticate;
+
+         if (tls_authenticate) {
+            tls_local_need = BNET_TLS_REQUIRED;
+         }
+
          if (cons->tls_verify_peer) {
             verify_list = cons->tls_allowed_cns;
          }
@@ -340,6 +372,7 @@ int authenticate_user_agent(UAContext *uac)
       }
    }
 
+
    /* Verify that the remote peer is willing to meet our TLS requirements */
    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
       Emsg0(M_FATAL, 0, _("Authorization problem:"
@@ -369,6 +402,9 @@ int authenticate_user_agent(UAContext *uac)
          auth_success = false;
          goto auth_done;
       }
+      if (tls_authenticate) {            /* authentication only? */
+         ua->free_tls();                 /* stop tls */
+      }
    }
 
 
index c4dc63b69d1b7b4b06cf6b6db24051701eac5a2e..bccd480be136f8ee857d1a28fcbac718befbe500 100644 (file)
@@ -539,6 +539,7 @@ static bool check_resources()
 {
    bool OK = true;
    JOB *job;
+   bool need_tls;
 
    LockRes();
 
@@ -572,19 +573,22 @@ static bool check_resources()
          }
       }
 
-      if (!director->tls_certfile && director->tls_enable) {
+      need_tls = director->tls_enable || director->tls_authenticate;
+
+      if (!director->tls_certfile && need_tls) {
          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
             director->name(), configfile);
          OK = false;
       }
 
-      if (!director->tls_keyfile && director->tls_enable) {
+      if (!director->tls_keyfile && need_tls) {
          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
             director->name(), configfile);
          OK = false;
       }
 
-      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
+      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && 
+           need_tls && director->tls_verify_peer) {
          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
               " Certificate Dir\" are defined for Director \"%s\" in %s."
               " At least one CA certificate store is required"
@@ -594,7 +598,7 @@ static bool check_resources()
       }
 
       /* If everything is well, attempt to initialize our per-resource TLS context */
-      if (OK && (director->tls_enable || director->tls_require)) {
+      if (OK && (need_tls || director->tls_require)) {
          /* Initialize TLS context:
           * Args: CA certfile, CA certdir, Certfile, Keyfile,
           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
@@ -774,19 +778,22 @@ static bool check_resources()
          }
       }
 
-      if (!cons->tls_certfile && cons->tls_enable) {
+      need_tls = cons->tls_enable || cons->tls_authenticate;
+      
+      if (!cons->tls_certfile && need_tls) {
          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
             cons->name(), configfile);
          OK = false;
       }
 
-      if (!cons->tls_keyfile && cons->tls_enable) {
+      if (!cons->tls_keyfile && need_tls) {
          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
             cons->name(), configfile);
          OK = false;
       }
 
-      if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable && cons->tls_verify_peer) {
+      if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) 
+            && need_tls && cons->tls_verify_peer) {
          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
             " Certificate Dir\" are defined for Console \"%s\" in %s."
             " At least one CA certificate store is required"
@@ -795,7 +802,7 @@ static bool check_resources()
          OK = false;
       }
       /* If everything is well, attempt to initialize our per-resource TLS context */
-      if (OK && (cons->tls_enable || cons->tls_require)) {
+      if (OK && (need_tls || cons->tls_require)) {
          /* Initialize TLS context:
           * Args: CA certfile, CA certdir, Certfile, Keyfile,
           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
@@ -825,8 +832,8 @@ static bool check_resources()
             continue;
          }
       }
-
-      if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && client->tls_enable) {
+      need_tls = client->tls_enable || client->tls_authenticate;
+      if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
             " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
             client->name(), configfile);
@@ -834,7 +841,7 @@ static bool check_resources()
       }
 
       /* If everything is well, attempt to initialize our per-resource TLS context */
-      if (OK && (client->tls_enable || client->tls_require)) {
+      if (OK && (need_tls || client->tls_require)) {
          /* Initialize TLS context:
           * Args: CA certfile, CA certdir, Certfile, Keyfile,
           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
@@ -862,6 +869,7 @@ static bool check_resources()
 static bool check_catalog()
 {
    bool OK = true;
+   bool need_tls;
 
    /* Loop over databases */
    CAT *catalog;
@@ -929,7 +937,9 @@ static bool check_catalog()
             }
          } 
 
-         if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable) {
+         need_tls = store->tls_enable || store->tls_authenticate;
+
+         if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
             Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
                  " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
                  store->name(), configfile);
@@ -937,7 +947,7 @@ static bool check_catalog()
          }
 
          /* If everything is well, attempt to initialize our per-resource TLS context */
-         if (OK && (store->tls_enable || store->tls_require)) {
+         if (OK && (need_tls || store->tls_require)) {
            /* Initialize TLS context:
             * Args: CA certfile, CA certdir, Certfile, Keyfile,
             * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
index eb04adaa00092ddc6e98ffc155dcab9e17a389ee..04312c14cd446c1610cce0a370bfe0e21fc427a9 100644 (file)
@@ -122,6 +122,7 @@ static RES_ITEM dir_items[] = {
    {"fdconnecttimeout", store_time,ITEM(res_dir.FDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30},
    {"sdconnecttimeout", store_time,ITEM(res_dir.SDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30},
    {"heartbeatinterval", store_time, ITEM(res_dir.heartbeat_interval), 0, ITEM_DEFAULT, 0},
+   {"tlsauthenticate",      store_bool,      ITEM(res_dir.tls_authenticate), 0, 0, 0},
    {"tlsenable",            store_bool,      ITEM(res_dir.tls_enable), 0, 0, 0},
    {"tlsrequire",           store_bool,      ITEM(res_dir.tls_require), 0, 0, 0},
    {"tlsverifypeer",        store_bool,      ITEM(res_dir.tls_verify_peer), 0, ITEM_DEFAULT, true},
@@ -153,6 +154,7 @@ static RES_ITEM con_items[] = {
    {"filesetacl",  store_acl,      ITEM(res_con.ACL_lists), FileSet_ACL, 0, 0},
    {"catalogacl",  store_acl,      ITEM(res_con.ACL_lists), Catalog_ACL, 0, 0},
    {"whereacl",    store_acl,      ITEM(res_con.ACL_lists), Where_ACL, 0, 0},
+   {"tlsauthenticate",      store_bool,      ITEM(res_con.tls_authenticate), 0, 0, 0},
    {"tlsenable",            store_bool,      ITEM(res_con.tls_enable), 0, 0, 0},
    {"tlsrequire",           store_bool,      ITEM(res_con.tls_require), 0, 0, 0},
    {"tlsverifypeer",        store_bool,      ITEM(res_con.tls_verify_peer), 0, ITEM_DEFAULT, true},
@@ -186,6 +188,7 @@ static RES_ITEM cli_items[] = {
    {"heartbeatinterval", store_time, ITEM(res_client.heartbeat_interval), 0, ITEM_DEFAULT, 0},
    {"autoprune", store_bool,      ITEM(res_client.AutoPrune), 0, ITEM_DEFAULT, true},
    {"maximumconcurrentjobs", store_pint, ITEM(res_client.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1},
+   {"tlsauthenticate",      store_bool,      ITEM(res_client.tls_authenticate), 0, 0, 0},
    {"tlsenable",            store_bool,      ITEM(res_client.tls_enable), 0, 0, 0},
    {"tlsrequire",           store_bool,      ITEM(res_client.tls_require), 0, 0, 0},
    {"tlscacertificatefile", store_dir,       ITEM(res_client.tls_ca_certfile), 0, 0, 0},
@@ -215,6 +218,7 @@ static RES_ITEM store_items[] = {
    {"heartbeatinterval", store_time, ITEM(res_store.heartbeat_interval), 0, ITEM_DEFAULT, 0},
    {"maximumconcurrentjobs", store_pint, ITEM(res_store.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1},
    {"sddport", store_pint, ITEM(res_store.SDDport), 0, 0, 0}, /* deprecated */
+   {"tlsauthenticate",      store_bool,      ITEM(res_store.tls_authenticate), 0, 0, 0},
    {"tlsenable",            store_bool,      ITEM(res_store.tls_enable), 0, 0, 0},
    {"tlsrequire",           store_bool,      ITEM(res_store.tls_require), 0, 0, 0},
    {"tlscacertificatefile", store_dir,       ITEM(res_store.tls_ca_certfile), 0, 0, 0},
index 61e4a32cdbeb45f9151b7b5e6d5a6c6f26f98048..f8d91cacc80e1d48e92b27f86ceda87d02a6e4c0 100644 (file)
@@ -124,6 +124,7 @@ public:
    char *tls_dhfile;                  /* TLS Diffie-Hellman Parameters */
    alist *tls_allowed_cns;            /* TLS Allowed Clients */
    TLS_CONTEXT *tls_ctx;              /* Shared TLS Context */
+   bool tls_authenticate;             /* Authenticated with TLS */
    bool tls_enable;                   /* Enable TLS */
    bool tls_require;                  /* Require TLS */
    bool tls_verify_peer;              /* TLS Verify Client Certificate */
@@ -201,6 +202,7 @@ public:
    char *tls_dhfile;                  /* TLS Diffie-Hellman Parameters */
    alist *tls_allowed_cns;            /* TLS Allowed Clients */
    TLS_CONTEXT *tls_ctx;              /* Shared TLS Context */
+   bool tls_authenticate;             /* Authenticated with TLS */
    bool tls_enable;                   /* Enable TLS */
    bool tls_require;                  /* Require TLS */
    bool tls_verify_peer;              /* TLS Verify Client Certificate */
@@ -258,6 +260,7 @@ public:
    char *tls_keyfile;                 /* TLS Client Key File */
    alist *tls_allowed_cns;            /* TLS Allowed Clients */
    TLS_CONTEXT *tls_ctx;              /* Shared TLS Context */
+   bool tls_authenticate;             /* Authenticated with TLS */
    bool tls_enable;                   /* Enable TLS */
    bool tls_require;                  /* Require TLS */
    bool AutoPrune;                    /* Do automatic pruning? */
@@ -290,6 +293,7 @@ public:
    char *tls_certfile;                /* TLS Client Certificate File */
    char *tls_keyfile;                 /* TLS Client Key File */
    TLS_CONTEXT *tls_ctx;              /* Shared TLS Context */
+   bool tls_authenticate;             /* Authenticated with TLS */
    bool tls_enable;                   /* Enable TLS */
    bool tls_require;                  /* Require TLS */
    bool enabled;                      /* Set if device is enabled */
index 12de1816ceac6d6ae9276cf293e1b255eafc8bb9..0f0e01081b750ea3ec1851ecb79c19c267896b26 100644 (file)
@@ -59,7 +59,7 @@ static bool authenticate(int rcode, BSOCK *bs, JCR* jcr)
 
    if (rcode != R_DIRECTOR) {
       Dmsg1(dbglvl, "I only authenticate directors, not %d\n", rcode);
-      Emsg1(M_FATAL, 0, _("I only authenticate directors, not %d\n"), rcode);
+      Jmsg1(jcr, M_FATAL, 0, _("I only authenticate directors, not %d\n"), rcode);
       goto auth_fatal;
    }
    if (bs->msglen < 25 || bs->msglen > 500) {
@@ -67,7 +67,7 @@ static bool authenticate(int rcode, BSOCK *bs, JCR* jcr)
             bs->who(), bs->msglen);
       char addr[64];
       char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
-      Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
+      Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
              who, bs->msglen);
       goto auth_fatal;
    }
@@ -79,7 +79,7 @@ static bool authenticate(int rcode, BSOCK *bs, JCR* jcr)
       bs->msg[100] = 0;
       Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n",
             bs->who(), bs->msg);
-      Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
+      Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
             who, bs->msg);
       goto auth_fatal;
    }
@@ -89,9 +89,9 @@ static bool authenticate(int rcode, BSOCK *bs, JCR* jcr)
          break;
    }
    if (!director) {
-       char addr[64];
-       char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
-      Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"), 
+      char addr[64];
+      char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
+      Jmsg2(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"), 
             dirname, who);
       goto auth_fatal;
    }
@@ -106,6 +106,10 @@ static bool authenticate(int rcode, BSOCK *bs, JCR* jcr)
          }
       }
 
+      if (director->tls_authenticate) {
+         tls_local_need = BNET_TLS_REQUIRED;
+      }
+
       if (director->tls_verify_peer) {
          verify_list = director->tls_allowed_cns;
       }
@@ -138,27 +142,30 @@ static bool authenticate(int rcode, BSOCK *bs, JCR* jcr)
 
    /* Verify that the remote host is willing to meet our TLS requirements */
    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
-      Emsg0(M_FATAL, 0, _("Authorization problem: Remote server did not"
+      Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
            " advertize required TLS support.\n"));
+      Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
       auth_success = false;
       goto auth_fatal;
    }
 
    /* Verify that we are willing to meet the remote host's requirements */
    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
-      Emsg0(M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
+      Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
+      Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
       auth_success = false;
       goto auth_fatal;
    }
 
-   if (have_tls) {
-      if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
-         /* Engage TLS! Full Speed Ahead! */
-         if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
-            Emsg0(M_FATAL, 0, _("TLS negotiation failed.\n"));
-            auth_success = false;
-            goto auth_fatal;
-         }
+   if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
+      /* Engage TLS! Full Speed Ahead! */
+      if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
+         Jmsg0(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
+         auth_success = false;
+         goto auth_fatal;
+      }
+      if (director->tls_authenticate) {         /* authentication only? */
+         bs->free_tls();                        /* shutodown tls */
       }
    }
 
@@ -221,6 +228,10 @@ int authenticate_storagedaemon(JCR *jcr)
       }
    }
 
+   if (me->tls_authenticate) {
+      tls_local_need = BNET_TLS_REQUIRED;
+   }
+
    if (job_canceled(jcr)) {
       auth_success = false;     /* force quick exit */
       goto auth_fatal;
@@ -251,7 +262,8 @@ int authenticate_storagedaemon(JCR *jcr)
    /* Verify that the remote host is willing to meet our TLS requirements */
    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not" 
-           " advertise required TLS support.\n"));
+           " advertize required TLS support.\n"));
+      Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
       auth_success = false;
       goto auth_fatal;
    }
@@ -259,17 +271,21 @@ int authenticate_storagedaemon(JCR *jcr)
    /* Verify that we are willing to meet the remote host's requirements */
    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
+      Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
       auth_success = false;
       goto auth_fatal;
    }
 
-   if (have_tls && tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
+   if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
       /* Engage TLS! Full Speed Ahead! */
       if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
          auth_success = false;
          goto auth_fatal;
       }
+      if (me->tls_authenticate) {           /* tls authentication only? */
+         sd->free_tls();                    /* yes, shutdown tls */
+      }
    }
 
 auth_fatal:
index 5bbd1bb01ac661eaecc889bf500138b976050e83..9fad17c43ba22e216b9a0821aff3ed4515b8aacd 100644 (file)
@@ -274,6 +274,7 @@ static bool check_resources()
 {
    bool OK = true;
    DIRRES *director;
+   bool need_tls;
 
    LockRes();
 
@@ -305,8 +306,9 @@ static bool check_resources()
          me->tls_enable = true;
 #endif
       }
+      need_tls = me->tls_enable || me->tls_authenticate;
 
-      if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && me->tls_enable) {
+      if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && need_tls) {
          Emsg1(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
             " or \"TLS CA Certificate Dir\" are defined for File daemon in %s.\n"),
                             configfile);
@@ -314,7 +316,7 @@ static bool check_resources()
       }
 
       /* If everything is well, attempt to initialize our per-resource TLS context */
-      if (OK && (me->tls_enable || me->tls_require)) {
+      if (OK && (need_tls || me->tls_require)) {
          /* Initialize TLS context:
           * Args: CA certfile, CA certdir, Certfile, Keyfile,
           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
@@ -464,20 +466,21 @@ static bool check_resources()
          director->tls_enable = true;
 #endif
       }
+      need_tls = director->tls_enable || director->tls_authenticate;
 
-      if (!director->tls_certfile && director->tls_enable) {
+      if (!director->tls_certfile && need_tls) {
          Emsg2(M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
                director->hdr.name, configfile);
          OK = false;
       }
 
-      if (!director->tls_keyfile && director->tls_enable) {
+      if (!director->tls_keyfile && need_tls) {
          Emsg2(M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
                director->hdr.name, configfile);
          OK = false;
       }
 
-      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
+      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && need_tls && director->tls_verify_peer) {
          Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
                              " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
                              " At least one CA certificate store is required"
@@ -487,7 +490,7 @@ static bool check_resources()
       }
 
       /* If everything is well, attempt to initialize our per-resource TLS context */
-      if (OK && (director->tls_enable || director->tls_require)) {
+      if (OK && (need_tls || director->tls_require)) {
          /* Initialize TLS context:
           * Args: CA certfile, CA certdir, Certfile, Keyfile,
           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
index 427bc4bcfb6e9ce11aaff2f63d8ecbe42881a7f7..a7ce38b564fd2c05efdf4b01f426377ea89c3e5e 100644 (file)
@@ -108,6 +108,7 @@ static RES_ITEM cli_items[] = {
    {"pkisigner",             store_alist_str, ITEM(res_client.pki_signing_key_files), 0, 0, 0},
    {"pkimasterkey",          store_alist_str, ITEM(res_client.pki_master_key_files), 0, 0, 0},
 #endif
+   {"tlsauthenticate",       store_bool,    ITEM(res_client.tls_authenticate),  0, 0, 0},
    {"tlsenable",             store_bool,    ITEM(res_client.tls_enable),  0, 0, 0},
    {"tlsrequire",            store_bool,    ITEM(res_client.tls_require), 0, 0, 0},
    {"tlscacertificatefile",  store_dir,       ITEM(res_client.tls_ca_certfile), 0, 0, 0},
@@ -124,6 +125,7 @@ static RES_ITEM dir_items[] = {
    {"password",    store_password, ITEM(res_dir.password),  0, ITEM_REQUIRED, 0},
    {"address",     store_str,      ITEM(res_dir.address),   0, 0, 0},
    {"monitor",     store_bool,   ITEM(res_dir.monitor),   0, ITEM_DEFAULT, 0},
+   {"tlsauthenticate",      store_bool,    ITEM(res_dir.tls_authenticate), 0, 0, 0},
    {"tlsenable",            store_bool,    ITEM(res_dir.tls_enable), 0, 0, 0},
    {"tlsrequire",           store_bool,    ITEM(res_dir.tls_require), 0, 0, 0},
    {"tlsverifypeer",        store_bool,    ITEM(res_dir.tls_verify_peer), 0, ITEM_DEFAULT, 1},
index c64b35d17df5084cb2f084e3ca74986f982d6df0..2efbb2a2b05b483d74086b1f7f980b80a528f0cb 100644 (file)
@@ -59,6 +59,7 @@ struct DIRRES {
    char *password;                    /* Director password */
    char *address;                     /* Director address or zero */
    bool monitor;                      /* Have only access to status and .status functions */
+   bool tls_authenticate;             /* Authenticate with TSL */
    bool tls_enable;                   /* Enable TLS */
    bool tls_require;                  /* Require TLS */
    bool tls_verify_peer;              /* TLS Verify Client Certificate */
@@ -89,6 +90,7 @@ struct CLIENT {
    char *pki_keypair_file;            /* PKI Key Pair File */
    alist *pki_signing_key_files;      /* PKI Signing Key Files */
    alist *pki_master_key_files;       /* PKI Master Key Files */
+   bool tls_authenticate;             /* Authenticate with TLS */
    bool tls_enable;                   /* Enable TLS */
    bool tls_require;                  /* Require TLS */
    char *tls_ca_certfile;             /* TLS CA Certificate File */
index 08481133c0ced1839e5ea5e9281e6e7096596b0a..1ed8e78bbf8d2e98a7e411b9afb38f6f9b211a36 100644 (file)
@@ -261,6 +261,7 @@ bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
          goto err;
       }
    }
+   Dmsg0(50, "TLS server negotiation established.\n");
    return true;
 
 err:
@@ -307,7 +308,7 @@ bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
          goto err;
       }
    }
-
+   Dmsg0(50, "TLS client negotiation established.\n");
    return true;
 
 err:
index 560d6233c3522d5cc97c33ebaa93ce589dbb0d7f..c019f2ed91f5496e813ba226ee9d733726a0cfb0 100644 (file)
@@ -85,6 +85,12 @@ void BSOCK::free_bsock()
    destroy();
 }
 
+void BSOCK::free_tls()
+{
+   free_tls_connection(this->tls);
+   this->tls = NULL;
+}   
+
 /*
  * Try to connect to host for max_retry_time at retry_time intervals.
  *   Note, you must have called the constructor prior to calling
index f4a90085dc9fd950b32b0fcf4d81faee53a97349..118da0b2091330cba4102109006d1b9905ee0194 100644 (file)
@@ -91,6 +91,7 @@ public:
    /* methods -- in bsock.c */
    void init();
    void free_bsock();
+   void free_tls();
    bool connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
                 utime_t heart_beat, const char *name, char *host, 
                 char *service, int port, int verbose);
index 014ed4026bbc27114a22597109cc5a0d353a0b7b..af4a46fb5821113791fc96738cfcc357ea736e3c 100644 (file)
@@ -82,7 +82,7 @@ void openssl_post_errors(JCR *jcr, int code, const char *errstring)
    while((sslerr = ERR_get_error()) != 0) {
       /* Acquire the human readable string */
       ERR_error_string_n(sslerr, buf, sizeof(buf));
-      Dmsg3(100, "jcr=%p %s: ERR=%s\n", jcr, errstring, buf);
+      Dmsg3(50, "jcr=%p %s: ERR=%s\n", jcr, errstring, buf);
       Qmsg2(jcr, M_ERROR, 0, "%s: ERR=%s\n", errstring, buf);
    }
 }
index f8062c073a2669bf4bbbb846f3689e5a62ce9099..d70e4cb2d03d3e75207742188450214072872b2d 100644 (file)
@@ -500,7 +500,7 @@ static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server)
          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;
index 1a08709592ddbb82c8a90b0572037a32b29bc633..d525ae181abc3d313b2c85fc621fb18c1812a283 100644 (file)
@@ -82,8 +82,9 @@ static RES_ITEM dir_items[] = {
    {"dirport",     store_int,      ITEM(dir_res.DIRport),  0, ITEM_DEFAULT, 9101},
    {"address",     store_str,      ITEM(dir_res.address),  0, ITEM_REQUIRED, 0},
    {"password",    store_password, ITEM(dir_res.password), 0, 0, 0},
-   {"tlsenable",      store_bool,    ITEM(dir_res.tls_enable), 1, 0, 0},
-   {"tlsrequire",     store_bool,    ITEM(dir_res.tls_require), 1, 0, 0},
+   {"tlsauthenticate",store_bool,    ITEM(dir_res.tls_authenticate), 0, 0, 0},
+   {"tlsenable",      store_bool,    ITEM(dir_res.tls_enable), 0, 0, 0},
+   {"tlsrequire",     store_bool,    ITEM(dir_res.tls_require), 0, 0, 0},
    {"tlscacertificatefile", store_dir, ITEM(dir_res.tls_ca_certfile), 0, 0, 0},
    {"tlscacertificatedir", store_dir,  ITEM(dir_res.tls_ca_certdir), 0, 0, 0},
    {"tlscertificate", store_dir,       ITEM(dir_res.tls_certfile), 0, 0, 0},
@@ -96,8 +97,9 @@ static RES_ITEM con_items[] = {
    {"name",        store_name,     ITEM(con_res.hdr.name), 0, ITEM_REQUIRED, 0},
    {"description", store_str,      ITEM(con_res.hdr.desc), 0, 0, 0},
    {"password",    store_password, ITEM(con_res.password), 0, ITEM_REQUIRED, 0},
-   {"tlsenable",      store_bool,    ITEM(con_res.tls_enable), 1, 0, 0},
-   {"tlsrequire",     store_bool,    ITEM(con_res.tls_require), 1, 0, 0},
+   {"tlsauthenticate",store_bool,    ITEM(con_res.tls_authenticate), 0, 0, 0},
+   {"tlsenable",      store_bool,    ITEM(con_res.tls_enable), 0, 0, 0},
+   {"tlsrequire",     store_bool,    ITEM(con_res.tls_require), 0, 0, 0},
    {"tlscacertificatefile", store_dir, ITEM(con_res.tls_ca_certfile), 0, 0, 0},
    {"tlscacertificatedir", store_dir,  ITEM(con_res.tls_ca_certdir), 0, 0, 0},
    {"tlscertificate", store_dir,       ITEM(con_res.tls_certfile), 0, 0, 0},
index bcb6faa988776c23fc89fc3a3f789229fb4ec7ce..e09678c4a1e7ce91c00cd035b5762f344b56178c 100644 (file)
@@ -67,6 +67,7 @@ public:
    int   DIRport;                     /* UA server port */
    char *address;                     /* UA server address */
    char *password;                    /* UA server password */
+   bool tls_authenticate;             /* Authenticate with tls */
    bool tls_enable;                   /* Enable TLS */
    bool tls_require;                  /* Require TLS */
    char *tls_ca_certfile;             /* TLS CA Certificate File */
@@ -93,6 +94,7 @@ class CONRES {
 public:
    RES   hdr;
    char *password;                    /* UA server password */
+   bool tls_authenticate;             /* Authenticate with tls */
    bool tls_enable;                   /* Enable TLS on all connections */
    bool tls_require;                  /* Require TLS on all connections */
    char *tls_ca_certfile;             /* TLS CA Certificate File */
index 1ffd68bdeff86c1bf5889fba26f79ab37949ab54..dad53f44d2b39d1988699edd330fd314caf2c0b3 100644 (file)
@@ -58,6 +58,7 @@ bool Console::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons,
    BSOCK *dir = jcr->dir_bsock;
    int tls_local_need = BNET_TLS_NONE;
    int tls_remote_need = BNET_TLS_NONE;
+   bool tls_authenticate;
    int compatible = true;
    char bashed_name[MAX_NAME_LENGTH];
    char *password;
@@ -79,6 +80,7 @@ bool Console::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons,
             tls_local_need = BNET_TLS_OK;
          }
       }
+      tls_authenticate = cons->tls_authenticate;
       tls_ctx = cons->tls_ctx;
    } else {
       bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name));
@@ -92,8 +94,13 @@ bool Console::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons,
          }
       }
 
+      tls_authenticate = director->tls_authenticate;
       tls_ctx = director->tls_ctx;
    }
+   if (tls_authenticate) {
+      tls_local_need = BNET_TLS_REQUIRED;
+   }
+
    /* Timeout Hello after 15 secs */
    dir->start_timer(15);
    dir->fsend(hello, bashed_name);
@@ -125,14 +132,15 @@ bool Console::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons,
    }
 
    /* Is TLS Enabled? */
-   if (have_tls) {
-      if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
-         /* Engage TLS! Full Speed Ahead! */
-         if (!bnet_tls_client(tls_ctx, dir, NULL)) {
-            bsnprintf(errmsg, errmsg_len, _("TLS negotiation failed with Director at \"%s:%d\"\n"),
-               dir->host(), dir->port());
-            goto bail_out;
-         }
+   if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
+      /* Engage TLS! Full Speed Ahead! */
+      if (!bnet_tls_client(tls_ctx, dir, NULL)) {
+         bsnprintf(errmsg, errmsg_len, _("TLS negotiation failed with Director at \"%s:%d\"\n"),
+            dir->host(), dir->port());
+         goto bail_out;
+      }
+      if (tls_authenticate) {               /* authenticate only? */
+         dir->free_tls();                   /* Yes, shutdown tls */
       }
    }
 
index 1facbaa7bd7123129a4064e9969b733635f44783..8aa2b39f3905007b136dd42f623a101f2fdad39b 100644 (file)
@@ -195,6 +195,7 @@ static int check_resources()
    bool ok = true;
    DIRRES *director;
    int numdir;
+   bool tls_needed;
 
    LockRes();
 
@@ -211,8 +212,9 @@ static int check_resources()
             continue;
          }
       }
+      tls_needed = director->tls_enable || director->tls_authenticate;
 
-      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable) {
+      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed) {
          Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
                              " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
                              " At least one CA certificate store is required.\n"),
@@ -240,8 +242,9 @@ static int check_resources()
             continue;
          }
       }
+      tls_needed = cons->tls_enable || cons->tls_authenticate;
 
-      if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable) {
+      if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && tls_needed) {
          Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
                              " or \"TLS CA Certificate Dir\" are defined for Console \"%s\" in %s.\n"),
                              cons->hdr.name, configfile);
index 49f6551fc54a719ea13dc57fcca3043620736c58..bffb987e159539784e8d838bd25ce2933d152284 100644 (file)
@@ -60,13 +60,13 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
 
    if (rcode != R_DIRECTOR) {
       Dmsg1(dbglvl, "I only authenticate Directors, not %d\n", rcode);
-      Emsg1(M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode);
+      Jmsg1(jcr, M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode);
       return 0;
    }
    if (bs->msglen < 25 || bs->msglen > 500) {
       Dmsg2(dbglvl, "Bad Hello command from Director at %s. Len=%d.\n",
             bs->who(), bs->msglen);
-      Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
+      Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
             bs->who(), bs->msglen);
       return 0;
    }
@@ -77,7 +77,7 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
       bs->msg[100] = 0;
       Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n",
             bs->who(), bs->msg);
-      Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
+      Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
             bs->who(), bs->msg);
       return 0;
    }
@@ -90,7 +90,7 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
    if (!director) {
       Dmsg2(dbglvl, "Connection from unknown Director %s at %s rejected.\n",
             dirname, bs->who());
-      Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"
+      Jmsg2(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"
        "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
             dirname, bs->who());
       free_pool_memory(dirname);
@@ -106,6 +106,10 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
       }
    }
 
+   if (director->tls_authenticate) {
+      tls_local_need = BNET_TLS_REQUIRED;
+   }
+
    if (director->tls_verify_peer) {
       verify_list = director->tls_allowed_cns;
    }
@@ -123,7 +127,7 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
    }
 
    if (!auth_success) {
-      Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n"
+      Jmsg0(jcr, M_FATAL, 0, _("Incorrect password given by Director.\n"
        "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
       auth_success = false;
       goto auth_fatal;
@@ -131,15 +135,17 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
 
    /* Verify that the remote host is willing to meet our TLS requirements */
    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
-      Emsg0(M_FATAL, 0, _("Authorization problem: Remote server did not" 
-           " advertise required TLS support.\n"));
+      Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not" 
+           " advertize required TLS support.\n"));
+      Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
       auth_success = false;
       goto auth_fatal;
    }
 
    /* Verify that we are willing to meet the remote host's requirements */
    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
-      Emsg0(M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
+      Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
+      Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
       auth_success = false;
       goto auth_fatal;
    }
@@ -147,10 +153,14 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
       /* Engage TLS! Full Speed Ahead! */
       if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
-         Emsg0(M_FATAL, 0, _("TLS negotiation failed.\n"));
+         Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with DIR at \"%s:%d\"\n"),
+            bs->host(), bs->port());
          auth_success = false;
          goto auth_fatal;
       }
+      if (director->tls_authenticate) {     /* authenticate with tls only? */
+         bs->free_tls();                    /* yes, shut it down */
+      }
    }
 
 auth_fatal:
@@ -179,7 +189,7 @@ int authenticate_director(JCR *jcr)
    if (!authenticate(R_DIRECTOR, dir, jcr)) {
       dir->fsend("%s", Dir_sorry);
       Dmsg1(dbglvl, "Unable to authenticate Director at %s.\n", dir->who());
-      Emsg1(M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who());
+      Jmsg1(jcr, M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who());
       bmicrosleep(5, 0);
       return 0;
    }
@@ -204,6 +214,10 @@ int authenticate_filed(JCR *jcr)
       }
    }
 
+   if (me->tls_authenticate) {
+      tls_local_need = BNET_TLS_REQUIRED;
+   }
+
    if (me->tls_verify_peer) {
       verify_list = me->tls_allowed_cns;
    }
@@ -233,7 +247,8 @@ int authenticate_filed(JCR *jcr)
    /* Verify that the remote host is willing to meet our TLS requirements */
    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not" 
-           " advertise required TLS support.\n"));
+           " advertize required TLS support.\n"));
+      Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
       auth_success = false;
       goto auth_fatal;
    }
@@ -241,6 +256,7 @@ int authenticate_filed(JCR *jcr)
    /* Verify that we are willing to meet the remote host's requirements */
    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
+      Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
       auth_success = false;
       goto auth_fatal;
    }
@@ -248,10 +264,14 @@ int authenticate_filed(JCR *jcr)
    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
       /* Engage TLS! Full Speed Ahead! */
       if (!bnet_tls_server(me->tls_ctx, fd, verify_list)) {
-         Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
+         Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\"\n"),
+            fd->host(), fd->port());
          auth_success = false;
          goto auth_fatal;
       }
+      if (me->tls_authenticate) {          /* tls authenticate only? */
+         fd->free_tls();                   /* yes, shut it down */
+      }
    }
 
 auth_fatal:
index f7d7605c1ede9f903f88d1e511629b6a695b6e43..d878330cfb44ee5b145125442fdb39c394fc3545 100644 (file)
@@ -287,6 +287,7 @@ uint32_t newVolSessionId()
 static int check_resources()
 {
    bool OK = true;
+   bool tls_needed;
 
 
    me = (STORES *)GetNextRes(R_STORAGE, NULL);
@@ -341,19 +342,21 @@ static int check_resources()
          }
       }
 
-      if (!store->tls_certfile && store->tls_enable) {
+      tls_needed = store->tls_enable || store->tls_authenticate;
+
+      if (!store->tls_certfile && tls_needed) {
          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n"),
               store->hdr.name, configfile);
          OK = false;
       }
 
-      if (!store->tls_keyfile && store->tls_enable) {
+      if (!store->tls_keyfile && tls_needed) {
          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Storage \"%s\" in %s.\n"),
               store->hdr.name, configfile);
          OK = false;
       }
 
-      if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable && store->tls_verify_peer) {
+      if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && tls_needed && store->tls_verify_peer) {
          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
               " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s."
               " At least one CA certificate store is required"
@@ -363,7 +366,7 @@ static int check_resources()
       }
 
       /* If everything is well, attempt to initialize our per-resource TLS context */
-      if (OK && (store->tls_enable || store->tls_require)) {
+      if (OK && (tls_needed || store->tls_require)) {
          /* Initialize TLS context:
           * Args: CA certfile, CA certdir, Certfile, Keyfile,
           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
@@ -386,19 +389,21 @@ static int check_resources()
          director->tls_enable = true;
       }
 
-      if (!director->tls_certfile && director->tls_enable) {
+      tls_needed = director->tls_enable || director->tls_authenticate;
+
+      if (!director->tls_certfile && tls_needed) {
          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
               director->hdr.name, configfile);
          OK = false;
       }
 
-      if (!director->tls_keyfile && director->tls_enable) {
+      if (!director->tls_keyfile && tls_needed) {
          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
               director->hdr.name, configfile);
          OK = false;
       }
 
-      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
+      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed && director->tls_verify_peer) {
          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
               " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
               " At least one CA certificate store is required"
@@ -408,7 +413,7 @@ static int check_resources()
       }
 
       /* If everything is well, attempt to initialize our per-resource TLS context */
-      if (OK && (director->tls_enable || director->tls_require)) {
+      if (OK && (tls_needed || director->tls_require)) {
          /* Initialize TLS context:
           * Args: CA certfile, CA certdir, Certfile, Keyfile,
           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
index caace4c9707116bee60162ca31f0b68cb507f8e0..0c96fd27c93a36bb41850aa258a486b5d2d9d151 100644 (file)
@@ -77,9 +77,10 @@ static RES_ITEM store_items[] = {
    {"scriptsdirectory",      store_dir,  ITEM(res_store.scripts_directory), 0, 0, 0},
    {"maximumconcurrentjobs", store_pint, ITEM(res_store.max_concurrent_jobs), 0, ITEM_DEFAULT, 20},
    {"heartbeatinterval",     store_time, ITEM(res_store.heartbeat_interval), 0, ITEM_DEFAULT, 0},
-   {"tlsenable",             store_bit,     ITEM(res_store.tls_enable), 1, 0, 0},
-   {"tlsrequire",            store_bit,     ITEM(res_store.tls_require), 1, 0, 0},
-   {"tlsverifypeer",         store_bit,     ITEM(res_store.tls_verify_peer), 1, ITEM_DEFAULT, 1},
+   {"tlsauthenticate",       store_bool,    ITEM(res_store.tls_authenticate), 0, 0, 0},
+   {"tlsenable",             store_bool,    ITEM(res_store.tls_enable), 0, 0, 0},
+   {"tlsrequire",            store_bool,    ITEM(res_store.tls_require), 0, 0, 0},
+   {"tlsverifypeer",         store_bool,    ITEM(res_store.tls_verify_peer), 1, ITEM_DEFAULT, 1},
    {"tlscacertificatefile",  store_dir,       ITEM(res_store.tls_ca_certfile), 0, 0, 0},
    {"tlscacertificatedir",   store_dir,       ITEM(res_store.tls_ca_certdir), 0, 0, 0},
    {"tlscertificate",        store_dir,       ITEM(res_store.tls_certfile), 0, 0, 0},
@@ -96,10 +97,11 @@ static RES_ITEM dir_items[] = {
    {"name",        store_name,     ITEM(res_dir.hdr.name),   0, ITEM_REQUIRED, 0},
    {"description", store_str,      ITEM(res_dir.hdr.desc),   0, 0, 0},
    {"password",    store_password, ITEM(res_dir.password),   0, ITEM_REQUIRED, 0},
-   {"monitor",     store_bit,    ITEM(res_dir.monitor),   1, ITEM_DEFAULT, 0},
-   {"tlsenable",            store_bit,     ITEM(res_dir.tls_enable), 1, 0, 0},
-   {"tlsrequire",           store_bit,     ITEM(res_dir.tls_require), 1, 0, 0},
-   {"tlsverifypeer",        store_bit,     ITEM(res_dir.tls_verify_peer), 1, ITEM_DEFAULT, 1},
+   {"monitor",     store_bool,     ITEM(res_dir.monitor),    0, 0, 0},
+   {"tlsauthenticate",      store_bool,    ITEM(res_dir.tls_authenticate), 0, 0, 0},
+   {"tlsenable",            store_bool,    ITEM(res_dir.tls_enable), 0, 0, 0},
+   {"tlsrequire",           store_bool,    ITEM(res_dir.tls_require), 0, 0, 0},
+   {"tlsverifypeer",        store_bool,    ITEM(res_dir.tls_verify_peer), 1, ITEM_DEFAULT, 1},
    {"tlscacertificatefile", store_dir,       ITEM(res_dir.tls_ca_certfile), 0, 0, 0},
    {"tlscacertificatedir",  store_dir,       ITEM(res_dir.tls_ca_certdir), 0, 0, 0},
    {"tlscertificate",       store_dir,       ITEM(res_dir.tls_certfile), 0, 0, 0},
@@ -111,11 +113,11 @@ static RES_ITEM dir_items[] = {
 
 /* Device definition */
 static RES_ITEM dev_items[] = {
-   {"name",                  store_name,   ITEM(res_dev.hdr.name),        0, ITEM_REQUIRED, 0},
-   {"description",           store_str,    ITEM(res_dir.hdr.desc),        0, 0, 0},
-   {"mediatype",             store_strname,ITEM(res_dev.media_type),      0, ITEM_REQUIRED, 0},
-   {"devicetype",            store_devtype,ITEM(res_dev.dev_type), 0, 0, 0},
-   {"archivedevice",         store_strname,ITEM(res_dev.device_name),     0, ITEM_REQUIRED, 0},
+   {"name",                  store_name,   ITEM(res_dev.hdr.name),    0, ITEM_REQUIRED, 0},
+   {"description",           store_str,    ITEM(res_dir.hdr.desc),    0, 0, 0},
+   {"mediatype",             store_strname,ITEM(res_dev.media_type),  0, ITEM_REQUIRED, 0},
+   {"devicetype",            store_devtype,ITEM(res_dev.dev_type),    0, 0, 0},
+   {"archivedevice",         store_strname,ITEM(res_dev.device_name), 0, ITEM_REQUIRED, 0},
    {"hardwareendoffile",     store_bit,  ITEM(res_dev.cap_bits), CAP_EOF,  ITEM_DEFAULT, 1},
    {"hardwareendofmedium",   store_bit,  ITEM(res_dev.cap_bits), CAP_EOM,  ITEM_DEFAULT, 1},
    {"backwardspacerecord",   store_bit,  ITEM(res_dev.cap_bits), CAP_BSR,  ITEM_DEFAULT, 1},
index f59986b01ad967f9a532efb85129ff6426b39d1a..70b61268697b46be9d7bdfe7174ddc172cc62731 100644 (file)
@@ -57,10 +57,11 @@ public:
 
    char *password;                    /* Director password */
    char *address;                     /* Director IP address or zero */
-   int monitor;                       /* Have only access to status and .status functions */
-   int tls_enable;                    /* Enable TLS */
-   int tls_require;                   /* Require TLS */
-   int tls_verify_peer;              /* TLS Verify Client Certificate */
+   bool monitor;                      /* Have only access to status and .status functions */
+   bool tls_authenticate;             /* Authenticate with TLS */
+   bool tls_enable;                   /* Enable TLS */
+   bool tls_require;                  /* Require TLS */
+   bool tls_verify_peer;              /* TLS Verify Client Certificate */
    char *tls_ca_certfile;             /* TLS CA Certificate File */
    char *tls_ca_certdir;              /* TLS CA Certificate Directory */
    char *tls_certfile;                /* TLS Server Certificate File */
@@ -87,9 +88,10 @@ public:
    MSGS *messages;                    /* Daemon message handler */
    utime_t heartbeat_interval;        /* Interval to send hb to FD */
    utime_t client_wait;               /* Time to wait for FD to connect */
-   int tls_enable;                    /* Enable TLS */
-   int tls_require;                   /* Require TLS */
-   int tls_verify_peer;               /* TLS Verify Client Certificate */
+   bool tls_authenticate;             /* Authenticate with TLS */
+   bool tls_enable;                   /* Enable TLS */
+   bool tls_require;                  /* Require TLS */
+   bool tls_verify_peer;              /* TLS Verify Client Certificate */
    char *tls_ca_certfile;             /* TLS CA Certificate File */
    char *tls_ca_certdir;              /* TLS CA Certificate Directory */
    char *tls_certfile;                /* TLS Server Certificate File */
index 86a6c54da1d846c72bb4711e73652ff798dc5275..b12efcb1ec2dd86d4f48a9a9fb7f489228397948 100644 (file)
@@ -1,6 +1,10 @@
               Technical notes on version 2.3
 
 General:
+11Dec07
+kes  Implement a security enhancement: TLS authentication but no       
+     encryption. Enabled by setting 'TLS Authentication = yes'.
+     Note when this is on, TLS encryption is turned OFF!
 10Dec07
 kes  This patch corrects a problem where the maximum concurrent storage
      jobs counter gets out of sync during restore jobs causing jobs to