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 and included
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 static const int dbglvl = 50;
46 extern DIRRES *director;
48 /* Commands sent to Storage daemon and File daemon and received
49 * from the User Agent */
50 static char hello[] = "Hello Director %s calling\n";
52 /* Response from Storage daemon */
53 static char OKhello[] = "3000 OK Hello\n";
54 static char FDOKhello[] = "2000 OK Hello\n";
56 /* Sent to User Agent */
57 static char Dir_sorry[] = "1999 You are not authorized.\n";
59 /* Forward referenced functions */
62 * Authenticate Storage daemon connection
64 bool authenticate_storage_daemon(JCR *jcr, STORE *store)
66 BSOCK *sd = jcr->store_bsock;
67 char dirname[MAX_NAME_LENGTH];
68 int tls_local_need = BNET_TLS_NONE;
69 int tls_remote_need = BNET_TLS_NONE;
70 int compatible = true;
71 bool auth_success = false;
74 * Send my name to the Storage daemon then do authentication
76 bstrncpy(dirname, director->hdr.name, sizeof(dirname));
78 /* Timeout Hello after 1 min */
79 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
80 if (!sd->fsend(hello, dirname)) {
81 stop_bsock_timer(tid);
82 Dmsg1(dbglvl, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
83 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
88 if (store->tls_enable) {
89 if (store->tls_require) {
90 tls_local_need = BNET_TLS_REQUIRED;
92 tls_local_need = BNET_TLS_OK;
96 if (store->tls_authenticate) {
97 tls_local_need = BNET_TLS_REQUIRED;
100 auth_success = cram_md5_respond(sd, store->password, &tls_remote_need, &compatible);
102 auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible);
104 Dmsg1(dbglvl, "cram_challenge failed for %s\n", sd->who());
107 Dmsg1(dbglvl, "cram_respond failed for %s\n", sd->who());
111 stop_bsock_timer(tid);
112 Dmsg0(dbglvl, _("Director and Storage daemon passwords or names not the same.\n"));
113 Jmsg2(jcr, M_FATAL, 0,
114 _("Director unable to authenticate with Storage daemon at \"%s:%d\". Possible causes:\n"
115 "Passwords or names not the same or\n"
116 "Maximum Concurrent Jobs exceeded on the SD or\n"
117 "SD networking messed up (restart daemon).\n"
118 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
119 sd->host(), sd->port());
123 /* Verify that the remote host is willing to meet our TLS requirements */
124 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
125 stop_bsock_timer(tid);
126 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
130 /* Verify that we are willing to meet the remote host's requirements */
131 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
132 stop_bsock_timer(tid);
133 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
137 /* Is TLS Enabled? */
138 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
139 /* Engage TLS! Full Speed Ahead! */
140 if (!bnet_tls_client(store->tls_ctx, sd, NULL)) {
141 stop_bsock_timer(tid);
142 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD at \"%s:%d\"\n"),
143 sd->host(), sd->port());
146 if (store->tls_authenticate) { /* authentication only? */
147 sd->free_tls(); /* yes, stop tls */
151 Dmsg1(116, ">stored: %s", sd->msg);
152 if (sd->recv() <= 0) {
153 stop_bsock_timer(tid);
154 Jmsg3(jcr, M_FATAL, 0, _("bdird<stored: \"%s:%s\" bad response to Hello command: ERR=%s\n"),
155 sd->who(), sd->host(), sd->bstrerror());
158 Dmsg1(110, "<stored: %s", sd->msg);
159 stop_bsock_timer(tid);
160 if (strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
161 Dmsg0(dbglvl, _("Storage daemon rejected Hello command\n"));
162 Jmsg2(jcr, M_FATAL, 0, _("Storage daemon at \"%s:%d\" rejected Hello command\n"),
163 sd->host(), sd->port());
170 * Authenticate File daemon connection
172 int authenticate_file_daemon(JCR *jcr)
174 BSOCK *fd = jcr->file_bsock;
175 CLIENT *client = jcr->client;
176 char dirname[MAX_NAME_LENGTH];
177 int tls_local_need = BNET_TLS_NONE;
178 int tls_remote_need = BNET_TLS_NONE;
179 int compatible = true;
180 bool auth_success = false;
183 * Send my name to the File daemon then do authentication
185 bstrncpy(dirname, director->name(), sizeof(dirname));
186 bash_spaces(dirname);
187 /* Timeout Hello after 1 min */
188 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
189 if (!fd->fsend(hello, dirname)) {
190 stop_bsock_timer(tid);
191 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon at \"%s:%d\". ERR=%s\n"),
192 fd->host(), fd->port(), fd->bstrerror());
195 Dmsg1(dbglvl, "Sent: %s", fd->msg);
197 /* TLS Requirement */
198 if (client->tls_enable) {
199 if (client->tls_require) {
200 tls_local_need = BNET_TLS_REQUIRED;
202 tls_local_need = BNET_TLS_OK;
206 if (client->tls_authenticate) {
207 tls_local_need = BNET_TLS_REQUIRED;
210 auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
212 auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
214 Dmsg1(dbglvl, "cram_auth failed for %s\n", fd->who());
217 Dmsg1(dbglvl, "cram_get_auth failed for %s\n", fd->who());
220 stop_bsock_timer(tid);
221 Dmsg0(dbglvl, _("Director and File daemon passwords or names not the same.\n"));
222 Jmsg(jcr, M_FATAL, 0,
223 _("Unable to authenticate with File daemon at \"%s:%d\". Possible causes:\n"
224 "Passwords or names not the same or\n"
225 "Maximum Concurrent Jobs exceeded on the FD or\n"
226 "FD networking messed up (restart daemon).\n"
227 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
228 fd->host(), fd->port());
232 /* Verify that the remote host is willing to meet our TLS requirements */
233 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
234 stop_bsock_timer(tid);
235 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD \"%s:%s\" did not advertise required TLS support.\n"),
236 fd->who(), fd->host());
240 /* Verify that we are willing to meet the remote host's requirements */
241 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
242 stop_bsock_timer(tid);
243 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD at \"%s:%d\" requires TLS.\n"),
244 fd->host(), fd->port());
248 /* Is TLS Enabled? */
249 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
250 /* Engage TLS! Full Speed Ahead! */
251 if (!bnet_tls_client(client->tls_ctx, fd, client->tls_allowed_cns)) {
253 stop_bsock_timer(tid);
254 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\".\n"),
255 fd->host(), fd->port());
258 if (client->tls_authenticate) { /* tls authentication only? */
259 fd->free_tls(); /* yes, shutdown tls */
263 Dmsg1(116, ">filed: %s", fd->msg);
264 if (fd->recv() <= 0) {
265 stop_bsock_timer(tid);
266 Dmsg1(dbglvl, _("Bad response from File daemon to Hello command: ERR=%s\n"),
268 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon at \"%s:%d\" to Hello command: ERR=%s\n"),
269 fd->host(), fd->port(), fd->bstrerror());
272 Dmsg1(110, "<stored: %s", fd->msg);
273 stop_bsock_timer(tid);
274 if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
275 Dmsg0(dbglvl, _("File daemon rejected Hello command\n"));
276 Jmsg(jcr, M_FATAL, 0, _("File daemon at \"%s:%d\" rejected Hello command\n"),
277 fd->host(), fd->port());
283 /*********************************************************************
286 int authenticate_user_agent(UAContext *uac)
288 char name[MAX_NAME_LENGTH];
289 int tls_local_need = BNET_TLS_NONE;
290 int tls_remote_need = BNET_TLS_NONE;
292 bool tls_authenticate;
293 int compatible = true;
295 BSOCK *ua = uac->UA_sock;
296 bool auth_success = false;
297 TLS_CONTEXT *tls_ctx = NULL;
298 alist *verify_list = NULL;
300 if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
301 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(),
302 ua->host(), ua->port(), ua->msglen);
306 if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
307 ua->msg[100] = 0; /* terminate string */
308 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(),
309 ua->host(), ua->port(), ua->msg);
313 name[sizeof(name)-1] = 0; /* terminate name */
314 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
315 /* TLS Requirement */
316 if (director->tls_enable) {
317 if (director->tls_require) {
318 tls_local_need = BNET_TLS_REQUIRED;
320 tls_local_need = BNET_TLS_OK;
324 tls_authenticate = director->tls_authenticate;
325 need_tls = director->tls_enable || tls_authenticate;
327 if (tls_authenticate) {
328 tls_local_need = BNET_TLS_REQUIRED;
331 if (director->tls_verify_peer) {
332 verify_list = director->tls_allowed_cns;
335 auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
337 cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
340 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
342 /* TLS Requirement */
343 if (cons->tls_enable) {
344 if (cons->tls_require) {
345 tls_local_need = BNET_TLS_REQUIRED;
347 tls_local_need = BNET_TLS_OK;
351 tls_authenticate = cons->tls_authenticate;
352 need_tls = cons->tls_enable || tls_authenticate;
354 if (tls_authenticate) {
355 tls_local_need = BNET_TLS_REQUIRED;
358 if (cons->tls_verify_peer) {
359 verify_list = cons->tls_allowed_cns;
362 auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
364 cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
367 uac->cons = cons; /* save console resource pointer */
370 auth_success = false;
376 /* Verify that the remote peer is willing to meet our TLS requirements */
377 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
378 Emsg0(M_FATAL, 0, _("Authorization problem:"
379 " Remote client did not advertise required TLS support.\n"));
380 auth_success = false;
384 /* Verify that we are willing to meet the peer's requirements */
385 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
386 Emsg0(M_FATAL, 0, _("Authorization problem:"
387 " Remote client requires TLS.\n"));
388 auth_success = false;
392 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
394 tls_ctx = cons->tls_ctx;
396 tls_ctx = director->tls_ctx;
399 /* Engage TLS! Full Speed Ahead! */
400 if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
401 Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
402 auth_success = false;
405 if (tls_authenticate) { /* authentication only? */
406 ua->free_tls(); /* stop tls */
411 /* Authorization Completed */
414 ua->fsend("%s", _(Dir_sorry));
415 Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
416 name, ua->who(), ua->host(), ua->port());
420 ua->fsend(_("1000 OK: %s Version: %s (%s)\n"), my_name, VERSION, BDATE);