2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
23 * Written by Kern Sibbald, October 2000
31 extern STORES *me; /* our Global resource */
33 const int dbglvl = 50;
35 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
38 * Authenticate the Director
40 bool authenticate_director(JCR* jcr)
42 DIRRES *director = jcr->director;
43 int tls_local_need = BNET_TLS_NONE;
44 int tls_remote_need = BNET_TLS_NONE;
45 int compatible = true; /* require md5 compatible DIR */
46 bool auth_success = false;
47 alist *verify_list = NULL;
48 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;
67 /* Timeout authentication after 10 mins */
68 btimer_t *tid = start_bsock_timer(dir, AUTH_TIMEOUT);
69 auth_success = cram_md5_challenge(dir, director->password, tls_local_need, compatible);
71 auth_success = cram_md5_respond(dir, director->password, &tls_remote_need, &compatible);
73 Dmsg1(dbglvl, "cram_get_auth respond failed with Director %s\n", dir->who());
76 Dmsg1(dbglvl, "cram_auth challenge failed with Director %s\n", dir->who());
80 Jmsg0(jcr, M_FATAL, 0, _("Incorrect password given by Director.\n"
81 "For help, please see: " MANUAL_AUTH_URL "\n"));
86 /* Verify that the remote host is willing to meet our TLS requirements */
87 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
88 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
89 " advertize required TLS support.\n"));
90 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
95 /* Verify that we are willing to meet the remote host's requirements */
96 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
97 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
98 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
103 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
104 /* Engage TLS! Full Speed Ahead! */
105 if (!bnet_tls_server(director->tls_ctx, dir, verify_list)) {
106 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with DIR at \"%s:%d\"\n"),
107 dir->host(), dir->port());
108 auth_success = false;
111 if (director->tls_authenticate) { /* authenticate with tls only? */
112 dir->free_tls(); /* yes, shut it down */
117 stop_bsock_timer(tid);
118 jcr->director = director;
120 return send_hello_ok(dir);
123 Dmsg1(dbglvl, "Unable to authenticate Director at %s.\n", dir->who());
124 Jmsg1(jcr, M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who());
130 int authenticate_filed(JCR *jcr, BSOCK *fd, int FDVersion)
132 int tls_local_need = BNET_TLS_NONE;
133 int tls_remote_need = BNET_TLS_NONE;
134 int compatible = true; /* require md5 compatible FD */
135 bool auth_success = false;
136 alist *verify_list = NULL;
138 /* TLS Requirement */
139 if (me->tls_enable) {
140 if (me->tls_require) {
141 tls_local_need = BNET_TLS_REQUIRED;
143 tls_local_need = BNET_TLS_OK;
147 if (me->tls_authenticate) {
148 tls_local_need = BNET_TLS_REQUIRED;
151 if (me->tls_verify_peer) {
152 verify_list = me->tls_allowed_cns;
155 /* Timeout authentication after 5 mins */
156 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
158 Dmsg0(050, "Challenge FD\n");
159 auth_success = cram_md5_challenge(fd, jcr->sd_auth_key, tls_local_need, compatible);
161 /* Respond to his challenge */
162 Dmsg0(050, "Respond to FD challenge\n");
163 auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible);
165 Dmsg1(dbglvl, "Respond cram-get-auth respond failed with FD: %s\n", fd->who());
168 Dmsg1(dbglvl, "Challenge cram-auth failed with FD: %s\n", fd->who());
172 Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
173 "For help, please see: " MANUAL_AUTH_URL "\n"),
175 auth_success = false;
179 /* Verify that the remote host is willing to meet our TLS requirements */
180 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
181 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
182 " advertize required TLS support.\n"));
183 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
184 auth_success = false;
188 /* Verify that we are willing to meet the remote host's requirements */
189 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
190 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
191 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
192 auth_success = false;
196 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
197 /* Engage TLS! Full Speed Ahead! */
198 if (!bnet_tls_server(me->tls_ctx, fd, verify_list)) {
199 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\"\n"),
200 fd->host(), fd->port());
201 auth_success = false;
204 if (me->tls_authenticate) { /* tls authenticate only? */
205 fd->free_tls(); /* yes, shut it down */
210 stop_bsock_timer(tid);
212 Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
213 "For help, please see: " MANUAL_AUTH_URL "\n"),
217 /* Version 5 of the protocol is a bit special, it is used by both 6.0.0
218 * Enterprise version and 7.0.x Community version, but do not support the
219 * same level of features. As nobody is using the 6.0.0 release, we can
220 * be pretty sure that the FD in version 5 is a community FD.
222 if (auth_success && (FDVersion >= 9 || FDVersion == 5)) {
229 * First prove our identity to the Storage daemon, then
230 * make him prove his identity.
232 bool authenticate_storagedaemon(JCR *jcr)
234 BSOCK *sd = jcr->store_bsock;
235 int tls_local_need = BNET_TLS_NONE;
236 int tls_remote_need = BNET_TLS_NONE;
237 int compatible = true;
238 bool auth_success = false;
241 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
243 /* TLS Requirement */
244 if (have_tls && me->tls_enable) {
245 if (me->tls_require) {
246 tls_local_need = BNET_TLS_REQUIRED;
248 tls_local_need = BNET_TLS_OK;
252 if (me->tls_authenticate) {
253 tls_local_need = BNET_TLS_REQUIRED;
256 if (job_canceled(jcr)) {
257 auth_success = false; /* force quick exit */
261 /* Respond to SD challenge */
262 Dmsg0(050, "Respond to SD challenge\n");
263 auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
264 if (job_canceled(jcr)) {
265 auth_success = false; /* force quick exit */
269 Dmsg1(dbglvl, "cram_respond failed for SD: %s\n", sd->who());
271 /* Now challenge him */
272 Dmsg0(050, "Challenge SD\n");
273 auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
275 Dmsg1(dbglvl, "cram_challenge failed for SD: %s\n", sd->who());
280 Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
281 "Please see " MANUAL_AUTH_URL " for help.\n"));
284 Dmsg0(050, "Authorization with SD is OK\n");
287 /* Verify that the remote host is willing to meet our TLS requirements */
288 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
289 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
290 " advertize required TLS support.\n"));
291 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
292 auth_success = false;
296 /* Verify that we are willing to meet the remote host's requirements */
297 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
298 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
299 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
300 auth_success = false;
304 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
305 /* Engage TLS! Full Speed Ahead! */
306 if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
307 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
308 auth_success = false;
311 if (me->tls_authenticate) { /* tls authentication only? */
312 sd->free_tls(); /* yes, shutdown tls */
315 if (sd->recv() <= 0) {
316 auth_success = false;
319 sscanf(sd->msg, "3000 OK Hello %d", &sd_version);
320 /* At this point, we have successfully connected */
323 /* Destroy session key */
324 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
325 stop_bsock_timer(tid);
326 /* Single thread all failures to avoid DOS */