1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 Kern Sibbald
5
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.
8
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.
13
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
16
17 Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20 * Hello routines for Storage daemon.
21 *
22 * This file contains all the code relating to reading and writing of
23 * all Hello commands between the daemons.
24 *
25 * Written by Kern Sibbald, June 2014
26 *
27 */
28
29
30 #include "bacula.h"
31 #include "stored.h"
32
33 extern STORES *me; /* our Global resource */
34
35 const int dbglvl = 50;
36
37 static char hello_sd[] = "Hello Bacula SD: Start Job %s %d %d tlspsk=%d\n";
38
39 static char Sorry[] = "3999 No go\n";
40 static char OK_hello[] = "3000 OK Hello %d\n";
41
42 /* We store caps in a special structure to update JCR
43 * only after the auth phase
44 */
45 class caps_fd {
46 public:
47 int32_t fd_dedup;
48 int32_t fd_rehydration;
caps_fd()49 caps_fd() :
50 fd_dedup(0),
51 fd_rehydration(0)
52 {};
scan(const char * msg)53 bool scan(const char *msg) {
54 return sscanf(msg, "fdcaps: dedup=%ld rehydration=%ld",
55 &fd_dedup, &fd_rehydration) == 2;
56 }
57 /* Set variable that we got in JCR */
set(JCR * jcr)58 void set(JCR *jcr) {
59 jcr->fd_dedup = fd_dedup;
60 jcr->fd_rehydration = fd_rehydration;
61 };
62 };
63
64 static bool recv_fdcaps(JCR *jcr, BSOCK *cl, caps_fd *caps);
65 static bool send_sdcaps(JCR *jcr, BSOCK *cl);
66 static bool recv_sdcaps(JCR *jcr, BSOCK *cl);
67 static bool send_fdcaps(JCR *jcr, BSOCK *cl);
68
69
70 /*********************************************************************
71 *
72 * Validate hello from the Director.
73 *
74 * Returns: true if Hello is good.
75 * false if Hello is bad.
76 */
validate_dir_hello(JCR * jcr)77 bool validate_dir_hello(JCR* jcr)
78 {
79 POOLMEM *dirname;
80 DIRRES *director = NULL;
81 int dir_version = 0;
82 BSOCK *dir = jcr->dir_bsock;
83
84 if (dir->msglen < 25 || dir->msglen > 500) {
85 Dmsg2(dbglvl, "Bad Hello command from Director at %s. Len=%d.\n",
86 dir->who(), dir->msglen);
87 Qmsg2(jcr, M_SECURITY, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
88 dir->who(), dir->msglen);
89 sleep(5);
90 return false;
91 }
92 dirname = get_pool_memory(PM_MESSAGE);
93 dirname = check_pool_memory_size(dirname, dir->msglen);
94 dir->tlspsk_remote = 0;
95 if (scan_string(dir->msg, "Hello SD: Bacula Director %127s calling %d tlspsk=%d",
96 dirname, &dir_version, &dir->tlspsk_remote) != 3 &&
97 scan_string(dir->msg, "Hello SD: Bacula Director %127s calling %d",
98 dirname, &dir_version) != 2 &&
99 scan_string(dir->msg, "Hello SD: Bacula Director %127s calling",
100 dirname) != 1) {
101 dir->msg[100] = 0;
102 Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n",
103 dir->who(), dir->msg);
104 Qmsg2(jcr, M_SECURITY, 0, _("Bad Hello command from Director at %s: %s\n"),
105 dir->who(), dir->msg);
106 free_pool_memory(dirname);
107 sleep(5);
108 return false;
109 }
110
111 if (dir_version >= 1 && me->comm_compression) {
112 dir->set_compress();
113 } else {
114 dir->clear_compress();
115 Dmsg0(050, "**** No SD compression to Dir\n");
116 }
117 director = NULL;
118 unbash_spaces(dirname);
119 foreach_res(director, R_DIRECTOR) {
120 if (strcasecmp(director->hdr.name, dirname) == 0) {
121 break;
122 }
123 }
124 if (!director) {
125 Dmsg2(dbglvl, "Connection from unknown Director %s at %s rejected.\n",
126 dirname, dir->who());
127 Qmsg2(jcr, M_SECURITY, 0, _("Connection from unknown Director %s at %s rejected.\n"
128 "Please see " MANUAL_AUTH_URL " for help.\n"),
129 dirname, dir->who());
130 free_pool_memory(dirname);
131 sleep(5);
132 return false;
133 }
134 jcr->director = director;
135 free_pool_memory(dirname);
136 return true;
137 }
138
139 /*
140 * After receiving a connection (in dircmd.c) if it is
141 * from the File daemon, this routine is called.
142 */
handle_client_connection(BSOCK * fd)143 void handle_client_connection(BSOCK *fd)
144 {
145 JCR *jcr;
146 int fd_version = 0;
147 int sd_version = 0;
148 char job_name[500];
149 caps_fd fdcaps;
150 /*
151 * Do a sanity check on the message received
152 */
153 if (fd->msglen < 25 || fd->msglen > (int)sizeof(job_name)) {
154 Pmsg1(000, "<filed: %s", fd->msg);
155 Qmsg2(NULL, M_SECURITY, 0, _("Invalid connection from %s. Len=%d\n"), fd->who(), fd->msglen);
156 bmicrosleep(5, 0); /* make user wait 5 seconds */
157 fd->destroy();
158 return;
159 }
160
161 Dmsg1(dbglvl, "authenticate: %s", fd->msg);
162 /*
163 * See if this is a File daemon connection. If so
164 * call FD handler.
165 */
166 fd->tlspsk_remote = 0;
167 if (scan_string(fd->msg, "Hello Bacula SD: Start Job %127s %d %d tlspsk=%d", job_name, &fd_version, &sd_version, &fd->tlspsk_remote) != 4 &&
168 scan_string(fd->msg, "Hello Bacula SD: Start Job %127s %d %d", job_name, &fd_version, &sd_version) != 3 &&
169 scan_string(fd->msg, "Hello Bacula SD: Start Job %127s %d tlspsk=%d", job_name, &fd_version, &fd->tlspsk_remote) != 3 &&
170 scan_string(fd->msg, "Hello Bacula SD: Start Job %127s %d", job_name, &fd_version) != 2 &&
171 scan_string(fd->msg, "Hello FD: Bacula Storage calling Start Job %127s %d", job_name, &sd_version) != 2 &&
172 scan_string(fd->msg, "Hello Start Job %127s", job_name) != 1) {
173 Qmsg2(NULL, M_SECURITY, 0, _("Invalid Hello from %s. Len=%d\n"), fd->who(), fd->msglen);
174 sleep(5);
175 fd->destroy();
176 return;
177 }
178
179 if (!(jcr=get_jcr_by_full_name(job_name))) {
180 Qmsg1(NULL, M_SECURITY, 0, _("Client connect failed: Job name not found: %s\n"), job_name);
181 Dmsg1(3, "**** Job \"%s\" not found.\n", job_name);
182 sleep(5);
183 fd->destroy();
184 return;
185 }
186
187 /* After this point, we can use bail_out */
188 Dmsg1(100, "Found Client Job %s\n", job_name);
189 if (jcr->authenticated) {
190 Jmsg3(jcr, M_SECURITY, 0, _("A Client \"%s\" tried to authenticate for Job %s, "
191 "but the Job is already authenticated with \"%s\".\n"),
192 fd->who(), jcr->Job, jcr->file_bsock?jcr->file_bsock->who():"N/A");
193 Dmsg2(050, "Hey!!!! JobId %u Job %s already authenticated.\n",
194 (uint32_t)jcr->JobId, jcr->Job);
195 goto bail_out;
196 }
197
198 fd->set_jcr(jcr);
199 Dmsg2(050, "fd_version=%d sd_version=%d\n", fd_version, sd_version);
200
201 /* Turn on compression for newer FDs, except for community version */
202 if ((fd_version >= 9 || sd_version >= 1) && fd_version != 213 && me->comm_compression) {
203 fd->set_compress(); /* set compression allowed */
204 } else {
205 fd->clear_compress();
206 Dmsg0(050, "*** No SD compression to FD\n");
207 }
208
209 /* The community version 213 doesn't send caps, the 215 version might do it */
210 if (fd_version >= 12 && fd_version != 213 && fd_version != 214) {
211 /* Send and get capabilities */
212 if (!send_sdcaps(jcr, fd)) {
213 goto bail_out;
214 }
215 if (!recv_fdcaps(jcr, fd, &fdcaps)) {
216 goto bail_out;
217 }
218 }
219
220 /*
221 * Authenticate the Client (FD or SD)
222 */
223 jcr->lock_auth(); /* Ensure that only one thread is dealing with auth */
224 if (jcr->authenticated) {
225 Jmsg2(jcr, M_SECURITY, 0, _("A Client \"%s\" tried to authenticate for Job %s, "
226 "but the job is already authenticated.\n"),
227 fd->who(), jcr->Job);
228
229 } else if (!authenticate_filed(jcr, fd, fd_version)) {
230 Dmsg1(50, "Authentication failed Job %s\n", jcr->Job);
231 /* Job not yet started, we can cancel */
232 Jmsg(jcr, M_SECURITY, 0, _("Unable to authenticate File daemon\n"));
233
234 } else {
235 Dmsg2(050, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job);
236 jcr->file_bsock = fd;
237 jcr->FDVersion = fd_version;
238 jcr->SDVersion = sd_version;
239 fdcaps.set(jcr);
240 jcr->authenticated = true;
241
242 if (sd_version > 0) {
243 jcr->sd_client = true;
244 }
245 }
246 jcr->unlock_auth();
247
248 if (!jcr->authenticated) {
249 jcr->setJobStatus(JS_ErrorTerminated);
250 }
251
252 Dmsg4(050, "=== Auth %s, unblock Job %s jid=%d sd_ver=%d\n",
253 jcr->authenticated?"OK":"KO", job_name, jcr->JobId, sd_version);
254
255 bail_out:
256 /* file_bsock might be NULL or a previous BSOCK */
257 if (jcr->file_bsock != fd) {
258 fd->destroy();
259 }
260 pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
261 free_jcr(jcr);
262 if (!jcr->authenticated) {
263 sleep(5);
264 }
265 return;
266 }
267
268
is_client_connection(BSOCK * bs)269 bool is_client_connection(BSOCK *bs)
270 {
271 return
272 scan_string(bs->msg, "Hello Bacula SD: Start Job ") == 0 ||
273 scan_string(bs->msg, "Hello FD: Bacula Storage calling Start Job ") == 0 ||
274 scan_string(bs->msg, "Hello Start Job ") == 0;
275 }
276
277 /*
278 * If sd_calls_client, we must read the client's response to
279 * the hello we previously sent.
280 */
read_client_hello(JCR * jcr)281 bool read_client_hello(JCR *jcr)
282 {
283 int i;
284 int stat;
285 int fd_version = 0;
286 int sd_version = 0;
287 BSOCK *cl = jcr->file_bsock;
288 char job_name[500];
289 caps_fd fdcaps;
290
291 /* We connected to Client, so finish work */
292 if (!cl) {
293 Jmsg0(jcr, M_FATAL, 0, _("Client socket not open. Could not connect to Client.\n"));
294 Dmsg0(050, "Client socket not open. Could not connect to Client.\n");
295 return false;
296 }
297 /* Get response to Hello command sent earlier */
298 Dmsg0(050, "Read Hello command from Client\n");
299 for (i=0; i<60; i++) {
300 stat = cl->recv();
301 if (stat <= 0) {
302 bmicrosleep(1, 0);
303 } else {
304 break;
305 }
306 }
307 if (stat <= 0) {
308 berrno be;
309 Jmsg1(jcr, M_FATAL, 0, _("Recv request to Client failed. ERR=%s\n"),
310 be.bstrerror());
311 Dmsg1(050, _("Recv request to Client failed. ERR=%s\n"), be.bstrerror());
312 return false;
313 }
314 Dmsg1(dbglvl, "authenticate: %s", cl->msg);
315 cl->tlspsk_remote = 0;
316 if (scan_string(cl->msg, "Hello Bacula SD: Start Job %127s %d %d tlspsk=%d", job_name, &fd_version, &sd_version, &cl->tlspsk_remote) != 4 &&
317 scan_string(cl->msg, "Hello Bacula SD: Start Job %127s %d tlspsk=%d", job_name, &fd_version, &cl->tlspsk_remote) != 3 &&
318 scan_string(cl->msg, "Hello Bacula SD: Start Job %127s %d %d", job_name, &fd_version, &sd_version) != 3 &&
319 scan_string(cl->msg, "Hello Bacula SD: Start Job %127s %d", job_name, &fd_version) != 2) {
320 Jmsg1(jcr, M_FATAL, 0, _("Bad Hello from Client: %s.\n"), cl->msg);
321 Dmsg1(050, _("Bad Hello from Client: %s.\n"), cl->msg);
322 return false;
323 }
324
325 unbash_spaces(job_name);
326 jcr->FDVersion = fd_version;
327 jcr->SDVersion = sd_version;
328 Dmsg1(050, "FDVersion=%d\n", fd_version);
329 /* Turn on compression for newer FDs, except for Community version */
330 if (jcr->FDVersion >= 9 && jcr->FDVersion != 213 && me->comm_compression) {
331 cl->set_compress(); /* set compression allowed */
332 } else {
333 cl->clear_compress();
334 Dmsg0(050, "*** No SD compression to FD\n");
335 }
336
337 /* The community version 213 doesn't have caps */
338 if (fd_version >= 12 && fd_version != 213 && fd_version != 214) {
339 /* Send and get capabilities */
340 if (!send_sdcaps(jcr, cl)) {
341 return false;
342 }
343 if (!recv_fdcaps(jcr, cl, &fdcaps)) {
344 return false;
345 }
346 fdcaps.set(jcr);
347 }
348 return true;
349 }
350
351 /*
352 * Send Hello OK to DIR or FD
353 */
send_hello_ok(BSOCK * bs)354 bool send_hello_ok(BSOCK *bs)
355 {
356 return bs->fsend(OK_hello, SD_VERSION);
357 }
358
send_sorry(BSOCK * bs)359 bool send_sorry(BSOCK *bs)
360 {
361 return bs->fsend(Sorry);
362 }
363
364 /*
365 * We are acting as a client, so send Hello to the SD.
366 */
send_hello_sd(JCR * jcr,char * Job,int tlspsk)367 bool send_hello_sd(JCR *jcr, char *Job, int tlspsk)
368 {
369 bool rtn;
370 BSOCK *sd = jcr->store_bsock;
371
372 bash_spaces(Job);
373 rtn = sd->fsend(hello_sd, Job, FD_VERSION, SD_VERSION, tlspsk);
374 unbash_spaces(Job);
375 Dmsg1(100, "Send to SD: %s\n", sd->msg);
376 if (!rtn) {
377 return false;
378 }
379
380 /* Receive and send capabilities */
381 if (!recv_sdcaps(jcr, sd)) {
382 return false;
383 }
384 if (!send_fdcaps(jcr, sd)) {
385 return false;
386 }
387 return true;
388 }
389
390 /*
391 * We are SD so send Hello to client
392 * Note: later the Client will send us a Hello.
393 */
send_hello_client(JCR * jcr,char * Job)394 bool send_hello_client(JCR *jcr, char *Job)
395 {
396 bool rtn;
397 BSOCK *cl = jcr->file_bsock;
398
399 bash_spaces(Job);
400 // This is a "dummy" hello, just to connect to the waiting FD job
401 // No need of a TLS-PSK field here, the FD will send the "real" TLS-PSK field
402 rtn = cl->fsend("Hello FD: Bacula Storage calling Start Job %s %d\n", Job, SD_VERSION);
403 unbash_spaces(Job);
404 if (!rtn) {
405 return false;
406 }
407 return rtn;
408 }
409
410 /*
411 * Capabilities Exchange
412 *
413 * Immediately after the Hello is sent/received by the SD, the SD sends
414 * its capabilities to the client (FD), and the client responds by
415 * sending its capabilities.
416 */
send_sdcaps(JCR * jcr,BSOCK * cl)417 static bool send_sdcaps(JCR *jcr, BSOCK *cl)
418 {
419 int stat;
420 int32_t dedup = 0;
421 int32_t hash = DEDUP_DEFAULT_HASH_ID;
422 uint32_t block_size = DEDUP_IDEAL_BLOCK_SIZE;
423 uint32_t min_block_size = DEDUP_MIN_BLOCK_SIZE;
424 uint32_t max_block_size = DEDUP_MAX_BLOCK_SIZE;
425
426 /* Set dedup, if SD is dedup enabled and device is dedup type */
427 if (jcr->dcr) {
428 dedup = jcr->dcr->dev->dev_type==B_DEDUP_DEV;
429 }
430 Dmsg5(200, ">Send sdcaps: dedup=%ld hash=%ld dedup_block=%lu min_dedup_block=%lu max_dedup_block=%lu\n",
431 dedup, hash, block_size, min_block_size, max_block_size);
432 stat = cl->fsend("sdcaps: dedup=%ld hash=%ld dedup_block=%lu min_dedup_block=%lu max_dedup_block=%lu\n",
433 dedup, hash, block_size, min_block_size, max_block_size);
434 if (!stat) {
435 berrno be;
436 Jmsg1(jcr, M_FATAL, 0, _("Send caps to Client failed. ERR=%s\n"),
437 be.bstrerror());
438 Dmsg1(050, _("Send caps to Client failed. ERR=%s\n"), be.bstrerror());
439 return false;
440 }
441 return true;
442 }
443
recv_fdcaps(JCR * jcr,BSOCK * cl,caps_fd * caps)444 static bool recv_fdcaps(JCR *jcr, BSOCK *cl, caps_fd *caps)
445 {
446 int stat;
447
448 stat = cl->recv();
449 if (stat <= 0) {
450 berrno be;
451 Jmsg1(jcr, M_FATAL, 0, _("Recv caps from Client failed. ERR=%s\n"),
452 be.bstrerror());
453 Dmsg1(050, _("Recv caps from Client failed. ERR=%s\n"), be.bstrerror());
454 return false;
455 }
456 if (!caps->scan(cl->msg)) {
457 Jmsg1(jcr, M_FATAL, 0, _("Recv bad caps from Client: %s.\n"), cl->msg);
458 Dmsg1(050, _("Recv bad caps from Client %s\n"), cl->msg);
459 return false;
460 }
461 return true;
462 }
463
464 /* ======================== */
465
466
467 /*
468 * Note: for the following two subroutines, during copy/migration
469 * jobs, we are acting as a File daemon.
470 */
send_fdcaps(JCR * jcr,BSOCK * sd)471 static bool send_fdcaps(JCR *jcr, BSOCK *sd)
472 {
473 int dedup = 0;
474 if (jcr->dcr->device->dev_type == B_DEDUP_DEV) {
475 dedup = 1;
476 }
477 return sd->fsend("fdcaps: dedup=%d rehydration=%d\n", dedup, dedup);
478 }
479
480 /* Result not used */
recv_sdcaps(JCR * jcr,BSOCK * sd)481 static bool recv_sdcaps(JCR *jcr, BSOCK *sd)
482 {
483 int stat;
484 int32_t dedup = 0;
485 int32_t hash = 0;
486 int32_t block_size = 0;
487 int32_t min_block_size = 0;
488 int32_t max_block_size = 0;
489
490
491 stat = sd->recv();
492 if (stat <= 0) {
493 berrno be;
494 Jmsg1(jcr, M_FATAL, 0, _("Recv caps from SD failed. ERR=%s\n"),
495 be.bstrerror());
496 Dmsg1(050, _("Recv caps from SD failed. ERR=%s\n"), be.bstrerror());
497 return false;
498 }
499
500 if (sscanf(sd->msg, "sdcaps: dedup=%ld hash=%ld dedup_block=%ld min_dedup_block=%ld max_dedup_block=%ld",
501 &dedup, &hash, &block_size, &min_block_size, &max_block_size) != 5) {
502 Jmsg1(jcr, M_FATAL, 0, _("Bad caps from SD: %s.\n"), sd->msg);
503 Dmsg1(050, _("Bad caps from SD: %s\n"), sd->msg);
504 return false;
505 }
506 Dmsg5(200, "sdcaps: dedup=%ld hash=%ld dedup_block=%ld min_dedup_block=%ld max_dedup_block=%ld\n",
507 dedup, hash, block_size, min_block_size, max_block_size);
508 return true;
509 }
510