]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add M_SECURITY when connection is bad + fix bug where invalid probes sent to Dir
authorKern Sibbald <kern@sibbald.com>
Mon, 6 Aug 2018 11:51:29 +0000 (13:51 +0200)
committerKern Sibbald <kern@sibbald.com>
Tue, 7 Aug 2018 09:04:14 +0000 (11:04 +0200)
bacula/src/dird/authenticate.c
bacula/src/filed/job.c
bacula/src/lib/bnet_server.c
bacula/src/lib/message.c
bacula/src/stored/dircmd.c
bacula/src/stored/fd_cmds.c
bacula/src/stored/hello.c
bacula/src/stored/job.c

index 19ecba6bdae8fd630ea0b7ac133d535635f22d31..0d044b122f9191584290ae86eeab0219bddf25e7 100644 (file)
@@ -326,7 +326,7 @@ int authenticate_user_agent(UAContext *uac)
    int ua_version = 0;
 
    if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
-      Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(),
+      Jmsg4(NULL, M_SECURITY, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(),
             ua->host(), ua->port(), ua->msglen);
       return 0;
    }
@@ -334,7 +334,7 @@ int authenticate_user_agent(UAContext *uac)
    if (sscanf(ua->msg, "Hello %127s calling %d", name, &ua_version) != 2 &&
        sscanf(ua->msg, "Hello %127s calling", name) != 1) {
       ua->msg[100] = 0;               /* terminate string */
-      Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(),
+      Jmsg4(NULL, M_SECURITY, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(),
             ua->host(), ua->port(), ua->msg);
       return 0;
    }
@@ -409,7 +409,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:"
+      Jmsg0(NULL, M_SECURITY, 0, _("Authorization problem:"
             " Remote client did not advertise required TLS support.\n"));
       auth_success = false;
       goto auth_done;
@@ -417,7 +417,7 @@ int authenticate_user_agent(UAContext *uac)
 
    /* Verify that we are willing to meet the peer'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:"
+      Jmsg0(NULL, M_SECURITY, 0, _("Authorization problem:"
             " Remote client requires TLS.\n"));
       auth_success = false;
       goto auth_done;
@@ -432,7 +432,7 @@ int authenticate_user_agent(UAContext *uac)
 
       /* Engage TLS! Full Speed Ahead! */
       if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
-         Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
+         Jmsg0(NULL, M_SECURITY, 0, _("TLS negotiation failed.\n"));
          auth_success = false;
          goto auth_done;
       }
@@ -446,7 +446,7 @@ int authenticate_user_agent(UAContext *uac)
 auth_done:
    if (!auth_success) {
       ua->fsend("%s", _(Dir_sorry));
-      Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
+      Jmsg4(NULL, M_SECURITY, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
             name, ua->who(), ua->host(), ua->port());
       sleep(5);
       return 0;
index c42bd2e9b006e878856f73eeb57b470d0bfea5d5..0d31ed19402cf13e9ad19bd4b13ee51fd9d8b8dd 100644 (file)
@@ -505,7 +505,7 @@ bail_out:
    Dmsg2(100, "Bad command from %s. Len=%d.\n", bs->who(), bs->msglen);
    char addr[64];
    char *who = bs->get_peer(addr, sizeof(addr)) ? bs->who() : addr;
-   Jmsg2(NULL, M_FATAL, 0, _("Bad command from %s. Len=%d.\n"), who, bs->msglen);
+   Qmsg2(NULL, M_SECURITY, 0, _("FD expecting Hello got bad command from %s. Len=%d.\n"), who, bs->msglen);
    bs->destroy();
    return NULL;
 }
index 0144047d28f5e8212b09b4a776ed35e5687e05c1..3af76a2939e47e96beba778b8b0fead1a49e1cdc 100644 (file)
@@ -190,7 +190,7 @@ void bnet_thread_server(dlist *addrs, int max_clients,
             fromhost(&request);
             if (!hosts_access(&request)) {
                V(mutex);
-               Jmsg2(NULL, M_SECURITY, 0,
+               Qmsg2(NULL, M_SECURITY, 0,
                      _("Connection from %s:%d refused by hosts.access\n"),
                      sockaddr_to_ascii((struct sockaddr *)&clientaddr,
                                        sizeof(clientaddr), buf, sizeof(buf)),
@@ -207,7 +207,7 @@ void bnet_thread_server(dlist *addrs, int max_clients,
             if (setsockopt(newsockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon,
                  sizeof(turnon)) < 0) {
                berrno be;
-               Emsg1(M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
+               Qmsg1(NULL, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
                      be.bstrerror());
             }
 
@@ -219,14 +219,15 @@ void bnet_thread_server(dlist *addrs, int max_clients,
             bs = init_bsock(NULL, newsockfd, "client", buf, ntohs(fd_ptr->port),
                     (struct sockaddr *)&clientaddr);
             if (bs == NULL) {
-               Jmsg0(NULL, M_ABORT, 0, _("Could not create client BSOCK.\n"));
+               Qmsg0(NULL, M_ABORT, 0, _("Could not create client BSOCK.\n"));
             }
 
             /* Queue client to be served */
             if ((stat = workq_add(client_wq, (void *)bs, NULL, 0)) != 0) {
                berrno be;
                be.set_errno(stat);
-               Jmsg1(NULL, M_ABORT, 0, _("Could not add job to client queue: ERR=%s\n"),
+               bs->destroy();
+               Qmsg1(NULL, M_ABORT, 0, _("Could not add job to client queue: ERR=%s\n"),
                      be.bstrerror());
             }
          }
@@ -243,7 +244,7 @@ void bnet_thread_server(dlist *addrs, int max_clients,
    if ((stat = workq_destroy(client_wq)) != 0) {
       berrno be;
       be.set_errno(stat);
-      Emsg1(M_FATAL, 0, _("Could not destroy client queue: ERR=%s\n"),
+      Jmsg1(NULL, M_FATAL, 0, _("Could not destroy client queue: ERR=%s\n"),
             be.bstrerror());
    }
 }
index 6b553c0279223c5f9ed7ac89b13279406c6bca14..602d0d07f717aef62d6b9f9550d583d33e71e701 100644 (file)
@@ -1382,7 +1382,7 @@ e_msg(const char *file, int line, int type, int level, const char *fmt,...)
        len = bsnprintf(buf, sizeof(buf), _("%s: Warning: "), my_name);
        break;
     case M_SECURITY:
-       len = bsnprintf(buf, sizeof(buf), _("%s: Security violation: "), my_name);
+       len = bsnprintf(buf, sizeof(buf), _("%s: Security Alert: "), my_name);
        break;
     default:
        len = bsnprintf(buf, sizeof(buf), "%s: ", my_name);
@@ -1439,11 +1439,14 @@ Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
 
     Dmsg1(850, "Enter Jmsg type=%d\n", type);
 
-    /* Special case for the console, which has a dir_bsock and JobId==0,
+    /*
+     * Special case for the console, which has a dir_bsock and JobId==0,
      *  in that case, we send the message directly back to the
      *  dir_bsock.
+     *  This allow commands such as "estimate" to work.
+     *  It probably should be restricted to work only in the FD.
      */
-    if (jcr && jcr->JobId == 0 && jcr->dir_bsock) {
+    if (jcr && jcr->JobId == 0 && jcr->dir_bsock && type != M_SECURITY) {
        BSOCK *dir = jcr->dir_bsock;
        va_start(arg_ptr, fmt);
        dir->msglen = bvsnprintf(dir->msg, sizeof_pool_memory(dir->msg),
@@ -1515,7 +1518,7 @@ Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
        }
        break;
     case M_SECURITY:
-       len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Security violation: "),
+       len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Security Alert: "),
                my_name, JobId);
        break;
     default:
@@ -1755,6 +1758,9 @@ void dequeue_daemon_messages(JCR *jcr)
       jcr->JobId = 0;       /* set daemon JobId == 0 */
       if (jcr->dir_bsock) jcr->dir_bsock->suppress_error_messages(true);
       foreach_dlist(item, daemon_msg_queue) {
+         if (item->type == M_FATAL || item->type == M_ERROR) {
+            item->type = M_SECURITY;
+         }
          Jmsg(jcr, item->type, item->mtime, "%s", item->msg);
       }
       if (jcr->dir_bsock) jcr->dir_bsock->suppress_error_messages(false);
index 4b9c0fc01b3f4440258430f1a100877309d589cc..bd605cc29419490447446c510999fd399896dde6 100644 (file)
@@ -169,7 +169,7 @@ void *handle_connection_request(void *arg)
    char tbuf[100];
 
    if (bs->recv() <= 0) {
-      Jmsg1(NULL, M_ERROR, 0, _("Connection request from %s failed.\n"), bs->who());
+      Qmsg1(NULL, M_ERROR, 0, _("Connection request from %s failed.\n"), bs->who());
       bmicrosleep(5, 0);   /* make user wait 5 seconds */
       bs->destroy();
       return NULL;
@@ -195,7 +195,7 @@ void *handle_connection_request(void *arg)
    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
    if (errstat != 0) {
       berrno be;
-      Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
+      Qmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
       goto bail_out;
    }
 
@@ -208,7 +208,7 @@ void *handle_connection_request(void *arg)
       goto bail_out;
    }
    if (!authenticate_director(jcr)) {
-      Jmsg(jcr, M_FATAL, 0, _("[SF0100] Unable to authenticate Director\n"));
+      Qmsg(jcr, M_FATAL, 0, _("[SF0100] Unable to authenticate Director\n"));
       goto bail_out;
    }
    Dmsg0(90, "Message channel init completed.\n");
@@ -259,6 +259,8 @@ bail_out:
    dequeue_messages(jcr);             /* send any queued messages */
    dequeue_daemon_messages(jcr);
    bs->signal(BNET_TERMINATE);
+   bs->destroy();
+   jcr->dir_bsock = NULL;             /* just freed bsock */
    free_plugins(jcr);                 /* release instantiated plugins */
    free_jcr(jcr);
    return NULL;
index 9569ee3066a810c8b776cfeef6bb31af449af452..21314d6a7c81951bee736bd2525cf2756acbf06f 100644 (file)
@@ -193,6 +193,9 @@ void do_client_commands(JCR *jcr)
    bool found, quit;
    BSOCK *fd = jcr->file_bsock;
 
+   if (!fd) {
+      return;
+   }
    fd->set_jcr(jcr);
    for (quit=false; !quit;) {
       int stat;
index 14d0f9d0a49333ce76ac14e01bae6d2b199b8f5e..4c5ac2a091517739482348da807294f11454236d 100644 (file)
@@ -73,7 +73,7 @@ bool validate_dir_hello(JCR* jcr)
    if (dir->msglen < 25 || dir->msglen > 500) {
       Dmsg2(dbglvl, "Bad Hello command from Director at %s. Len=%d.\n",
             dir->who(), dir->msglen);
-      Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
+      Qmsg2(jcr, M_SECURITY, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
             dir->who(), dir->msglen);
       return false;
    }
@@ -87,7 +87,7 @@ bool validate_dir_hello(JCR* jcr)
       dir->msg[100] = 0;
       Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n",
             dir->who(), dir->msg);
-      Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
+      Qmsg2(jcr, M_SECURITY, 0, _("Bad Hello command from Director at %s: %s\n"),
             dir->who(), dir->msg);
       free_pool_memory(dirname);
       return false;
@@ -109,7 +109,7 @@ bool validate_dir_hello(JCR* jcr)
    if (!director) {
       Dmsg2(dbglvl, "Connection from unknown Director %s at %s rejected.\n",
             dirname, dir->who());
-      Jmsg2(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"
+      Qmsg2(jcr, M_SECURITY, 0, _("Connection from unknown Director %s at %s rejected.\n"
             "Please see " MANUAL_AUTH_URL " for help.\n"),
             dirname, dir->who());
       free_pool_memory(dirname);
@@ -135,7 +135,7 @@ void handle_client_connection(BSOCK *fd)
     */
    if (fd->msglen < 25 || fd->msglen > (int)sizeof(job_name)) {
       Pmsg1(000, "<filed: %s", fd->msg);
-      Jmsg2(NULL, M_ERROR, 0, _("Invalid connection from %s. Len=%d\n"), fd->who(), fd->msglen);
+      Qmsg2(NULL, M_SECURITY, 0, _("Invalid connection from %s. Len=%d\n"), fd->who(), fd->msglen);
       bmicrosleep(5, 0);   /* make user wait 5 seconds */
       fd->destroy();
       return;
@@ -149,12 +149,13 @@ void handle_client_connection(BSOCK *fd)
    if (sscanf(fd->msg, "Hello Bacula SD: Start Job %127s %d %d", job_name, &fd_version, &sd_version) != 3 &&
        sscanf(fd->msg, "Hello FD: Bacula Storage calling Start Job %127s %d", job_name, &sd_version) != 2 &&
        sscanf(fd->msg, "Hello Start Job %127s", job_name) != 1) {
-      Jmsg2(NULL, M_ERROR, 0, _("Invalid Hello from %s. Len=%d\n"), fd->who(), fd->msglen);
+      Qmsg2(NULL, M_SECURITY, 0, _("Invalid Hello from %s. Len=%d\n"), fd->who(), fd->msglen);
+      fd->destroy();
       return;
    }
 
    if (!(jcr=get_jcr_by_full_name(job_name))) {
-      Jmsg1(NULL, M_FATAL, 0, _("Client connect failed: Job name not found: %s\n"), job_name);
+      Qmsg1(NULL, M_SECURITY, 0, _("Client connect failed: Job name not found: %s\n"), job_name);
       Dmsg1(3, "**** Job \"%s\" not found.\n", job_name);
       fd->destroy();
       return;
@@ -163,7 +164,7 @@ void handle_client_connection(BSOCK *fd)
    /* After this point, we can use bail_out */
    Dmsg1(100, "Found Client Job %s\n", job_name);
    if (jcr->authenticated) {
-      Jmsg3(jcr, M_WARNING, 0, _("A Client \"%s\" tried to authenticate for Job %s, "
+      Jmsg3(jcr, M_SECURITY, 0, _("A Client \"%s\" tried to authenticate for Job %s, "
                                  "but the Job is already authenticated with \"%s\".\n"),
             fd->who(), jcr->Job, jcr->file_bsock?jcr->file_bsock->who():"N/A");
       Dmsg2(050, "Hey!!!! JobId %u Job %s already authenticated.\n",
@@ -187,14 +188,14 @@ void handle_client_connection(BSOCK *fd)
     */
    jcr->lock_auth();     /* Ensure that only one thread is dealing with auth */
    if (jcr->authenticated) {
-      Jmsg2(jcr, M_WARNING, 0, _("A Client \"%s\" tried to authenticate for Job %s, "
+      Jmsg2(jcr, M_SECURITY, 0, _("A Client \"%s\" tried to authenticate for Job %s, "
                                  "but the job is already authenticated.\n"),
             fd->who(), jcr->Job);
 
    } else if (!authenticate_filed(jcr, fd, fd_version)) {
       Dmsg1(50, "Authentication failed Job %s\n", jcr->Job);
       /* Job not yet started, we can cancel */
-      Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n"));
+      Jmsg(jcr, M_SECURITY, 0, _("Unable to authenticate File daemon\n"));
 
    } else {
       Dmsg2(050, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job);
@@ -219,7 +220,7 @@ void handle_client_connection(BSOCK *fd)
 bail_out:
    /* file_bsock might be NULL or a previous BSOCK */
    if (jcr->file_bsock != fd) {
-      free_bsock(fd);
+      fd->destroy();
    }
    pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
    free_jcr(jcr);
index a89014c2eec9e4ba961af3ec599f343794043dbc..6e8b4a892c3c285648a11079f28a07145a020b47 100644 (file)
@@ -196,7 +196,7 @@ bool run_cmd(JCR *jcr)
       Dmsg0(050, "=== Authenticate FD\n");
       if (jcr->authenticated || !authenticate_filed(jcr, jcr->file_bsock, jcr->FDVersion)) {
          Dmsg1(050, "Authentication failed Job %s\n", jcr->Job);
-         Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n"));
+         Qmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n"));
       } else {
          jcr->authenticated = true;
       }
@@ -331,8 +331,11 @@ void stored_free_jcr(JCR *jcr)
       Dmsg2(800, "Send terminate jid=%d %p\n", jcr->JobId, jcr);
       jcr->dir_bsock->signal(BNET_EOD);
       jcr->dir_bsock->signal(BNET_TERMINATE);
+      jcr->dir_bsock->destroy();
+   }
+   if (jcr->file_bsock) {
+      jcr->file_bsock->destroy();
    }
-   free_bsock(jcr->file_bsock);
    if (jcr->job_name) {
       free_pool_memory(jcr->job_name);
    }
@@ -358,7 +361,7 @@ void stored_free_jcr(JCR *jcr)
       jcr->RestoreBootstrap = NULL;
    }
    if (jcr->next_dev || jcr->prev_dev) {
-      Emsg0(M_FATAL, 0, _("In free_jcr(), but still attached to device!!!!\n"));
+      Qmsg0(NULL, M_FATAL, 0, _("In free_jcr(), but still attached to device!!!!\n"));
    }
    pthread_cond_destroy(&jcr->job_start_wait);
    if (jcr->dcrs) {