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.
22 * Written by Kern Sibbald, October 2000
29 extern STORES *me; /* our Global resource */
31 const int dbglvl = 50;
33 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
35 /* Version at end of Hello
36 * prior to 06Aug13 no version
37 * 1 06Aug13 - added comm line compression
38 * 2 13Dec13 - added api version to status command
44 * Authenticate the Director
46 bool authenticate_director(JCR* jcr)
48 DIRRES *director = jcr->director;
49 int tls_local_need = BNET_TLS_NONE;
50 int tls_remote_need = BNET_TLS_NONE;
51 int compatible = true; /* require md5 compatible DIR */
52 bool auth_success = false;
53 alist *verify_list = NULL;
54 BSOCK *dir = jcr->dir_bsock;
57 if (director->tls_enable) {
58 if (director->tls_require) {
59 tls_local_need = BNET_TLS_REQUIRED;
61 tls_local_need = BNET_TLS_OK;
65 if (director->tls_authenticate) {
66 tls_local_need = BNET_TLS_REQUIRED;
69 if (director->tls_verify_peer) {
70 verify_list = director->tls_allowed_cns;
73 /* Timeout authentication after 10 mins */
74 btimer_t *tid = start_bsock_timer(dir, AUTH_TIMEOUT);
75 auth_success = cram_md5_challenge(dir, director->password, tls_local_need, compatible);
77 auth_success = cram_md5_respond(dir, director->password, &tls_remote_need, &compatible);
79 Dmsg1(dbglvl, "cram_get_auth respond failed with Director %s\n", dir->who());
82 Dmsg1(dbglvl, "cram_auth challenge failed with Director %s\n", dir->who());
86 Jmsg0(jcr, M_FATAL, 0, _("Incorrect password given by Director.\n"
87 "For help, please see: " MANUAL_AUTH_URL "\n"));
92 /* Verify that the remote host is willing to meet our TLS requirements */
93 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
94 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
95 " advertize required TLS support.\n"));
96 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
101 /* Verify that we are willing to meet the remote host's requirements */
102 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
103 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
104 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
105 auth_success = false;
109 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
110 /* Engage TLS! Full Speed Ahead! */
111 if (!bnet_tls_server(director->tls_ctx, dir, verify_list)) {
112 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with DIR at \"%s:%d\"\n"),
113 dir->host(), dir->port());
114 auth_success = false;
117 if (director->tls_authenticate) { /* authenticate with tls only? */
118 dir->free_tls(); /* yes, shut it down */
123 stop_bsock_timer(tid);
124 jcr->director = director;
126 return send_hello_ok(dir);
129 Dmsg1(dbglvl, "Unable to authenticate Director at %s.\n", dir->who());
130 Jmsg1(jcr, M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who());
136 int authenticate_filed(JCR *jcr, BSOCK *fd, int FDVersion)
138 int tls_local_need = BNET_TLS_NONE;
139 int tls_remote_need = BNET_TLS_NONE;
140 int compatible = true; /* require md5 compatible FD */
141 bool auth_success = false;
142 alist *verify_list = NULL;
144 /* TLS Requirement */
145 if (me->tls_enable) {
146 if (me->tls_require) {
147 tls_local_need = BNET_TLS_REQUIRED;
149 tls_local_need = BNET_TLS_OK;
153 if (me->tls_authenticate) {
154 tls_local_need = BNET_TLS_REQUIRED;
157 if (me->tls_verify_peer) {
158 verify_list = me->tls_allowed_cns;
161 /* Timeout authentication after 5 mins */
162 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
164 Dmsg0(050, "Challenge FD\n");
165 auth_success = cram_md5_challenge(fd, jcr->sd_auth_key, tls_local_need, compatible);
167 /* Respond to his challenge */
168 Dmsg0(050, "Respond to FD challenge\n");
169 auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible);
171 Dmsg1(dbglvl, "Respond cram-get-auth respond failed with FD: %s\n", fd->who());
174 Dmsg1(dbglvl, "Challenge cram-auth failed with FD: %s\n", fd->who());
178 Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
179 "For help, please see: " MANUAL_AUTH_URL "\n"),
181 auth_success = false;
185 /* Verify that the remote host is willing to meet our TLS requirements */
186 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
187 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
188 " advertize required TLS support.\n"));
189 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
190 auth_success = false;
194 /* Verify that we are willing to meet the remote host's requirements */
195 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
196 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
197 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
198 auth_success = false;
202 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
203 /* Engage TLS! Full Speed Ahead! */
204 if (!bnet_tls_server(me->tls_ctx, fd, verify_list)) {
205 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\"\n"),
206 fd->host(), fd->port());
207 auth_success = false;
210 if (me->tls_authenticate) { /* tls authenticate only? */
211 fd->free_tls(); /* yes, shut it down */
216 stop_bsock_timer(tid);
218 Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
219 "For help, please see: " MANUAL_AUTH_URL "\n"),
223 /* Version 5 of the protocol is a bit special, it is used by both 6.0.0
224 * Enterprise version and 7.0.x Community version, but do not support the
225 * same level of features. As nobody is using the 6.0.0 release, we can
226 * be pretty sure that the FD in version 5 is a community FD.
228 if (auth_success && (FDVersion >= 9 || FDVersion == 5)) {
235 * First prove our identity to the Storage daemon, then
236 * make him prove his identity.
238 bool authenticate_storagedaemon(JCR *jcr)
240 BSOCK *sd = jcr->store_bsock;
241 int tls_local_need = BNET_TLS_NONE;
242 int tls_remote_need = BNET_TLS_NONE;
243 int compatible = true;
244 bool auth_success = false;
247 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
249 /* TLS Requirement */
250 if (have_tls && me->tls_enable) {
251 if (me->tls_require) {
252 tls_local_need = BNET_TLS_REQUIRED;
254 tls_local_need = BNET_TLS_OK;
258 if (me->tls_authenticate) {
259 tls_local_need = BNET_TLS_REQUIRED;
262 if (job_canceled(jcr)) {
263 auth_success = false; /* force quick exit */
267 /* Respond to SD challenge */
268 Dmsg0(050, "Respond to SD challenge\n");
269 auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
270 if (job_canceled(jcr)) {
271 auth_success = false; /* force quick exit */
275 Dmsg1(dbglvl, "cram_respond failed for SD: %s\n", sd->who());
277 /* Now challenge him */
278 Dmsg0(050, "Challenge SD\n");
279 auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
281 Dmsg1(dbglvl, "cram_challenge failed for SD: %s\n", sd->who());
286 Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
287 "Please see " MANUAL_AUTH_URL " for help.\n"));
290 Dmsg0(050, "Authorization with SD is OK\n");
293 /* Verify that the remote host is willing to meet our TLS requirements */
294 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
295 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
296 " advertize required TLS support.\n"));
297 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
298 auth_success = false;
302 /* Verify that we are willing to meet the remote host's requirements */
303 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
304 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
305 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
306 auth_success = false;
310 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
311 /* Engage TLS! Full Speed Ahead! */
312 if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
313 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
314 auth_success = false;
317 if (me->tls_authenticate) { /* tls authentication only? */
318 sd->free_tls(); /* yes, shutdown tls */
321 if (sd->recv() <= 0) {
322 auth_success = false;
325 sscanf(sd->msg, "3000 OK Hello %d", &sd_version);
326 if (sd_version >= 1 && me->comm_compression) {
329 sd->clear_compress();
330 Dmsg0(050, "*** No FD compression with SD\n");
333 /* At this point, we have successfully connected */
336 /* Destroy session key */
337 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
338 stop_bsock_timer(tid);
339 /* Single thread all failures to avoid DOS */