]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/authenticate.c
- Tweak catalog make scripts.
[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       Jmsg0(jcr, M_FATAL, 0,
95             _("Director unable to authenticate with Storage daemon. 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       return 0;
101    }
102
103    /* Verify that the remote host is willing to meet our TLS requirements */
104    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
105       stop_bsock_timer(tid);
106       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
107       return 0;
108    }
109
110    /* Verify that we are willing to meet the remote host's 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 requires TLS.\n"));
114       return 0;
115    }
116
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
127    Dmsg1(116, ">stored: %s", sd->msg);
128    if (bnet_recv(sd) <= 0) {
129       stop_bsock_timer(tid);
130       Jmsg1(jcr, M_FATAL, 0, _("bdird<stored: bad response to Hello command: ERR=%s\n"),
131          bnet_strerror(sd));
132       return 0;
133    }
134    Dmsg1(110, "<stored: %s", sd->msg);
135    stop_bsock_timer(tid);
136    if (strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
137       Dmsg0(50, _("Storage daemon rejected Hello command\n"));
138       Jmsg0(jcr, M_FATAL, 0, _("Storage daemon rejected Hello command\n"));
139       return 0;
140    }
141    return 1;
142 }
143
144 /*
145  * Authenticate File daemon connection
146  */
147 int authenticate_file_daemon(JCR *jcr)
148 {
149    BSOCK *fd = jcr->file_bsock;
150    CLIENT *client = jcr->client;
151    char dirname[MAX_NAME_LENGTH];
152    int tls_local_need = BNET_TLS_NONE;
153    int tls_remote_need = BNET_TLS_NONE;
154    int compatible = true;
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    /* TLS Requirement */
171    if (client->tls_enable) {
172      if (client->tls_require) {
173         tls_local_need = BNET_TLS_REQUIRED;
174      } else {
175         tls_local_need = BNET_TLS_OK;
176      }
177    }
178
179    auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
180    if (auth_success) {
181       auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
182       if (!auth_success) {
183          Dmsg1(50, "cram_auth failed for %s\n", fd->who);
184       }
185    } else {
186       Dmsg1(50, "cram_get_auth failed for %s\n", fd->who);
187    }
188    if (!auth_success) {
189       stop_bsock_timer(tid);
190       Dmsg0(50, _("Director and File daemon passwords or names not the same.\n"));
191       Jmsg(jcr, M_FATAL, 0,
192             _("Unable to authenticate with File daemon. Possible causes:\n"
193             "Passwords or names not the same or\n"
194             "Maximum Concurrent Jobs exceeded on the FD or\n"
195             "FD networking messed up (restart daemon).\n"
196             "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
197       return 0;
198    }
199
200    /* Verify that the remote host is willing to meet our TLS requirements */
201    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
202       stop_bsock_timer(tid);
203       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
204       return 0;
205    }
206
207    /* Verify that we are willing to meet the remote host's requirements */
208    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
209       stop_bsock_timer(tid);
210       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
211       return 0;
212    }
213
214    /* Is TLS Enabled? */
215    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
216       /* Engage TLS! Full Speed Ahead! */
217       if (!bnet_tls_client(client->tls_ctx, fd)) {
218          stop_bsock_timer(tid);
219          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
220          return 0;
221       }
222    }
223
224    Dmsg1(116, ">filed: %s", fd->msg);
225    if (bnet_recv(fd) <= 0) {
226       stop_bsock_timer(tid);
227       Dmsg1(50, _("Bad response from File daemon to Hello command: ERR=%s\n"),
228          bnet_strerror(fd));
229       Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon to Hello command: ERR=%s\n"),
230          bnet_strerror(fd));
231       return 0;
232    }
233    Dmsg1(110, "<stored: %s", fd->msg);
234    stop_bsock_timer(tid);
235    if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
236       Dmsg0(50, _("File daemon rejected Hello command\n"));
237       Jmsg(jcr, M_FATAL, 0, _("File daemon rejected Hello command\n"));
238       return 0;
239    }
240    return 1;
241 }
242
243 /*********************************************************************
244  *
245  */
246 int authenticate_user_agent(UAContext *uac)
247 {
248    char name[MAX_NAME_LENGTH];
249    int tls_local_need = BNET_TLS_NONE;
250    int tls_remote_need = BNET_TLS_NONE;
251    int compatible = true;
252    CONRES *cons = NULL;
253    BSOCK *ua = uac->UA_sock;
254    bool auth_success = false;
255    TLS_CONTEXT *tls_ctx = NULL;
256    alist *verify_list = NULL;
257  
258
259 //  Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
260 //          ua->host, ua->port, ua->msglen);
261    if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
262       Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
263             ua->host, ua->port, ua->msglen);
264       return 0;
265    }
266
267    if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
268       ua->msg[100] = 0;               /* terminate string */
269       Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who,
270             ua->host, ua->port, ua->msg);
271       return 0;
272    }
273
274    name[sizeof(name)-1] = 0;             /* terminate name */
275    if (strcmp(name, "*UserAgent*") == 0) {  /* default console */
276       /* TLS Requirement */
277       if (director->tls_enable) {
278          if (director->tls_require) {
279             tls_local_need = BNET_TLS_REQUIRED;
280          } else {
281             tls_local_need = BNET_TLS_OK;
282          }
283       }
284
285       if (director->tls_verify_peer) {
286          verify_list = director->tls_allowed_cns;
287       }
288
289       auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
290                                         compatible) &&
291                      cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
292    } else {
293       unbash_spaces(name);
294       cons = (CONRES *)GetResWithName(R_CONSOLE, name);
295       if (cons) {
296          /* TLS Requirement */
297          if (cons->tls_enable) {
298             if (cons->tls_require) {
299                tls_local_need = BNET_TLS_REQUIRED;
300             } else {
301                tls_local_need = BNET_TLS_OK;
302             }
303          }
304
305          if (cons->tls_verify_peer) {
306             verify_list = cons->tls_allowed_cns;
307          }
308
309          auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
310                                            compatible) &&
311                      cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
312
313          if (auth_success) {
314             uac->cons = cons;         /* save console resource pointer */
315          }
316       } else {
317          auth_success = false;
318          goto auth_done;
319       }
320    }
321
322    /* Verify that the remote peer is willing to meet our TLS requirements */
323    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
324       Emsg0(M_FATAL, 0, _("Authorization problem:"
325             " Remote client did not advertise required TLS support.\n"));
326       auth_success = false;
327       goto auth_done;
328    }
329
330    /* Verify that we are willing to meet the peer's requirements */
331    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
332       Emsg0(M_FATAL, 0, _("Authorization problem:"
333             " Remote client requires TLS.\n"));
334       auth_success = false;
335       goto auth_done;
336    }
337
338    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
339       if (cons) {
340          tls_ctx = cons->tls_ctx;
341       } else {
342          tls_ctx = director->tls_ctx;
343       }
344
345       /* Engage TLS! Full Speed Ahead! */
346       if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
347          Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
348          auth_success = false;
349          goto auth_done;
350       }
351    }
352
353
354 /* Authorization Completed */
355 auth_done:
356    if (!auth_success) {
357       bnet_fsend(ua, "%s", _(Dir_sorry));
358       Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
359             name, ua->who, ua->host, ua->port);
360       sleep(5);
361       return 0;
362    }
363    bnet_fsend(ua, _("1000 OK: %s Version: %s (%s)\n"), my_name, VERSION, BDATE);
364    return 1;
365 }