]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/authenticate.c
Make cd accept wildcards
[bacula/bacula] / bacula / src / stored / authenticate.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
5
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
11    in the file LICENSE.
12
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.
17
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
21    02110-1301, USA.
22
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.
27 */
28 /*
29  * Authenticate caller
30  *
31  *   Kern Sibbald, October 2000
32  *
33  */
34
35
36 #include "bacula.h"
37 #include "stored.h"
38
39 const int dbglvl = 50;
40
41 static char Dir_sorry[] = "3999 No go\n";
42 static char OK_hello[]  = "3000 OK Hello\n";
43
44
45 /*********************************************************************
46  *
47  *
48  */
49 static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
50 {
51    POOLMEM *dirname;
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;
58
59    if (rcode != R_DIRECTOR) {
60       Dmsg1(dbglvl, "I only authenticate Directors, not %d\n", rcode);
61       Jmsg1(jcr, M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode);
62       return 0;
63    }
64    if (bs->msglen < 25 || bs->msglen > 500) {
65       Dmsg2(dbglvl, "Bad Hello command from Director at %s. Len=%d.\n",
66             bs->who(), bs->msglen);
67       Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
68             bs->who(), bs->msglen);
69       return 0;
70    }
71    dirname = get_pool_memory(PM_MESSAGE);
72    dirname = check_pool_memory_size(dirname, bs->msglen);
73
74    if (sscanf(bs->msg, "Hello Director %127s calling", dirname) != 1) {
75       bs->msg[100] = 0;
76       Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n",
77             bs->who(), bs->msg);
78       Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
79             bs->who(), bs->msg);
80       return 0;
81    }
82    director = NULL;
83    unbash_spaces(dirname);
84    foreach_res(director, rcode) {
85       if (strcmp(director->hdr.name, dirname) == 0) {
86          break;
87       }
88    }
89    if (!director) {
90       Dmsg2(dbglvl, "Connection from unknown Director %s at %s rejected.\n",
91             dirname, bs->who());
92       Jmsg2(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"
93        "Please see " MANUAL_AUTH_URL " for help.\n"),
94             dirname, bs->who());
95       free_pool_memory(dirname);
96       return 0;
97    }
98
99    /* TLS Requirement */
100    if (director->tls_enable) {
101       if (director->tls_require) {
102          tls_local_need = BNET_TLS_REQUIRED;
103       } else {
104          tls_local_need = BNET_TLS_OK;
105       }
106    }
107
108    if (director->tls_authenticate) {
109       tls_local_need = BNET_TLS_REQUIRED;
110    }
111
112    if (director->tls_verify_peer) {
113       verify_list = director->tls_allowed_cns;
114    }
115
116    /* Timeout Hello after 10 mins */
117    btimer_t *tid = start_bsock_timer(bs, AUTH_TIMEOUT);
118    auth_success = cram_md5_challenge(bs, director->password, tls_local_need, compatible);
119    if (auth_success) {
120       auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible);
121       if (!auth_success) {
122          Dmsg1(dbglvl, "cram_get_auth failed with %s\n", bs->who());
123       }
124    } else {
125       Dmsg1(dbglvl, "cram_auth failed with %s\n", bs->who());
126    }
127
128    if (!auth_success) {
129       Jmsg0(jcr, M_FATAL, 0, _("Incorrect password given by Director.\n"
130        "Please see " MANUAL_AUTH_URL " for help.\n"));
131       auth_success = false;
132       goto auth_fatal;
133    }
134
135    /* Verify that the remote host is willing to meet our TLS requirements */
136    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
137       Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not" 
138            " advertize required TLS support.\n"));
139       Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
140       auth_success = false;
141       goto auth_fatal;
142    }
143
144    /* Verify that we are willing to meet the remote host's requirements */
145    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
146       Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
147       Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
148       auth_success = false;
149       goto auth_fatal;
150    }
151
152    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
153       /* Engage TLS! Full Speed Ahead! */
154       if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
155          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with DIR at \"%s:%d\"\n"),
156             bs->host(), bs->port());
157          auth_success = false;
158          goto auth_fatal;
159       }
160       if (director->tls_authenticate) {     /* authenticate with tls only? */
161          bs->free_tls();                    /* yes, shut it down */
162       }
163    }
164
165 auth_fatal:
166    stop_bsock_timer(tid);
167    free_pool_memory(dirname);
168    jcr->director = director;
169    return auth_success;
170 }
171
172 /*
173  * Inititiate the message channel with the Director.
174  * He has made a connection to our server.
175  *
176  * Basic tasks done here:
177  *   Assume the Hello message is already in the input
178  *     buffer.  We then authenticate him.
179  *   Get device, media, and pool information from Director
180  *
181  *   This is the channel across which we will send error
182  *     messages and job status information.
183  */
184 int authenticate_director(JCR *jcr)
185 {
186    BSOCK *dir = jcr->dir_bsock;
187
188    if (!authenticate(R_DIRECTOR, dir, jcr)) {
189       dir->fsend("%s", Dir_sorry);
190       Dmsg1(dbglvl, "Unable to authenticate Director at %s.\n", dir->who());
191       Jmsg1(jcr, M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who());
192       bmicrosleep(5, 0);
193       return 0;
194    }
195    return dir->fsend("%s", OK_hello);
196 }
197
198 int authenticate_filed(JCR *jcr)
199 {
200    BSOCK *fd = jcr->file_bsock;
201    int tls_local_need = BNET_TLS_NONE;
202    int tls_remote_need = BNET_TLS_NONE;
203    int compatible = true;                 /* require md5 compatible FD */
204    bool auth_success = false;
205    alist *verify_list = NULL;
206
207    /* TLS Requirement */
208    if (me->tls_enable) {
209       if (me->tls_require) {
210          tls_local_need = BNET_TLS_REQUIRED;
211       } else {
212          tls_local_need = BNET_TLS_OK;
213       }
214    }
215
216    if (me->tls_authenticate) {
217       tls_local_need = BNET_TLS_REQUIRED;
218    }
219
220    if (me->tls_verify_peer) {
221       verify_list = me->tls_allowed_cns;
222    }
223
224    /* Timeout Hello after 5 mins */
225    btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
226    /* Challenge FD */
227    auth_success = cram_md5_challenge(fd, jcr->sd_auth_key, tls_local_need, compatible);
228    if (auth_success) {
229        /* Respond to his challenge */
230        auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible);
231        if (!auth_success) {
232           Dmsg1(dbglvl, "Respond cram-get-auth failed with %s\n", fd->who());
233        }
234    } else {
235       Dmsg1(dbglvl, "Challenge cram-auth failed with %s\n", fd->who());
236    }
237
238    if (!auth_success) {
239       Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
240        "Please see " MANUAL_AUTH_URL " for help.\n"),
241            fd->who());
242       auth_success = false;
243       goto auth_fatal;
244    }
245
246    /* Verify that the remote host is willing to meet our TLS requirements */
247    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
248       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not" 
249            " advertize required TLS support.\n"));
250       Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
251       auth_success = false;
252       goto auth_fatal;
253    }
254
255    /* Verify that we are willing to meet the remote host's requirements */
256    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
257       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
258       Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
259       auth_success = false;
260       goto auth_fatal;
261    }
262
263    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
264       /* Engage TLS! Full Speed Ahead! */
265       if (!bnet_tls_server(me->tls_ctx, fd, verify_list)) {
266          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\"\n"),
267             fd->host(), fd->port());
268          auth_success = false;
269          goto auth_fatal;
270       }
271       if (me->tls_authenticate) {          /* tls authenticate only? */
272          fd->free_tls();                   /* yes, shut it down */
273       }
274    }
275
276 auth_fatal:
277    stop_bsock_timer(tid);
278    if (!auth_success) {
279       Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
280        "Please see " MANUAL_AUTH_URL " for help.\n"),
281            fd->who());
282    }
283    jcr->authenticated = auth_success;
284    return auth_success;
285 }