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 Bacula® - The Network Backup Solution
16 Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
18 The main author of Bacula is Kern Sibbald, with contributions from
19 many others, a complete list can be found in the file AUTHORS.
20 This program is Free Software; you can redistribute it and/or
21 modify it under the terms of version two of the GNU General Public
22 License as published by the Free Software Foundation plus additions
23 that are listed in the file LICENSE.
25 This program is distributed in the hope that it will be useful, but
26 WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 General Public License for more details.
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 Bacula® is a registered trademark of John Walker.
36 The licensor of Bacula is the Free Software Foundation Europe
37 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
38 Switzerland, email:ftf@fsfeurope.org.
44 extern DIRRES *director;
46 /* Commands sent to Storage daemon and File daemon and received
47 * from the User Agent */
48 static char hello[] = "Hello Director %s calling\n";
50 /* Response from Storage daemon */
51 static char OKhello[] = "3000 OK Hello\n";
52 static char FDOKhello[] = "2000 OK Hello\n";
54 /* Sent to User Agent */
55 static char Dir_sorry[] = "1999 You are not authorized.\n";
57 /* Forward referenced functions */
60 * Authenticate Storage daemon connection
62 bool authenticate_storage_daemon(JCR *jcr, STORE *store)
64 BSOCK *sd = jcr->store_bsock;
65 char dirname[MAX_NAME_LENGTH];
66 int tls_local_need = BNET_TLS_NONE;
67 int tls_remote_need = BNET_TLS_NONE;
68 int compatible = true;
69 bool auth_success = false;
72 * Send my name to the Storage daemon then do authentication
74 bstrncpy(dirname, director->hdr.name, sizeof(dirname));
76 /* Timeout Hello after 1 min */
77 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
78 if (!bnet_fsend(sd, hello, dirname)) {
79 stop_bsock_timer(tid);
80 Dmsg1(50, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
81 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
86 if (store->tls_enable) {
87 if (store->tls_require) {
88 tls_local_need = BNET_TLS_REQUIRED;
90 tls_local_need = BNET_TLS_OK;
94 auth_success = cram_md5_respond(sd, store->password, &tls_remote_need, &compatible);
96 auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible);
98 Dmsg1(50, "cram_challenge failed for %s\n", sd->who());
101 Dmsg1(50, "cram_respond failed for %s\n", sd->who());
105 stop_bsock_timer(tid);
106 Dmsg0(50, _("Director and Storage daemon passwords or names not the same.\n"));
107 Jmsg2(jcr, M_FATAL, 0,
108 _("Director unable to authenticate with Storage daemon on \"%s:%d\". Possible causes:\n"
109 "Passwords or names not the same or\n"
110 "Maximum Concurrent Jobs exceeded on the SD or\n"
111 "SD networking messed up (restart daemon).\n"
112 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
113 sd->host(), sd->port());
117 /* Verify that the remote host is willing to meet our TLS 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 did not advertise required TLS support.\n"));
124 /* Verify that we are willing to meet the remote host's requirements */
125 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
126 stop_bsock_timer(tid);
127 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
131 /* Is TLS Enabled? */
132 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
133 /* Engage TLS! Full Speed Ahead! */
134 if (!bnet_tls_client(store->tls_ctx, sd, NULL)) {
135 stop_bsock_timer(tid);
136 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD on \"%s:%d\"\n"),
137 sd->host(), sd->port());
142 Dmsg1(116, ">stored: %s", sd->msg);
143 if (bnet_recv(sd) <= 0) {
144 stop_bsock_timer(tid);
145 Jmsg3(jcr, M_FATAL, 0, _("bdird<stored: \"%s:%s\" bad response to Hello command: ERR=%s\n"),
146 sd->who(), sd->host(), bnet_strerror(sd));
149 Dmsg1(110, "<stored: %s", sd->msg);
150 stop_bsock_timer(tid);
151 if (strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
152 Dmsg0(50, _("Storage daemon rejected Hello command\n"));
153 Jmsg2(jcr, M_FATAL, 0, _("Storage daemon on \"%s:%d\" rejected Hello command\n"),
154 sd->host(), sd->port());
161 * Authenticate File daemon connection
163 int authenticate_file_daemon(JCR *jcr)
165 BSOCK *fd = jcr->file_bsock;
166 CLIENT *client = jcr->client;
167 char dirname[MAX_NAME_LENGTH];
168 int tls_local_need = BNET_TLS_NONE;
169 int tls_remote_need = BNET_TLS_NONE;
170 int compatible = true;
171 bool auth_success = false;
174 * Send my name to the File daemon then do authentication
176 bstrncpy(dirname, director->hdr.name, sizeof(dirname));
177 bash_spaces(dirname);
178 /* Timeout Hello after 10 mins */
179 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
180 if (!bnet_fsend(fd, hello, dirname)) {
181 stop_bsock_timer(tid);
182 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon on \"%s:%d\". ERR=%s\n"),
183 fd->host(), fd->port(), bnet_strerror(fd));
186 Dmsg1(50, "Sent: %s", fd->msg);
188 /* TLS Requirement */
189 if (client->tls_enable) {
190 if (client->tls_require) {
191 tls_local_need = BNET_TLS_REQUIRED;
193 tls_local_need = BNET_TLS_OK;
197 auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
199 auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
201 Dmsg1(50, "cram_auth failed for %s\n", fd->who());
204 Dmsg1(50, "cram_get_auth failed for %s\n", fd->who());
207 stop_bsock_timer(tid);
208 Dmsg0(50, _("Director and File daemon passwords or names not the same.\n"));
209 Jmsg(jcr, M_FATAL, 0,
210 _("Unable to authenticate with File daemon on \"%s:%d\". Possible causes:\n"
211 "Passwords or names not the same or\n"
212 "Maximum Concurrent Jobs exceeded on the FD or\n"
213 "FD networking messed up (restart daemon).\n"
214 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
215 fd->host(), fd->port());
219 /* Verify that the remote host is willing to meet our TLS requirements */
220 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
221 stop_bsock_timer(tid);
222 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD \"%s:%s\" did not advertise required TLS support.\n"),
223 fd->who(), fd->host());
227 /* Verify that we are willing to meet the remote host's requirements */
228 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
229 stop_bsock_timer(tid);
230 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD on \"%s:%d\" requires TLS.\n"),
231 fd->host(), fd->port());
235 /* Is TLS Enabled? */
236 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
237 /* Engage TLS! Full Speed Ahead! */
238 if (!bnet_tls_client(client->tls_ctx, fd, client->tls_allowed_cns)) {
240 stop_bsock_timer(tid);
241 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD on \"%s:%d\".\n"),
242 fd->host(), fd->port());
247 Dmsg1(116, ">filed: %s", fd->msg);
248 if (bnet_recv(fd) <= 0) {
249 stop_bsock_timer(tid);
250 Dmsg1(50, _("Bad response from File daemon to Hello command: ERR=%s\n"),
252 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon on \"%s:%d\" to Hello command: ERR=%s\n"),
253 fd->host(), fd->port(), bnet_strerror(fd));
256 Dmsg1(110, "<stored: %s", fd->msg);
257 stop_bsock_timer(tid);
258 if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
259 Dmsg0(50, _("File daemon rejected Hello command\n"));
260 Jmsg(jcr, M_FATAL, 0, _("File daemon on \"%s:%d\" rejected Hello command\n"),
261 fd->host(), fd->port());
267 /*********************************************************************
270 int authenticate_user_agent(UAContext *uac)
272 char name[MAX_NAME_LENGTH];
273 int tls_local_need = BNET_TLS_NONE;
274 int tls_remote_need = BNET_TLS_NONE;
275 int compatible = true;
277 BSOCK *ua = uac->UA_sock;
278 bool auth_success = false;
279 TLS_CONTEXT *tls_ctx = NULL;
280 alist *verify_list = NULL;
283 // Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(),
284 // ua->host(), ua->port(), ua->msglen);
285 if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
286 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(),
287 ua->host(), ua->port(), ua->msglen);
291 if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
292 ua->msg[100] = 0; /* terminate string */
293 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(),
294 ua->host(), ua->port(), ua->msg);
298 name[sizeof(name)-1] = 0; /* terminate name */
299 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
300 /* TLS Requirement */
301 if (director->tls_enable) {
302 if (director->tls_require) {
303 tls_local_need = BNET_TLS_REQUIRED;
305 tls_local_need = BNET_TLS_OK;
309 if (director->tls_verify_peer) {
310 verify_list = director->tls_allowed_cns;
313 auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
315 cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
318 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
320 /* TLS Requirement */
321 if (cons->tls_enable) {
322 if (cons->tls_require) {
323 tls_local_need = BNET_TLS_REQUIRED;
325 tls_local_need = BNET_TLS_OK;
329 if (cons->tls_verify_peer) {
330 verify_list = cons->tls_allowed_cns;
333 auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
335 cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
338 uac->cons = cons; /* save console resource pointer */
341 auth_success = false;
346 /* Verify that the remote peer is willing to meet our TLS requirements */
347 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
348 Emsg0(M_FATAL, 0, _("Authorization problem:"
349 " Remote client did not advertise required TLS support.\n"));
350 auth_success = false;
354 /* Verify that we are willing to meet the peer's requirements */
355 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
356 Emsg0(M_FATAL, 0, _("Authorization problem:"
357 " Remote client requires TLS.\n"));
358 auth_success = false;
362 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
364 tls_ctx = cons->tls_ctx;
366 tls_ctx = director->tls_ctx;
369 /* Engage TLS! Full Speed Ahead! */
370 if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
371 Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
372 auth_success = false;
378 /* Authorization Completed */
381 bnet_fsend(ua, "%s", _(Dir_sorry));
382 Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
383 name, ua->who(), ua->host(), ua->port());
387 bnet_fsend(ua, _("1000 OK: %s Version: %s (%s)\n"), my_name, VERSION, BDATE);