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-2006 Kern Sibbald
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.
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.
31 extern DIRRES *director;
32 extern char my_name[];
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";
38 /* Response from Storage daemon */
39 static char OKhello[] = "3000 OK Hello\n";
40 static char FDOKhello[] = "2000 OK Hello\n";
42 /* Sent to User Agent */
43 static char Dir_sorry[] = "1999 You are not authorized.\n";
45 /* Forward referenced functions */
48 * Authenticate Storage daemon connection
50 bool authenticate_storage_daemon(JCR *jcr, STORE *store)
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;
59 * Send my name to the Storage daemon then do authentication
61 bstrncpy(dirname, director->hdr.name, sizeof(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));
73 if (store->tls_enable) {
74 if (store->tls_require) {
75 tls_local_need = BNET_TLS_REQUIRED;
77 tls_local_need = BNET_TLS_OK;
81 auth_success = cram_md5_get_auth(sd, store->password, &tls_remote_need);
83 auth_success = cram_md5_auth(sd, store->password, tls_local_need);
85 Dmsg1(50, "cram_auth failed for %s\n", sd->who);
88 Dmsg1(50, "cram_get_auth failed for %s\n", sd->who);
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"));
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"));
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"));
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"));
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"),
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"));
147 * Authenticate File daemon connection
149 int authenticate_file_daemon(JCR *jcr)
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;
159 * Send my name to the File daemon then do authentication
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));
172 /* TLS Requirement */
173 if (client->tls_enable) {
174 if (client->tls_require) {
175 tls_local_need = BNET_TLS_REQUIRED;
177 tls_local_need = BNET_TLS_OK;
182 auth_success = cram_md5_get_auth(fd, client->password, &tls_remote_need);
184 auth_success = cram_md5_auth(fd, client->password, tls_local_need);
186 Dmsg1(50, "cram_auth failed for %s\n", fd->who);
189 Dmsg1(50, "cram_get_auth failed for %s\n", fd->who);
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"));
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"));
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"));
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"));
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"),
234 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon to Hello command: ERR=%s\n"),
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"));
248 /*********************************************************************
251 int authenticate_user_agent(UAContext *uac)
253 char name[MAX_NAME_LENGTH];
254 int tls_local_need = BNET_TLS_NONE;
255 int tls_remote_need = BNET_TLS_NONE;
257 BSOCK *ua = uac->UA_sock;
258 bool auth_success = false;
260 TLS_CONTEXT *tls_ctx = NULL;
261 alist *verify_list = NULL;
262 #endif /* HAVE_TLS */
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);
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);
280 name[sizeof(name)-1] = 0; /* terminate name */
281 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
283 /* TLS Requirement */
284 if (director->tls_enable) {
285 if (director->tls_require) {
286 tls_local_need = BNET_TLS_REQUIRED;
288 tls_local_need = BNET_TLS_OK;
292 if (director->tls_verify_peer) {
293 verify_list = director->tls_allowed_cns;
295 #endif /* HAVE_TLS */
297 auth_success = cram_md5_auth(ua, director->password, tls_local_need) &&
298 cram_md5_get_auth(ua, director->password, &tls_remote_need);
301 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
304 /* TLS Requirement */
305 if (cons->tls_enable) {
306 if (cons->tls_require) {
307 tls_local_need = BNET_TLS_REQUIRED;
309 tls_local_need = BNET_TLS_OK;
313 if (cons->tls_verify_peer) {
314 verify_list = cons->tls_allowed_cns;
316 #endif /* HAVE_TLS */
318 auth_success = cram_md5_auth(ua, cons->password, tls_local_need) &&
319 cram_md5_get_auth(ua, cons->password, &tls_remote_need);
322 uac->cons = cons; /* save console resource pointer */
325 auth_success = false;
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;
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;
347 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
349 tls_ctx = cons->tls_ctx;
351 tls_ctx = director->tls_ctx;
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;
361 #endif /* HAVE_TLS */
364 /* Authorization Completed */
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);
373 bnet_fsend(ua, _("1000 OK: %s Version: %s (%s)\n"), my_name, VERSION, BDATE);