* Authenticate caller
*
* Written by Kern Sibbald, October 2000
+ *
*/
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-/* Version at end of Hello
- * prior to 06Aug13 no version
- * 1 06Aug13 - added comm line compression
- * 2 13Dec13 - added api version to status command
- */
-#define SD_VERSION 2
-
+SDAuthenticateDIR::SDAuthenticateDIR(JCR *jcr):
+AuthenticateBase(jcr, jcr->dir_bsock, dtSrv, dcSD, dcDIR)
+{
+}
/*
* Authenticate the Director
*/
-bool authenticate_director(JCR* jcr)
+bool SDAuthenticateDIR::authenticate_director()
{
- DIRRES *director = jcr->director;
- 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;
- alist *verify_list = NULL;
BSOCK *dir = jcr->dir_bsock;
+ DIRRES *director = jcr->director;
- /* 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_authenticate) {
- tls_local_need = BNET_TLS_REQUIRED;
- }
+ DecodeRemoteTLSPSKNeed(bsock->tlspsk_remote);
- if (director->tls_verify_peer) {
- verify_list = director->tls_allowed_cns;
- }
+ /* TLS Requirement */
+ CalcLocalTLSNeedFromRes(director->tls_enable, director->tls_require,
+ director->tls_authenticate, director->tls_verify_peer,
+ director->tls_allowed_cns, director->tls_ctx,
+ director->tls_psk_enable, director->psk_ctx, director->password);
/* Timeout authentication after 10 mins */
- btimer_t *tid = start_bsock_timer(dir, AUTH_TIMEOUT);
- auth_success = cram_md5_challenge(dir, director->password, tls_local_need, compatible);
- if (auth_success) {
- auth_success = cram_md5_respond(dir, director->password, &tls_remote_need, &compatible);
- if (!auth_success) {
- Dmsg1(dbglvl, "cram_get_auth respond failed with Director %s\n", dir->who());
- }
- } else {
- Dmsg1(dbglvl, "cram_auth challenge failed with Director %s\n", dir->who());
- }
-
- if (!auth_success) {
- Jmsg0(jcr, M_FATAL, 0, _("Incorrect password given by Director.\n"
- "For help, please see: " MANUAL_AUTH_URL "\n"));
- auth_success = false;
- goto auth_fatal;
- }
+ StartAuthTimeout();
- /* 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) {
- Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
- " advertize required TLS support.\n"));
- Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
- 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) {
- Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
- Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
- auth_success = false;
+ /* Challenge the director */
+ if (!ServerCramMD5Authenticate(password)) {
goto auth_fatal;
}
- 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, dir, verify_list)) {
- Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with DIR at \"%s:%d\"\n"),
- dir->host(), dir->port());
- auth_success = false;
- goto auth_fatal;
- }
- if (director->tls_authenticate) { /* authenticate with tls only? */
- dir->free_tls(); /* yes, shut it down */
- }
- }
+ this->auth_success = HandleTLS();
auth_fatal:
- stop_bsock_timer(tid);
- jcr->director = director;
if (auth_success) {
return send_hello_ok(dir);
}
send_sorry(dir);
- Dmsg1(dbglvl, "Unable to authenticate Director at %s.\n", dir->who());
- Jmsg1(jcr, M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who());
bmicrosleep(5, 0);
return false;
}
-
-int authenticate_filed(JCR *jcr, BSOCK *fd, int FDVersion)
+class SDAuthenticateFD: public AuthenticateBase
{
- 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;
- alist *verify_list = NULL;
-
- /* TLS Requirement */
- if (me->tls_enable) {
- if (me->tls_require) {
- tls_local_need = BNET_TLS_REQUIRED;
- } else {
- tls_local_need = BNET_TLS_OK;
- }
+public:
+ SDAuthenticateFD(JCR *jcr, BSOCK *bsock):
+ AuthenticateBase(jcr, bsock, dtSrv, dcSD, dcFD)
+ {
}
+ virtual ~SDAuthenticateFD() {};
+ int authenticate_filed(int FDVersion);
+};
- if (me->tls_authenticate) {
- tls_local_need = BNET_TLS_REQUIRED;
- }
-
- if (me->tls_verify_peer) {
- verify_list = me->tls_allowed_cns;
- }
+int authenticate_filed(JCR *jcr, BSOCK *fd, int FDVersion)
+{
+ return SDAuthenticateFD(jcr, fd).authenticate_filed(FDVersion);
+}
- /* Timeout authentication after 5 mins */
- btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
- /* Challenge FD */
- Dmsg0(050, "Challenge FD\n");
- auth_success = cram_md5_challenge(fd, jcr->sd_auth_key, tls_local_need, compatible);
- if (auth_success) {
- /* Respond to his challenge */
- Dmsg0(050, "Respond to FD challenge\n");
- auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible);
- if (!auth_success) {
- Dmsg1(dbglvl, "Respond cram-get-auth respond failed with FD: %s\n", fd->who());
- }
- } else {
- Dmsg1(dbglvl, "Challenge cram-auth failed with FD: %s\n", fd->who());
- }
+int SDAuthenticateFD::authenticate_filed(int FDVersion)
+{
+ BSOCK *fd = bsock;
- if (!auth_success) {
- Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
- "For help, please see: " MANUAL_AUTH_URL "\n"),
- fd->who());
- auth_success = false;
- goto auth_fatal;
- }
+ DecodeRemoteTLSPSKNeed(bsock->tlspsk_remote);
+ /* TLS Requirement */
+ CalcLocalTLSNeedFromRes(me->tls_enable, me->tls_require, me->tls_authenticate,
+ me->tls_verify_peer, me->tls_allowed_cns, me->tls_ctx,
+ me->tls_psk_enable, me->psk_ctx, jcr->sd_auth_key);
- /* 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) {
- Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
- " advertize required TLS support.\n"));
- Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
- auth_success = false;
- goto auth_fatal;
- }
+ /* Timeout authentication after 10 mins */
+ StartAuthTimeout();
- /* 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) {
- Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
- Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
- auth_success = false;
+ /* Challenge the FD */
+ if (!ServerCramMD5Authenticate(jcr->sd_auth_key)) {
goto auth_fatal;
}
- 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)) {
- Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\"\n"),
- fd->host(), fd->port());
- auth_success = false;
- goto auth_fatal;
- }
- if (me->tls_authenticate) { /* tls authenticate only? */
- fd->free_tls(); /* yes, shut it down */
- }
- }
+ this->auth_success = HandleTLS();
auth_fatal:
- stop_bsock_timer(tid);
- if (!auth_success) {
- Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
- "For help, please see: " MANUAL_AUTH_URL "\n"),
- fd->who());
- }
-
/* Version 5 of the protocol is a bit special, it is used by both 6.0.0
* Enterprise version and 7.0.x Community version, but do not support the
* same level of features. As nobody is using the 6.0.0 release, we can
return auth_success;
}
+class SDAuthenticateSD: public AuthenticateBase
+{
+public:
+ SDAuthenticateSD(JCR *jcr):
+ AuthenticateBase(jcr, jcr->store_bsock, dtCli, dcSD, dcSD) {
+ /* TLS Requirement */
+ CalcLocalTLSNeedFromRes(me->tls_enable, me->tls_require, me->tls_authenticate,
+ me->tls_verify_peer, me->tls_allowed_cns, me->tls_ctx,
+ me->tls_psk_enable, me->psk_ctx, jcr->sd_auth_key);
+ }
+ virtual ~SDAuthenticateSD() {};
+ bool authenticate_storagedaemon();
+};
+
+
+bool send_hello_and_authenticate_sd(JCR *jcr, char *Job)
+{
+ SDAuthenticateSD auth(jcr);
+ /* TODO disable PSK/TLS when the SD talk to itself */
+ if (!send_hello_sd(jcr, Job, auth.GetTLSPSKLocalNeed())) {
+ return false;
+ }
+ return auth.authenticate_storagedaemon();
+}
+
/*
* First prove our identity to the Storage daemon, then
* make him prove his identity.
*/
-bool authenticate_storagedaemon(JCR *jcr)
+bool SDAuthenticateSD::authenticate_storagedaemon()
{
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;
int sd_version = 0;
- btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
-
- /* TLS Requirement */
- if (have_tls && me->tls_enable) {
- if (me->tls_require) {
- tls_local_need = BNET_TLS_REQUIRED;
- } else {
- tls_local_need = BNET_TLS_OK;
- }
- }
-
- if (me->tls_authenticate) {
- tls_local_need = BNET_TLS_REQUIRED;
- }
+ /* Timeout authentication after 10 mins */
+ StartAuthTimeout();
- if (job_canceled(jcr)) {
- auth_success = false; /* force quick exit */
+ /* Challenge the FD */
+ if (!ClientCramMD5Authenticate(jcr->sd_auth_key)) {
goto auth_fatal;
}
- /* Respond to SD challenge */
- Dmsg0(050, "Respond to SD challenge\n");
- auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
- if (job_canceled(jcr)) {
- auth_success = false; /* force quick exit */
- goto auth_fatal;
- }
- if (!auth_success) {
- Dmsg1(dbglvl, "cram_respond failed for SD: %s\n", sd->who());
- } else {
- /* Now challenge him */
- Dmsg0(050, "Challenge SD\n");
- auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
- if (!auth_success) {
- Dmsg1(dbglvl, "cram_challenge failed for SD: %s\n", sd->who());
- }
- }
+ this->auth_success = HandleTLS();
if (!auth_success) {
- Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
- "Please see " MANUAL_AUTH_URL " for help.\n"));
- goto auth_fatal;
- } else {
- Dmsg0(050, "Authorization with SD is OK\n");
- }
-
- /* 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) {
- Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
- " advertize required TLS support.\n"));
- Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
- 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) {
- Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
- Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
- auth_success = false;
- goto auth_fatal;
- }
-
- if (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, NULL)) {
- Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
- auth_success = false;
- goto auth_fatal;
- }
- if (me->tls_authenticate) { /* tls authentication only? */
- sd->free_tls(); /* yes, shutdown tls */
- }
- }
if (sd->recv() <= 0) {
auth_success = false;
goto auth_fatal;
auth_fatal:
/* Destroy session key */
memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
- stop_bsock_timer(tid);
/* Single thread all failures to avoid DOS */
if (!auth_success) {
P(mutex);