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 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"));
117 /* Is TLS Enabled? */
118 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
119 /* Engage TLS! Full Speed Ahead! */
120 if (!bnet_tls_client(store->tls_ctx, sd)) {
121 stop_bsock_timer(tid);
122 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
127 Dmsg1(116, ">stored: %s", sd->msg);
128 if (bnet_recv(sd) <= 0) {
129 stop_bsock_timer(tid);
130 Jmsg1(jcr, M_FATAL, 0, _("bdird<stored: bad response to Hello command: ERR=%s\n"),
134 Dmsg1(110, "<stored: %s", sd->msg);
135 stop_bsock_timer(tid);
136 if (strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
137 Dmsg0(50, _("Storage daemon rejected Hello command\n"));
138 Jmsg0(jcr, M_FATAL, 0, _("Storage daemon rejected Hello command\n"));
145 * Authenticate File daemon connection
147 int authenticate_file_daemon(JCR *jcr)
149 BSOCK *fd = jcr->file_bsock;
150 CLIENT *client = jcr->client;
151 char dirname[MAX_NAME_LENGTH];
152 int tls_local_need = BNET_TLS_NONE;
153 int tls_remote_need = BNET_TLS_NONE;
154 int compatible = true;
155 bool auth_success = false;
158 * Send my name to the File daemon then do authentication
160 bstrncpy(dirname, director->hdr.name, sizeof(dirname));
161 bash_spaces(dirname);
162 /* Timeout Hello after 10 mins */
163 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
164 if (!bnet_fsend(fd, hello, dirname)) {
165 stop_bsock_timer(tid);
166 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon. ERR=%s\n"), bnet_strerror(fd));
170 /* TLS Requirement */
171 if (client->tls_enable) {
172 if (client->tls_require) {
173 tls_local_need = BNET_TLS_REQUIRED;
175 tls_local_need = BNET_TLS_OK;
179 auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
181 auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
183 Dmsg1(50, "cram_auth failed for %s\n", fd->who);
186 Dmsg1(50, "cram_get_auth failed for %s\n", fd->who);
189 stop_bsock_timer(tid);
190 Dmsg0(50, _("Director and File daemon passwords or names not the same.\n"));
191 Jmsg(jcr, M_FATAL, 0,
192 _("Unable to authenticate with File daemon. Possible causes:\n"
193 "Passwords or names not the same or\n"
194 "Maximum Concurrent Jobs exceeded on the FD or\n"
195 "FD networking messed up (restart daemon).\n"
196 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
200 /* Verify that the remote host is willing to meet our TLS requirements */
201 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
202 stop_bsock_timer(tid);
203 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
207 /* Verify that we are willing to meet the remote host's requirements */
208 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
209 stop_bsock_timer(tid);
210 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
214 /* Is TLS Enabled? */
215 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
216 /* Engage TLS! Full Speed Ahead! */
217 if (!bnet_tls_client(client->tls_ctx, fd)) {
218 stop_bsock_timer(tid);
219 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
224 Dmsg1(116, ">filed: %s", fd->msg);
225 if (bnet_recv(fd) <= 0) {
226 stop_bsock_timer(tid);
227 Dmsg1(50, _("Bad response from File daemon to Hello command: ERR=%s\n"),
229 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon to Hello command: ERR=%s\n"),
233 Dmsg1(110, "<stored: %s", fd->msg);
234 stop_bsock_timer(tid);
235 if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
236 Dmsg0(50, _("File daemon rejected Hello command\n"));
237 Jmsg(jcr, M_FATAL, 0, _("File daemon rejected Hello command\n"));
243 /*********************************************************************
246 int authenticate_user_agent(UAContext *uac)
248 char name[MAX_NAME_LENGTH];
249 int tls_local_need = BNET_TLS_NONE;
250 int tls_remote_need = BNET_TLS_NONE;
251 int compatible = true;
253 BSOCK *ua = uac->UA_sock;
254 bool auth_success = false;
255 TLS_CONTEXT *tls_ctx = NULL;
256 alist *verify_list = NULL;
259 // Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
260 // ua->host, ua->port, ua->msglen);
261 if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
262 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
263 ua->host, ua->port, ua->msglen);
267 if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
268 ua->msg[100] = 0; /* terminate string */
269 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who,
270 ua->host, ua->port, ua->msg);
274 name[sizeof(name)-1] = 0; /* terminate name */
275 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
276 /* TLS Requirement */
277 if (director->tls_enable) {
278 if (director->tls_require) {
279 tls_local_need = BNET_TLS_REQUIRED;
281 tls_local_need = BNET_TLS_OK;
285 if (director->tls_verify_peer) {
286 verify_list = director->tls_allowed_cns;
289 auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
291 cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
294 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
296 /* TLS Requirement */
297 if (cons->tls_enable) {
298 if (cons->tls_require) {
299 tls_local_need = BNET_TLS_REQUIRED;
301 tls_local_need = BNET_TLS_OK;
305 if (cons->tls_verify_peer) {
306 verify_list = cons->tls_allowed_cns;
309 auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
311 cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
314 uac->cons = cons; /* save console resource pointer */
317 auth_success = false;
322 /* Verify that the remote peer is willing to meet our TLS requirements */
323 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
324 Emsg0(M_FATAL, 0, _("Authorization problem:"
325 " Remote client did not advertise required TLS support.\n"));
326 auth_success = false;
330 /* Verify that we are willing to meet the peer's 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 requires TLS.\n"));
334 auth_success = false;
338 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
340 tls_ctx = cons->tls_ctx;
342 tls_ctx = director->tls_ctx;
345 /* Engage TLS! Full Speed Ahead! */
346 if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
347 Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
348 auth_success = false;
354 /* Authorization Completed */
357 bnet_fsend(ua, "%s", _(Dir_sorry));
358 Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
359 name, ua->who, ua->host, ua->port);
363 bnet_fsend(ua, _("1000 OK: %s Version: %s (%s)\n"), my_name, VERSION, BDATE);