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));
169 Dmsg1(50, "Sent: %s", fd->msg);
171 /* TLS Requirement */
172 if (client->tls_enable) {
173 if (client->tls_require) {
174 tls_local_need = BNET_TLS_REQUIRED;
176 tls_local_need = BNET_TLS_OK;
180 auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
182 auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
184 Dmsg1(50, "cram_auth failed for %s\n", fd->who);
187 Dmsg1(50, "cram_get_auth failed for %s\n", fd->who);
190 stop_bsock_timer(tid);
191 Dmsg0(50, _("Director and File daemon passwords or names not the same.\n"));
192 Jmsg(jcr, M_FATAL, 0,
193 _("Unable to authenticate with File daemon. Possible causes:\n"
194 "Passwords or names not the same or\n"
195 "Maximum Concurrent Jobs exceeded on the FD or\n"
196 "FD networking messed up (restart daemon).\n"
197 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
201 /* Verify that the remote host is willing to meet our TLS requirements */
202 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
203 stop_bsock_timer(tid);
204 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
208 /* Verify that we are willing to meet the remote host's requirements */
209 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
210 stop_bsock_timer(tid);
211 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
215 /* Is TLS Enabled? */
216 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
217 /* Engage TLS! Full Speed Ahead! */
218 if (!bnet_tls_client(client->tls_ctx, fd)) {
219 stop_bsock_timer(tid);
220 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
225 Dmsg1(116, ">filed: %s", fd->msg);
226 if (bnet_recv(fd) <= 0) {
227 stop_bsock_timer(tid);
228 Dmsg1(50, _("Bad response from File daemon to Hello command: ERR=%s\n"),
230 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon to Hello command: ERR=%s\n"),
234 Dmsg1(110, "<stored: %s", fd->msg);
235 stop_bsock_timer(tid);
236 if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
237 Dmsg0(50, _("File daemon rejected Hello command\n"));
238 Jmsg(jcr, M_FATAL, 0, _("File daemon rejected Hello command\n"));
244 /*********************************************************************
247 int authenticate_user_agent(UAContext *uac)
249 char name[MAX_NAME_LENGTH];
250 int tls_local_need = BNET_TLS_NONE;
251 int tls_remote_need = BNET_TLS_NONE;
252 int compatible = true;
254 BSOCK *ua = uac->UA_sock;
255 bool auth_success = false;
256 TLS_CONTEXT *tls_ctx = NULL;
257 alist *verify_list = NULL;
260 // Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
261 // ua->host, ua->port, ua->msglen);
262 if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
263 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
264 ua->host, ua->port, ua->msglen);
268 if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
269 ua->msg[100] = 0; /* terminate string */
270 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who,
271 ua->host, ua->port, ua->msg);
275 name[sizeof(name)-1] = 0; /* terminate name */
276 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
277 /* TLS Requirement */
278 if (director->tls_enable) {
279 if (director->tls_require) {
280 tls_local_need = BNET_TLS_REQUIRED;
282 tls_local_need = BNET_TLS_OK;
286 if (director->tls_verify_peer) {
287 verify_list = director->tls_allowed_cns;
290 auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
292 cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
295 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
297 /* TLS Requirement */
298 if (cons->tls_enable) {
299 if (cons->tls_require) {
300 tls_local_need = BNET_TLS_REQUIRED;
302 tls_local_need = BNET_TLS_OK;
306 if (cons->tls_verify_peer) {
307 verify_list = cons->tls_allowed_cns;
310 auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
312 cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
315 uac->cons = cons; /* save console resource pointer */
318 auth_success = false;
323 /* Verify that the remote peer is willing to meet our TLS requirements */
324 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
325 Emsg0(M_FATAL, 0, _("Authorization problem:"
326 " Remote client did not advertise required TLS support.\n"));
327 auth_success = false;
331 /* Verify that we are willing to meet the peer's requirements */
332 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
333 Emsg0(M_FATAL, 0, _("Authorization problem:"
334 " Remote client requires TLS.\n"));
335 auth_success = false;
339 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
341 tls_ctx = cons->tls_ctx;
343 tls_ctx = director->tls_ctx;
346 /* Engage TLS! Full Speed Ahead! */
347 if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
348 Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
349 auth_success = false;
355 /* Authorization Completed */
358 bnet_fsend(ua, "%s", _(Dir_sorry));
359 Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
360 name, ua->who, ua->host, ua->port);
364 bnet_fsend(ua, _("1000 OK: %s Version: %s (%s)\n"), my_name, VERSION, BDATE);