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;
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";
37 /* Response from Storage daemon */
38 static char OKhello[] = "3000 OK Hello\n";
39 static char FDOKhello[] = "2000 OK Hello\n";
41 /* Sent to User Agent */
42 static char Dir_sorry[] = "1999 You are not authorized.\n";
44 /* Forward referenced functions */
47 * Authenticate Storage daemon connection
49 bool authenticate_storage_daemon(JCR *jcr, STORE *store)
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;
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_respond(sd, store->password, &tls_remote_need, &compatible);
83 auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible);
85 Dmsg1(50, "cram_challenge failed for %s\n", sd->who);
88 Dmsg1(50, "cram_respond 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 Jmsg2(jcr, M_FATAL, 0,
95 _("Director unable to authenticate with Storage daemon on \"%s:%d\". 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"),
104 /* Verify that the remote host is willing to meet our TLS requirements */
105 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
106 stop_bsock_timer(tid);
107 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
111 /* Verify that we are willing to meet the remote host's requirements */
112 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
113 stop_bsock_timer(tid);
114 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 with SD on \"%s:%d\"\n"),
129 Dmsg1(116, ">stored: %s", sd->msg);
130 if (bnet_recv(sd) <= 0) {
131 stop_bsock_timer(tid);
132 Jmsg3(jcr, M_FATAL, 0, _("bdird<stored: \"%s:%s\" bad response to Hello command: ERR=%s\n"),
133 sd->who, sd->host, bnet_strerror(sd));
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 Jmsg2(jcr, M_FATAL, 0, _("Storage daemon on \"%s:%d\" rejected Hello command\n"),
148 * Authenticate File daemon connection
150 int authenticate_file_daemon(JCR *jcr)
152 BSOCK *fd = jcr->file_bsock;
153 CLIENT *client = jcr->client;
154 char dirname[MAX_NAME_LENGTH];
155 int tls_local_need = BNET_TLS_NONE;
156 int tls_remote_need = BNET_TLS_NONE;
157 int compatible = true;
158 bool auth_success = false;
161 * Send my name to the File daemon then do authentication
163 bstrncpy(dirname, director->hdr.name, sizeof(dirname));
164 bash_spaces(dirname);
165 /* Timeout Hello after 10 mins */
166 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
167 if (!bnet_fsend(fd, hello, dirname)) {
168 stop_bsock_timer(tid);
169 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon on \"%s:%d\". ERR=%s\n"),
170 fd->host, fd->port, bnet_strerror(fd));
173 Dmsg1(50, "Sent: %s", fd->msg);
175 /* TLS Requirement */
176 if (client->tls_enable) {
177 if (client->tls_require) {
178 tls_local_need = BNET_TLS_REQUIRED;
180 tls_local_need = BNET_TLS_OK;
184 auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
186 auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
188 Dmsg1(50, "cram_auth failed for %s\n", fd->who);
191 Dmsg1(50, "cram_get_auth failed for %s\n", fd->who);
194 stop_bsock_timer(tid);
195 Dmsg0(50, _("Director and File daemon passwords or names not the same.\n"));
196 Jmsg(jcr, M_FATAL, 0,
197 _("Unable to authenticate with File daemon on \"%s:%d\". Possible causes:\n"
198 "Passwords or names not the same or\n"
199 "Maximum Concurrent Jobs exceeded on the FD or\n"
200 "FD networking messed up (restart daemon).\n"
201 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
206 /* Verify that the remote host is willing to meet our TLS requirements */
207 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
208 stop_bsock_timer(tid);
209 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD \"%s:%s\" did not advertise required TLS support.\n"),
214 /* Verify that we are willing to meet the remote host's requirements */
215 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
216 stop_bsock_timer(tid);
217 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD on \"%s:%d\" requires TLS.\n"),
222 /* Is TLS Enabled? */
223 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
224 /* Engage TLS! Full Speed Ahead! */
225 if (!bnet_tls_client(client->tls_ctx, fd)) {
226 stop_bsock_timer(tid);
227 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD on \"%s:%d\".\n"),
233 Dmsg1(116, ">filed: %s", fd->msg);
234 if (bnet_recv(fd) <= 0) {
235 stop_bsock_timer(tid);
236 Dmsg1(50, _("Bad response from File daemon to Hello command: ERR=%s\n"),
238 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon on \"%s:%d\" to Hello command: ERR=%s\n"),
239 fd->host, fd->port, bnet_strerror(fd));
242 Dmsg1(110, "<stored: %s", fd->msg);
243 stop_bsock_timer(tid);
244 if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
245 Dmsg0(50, _("File daemon rejected Hello command\n"));
246 Jmsg(jcr, M_FATAL, 0, _("File daemon on \"%s:%d\" rejected Hello command\n"),
253 /*********************************************************************
256 int authenticate_user_agent(UAContext *uac)
258 char name[MAX_NAME_LENGTH];
259 int tls_local_need = BNET_TLS_NONE;
260 int tls_remote_need = BNET_TLS_NONE;
261 int compatible = true;
263 BSOCK *ua = uac->UA_sock;
264 bool auth_success = false;
265 TLS_CONTEXT *tls_ctx = NULL;
266 alist *verify_list = NULL;
269 // Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
270 // ua->host, ua->port, ua->msglen);
271 if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
272 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
273 ua->host, ua->port, ua->msglen);
277 if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
278 ua->msg[100] = 0; /* terminate string */
279 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who,
280 ua->host, ua->port, ua->msg);
284 name[sizeof(name)-1] = 0; /* terminate name */
285 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
286 /* TLS Requirement */
287 if (director->tls_enable) {
288 if (director->tls_require) {
289 tls_local_need = BNET_TLS_REQUIRED;
291 tls_local_need = BNET_TLS_OK;
295 if (director->tls_verify_peer) {
296 verify_list = director->tls_allowed_cns;
299 auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
301 cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
304 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
306 /* TLS Requirement */
307 if (cons->tls_enable) {
308 if (cons->tls_require) {
309 tls_local_need = BNET_TLS_REQUIRED;
311 tls_local_need = BNET_TLS_OK;
315 if (cons->tls_verify_peer) {
316 verify_list = cons->tls_allowed_cns;
319 auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
321 cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
324 uac->cons = cons; /* save console resource pointer */
327 auth_success = false;
332 /* Verify that the remote peer is willing to meet our TLS requirements */
333 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
334 Emsg0(M_FATAL, 0, _("Authorization problem:"
335 " Remote client did not advertise required TLS support.\n"));
336 auth_success = false;
340 /* Verify that we are willing to meet the peer's requirements */
341 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
342 Emsg0(M_FATAL, 0, _("Authorization problem:"
343 " Remote client requires TLS.\n"));
344 auth_success = false;
348 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
350 tls_ctx = cons->tls_ctx;
352 tls_ctx = director->tls_ctx;
355 /* Engage TLS! Full Speed Ahead! */
356 if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
357 Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
358 auth_success = false;
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);