]> git.sur5r.net Git - bacula/bacula/commitdiff
- Harden authentication failure in FD by single threading errors
authorKern Sibbald <kern@sibbald.com>
Sat, 24 Jun 2006 10:06:24 +0000 (10:06 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 24 Jun 2006 10:06:24 +0000 (10:06 +0000)
  and forcing a 6 second wait.

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

bacula/kes-1.39
bacula/src/filed/authenticate.c
bacula/src/version.h

index 750b5d8616c66075ad21b482ff85861609f64939..cdde06eaafeff0e0ec01aed0d34d81238e4e832b 100644 (file)
@@ -3,6 +3,8 @@
 
 General:
 24Jun06
+- Harden authentication failure in FD by single threading errors
+  and forcing a 6 second wait.
 - ========= Remove Accept Any Volume ========= directive.
 - Major cleanup and simplification of regress using shell functions
   (more tests to be converted to new format)   
index c1165a3d1b4800f2b7328244562dfd11eb21d1ae..ddd12b02d77f9fb16cbd2fb789f77f674f8a6121 100644 (file)
 
 static char OK_hello[]  = "2000 OK Hello\n";
 static char Dir_sorry[] = "2999 No go\n";
-
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /*********************************************************************
  *
  */
 static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
 {
-   POOLMEM *dirname;
-   DIRRES *director;
+   POOLMEM *dirname = get_pool_memory(PM_MESSAGE);
+   DIRRES *director = NULL;
    int tls_local_need = BNET_TLS_NONE;
    int tls_remote_need = BNET_TLS_NONE;
    bool auth_success = false;
    alist *verify_list = NULL;
+   btimer_t *tid = NULL;
 
    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;
+      goto auth_fatal;
    }
    if (bs->msglen < 25 || bs->msglen > 200) {
       Dmsg2(50, "Bad Hello command from Director at %s. Len=%d.\n",
             bs->who, bs->msglen);
-       char addr[64];
-       char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
+      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"),
-            who, bs->msglen);
-      return 0;
+             who, bs->msglen);
+      goto auth_fatal;
    }
-   dirname = get_pool_memory(PM_MESSAGE);
    dirname = check_pool_memory_size(dirname, bs->msglen);
 
    if (sscanf(bs->msg, "Hello Director %s calling\n", dirname) != 1) {
        char addr[64];
        char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
-      free_pool_memory(dirname);
       bs->msg[100] = 0;
       Dmsg2(50, "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"),
-           who, bs->msg);
-      return 0;
+            who, bs->msg);
+      goto auth_fatal;
    }
    unbash_spaces(dirname);
    LockRes();
@@ -79,9 +78,8 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
        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"), 
-           dirname, who);
-      free_pool_memory(dirname);
-      return 0;
+            dirname, who);
+      goto auth_fatal;
    }
 
    if (have_tls) {
@@ -99,14 +97,14 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
       }
    }
 
-   btimer_t *tid = start_bsock_timer(bs, AUTH_TIMEOUT);
+   tid = start_bsock_timer(bs, AUTH_TIMEOUT);
    auth_success = cram_md5_auth(bs, director->password, tls_local_need);  
    if (auth_success) {
       auth_success = cram_md5_get_auth(bs, director->password, &tls_remote_need);
       if (!auth_success) {
-         char addr[64];
-         char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
-         Dmsg1(50, "cram_get_auth failed for %s\n", who);
+          char addr[64];
+          char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
+          Dmsg1(50, "cram_get_auth failed for %s\n", who);
       }
    } else {
        char addr[64];
@@ -115,23 +113,22 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
    }
    if (!auth_success) {
        Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
-            bs->who);
-       director = NULL;
+             bs->who);
        goto auth_fatal;
    }
 
    /* 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"));
-      director = NULL;
+           " advertize required TLS support.\n"));
+      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"));
-      director = NULL;
+      auth_success = false;
       goto auth_fatal;
    }
 
@@ -140,16 +137,25 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
          /* Engage TLS! Full Speed Ahead! */
          if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
             Emsg0(M_FATAL, 0, _("TLS negotiation failed.\n"));
-            director = NULL;
+            auth_success = false;
             goto auth_fatal;
          }
       }
    }
 
 auth_fatal:
-   stop_bsock_timer(tid);
+   if (tid) {
+      stop_bsock_timer(tid);
+      tid = NULL;
+   }
    free_pool_memory(dirname);
    jcr->director = director;
+   /* Single thread all failures to avoid DOS */
+   if (auth_success) {
+      P(mutex);
+      bmicrosleep(6, 0);
+      V(mutex);
+   }
    return (director != NULL);
 }
 
@@ -166,9 +172,12 @@ int authenticate_director(JCR *jcr)
    BSOCK *dir = jcr->dir_bsock;
 
    if (!authenticate(R_DIRECTOR, dir, jcr)) {
+      /* Single thread all failures to avoid DOS */
+      P(mutex);
+      bmicrosleep(6, 0);
+      V(mutex);
       bnet_fsend(dir, "%s", Dir_sorry);
       Emsg0(M_FATAL, 0, _("Unable to authenticate Director\n"));
-      bmicrosleep(5, 0);
       return 0;
    }
    return bnet_fsend(dir, "%s", OK_hello);
@@ -185,18 +194,17 @@ int authenticate_storagedaemon(JCR *jcr)
    int tls_remote_need = BNET_TLS_NONE;
    bool auth_success = false;
 
-#ifdef HAVE_TLS
+   btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
+
    /* TLS Requirement */
-   if (me->tls_enable) {
+   if (have_tls && me->tls_enable) {
       if (me->tls_require) {
          tls_local_need = BNET_TLS_REQUIRED;
       } else {
          tls_local_need = BNET_TLS_OK;
       }
    }
-#endif /* HAVE_TLS */
 
-   btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
    auth_success = cram_md5_get_auth(sd, jcr->sd_auth_key, &tls_remote_need);
    if (!auth_success) {
       Dmsg1(50, "cram_get_auth failed for %s\n", sd->who);
@@ -231,8 +239,7 @@ int authenticate_storagedaemon(JCR *jcr)
       goto auth_fatal;
    }
 
-#ifdef HAVE_TLS
-   if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
+   if (have_tls && 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)) {
          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
@@ -240,9 +247,14 @@ int authenticate_storagedaemon(JCR *jcr)
          goto auth_fatal;
       }
    }
-#endif /* HAVE_TLS */
 
 auth_fatal:
    stop_bsock_timer(tid);
+   /* Single thread all failures to avoid DOS */
+   if (!auth_success) {
+      P(mutex);
+      bmicrosleep(6, 0);
+      V(mutex);
+   }
    return auth_success;
 }
index 8a5db7555edff59a542f16d21d7b642df28e281d..13fb7a8d85131fa36fd4d7acad97751eb94cb940 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "1.39.14"
-#define BDATE   "22 June 2006"
-#define LSMDATE "22Jun06"
+#define BDATE   "24 June 2006"
+#define LSMDATE "24Jun06"
 
 /* Debug flags */
 #undef  DEBUG