2 Bacula® - The Network Backup Solution
4 Copyright (C) 2001-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation plus additions
11 that are listed in the file LICENSE.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Director -- authorize.c -- handles authorization of
31 * Storage and File daemons.
33 * Kern Sibbald, May MMI
35 * This routine runs as a thread and must be thread reentrant.
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 (!sd->fsend(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 at \"%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 at \"%s:%d\"\n"),
137 sd->host(), sd->port());
142 Dmsg1(116, ">stored: %s", sd->msg);
143 if (sd->recv() <= 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(), sd->bstrerror());
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 at \"%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 1 min */
179 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
180 if (!fd->fsend(hello, dirname)) {
181 stop_bsock_timer(tid);
182 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon at \"%s:%d\". ERR=%s\n"),
183 fd->host(), fd->port(), fd->bstrerror());
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 at \"%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 at \"%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 at \"%s:%d\".\n"),
242 fd->host(), fd->port());
247 Dmsg1(116, ">filed: %s", fd->msg);
248 if (fd->recv() <= 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 at \"%s:%d\" to Hello command: ERR=%s\n"),
253 fd->host(), fd->port(), fd->bstrerror());
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 at \"%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;
282 if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
283 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(),
284 ua->host(), ua->port(), ua->msglen);
288 if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
289 ua->msg[100] = 0; /* terminate string */
290 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(),
291 ua->host(), ua->port(), ua->msg);
295 name[sizeof(name)-1] = 0; /* terminate name */
296 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
297 /* TLS Requirement */
298 if (director->tls_enable) {
299 if (director->tls_require) {
300 tls_local_need = BNET_TLS_REQUIRED;
302 tls_local_need = BNET_TLS_OK;
306 if (director->tls_verify_peer) {
307 verify_list = director->tls_allowed_cns;
310 auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
312 cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
315 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
317 /* TLS Requirement */
318 if (cons->tls_enable) {
319 if (cons->tls_require) {
320 tls_local_need = BNET_TLS_REQUIRED;
322 tls_local_need = BNET_TLS_OK;
326 if (cons->tls_verify_peer) {
327 verify_list = cons->tls_allowed_cns;
330 auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
332 cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
335 uac->cons = cons; /* save console resource pointer */
338 auth_success = false;
343 /* Verify that the remote peer is willing to meet our TLS requirements */
344 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
345 Emsg0(M_FATAL, 0, _("Authorization problem:"
346 " Remote client did not advertise required TLS support.\n"));
347 auth_success = false;
351 /* Verify that we are willing to meet the peer's requirements */
352 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
353 Emsg0(M_FATAL, 0, _("Authorization problem:"
354 " Remote client requires TLS.\n"));
355 auth_success = false;
359 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
361 tls_ctx = cons->tls_ctx;
363 tls_ctx = director->tls_ctx;
366 /* Engage TLS! Full Speed Ahead! */
367 if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
368 Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
369 auth_success = false;
375 /* Authorization Completed */
378 ua->fsend("%s", _(Dir_sorry));
379 Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
380 name, ua->who(), ua->host(), ua->port());
384 ua->fsend(_("1000 OK: %s Version: %s (%s)\n"), my_name, VERSION, BDATE);