2 Bacula® - The Network Backup Solution
4 Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 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 Bacula® is a registered trademark of Kern Sibbald.
18 * Bacula Director -- authenticate.c -- handles authorization of
19 * Storage and File daemons.
21 * Written by: Kern Sibbald, May MMI
23 * This routine runs as a thread and must be thread reentrant.
30 static const int dbglvl = 50;
32 extern DIRRES *director;
34 /* Version at end of Hello
35 * prior to 06Aug13 no version
36 * 1 06Aug13 - added comm line compression
41 /* Command sent to SD */
42 static char hello[] = "Hello %sDirector %s calling %d\n";
44 /* Responses from Storage and File daemons */
45 static char OKhello[] = "3000 OK Hello";
46 static char SDOKnewHello[] = "3000 OK Hello %d";
47 static char FDOKhello[] = "2000 OK Hello";
48 static char FDOKnewHello[] = "2000 OK Hello %d";
50 /* Sent to User Agent */
51 static char Dir_sorry[] = "1999 You are not authorized.\n";
53 /* Forward referenced functions */
56 * Authenticate Storage daemon connection
58 bool authenticate_storage_daemon(JCR *jcr, STORE *store)
60 BSOCK *sd = jcr->store_bsock;
61 char dirname[MAX_NAME_LENGTH];
62 int tls_local_need = BNET_TLS_NONE;
63 int tls_remote_need = BNET_TLS_NONE;
64 int compatible = true;
65 bool auth_success = false;
68 * Send my name to the Storage daemon then do authentication
70 bstrncpy(dirname, director->hdr.name, sizeof(dirname));
72 /* Timeout Hello after 1 min */
73 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
74 /* Sent Hello SD: Bacula Director <dirname> calling <version> */
75 if (!sd->fsend(hello, "SD: Bacula ", dirname, DIR_VERSION)) {
76 stop_bsock_timer(tid);
77 Dmsg1(dbglvl, _("Error sending Hello to Storage daemon. ERR=%s\n"), sd->bstrerror());
78 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), sd->bstrerror());
83 if (store->tls_enable) {
84 if (store->tls_require) {
85 tls_local_need = BNET_TLS_REQUIRED;
87 tls_local_need = BNET_TLS_OK;
91 if (store->tls_authenticate) {
92 tls_local_need = BNET_TLS_REQUIRED;
95 auth_success = cram_md5_respond(sd, store->password, &tls_remote_need, &compatible);
97 auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible);
99 Dmsg1(dbglvl, "cram_challenge failed for %s\n", sd->who());
102 Dmsg1(dbglvl, "cram_respond failed for %s\n", sd->who());
106 stop_bsock_timer(tid);
107 Dmsg0(dbglvl, _("Director and Storage daemon passwords or names not the same.\n"));
108 Jmsg2(jcr, M_FATAL, 0,
109 _("Director unable to authenticate with Storage daemon at \"%s:%d\". Possible causes:\n"
110 "Passwords or names not the same or\n"
111 "Maximum Concurrent Jobs exceeded on the SD or\n"
112 "SD networking messed up (restart daemon).\n"
113 "Please see " MANUAL_AUTH_URL " for help.\n"),
114 sd->host(), sd->port());
118 /* Verify that the remote host is willing to meet our TLS requirements */
119 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
120 stop_bsock_timer(tid);
121 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n"));
125 /* Verify that we are willing to meet the remote host's requirements */
126 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
127 stop_bsock_timer(tid);
128 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
132 /* Is TLS Enabled? */
133 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
134 /* Engage TLS! Full Speed Ahead! */
135 if (!bnet_tls_client(store->tls_ctx, sd, NULL)) {
136 stop_bsock_timer(tid);
137 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD at \"%s:%d\"\n"),
138 sd->host(), sd->port());
141 if (store->tls_authenticate) { /* authentication only? */
142 sd->free_tls(); /* yes, stop tls */
146 Dmsg1(116, ">stored: %s", sd->msg);
147 if (sd->recv() <= 0) {
148 stop_bsock_timer(tid);
149 Jmsg3(jcr, M_FATAL, 0, _("bdird<stored: \"%s:%s\" bad response to Hello command: ERR=%s\n"),
150 sd->who(), sd->host(), sd->bstrerror());
153 Dmsg1(110, "<stored: %s", sd->msg);
154 stop_bsock_timer(tid);
156 if (sscanf(sd->msg, SDOKnewHello, &jcr->SDVersion) != 1 &&
157 strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
158 Dmsg0(dbglvl, _("Storage daemon rejected Hello command\n"));
159 Jmsg2(jcr, M_FATAL, 0, _("Storage daemon at \"%s:%d\" rejected Hello command\n"),
160 sd->host(), sd->port());
167 * Authenticate File daemon connection
169 int authenticate_file_daemon(JCR *jcr)
171 BSOCK *fd = jcr->file_bsock;
172 CLIENT *client = jcr->client;
173 char dirname[MAX_NAME_LENGTH];
174 int tls_local_need = BNET_TLS_NONE;
175 int tls_remote_need = BNET_TLS_NONE;
176 int compatible = true;
177 bool auth_success = false;
180 * Send my name to the File daemon then do authentication
182 bstrncpy(dirname, director->name(), sizeof(dirname));
183 bash_spaces(dirname);
184 /* Timeout Hello after 1 min */
185 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
186 if (!fd->fsend(hello, "", dirname, DIR_VERSION)) {
187 stop_bsock_timer(tid);
188 Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon at \"%s:%d\". ERR=%s\n"),
189 fd->host(), fd->port(), fd->bstrerror());
190 Dmsg3(50, _("Error sending Hello to File daemon at \"%s:%d\". ERR=%s\n"),
191 fd->host(), fd->port(), fd->bstrerror());
194 Dmsg1(dbglvl, "Sent: %s", fd->msg);
196 /* TLS Requirement */
197 if (client->tls_enable) {
198 if (client->tls_require) {
199 tls_local_need = BNET_TLS_REQUIRED;
201 tls_local_need = BNET_TLS_OK;
205 if (client->tls_authenticate) {
206 tls_local_need = BNET_TLS_REQUIRED;
209 auth_success = cram_md5_respond(fd, client->password, &tls_remote_need, &compatible);
211 auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible);
213 Dmsg1(dbglvl, "cram_auth failed for %s\n", fd->who());
216 Dmsg1(dbglvl, "cram_get_auth failed for %s\n", fd->who());
219 stop_bsock_timer(tid);
220 Dmsg0(dbglvl, _("Director and File daemon passwords or names not the same.\n"));
221 Jmsg(jcr, M_FATAL, 0,
222 _("Unable to authenticate with File daemon at \"%s:%d\". Possible causes:\n"
223 "Passwords or names not the same or\n"
224 "Maximum Concurrent Jobs exceeded on the FD or\n"
225 "FD networking messed up (restart daemon).\n"
226 "Please see " MANUAL_AUTH_URL " for help.\n"),
227 fd->host(), fd->port());
231 /* Verify that the remote host is willing to meet our TLS requirements */
232 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
233 stop_bsock_timer(tid);
234 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD \"%s:%s\" did not advertise required TLS support.\n"),
235 fd->who(), fd->host());
239 /* Verify that we are willing to meet the remote host's requirements */
240 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
241 stop_bsock_timer(tid);
242 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD at \"%s:%d\" requires TLS.\n"),
243 fd->host(), fd->port());
247 /* Is TLS Enabled? */
248 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
249 /* Engage TLS! Full Speed Ahead! */
250 if (!bnet_tls_client(client->tls_ctx, fd, client->tls_allowed_cns)) {
251 stop_bsock_timer(tid);
252 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\".\n"),
253 fd->host(), fd->port());
256 if (client->tls_authenticate) { /* tls authentication only? */
257 fd->free_tls(); /* yes, shutdown tls */
261 Dmsg1(116, ">filed: %s", fd->msg);
262 if (fd->recv() <= 0) {
263 stop_bsock_timer(tid);
264 Dmsg1(dbglvl, _("Bad response from File daemon to Hello command: ERR=%s\n"),
266 Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon at \"%s:%d\" to Hello command: ERR=%s\n"),
267 fd->host(), fd->port(), fd->bstrerror());
270 Dmsg1(110, "<filed: %s", fd->msg);
271 stop_bsock_timer(tid);
273 if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0 &&
274 sscanf(fd->msg, FDOKnewHello, &jcr->FDVersion) != 1) {
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;
291 bool tls_authenticate;
292 int compatible = true;
294 BSOCK *ua = uac->UA_sock;
295 bool auth_success = false;
296 TLS_CONTEXT *tls_ctx = NULL;
297 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 %d", name, &ua_version) != 2 &&
307 sscanf(ua->msg, "Hello %127s calling", name) != 1) {
308 ua->msg[100] = 0; /* terminate string */
309 Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(),
310 ua->host(), ua->port(), ua->msg);
314 name[sizeof(name)-1] = 0; /* terminate name */
315 if (strcmp(name, "*UserAgent*") == 0) { /* default console */
316 /* TLS Requirement */
317 if (director->tls_enable) {
318 if (director->tls_require) {
319 tls_local_need = BNET_TLS_REQUIRED;
321 tls_local_need = BNET_TLS_OK;
325 tls_authenticate = director->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;
353 if (tls_authenticate) {
354 tls_local_need = BNET_TLS_REQUIRED;
357 if (cons->tls_verify_peer) {
358 verify_list = cons->tls_allowed_cns;
361 auth_success = cram_md5_challenge(ua, cons->password, tls_local_need,
363 cram_md5_respond(ua, cons->password, &tls_remote_need, &compatible);
366 uac->cons = cons; /* save console resource pointer */
369 auth_success = false;
375 /* Verify that the remote peer is willing to meet our TLS requirements */
376 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
377 Emsg0(M_FATAL, 0, _("Authorization problem:"
378 " Remote client did not advertise required TLS support.\n"));
379 auth_success = false;
383 /* Verify that we are willing to meet the peer's requirements */
384 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
385 Emsg0(M_FATAL, 0, _("Authorization problem:"
386 " Remote client requires TLS.\n"));
387 auth_success = false;
391 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
393 tls_ctx = cons->tls_ctx;
395 tls_ctx = director->tls_ctx;
398 /* Engage TLS! Full Speed Ahead! */
399 if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
400 Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n"));
401 auth_success = false;
404 if (tls_authenticate) { /* authentication only? */
405 ua->free_tls(); /* stop tls */
410 /* Authorization Completed */
413 ua->fsend("%s", _(Dir_sorry));
414 Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
415 name, ua->who(), ua->host(), ua->port());
419 ua->fsend(_("1000 OK: %d %s Version: %s (%s)\n"),
420 DIR_VERSION, my_name, VERSION, BDATE);