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();
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) {
}
}
- 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];
}
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;
}
/* 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);
}
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);
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);
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"));
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;
}