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