]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/authenticate.c
bb73cd3de23e1d647f495372941f8630274eeea2
[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-2005 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 ammended 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 extern char my_name[];
33
34 /* Commands sent to Storage daemon and File daemon and received
35  *  from the User Agent */
36 static char hello[]    = "Hello Director %s calling\n";
37
38 /* Response from Storage daemon */
39 static char OKhello[]   = "3000 OK Hello\n";
40 static char FDOKhello[] = "2000 OK Hello\n";
41
42 /* Sent to User Agent */
43 static char Dir_sorry[]  = "1999 You are not authorized.\n";
44
45 /* Forward referenced functions */
46
47 /*
48  * Authenticate Storage daemon connection
49  */
50 bool authenticate_storage_daemon(JCR *jcr, STORE *store)
51 {
52    BSOCK *sd = jcr->store_bsock;
53    char dirname[MAX_NAME_LENGTH];
54    int tls_local_need = BNET_TLS_NONE;
55    int tls_remote_need = BNET_TLS_NONE;
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_get_auth(sd, store->password, &tls_remote_need);
82    if (auth_success) {
83       auth_success = cram_md5_auth(sd, store->password, tls_local_need);
84       if (!auth_success) {
85          Dmsg1(50, "cram_auth failed for %s\n", sd->who);
86       }
87    } else {
88       Dmsg1(50, "cram_get_auth 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             _("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 #ifdef HAVE_TLS
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.\n"));
124          return 0;
125       }
126    }
127 #endif
128
129    Dmsg1(116, ">stored: %s", sd->msg);
130    if (bnet_recv(sd) <= 0) {
131       stop_bsock_timer(tid);
132       Jmsg1(jcr, M_FATAL, 0, _("bdird<stored: bad response to Hello command: ERR=%s\n"),
133          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       Jmsg0(jcr, M_FATAL, 0, _("Storage daemon rejected Hello command\n"));
141       return 0;
142    }
143    return 1;
144 }
145
146 /*
147  * Authenticate File daemon connection
148  */
149 int authenticate_file_daemon(JCR *jcr)
150 {
151    BSOCK *fd = jcr->file_bsock;
152    CLIENT *client = jcr->client;
153    char dirname[MAX_NAME_LENGTH];
154    int tls_local_need = BNET_TLS_NONE;
155    int tls_remote_need = BNET_TLS_NONE;
156    bool auth_success = false;
157
158    /*
159     * Send my name to the File daemon then do authentication
160     */
161    bstrncpy(dirname, director->hdr.name, sizeof(dirname));
162    bash_spaces(dirname);
163    /* Timeout Hello after 10 mins */
164    btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
165    if (!bnet_fsend(fd, hello, dirname)) {
166       stop_bsock_timer(tid);
167       Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon. ERR=%s\n"), bnet_strerror(fd));
168       return 0;
169    }
170
171 #ifdef HAVE_TLS
172    /* TLS Requirement */
173    if (client->tls_enable) {
174      if (client->tls_require) {
175         tls_local_need = BNET_TLS_REQUIRED;
176      } else {
177         tls_local_need = BNET_TLS_OK;
178      }
179    }
180 #endif
181
182    auth_success = cram_md5_get_auth(fd, client->password, &tls_remote_need);
183    if (auth_success) {
184       auth_success = cram_md5_auth(fd, client->password, tls_local_need);
185       if (!auth_success) {
186          Dmsg1(50, "cram_auth failed for %s\n", fd->who);
187       }
188    } else {
189       Dmsg1(50, "cram_get_auth failed for %s\n", fd->who);
190    }
191    if (!auth_success) {
192       stop_bsock_timer(tid);
193       Dmsg0(50, _("Director and File daemon passwords or names not the same.\n"));
194       Jmsg(jcr, M_FATAL, 0,
195             _("Unable to authenticate with File daemon. Possible causes:\n"
196             "Passwords or names not the same or\n"
197             "Maximum Concurrent Jobs exceeded on the FD or\n"
198             "FD networking messed up (restart daemon).\n"
199             "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
200       return 0;
201    }
202
203    /* Verify that the remote host is willing to meet our TLS requirements */
204    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
205       stop_bsock_timer(tid);
206       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
207       return 0;
208    }
209
210    /* Verify that we are willing to meet the remote host's 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 requires TLS.\n"));
214       return 0;
215    }
216
217 #ifdef HAVE_TLS
218    /* Is TLS Enabled? */
219    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
220       /* Engage TLS! Full Speed Ahead! */
221       if (!bnet_tls_client(client->tls_ctx, fd)) {
222          stop_bsock_timer(tid);
223          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
224          return 0;
225       }
226    }
227 #endif
228
229    Dmsg1(116, ">filed: %s", fd->msg);
230    if (bnet_recv(fd) <= 0) {
231       stop_bsock_timer(tid);
232       Dmsg1(50, _("Bad response from File daemon to Hello command: ERR=%s\n"),
233          bnet_strerror(fd));
234       Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon to Hello command: ERR=%s\n"),
235          bnet_strerror(fd));
236       return 0;
237    }
238    Dmsg1(110, "<stored: %s", fd->msg);
239    stop_bsock_timer(tid);
240    if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
241       Dmsg0(50, _("File daemon rejected Hello command\n"));
242       Jmsg(jcr, M_FATAL, 0, _("File daemon rejected Hello command\n"));
243       return 0;
244    }
245    return 1;
246 }
247
248 /*********************************************************************
249  *
250  */
251 int authenticate_user_agent(UAContext *uac)
252 {
253    char name[MAX_NAME_LENGTH];
254    int tls_local_need = BNET_TLS_NONE;
255    int tls_remote_need = BNET_TLS_NONE;
256    CONRES *cons = NULL;
257    BSOCK *ua = uac->UA_sock;
258    bool auth_success = false;
259 #ifdef HAVE_TLS
260    TLS_CONTEXT *tls_ctx = NULL;
261    alist *verify_list = NULL;
262 #endif /* HAVE_TLS */
263  
264
265 //  Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
266 //          ua->host, ua->port, ua->msglen);
267    if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
268       Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
269             ua->host, ua->port, ua->msglen);
270       return 0;
271    }
272
273    if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
274       ua->msg[100] = 0;               /* terminate string */
275       Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who,
276             ua->host, ua->port, ua->msg);
277       return 0;
278    }
279
280    name[sizeof(name)-1] = 0;             /* terminate name */
281    if (strcmp(name, "*UserAgent*") == 0) {  /* default console */
282 #ifdef HAVE_TLS
283       /* TLS Requirement */
284       if (director->tls_enable) {
285          if (director->tls_require) {
286             tls_local_need = BNET_TLS_REQUIRED;
287          } else {
288             tls_local_need = BNET_TLS_OK;
289          }
290       }
291
292       if (director->tls_verify_peer) {
293          verify_list = director->tls_allowed_cns;
294       }
295 #endif /* HAVE_TLS */
296
297       auth_success = cram_md5_auth(ua, director->password, tls_local_need) &&
298            cram_md5_get_auth(ua, director->password, &tls_remote_need);
299    } else {
300       unbash_spaces(name);
301       cons = (CONRES *)GetResWithName(R_CONSOLE, name);
302       if (cons) {
303 #ifdef HAVE_TLS
304          /* TLS Requirement */
305          if (cons->tls_enable) {
306             if (cons->tls_require) {
307                tls_local_need = BNET_TLS_REQUIRED;
308             } else {
309                tls_local_need = BNET_TLS_OK;
310             }
311          }
312
313          if (cons->tls_verify_peer) {
314             verify_list = cons->tls_allowed_cns;
315          }
316 #endif /* HAVE_TLS */
317
318          auth_success = cram_md5_auth(ua, cons->password, tls_local_need) &&
319               cram_md5_get_auth(ua, cons->password, &tls_remote_need);
320
321          if (auth_success) {
322             uac->cons = cons;         /* save console resource pointer */
323          }
324       } else {
325          auth_success = false;
326          goto auth_done;
327       }
328    }
329
330    /* Verify that the remote peer is willing to meet our TLS 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 did not advertise required TLS support.\n"));
334       auth_success = false;
335       goto auth_done;
336    }
337
338    /* Verify that we are willing to meet the peer's requirements */
339    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
340       Emsg0(M_FATAL, 0, _("Authorization problem:"
341             " Remote client requires TLS.\n"));
342       auth_success = false;
343       goto auth_done;
344    }
345
346 #ifdef HAVE_TLS
347    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
348       if (cons) {
349          tls_ctx = cons->tls_ctx;
350       } else {
351          tls_ctx = director->tls_ctx;
352       }
353
354       /* Engage TLS! Full Speed Ahead! */
355       if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
356          Emsg0(M_ERROR, 0, "TLS negotiation failed.\n");
357          auth_success = false;
358          goto auth_done;
359       }
360    }
361 #endif /* HAVE_TLS */
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: " VERSION " (" BDATE ")\n", my_name);
374    return 1;
375 }