--- /dev/null
+
+ Bacula Support request form. Please fill it out and email it to
+ bacula-users@lists.sourceforge.net
+
+Bacula version:
+
+OS type and version:
+
+How was Bacula built/installed? Source, rpms, ... be specific.
+
+Concise description of the problem:
+
+
+Bacula output showing the problem:
+
+
+Steps to reproduce the problem:
+
+
+
+Other information (optional):
+A copy of your config.out file (if built from source)
+
+Tape drive/autochanger (for tape problems):
+
+Have you run btape "test" command?
+
+Database problems: what database are you using?
+What is the database version?
+
+If the output involves configuration files, consider attaching
+bacula-dir.conf, bacula-fd.conf, and bacula-sd.conf if necessary,
+appropriate.
File.FilenameId=(FilenameId-from-above) and File.PathId=Path.PathId
order by Path.Path ASC;
+- Look into using Dart for testing
+ http://public.kitware.com/Dart/HTML/Index.shtml
+- Look into replacing autotools with cmake
+ http://www.cmake.org/HTML/Index.html
=== Migration from David ===
What I'd like to see:
- Make Dir and SD authentication errors single threaded.
- Install man pages
- Fix catreq.c digestbuf at line 411 in src/dird/catreq.c
-
Kern Sibbald
General:
+04Jul06
+ ======================= Warning ==========================
+ All hash codes in the database are now kept in world
+ compatible base64 format (no = filling). This means that
+ all FileSets will be updated and if you are running
+ verify jobs, you must do an InitCatalog.
+ Authentication uses the new algorithm, but should be
+ backward compatible with 1.38.x
+ ===========================================================
+
+- Modify the authentication routines so that the 1.39.15 Director
+ always runs with the compatible binary to base64 code (same as
+ the rest of the world). It will however detect if an SD or
+ FD is running the old code and if that is the case, will use
+ the old algorithm for authentication. However, all consoles must
+ use the compatible algorithm, and all data entered into the database
+ (all hash signatures, MD5, SHA1, ..., and all FileSet hashes) will
+ use the compatible algorithm.
+- Rename the cram_md5 routine names to be slightly more appropriate
+ to what they are doing (challenge and respond).
+- Robert committed his #ifdef and header cleanup.
+
30Jun06
- Fix a complier warning in files/backup.c
- Cleanup NOT NULL vs DEFALT 0 in database creation.
--- /dev/null
+Makefile
+bacula
+bacula-dir
+bacula-fd
+bacula-sd
+bacula.spec
*
*/
/*
- Copyright (C) 2001-2005 Kern Sibbald
+ Copyright (C) 2001-2006 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
BSOCK *dir = jcr->dir_bsock;
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true;
char bashed_name[MAX_NAME_LENGTH];
char *password;
TLS_CONTEXT *tls_ctx = NULL;
btimer_t *tid = start_bsock_timer(dir, 60 * 5);
bnet_fsend(dir, hello, bashed_name);
- if (!cram_md5_get_auth(dir, password, &tls_remote_need) ||
- !cram_md5_auth(dir, password, tls_local_need)) {
+ if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
+ !cram_md5_challenge(dir, password, tls_local_need, compatible)) {
goto bail_out;
}
$(CXX) $(WLDFLAGS) $(LDFLAGS) -L../lib -L../cats -L../findlib -o $@ $(SVROBJS) \
-lsql -lfind -lbac -lm $(PYTHON_LIBS) $(DLIB) $(DB_LIBS) $(LIBS) \
$(WRAPLIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS)
+
static-bacula-dir: $(SVROBJS) ../lib/libbac.a ../cats/libsql.a ../findlib/libfind.a
$(CXX) $(WLDFLAGS) $(LDFLAGS) -static -L../lib -L../cats -L../findlib -o $@ $(SVROBJS) \
char dirname[MAX_NAME_LENGTH];
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true;
bool auth_success = false;
/*
}
}
- auth_success = cram_md5_get_auth(sd, store->password, &tls_remote_need);
+ auth_success = cram_md5_respond(sd, store->password, &tls_remote_need, &compatible);
if (auth_success) {
- auth_success = cram_md5_auth(sd, store->password, tls_local_need);
+ auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible);
if (!auth_success) {
- Dmsg1(50, "cram_auth failed for %s\n", sd->who);
+ Dmsg1(50, "cram_challenge failed for %s\n", sd->who);
}
} else {
- Dmsg1(50, "cram_get_auth failed for %s\n", sd->who);
+ Dmsg1(50, "cram_respond failed for %s\n", sd->who);
}
if (!auth_success) {
return 0;
}
-#ifdef HAVE_TLS
/* Is TLS Enabled? */
if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
/* Engage TLS! Full Speed Ahead! */
return 0;
}
}
-#endif
Dmsg1(116, ">stored: %s", sd->msg);
if (bnet_recv(sd) <= 0) {
char dirname[MAX_NAME_LENGTH];
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true;
bool auth_success = false;
/*
return 0;
}
-#ifdef HAVE_TLS
/* TLS Requirement */
if (client->tls_enable) {
if (client->tls_require) {
tls_local_need = BNET_TLS_OK;
}
}
-#endif
- auth_success = cram_md5_get_auth(fd, client->password, &tls_remote_need);
+ auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
if (auth_success) {
- auth_success = cram_md5_auth(fd, client->password, tls_local_need);
+ 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);
}
return 0;
}
-#ifdef HAVE_TLS
/* Is TLS Enabled? */
if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
/* Engage TLS! Full Speed Ahead! */
return 0;
}
}
-#endif
Dmsg1(116, ">filed: %s", fd->msg);
if (bnet_recv(fd) <= 0) {
char name[MAX_NAME_LENGTH];
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true;
CONRES *cons = NULL;
BSOCK *ua = uac->UA_sock;
bool auth_success = false;
-#ifdef HAVE_TLS
TLS_CONTEXT *tls_ctx = NULL;
alist *verify_list = NULL;
-#endif /* HAVE_TLS */
// Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
name[sizeof(name)-1] = 0; /* terminate name */
if (strcmp(name, "*UserAgent*") == 0) { /* default console */
-#ifdef HAVE_TLS
/* TLS Requirement */
if (director->tls_enable) {
if (director->tls_require) {
if (director->tls_verify_peer) {
verify_list = director->tls_allowed_cns;
}
-#endif /* HAVE_TLS */
- auth_success = cram_md5_auth(ua, director->password, tls_local_need) &&
- cram_md5_get_auth(ua, director->password, &tls_remote_need);
+ auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
+ compatible) &&
+ cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
} else {
unbash_spaces(name);
cons = (CONRES *)GetResWithName(R_CONSOLE, name);
if (cons) {
-#ifdef HAVE_TLS
/* TLS Requirement */
if (cons->tls_enable) {
if (cons->tls_require) {
if (cons->tls_verify_peer) {
verify_list = cons->tls_allowed_cns;
}
-#endif /* HAVE_TLS */
- auth_success = cram_md5_auth(ua, cons->password, tls_local_need) &&
- cram_md5_get_auth(ua, cons->password, &tls_remote_need);
+ auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
+ compatible) &&
+ cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
if (auth_success) {
uac->cons = cons; /* save console resource pointer */
goto auth_done;
}
-#ifdef HAVE_TLS
if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
if (cons) {
tls_ctx = cons->tls_ctx;
goto auth_done;
}
}
-#endif /* HAVE_TLS */
/* Authorization Completed */
Stream);
}
- bin_to_base64(digestbuf, fname, len);
+ bin_to_base64(digestbuf, sizeof(digestbuf), fname, len, true);
Dmsg3(400, "DigestLen=%d Digest=%s type=%d\n", strlen(digestbuf), digestbuf, Stream);
if (jcr->cached_attribute) {
ar->Digest = digestbuf;
unsigned char digest[MD5HashSize];
memcpy(&md5c, &jcr->fileset->md5c, sizeof(md5c));
MD5Final(digest, &md5c);
- bin_to_base64(fsr.MD5, (char *)digest, MD5HashSize);
+ bin_to_base64(fsr.MD5, sizeof(fsr.MD5), (char *)digest, MD5HashSize, true);
bstrncpy(jcr->fileset->MD5, fsr.MD5, sizeof(jcr->fileset->MD5));
} else {
Jmsg(jcr, M_WARNING, 0, _("FileSet MD5 digest not found.\n"));
*
*/
/*
- Copyright (C) 2000-2005 Kern Sibbald
+ Copyright (C) 2000-2006 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
DIRRES *director = NULL;
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true; /* Want md5 compatible DIR */
bool auth_success = false;
alist *verify_list = NULL;
btimer_t *tid = NULL;
Emsg1(M_FATAL, 0, _("I only authenticate directors, not %d\n"), rcode);
goto auth_fatal;
}
- if (bs->msglen < 25 || bs->msglen > 200) {
+ if (bs->msglen < 25 || bs->msglen > 500) {
Dmsg2(50, "Bad Hello command from Director at %s. Len=%d.\n",
bs->who, bs->msglen);
char addr[64];
}
dirname = check_pool_memory_size(dirname, bs->msglen);
- if (sscanf(bs->msg, "Hello Director %s calling\n", dirname) != 1) {
+ if (sscanf(bs->msg, "Hello Director %s calling", dirname) != 1) {
char addr[64];
char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
bs->msg[100] = 0;
goto auth_fatal;
}
unbash_spaces(dirname);
- LockRes();
foreach_res(director, R_DIRECTOR) {
if (strcmp(director->hdr.name, dirname) == 0)
break;
}
- UnlockRes();
if (!director) {
char addr[64];
char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
}
tid = start_bsock_timer(bs, AUTH_TIMEOUT);
- auth_success = cram_md5_auth(bs, director->password, tls_local_need);
+ /* Challenge the director */
+ auth_success = cram_md5_challenge(bs, director->password, tls_local_need, compatible);
if (auth_success) {
- auth_success = cram_md5_get_auth(bs, director->password, &tls_remote_need);
+ auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
if (!auth_success) {
char addr[64];
char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
BSOCK *sd = jcr->store_bsock;
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true;
bool auth_success = false;
btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
}
}
- auth_success = cram_md5_get_auth(sd, jcr->sd_auth_key, &tls_remote_need);
+ /* Respond to SD challenge */
+ auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
if (!auth_success) {
- Dmsg1(50, "cram_get_auth failed for %s\n", sd->who);
+ Dmsg1(50, "cram_respond failed for %s\n", sd->who);
} else {
- auth_success = cram_md5_auth(sd, jcr->sd_auth_key, tls_local_need);
+ /* Now challenge him */
+ auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
if (!auth_success) {
- Dmsg1(50, "cram_auth failed for %s\n", sd->who);
+ Dmsg1(50, "cram_challenge failed for %s\n", sd->who);
}
}
digest_buf = (char *)malloc(BASE64_SIZE(size));
digest_name = crypto_digest_name(digest);
- bin_to_base64(digest_buf, md, size);
+ bin_to_base64(digest_buf, BASE64_SIZE(size), md, size, true);
Dmsg3(400, "send inx=%d %s=%s\n", jcr->JobFiles, digest_name, digest_buf);
bnet_fsend(dir, "%d %d %s *%s-%d*", jcr->JobFiles, digest_stream, digest_buf,
digest_name, jcr->JobFiles);
break;
case STREAM_MD5_DIGEST:
- bin_to_base64(digest, (char *)sd->msg, CRYPTO_DIGEST_MD5_SIZE);
+ bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_MD5_SIZE, true);
Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, digest);
bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_DIGEST, digest,
jcr->JobFiles);
break;
case STREAM_SHA1_DIGEST:
- bin_to_base64(digest, (char *)sd->msg, CRYPTO_DIGEST_SHA1_SIZE);
+ bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA1_SIZE, true);
Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, digest);
bnet_fsend(dir, "%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_DIGEST,
digest, jcr->JobFiles);
break;
case STREAM_SHA256_DIGEST:
- bin_to_base64(digest, (char *)sd->msg, CRYPTO_DIGEST_SHA256_SIZE);
+ bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA256_SIZE, true);
Dmsg2(400, "send inx=%d SHA256=%s\n", jcr->JobFiles, digest);
bnet_fsend(dir, "%d %d %s *SHA256-%d*", jcr->JobFiles, STREAM_SHA256_DIGEST,
digest, jcr->JobFiles);
break;
case STREAM_SHA512_DIGEST:
- bin_to_base64(digest, (char *)sd->msg, CRYPTO_DIGEST_SHA512_SIZE);
+ bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA512_SIZE, true);
Dmsg2(400, "send inx=%d SHA512=%s\n", jcr->JobFiles, digest);
bnet_fsend(dir, "%d %d %s *SHA512-%d*", jcr->JobFiles, STREAM_SHA512_DIGEST,
digest, jcr->JobFiles);
BSOCK *dir = jcr->dir_bsock;
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true;
char bashed_name[MAX_NAME_LENGTH];
char *password;
btimer_t *tid = start_bsock_timer(dir, 60 * 5);
bnet_fsend(dir, hello, bashed_name);
- if (!cram_md5_get_auth(dir, password, &tls_remote_need) ||
- !cram_md5_auth(dir, password, tls_local_need)) {
+ /* 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);
set_text(_("Director authorization problem.\n"), -1);
GtkWidget *dir_select;
GtkWidget *about1; /* about box */
GtkWidget *label_dialog;
-PangoFontDescription *font_desc;
-PangoFontDescription *console_font_desc = NULL;
+PangoFontDescription *font_desc = NULL;
+PangoFontDescription *text_font_desc = NULL;
pthread_mutex_t cmd_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cmd_wait;
char cmd[1000];
continue;
}
Dmsg1(100, "Now loading: %s\n",con_font->fontface);
- console_font_desc = pango_font_description_from_string(con_font->fontface);
- if (console_font_desc == NULL) {
+ text_font_desc = pango_font_description_from_string(con_font->fontface);
+ if (text_font_desc == NULL) {
Dmsg2(400, "Load of requested ConsoleFont \"%s\" (%s) failed!\n",
con_font->hdr.name, con_font->fontface);
} else {
}
}
UnlockRes();
-
+
font_desc = pango_font_description_from_string("LucidaTypewriter 9");
+ if (!text_font_desc) {
+ text_font_desc = pango_font_description_from_string("Monospace 10");
+ }
+ if (!text_font_desc) {
+ text_font_desc = pango_font_description_from_string("monospace");
+ }
+
gtk_widget_modify_font(console, font_desc);
gtk_widget_modify_font(entry1, font_desc);
gtk_widget_modify_font(status1, font_desc);
- if (console_font_desc) {
- gtk_widget_modify_font(text1, console_font_desc);
- pango_font_description_free(console_font_desc);
+ if (text_font_desc) {
+ gtk_widget_modify_font(text1, text_font_desc);
+ pango_font_description_free(text_font_desc);
} else {
gtk_widget_modify_font(text1, font_desc);
}
return 1;
}
+#if defined(HAVE_WIN32)
static void strip_double_slashes(char *fname)
{
char *p = fname;
}
}
}
+#endif
/*
* Build attr->ofname from attr->fname and
#include "bacula.h"
-/*
- * If compatible is true, the bin_to_base64 routine will be compatible
- * with what the rest of the world uses. However, this would destroy
- * existing database compatibility.
- */
-const bool compatible = false;
#ifdef TEST_MODE
#include <glob.h>
* Encode binary data in bin of len bytes into
* buf as base64 characters.
*
+ * If compatible is true, the bin_to_base64 routine will be compatible
+ * with what the rest of the world uses.
+ *
* Returns: the number of characters stored not
* including the EOS
*/
int
-bin_to_base64(char *buf, char *bin, int len)
+bin_to_base64(char *buf, int buflen, char *bin, int binlen, int compatible)
{
uint32_t reg, save, mask;
int rem, i;
reg = 0;
rem = 0;
- for (i=0; i<len; ) {
+ buflen--; /* allow for storing EOS */
+ for (i=0; i < binlen; ) {
if (rem < 6) {
reg <<= 8;
if (compatible) {
}
save = reg;
reg >>= (rem - 6);
- buf[j++] = base64_digits[reg & 0x3F];
+ if (j < buflen) {
+ buf[j++] = base64_digits[reg & 0x3F];
+ }
reg = save;
rem -= 6;
}
- if (rem) {
-#ifdef OLDxxxx
- mask = 1;
- for (i=1; i<rem; i++) {
- mask = (mask << 1) | 1;
- }
-#else
+ if (rem && j < buflen) {
mask = (1 << rem) - 1;
-#endif
if (compatible) {
buf[j++] = base64_digits[(reg & mask) << 6 - rem];
} else {
#ifdef xxxx
for (i=0; i < 1000; i++) {
- bin_to_base64(buf, (char *)&xx, 4);
+ bin_to_base64(buf, sizeof(buf), (char *)&xx, 4, true);
printf("xx=%s\n", buf);
xx++;
}
for (i=1; i<100; i++) {
junk[i] = junk[i-1]-1;
}
- len = bin_to_base64(buf, junk, 16);
+ len = bin_to_base64(buf, sizeof(buf) junk, 16, true);
printf("len=%d junk=%s\n", len, buf);
return 0;
}
/*
* Establish a TLS connection -- server side
- * Returns: 1 on success
- * 0 failure
+ * Returns: true on success
+ * false on failure
*/
#ifdef HAVE_TLS
-int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
+bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
{
TLS_CONNECTION *tls;
tls = new_tls_connection(ctx, bsock->fd);
if (!tls) {
Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
- return 0;
+ return false;
}
bsock->tls = tls;
goto err;
}
}
-
- return 1;
+ return true;
err:
free_tls_connection(tls);
bsock->tls = NULL;
- return 0;
+ return false;
}
/*
* Establish a TLS connection -- client side
- * Returns: 1 on success
- * 0 failure
+ * Returns: true on success
+ * false on failure
*/
-int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
+bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
{
TLS_CONNECTION *tls;
tls = new_tls_connection(ctx, bsock->fd);
if (!tls) {
Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
- return 0;
+ return false;
}
bsock->tls = tls;
Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), bsock->host);
goto err;
}
-
- return 1;
+ return true;
err:
free_tls_connection(tls);
bsock->tls = NULL;
- return 0;
+ return false;
}
#else
-int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
+bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
{
- Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n"));
- return 0;
+ Jmsg(bsock->jcr, M_ABORT, 0, _("TLS enabled but not configured.\n"));
+ return false;
}
-int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
+bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
{
- Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n"));
- return 0;
+ Jmsg(bsock->jcr, M_ABORT, 0, _("TLS enable but not configured.\n"));
+ return false;
}
#endif /* HAVE_TLS */
int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) {
#if !defined(HAVE_WIN32)
if (bs->peer_addr.sin_family == 0) {
- socklen_t salen = sizeof(bs->peer_addr);
- int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
- if (rval < 0) return rval;
+ socklen_t salen = sizeof(bs->peer_addr);
+ int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
+ if (rval < 0) return rval;
}
if (!inet_ntop(bs->peer_addr.sin_family, &bs->peer_addr.sin_addr, buf, buflen))
- return -1;
+ return -1;
return 0;
#else
* BNET_TLS_NONE I cannot do tls
* BNET_TLS_OK I can do tls, but it is not required on my end
* BNET_TLS_REQUIRED tls is required on my end
+ *
+ * Returns: false if authentication failed
+ * true if OK
*/
-int cram_md5_auth(BSOCK *bs, char *password, int tls_local_need)
+bool cram_md5_challenge(BSOCK *bs, char *password, int tls_local_need, int compatible)
{
struct timeval t1;
struct timeval t2;
struct timezone tz;
- int i, ok;
+ int i;
+ bool ok;
char chal[MAXSTRING];
char host[MAXSTRING];
uint8_t hmac[20];
if (!gethostname(host, sizeof(host))) {
bstrncpy(host, my_name, sizeof(host));
}
+ /* Send challenge -- no hashing yet */
bsnprintf(chal, sizeof(chal), "<%u.%u@%s>", (uint32_t)random(), (uint32_t)time(NULL), host);
Dmsg2(50, "send: auth cram-md5 %s ssl=%d\n", chal, tls_local_need);
- if (!bnet_fsend(bs, "auth cram-md5 %s ssl=%d\n", chal, tls_local_need)) {
- Dmsg1(50, "Bnet send challenge error.\n", bnet_strerror(bs));
- return 0;
+ if (compatible) {
+ if (!bnet_fsend(bs, "auth cram-md5c %s ssl=%d\n", chal, tls_local_need)) {
+ Dmsg1(50, "Bnet send challenge error.\n", bnet_strerror(bs));
+ return false;
+ }
+ } else {
+ /* Old non-compatible system */
+ if (!bnet_fsend(bs, "auth cram-md5 %s ssl=%d\n", chal, tls_local_need)) {
+ Dmsg1(50, "Bnet send challenge error.\n", bnet_strerror(bs));
+ return false;
+ }
}
+ /* Read hashed response to challenge */
if (bnet_wait_data(bs, 180) <= 0 || bnet_recv(bs) <= 0) {
Dmsg1(50, "Bnet receive challenge response error.\n", bnet_strerror(bs));
bmicrosleep(5, 0);
- return 0;
+ return false;
}
+
+ /* Attempt to duplicate hash with our password */
hmac_md5((uint8_t *)chal, strlen(chal), (uint8_t *)password, strlen(password), hmac);
- bin_to_base64(host, (char *)hmac, 16);
-// Dmsg3(100, "auth: chal=%s pw=%s hmac=%s\n", chal, password, host);
+ bin_to_base64(host, sizeof(host), (char *)hmac, 16, compatible);
ok = strcmp(bs->msg, host) == 0;
if (ok) {
Dmsg1(50, "Authenticate OK %s\n", host);
return ok;
}
-/* Get authorization from other end */
-int cram_md5_get_auth(BSOCK *bs, char *password, int *tls_remote_need)
+/* Respond to challenge from other end */
+bool cram_md5_respond(BSOCK *bs, char *password, int *tls_remote_need, int *compatible)
{
char chal[MAXSTRING];
uint8_t hmac[20];
+ *compatible = false;
if (bnet_recv(bs) <= 0) {
bmicrosleep(5, 0);
- return 0;
+ return false;
}
if (bs->msglen >= MAXSTRING) {
Dmsg1(50, "Msg too long wanted auth cram... Got: %s", bs->msg);
bmicrosleep(5, 0);
- return 0;
+ return false;
}
Dmsg1(100, "cram-get: %s", bs->msg);
- if (sscanf(bs->msg, "auth cram-md5 %s ssl=%d\n", chal, tls_remote_need) != 2) {
+ if (sscanf(bs->msg, "auth cram-md5c %s ssl=%d", chal, tls_remote_need) == 2) {
+ *compatible = true;
+ } else if (sscanf(bs->msg, "auth cram-md5 %s ssl=%d", chal, tls_remote_need) != 2) {
if (sscanf(bs->msg, "auth cram-md5 %s\n", chal) != 1) {
Dmsg1(50, "Cannot scan challenge: %s", bs->msg);
bnet_fsend(bs, _("1999 Authorization failed.\n"));
bmicrosleep(5, 0);
- return 0;
+ return false;
}
}
hmac_md5((uint8_t *)chal, strlen(chal), (uint8_t *)password, strlen(password), hmac);
- bs->msglen = bin_to_base64(bs->msg, (char *)hmac, 16) + 1;
+ bs->msglen = bin_to_base64(bs->msg, 50, (char *)hmac, 16, *compatible) + 1;
// Dmsg3(100, "get_auth: chal=%s pw=%s hmac=%s\n", chal, password, bs->msg);
if (!bnet_send(bs)) {
Dmsg1(50, "Send challenge failed. ERR=%s\n", bnet_strerror(bs));
- return 0;
+ return false;
}
Dmsg1(99, "sending resp to challenge: %s\n", bs->msg);
if (bnet_wait_data(bs, 180) <= 0 || bnet_recv(bs) <= 0) {
Dmsg1(50, "Receive chanllenge response failed. ERR=%s\n", bnet_strerror(bs));
bmicrosleep(5, 0);
- return 0;
+ return false;
}
if (strcmp(bs->msg, "1000 OK auth\n") == 0) {
- return 1;
+ return true;
}
Dmsg1(50, "Bad auth response: %s\n", bs->msg);
bmicrosleep(5, 0);
- return 0;
+ return false;
}
#ifdef OUTPUT_BASE64
char MD5buf[40]; /* 24 should do */
memset(MD5buf, 0, 40);
- bin_to_base64(MD5buf, (char *)signature, 16); /* encode 16 bytes */
+ bin_to_base64(MD5buf, sizeof(MD5buf), (char *)signature, 16, true); /* encode 16 bytes */
printf(" %s", MD5buf);
#endif
printf(" %s\n", argv[0]);
}
signature[16] = 0;
printf("%s", buf);
- bin_to_base64(bin, (char *)signature, 16);
+ bin_to_base64(bin, sizeof(bin), (char *)signature, 16, true);
printf("%s\n", bin);
}
}
void base64_init (void);
int to_base64 (intmax_t value, char *where);
int from_base64 (intmax_t *value, char *where);
-int bin_to_base64 (char *buf, char *bin, int len);
+int bin_to_base64 (char *buf, int buflen, char *bin, int binlen,
+ int compatible);
/* bsys.c */
char *bstrncpy (char *dest, const char *src, int maxlen);
bool bnet_fsend (BSOCK *bs, const char *fmt, ...);
bool bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw);
bool bnet_sig (BSOCK *bs, int sig);
-int bnet_tls_server (TLS_CONTEXT *ctx, BSOCK *bsock,
+bool bnet_tls_server (TLS_CONTEXT *ctx, BSOCK *bsock,
alist *verify_list);
-int bnet_tls_client (TLS_CONTEXT *ctx, BSOCK *bsock);
+bool bnet_tls_client (TLS_CONTEXT *ctx, BSOCK *bsock);
BSOCK * bnet_connect (JCR *jcr, int retry_interval,
int max_retry_time, const char *name, char *host, char *service,
int port, int verbose);
int close_bpipe(BPIPE *bpipe);
/* cram-md5.c */
-int cram_md5_get_auth(BSOCK *bs, char *password, int *tls_remote_need);
-int cram_md5_auth(BSOCK *bs, char *password, int tls_local_need);
-void hmac_md5(uint8_t* text, int text_len, uint8_t* key,
- int key_len, uint8_t *hmac);
+bool cram_md5_respond(BSOCK *bs, char *password, int *tls_remote_need, int *compatible);
+bool cram_md5_challenge(BSOCK *bs, char *password, int tls_local_need, int compatible);
+void hmac_md5(uint8_t* text, int text_len, uint8_t* key, int key_len, uint8_t *hmac);
/* crc32.c */
*
* Version $Id$
*
- * Copyright (C) 2005 Kern Sibbald
+ * Copyright (C) 2005-2006 Kern Sibbald
*
* This file was contributed to the Bacula project by Landon Fuller
* and Three Rings Design, Inc.
*
*/
/*
- Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+ Copyright (C) 2000-2006 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.
+ modify it under the terms of the GNU General Public License
+ 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.
-
- 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.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional details.
*/
DIRRES *director = NULL;
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true; /* require md5 compatible DIR */
bool auth_success = false;
-#ifdef HAVE_TLS
alist *verify_list = NULL;
-#endif
if (rcode != R_DIRECTOR) {
Dmsg1(50, "I only authenticate Directors, not %d\n", rcode);
Emsg1(M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode);
return 0;
}
- if (bs->msglen < 25 || bs->msglen > 200) {
+ if (bs->msglen < 25 || bs->msglen > 500) {
Dmsg2(50, "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"),
dirname = get_pool_memory(PM_MESSAGE);
dirname = check_pool_memory_size(dirname, bs->msglen);
- if (sscanf(bs->msg, "Hello Director %127s calling\n", dirname) != 1) {
+ if (sscanf(bs->msg, "Hello Director %127s calling", dirname) != 1) {
bs->msg[100] = 0;
Dmsg2(50, "Bad Hello command from Director at %s: %s\n",
bs->who, bs->msg);
}
director = NULL;
unbash_spaces(dirname);
-// LockRes();
foreach_res(director, rcode) {
if (strcmp(director->hdr.name, dirname) == 0)
break;
}
-// UnlockRes();
if (!director) {
Dmsg2(50, "Connection from unknown Director %s at %s rejected.\n",
dirname, bs->who);
return 0;
}
-#ifdef HAVE_TLS
/* TLS Requirement */
if (director->tls_enable) {
if (director->tls_require) {
if (director->tls_verify_peer) {
verify_list = director->tls_allowed_cns;
}
-#endif /* HAVE_TLS */
/* Timeout Hello after 10 mins */
btimer_t *tid = start_bsock_timer(bs, AUTH_TIMEOUT);
- auth_success = cram_md5_auth(bs, director->password, tls_local_need);
+ auth_success = cram_md5_challenge(bs, director->password, tls_local_need, compatible);
if (auth_success) {
- auth_success = cram_md5_get_auth(bs, director->password, &tls_remote_need);
+ auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
if (!auth_success) {
Dmsg1(50, "cram_get_auth failed with %s\n", bs->who);
}
goto auth_fatal;
}
-#ifdef 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)) {
goto auth_fatal;
}
}
-#endif /* HAVE_TLS */
auth_fatal:
stop_bsock_timer(tid);
BSOCK *fd = jcr->file_bsock;
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true; /* require md5 compatible FD */
bool auth_success = false;
-#ifdef HAVE_TLS
alist *verify_list = NULL;
-#endif
-#ifdef HAVE_TLS
/* TLS Requirement */
if (me->tls_enable) {
if (me->tls_require) {
if (me->tls_verify_peer) {
verify_list = me->tls_allowed_cns;
}
-#endif /* HAVE_TLS */
/* Timeout Hello after 5 mins */
btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
- auth_success = cram_md5_auth(fd, jcr->sd_auth_key, tls_local_need);
+ /* Challenge FD */
+ auth_success = cram_md5_challenge(fd, jcr->sd_auth_key, tls_local_need, compatible);
if (auth_success) {
- auth_success = cram_md5_get_auth(fd, jcr->sd_auth_key, &tls_remote_need);
+ /* Respond to his challenge */
+ auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible);
if (!auth_success) {
Dmsg1(50, "cram-get-auth failed with %s\n", fd->who);
}
goto auth_fatal;
}
-#ifdef HAVE_TLS
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)) {
goto auth_fatal;
}
}
-#endif /* HAVE_TLS */
auth_fatal:
stop_bsock_timer(tid);
break;
case STREAM_MD5_DIGEST:
- bin_to_base64(digest, (char *)rec->data, CRYPTO_DIGEST_MD5_SIZE);
+ bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_MD5_SIZE, true);
if (verbose > 1) {
Pmsg1(000, _("Got MD5 record: %s\n"), digest);
}
break;
case STREAM_SHA1_DIGEST:
- bin_to_base64(digest, (char *)rec->data, CRYPTO_DIGEST_SHA1_SIZE);
+ bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA1_SIZE, true);
if (verbose > 1) {
Pmsg1(000, _("Got SHA1 record: %s\n"), digest);
}
break;
case STREAM_SHA256_DIGEST:
- bin_to_base64(digest, (char *)rec->data, CRYPTO_DIGEST_SHA256_SIZE);
+ bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA256_SIZE, true);
if (verbose > 1) {
Pmsg1(000, _("Got SHA256 record: %s\n"), digest);
}
break;
case STREAM_SHA512_DIGEST:
- bin_to_base64(digest, (char *)rec->data, CRYPTO_DIGEST_SHA512_SIZE);
+ bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA512_SIZE, true);
if (verbose > 1) {
Pmsg1(000, _("Got SHA512 record: %s\n"), digest);
}
*
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2006 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"
BSOCK *dir = jcr->dir_bsock;
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true;
char bashed_name[MAX_NAME_LENGTH];
char *password;
btimer_t *tid = start_bsock_timer(dir, 60 * 5);
bnet_fsend(dir, DIRhello, bashed_name);
- if (!cram_md5_get_auth(dir, password, &tls_remote_need) ||
- !cram_md5_auth(dir, password, tls_local_need)) {
+ if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
+ !cram_md5_challenge(dir, password, tls_local_need, compatible)) {
stop_bsock_timer(tid);
Jmsg0(jcr, M_FATAL, 0, _("Director authorization problem.\n"
"Most likely the passwords do not agree.\n"
char dirname[MAX_NAME_LENGTH];
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true;
/*
* Send my name to the Storage daemon then do authentication
Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
return 0;
}
- if (!cram_md5_get_auth(sd, store->password, &tls_remote_need) ||
- !cram_md5_auth(sd, store->password, tls_local_need)) {
+ if (!cram_md5_respond(sd, store->password, &tls_remote_need, &compatible) ||
+ !cram_md5_challenge(sd, store->password, tls_local_need, compatible)) {
stop_bsock_timer(tid);
Jmsg0(jcr, M_FATAL, 0, _("Director and Storage daemon passwords or names not the same.\n"
"Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
char dirname[MAX_NAME_LENGTH];
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true;
/*
* Send my name to the File daemon then do authentication
Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon. ERR=%s\n"), bnet_strerror(fd));
return 0;
}
- if (!cram_md5_get_auth(fd, client->password, &tls_remote_need) ||
- !cram_md5_auth(fd, client->password, tls_local_need)) {
+ if (!cram_md5_respond(fd, client->password, &tls_remote_need, &compatible) ||
+ !cram_md5_challenge(fd, client->password, tls_local_need, compatible)) {
stop_bsock_timer(tid);
Jmsg(jcr, M_FATAL, 0, _("Director and File daemon passwords or names not the same.\n"
"Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
*/
#undef VERSION
-#define VERSION "1.39.14"
-#define BDATE "30 June 2006"
-#define LSMDATE "30Jun06"
+#define VERSION "1.39.15"
+#define BDATE "4 July 2006"
+#define LSMDATE "04Jul06"
/* Debug flags */
#undef DEBUG
Makefile
bacula.ncb
bacula.suo
+1
+2
+3
+mingwm10.dll
BSOCK *dir = jcr->dir_bsock;
int tls_local_need = BNET_TLS_NONE;
int tls_remote_need = BNET_TLS_NONE;
+ int compatible = true;
char bashed_name[MAX_NAME_LENGTH];
char *password;
TLS_CONTEXT *tls_ctx = NULL;
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;
- }
+ if (cons->tls_require) {
+ tls_local_need = BNET_TLS_REQUIRED;
+ } else {
+ tls_local_need = BNET_TLS_OK;
+ }
}
tls_ctx = cons->tls_ctx;
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;
- }
+ if (director->tls_require) {
+ tls_local_need = BNET_TLS_REQUIRED;
+ } else {
+ tls_local_need = BNET_TLS_OK;
+ }
}
tls_ctx = director->tls_ctx;
btimer_t *tid = start_bsock_timer(dir, 60 * 5);
bnet_fsend(dir, hello, bashed_name);
- if (!cram_md5_get_auth(dir, password, &tls_remote_need) ||
- !cram_md5_auth(dir, password, tls_local_need)) {
+ if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
+ !cram_md5_challenge(dir, password, tls_local_need, compatible)) {
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) {
/* 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)) {
+ /* Engage TLS! Full Speed Ahead! */
+ if (!bnet_tls_client(tls_ctx, dir)) {
csprint(_("TLS negotiation failed\n"));
- goto bail_out;
- }
+ goto bail_out;
+ }
}
}