For 1.37:
 - update volume=xxx --- add status=Full
-- After rename
-  04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume 
-     "DLT-13Feb04".
-  Current Volume "DLT-04Jul05" not acceptable because:
-  1997 Volume "DLT-13Feb04" not in catalog.
-  04-Jul 13:01 MainSD: Please mount Volume "DLT-04Jul05" on Storage Device 
-     "HP DLT 80" (/dev/nst0) for Job Rufus.2005-07-04_01.05.02
 - Remove old spool files on startup.
 - Exclude SD spool/working directory.
 - Finish TLS implementation.
 - Review all items in "restore".
 - Fix PostgreSQL GROUP BY problems in restore.
 - Fix PostgreSQL sql problems in bugs.
+- After rename
+  04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume 
+     "DLT-13Feb04".
+  Current Volume "DLT-04Jul05" not acceptable because:
+  1997 Volume "DLT-13Feb04" not in catalog.
+  04-Jul 13:01 MainSD: Please mount Volume "DLT-04Jul05" on Storage Device 
+     "HP DLT 80" (/dev/nst0) for Job Rufus.2005-07-04_01.05.02
+
 
 General:
 
 Changes to 1.37.28:
+09Jul05
+- Implement TLS in gnome console and wx-console.
 08Jul05
 - Correct a NULL pointer reference in the mount command.
 - Correct typo in Copyright
 
    buf[0] = 0;
    return 0;
 #endif
-
 }
 
 
 
  *
  *     Version $Id$
  */
-
 /*
-   Copyright (C) 2002-2004 Kern Sibbald and John Walker
+   Copyright (C) 2002-2005 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 2
-   of the License, or (at your option) any later version.
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "bacula.h"
 static bool ready = false;
 static bool quit = false;
 static guint initial;
+static int numdir = 0;
 
 #define CONFIG_FILE "./gnome-console.conf"   /* default configuration file */
 
 static void usage()
 {
    fprintf(stderr, _(
-"Copyright (C) 2002-2004 Kern Sibbald and John Walker\n"
+"Copyright (C) 2002-2005 Kern Sibbald\n"
 "\nVersion: " VERSION " (" BDATE ") %s %s %s\n\n"
 "Usage: gnome-console [-s] [-c config_file] [-d debug_level] [config_file]\n"
 "       -c <file>   set configuration file to file\n"
    exit(1);
 }
 
+/*
+ * Call-back for reading a passphrase for an encrypted PEM file
+ * This function uses getpass(), which uses a static buffer and is NOT thread-safe.
+ */
+static int tls_pem_callback(char *buf, int size, const void *userdata)
+{
+#ifdef HAVE_TLS
+   const char *prompt = (const char *) userdata;
+   char *passwd;
+
+   passwd = getpass(prompt);
+   bstrncpy(buf, passwd, size);
+   return (strlen(buf));
+#else
+   buf[0] = 0;
+   return 0;
+#endif
+}
+
+
+/*
+ * Make a quick check to see that we have all the
+ * resources needed.
+ */
+static int check_resources()
+{
+   int xOK = true;
+   DIRRES *director;
+
+   LockRes();
+
+   numdir = 0;
+   foreach_res(director, R_DIRECTOR) {
+      numdir++;
+      /* tls_require implies tls_enable */
+      if (director->tls_require) {
+         if (have_tls) {
+            director->tls_enable = true;
+         } else {
+            Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
+            xOK = false;
+            continue;
+         }
+      }
+
+      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable) {
+         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"),
+                             director->hdr.name, configfile);
+         xOK = false;
+      }
+   }
+   
+   if (numdir == 0) {
+      Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n"
+                          "Without that I don't how to speak to the Director :-(\n"), configfile);
+      xOK = false;
+   }
+
+   CONRES *cons;
+   /* Loop over Consoles */
+   foreach_res(cons, R_CONSOLE) {
+      /* tls_require implies tls_enable */
+      if (cons->tls_require) {
+         if (have_tls) {
+            cons->tls_enable = true;
+         } else {
+            Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
+            xOK = false;
+            continue;
+         }
+      }
+
+      if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable) {
+         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);
+         xOK = false;
+      }
+   }
+
+   UnlockRes();
+
+   return xOK;
+}
+
 
 /*********************************************************************
  *
 
    parse_config(configfile);
 
-   LockRes();
-   ndir = 0;
-   foreach_res(dir, R_DIRECTOR) {
-      ndir++;
+   if (init_tls() != 0) {
+      Emsg0(M_ERROR_TERM, 0, _("TLS library initialization failed.\n"));
    }
-   UnlockRes();
-   if (ndir == 0) {
-      Emsg1(M_ERROR_TERM, 0, _("No director resource defined in %s\n"
-"Without that I don't how to speak to the Director :-(\n"), configfile);
-   }
-
 
+   if (!check_resources()) {
+      Emsg1(M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
+   }
 
    console = create_console();
    gtk_window_set_default_size(GTK_WINDOW(console), 800, 700);
    while (gtk_events_pending()) {     /* fully paint screen */
       gtk_main_iteration();
    }
+
+   LockRes();
+   /* If cons==NULL, default console will be used */
+   CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
+   UnlockRes();
+
+   char buf[1024];
+   /* Initialize Console TLS context */
+   if (cons && (cons->tls_enable || cons->tls_require)) {
+      /* Generate passphrase prompt */
+      bsnprintf(buf, sizeof(buf), "Passphrase for Console \"%s\" TLS private key: ", cons->hdr.name);
+
+      /* Initialize TLS context:
+       * Args: CA certfile, CA certdir, Certfile, Keyfile,
+       * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
+      cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
+         cons->tls_ca_certdir, cons->tls_certfile,
+         cons->tls_keyfile, tls_pem_callback, &buf, NULL, true);
+
+      if (!cons->tls_ctx) {
+         bsnprintf(buf, sizeof(buf), _("Failed to initialize TLS context for Console \"%s\".\n"),
+            dir->hdr.name);
+         set_text(buf, strlen(buf));
+         terminate_console(0);
+         return 1;
+      }
+
+   }
+
+   /* Initialize Director TLS context */
+   if (dir->tls_enable || dir->tls_require) {
+      /* Generate passphrase prompt */
+      bsnprintf(buf, sizeof(buf), "Passphrase for Director \"%s\" TLS private key: ", dir->hdr.name);
+
+      /* Initialize TLS context:
+       * Args: CA certfile, CA certdir, Certfile, Keyfile,
+       * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
+      dir->tls_ctx = new_tls_context(dir->tls_ca_certfile,
+         dir->tls_ca_certdir, dir->tls_certfile,
+         dir->tls_keyfile, tls_pem_callback, &buf, NULL, true);
+
+      if (!dir->tls_ctx) {
+         bsnprintf(buf, sizeof(buf), _("Failed to initialize TLS context for Director \"%s\".\n"),
+            dir->hdr.name);
+         set_text(buf, strlen(buf));
+         terminate_console(0);
+         return 1;
+      }
+   }
+
+
    UA_sock = bnet_connect(NULL, 5, 15, "Director daemon", dir->address,
                           NULL, dir->DIRport, 0);
    if (UA_sock == NULL) {
    }
 
    jcr.dir_bsock = UA_sock;
-   LockRes();
-   /* If cons==NULL, default console will be used */
-   CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
-   UnlockRes();
    if (!authenticate_director(&jcr, dir, cons)) {
       set_text(UA_sock->msg, UA_sock->msglen);
       return 0;
 /* Cleanup and then exit */
 void terminate_console(int sig)
 {
-   static int already_here = FALSE;
+   static bool already_here = false;
 
    if (already_here)                  /* avoid recursive temination problems */
       exit(1);
-   already_here = TRUE;
+   already_here = true;
+   cleanup_tls();
    disconnect_from_director((gpointer)NULL);
    gtk_main_quit();
    exit(0);
 
  *   1. The generic lexical scanner in lib/lex.c and lib/lex.h
  *
  *   2. The generic config  scanner in lib/parse_config.c and
- *     lib/parse_config.h.
- *     These files contain the parser code, some utility
- *     routines, and the common store routines (name, int,
- *     string).
+ *      lib/parse_config.h.
+ *      These files contain the parser code, some utility
+ *      routines, and the common store routines (name, int,
+ *      string).
  *
  *   3. The daemon specific file, which contains the Resource
- *     definitions as well as any specific store routines
- *     for the resource records.
+ *      definitions as well as any specific store routines
+ *      for the resource records.
  *
  *     Kern Sibbald, January MM, September MM
  *
  *     Version $Id$
  */
-
 /*
-   Copyright (C) 2000, 2001 Kern Sibbald and John Walker
+   Copyright (C) 2000-2005 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 2
-   of the License, or (at your option) any later version.
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "bacula.h"
    {"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},
-   {"enablessl", store_yesno,      ITEM(dir_res.enable_ssl), 1, ITEM_DEFAULT, 0},
+   {"tlsenable",      store_yesno,     ITEM(dir_res.tls_enable), 1, ITEM_DEFAULT, 0},
+   {"tlsrequire",     store_yesno,     ITEM(dir_res.tls_require), 1, ITEM_DEFAULT, 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},
+   {"tlskey",         store_dir,       ITEM(dir_res.tls_keyfile), 0, 0, 0},
    {NULL, NULL, NULL, 0, 0, 0}
 };
 
    {"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},
-   {"requiressl",  store_yesno,    ITEM(con_res.require_ssl), 1, ITEM_DEFAULT, 0},
+   {"tlsenable",      store_yesno,     ITEM(con_res.tls_enable), 1, ITEM_DEFAULT, 0},
+   {"tlsrequire",     store_yesno,     ITEM(con_res.tls_require), 1, ITEM_DEFAULT, 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},
+   {"tlskey",         store_dir,       ITEM(con_res.tls_keyfile), 0, 0, 0},
    {NULL, NULL, NULL, 0, 0, 0}
 };
 
    {"director",      dir_items,   R_DIRECTOR},
    {"console",       con_items,   R_CONSOLE},
    {"consolefont",   con_font_items, R_CONSOLE_FONT},
-   {NULL,           NULL,        0}
+   {NULL,            NULL,        0}
 };
 
 
       printf("No record for %d %s\n", type, res_to_str(type));
       return;
    }
-   if (type < 0) {                   /* no recursion */
+   if (type < 0) {                    /* no recursion */
       type = - type;
       recurse = false;
    }
    switch (type) {
    case R_DIRECTOR:
       printf("Director: name=%s address=%s DIRport=%d\n", reshdr->name,
-             res->dir_res.address, res->dir_res.DIRport);
+              res->dir_res.address, res->dir_res.DIRport);
       break;
    case R_CONSOLE:
       printf("Console: name=%s\n", reshdr->name);
       break;
    case R_CONSOLE_FONT:
       printf("ConsoleFont: name=%s font face=%s\n",
-            reshdr->name, NPRT(res->con_font.fontface));
+             reshdr->name, NPRT(res->con_font.fontface));
       break;
    default:
       printf("Unknown resource type %d\n", type);
    switch (type) {
    case R_DIRECTOR:
       if (res->dir_res.address) {
-        free(res->dir_res.address);
+         free(res->dir_res.address);
+      }
+      if (res->dir_res.tls_ctx) { 
+         free_tls_context(res->dir_res.tls_ctx);
+      }
+      if (res->dir_res.tls_ca_certfile) {
+         free(res->dir_res.tls_ca_certfile);
+      }
+      if (res->dir_res.tls_ca_certdir) {
+         free(res->dir_res.tls_ca_certdir);
+      }
+      if (res->dir_res.tls_certfile) {
+         free(res->dir_res.tls_certfile);
+      }
+      if (res->dir_res.tls_keyfile) {
+         free(res->dir_res.tls_keyfile);
       }
       break;
    case R_CONSOLE:
       if (res->con_res.password) {
-        free(res->con_res.password);
+         free(res->con_res.password);
+      }
+      if (res->con_res.tls_ctx) { 
+         free_tls_context(res->con_res.tls_ctx);
+      }
+      if (res->con_res.tls_ca_certfile) {
+         free(res->con_res.tls_ca_certfile);
+      }
+      if (res->con_res.tls_ca_certdir) {
+         free(res->con_res.tls_ca_certdir);
+      }
+      if (res->con_res.tls_certfile) {
+         free(res->con_res.tls_certfile);
+      }
+      if (res->con_res.tls_keyfile) {
+         free(res->con_res.tls_keyfile);
       }
       break;
    case R_CONSOLE_FONT:
       if (res->con_font.fontface) {
-        free(res->con_font.fontface);
+         free(res->con_font.fontface);
       }
       break;
    default:
     */
    for (i=0; items[i].name; i++) {
       if (items[i].flags & ITEM_REQUIRED) {
-           if (!bit_is_set(i, res_all.dir_res.hdr.item_present)) {
-              Emsg2(M_ABORT, 0, "%s item is required in %s resource, but not found.\n",
-                items[i].name, resources[rindex]);
-            }
+            if (!bit_is_set(i, res_all.dir_res.hdr.item_present)) {
+               Emsg2(M_ABORT, 0, "%s item is required in %s resource, but not found.\n",
+                 items[i].name, resources[rindex]);
+             }
       }
    }
 
       switch (type) {
       /* Resources not containing a resource */
       case R_DIRECTOR:
-        break;
+         break;
 
       case R_CONSOLE:
       case R_CONSOLE_FONT:
-        break;
+         break;
 
       default:
-        Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type);
-        error = 1;
-        break;
+         Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type);
+         error = 1;
+         break;
       }
       /* Note, the resoure name was already saved during pass 1,
        * so here, we can just release it.
        */
       if (res_all.dir_res.hdr.name) {
-        free(res_all.dir_res.hdr.name);
-        res_all.dir_res.hdr.name = NULL;
+         free(res_all.dir_res.hdr.name);
+         res_all.dir_res.hdr.name = NULL;
       }
       if (res_all.dir_res.hdr.desc) {
-        free(res_all.dir_res.hdr.desc);
-        res_all.dir_res.hdr.desc = NULL;
+         free(res_all.dir_res.hdr.desc);
+         res_all.dir_res.hdr.desc = NULL;
       }
       return;
    }
       res = (URES *)malloc(size);
       memcpy(res, &res_all, size);
       if (!res_head[rindex]) {
-        res_head[rindex] = (RES *)res; /* store first entry */
+         res_head[rindex] = (RES *)res; /* store first entry */
       } else {
-        RES *next;
-        /* Add new res to end of chain */
-        for (next=res_head[rindex]; next->next; next=next->next) {
-           if (strcmp(next->name, res->dir_res.hdr.name) == 0) {
-              Emsg2(M_ERROR_TERM, 0,
-                 _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
-                 resources[rindex].name, res->dir_res.hdr.name);
-           }
-        }
-        next->next = (RES *)res;
-        Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
-              res->dir_res.hdr.name);
+         RES *next;
+         /* Add new res to end of chain */
+         for (next=res_head[rindex]; next->next; next=next->next) {
+            if (strcmp(next->name, res->dir_res.hdr.name) == 0) {
+               Emsg2(M_ERROR_TERM, 0,
+                  _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
+                  resources[rindex].name, res->dir_res.hdr.name);
+            }
+         }
+         next->next = (RES *)res;
+         Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
+               res->dir_res.hdr.name);
       }
    }
 }
 
 enum {
    R_DIRECTOR = 1001,
    R_CONSOLE,
-   R_CONSOLE_FONT
+   R_CONSOLE_FONT,
+   R_FIRST = R_DIRECTOR,
+   R_LAST = R_CONSOLE_FONT            /* Keep this updated */
 };
 
-#define R_FIRST     R_DIRECTOR
-#define R_LAST     R_CONSOLE_FONT
-
 /*
  * Some resource attributes
  */
-#define R_NAME                       1020
-#define R_ADDRESS                    1021
-#define R_PASSWORD                   1022
-#define R_TYPE                       1023
-#define R_BACKUP                     1024
+enum {
+   R_NAME = 1020,
+   R_ADDRESS,
+   R_PASSWORD,
+   R_TYPE,
+   R_BACKUP
+};
 
 
 /* Definition of the contents of each Resource */
-struct s_res_dir {
-   RES  hdr;
-   int  DIRport;                     /* UA server port */
-   char *address;                    /* UA server address */
-   char *password;                   /* UA server password */
-   int enable_ssl;                   /* Use SSL */
+struct DIRRES {
+   RES   hdr;
+   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 */
+   char *tls_ca_certfile;             /* TLS CA Certificate File */
+   char *tls_ca_certdir;              /* TLS CA Certificate Directory */
+   char *tls_certfile;                /* TLS Client Certificate File */
+   char *tls_keyfile;                 /* TLS Client Key File */
+
+   TLS_CONTEXT *tls_ctx;              /* Shared TLS Context */
 };
-typedef struct s_res_dir DIRRES;
 
-struct s_con_font {
-   RES  hdr;
-   char *fontface;                   /* Console Font specification */
-   int require_ssl;                  /* Require SSL on all connections */
+struct CONFONTRES {
+   RES   hdr;
+   char *fontface;                    /* Console Font specification */
+   int require_ssl;                   /* Require SSL on all connections */
 };
-typedef struct s_con_font CONFONTRES;
 
-struct s_con_res {
-   RES  hdr;
-   char *password;                   /* UA server password */
-   int require_ssl;                  /* Require SSL on all connections */
+struct CONRES {
+   RES   hdr;
+   char *password;                    /* UA server password */
+   int tls_enable;                    /* Enable TLS on all connections */
+   int 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 */
+   char *tls_keyfile;                 /* TLS Client Key File */
+
+   TLS_CONTEXT *tls_ctx;              /* Shared TLS Context */
 };
-typedef struct s_con_res CONRES;
 
 
 /* Define the Union of all the above
  * resource structure definitions.
  */
 union u_res {
-   struct s_res_dir    dir_res;
-   struct s_con_font   con_font;
-   struct s_con_res    con_res;
+   DIRRES dir_res;
+   CONRES con_res;
+   CONFONTRES con_font;
    RES hdr;
 };
 
 
 /* */
 #undef  VERSION
 #define VERSION "1.37.28"
-#define BDATE   "08 July 2005"
-#define LSMDATE "08Jul05"
+#define BDATE   "09 July 2005"
+#define LSMDATE "09Jul05"
 
 /* Debug flags */
 #undef  DEBUG
 
 /* Definition of the contents of each Resource */
 
 /* Console "globals" */
-struct s_res_con {
+struct CONRES {
    RES   hdr;
    char *rc_file;                     /* startup file */
    char *hist_file;                   /* command history file */
 
    TLS_CONTEXT *tls_ctx;              /* Shared TLS Context */
 };
-typedef struct s_res_con CONRES;
 
 /* Director */
-struct s_res_dir {
+struct DIRRES {
    RES   hdr;
    int   DIRport;                     /* UA server port */
    char *address;                     /* UA server address */
 
    TLS_CONTEXT *tls_ctx;              /* Shared TLS Context */
 };
-typedef struct s_res_dir DIRRES;
 
 
 /* Define the Union of all the above
  * resource structure definitions.
  */
 union u_res {
-   struct s_res_dir     res_dir;
-   struct s_res_con     res_cons;
+   DIRRES res_dir;
+   CONRES res_cons;
    RES hdr;
 };
 
 
 bool console_thread::configloaded = false;
 wxString console_thread::working_dir = wxT(".");
 
+int numdir = 0;
+
+/*
+ * Call-back for reading a passphrase for an encrypted PEM file
+ * This function uses getpass(), which uses a static buffer and is NOT thread-safe.
+ */
+static int tls_pem_callback(char *buf, int size, const void *userdata)
+{
+#ifdef HAVE_TLS
+   const char *prompt = (const char *) userdata;
+   char *passwd;
+
+   passwd = getpass(prompt);
+   bstrncpy(buf, passwd, size);
+   return (strlen(buf));
+#else
+   buf[0] = 0;
+   return 0;
+#endif
+}
+
+
+/*
+ * Make a quick check to see that we have all the
+ * resources needed.
+ */
+static int check_resources()
+{
+   int xOK = true;
+   DIRRES *director;
+
+   LockRes();
+
+   numdir = 0;
+   foreach_res(director, R_DIRECTOR) {
+      numdir++;
+      /* tls_require implies tls_enable */
+      if (director->tls_require) {
+         if (have_tls) {
+            director->tls_enable = true;
+         } else {
+            Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
+            xOK = false;
+            continue;
+         }
+      }
+
+      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable) {
+         Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
+                             " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in config file.\n"
+                             " At least one CA certificate store is required.\n"),
+                             director->hdr.name);
+         xOK = false;
+      }
+   }
+   
+   if (numdir == 0) {
+      Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in config file.\n"
+                          "Without that I don't how to speak to the Director :-(\n"));
+      xOK = false;
+   }
+
+   CONRES *cons;
+   /* Loop over Consoles */
+   foreach_res(cons, R_CONSOLE) {
+      /* tls_require implies tls_enable */
+      if (cons->tls_require) {
+         if (have_tls) {
+            cons->tls_enable = true;
+         } else {
+            Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
+            xOK = false;
+            continue;
+         }
+      }
+
+      if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable) {
+         Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
+                             " or \"TLS CA Certificate Dir\" are defined for Console \"%s\" in config file.\n"),
+                             cons->hdr.name);
+         xOK = false;
+      }
+   }
+   UnlockRes();
+   return xOK;
+}
+
+
 void console_thread::SetWorkingDirectory(wxString w_dir) {
    if ((w_dir.Last() == '/') || (w_dir.Last() == '\\')) {
       console_thread::working_dir = w_dir.Mid(0, w_dir.Length()-1);
       return errmsg;
    }
    
+   if (init_tls() != 0) {
+      Jmsg(NULL, M_ERROR_TERM, 0, _("TLS library initialization failed.\n"));
+   }
+
+   if (!check_resources()) {
+      Jmsg(NULL, M_ERROR_TERM, 0, _("Please correct configuration file.\n"));
+   }
+
    term_msg();
    wxRemoveFile(console_thread::working_dir + wxT("/wx-console.conmsg"));
    init_msg(NULL, NULL);
  * Thread entry point
  */
 void* console_thread::Entry() {
+   DIRRES* dir;
    if (!inited) {
       csprint("Error : Library not initialized\n");
       csprint(NULL, CS_END);
    DIRRES* res[16]; /* Maximum 16 directors */
    
    LockRes();
-   DIRRES* dir;
    foreach_res(dir, R_DIRECTOR) {
       res[count] = dir;
       count++;
          Exit();
       #endif
       return NULL;
-   }
-   else if (count == 1) {
+   } else if (count == 1) {
       directorchoosen = 1;
-   }
-   else {
+   } else {
       while (true) {
          csprint("Multiple directors found in your config file.\n");
          for (int i = 0; i < count; i++) {
          }
       }
    }
+   dir = res[directorchoosen-1];
 
    memset(&jcr, 0, sizeof(jcr));
    
    jcr.dequeuing = 1; /* TODO: catch messages */
 
+   LockRes();
+   /* If cons==NULL, default console will be used */
+   CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
+   UnlockRes();
+
+   char buf[1024];
+   /* Initialize Console TLS context */
+   if (cons && (cons->tls_enable || cons->tls_require)) {
+      /* Generate passphrase prompt */
+      bsnprintf(buf, sizeof(buf), "Passphrase for Console \"%s\" TLS private key: ", cons->hdr.name);
+
+      /* Initialize TLS context:
+       * Args: CA certfile, CA certdir, Certfile, Keyfile,
+       * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
+      cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
+         cons->tls_ca_certdir, cons->tls_certfile,
+         cons->tls_keyfile, tls_pem_callback, &buf, NULL, true);
+
+      if (!cons->tls_ctx) {
+         bsnprintf(buf, sizeof(buf), _("Failed to initialize TLS context for Console \"%s\".\n"),
+            dir->hdr.name);
+         csprint(buf);
+         return NULL;
+      }
+
+   }
+
+   /* Initialize Director TLS context */
+   if (dir->tls_enable || dir->tls_require) {
+      /* Generate passphrase prompt */
+      bsnprintf(buf, sizeof(buf), "Passphrase for Director \"%s\" TLS private key: ", dir->hdr.name);
+
+      /* Initialize TLS context:
+       * Args: CA certfile, CA certdir, Certfile, Keyfile,
+       * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
+      dir->tls_ctx = new_tls_context(dir->tls_ca_certfile,
+         dir->tls_ca_certdir, dir->tls_certfile,
+         dir->tls_keyfile, tls_pem_callback, &buf, NULL, true);
+
+      if (!dir->tls_ctx) {
+         bsnprintf(buf, sizeof(buf), _("Failed to initialize TLS context for Director \"%s\".\n"),
+            dir->hdr.name);
+         csprint(buf);
+         return NULL;
+      }
+   }
+
+
    UA_sock = bnet_connect(&jcr, 3, 3, "Director daemon",
-      res[directorchoosen-1]->address, NULL, res[directorchoosen-1]->DIRport, 0);
+      dir->address, NULL, dir->DIRport, 0);
       
    if (UA_sock == NULL) {
       csprint("Failed to connect to the director\n");
    csprint("Connected\n");
 
    jcr.dir_bsock = UA_sock;
-   LockRes();
-   /* If cons==NULL, default console will be used */
-   CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
-   UnlockRes();
-   if (!authenticate_director(&jcr, res[directorchoosen-1], cons)) {
+   if (!authenticate_director(&jcr, dir, cons)) {
       csprint("ERR=");
       csprint(UA_sock->msg);
       csprint(NULL, CS_END);