2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
22 * Bacula Director -- authenticate.c -- handles authorization of
23 * Storage and File daemons.
25 * Written by: Kern Sibbald, May MMI
27 * This routine runs as a thread and must be thread reentrant.
34 static const int dbglvl = 50;
36 extern DIRRES *director;
38 /* Version at end of Hello
39 * prior to 06Aug13 no version
40 * 102 04Jun15 - added jobmedia change
42 #define DIR_VERSION 102
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 * 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 /* Sent Hello SD: Bacula Director <dirname> calling <version> */
79 if (!sd->fsend(hello, "SD: Bacula ", dirname, DIR_VERSION)) {
80 stop_bsock_timer(tid);
81 Dmsg1(dbglvl, _("Error sending Hello to Storage daemon. ERR=%s\n"), sd->bstrerror());
82 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), sd->bstrerror());
87 if (store->tls_enable) {
88 if (store->tls_require) {
89 tls_local_need = BNET_TLS_REQUIRED;
91 tls_local_need = BNET_TLS_OK;
95 if (store->tls_authenticate) {
96 tls_local_need = BNET_TLS_REQUIRED;
99 auth_success = cram_md5_respond(sd, store->password, &tls_remote_need, &compatible);
101 auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible);
103 Dmsg1(dbglvl, "cram_challenge failed for %s\n", sd->who());
106 Dmsg1(dbglvl, "cram_respond failed for %s\n", sd->who());
110 stop_bsock_timer(tid);
111 Dmsg0(dbglvl, _("Director and Storage daemon passwords or names not the same.\n"));
112 Jmsg2(jcr, M_FATAL, 0,
113 _("Director unable to authenticate with Storage daemon at \"%s:%d\". Possible causes:\n"
114 "Passwords or names not the same or\n"
115 "Maximum Concurrent Jobs exceeded on the SD or\n"
116 "SD networking messed up (restart daemon).\n"
117 "For help, please see: " MANUAL_AUTH_URL "\n"),
118 sd->host(), sd->port());
122 /* Verify that the remote host is willing to meet our TLS requirements */
123 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
124 stop_bsock_timer(tid);
125 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
129 /* Verify that we are willing to meet the remote host's requirements */
130 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
131 stop_bsock_timer(tid);
132 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
136 /* Is TLS Enabled? */
137 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
138 /* Engage TLS! Full Speed Ahead! */
139 if (!bnet_tls_client(store->tls_ctx, sd, NULL)) {
140 stop_bsock_timer(tid);
141 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD at \"%s:%d\"\n"),
142 sd->host(), sd->port());
145 if (store->tls_authenticate) { /* authentication only? */
146 sd->free_tls(); /* yes, stop tls */
150 Dmsg1(116, ">stored: %s", sd->msg);
151 if (sd->recv() <= 0) {
152 stop_bsock_timer(tid);
153 Jmsg3(jcr, M_FATAL, 0, _("bdird<stored: \"%s:%s\" bad response to Hello command: ERR=%s\n"),
154 sd->who(), sd->host(), sd->bstrerror());
157 Dmsg1(110, "<stored: %s", sd->msg);
158 stop_bsock_timer(tid);
160 if (sscanf(sd->msg, SDOKnewHello, &jcr->SDVersion) != 1 &&
161 strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
162 Dmsg0(dbglvl, _("Storage daemon rejected Hello command\n"));
163 Jmsg2(jcr, M_FATAL, 0, _("Storage daemon at \"%s:%d\" rejected Hello command\n"),
164 sd->host(), sd->port());
167 if (jcr->SDVersion < 305) {
168 Jmsg2(jcr, M_FATAL, 0, _("Older Storage daemon at \"%s:%d\" incompatible with this Director.\n"),
169 sd->host(), sd->port());
176 * Authenticate File daemon connection
178 int authenticate_file_daemon(JCR *jcr)
180 BSOCK *fd = jcr->file_bsock;
181 CLIENT *client = jcr->client;
182 char dirname[MAX_NAME_LENGTH];
183 int tls_local_need = BNET_TLS_NONE;
184 int tls_remote_need = BNET_TLS_NONE;
185 int compatible = true;
186 bool auth_success = false;
189 * Send my name to the File daemon then do authentication
191 bstrncpy(dirname, director->name(), sizeof(dirname));
192 bash_spaces(dirname);
193 /* Timeout Hello after 1 min */
194 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
195 if (!fd->fsend(hello, "", dirname, DIR_VERSION)) {
196 stop_bsock_timer(tid);
197 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon at \"%s:%d\". ERR=%s\n"),
198 fd->host(), fd->port(), fd->bstrerror());
199 Dmsg3(50, _("Error sending Hello to File daemon at \"%s:%d\". ERR=%s\n"),
200 fd->host(), fd->port(), fd->bstrerror());
203 Dmsg1(dbglvl, "Sent: %s", fd->msg);
205 /* TLS Requirement */
206 if (client->tls_enable) {
207 if (client->tls_require) {
208 tls_local_need = BNET_TLS_REQUIRED;
210 tls_local_need = BNET_TLS_OK;
214 if (client->tls_authenticate) {
215 tls_local_need = BNET_TLS_REQUIRED;
218 auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
220 auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
222 Dmsg1(dbglvl, "cram_auth failed for %s\n", fd->who());
225 Dmsg1(dbglvl, "cram_get_auth failed for %s\n", fd->who());
228 stop_bsock_timer(tid);
229 Dmsg0(dbglvl, _("Director and File daemon passwords or names not the same.\n"));
230 Jmsg(jcr, M_FATAL, 0,
231 _("Unable to authenticate with File daemon at \"%s:%d\". Possible causes:\n"
232 "Passwords or names not the same or\n"
233 "Maximum Concurrent Jobs exceeded on the FD or\n"
234 "FD networking messed up (restart daemon).\n"
235 "For help, please see: " MANUAL_AUTH_URL "\n"),
236 fd->host(), fd->port());
240 /* Verify that the remote host is willing to meet our TLS 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 \"%s:%s\" did not advertise required TLS support.\n"),
244 fd->who(), fd->host());
248 /* Verify that we are willing to meet the remote host's requirements */
249 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
250 stop_bsock_timer(tid);
251 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD at \"%s:%d\" requires TLS.\n"),
252 fd->host(), fd->port());
256 /* Is TLS Enabled? */
257 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
258 /* Engage TLS! Full Speed Ahead! */
259 if (!bnet_tls_client(client->tls_ctx, fd, client->tls_allowed_cns)) {
260 stop_bsock_timer(tid);
261 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\".\n"),
262 fd->host(), fd->port());
265 if (client->tls_authenticate) { /* tls authentication only? */
266 fd->free_tls(); /* yes, shutdown tls */
270 Dmsg1(116, ">filed: %s", fd->msg);
271 if (fd->recv() <= 0) {
272 stop_bsock_timer(tid);
273 Dmsg1(dbglvl, _("Bad response from File daemon to Hello command: ERR=%s\n"),
275 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon at \"%s:%d\" to Hello command: ERR=%s\n"),
276 fd->host(), fd->port(), fd->bstrerror());
279 Dmsg1(110, "<filed: %s", fd->msg);
280 stop_bsock_timer(tid);
282 if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0 &&
283 sscanf(fd->msg, FDOKnewHello, &jcr->FDVersion) != 1) {
284 Dmsg0(dbglvl, _("File daemon rejected Hello command\n"));
285 Jmsg(jcr, M_FATAL, 0, _("File daemon at \"%s:%d\" rejected Hello command\n"),
286 fd->host(), fd->port());
292 /*********************************************************************
295 int authenticate_user_agent(UAContext *uac)
297 char name[MAX_NAME_LENGTH];
298 int tls_local_need = BNET_TLS_NONE;
299 int tls_remote_need = BNET_TLS_NONE;
300 bool tls_authenticate;
301 int compatible = true;
303 BSOCK *ua = uac->UA_sock;
304 bool auth_success = false;
305 TLS_CONTEXT *tls_ctx = NULL;
306 alist *verify_list = NULL;
309 if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
310 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(),
311 ua->host(), ua->port(), ua->msglen);
315 if (sscanf(ua->msg, "Hello %127s calling %d", name, &ua_version) != 2 &&
316 sscanf(ua->msg, "Hello %127s calling", name) != 1) {
317 ua->msg[100] = 0; /* terminate string */
318 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(),
319 ua->host(), ua->port(), ua->msg);
323 name[sizeof(name)-1] = 0; /* terminate name */
324 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
325 /* TLS Requirement */
326 if (director->tls_enable) {
327 if (director->tls_require) {
328 tls_local_need = BNET_TLS_REQUIRED;
330 tls_local_need = BNET_TLS_OK;
334 tls_authenticate = director->tls_authenticate;
336 if (tls_authenticate) {
337 tls_local_need = BNET_TLS_REQUIRED;
340 if (director->tls_verify_peer) {
341 verify_list = director->tls_allowed_cns;
344 auth_success = cram_md5_challenge(ua, director->password, tls_local_need,
346 cram_md5_respond(ua, director->password, &tls_remote_need, &compatible);
349 cons = (CONRES *)GetResWithName(R_CONSOLE, name);
351 /* TLS Requirement */
352 if (cons->tls_enable) {
353 if (cons->tls_require) {
354 tls_local_need = BNET_TLS_REQUIRED;
356 tls_local_need = BNET_TLS_OK;
360 tls_authenticate = cons->tls_authenticate;
362 if (tls_authenticate) {
363 tls_local_need = BNET_TLS_REQUIRED;
366 if (cons->tls_verify_peer) {
367 verify_list = cons->tls_allowed_cns;
370 auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
372 cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
375 uac->cons = cons; /* save console resource pointer */
378 auth_success = false;
384 /* Verify that the remote peer is willing to meet our TLS 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 did not advertise required TLS support.\n"));
388 auth_success = false;
392 /* Verify that we are willing to meet the peer's requirements */
393 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
394 Emsg0(M_FATAL, 0, _("Authorization problem:"
395 " Remote client requires TLS.\n"));
396 auth_success = false;
400 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
402 tls_ctx = cons->tls_ctx;
404 tls_ctx = director->tls_ctx;
407 /* Engage TLS! Full Speed Ahead! */
408 if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
409 Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
410 auth_success = false;
413 if (tls_authenticate) { /* authentication only? */
414 ua->free_tls(); /* stop tls */
419 /* Authorization Completed */
422 ua->fsend("%s", _(Dir_sorry));
423 Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
424 name, ua->who(), ua->host(), ua->port());
428 ua->fsend(_("1000 OK: %d %s %sVersion: %s (%s)\n"),
429 DIR_VERSION, my_name, "", VERSION, BDATE);