From cfe90ec010bedc334d7a60db9208e77bfab440e4 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 6 Aug 2018 13:51:29 +0200 Subject: [PATCH] Add M_SECURITY when connection is bad + fix bug where invalid probes sent to Dir --- bacula/src/dird/authenticate.c | 12 ++++++------ bacula/src/filed/job.c | 2 +- bacula/src/lib/bnet_server.c | 11 ++++++----- bacula/src/lib/message.c | 14 ++++++++++---- bacula/src/stored/dircmd.c | 8 +++++--- bacula/src/stored/fd_cmds.c | 3 +++ bacula/src/stored/hello.c | 21 +++++++++++---------- bacula/src/stored/job.c | 9 ++++++--- 8 files changed, 48 insertions(+), 32 deletions(-) diff --git a/bacula/src/dird/authenticate.c b/bacula/src/dird/authenticate.c index 19ecba6bd..0d044b122 100644 --- a/bacula/src/dird/authenticate.c +++ b/bacula/src/dird/authenticate.c @@ -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; diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index c42bd2e9b..0d31ed194 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -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; } diff --git a/bacula/src/lib/bnet_server.c b/bacula/src/lib/bnet_server.c index 0144047d2..3af76a293 100644 --- a/bacula/src/lib/bnet_server.c +++ b/bacula/src/lib/bnet_server.c @@ -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()); } } diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 6b553c027..602d0d07f 100644 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -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); diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 4b9c0fc01..bd605cc29 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -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; diff --git a/bacula/src/stored/fd_cmds.c b/bacula/src/stored/fd_cmds.c index 9569ee306..21314d6a7 100644 --- a/bacula/src/stored/fd_cmds.c +++ b/bacula/src/stored/fd_cmds.c @@ -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; diff --git a/bacula/src/stored/hello.c b/bacula/src/stored/hello.c index 14d0f9d0a..4c5ac2a09 100644 --- a/bacula/src/stored/hello.c +++ b/bacula/src/stored/hello.c @@ -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, "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); diff --git a/bacula/src/stored/job.c b/bacula/src/stored/job.c index a89014c2e..6e8b4a892 100644 --- a/bacula/src/stored/job.c +++ b/bacula/src/stored/job.c @@ -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) { -- 2.47.3