/* Timeout Hello after 5 mins */
btimer_t *tid = start_bsock_timer(dir, 60 * 5);
- bnet_fsend(dir, hello, bashed_name);
+ dir->fsend(hello, bashed_name);
if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
!cram_md5_challenge(dir, password, tls_local_need, compatible)) {
* be dropped here if an invalid client certificate was presented
*/
Dmsg1(6, ">dird: %s", dir->msg);
- if (bnet_recv(dir) <= 0) {
+ if (dir->recv() <= 0) {
senditf(_("Bad response to Hello command: ERR=%s\n"),
- bnet_strerror(dir));
+ dir->bstrerror());
goto bail_out;
}
int compatible = true;
char bashed_name[MAX_NAME_LENGTH];
char *password;
+ TLS_CONTEXT *tls_ctx = NULL;
/*
* Send my name to the Director then do authentication
bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name));
bash_spaces(bashed_name);
password = cons->password;
+ /* TLS Requirement */
+ if (cons->tls_enable) {
+ if (cons->tls_require) {
+ tls_local_need = BNET_TLS_REQUIRED;
+ } else {
+ tls_local_need = BNET_TLS_OK;
+ }
+ }
+
+ tls_ctx = cons->tls_ctx;
} else {
bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name));
password = director->password;
+ /* TLS Requirement */
+ if (director->tls_enable) {
+ if (director->tls_require) {
+ tls_local_need = BNET_TLS_REQUIRED;
+ } else {
+ tls_local_need = BNET_TLS_OK;
+ }
+ }
+
+ tls_ctx = director->tls_ctx;
}
- /* Timeout Hello after 5 mins */
- btimer_t *tid = start_bsock_timer(dir, 60 * 5);
- bnet_fsend(dir, hello, bashed_name);
+ /* Timeout Hello after 30 secs */
+ btimer_t *tid = start_bsock_timer(dir, 30);
+ dir->fsend(hello, bashed_name);
/* respond to Dir challenge */
if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
/* Now challenge dir */
!cram_md5_challenge(dir, password, tls_local_need, compatible)) {
- stop_bsock_timer(tid);
printf(_("%s: Director authorization problem.\n"), my_name);
display_text(_("Director authorization problem.\n"));
- display_text(_(
- "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
- return false;
+ goto bail_out;
+ }
+
+ /* 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) {
+ display_text(_("Authorization problem:"
+ " Remote server did not advertise required TLS support.\n"));
+ goto bail_out;
+ }
+
+ /* 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) {
+ display_text(_("Authorization problem:"
+ " Remote server requires TLS.\n"));
+ goto bail_out;
+ }
+
+ /* 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)) {
+ display_text(_("TLS negotiation failed\n"));
+ goto bail_out;
+ }
+ }
}
Dmsg1(6, ">dird: %s", dir->msg);
- if (bnet_recv(dir) <= 0) {
+ if (dir->recv() <= 0) {
stop_bsock_timer(tid);
display_textf(_("Bad response to Hello command: ERR=%s\n"),
- bnet_strerror(dir));
+ dir->bstrerror());
printf(_("%s: Bad response to Hello command: ERR=%s\n"),
- my_name, bnet_strerror(dir));
+ my_name, dir->bstrerror());
display_text(_("The Director is probably not running.\n"));
return false;
}
+
stop_bsock_timer(tid);
Dmsg1(10, "<dird: %s", dir->msg);
if (strncmp(dir->msg, OKhello, sizeof(OKhello)-1) != 0) {
display_text(dir->msg);
}
return true;
+
+bail_out:
+ stop_bsock_timer(tid);
+ display_text(_("Director authorization problem.\n"
+ "Most likely the passwords do not agree.\n"
+ "If you are using TLS, there may have been a certificate validation error during the TLS handshake.\n"
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
+ return false;
}
#include "select.h"
#include "run/run.h"
+static int tls_pem_callback(char *buf, int size, const void *userdata);
+
+
Console::Console(QStackedWidget *parent)
{
QFont font;
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) {
+ display_textf(_("Failed to initialize TLS context for Console \"%s\".\n"),
+ m_dir->hdr.name);
+ return;
+ }
+ }
+
+ /* Initialize Director TLS context */
+ if (m_dir->tls_enable || m_dir->tls_require) {
+ /* Generate passphrase prompt */
+ bsnprintf(buf, sizeof(buf), "Passphrase for Director \"%s\" TLS private key: ",
+ m_dir->hdr.name);
+
+ /* Initialize TLS context:
+ * Args: CA certfile, CA certdir, Certfile, Keyfile,
+ * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
+ m_dir->tls_ctx = new_tls_context(m_dir->tls_ca_certfile,
+ m_dir->tls_ca_certdir, m_dir->tls_certfile,
+ m_dir->tls_keyfile, tls_pem_callback, &buf, NULL, true);
+
+ if (!m_dir->tls_ctx) {
+ display_textf(_("Failed to initialize TLS context for Director \"%s\".\n"),
+ m_dir->hdr.name);
+ mainWin->set_status("Connection failed");
+ return;
+ }
+ }
+
if (m_dir->heartbeat_interval) {
heart_beat = m_dir->heartbeat_interval;
} else if (cons) {
return true;
}
}
+
+/*
+ * 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;
+# if defined(HAVE_WIN32)
+ sendit(prompt);
+ if (win32_cgets(buf, size) == NULL) {
+ buf[0] = 0;
+ return 0;
+ } else {
+ return strlen(buf);
+ }
+# else
+ char *passwd;
+
+ passwd = getpass(prompt);
+ bstrncpy(buf, passwd, size);
+ return strlen(buf);
+# endif
+#else
+ buf[0] = 0;
+ return 0;
+#endif
+}
#undef VERSION
#define VERSION "2.1.11"
-#define BDATE "20 May 2007"
-#define LSMDATE "20May07"
+#define BDATE "21 May 2007"
+#define LSMDATE "21May07"
#define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
#define BYEAR "2007" /* year for copyright messages in progs */
-/*
- *
- * Bacula UA authentication. Provides authentication with
- * the Director.
- *
- * Kern Sibbald, June MMI
- *
- * This routine runs as a thread and must be thread reentrant.
- *
- * Basic tasks done here:
- *
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2001-2007 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ *
+ * Bacula UA authentication. Provides authentication with
+ * the Director.
+ *
+ * Kern Sibbald, June MMI
+ *
+ * This routine runs as a thread and must be thread reentrant.
+ *
+ * Basic tasks done here:
+ *
+ */
/* _("...") macro returns a wxChar*, so if we need a char*, we need to convert it with:
* wxString(_("...")).mb_str(*wxConvCurrent) */
General:
21May07
+kes Begin adding TLS support to bat.
kes Apply UTF-8/16 patch from Yves Orton <demerphq@gmail.com> to
clean up lex.c and make it more readable.
20May07