3 * Bacula Director -- authorize.c -- handles authorization of
4 * Storage and File daemons.
6 * Kern Sibbald, May MMI
8 * This routine runs as a thread and must be thread reentrant.
14 Bacula® - The Network Backup Solution
16 Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
18 The main author of Bacula is Kern Sibbald, with contributions from
19 many others, a complete list can be found in the file AUTHORS.
20 This program is Free Software; you can redistribute it and/or
21 modify it under the terms of version two of the GNU General Public
22 License as published by the Free Software Foundation plus additions
23 that are listed in the file LICENSE.
25 This program is distributed in the hope that it will be useful, but
26 WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 General Public License for more details.
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 Bacula® is a registered trademark of John Walker.
36 The licensor of Bacula is the Free Software Foundation Europe
37 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
38 Switzerland, email:ftf@fsfeurope.org.
44 extern DIRRES *director;
46 /* Commands sent to Storage daemon and File daemon and received
47 * from the User Agent */
48 static char hello[] = "Hello Director %s calling\n";
50 /* Response from Storage daemon */
51 static char OKhello[] = "3000 OK Hello\n";
52 static char FDOKhello[] = "2000 OK Hello\n";
54 /* Sent to User Agent */
55 static char Dir_sorry[] = "1999 You are not authorized.\n";
57 /* Forward referenced functions */
60 * Authenticate Storage daemon connection
62 bool authenticate_storage_daemon(JCR *jcr, STORE *store)
64 BSOCK *sd = jcr->store_bsock;
65 char dirname[MAX_NAME_LENGTH];
66 int tls_local_need = BNET_TLS_NONE;
67 int tls_remote_need = BNET_TLS_NONE;
68 int compatible = true;
69 bool auth_success = false;
72 * Send my name to the Storage daemon then do authentication
74 bstrncpy(dirname, director->hdr.name, sizeof(dirname));
76 /* Timeout Hello after 1 min */
77 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
78 if (!bnet_fsend(sd, hello, dirname)) {
79 stop_bsock_timer(tid);
80 Dmsg1(50, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
81 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
86 if (store->tls_enable) {
87 if (store->tls_require) {
88 tls_local_need = BNET_TLS_REQUIRED;
90 tls_local_need = BNET_TLS_OK;
94 auth_success = cram_md5_respond(sd, store->password, &tls_remote_need, &compatible);
96 auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible);
98 Dmsg1(50, "cram_challenge failed for %s\n", sd->who);
101 Dmsg1(50, "cram_respond failed for %s\n", sd->who);
105 stop_bsock_timer(tid);
106 Dmsg0(50, _("Director and Storage daemon passwords or names not the same.\n"));
107 Jmsg2(jcr, M_FATAL, 0,
108 _("Director unable to authenticate with Storage daemon on \"%s:%d\". Possible causes:\n"
109 "Passwords or names not the same or\n"
110 "Maximum Concurrent Jobs exceeded on the SD or\n"
111 "SD networking messed up (restart daemon).\n"
112 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
117 /* Verify that the remote host is willing to meet our TLS 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 did not advertise required TLS support.\n"));
124 /* Verify that we are willing to meet the remote host's requirements */
125 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
126 stop_bsock_timer(tid);
127 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
131 /* Is TLS Enabled? */
132 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
133 /* Engage TLS! Full Speed Ahead! */
134 if (!bnet_tls_client(store->tls_ctx, sd)) {
135 stop_bsock_timer(tid);
136 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD on \"%s:%d\"\n"),
142 Dmsg1(116, ">stored: %s", sd->msg);
143 if (bnet_recv(sd) <= 0) {
144 stop_bsock_timer(tid);
145 Jmsg3(jcr, M_FATAL, 0, _("bdird<stored: \"%s:%s\" bad response to Hello command: ERR=%s\n"),
146 sd->who, sd->host, bnet_strerror(sd));
149 Dmsg1(110, "<stored: %s", sd->msg);
150 stop_bsock_timer(tid);
151 if (strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
152 Dmsg0(50, _("Storage daemon rejected Hello command\n"));
153 Jmsg2(jcr, M_FATAL, 0, _("Storage daemon on \"%s:%d\" rejected Hello command\n"),
161 * Authenticate File daemon connection
163 int authenticate_file_daemon(JCR *jcr)
165 BSOCK *fd = jcr->file_bsock;
166 CLIENT *client = jcr->client;
167 char dirname[MAX_NAME_LENGTH];
168 int tls_local_need = BNET_TLS_NONE;
169 int tls_remote_need = BNET_TLS_NONE;
170 int compatible = true;
171 bool auth_success = false;
174 * Send my name to the File daemon then do authentication
176 bstrncpy(dirname, director->hdr.name, sizeof(dirname));
177 bash_spaces(dirname);
178 /* Timeout Hello after 10 mins */
179 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
180 if (!bnet_fsend(fd, hello, dirname)) {
181 stop_bsock_timer(tid);
182 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon on \"%s:%d\". ERR=%s\n"),
183 fd->host, fd->port, bnet_strerror(fd));
186 Dmsg1(50, "Sent: %s", fd->msg);
188 /* TLS Requirement */
189 if (client->tls_enable) {
190 if (client->tls_require) {
191 tls_local_need = BNET_TLS_REQUIRED;
193 tls_local_need = BNET_TLS_OK;
197 auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
199 auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
201 Dmsg1(50, "cram_auth failed for %s\n", fd->who);
204 Dmsg1(50, "cram_get_auth failed for %s\n", fd->who);
207 stop_bsock_timer(tid);
208 Dmsg0(50, _("Director and File daemon passwords or names not the same.\n"));
209 Jmsg(jcr, M_FATAL, 0,
210 _("Unable to authenticate with File daemon on \"%s:%d\". Possible causes:\n"
211 "Passwords or names not the same or\n"
212 "Maximum Concurrent Jobs exceeded on the FD or\n"
213 "FD networking messed up (restart daemon).\n"
214 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
219 /* Verify that the remote host is willing to meet our TLS requirements */
220 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
221 stop_bsock_timer(tid);
222 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD \"%s:%s\" did not advertise required TLS support.\n"),
227 /* Verify that we are willing to meet the remote host's requirements */
228 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
229 stop_bsock_timer(tid);
230 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD on \"%s:%d\" requires TLS.\n"),
235 /* Is TLS Enabled? */
236 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
237 /* Engage TLS! Full Speed Ahead! */
238 if (!bnet_tls_client(client->tls_ctx, fd)) {
239 stop_bsock_timer(tid);
240 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD on \"%s:%d\".\n"),
246 Dmsg1(116, ">filed: %s", fd->msg);
247 if (bnet_recv(fd) <= 0) {
248 stop_bsock_timer(tid);
249 Dmsg1(50, _("Bad response from File daemon to Hello command: ERR=%s\n"),
251 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon on \"%s:%d\" to Hello command: ERR=%s\n"),
252 fd->host, fd->port, bnet_strerror(fd));
255 Dmsg1(110, "<stored: %s", fd->msg);
256 stop_bsock_timer(tid);
257 if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
258 Dmsg0(50, _("File daemon rejected Hello command\n"));
259 Jmsg(jcr, M_FATAL, 0, _("File daemon on \"%s:%d\" rejected Hello command\n"),
266 /*********************************************************************
269 int authenticate_user_agent(UAContext *uac)
271 char name[MAX_NAME_LENGTH];
272 int tls_local_need = BNET_TLS_NONE;
273 int tls_remote_need = BNET_TLS_NONE;
274 int compatible = true;
276 BSOCK *ua = uac->UA_sock;
277 bool auth_success = false;
278 TLS_CONTEXT *tls_ctx = NULL;
279 alist *verify_list = NULL;
282 // Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
283 // ua->host, ua->port, ua->msglen);
284 if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
285 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
286 ua->host, ua->port, ua->msglen);
290 if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
291 ua->msg[100] = 0; /* terminate string */
292 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who,
293 ua->host, ua->port, ua->msg);
297 name[sizeof(name)-1] = 0; /* terminate name */
298 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
299 /* TLS Requirement */
300 if (director->tls_enable) {
301 if (director->tls_require) {
302 tls_local_need = BNET_TLS_REQUIRED;
304 tls_local_need = BNET_TLS_OK;
308 if (director->tls_verify_peer) {
309 verify_list = director->tls_allowed_cns;
312 auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
314 cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
317 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
319 /* TLS Requirement */
320 if (cons->tls_enable) {
321 if (cons->tls_require) {
322 tls_local_need = BNET_TLS_REQUIRED;
324 tls_local_need = BNET_TLS_OK;
328 if (cons->tls_verify_peer) {
329 verify_list = cons->tls_allowed_cns;
332 auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
334 cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
337 uac->cons = cons; /* save console resource pointer */
340 auth_success = false;
345 /* Verify that the remote peer is willing to meet our TLS 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 did not advertise required TLS support.\n"));
349 auth_success = false;
353 /* Verify that we are willing to meet the peer's requirements */
354 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
355 Emsg0(M_FATAL, 0, _("Authorization problem:"
356 " Remote client requires TLS.\n"));
357 auth_success = false;
361 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
363 tls_ctx = cons->tls_ctx;
365 tls_ctx = director->tls_ctx;
368 /* Engage TLS! Full Speed Ahead! */
369 if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
370 Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
371 auth_success = false;
377 /* Authorization Completed */
380 bnet_fsend(ua, "%s", _(Dir_sorry));
381 Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
382 name, ua->who, ua->host, ua->port);
386 bnet_fsend(ua, _("1000 OK: %s Version: %s (%s)\n"), my_name, VERSION, BDATE);