]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/filed.c
Implement a security enhancement: TLS authentication but no
[bacula/bacula] / bacula / src / filed / filed.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *  Bacula File Daemon
30  *
31  *    Kern Sibbald, March MM
32  *
33  *   Version $Id$
34  *
35  */
36
37 #include "bacula.h"
38 #include "filed.h"
39
40 /* Imported Functions */
41 extern void *handle_client_request(void *dir_sock);
42
43 /* Forward referenced functions */
44 void terminate_filed(int sig);
45 static bool check_resources();
46
47 /* Exported variables */
48 CLIENT *me;                           /* my resource */
49 bool no_signals = false;
50 void *start_heap;
51
52
53 #define CONFIG_FILE "bacula-fd.conf" /* default config file */
54
55 char *configfile = NULL;
56 static bool foreground = false;
57 static workq_t dir_workq;             /* queue of work from Director */
58 static pthread_t server_tid;
59
60
61 static void usage()
62 {
63    Pmsg3(-1, _(
64 PROG_COPYRIGHT
65 "\nVersion: %s (%s)\n\n"
66 "Usage: bacula-fd [-f -s] [-c config_file] [-d debug_level]\n"
67 "        -c <file>   use <file> as configuration file\n"
68 "        -d <nn>     set debug level to <nn>\n"
69 "        -dt         print timestamp in debug output\n"
70 "        -f          run in foreground (for debugging)\n"
71 "        -g          groupid\n"
72 "        -s          no signals (for debugging)\n"
73 "        -t          test configuration file and exit\n"
74 "        -u          userid\n"
75 "        -v          verbose user messages\n"
76 "        -?          print this message.\n"
77 "\n"), 2000, VERSION, BDATE);
78    exit(1);
79 }
80
81
82 /*********************************************************************
83  *
84  *  Main Bacula Unix Client Program
85  *
86  */
87 #if defined(HAVE_WIN32)
88 #define main BaculaMain
89 #endif
90
91 int main (int argc, char *argv[])
92 {
93    int ch;
94    bool test_config = false;
95    char *uid = NULL;
96    char *gid = NULL;
97
98    start_heap = sbrk(0);
99    setlocale(LC_ALL, "");
100    bindtextdomain("bacula", LOCALEDIR);
101    textdomain("bacula");
102
103    init_stack_dump();
104    my_name_is(argc, argv, "bacula-fd");
105    init_msg(NULL, NULL);
106    daemon_start_time = time(NULL);
107
108    while ((ch = getopt(argc, argv, "c:d:fg:stu:v?")) != -1) {
109       switch (ch) {
110       case 'c':                    /* configuration file */
111          if (configfile != NULL) {
112             free(configfile);
113          }
114          configfile = bstrdup(optarg);
115          break;
116
117       case 'd':                    /* debug level */
118          if (*optarg == 't') {
119             dbg_timestamp = true;
120          } else {
121             debug_level = atoi(optarg);
122             if (debug_level <= 0) {
123                debug_level = 1;
124             }
125          }
126          break;
127
128       case 'f':                    /* run in foreground */
129          foreground = true;
130          break;
131
132       case 'g':                    /* set group */
133          gid = optarg;
134          break;
135
136       case 's':
137          no_signals = true;
138          break;
139
140       case 't':
141          test_config = true;
142          break;
143
144       case 'u':                    /* set userid */
145          uid = optarg;
146          break;
147
148       case 'v':                    /* verbose */
149          verbose++;
150          break;
151
152       case '?':
153       default:
154          usage();
155
156       }
157    }
158    argc -= optind;
159    argv += optind;
160
161    if (argc) {
162       if (configfile != NULL)
163          free(configfile);
164       configfile = bstrdup(*argv);
165       argc--;
166       argv++;
167    }
168    if (argc) {
169       usage();
170    }
171
172    server_tid = pthread_self();
173    if (!no_signals) {
174       init_signals(terminate_filed);
175    } else {
176       /* This reduces the number of signals facilitating debugging */
177       watchdog_sleep_time = 120;      /* long timeout for debugging */
178    }
179
180    if (configfile == NULL) {
181       configfile = bstrdup(CONFIG_FILE);
182    }
183
184    parse_config(configfile);
185
186    if (init_crypto() != 0) {
187       Emsg0(M_ERROR, 0, _("Cryptography library initialization failed.\n"));
188       terminate_filed(1);
189    }
190
191    if (!check_resources()) {
192       Emsg1(M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
193       terminate_filed(1);
194    }
195
196    set_working_directory(me->working_directory);
197
198    if (test_config) {
199       terminate_filed(0);
200    }
201
202    if (!foreground) {
203       daemon_start();
204       init_stack_dump();              /* set new pid */
205    }
206
207    /* Maximum 1 daemon at a time */
208    create_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
209    read_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
210
211    drop(uid, gid);
212
213 #ifdef BOMB
214    me += 1000000;
215 #endif
216
217    init_python_interpreter(me->hdr.name, me->scripts_directory, "FDStartUp");
218
219    set_thread_concurrency(10);
220
221    if (!no_signals) {
222       start_watchdog();               /* start watchdog thread */
223       init_jcr_subsystem();           /* start JCR watchdogs etc. */
224    }
225    server_tid = pthread_self();
226
227    /* Become server, and handle requests */
228    IPADDR *p;
229    foreach_dlist(p, me->FDaddrs) {
230       Dmsg1(10, "filed: listening on port %d\n", p->get_port_host_order());
231    }
232    bnet_thread_server(me->FDaddrs, me->MaxConcurrentJobs, &dir_workq, handle_client_request);
233
234    terminate_filed(0);
235    exit(0);                           /* should never get here */
236 }
237
238 void terminate_filed(int sig)
239 {
240    static bool already_here = false;
241
242    if (already_here) {
243       bmicrosleep(2, 0);              /* yield */
244       exit(1);                        /* prevent loops */
245    }
246    already_here = true;
247    stop_watchdog();
248
249    bnet_stop_thread_server(server_tid);
250    generate_daemon_event(NULL, "Exit");
251    write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
252    delete_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
253
254    if (configfile != NULL) {
255       free(configfile);
256    }
257
258    if (debug_level > 0) {
259       print_memory_pool_stats();
260    }
261    term_msg();
262    free_config_resources();
263    cleanup_crypto();
264    close_memory_pool();               /* release free memory in pool */
265    sm_dump(false);                    /* dump orphaned buffers */
266    exit(sig);
267 }
268
269 /*
270 * Make a quick check to see that we have all the
271 * resources needed.
272 */
273 static bool check_resources()
274 {
275    bool OK = true;
276    DIRRES *director;
277    bool need_tls;
278
279    LockRes();
280
281    me = (CLIENT *)GetNextRes(R_CLIENT, NULL);
282    if (!me) {
283       Emsg1(M_FATAL, 0, _("No File daemon resource defined in %s\n"
284             "Without that I don't know who I am :-(\n"), configfile);
285       OK = false;
286    } else {
287       if (GetNextRes(R_CLIENT, (RES *) me) != NULL) {
288          Emsg1(M_FATAL, 0, _("Only one Client resource permitted in %s\n"),
289               configfile);
290          OK = false;
291       }
292       my_name_is(0, NULL, me->hdr.name);
293       if (!me->messages) {
294          me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
295          if (!me->messages) {
296              Emsg1(M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
297              OK = false;
298          }
299       }
300       /* tls_require implies tls_enable */
301       if (me->tls_require) {
302 #ifndef HAVE_TLS
303          Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
304          OK = false;
305 #else
306          me->tls_enable = true;
307 #endif
308       }
309       need_tls = me->tls_enable || me->tls_authenticate;
310
311       if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && need_tls) {
312          Emsg1(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
313             " or \"TLS CA Certificate Dir\" are defined for File daemon in %s.\n"),
314                             configfile);
315         OK = false;
316       }
317
318       /* If everything is well, attempt to initialize our per-resource TLS context */
319       if (OK && (need_tls || me->tls_require)) {
320          /* Initialize TLS context:
321           * Args: CA certfile, CA certdir, Certfile, Keyfile,
322           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
323          me->tls_ctx = new_tls_context(me->tls_ca_certfile,
324             me->tls_ca_certdir, me->tls_certfile, me->tls_keyfile,
325             NULL, NULL, NULL, true);
326
327          if (!me->tls_ctx) { 
328             Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
329                                 me->hdr.name, configfile);
330             OK = false;
331          }
332       }
333
334       if (me->pki_encrypt || me->pki_sign) {
335 #ifndef HAVE_CRYPTO
336          Jmsg(NULL, M_FATAL, 0, _("PKI encryption/signing enabled but not compiled into Bacula.\n"));
337          OK = false;
338 #endif
339       }
340
341       /* pki_encrypt implies pki_sign */
342       if (me->pki_encrypt) {
343          me->pki_sign = true;
344       }
345
346       if ((me->pki_encrypt || me->pki_sign) && !me->pki_keypair_file) {
347          Emsg2(M_FATAL, 0, _("\"PKI Key Pair\" must be defined for File"
348             " daemon \"%s\" in %s if either \"PKI Sign\" or"
349             " \"PKI Encrypt\" are enabled.\n"), me->hdr.name, configfile);
350          OK = false;
351       }
352
353       /* If everything is well, attempt to initialize our public/private keys */
354       if (OK && (me->pki_encrypt || me->pki_sign)) {
355          char *filepath;
356          /* Load our keypair */
357          me->pki_keypair = crypto_keypair_new();
358          if (!me->pki_keypair) {
359             Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
360             OK = false;
361          } else {
362             if (!crypto_keypair_load_cert(me->pki_keypair, me->pki_keypair_file)) {
363                Emsg2(M_FATAL, 0, _("Failed to load public certificate for File"
364                      " daemon \"%s\" in %s.\n"), me->hdr.name, configfile);
365                OK = false;
366             }
367
368             if (!crypto_keypair_load_key(me->pki_keypair, me->pki_keypair_file, NULL, NULL)) {
369                Emsg2(M_FATAL, 0, _("Failed to load private key for File"
370                      " daemon \"%s\" in %s.\n"), me->hdr.name, configfile);
371                OK = false;
372             }
373          }
374
375          /*
376           * Trusted Signers. We're always trusted.
377           */
378          me->pki_signers = New(alist(10, not_owned_by_alist));
379          if (me->pki_keypair) {
380             me->pki_signers->append(crypto_keypair_dup(me->pki_keypair));
381          }
382
383          /* If additional signing public keys have been specified, load them up */
384          if (me->pki_signing_key_files) {
385             foreach_alist(filepath, me->pki_signing_key_files) {
386                X509_KEYPAIR *keypair;
387
388                keypair = crypto_keypair_new();
389                if (!keypair) {
390                   Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
391                   OK = false;
392                } else {
393                   if (crypto_keypair_load_cert(keypair, filepath)) {
394                      me->pki_signers->append(keypair);
395
396                      /* Attempt to load a private key, if available */
397                      if (crypto_keypair_has_key(filepath)) {
398                         if (!crypto_keypair_load_key(keypair, filepath, NULL, NULL)) {
399                            Emsg3(M_FATAL, 0, _("Failed to load private key from file %s for File"
400                               " daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
401                            OK = false;
402                         }
403                      }
404
405                   } else {
406                      Emsg3(M_FATAL, 0, _("Failed to load trusted signer certificate"
407                         " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
408                      OK = false;
409                   }
410                }
411             }
412          }
413
414          /*
415           * Crypto recipients. We're always included as a recipient.
416           * The symmetric session key will be encrypted for each of these readers.
417           */
418          me->pki_recipients = New(alist(10, not_owned_by_alist));
419          if (me->pki_keypair) {
420             me->pki_recipients->append(crypto_keypair_dup(me->pki_keypair));
421          }
422
423
424          /* If additional keys have been specified, load them up */
425          if (me->pki_master_key_files) {
426             foreach_alist(filepath, me->pki_master_key_files) {
427                X509_KEYPAIR *keypair;
428
429                keypair = crypto_keypair_new();
430                if (!keypair) {
431                   Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
432                   OK = false;
433                } else {
434                   if (crypto_keypair_load_cert(keypair, filepath)) {
435                      me->pki_recipients->append(keypair);
436                   } else {
437                      Emsg3(M_FATAL, 0, _("Failed to load master key certificate"
438                         " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
439                      OK = false;
440                   }
441                }
442             }
443          }
444       }
445    }
446
447
448    /* Verify that a director record exists */
449    LockRes();
450    director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
451    UnlockRes();
452    if (!director) {
453       Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n"),
454             configfile);
455       OK = false;
456    }
457
458    foreach_res(director, R_DIRECTOR) { 
459       /* tls_require implies tls_enable */
460       if (director->tls_require) {
461 #ifndef HAVE_TLS
462          Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
463          OK = false;
464          continue;
465 #else
466          director->tls_enable = true;
467 #endif
468       }
469       need_tls = director->tls_enable || director->tls_authenticate;
470
471       if (!director->tls_certfile && need_tls) {
472          Emsg2(M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
473                director->hdr.name, configfile);
474          OK = false;
475       }
476
477       if (!director->tls_keyfile && need_tls) {
478          Emsg2(M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
479                director->hdr.name, configfile);
480          OK = false;
481       }
482
483       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && need_tls && director->tls_verify_peer) {
484          Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
485                              " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
486                              " At least one CA certificate store is required"
487                              " when using \"TLS Verify Peer\".\n"),
488                              director->hdr.name, configfile);
489          OK = false;
490       }
491
492       /* If everything is well, attempt to initialize our per-resource TLS context */
493       if (OK && (need_tls || director->tls_require)) {
494          /* Initialize TLS context:
495           * Args: CA certfile, CA certdir, Certfile, Keyfile,
496           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
497          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
498             director->tls_ca_certdir, director->tls_certfile,
499             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
500             director->tls_verify_peer);
501
502          if (!director->tls_ctx) { 
503             Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
504                                 director->hdr.name, configfile);
505             OK = false;
506          }
507       }
508    }
509
510    UnlockRes();
511
512    if (OK) {
513       close_msg(NULL);                /* close temp message handler */
514       init_msg(NULL, me->messages);   /* open user specified message handler */
515    }
516
517    return OK;
518 }