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