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