2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-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.
17 * Authenticate Director who is attempting to connect.
19 * Kern Sibbald, October 2000
26 extern CLIENT *me; /* my resource */
28 const int dbglvl = 50;
30 /* Version at end of Hello
31 * prior to 10Mar08 no version
33 * 2 13Mar09 - added the ability to restore from multiple storages
34 * 3 03Sep10 - added the restore object command for vss plugin 4.0
35 * 4 25Nov10 - added bandwidth command 5.1
36 * 5 01Jan14 - added SD Calls Client and api version to status command
40 static char hello_sd[] = "Hello Bacula SD: Start Job %s %d\n";
42 static char hello_dir[] = "2000 OK Hello %d\n";
43 static char Dir_sorry[] = "2999 Authentication failed.\n";
44 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
46 /*********************************************************************
49 static bool authenticate(int rcode, BSOCK *bs, JCR* jcr)
51 POOLMEM *dirname = get_pool_memory(PM_MESSAGE);
52 DIRRES *director = NULL;
53 int tls_local_need = BNET_TLS_NONE;
54 int tls_remote_need = BNET_TLS_NONE;
55 int compatible = true; /* Want md5 compatible DIR */
56 bool auth_success = false;
57 alist *verify_list = NULL;
61 if (rcode != R_DIRECTOR) {
62 Dmsg1(dbglvl, "I only authenticate directors, not %d\n", rcode);
63 Jmsg1(jcr, M_FATAL, 0, _("I only authenticate directors, not %d\n"), rcode);
67 dirname = check_pool_memory_size(dirname, bs->msglen);
69 if (sscanf(bs->msg, "Hello Director %s calling %d", dirname, &dir_version) != 2 &&
70 sscanf(bs->msg, "Hello Director %s calling", dirname) != 1) {
72 char *who = bs->get_peer(addr, sizeof(addr)) ? bs->who() : addr;
74 Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n",
76 Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
80 unbash_spaces(dirname);
81 foreach_res(director, R_DIRECTOR) {
82 if (strcmp(director->hdr.name, dirname) == 0)
87 char *who = bs->get_peer(addr, sizeof(addr)) ? bs->who() : addr;
88 Jmsg2(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"),
95 if (director->tls_enable) {
96 if (director->tls_require) {
97 tls_local_need = BNET_TLS_REQUIRED;
99 tls_local_need = BNET_TLS_OK;
103 if (director->tls_authenticate) {
104 tls_local_need = BNET_TLS_REQUIRED;
107 if (director->tls_verify_peer) {
108 verify_list = director->tls_allowed_cns;
112 tid = start_bsock_timer(bs, AUTH_TIMEOUT);
113 /* Challenge the director */
114 auth_success = cram_md5_challenge(bs, director->password, tls_local_need, compatible);
115 if (job_canceled(jcr)) {
116 auth_success = false;
117 goto auth_fatal; /* quick exit */
120 auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
123 char *who = bs->get_peer(addr, sizeof(addr)) ? bs->who() : addr;
124 Dmsg1(dbglvl, "cram_get_auth respond failed for Director: %s\n", who);
128 char *who = bs->get_peer(addr, sizeof(addr)) ? bs->who() : addr;
129 Dmsg1(dbglvl, "cram_auth challenge failed for Director %s\n", who);
132 Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
137 /* Verify that the remote host is willing to meet our TLS requirements */
138 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
139 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
140 " advertize required TLS support.\n"));
141 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
142 auth_success = false;
146 /* Verify that we are willing to meet the remote host's requirements */
147 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
148 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
149 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
150 auth_success = false;
154 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
155 /* Engage TLS! Full Speed Ahead! */
156 if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
157 Jmsg0(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
158 auth_success = false;
161 if (director->tls_authenticate) { /* authentication only? */
162 bs->free_tls(); /* shutodown tls */
168 stop_bsock_timer(tid);
171 free_pool_memory(dirname);
172 jcr->director = director;
173 /* Single thread all failures to avoid DOS */
183 * Inititiate the communications with the Director.
184 * He has made a connection to our server.
186 * Basic tasks done here:
187 * We read Director's initial message and authorize him.
190 int authenticate_director(JCR *jcr)
192 BSOCK *dir = jcr->dir_bsock;
194 if (!authenticate(R_DIRECTOR, dir, jcr)) {
195 dir->fsend("%s", Dir_sorry);
196 Emsg0(M_FATAL, 0, _("Unable to authenticate Director\n"));
199 return dir->fsend(hello_dir, FD_VERSION);
203 * First prove our identity to the Storage daemon, then
204 * make him prove his identity.
206 int authenticate_storagedaemon(JCR *jcr)
208 BSOCK *sd = jcr->store_bsock;
209 int tls_local_need = BNET_TLS_NONE;
210 int tls_remote_need = BNET_TLS_NONE;
211 int compatible = true;
212 bool auth_success = false;
215 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
217 /* TLS Requirement */
218 if (have_tls && me->tls_enable) {
219 if (me->tls_require) {
220 tls_local_need = BNET_TLS_REQUIRED;
222 tls_local_need = BNET_TLS_OK;
226 if (me->tls_authenticate) {
227 tls_local_need = BNET_TLS_REQUIRED;
230 if (job_canceled(jcr)) {
231 auth_success = false; /* force quick exit */
236 sd->fsend(hello_sd, jcr->Job, FD_VERSION);
237 Dmsg1(100, "Send to SD: %s\n", sd->msg);
239 /* Respond to SD challenge */
240 Dmsg0(050, "==== respond to SD challenge\n");
241 auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
242 if (job_canceled(jcr)) {
243 auth_success = false; /* force quick exit */
247 Dmsg1(dbglvl, "cram_respond failed for SD: %s\n", sd->who());
249 /* Now challenge him */
250 Dmsg0(050, "==== Challenge SD\n");
251 auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
253 Dmsg1(dbglvl, "cram_challenge failed for SD: %s\n", sd->who());
258 Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
259 "Please see " MANUAL_AUTH_URL " for help.\n"));
262 Dmsg0(050, "Authorization with SD is OK\n");
265 /* Verify that the remote host is willing to meet our TLS requirements */
266 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
267 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
268 " advertize required TLS support.\n"));
269 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
270 auth_success = false;
274 /* Verify that we are willing to meet the remote host's requirements */
275 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
276 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
277 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
278 auth_success = false;
282 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
283 /* Engage TLS! Full Speed Ahead! */
284 if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
285 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
286 auth_success = false;
289 if (me->tls_authenticate) { /* tls authentication only? */
290 sd->free_tls(); /* yes, shutdown tls */
293 if (sd->recv() <= 0) {
294 auth_success = false;
297 sscanf(sd->msg, "3000 OK Hello %d", &sd_version);
299 /* At this point, we have successfully connected */
302 /* Destroy session key */
303 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
304 stop_bsock_timer(tid);
305 /* Single thread all failures to avoid DOS */