2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2007 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 two of the GNU 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 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 John Walker.
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.
31 * Kern Sibbald, October 2000
41 static char Dir_sorry[] = "3999 No go\n";
42 static char OK_hello[] = "3000 OK Hello\n";
45 /*********************************************************************
49 static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
52 DIRRES *director = NULL;
53 int tls_local_need = BNET_TLS_NONE;
54 int tls_remote_need = BNET_TLS_NONE;
55 int compatible = true; /* require md5 compatible DIR */
56 bool auth_success = false;
57 alist *verify_list = NULL;
59 if (rcode != R_DIRECTOR) {
60 Dmsg1(50, "I only authenticate Directors, not %d\n", rcode);
61 Emsg1(M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode);
64 if (bs->msglen < 25 || bs->msglen > 500) {
65 Dmsg2(50, "Bad Hello command from Director at %s. Len=%d.\n",
66 bs->who(), bs->msglen);
67 Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
68 bs->who(), bs->msglen);
71 dirname = get_pool_memory(PM_MESSAGE);
72 dirname = check_pool_memory_size(dirname, bs->msglen);
74 if (sscanf(bs->msg, "Hello Director %127s calling", dirname) != 1) {
76 Dmsg2(50, "Bad Hello command from Director at %s: %s\n",
78 Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
83 unbash_spaces(dirname);
84 foreach_res(director, rcode) {
85 if (strcmp(director->hdr.name, dirname) == 0)
89 Dmsg2(50, "Connection from unknown Director %s at %s rejected.\n",
91 Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"
92 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
94 free_pool_memory(dirname);
99 if (director->tls_enable) {
100 if (director->tls_require) {
101 tls_local_need = BNET_TLS_REQUIRED;
103 tls_local_need = BNET_TLS_OK;
107 if (director->tls_verify_peer) {
108 verify_list = director->tls_allowed_cns;
111 /* Timeout Hello after 10 mins */
112 btimer_t *tid = start_bsock_timer(bs, AUTH_TIMEOUT);
113 auth_success = cram_md5_challenge(bs, director->password, tls_local_need, compatible);
115 auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
117 Dmsg1(50, "cram_get_auth failed with %s\n", bs->who());
120 Dmsg1(50, "cram_auth failed with %s\n", bs->who());
124 Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n"
125 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
126 auth_success = false;
130 /* Verify that the remote host is willing to meet our TLS requirements */
131 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
132 Emsg0(M_FATAL, 0, _("Authorization problem: Remote server did not"
133 " advertise required TLS support.\n"));
134 auth_success = false;
138 /* Verify that we are willing to meet the remote host's requirements */
139 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
140 Emsg0(M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
141 auth_success = false;
145 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
146 /* Engage TLS! Full Speed Ahead! */
147 if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
148 Emsg0(M_FATAL, 0, _("TLS negotiation failed.\n"));
149 auth_success = false;
155 stop_bsock_timer(tid);
156 free_pool_memory(dirname);
157 jcr->director = director;
162 * Inititiate the message channel with the Director.
163 * He has made a connection to our server.
165 * Basic tasks done here:
166 * Assume the Hello message is already in the input
167 * buffer. We then authenticate him.
168 * Get device, media, and pool information from Director
170 * This is the channel across which we will send error
171 * messages and job status information.
173 int authenticate_director(JCR *jcr)
175 BSOCK *dir = jcr->dir_bsock;
177 if (!authenticate(R_DIRECTOR, dir, jcr)) {
178 bnet_fsend(dir, "%s", Dir_sorry);
179 Dmsg1(50, "Unable to authenticate Director at %s.\n", dir->who());
180 Emsg1(M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who());
184 return bnet_fsend(dir, "%s", OK_hello);
187 int authenticate_filed(JCR *jcr)
189 BSOCK *fd = jcr->file_bsock;
190 int tls_local_need = BNET_TLS_NONE;
191 int tls_remote_need = BNET_TLS_NONE;
192 int compatible = true; /* require md5 compatible FD */
193 bool auth_success = false;
194 alist *verify_list = NULL;
196 /* TLS Requirement */
197 if (me->tls_enable) {
198 if (me->tls_require) {
199 tls_local_need = BNET_TLS_REQUIRED;
201 tls_local_need = BNET_TLS_OK;
205 if (me->tls_verify_peer) {
206 verify_list = me->tls_allowed_cns;
209 /* Timeout Hello after 5 mins */
210 btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
212 if (debug_level == 3) {
213 Pmsg1(000, "sd_auth_key=%s\n", jcr->sd_auth_key);
215 auth_success = cram_md5_challenge(fd, jcr->sd_auth_key, tls_local_need, compatible);
217 /* Respond to his challenge */
218 auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible);
220 Dmsg1(50, "cram-get-auth failed with %s\n", fd->who());
223 Dmsg1(50, "cram-auth failed with %s\n", fd->who());
227 Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
228 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
230 auth_success = false;
234 /* Verify that the remote host is willing to meet our TLS 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 did not"
237 " advertise required TLS support.\n"));
238 auth_success = false;
242 /* Verify that we are willing to meet the remote host's requirements */
243 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
244 Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
245 auth_success = false;
249 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
250 /* Engage TLS! Full Speed Ahead! */
251 if (!bnet_tls_server(me->tls_ctx, fd, verify_list)) {
252 Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
253 auth_success = false;
259 stop_bsock_timer(tid);
261 Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
262 "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
265 jcr->authenticated = auth_success;