2 * Authenticate Director who is attempting to connect.
4 * Kern Sibbald, October 2000
10 Copyright (C) 2000-2006 Kern Sibbald
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 version 2 as amended with additional clauses defined in the
15 file LICENSE in the main source directory.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 the file LICENSE for additional details.
27 static char OK_hello[] = "2000 OK Hello\n";
28 static char Dir_sorry[] = "2999 No go\n";
29 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
31 /*********************************************************************
34 static bool authenticate(int rcode, BSOCK *bs, JCR* jcr)
36 POOLMEM *dirname = get_pool_memory(PM_MESSAGE);
37 DIRRES *director = NULL;
38 int tls_local_need = BNET_TLS_NONE;
39 int tls_remote_need = BNET_TLS_NONE;
40 int compatible = true; /* Want md5 compatible DIR */
41 bool auth_success = false;
42 alist *verify_list = NULL;
45 if (rcode != R_DIRECTOR) {
46 Dmsg1(50, "I only authenticate directors, not %d\n", rcode);
47 Emsg1(M_FATAL, 0, _("I only authenticate directors, not %d\n"), rcode);
50 if (bs->msglen < 25 || bs->msglen > 500) {
51 Dmsg2(50, "Bad Hello command from Director at %s. Len=%d.\n",
54 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
55 Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
59 dirname = check_pool_memory_size(dirname, bs->msglen);
61 if (sscanf(bs->msg, "Hello Director %s calling", dirname) != 1) {
63 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
65 Dmsg2(50, "Bad Hello command from Director at %s: %s\n",
67 Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
71 unbash_spaces(dirname);
72 foreach_res(director, R_DIRECTOR) {
73 if (strcmp(director->hdr.name, dirname) == 0)
78 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
79 Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"),
86 if (director->tls_enable) {
87 if (director->tls_require) {
88 tls_local_need = BNET_TLS_REQUIRED;
90 tls_local_need = BNET_TLS_OK;
94 if (director->tls_verify_peer) {
95 verify_list = director->tls_allowed_cns;
99 tid = start_bsock_timer(bs, AUTH_TIMEOUT);
100 /* Challenge the director */
101 auth_success = cram_md5_challenge(bs, director->password, tls_local_need, compatible);
103 auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
106 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
107 Dmsg1(50, "cram_get_auth failed for %s\n", who);
111 char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
112 Dmsg1(50, "cram_auth failed for %s\n", who);
115 Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
120 /* Verify that the remote host is willing to meet our TLS requirements */
121 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
122 Emsg0(M_FATAL, 0, _("Authorization problem: Remote server did not"
123 " advertize required TLS support.\n"));
124 auth_success = false;
128 /* Verify that we are willing to meet the remote host's requirements */
129 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
130 Emsg0(M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
131 auth_success = false;
136 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
137 /* Engage TLS! Full Speed Ahead! */
138 if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
139 Emsg0(M_FATAL, 0, _("TLS negotiation failed.\n"));
140 auth_success = false;
148 stop_bsock_timer(tid);
151 free_pool_memory(dirname);
152 jcr->director = director;
153 /* Single thread all failures to avoid DOS */
163 * Inititiate the communications with the Director.
164 * He has made a connection to our server.
166 * Basic tasks done here:
167 * We read Director's initial message and authorize him.
170 int authenticate_director(JCR *jcr)
172 BSOCK *dir = jcr->dir_bsock;
174 if (!authenticate(R_DIRECTOR, dir, jcr)) {
175 bnet_fsend(dir, "%s", Dir_sorry);
176 Emsg0(M_FATAL, 0, _("Unable to authenticate Director\n"));
179 return bnet_fsend(dir, "%s", OK_hello);
183 * First prove our identity to the Storage daemon, then
184 * make him prove his identity.
186 int authenticate_storagedaemon(JCR *jcr)
188 BSOCK *sd = jcr->store_bsock;
189 int tls_local_need = BNET_TLS_NONE;
190 int tls_remote_need = BNET_TLS_NONE;
191 int compatible = true;
192 bool auth_success = false;
194 btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
196 /* TLS Requirement */
197 if (have_tls && me->tls_enable) {
198 if (me->tls_require) {
199 tls_local_need = BNET_TLS_REQUIRED;
201 tls_local_need = BNET_TLS_OK;
205 /* Respond to SD challenge */
206 auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
208 Dmsg1(50, "cram_respond failed for %s\n", sd->who);
210 /* Now challenge him */
211 auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
213 Dmsg1(50, "cram_challenge failed for %s\n", sd->who);
217 /* Destroy session key */
218 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
221 Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
222 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
226 /* Verify that the remote host is willing to meet our TLS requirements */
227 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
228 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
229 " advertise required TLS support.\n"));
230 auth_success = false;
234 /* Verify that we are willing to meet the remote host's requirements */
235 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
236 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
237 auth_success = false;
241 if (have_tls && tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
242 /* Engage TLS! Full Speed Ahead! */
243 if (!bnet_tls_client(me->tls_ctx, sd)) {
244 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
245 auth_success = false;
251 stop_bsock_timer(tid);
252 /* Single thread all failures to avoid DOS */