2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Authenticate Director who is attempting to connect.
31 * Kern Sibbald, October 2000
40 const int dbglvl = 50;
42 /* Version at end of Hello
43 * prior to 10Mar08 no version
45 * 2 13Mar09 - added the ability to restore from multiple storages
47 static char OK_hello[] = "2000 OK Hello 2\n";
48 static char Dir_sorry[] = "2999 Authentication failed.\n";
49 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
51 /*********************************************************************
54 static bool authenticate(int rcode, BSOCK *bs, JCR* jcr)
56 POOLMEM *dirname = get_pool_memory(PM_MESSAGE);
57 DIRRES *director = NULL;
58 int tls_local_need = BNET_TLS_NONE;
59 int tls_remote_need = BNET_TLS_NONE;
60 int compatible = true; /* Want md5 compatible DIR */
61 bool auth_success = false;
62 alist *verify_list = NULL;
65 if (rcode != R_DIRECTOR) {
66 Dmsg1(dbglvl, "I only authenticate directors, not %d\n", rcode);
67 Jmsg1(jcr, M_FATAL, 0, _("I only authenticate directors, not %d\n"), rcode);
70 if (bs->msglen < 25 || bs->msglen > 500) {
71 Dmsg2(dbglvl, "Bad Hello command from Director at %s. Len=%d.\n",
72 bs->who(), bs->msglen);
74 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
75 Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
79 dirname = check_pool_memory_size(dirname, bs->msglen);
81 if (sscanf(bs->msg, "Hello Director %s calling", dirname) != 1) {
83 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
85 Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n",
87 Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
91 unbash_spaces(dirname);
92 foreach_res(director, R_DIRECTOR) {
93 if (strcmp(director->hdr.name, dirname) == 0)
98 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
99 Jmsg2(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"),
105 /* TLS Requirement */
106 if (director->tls_enable) {
107 if (director->tls_require) {
108 tls_local_need = BNET_TLS_REQUIRED;
110 tls_local_need = BNET_TLS_OK;
114 if (director->tls_authenticate) {
115 tls_local_need = BNET_TLS_REQUIRED;
118 if (director->tls_verify_peer) {
119 verify_list = director->tls_allowed_cns;
123 tid = start_bsock_timer(bs, AUTH_TIMEOUT);
124 /* Challenge the director */
125 auth_success = cram_md5_challenge(bs, director->password, tls_local_need, compatible);
126 if (job_canceled(jcr)) {
127 auth_success = false;
128 goto auth_fatal; /* quick exit */
131 auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
134 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
135 Dmsg1(dbglvl, "cram_get_auth failed for %s\n", who);
139 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
140 Dmsg1(dbglvl, "cram_auth failed for %s\n", who);
143 Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
148 /* Verify that the remote host is willing to meet our TLS requirements */
149 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
150 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
151 " advertize required TLS support.\n"));
152 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
153 auth_success = false;
157 /* Verify that we are willing to meet the remote host's requirements */
158 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
159 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
160 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
161 auth_success = false;
165 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
166 /* Engage TLS! Full Speed Ahead! */
167 if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
168 Jmsg0(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
169 auth_success = false;
172 if (director->tls_authenticate) { /* authentication only? */
173 bs->free_tls(); /* shutodown tls */
179 stop_bsock_timer(tid);
182 free_pool_memory(dirname);
183 jcr->director = director;
184 /* Single thread all failures to avoid DOS */
194 * Inititiate the communications with the Director.
195 * He has made a connection to our server.
197 * Basic tasks done here:
198 * We read Director's initial message and authorize him.
201 int authenticate_director(JCR *jcr)
203 BSOCK *dir = jcr->dir_bsock;
205 if (!authenticate(R_DIRECTOR, dir, jcr)) {
206 bnet_fsend(dir, "%s", Dir_sorry);
207 Emsg0(M_FATAL, 0, _("Unable to authenticate Director\n"));
210 return bnet_fsend(dir, "%s", OK_hello);
214 * First prove our identity to the Storage daemon, then
215 * make him prove his identity.
217 int authenticate_storagedaemon(JCR *jcr)
219 BSOCK *sd = jcr->store_bsock;
220 int tls_local_need = BNET_TLS_NONE;
221 int tls_remote_need = BNET_TLS_NONE;
222 int compatible = true;
223 bool auth_success = false;
225 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
227 /* TLS Requirement */
228 if (have_tls && me->tls_enable) {
229 if (me->tls_require) {
230 tls_local_need = BNET_TLS_REQUIRED;
232 tls_local_need = BNET_TLS_OK;
236 if (me->tls_authenticate) {
237 tls_local_need = BNET_TLS_REQUIRED;
240 if (job_canceled(jcr)) {
241 auth_success = false; /* force quick exit */
245 /* Respond to SD challenge */
246 auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
247 if (job_canceled(jcr)) {
248 auth_success = false; /* force quick exit */
252 Dmsg1(dbglvl, "cram_respond failed for %s\n", sd->who());
254 /* Now challenge him */
255 auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
257 Dmsg1(dbglvl, "cram_challenge failed for %s\n", sd->who());
262 Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
263 "Please see http://www.bacula.org/en/rel-manual/Bacula_Freque_Asked_Questi.html#SECTION003760000000000000000 for help.\n"));
267 /* Verify that the remote host is willing to meet our TLS requirements */
268 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
269 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
270 " advertize required TLS support.\n"));
271 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
272 auth_success = false;
276 /* Verify that we are willing to meet the remote host's requirements */
277 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
278 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
279 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
280 auth_success = false;
284 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
285 /* Engage TLS! Full Speed Ahead! */
286 if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
287 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
288 auth_success = false;
291 if (me->tls_authenticate) { /* tls authentication only? */
292 sd->free_tls(); /* yes, shutdown tls */
297 /* Destroy session key */
298 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
299 stop_bsock_timer(tid);
300 /* Single thread all failures to avoid DOS */