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