]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/authenticate.c
Update copyright
[bacula/bacula] / bacula / src / stored / authenticate.c
1 /*
2  * Authenticate caller
3  *
4  *   Kern Sibbald, October 2000
5  *
6  *   Version $Id$
7  *
8  */
9 /*
10    Bacula® - The Network Backup Solution
11
12    Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
13
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.
20
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.
25
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
29    02110-1301, USA.
30
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.
35 */
36
37 #include "bacula.h"
38 #include "stored.h"
39
40 static char Dir_sorry[] = "3999 No go\n";
41 static char OK_hello[]  = "3000 OK Hello\n";
42
43
44 /*********************************************************************
45  *
46  *
47  */
48 static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
49 {
50    POOLMEM *dirname;
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;
57
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);
61       return 0;
62    }
63    if (bs->msglen < 25 || bs->msglen > 500) {
64       Dmsg2(50, "Bad Hello command from Director at %s. Len=%d.\n",
65             bs->who, bs->msglen);
66       Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
67             bs->who, bs->msglen);
68       return 0;
69    }
70    dirname = get_pool_memory(PM_MESSAGE);
71    dirname = check_pool_memory_size(dirname, bs->msglen);
72
73    if (sscanf(bs->msg, "Hello Director %127s calling", dirname) != 1) {
74       bs->msg[100] = 0;
75       Dmsg2(50, "Bad Hello command from Director at %s: %s\n",
76             bs->who, bs->msg);
77       Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
78             bs->who, bs->msg);
79       return 0;
80    }
81    director = NULL;
82    unbash_spaces(dirname);
83    foreach_res(director, rcode) {
84       if (strcmp(director->hdr.name, dirname) == 0)
85          break;
86    }
87    if (!director) {
88       Dmsg2(50, "Connection from unknown Director %s at %s rejected.\n",
89             dirname, bs->who);
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"),
92             dirname, bs->who);
93       free_pool_memory(dirname);
94       return 0;
95    }
96
97    /* TLS Requirement */
98    if (director->tls_enable) {
99       if (director->tls_require) {
100          tls_local_need = BNET_TLS_REQUIRED;
101       } else {
102          tls_local_need = BNET_TLS_OK;
103       }
104    }
105
106    if (director->tls_verify_peer) {
107       verify_list = director->tls_allowed_cns;
108    }
109
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);
113    if (auth_success) {
114       auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
115       if (!auth_success) {
116          Dmsg1(50, "cram_get_auth failed with %s\n", bs->who);
117       }
118    } else {
119       Dmsg1(50, "cram_auth failed with %s\n", bs->who);
120    }
121
122    if (!auth_success) {
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;
126       goto auth_fatal;
127    }
128
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;
134       goto auth_fatal;
135    }
136
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;
141       goto auth_fatal;
142    }
143
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;
149          goto auth_fatal;
150       }
151    }
152
153 auth_fatal:
154    stop_bsock_timer(tid);
155    free_pool_memory(dirname);
156    jcr->director = director;
157    return auth_success;
158 }
159
160 /*
161  * Inititiate the message channel with the Director.
162  * He has made a connection to our server.
163  *
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
168  *
169  *   This is the channel across which we will send error
170  *     messages and job status information.
171  */
172 int authenticate_director(JCR *jcr)
173 {
174    BSOCK *dir = jcr->dir_bsock;
175
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);
180       bmicrosleep(5, 0);
181       return 0;
182    }
183    return bnet_fsend(dir, "%s", OK_hello);
184 }
185
186 int authenticate_filed(JCR *jcr)
187 {
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;
194
195    /* TLS Requirement */
196    if (me->tls_enable) {
197       if (me->tls_require) {
198          tls_local_need = BNET_TLS_REQUIRED;
199       } else {
200          tls_local_need = BNET_TLS_OK;
201       }
202    }
203
204    if (me->tls_verify_peer) {
205       verify_list = me->tls_allowed_cns;
206    }
207
208    /* Timeout Hello after 5 mins */
209    btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
210    /* Challenge FD */
211    auth_success = cram_md5_challenge(fd, jcr->sd_auth_key, tls_local_need, compatible);
212    if (auth_success) {
213        /* Respond to his challenge */
214        auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible);
215        if (!auth_success) {
216           Dmsg1(50, "cram-get-auth failed with %s\n", fd->who);
217        }
218    } else {
219       Dmsg1(50, "cram-auth failed with %s\n", fd->who);
220    }
221
222    if (!auth_success) {
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"),
225            fd->who);
226       auth_success = false;
227       goto auth_fatal;
228    }
229
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;
235       goto auth_fatal;
236    }
237
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;
242       goto auth_fatal;
243    }
244
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;
250          goto auth_fatal;
251       }
252    }
253
254 auth_fatal:
255    stop_bsock_timer(tid);
256    if (!auth_success) {
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"),
259            fd->who);
260    }
261    jcr->authenticated = auth_success;
262    return auth_success;
263 }