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 Copyright (C) 2001-2004 Kern Sibbald and John Walker
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.
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.
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,
36 extern DIRRES *director;
37 extern char my_name[];
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";
43 /* Response from Storage daemon */
44 static char OKhello[] = "3000 OK Hello\n";
45 static char FDOKhello[] = "2000 OK Hello\n";
47 /* Sent to User Agent */
48 static char Dir_sorry[] = "1999 You are not authorized.\n";
50 /* Forward referenced functions */
53 * Authenticate Storage daemon connection
55 bool authenticate_storage_daemon(JCR *jcr, STORE *store)
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;
64 * Send my name to the Storage daemon then do authentication
66 bstrncpy(dirname, director->hdr.name, sizeof(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));
79 if (store->tls_enable) {
80 if (store->tls_require) {
81 tls_local_need = BNET_TLS_REQUIRED;
83 tls_local_need = BNET_TLS_OK;
88 auth_success = cram_md5_get_auth(sd, store->password, &tls_remote_need);
90 auth_success = cram_md5_auth(sd, store->password, tls_local_need);
92 Dmsg1(50, "cram_auth failed for %s\n", sd->who);
95 Dmsg1(50, "cram_get_auth failed for %s\n", sd->who);
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"));
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"));
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"));
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"));
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"),
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"));
154 * Authenticate File daemon connection
156 int authenticate_file_daemon(JCR *jcr)
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;
166 * Send my name to the File daemon then do authentication
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));
179 /* TLS Requirement */
180 if (client->tls_enable) {
181 if (client->tls_require) {
182 tls_local_need = BNET_TLS_REQUIRED;
184 tls_local_need = BNET_TLS_OK;
189 auth_success = cram_md5_get_auth(fd, client->password, &tls_remote_need);
191 auth_success = cram_md5_auth(fd, client->password, tls_local_need);
193 Dmsg1(50, "cram_auth failed for %s\n", fd->who);
196 Dmsg1(50, "cram_get_auth failed for %s\n", fd->who);
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"));
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"));
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"));
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"));
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"),
241 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon to Hello command: ERR=%s\n"),
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"));
255 /*********************************************************************
258 int authenticate_user_agent(UAContext *uac)
260 char name[MAX_NAME_LENGTH];
261 int tls_local_need = BNET_TLS_NONE;
262 int tls_remote_need = BNET_TLS_NONE;
264 BSOCK *ua = uac->UA_sock;
265 bool auth_success = false;
267 TLS_CONTEXT *tls_ctx = NULL;
268 alist *verify_list = NULL;
269 #endif /* HAVE_TLS */
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);
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);
287 name[sizeof(name)-1] = 0; /* terminate name */
288 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
290 /* TLS Requirement */
291 if (director->tls_enable) {
292 if (director->tls_require) {
293 tls_local_need = BNET_TLS_REQUIRED;
295 tls_local_need = BNET_TLS_OK;
299 if (director->tls_verify_peer) {
300 verify_list = director->tls_allowed_cns;
302 #endif /* HAVE_TLS */
304 auth_success = cram_md5_auth(ua, director->password, tls_local_need) &&
305 cram_md5_get_auth(ua, director->password, &tls_remote_need);
308 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
311 /* TLS Requirement */
312 if (cons->tls_enable) {
313 if (cons->tls_require) {
314 tls_local_need = BNET_TLS_REQUIRED;
316 tls_local_need = BNET_TLS_OK;
320 if (cons->tls_verify_peer) {
321 verify_list = cons->tls_allowed_cns;
323 #endif /* HAVE_TLS */
325 auth_success = cram_md5_auth(ua, cons->password, tls_local_need) &&
326 cram_md5_get_auth(ua, cons->password, &tls_remote_need);
329 uac->cons = cons; /* save console resource pointer */
332 auth_success = false;
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;
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;
354 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
356 tls_ctx = cons->tls_ctx;
358 tls_ctx = director->tls_ctx;
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;
368 #endif /* HAVE_TLS */
371 /* Authorization Completed */
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);
380 bnet_fsend(ua, "1000 OK: %s Version: " VERSION " (" BDATE ")\n", my_name);