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