2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2010 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
38 const int dbglvl = 50;
40 /* Version at end of Hello
41 * prior to 10Mar08 no version
43 * 2 13Mar09 - added the ability to restore from multiple storages
44 * 3 03Sep10 - added the restore object command for vss plugin 4.0
45 * 4 25Nov10 - added bandwidth command 5.1
46 * 5 24Nov11 - added new restore object command format (pluginname) 6.0
48 static char OK_hello[] = "2000 OK Hello 5\n";
49 static char Dir_sorry[] = "2999 Authentication failed.\n";
50 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
52 /*********************************************************************
55 static bool authenticate(int rcode, BSOCK *bs, JCR* jcr)
57 POOLMEM *dirname = get_pool_memory(PM_MESSAGE);
58 DIRRES *director = NULL;
59 int tls_local_need = BNET_TLS_NONE;
60 int tls_remote_need = BNET_TLS_NONE;
61 int compatible = true; /* Want md5 compatible DIR */
62 bool auth_success = false;
63 alist *verify_list = NULL;
66 if (rcode != R_DIRECTOR) {
67 Dmsg1(dbglvl, "I only authenticate directors, not %d\n", rcode);
68 Jmsg1(jcr, M_FATAL, 0, _("I only authenticate directors, not %d\n"), rcode);
71 if (bs->msglen < 25 || bs->msglen > 500) {
72 Dmsg2(dbglvl, "Bad Hello command from Director at %s. Len=%d.\n",
73 bs->who(), bs->msglen);
75 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
76 Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
80 dirname = check_pool_memory_size(dirname, bs->msglen);
82 if (sscanf(bs->msg, "Hello Director %s calling", dirname) != 1) {
84 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
86 Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n",
88 Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
92 unbash_spaces(dirname);
93 foreach_res(director, R_DIRECTOR) {
94 if (strcmp(director->hdr.name, dirname) == 0)
99 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
100 Jmsg2(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"),
106 /* TLS Requirement */
107 if (director->tls_enable) {
108 if (director->tls_require) {
109 tls_local_need = BNET_TLS_REQUIRED;
111 tls_local_need = BNET_TLS_OK;
115 if (director->tls_authenticate) {
116 tls_local_need = BNET_TLS_REQUIRED;
119 if (director->tls_verify_peer) {
120 verify_list = director->tls_allowed_cns;
124 tid = start_bsock_timer(bs, AUTH_TIMEOUT);
125 /* Challenge the director */
126 auth_success = cram_md5_challenge(bs, director->password, tls_local_need, compatible);
127 if (job_canceled(jcr)) {
128 auth_success = false;
129 goto auth_fatal; /* quick exit */
132 auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
135 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
136 Dmsg1(dbglvl, "cram_get_auth failed for %s\n", who);
140 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr;
141 Dmsg1(dbglvl, "cram_auth failed for %s\n", who);
144 Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
149 /* Verify that the remote host is willing to meet our TLS requirements */
150 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
151 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
152 " advertize required TLS support.\n"));
153 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
154 auth_success = false;
158 /* Verify that we are willing to meet the remote host's requirements */
159 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
160 Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
161 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
162 auth_success = false;
166 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
167 /* Engage TLS! Full Speed Ahead! */
168 if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
169 Jmsg0(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
170 auth_success = false;
173 if (director->tls_authenticate) { /* authentication only? */
174 bs->free_tls(); /* shutodown tls */
180 stop_bsock_timer(tid);
183 free_pool_memory(dirname);
184 jcr->director = director;
185 /* Single thread all failures to avoid DOS */
195 * Inititiate the communications with the Director.
196 * He has made a connection to our server.
198 * Basic tasks done here:
199 * We read Director's initial message and authorize him.
202 int authenticate_director(JCR *jcr)
204 BSOCK *dir = jcr->dir_bsock;
206 if (!authenticate(R_DIRECTOR, dir, jcr)) {
207 bnet_fsend(dir, "%s", Dir_sorry);
208 Emsg0(M_FATAL, 0, _("Unable to authenticate Director\n"));
211 return bnet_fsend(dir, "%s", OK_hello);
215 * First prove our identity to the Storage daemon, then
216 * make him prove his identity.
218 int authenticate_storagedaemon(JCR *jcr)
220 BSOCK *sd = jcr->store_bsock;
221 int tls_local_need = BNET_TLS_NONE;
222 int tls_remote_need = BNET_TLS_NONE;
223 int compatible = true;
224 bool auth_success = false;
226 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
228 /* TLS Requirement */
229 if (have_tls && me->tls_enable) {
230 if (me->tls_require) {
231 tls_local_need = BNET_TLS_REQUIRED;
233 tls_local_need = BNET_TLS_OK;
237 if (me->tls_authenticate) {
238 tls_local_need = BNET_TLS_REQUIRED;
241 if (job_canceled(jcr)) {
242 auth_success = false; /* force quick exit */
246 /* Respond to SD challenge */
247 auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
248 if (job_canceled(jcr)) {
249 auth_success = false; /* force quick exit */
253 Dmsg1(dbglvl, "cram_respond failed for %s\n", sd->who());
255 /* Now challenge him */
256 auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
258 Dmsg1(dbglvl, "cram_challenge failed for %s\n", sd->who());
263 Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
264 "Please see " MANUAL_AUTH_URL " for help.\n"));
268 /* Verify that the remote host is willing to meet our TLS requirements */
269 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
270 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
271 " advertize required TLS support.\n"));
272 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
273 auth_success = false;
277 /* Verify that we are willing to meet the remote host's requirements */
278 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
279 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
280 Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
281 auth_success = false;
285 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
286 /* Engage TLS! Full Speed Ahead! */
287 if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
288 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
289 auth_success = false;
292 if (me->tls_authenticate) { /* tls authentication only? */
293 sd->free_tls(); /* yes, shutdown tls */
298 /* Destroy session key */
299 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
300 stop_bsock_timer(tid);
301 /* Single thread all failures to avoid DOS */