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.
20 * Authenticate Director who is attempting to connect.
22 * Kern Sibbald, October 2000
29 extern CLIENT *me; /* my resource */
31 const int dbglvl = 50;
33 /* Version at end of Hello
34 * prior to 10Mar08 no version
36 * 2 13Mar09 - added the ability to restore from multiple storages
37 * 3 03Sep10 - added the restore object command for vss plugin 4.0
38 * 4 25Nov10 - added bandwidth command 5.1
39 * 5 24Nov11 - added new restore object command format (pluginname) 6.0
40 * 6 15Feb12 - added Component selection information list
41 * 7 19Feb12 - added Expected files to restore
42 * 8 22Mar13 - added restore options + version for SD
43 * 9 06Aug13 - added comm line compression
44 * 10 01Jan14 - added SD Calls Client and api version to status command
48 /* For compatibility with old Community SDs */
49 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
52 * Authenticated the Director
54 bool authenticate_director(JCR *jcr)
56 DIRRES *director = jcr->director;
57 int tls_local_need = BNET_TLS_NONE;
58 int tls_remote_need = BNET_TLS_NONE;
59 int compatible = true; /* Want md5 compatible DIR */
60 bool auth_success = false;
61 alist *verify_list = NULL;
63 BSOCK *dir = jcr->dir_bsock;
67 if (director->tls_enable) {
68 if (director->tls_require) {
69 tls_local_need = BNET_TLS_REQUIRED;
71 tls_local_need = BNET_TLS_OK;
75 if (director->tls_authenticate) {
76 tls_local_need = BNET_TLS_REQUIRED;
79 if (director->tls_verify_peer) {
80 verify_list = director->tls_allowed_cns;
84 tid = start_bsock_timer(dir, AUTH_TIMEOUT);
85 /* Challenge the director */
86 auth_success = cram_md5_challenge(dir, director->password, tls_local_need, compatible);
87 if (job_canceled(jcr)) {
89 goto auth_fatal; /* quick exit */
92 auth_success = cram_md5_respond(dir, director->password, &tls_remote_need, &compatible);
95 char *who = dir->get_peer(addr, sizeof(addr)) ? dir->who() : addr;
96 Dmsg1(dbglvl, "cram_get_auth respond failed for Director: %s\n", who);
100 char *who = dir->get_peer(addr, sizeof(addr)) ? dir->who() : addr;
101 Dmsg1(dbglvl, "cram_auth challenge failed for Director %s\n", who);
104 Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
109 /* Verify that the remote host is willing to meet our TLS requirements */
110 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
111 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
112 " advertize required TLS support.\n"));
113 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
114 auth_success = false;
118 /* Verify that we are willing to meet the remote host's requirements */
119 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
120 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
121 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
122 auth_success = false;
126 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
127 /* Engage TLS! Full Speed Ahead! */
128 if (!bnet_tls_server(director->tls_ctx, dir, verify_list)) {
129 Jmsg0(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
130 auth_success = false;
133 if (director->tls_authenticate) { /* authentication only? */
134 dir->free_tls(); /* shutodown tls */
141 stop_bsock_timer(tid);
145 return send_hello_ok(dir);
148 /* Single thread all failures to avoid DOS */
157 * First prove our identity to the Storage daemon, then
158 * make him prove his identity.
160 bool authenticate_storagedaemon(JCR *jcr)
162 BSOCK *sd = jcr->store_bsock;
163 int tls_local_need = BNET_TLS_NONE;
164 int tls_remote_need = BNET_TLS_NONE;
165 int compatible = true;
166 bool auth_success = false;
169 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
171 /* TLS Requirement */
172 if (have_tls && me->tls_enable) {
173 if (me->tls_require) {
174 tls_local_need = BNET_TLS_REQUIRED;
176 tls_local_need = BNET_TLS_OK;
180 if (me->tls_authenticate) {
181 tls_local_need = BNET_TLS_REQUIRED;
184 if (job_canceled(jcr)) {
185 auth_success = false; /* force quick exit */
189 /* Respond to SD challenge */
190 Dmsg0(050, "==== respond to SD challenge\n");
191 auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
192 if (job_canceled(jcr)) {
193 auth_success = false; /* force quick exit */
197 Dmsg1(dbglvl, "cram_respond failed for SD: %s\n", sd->who());
199 /* Now challenge him */
200 Dmsg0(050, "==== Challenge SD\n");
201 auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
203 Dmsg1(dbglvl, "cram_challenge failed for SD: %s\n", sd->who());
208 Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
209 "For help, please see " MANUAL_AUTH_URL "\n"));
212 Dmsg0(050, "Authorization with SD is OK\n");
215 /* Verify that the remote host is willing to meet our TLS requirements */
216 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
217 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
218 " advertize required TLS support.\n"));
219 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
220 auth_success = false;
224 /* Verify that we are willing to meet the remote host's requirements */
225 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
226 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
227 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
228 auth_success = false;
232 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
233 /* Engage TLS! Full Speed Ahead! */
234 if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
235 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
236 auth_success = false;
239 if (me->tls_authenticate) { /* tls authentication only? */
240 sd->free_tls(); /* yes, shutdown tls */
243 if (sd->recv() <= 0) {
244 auth_success = false;
247 sscanf(sd->msg, "3000 OK Hello %d", &sd_version);
248 if (sd_version >= 1 && me->comm_compression) {
251 sd->clear_compress();
252 Dmsg0(050, "*** No FD compression with SD\n");
255 /* At this point, we have successfully connected */
258 /* Destroy session key */
259 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
260 stop_bsock_timer(tid);
261 /* Single thread all failures to avoid DOS */