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