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