]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/authenticate.c
kes Implement 'MaxFullInterval' and start 'MaxDiffInterval' based on
[bacula/bacula] / bacula / src / dird / authenticate.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2001-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  *
30  *   Bacula Director -- authorize.c -- handles authorization of
31  *     Storage and File daemons.
32  *
33  *     Kern Sibbald, May MMI
34  *
35  *    This routine runs as a thread and must be thread reentrant.
36  *
37  *   Version $Id$
38  *
39  */
40
41 #include "bacula.h"
42 #include "dird.h"
43
44 static const int dbglvl = 50;
45
46 extern DIRRES *director;
47
48 /* Commands sent to Storage daemon and File daemon and received
49  *  from the User Agent */
50 static char hello[]    = "Hello Director %s calling\n";
51
52 /* Response from Storage daemon */
53 static char OKhello[]   = "3000 OK Hello\n";
54 static char FDOKhello[] = "2000 OK Hello\n";
55
56 /* Sent to User Agent */
57 static char Dir_sorry[]  = "1999 You are not authorized.\n";
58
59 /* Forward referenced functions */
60
61 /*
62  * Authenticate Storage daemon connection
63  */
64 bool authenticate_storage_daemon(JCR *jcr, STORE *store)
65 {
66    BSOCK *sd = jcr->store_bsock;
67    char dirname[MAX_NAME_LENGTH];
68    int tls_local_need = BNET_TLS_NONE;
69    int tls_remote_need = BNET_TLS_NONE;
70    int compatible = true;
71    bool auth_success = false;
72
73    /*
74     * Send my name to the Storage daemon then do authentication
75     */
76    bstrncpy(dirname, director->hdr.name, sizeof(dirname));
77    bash_spaces(dirname);
78    /* Timeout Hello after 1 min */
79    btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
80    if (!sd->fsend(hello, dirname)) {
81       stop_bsock_timer(tid);
82       Dmsg1(dbglvl, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
83       Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
84       return 0;
85    }
86
87    /* TLS Requirement */
88    if (store->tls_enable) {
89      if (store->tls_require) {
90         tls_local_need = BNET_TLS_REQUIRED;
91      } else {
92         tls_local_need = BNET_TLS_OK;
93      }
94    }
95
96    if (store->tls_authenticate) {
97       tls_local_need = BNET_TLS_REQUIRED;
98    }
99
100    auth_success = cram_md5_respond(sd, store->password, &tls_remote_need, &compatible);
101    if (auth_success) {
102       auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible);
103       if (!auth_success) {
104          Dmsg1(dbglvl, "cram_challenge failed for %s\n", sd->who());
105       }
106    } else {
107       Dmsg1(dbglvl, "cram_respond failed for %s\n", sd->who());
108    }
109
110    if (!auth_success) {
111       stop_bsock_timer(tid);
112       Dmsg0(dbglvl, _("Director and Storage daemon passwords or names not the same.\n"));
113       Jmsg2(jcr, M_FATAL, 0,
114             _("Director unable to authenticate with Storage daemon at \"%s:%d\". Possible causes:\n"
115             "Passwords or names not the same or\n"
116             "Maximum Concurrent Jobs exceeded on the SD or\n"
117             "SD networking messed up (restart daemon).\n"
118             "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
119             sd->host(), sd->port());
120       return 0;
121    }
122
123    /* Verify that the remote host is willing to meet our TLS requirements */
124    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
125       stop_bsock_timer(tid);
126       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
127       return 0;
128    }
129
130    /* Verify that we are willing to meet the remote host's requirements */
131    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
132       stop_bsock_timer(tid);
133       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
134       return 0;
135    }
136
137    /* Is TLS Enabled? */
138    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
139       /* Engage TLS! Full Speed Ahead! */
140       if (!bnet_tls_client(store->tls_ctx, sd, NULL)) {
141          stop_bsock_timer(tid);
142          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD at \"%s:%d\"\n"),
143             sd->host(), sd->port());
144          return 0;
145       }
146       if (store->tls_authenticate) {       /* authentication only? */
147          sd->free_tls();                   /* yes, stop tls */
148       }
149    }
150
151    Dmsg1(116, ">stored: %s", sd->msg);
152    if (sd->recv() <= 0) {
153       stop_bsock_timer(tid);
154       Jmsg3(jcr, M_FATAL, 0, _("bdird<stored: \"%s:%s\" bad response to Hello command: ERR=%s\n"),
155          sd->who(), sd->host(), sd->bstrerror());
156       return 0;
157    }
158    Dmsg1(110, "<stored: %s", sd->msg);
159    stop_bsock_timer(tid);
160    if (strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
161       Dmsg0(dbglvl, _("Storage daemon rejected Hello command\n"));
162       Jmsg2(jcr, M_FATAL, 0, _("Storage daemon at \"%s:%d\" rejected Hello command\n"),
163          sd->host(), sd->port());
164       return 0;
165    }
166    return 1;
167 }
168
169 /*
170  * Authenticate File daemon connection
171  */
172 int authenticate_file_daemon(JCR *jcr)
173 {
174    BSOCK *fd = jcr->file_bsock;
175    CLIENT *client = jcr->client;
176    char dirname[MAX_NAME_LENGTH];
177    int tls_local_need = BNET_TLS_NONE;
178    int tls_remote_need = BNET_TLS_NONE;
179    int compatible = true;
180    bool auth_success = false;
181
182    /*
183     * Send my name to the File daemon then do authentication
184     */
185    bstrncpy(dirname, director->name(), sizeof(dirname));
186    bash_spaces(dirname);
187    /* Timeout Hello after 1 min */
188    btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
189    if (!fd->fsend(hello, dirname)) {
190       stop_bsock_timer(tid);
191       Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon at \"%s:%d\". ERR=%s\n"), 
192            fd->host(), fd->port(), fd->bstrerror());
193       return 0;
194    }
195    Dmsg1(dbglvl, "Sent: %s", fd->msg);
196
197    /* TLS Requirement */
198    if (client->tls_enable) {
199      if (client->tls_require) {
200         tls_local_need = BNET_TLS_REQUIRED;
201      } else {
202         tls_local_need = BNET_TLS_OK;
203      }
204    }
205
206    if (client->tls_authenticate) {
207       tls_local_need = BNET_TLS_REQUIRED;
208    }
209
210    auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
211    if (auth_success) {
212       auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
213       if (!auth_success) {
214          Dmsg1(dbglvl, "cram_auth failed for %s\n", fd->who());
215       }
216    } else {
217       Dmsg1(dbglvl, "cram_get_auth failed for %s\n", fd->who());
218    }
219    if (!auth_success) {
220       stop_bsock_timer(tid);
221       Dmsg0(dbglvl, _("Director and File daemon passwords or names not the same.\n"));
222       Jmsg(jcr, M_FATAL, 0,
223             _("Unable to authenticate with File daemon at \"%s:%d\". Possible causes:\n"
224             "Passwords or names not the same or\n"
225             "Maximum Concurrent Jobs exceeded on the FD or\n"
226             "FD networking messed up (restart daemon).\n"
227             "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
228             fd->host(), fd->port());
229       return 0;
230    }
231
232    /* Verify that the remote host is willing to meet our TLS requirements */
233    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
234       stop_bsock_timer(tid);
235       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD \"%s:%s\" did not advertise required TLS support.\n"),
236            fd->who(), fd->host());
237       return 0;
238    }
239
240    /* Verify that we are willing to meet the remote host's requirements */
241    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
242       stop_bsock_timer(tid);
243       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD at \"%s:%d\" requires TLS.\n"),
244            fd->host(), fd->port());
245       return 0;
246    }
247
248    /* Is TLS Enabled? */
249    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
250       /* Engage TLS! Full Speed Ahead! */
251       if (!bnet_tls_client(client->tls_ctx, fd, client->tls_allowed_cns)) {
252
253          stop_bsock_timer(tid);
254          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\".\n"),
255               fd->host(), fd->port());
256          return 0;
257       }
258       if (client->tls_authenticate) {        /* tls authentication only? */
259          fd->free_tls();                     /* yes, shutdown tls */
260       }
261    }
262
263    Dmsg1(116, ">filed: %s", fd->msg);
264    if (fd->recv() <= 0) {
265       stop_bsock_timer(tid);
266       Dmsg1(dbglvl, _("Bad response from File daemon to Hello command: ERR=%s\n"),
267          bnet_strerror(fd));
268       Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon at \"%s:%d\" to Hello command: ERR=%s\n"),
269          fd->host(), fd->port(), fd->bstrerror());
270       return 0;
271    }
272    Dmsg1(110, "<stored: %s", fd->msg);
273    stop_bsock_timer(tid);
274    if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
275       Dmsg0(dbglvl, _("File daemon rejected Hello command\n"));
276       Jmsg(jcr, M_FATAL, 0, _("File daemon at \"%s:%d\" rejected Hello command\n"),
277            fd->host(), fd->port());
278       return 0;
279    }
280    return 1;
281 }
282
283 /*********************************************************************
284  *
285  */
286 int authenticate_user_agent(UAContext *uac)
287 {
288    char name[MAX_NAME_LENGTH];
289    int tls_local_need = BNET_TLS_NONE;
290    int tls_remote_need = BNET_TLS_NONE;
291    bool need_tls;
292    bool tls_authenticate;
293    int compatible = true;
294    CONRES *cons = NULL;
295    BSOCK *ua = uac->UA_sock;
296    bool auth_success = false;
297    TLS_CONTEXT *tls_ctx = NULL;
298    alist *verify_list = NULL;
299  
300    if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
301       Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(),
302             ua->host(), ua->port(), ua->msglen);
303       return 0;
304    }
305
306    if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
307       ua->msg[100] = 0;               /* terminate string */
308       Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(),
309             ua->host(), ua->port(), ua->msg);
310       return 0;
311    }
312
313    name[sizeof(name)-1] = 0;             /* terminate name */
314    if (strcmp(name, "*UserAgent*") == 0) {  /* default console */
315       /* TLS Requirement */
316       if (director->tls_enable) {
317          if (director->tls_require) {
318             tls_local_need = BNET_TLS_REQUIRED;
319          } else {
320             tls_local_need = BNET_TLS_OK;
321          }
322       }
323
324       tls_authenticate = director->tls_authenticate;
325       need_tls = director->tls_enable || tls_authenticate;
326
327       if (tls_authenticate) {
328          tls_local_need = BNET_TLS_REQUIRED;
329       }
330
331       if (director->tls_verify_peer) {
332          verify_list = director->tls_allowed_cns;
333       }
334
335       auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
336                                         compatible) &&
337                      cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
338    } else {
339       unbash_spaces(name);
340       cons = (CONRES *)GetResWithName(R_CONSOLE, name);
341       if (cons) {
342          /* TLS Requirement */
343          if (cons->tls_enable) {
344             if (cons->tls_require) {
345                tls_local_need = BNET_TLS_REQUIRED;
346             } else {
347                tls_local_need = BNET_TLS_OK;
348             }
349          }
350
351          tls_authenticate = cons->tls_authenticate;
352          need_tls = cons->tls_enable || tls_authenticate;
353
354          if (tls_authenticate) {
355             tls_local_need = BNET_TLS_REQUIRED;
356          }
357
358          if (cons->tls_verify_peer) {
359             verify_list = cons->tls_allowed_cns;
360          }
361
362          auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
363                                            compatible) &&
364                      cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
365
366          if (auth_success) {
367             uac->cons = cons;         /* save console resource pointer */
368          }
369       } else {
370          auth_success = false;
371          goto auth_done;
372       }
373    }
374
375
376    /* Verify that the remote peer is willing to meet our TLS requirements */
377    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
378       Emsg0(M_FATAL, 0, _("Authorization problem:"
379             " Remote client did not advertise required TLS support.\n"));
380       auth_success = false;
381       goto auth_done;
382    }
383
384    /* Verify that we are willing to meet the peer's requirements */
385    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
386       Emsg0(M_FATAL, 0, _("Authorization problem:"
387             " Remote client requires TLS.\n"));
388       auth_success = false;
389       goto auth_done;
390    }
391
392    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
393       if (cons) {
394          tls_ctx = cons->tls_ctx;
395       } else {
396          tls_ctx = director->tls_ctx;
397       }
398
399       /* Engage TLS! Full Speed Ahead! */
400       if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
401          Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
402          auth_success = false;
403          goto auth_done;
404       }
405       if (tls_authenticate) {            /* authentication only? */
406          ua->free_tls();                 /* stop tls */
407       }
408    }
409
410
411 /* Authorization Completed */
412 auth_done:
413    if (!auth_success) {
414       ua->fsend("%s", _(Dir_sorry));
415       Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
416             name, ua->who(), ua->host(), ua->port());
417       sleep(5);
418       return 0;
419    }
420    ua->fsend(_("1000 OK: %s Version: %s (%s)\n"), my_name, VERSION, BDATE);
421    return 1;
422 }