4 * Kern Sibbald, October 2000
10 Bacula® - The Network Backup Solution
12 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
14 The main author of Bacula is Kern Sibbald, with contributions from
15 many others, a complete list can be found in the file AUTHORS.
16 This program is Free Software; you can redistribute it and/or
17 modify it under the terms of version two of the GNU General Public
18 License as published by the Free Software Foundation plus additions
19 that are listed in the file LICENSE.
21 This program is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 Bacula® is a registered trademark of John Walker.
32 The licensor of Bacula is the Free Software Foundation Europe
33 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34 Switzerland, email:ftf@fsfeurope.org.
40 static char Dir_sorry[] = "3999 No go\n";
41 static char OK_hello[] = "3000 OK Hello\n";
44 /*********************************************************************
48 static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
51 DIRRES *director = NULL;
52 int tls_local_need = BNET_TLS_NONE;
53 int tls_remote_need = BNET_TLS_NONE;
54 int compatible = true; /* require md5 compatible DIR */
55 bool auth_success = false;
56 alist *verify_list = NULL;
58 if (rcode != R_DIRECTOR) {
59 Dmsg1(50, "I only authenticate Directors, not %d\n", rcode);
60 Emsg1(M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode);
63 if (bs->msglen < 25 || bs->msglen > 500) {
64 Dmsg2(50, "Bad Hello command from Director at %s. Len=%d.\n",
66 Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
70 dirname = get_pool_memory(PM_MESSAGE);
71 dirname = check_pool_memory_size(dirname, bs->msglen);
73 if (sscanf(bs->msg, "Hello Director %127s calling", dirname) != 1) {
75 Dmsg2(50, "Bad Hello command from Director at %s: %s\n",
77 Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
82 unbash_spaces(dirname);
83 foreach_res(director, rcode) {
84 if (strcmp(director->hdr.name, dirname) == 0)
88 Dmsg2(50, "Connection from unknown Director %s at %s rejected.\n",
90 Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"
91 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
93 free_pool_memory(dirname);
98 if (director->tls_enable) {
99 if (director->tls_require) {
100 tls_local_need = BNET_TLS_REQUIRED;
102 tls_local_need = BNET_TLS_OK;
106 if (director->tls_verify_peer) {
107 verify_list = director->tls_allowed_cns;
110 /* Timeout Hello after 10 mins */
111 btimer_t *tid = start_bsock_timer(bs, AUTH_TIMEOUT);
112 auth_success = cram_md5_challenge(bs, director->password, tls_local_need, compatible);
114 auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
116 Dmsg1(50, "cram_get_auth failed with %s\n", bs->who);
119 Dmsg1(50, "cram_auth failed with %s\n", bs->who);
123 Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n"
124 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
125 auth_success = false;
129 /* Verify that the remote host is willing to meet our TLS requirements */
130 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
131 Emsg0(M_FATAL, 0, _("Authorization problem: Remote server did not"
132 " advertise required TLS support.\n"));
133 auth_success = false;
137 /* Verify that we are willing to meet the remote host's requirements */
138 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
139 Emsg0(M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
140 auth_success = false;
144 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
145 /* Engage TLS! Full Speed Ahead! */
146 if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
147 Emsg0(M_FATAL, 0, _("TLS negotiation failed.\n"));
148 auth_success = false;
154 stop_bsock_timer(tid);
155 free_pool_memory(dirname);
156 jcr->director = director;
161 * Inititiate the message channel with the Director.
162 * He has made a connection to our server.
164 * Basic tasks done here:
165 * Assume the Hello message is already in the input
166 * buffer. We then authenticate him.
167 * Get device, media, and pool information from Director
169 * This is the channel across which we will send error
170 * messages and job status information.
172 int authenticate_director(JCR *jcr)
174 BSOCK *dir = jcr->dir_bsock;
176 if (!authenticate(R_DIRECTOR, dir, jcr)) {
177 bnet_fsend(dir, "%s", Dir_sorry);
178 Dmsg1(50, "Unable to authenticate Director at %s.\n", dir->who);
179 Emsg1(M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who);
183 return bnet_fsend(dir, "%s", OK_hello);
186 int authenticate_filed(JCR *jcr)
188 BSOCK *fd = jcr->file_bsock;
189 int tls_local_need = BNET_TLS_NONE;
190 int tls_remote_need = BNET_TLS_NONE;
191 int compatible = true; /* require md5 compatible FD */
192 bool auth_success = false;
193 alist *verify_list = NULL;
195 /* TLS Requirement */
196 if (me->tls_enable) {
197 if (me->tls_require) {
198 tls_local_need = BNET_TLS_REQUIRED;
200 tls_local_need = BNET_TLS_OK;
204 if (me->tls_verify_peer) {
205 verify_list = me->tls_allowed_cns;
208 /* Timeout Hello after 5 mins */
209 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
211 auth_success = cram_md5_challenge(fd, jcr->sd_auth_key, tls_local_need, compatible);
213 /* Respond to his challenge */
214 auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible);
216 Dmsg1(50, "cram-get-auth failed with %s\n", fd->who);
219 Dmsg1(50, "cram-auth failed with %s\n", fd->who);
223 Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
224 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
226 auth_success = false;
230 /* Verify that the remote host is willing to meet our TLS requirements */
231 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
232 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
233 " advertise required TLS support.\n"));
234 auth_success = false;
238 /* Verify that we are willing to meet the remote host's requirements */
239 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
240 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
241 auth_success = false;
245 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
246 /* Engage TLS! Full Speed Ahead! */
247 if (!bnet_tls_server(me->tls_ctx, fd, verify_list)) {
248 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
249 auth_success = false;
255 stop_bsock_timer(tid);
257 Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
258 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
261 jcr->authenticated = auth_success;