2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Bacula Director -- authenticate.c -- handles authorization of
22 * Storage and File daemons.
24 * Written by: Kern Sibbald, May MMI
26 * This routine runs as a thread and must be thread reentrant.
33 static const int dbglvl = 50;
35 extern DIRRES *director;
37 /* Version at end of Hello
38 * prior to 06Aug13 no version
39 * 102 04Jun15 - added jobmedia change
40 * 103 14Feb17 - added comm line compression
42 #define DIR_VERSION 103
45 /* Command sent to SD */
46 static char hello[] = "Hello %sDirector %s calling %d\n";
48 /* Responses from Storage and File daemons */
49 static char OKhello[] = "3000 OK Hello";
50 static char SDOKnewHello[] = "3000 OK Hello %d";
51 static char FDOKhello[] = "2000 OK Hello";
52 static char FDOKnewHello[] = "2000 OK Hello %d";
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 Dmsg0(dbglvl, "Invalid bsock\n");
77 * Send my name to the Storage daemon then do authentication
79 bstrncpy(dirname, director->hdr.name, sizeof(dirname));
81 /* Timeout Hello after 1 min */
82 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
83 /* Sent Hello SD: Bacula Director <dirname> calling <version> */
84 if (!sd->fsend(hello, "SD: Bacula ", dirname, DIR_VERSION)) {
85 stop_bsock_timer(tid);
86 Dmsg1(dbglvl, _("Error sending Hello to Storage daemon. ERR=%s\n"), sd->bstrerror());
87 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), sd->bstrerror());
92 if (store->tls_enable) {
93 if (store->tls_require) {
94 tls_local_need = BNET_TLS_REQUIRED;
96 tls_local_need = BNET_TLS_OK;
100 if (store->tls_authenticate) {
101 tls_local_need = BNET_TLS_REQUIRED;
104 auth_success = cram_md5_respond(sd, store->password, &tls_remote_need, &compatible);
106 auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible);
108 Dmsg1(dbglvl, "cram_challenge failed for %s\n", sd->who());
111 Dmsg1(dbglvl, "cram_respond failed for %s\n", sd->who());
115 stop_bsock_timer(tid);
116 Dmsg0(dbglvl, _("Director and Storage daemon passwords or names not the same.\n"));
117 Jmsg2(jcr, M_FATAL, 0,
118 _("Director unable to authenticate with Storage daemon at \"%s:%d\". Possible causes:\n"
119 "Passwords or names not the same or\n"
120 "Maximum Concurrent Jobs exceeded on the SD or\n"
121 "SD networking messed up (restart daemon).\n"
122 "For help, please see: " MANUAL_AUTH_URL "\n"),
123 sd->host(), sd->port());
127 /* Verify that the remote host is willing to meet our TLS requirements */
128 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
129 stop_bsock_timer(tid);
130 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
134 /* Verify that we are willing to meet the remote host's requirements */
135 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
136 stop_bsock_timer(tid);
137 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
141 /* Is TLS Enabled? */
142 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
143 /* Engage TLS! Full Speed Ahead! */
144 if (!bnet_tls_client(store->tls_ctx, sd, NULL)) {
145 stop_bsock_timer(tid);
146 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD at \"%s:%d\"\n"),
147 sd->host(), sd->port());
150 if (store->tls_authenticate) { /* authentication only? */
151 sd->free_tls(); /* yes, stop tls */
155 Dmsg1(116, ">stored: %s", sd->msg);
156 if (sd->recv() <= 0) {
157 stop_bsock_timer(tid);
158 Jmsg3(jcr, M_FATAL, 0, _("bdird<stored: \"%s:%s\" bad response to Hello command: ERR=%s\n"),
159 sd->who(), sd->host(), sd->bstrerror());
162 Dmsg1(110, "<stored: %s", sd->msg);
163 stop_bsock_timer(tid);
165 if (sscanf(sd->msg, SDOKnewHello, &jcr->SDVersion) != 1 &&
166 strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
167 Dmsg0(dbglvl, _("Storage daemon rejected Hello command\n"));
168 Jmsg2(jcr, M_FATAL, 0, _("Storage daemon at \"%s:%d\" rejected Hello command\n"),
169 sd->host(), sd->port());
172 /* For newer SD turn on comm line compression */
173 if (jcr->SDVersion >= 1 && director->comm_compression) {
176 sd->clear_compress();
177 Dmsg0(050, "*** No Dir compression to SD\n");
179 if (jcr->SDVersion < 2) {
180 Jmsg2(jcr, M_FATAL, 0, _("Older Storage daemon at \"%s:%d\" incompatible with this Director.\n"),
181 sd->host(), sd->port());
188 * Authenticate File daemon connection
190 int authenticate_file_daemon(JCR *jcr)
192 BSOCK *fd = jcr->file_bsock;
193 CLIENT *client = jcr->client;
194 char dirname[MAX_NAME_LENGTH];
195 int tls_local_need = BNET_TLS_NONE;
196 int tls_remote_need = BNET_TLS_NONE;
197 int compatible = true;
198 bool auth_success = false;
201 * Send my name to the File daemon then do authentication
203 bstrncpy(dirname, director->name(), sizeof(dirname));
204 bash_spaces(dirname);
205 /* Timeout Hello after 1 min */
206 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
207 if (!fd->fsend(hello, "", dirname, DIR_VERSION)) {
208 stop_bsock_timer(tid);
209 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon at \"%s:%d\". ERR=%s\n"),
210 fd->host(), fd->port(), fd->bstrerror());
211 Dmsg3(50, _("Error sending Hello to File daemon at \"%s:%d\". ERR=%s\n"),
212 fd->host(), fd->port(), fd->bstrerror());
215 Dmsg1(dbglvl, "Sent: %s", fd->msg);
217 /* TLS Requirement */
218 if (client->tls_enable) {
219 if (client->tls_require) {
220 tls_local_need = BNET_TLS_REQUIRED;
222 tls_local_need = BNET_TLS_OK;
226 if (client->tls_authenticate) {
227 tls_local_need = BNET_TLS_REQUIRED;
230 auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
232 auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
234 Dmsg1(dbglvl, "cram_auth failed for %s\n", fd->who());
237 Dmsg1(dbglvl, "cram_get_auth failed for %s\n", fd->who());
240 stop_bsock_timer(tid);
241 Dmsg0(dbglvl, _("Director and File daemon passwords or names not the same.\n"));
242 Jmsg(jcr, M_FATAL, 0,
243 _("Unable to authenticate with File daemon at \"%s:%d\". Possible causes:\n"
244 "Passwords or names not the same or\n"
245 "Maximum Concurrent Jobs exceeded on the FD or\n"
246 "FD networking messed up (restart daemon).\n"
247 "For help, please see: " MANUAL_AUTH_URL "\n"),
248 fd->host(), fd->port());
252 /* Verify that the remote host is willing to meet our TLS requirements */
253 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
254 stop_bsock_timer(tid);
255 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD \"%s:%s\" did not advertise required TLS support.\n"),
256 fd->who(), fd->host());
260 /* Verify that we are willing to meet the remote host's requirements */
261 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
262 stop_bsock_timer(tid);
263 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD at \"%s:%d\" requires TLS.\n"),
264 fd->host(), fd->port());
268 /* Is TLS Enabled? */
269 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
270 /* Engage TLS! Full Speed Ahead! */
271 if (!bnet_tls_client(client->tls_ctx, fd, client->tls_allowed_cns)) {
272 stop_bsock_timer(tid);
273 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\".\n"),
274 fd->host(), fd->port());
277 if (client->tls_authenticate) { /* tls authentication only? */
278 fd->free_tls(); /* yes, shutdown tls */
282 Dmsg1(116, ">filed: %s", fd->msg);
283 if (fd->recv() <= 0) {
284 stop_bsock_timer(tid);
285 Dmsg1(dbglvl, _("Bad response from File daemon to Hello command: ERR=%s\n"),
287 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon at \"%s:%d\" to Hello command: ERR=%s\n"),
288 fd->host(), fd->port(), fd->bstrerror());
291 Dmsg1(110, "<filed: %s", fd->msg);
292 stop_bsock_timer(tid);
294 if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0 &&
295 sscanf(fd->msg, FDOKnewHello, &jcr->FDVersion) != 1) {
296 Dmsg0(dbglvl, _("File daemon rejected Hello command\n"));
297 Jmsg(jcr, M_FATAL, 0, _("File daemon at \"%s:%d\" rejected Hello command\n"),
298 fd->host(), fd->port());
301 /* For newer FD turn on comm line compression */
302 if (jcr->FDVersion >= 214 && director->comm_compression) {
305 fd->clear_compress();
306 Dmsg0(050, "*** No Dir compression to FD\n");
311 /*********************************************************************
314 int authenticate_user_agent(UAContext *uac)
316 char name[MAX_NAME_LENGTH];
317 int tls_local_need = BNET_TLS_NONE;
318 int tls_remote_need = BNET_TLS_NONE;
319 bool tls_authenticate;
320 int compatible = true;
322 BSOCK *ua = uac->UA_sock;
323 bool auth_success = false;
324 TLS_CONTEXT *tls_ctx = NULL;
325 alist *verify_list = NULL;
328 if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
329 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(),
330 ua->host(), ua->port(), ua->msglen);
334 if (sscanf(ua->msg, "Hello %127s calling %d", name, &ua_version) != 2 &&
335 sscanf(ua->msg, "Hello %127s calling", name) != 1) {
336 ua->msg[100] = 0; /* terminate string */
337 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(),
338 ua->host(), ua->port(), ua->msg);
342 /* Turn on compression for newer consoles */
343 if (ua_version >= 1 && director->comm_compression) {
346 Dmsg0(050, "*** No Dir compression to UA\n");
349 name[sizeof(name)-1] = 0; /* terminate name */
350 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
351 /* TLS Requirement */
352 if (director->tls_enable) {
353 if (director->tls_require) {
354 tls_local_need = BNET_TLS_REQUIRED;
356 tls_local_need = BNET_TLS_OK;
360 tls_authenticate = director->tls_authenticate;
362 if (tls_authenticate) {
363 tls_local_need = BNET_TLS_REQUIRED;
366 if (director->tls_verify_peer) {
367 verify_list = director->tls_allowed_cns;
370 auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
372 cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
375 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
377 /* TLS Requirement */
378 if (cons->tls_enable) {
379 if (cons->tls_require) {
380 tls_local_need = BNET_TLS_REQUIRED;
382 tls_local_need = BNET_TLS_OK;
386 tls_authenticate = cons->tls_authenticate;
388 if (tls_authenticate) {
389 tls_local_need = BNET_TLS_REQUIRED;
392 if (cons->tls_verify_peer) {
393 verify_list = cons->tls_allowed_cns;
396 auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
398 cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
401 uac->cons = cons; /* save console resource pointer */
404 auth_success = false;
410 /* Verify that the remote peer is willing to meet our TLS requirements */
411 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
412 Emsg0(M_FATAL, 0, _("Authorization problem:"
413 " Remote client did not advertise required TLS support.\n"));
414 auth_success = false;
418 /* Verify that we are willing to meet the peer's requirements */
419 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
420 Emsg0(M_FATAL, 0, _("Authorization problem:"
421 " Remote client requires TLS.\n"));
422 auth_success = false;
426 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
428 tls_ctx = cons->tls_ctx;
430 tls_ctx = director->tls_ctx;
433 /* Engage TLS! Full Speed Ahead! */
434 if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
435 Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
436 auth_success = false;
439 if (tls_authenticate) { /* authentication only? */
440 ua->free_tls(); /* stop tls */
445 /* Authorization Completed */
448 ua->fsend("%s", _(Dir_sorry));
449 Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
450 name, ua->who(), ua->host(), ua->port());
454 ua->fsend(_("1000 OK: %d %s %sVersion: %s (%s)\n"),
455 DIR_VERSION, my_name, "", VERSION, BDATE);