2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 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 Bacula® is a registered trademark of Kern Sibbald.
19 * Written by Kern Sibbald, October 2000
27 extern STORES *me; /* our Global resource */
30 const int dbglvl = 50;
32 /* Version at end of Hello
33 * prior to 06Aug13 no version
34 * 1 06Aug13 - added comm line compression
35 * 2 13Dec13 - added api version to status command
36 * 3 22Feb14 - Added SD->SD with SD_Calls_Client
40 static char hello_sd[] = "Hello Bacula SD: Start Job %s %d %d\n";
43 static char Dir_sorry[] = "3999 No go\n";
44 static char OK_hello[] = "3000 OK Hello %d\n";
46 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
48 /*********************************************************************
52 static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
55 DIRRES *director = NULL;
56 int tls_local_need = BNET_TLS_NONE;
57 int tls_remote_need = BNET_TLS_NONE;
58 int compatible = true; /* require md5 compatible DIR */
59 bool auth_success = false;
60 alist *verify_list = NULL;
63 if (rcode != R_DIRECTOR) {
64 Dmsg1(dbglvl, "I only authenticate Directors, not %d\n", rcode);
65 Jmsg1(jcr, M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode);
68 if (bs->msglen < 25 || bs->msglen > 500) {
69 Dmsg2(dbglvl, "Bad Hello command from Director at %s. Len=%d.\n",
70 bs->who(), bs->msglen);
71 Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
72 bs->who(), bs->msglen);
75 dirname = get_pool_memory(PM_MESSAGE);
76 dirname = check_pool_memory_size(dirname, bs->msglen);
78 if (sscanf(bs->msg, "Hello SD: Bacula Director %127s calling %d",
79 dirname, &dir_version) != 2 &&
80 sscanf(bs->msg, "Hello SD: Bacula Director %127s calling",
83 Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n",
85 Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
87 free_pool_memory(dirname);
91 unbash_spaces(dirname);
92 foreach_res(director, rcode) {
93 if (strcasecmp(director->hdr.name, dirname) == 0) {
98 Dmsg2(dbglvl, "Connection from unknown Director %s at %s rejected.\n",
100 Jmsg2(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"
101 "Please see " MANUAL_AUTH_URL " for help.\n"),
103 free_pool_memory(dirname);
107 /* TLS Requirement */
108 if (director->tls_enable) {
109 if (director->tls_require) {
110 tls_local_need = BNET_TLS_REQUIRED;
112 tls_local_need = BNET_TLS_OK;
116 if (director->tls_authenticate) {
117 tls_local_need = BNET_TLS_REQUIRED;
120 if (director->tls_verify_peer) {
121 verify_list = director->tls_allowed_cns;
124 /* Timeout Hello after 10 mins */
125 btimer_t *tid = start_bsock_timer(bs, AUTH_TIMEOUT);
126 auth_success = cram_md5_challenge(bs, director->password, tls_local_need, compatible);
128 auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
130 Dmsg1(dbglvl, "cram_get_auth respond failed with Director %s\n", bs->who());
133 Dmsg1(dbglvl, "cram_auth challenge failed with Director %s\n", bs->who());
137 Jmsg0(jcr, M_FATAL, 0, _("Incorrect password given by Director.\n"
138 "Please see " MANUAL_AUTH_URL " for help.\n"));
139 auth_success = false;
143 /* Verify that the remote host is willing to meet our TLS requirements */
144 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
145 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
146 " advertize required TLS support.\n"));
147 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
148 auth_success = false;
152 /* Verify that we are willing to meet the remote host's requirements */
153 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
154 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
155 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
156 auth_success = false;
160 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
161 /* Engage TLS! Full Speed Ahead! */
162 if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
163 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with DIR at \"%s:%d\"\n"),
164 bs->host(), bs->port());
165 auth_success = false;
168 if (director->tls_authenticate) { /* authenticate with tls only? */
169 bs->free_tls(); /* yes, shut it down */
174 stop_bsock_timer(tid);
175 free_pool_memory(dirname);
176 jcr->director = director;
181 * Inititiate the message channel with the Director.
182 * He has made a connection to our server.
184 * Basic tasks done here:
185 * Assume the Hello message is already in the input
186 * buffer. We then authenticate him.
187 * Get device, media, and pool information from Director
189 * This is the channel across which we will send error
190 * messages and job status information.
192 int authenticate_director(JCR *jcr)
194 BSOCK *dir = jcr->dir_bsock;
196 if (!authenticate(R_DIRECTOR, dir, jcr)) {
197 dir->fsend(Dir_sorry);
198 Dmsg1(dbglvl, "Unable to authenticate Director at %s.\n", dir->who());
199 Jmsg1(jcr, M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who());
203 return dir->fsend(OK_hello, SD_VERSION);
206 int authenticate_filed(JCR *jcr)
208 BSOCK *fd = jcr->file_bsock;
209 int tls_local_need = BNET_TLS_NONE;
210 int tls_remote_need = BNET_TLS_NONE;
211 int compatible = true; /* require md5 compatible FD */
212 bool auth_success = false;
213 alist *verify_list = NULL;
215 /* TLS Requirement */
216 if (me->tls_enable) {
217 if (me->tls_require) {
218 tls_local_need = BNET_TLS_REQUIRED;
220 tls_local_need = BNET_TLS_OK;
224 if (me->tls_authenticate) {
225 tls_local_need = BNET_TLS_REQUIRED;
228 if (me->tls_verify_peer) {
229 verify_list = me->tls_allowed_cns;
232 /* Timeout Hello after 5 mins */
233 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
235 Dmsg0(050, "Challenge FD\n");
236 auth_success = cram_md5_challenge(fd, jcr->sd_auth_key, tls_local_need, compatible);
238 /* Respond to his challenge */
239 Dmsg0(050, "Respond to FD challenge\n");
240 auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible);
242 Dmsg1(dbglvl, "Respond cram-get-auth respond failed with FD: %s\n", fd->who());
245 Dmsg1(dbglvl, "Challenge cram-auth failed with FD: %s\n", fd->who());
249 Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
250 "Please see " MANUAL_AUTH_URL " for help.\n"),
252 auth_success = false;
256 /* Verify that the remote host is willing to meet our TLS requirements */
257 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
258 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
259 " advertize required TLS support.\n"));
260 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
261 auth_success = false;
265 /* Verify that we are willing to meet the remote host's requirements */
266 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
267 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
268 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
269 auth_success = false;
273 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
274 /* Engage TLS! Full Speed Ahead! */
275 if (!bnet_tls_server(me->tls_ctx, fd, verify_list)) {
276 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\"\n"),
277 fd->host(), fd->port());
278 auth_success = false;
281 if (me->tls_authenticate) { /* tls authenticate only? */
282 fd->free_tls(); /* yes, shut it down */
287 stop_bsock_timer(tid);
289 Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
290 "Please see " MANUAL_AUTH_URL " for help.\n"),
293 jcr->authenticated = auth_success;
294 if (auth_success && jcr->FDVersion >= 5) {
295 /* Send hello and our version to FD */
296 fd->fsend(OK_hello, SD_VERSION);
302 * First prove our identity to the Storage daemon, then
303 * make him prove his identity.
305 bool authenticate_storagedaemon(JCR *jcr, char *Job)
307 BSOCK *sd = jcr->store_bsock;
308 int tls_local_need = BNET_TLS_NONE;
309 int tls_remote_need = BNET_TLS_NONE;
310 int compatible = true;
311 bool auth_success = false;
314 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
316 /* TLS Requirement */
317 if (have_tls && me->tls_enable) {
318 if (me->tls_require) {
319 tls_local_need = BNET_TLS_REQUIRED;
321 tls_local_need = BNET_TLS_OK;
325 if (me->tls_authenticate) {
326 tls_local_need = BNET_TLS_REQUIRED;
329 if (job_canceled(jcr)) {
330 auth_success = false; /* force quick exit */
336 sd->fsend(hello_sd, Job, FD_VERSION, SD_VERSION);
337 Dmsg1(100, "Send to SD: %s\n", sd->msg);
339 /* Respond to SD challenge */
340 Dmsg0(050, "Respond to SD challenge\n");
341 auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
342 if (job_canceled(jcr)) {
343 auth_success = false; /* force quick exit */
347 Dmsg1(dbglvl, "cram_respond failed for SD: %s\n", sd->who());
349 /* Now challenge him */
350 Dmsg0(050, "Challenge SD\n");
351 auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
353 Dmsg1(dbglvl, "cram_challenge failed for SD: %s\n", sd->who());
358 Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
359 "Please see " MANUAL_AUTH_URL " for help.\n"));
362 Dmsg0(050, "Authorization with SD is OK\n");
365 /* Verify that the remote host is willing to meet our TLS requirements */
366 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
367 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
368 " advertize required TLS support.\n"));
369 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
370 auth_success = false;
374 /* Verify that we are willing to meet the remote host's requirements */
375 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
376 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
377 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
378 auth_success = false;
382 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
383 /* Engage TLS! Full Speed Ahead! */
384 if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
385 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
386 auth_success = false;
389 if (me->tls_authenticate) { /* tls authentication only? */
390 sd->free_tls(); /* yes, shutdown tls */
393 if (sd->recv() <= 0) {
394 auth_success = false;
397 sscanf(sd->msg, "3000 OK Hello %d", &sd_version);
399 /* At this point, we have successfully connected */
402 /* Destroy session key */
403 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
404 stop_bsock_timer(tid);
405 /* Single thread all failures to avoid DOS */