2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Authenticate Director who is attempting to connect.
22 * Kern Sibbald, October 2000
29 extern CLIENT *me; /* my resource */
31 const int dbglvl = 50;
33 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
36 * Authenticated the Director
38 bool authenticate_director(JCR *jcr)
40 DIRRES *director = jcr->director;
41 int tls_local_need = BNET_TLS_NONE;
42 int tls_remote_need = BNET_TLS_NONE;
43 int compatible = true; /* Want md5 compatible DIR */
44 bool auth_success = false;
45 alist *verify_list = NULL;
47 BSOCK *dir = jcr->dir_bsock;
51 if (director->tls_enable) {
52 if (director->tls_require) {
53 tls_local_need = BNET_TLS_REQUIRED;
55 tls_local_need = BNET_TLS_OK;
59 if (director->tls_authenticate) {
60 tls_local_need = BNET_TLS_REQUIRED;
63 if (director->tls_verify_peer) {
64 verify_list = director->tls_allowed_cns;
68 tid = start_bsock_timer(dir, AUTH_TIMEOUT);
69 /* Challenge the director */
70 auth_success = cram_md5_challenge(dir, director->password, tls_local_need, compatible);
71 if (job_canceled(jcr)) {
73 goto auth_fatal; /* quick exit */
76 auth_success = cram_md5_respond(dir, director->password, &tls_remote_need, &compatible);
79 char *who = dir->get_peer(addr, sizeof(addr)) ? dir->who() : addr;
80 Dmsg1(dbglvl, "cram_get_auth respond failed for Director: %s\n", who);
84 char *who = dir->get_peer(addr, sizeof(addr)) ? dir->who() : addr;
85 Dmsg1(dbglvl, "cram_auth challenge failed for Director %s\n", who);
88 Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
93 /* Verify that the remote host is willing to meet our TLS requirements */
94 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
95 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
96 " advertize required TLS support.\n"));
97 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
102 /* Verify that we are willing to meet the remote host's requirements */
103 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
104 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
105 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
106 auth_success = false;
110 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
111 /* Engage TLS! Full Speed Ahead! */
112 if (!bnet_tls_server(director->tls_ctx, dir, verify_list)) {
113 Jmsg0(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
114 auth_success = false;
117 if (director->tls_authenticate) { /* authentication only? */
118 dir->free_tls(); /* shutodown tls */
125 stop_bsock_timer(tid);
129 return send_hello_ok(dir);
132 /* Single thread all failures to avoid DOS */
141 * First prove our identity to the Storage daemon, then
142 * make him prove his identity.
144 bool authenticate_storagedaemon(JCR *jcr)
146 BSOCK *sd = jcr->store_bsock;
147 int tls_local_need = BNET_TLS_NONE;
148 int tls_remote_need = BNET_TLS_NONE;
149 int compatible = true;
150 bool auth_success = false;
153 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
155 /* TLS Requirement */
156 if (have_tls && me->tls_enable) {
157 if (me->tls_require) {
158 tls_local_need = BNET_TLS_REQUIRED;
160 tls_local_need = BNET_TLS_OK;
164 if (me->tls_authenticate) {
165 tls_local_need = BNET_TLS_REQUIRED;
168 if (job_canceled(jcr)) {
169 auth_success = false; /* force quick exit */
173 /* Respond to SD challenge */
174 Dmsg0(050, "==== respond to SD challenge\n");
175 auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
176 if (job_canceled(jcr)) {
177 auth_success = false; /* force quick exit */
181 Dmsg1(dbglvl, "cram_respond failed for SD: %s\n", sd->who());
183 /* Now challenge him */
184 Dmsg0(050, "==== Challenge SD\n");
185 auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
187 Dmsg1(dbglvl, "cram_challenge failed for SD: %s\n", sd->who());
192 Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
193 "For help, please see " MANUAL_AUTH_URL "\n"));
196 Dmsg0(050, "Authorization with SD is OK\n");
199 /* Verify that the remote host is willing to meet our TLS requirements */
200 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
201 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
202 " advertize required TLS support.\n"));
203 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
204 auth_success = false;
208 /* Verify that we are willing to meet the remote host's requirements */
209 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
210 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
211 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
212 auth_success = false;
216 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
217 /* Engage TLS! Full Speed Ahead! */
218 if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
219 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
220 auth_success = false;
223 if (me->tls_authenticate) { /* tls authentication only? */
224 sd->free_tls(); /* yes, shutdown tls */
227 if (sd->recv() <= 0) {
228 auth_success = false;
231 sscanf(sd->msg, "3000 OK Hello %d", &sd_version);
232 /* At this point, we have successfully connected */
235 /* Destroy session key */
236 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
237 stop_bsock_timer(tid);
238 /* Single thread all failures to avoid DOS */