]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/authenticate.c
fe2615d8df2d09bc630ec142d3e63918b6c8d882
[bacula/bacula] / bacula / src / filed / authenticate.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is 
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  * Authenticate Director who is attempting to connect.
21  *
22  *   Kern Sibbald, October 2000
23  *
24  */
25
26 #include "bacula.h"
27 #include "filed.h"
28
29 extern CLIENT *me;                 /* my resource */
30
31 const int dbglvl = 50;
32
33 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
34
35 /*
36  * Authenticated the Director
37  */
38 bool authenticate_director(JCR *jcr)
39 {
40    DIRRES *director = jcr->director;
41    int tls_local_need = BNET_TLS_NONE;
42    int tls_remote_need = BNET_TLS_NONE;
43    int compatible = true;                 /* Want md5 compatible DIR */
44    bool auth_success = false;
45    alist *verify_list = NULL;
46    btimer_t *tid = NULL;
47    BSOCK *dir = jcr->dir_bsock;
48
49    if (have_tls) {
50       /* TLS Requirement */
51       if (director->tls_enable) {
52          if (director->tls_require) {
53             tls_local_need = BNET_TLS_REQUIRED;
54          } else {
55             tls_local_need = BNET_TLS_OK;
56          }
57       }
58
59       if (director->tls_authenticate) {
60          tls_local_need = BNET_TLS_REQUIRED;
61       }
62
63       if (director->tls_verify_peer) {
64          verify_list = director->tls_allowed_cns;
65       }
66    }
67
68    tid = start_bsock_timer(dir, AUTH_TIMEOUT);
69    /* Challenge the director */
70    auth_success = cram_md5_challenge(dir, director->password, tls_local_need, compatible);
71    if (job_canceled(jcr)) {
72       auth_success = false;
73       goto auth_fatal;                   /* quick exit */
74    }
75    if (auth_success) {
76       auth_success = cram_md5_respond(dir, director->password, &tls_remote_need, &compatible);
77       if (!auth_success) {
78           char addr[64];
79           char *who = dir->get_peer(addr, sizeof(addr)) ? dir->who() : addr;
80           Dmsg1(dbglvl, "cram_get_auth respond failed for Director: %s\n", who);
81       }
82    } else {
83        char addr[64];
84        char *who = dir->get_peer(addr, sizeof(addr)) ? dir->who() : addr;
85        Dmsg1(dbglvl, "cram_auth challenge failed for Director %s\n", who);
86    }
87    if (!auth_success) {
88        Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
89              dir->who());
90        goto auth_fatal;
91    }
92
93    /* Verify that the remote host is willing to meet our TLS requirements */
94    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
95       Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
96            " advertize required TLS support.\n"));
97       Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
98       auth_success = false;
99       goto auth_fatal;
100    }
101
102    /* Verify that we are willing to meet the remote host's requirements */
103    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
104       Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
105       Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
106       auth_success = false;
107       goto auth_fatal;
108    }
109
110    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
111       /* Engage TLS! Full Speed Ahead! */
112       if (!bnet_tls_server(director->tls_ctx, dir, verify_list)) {
113          Jmsg0(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
114          auth_success = false;
115          goto auth_fatal;
116       }
117       if (director->tls_authenticate) {         /* authentication only? */
118          dir->free_tls();                        /* shutodown tls */
119       }
120    }
121    auth_success = true;
122
123 auth_fatal:
124    if (tid) {
125       stop_bsock_timer(tid);
126       tid = NULL;
127    }
128    if (auth_success) {
129       return send_hello_ok(dir);
130    }
131    send_sorry(dir);
132    /* Single thread all failures to avoid DOS */
133    P(mutex);
134    bmicrosleep(6, 0);
135    V(mutex);
136    return false;
137 }
138
139
140 /*
141  * First prove our identity to the Storage daemon, then
142  * make him prove his identity.
143  */
144 bool authenticate_storagedaemon(JCR *jcr)
145 {
146    BSOCK *sd = jcr->store_bsock;
147    int tls_local_need = BNET_TLS_NONE;
148    int tls_remote_need = BNET_TLS_NONE;
149    int compatible = true;
150    bool auth_success = false;
151    int sd_version = 0;
152
153    btimer_t *tid = start_bsock_timer(sd, AUTH_TIMEOUT);
154
155    /* TLS Requirement */
156    if (have_tls && me->tls_enable) {
157       if (me->tls_require) {
158          tls_local_need = BNET_TLS_REQUIRED;
159       } else {
160          tls_local_need = BNET_TLS_OK;
161       }
162    }
163
164    if (me->tls_authenticate) {
165       tls_local_need = BNET_TLS_REQUIRED;
166    }
167
168    if (job_canceled(jcr)) {
169       auth_success = false;     /* force quick exit */
170       goto auth_fatal;
171    }
172
173    /* Respond to SD challenge */
174    Dmsg0(050, "==== respond to SD challenge\n");
175    auth_success = cram_md5_respond(sd, jcr->sd_auth_key, &tls_remote_need, &compatible);
176    if (job_canceled(jcr)) {
177       auth_success = false;     /* force quick exit */
178       goto auth_fatal;
179    }
180    if (!auth_success) {
181       Dmsg1(dbglvl, "cram_respond failed for SD: %s\n", sd->who());
182    } else {
183       /* Now challenge him */
184       Dmsg0(050, "==== Challenge SD\n");
185       auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible);
186       if (!auth_success) {
187          Dmsg1(dbglvl, "cram_challenge failed for SD: %s\n", sd->who());
188       }
189    }
190
191    if (!auth_success) {
192       Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
193        "For help, please see " MANUAL_AUTH_URL "\n"));
194       goto auth_fatal;
195    } else {
196       Dmsg0(050, "Authorization with SD is OK\n");
197    }
198
199    /* Verify that the remote host is willing to meet our TLS requirements */
200    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
201       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
202            " advertize required TLS support.\n"));
203       Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
204       auth_success = false;
205       goto auth_fatal;
206    }
207
208    /* Verify that we are willing to meet the remote host's requirements */
209    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
210       Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n"));
211       Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need);
212       auth_success = false;
213       goto auth_fatal;
214    }
215
216    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
217       /* Engage TLS! Full Speed Ahead! */
218       if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
219          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
220          auth_success = false;
221          goto auth_fatal;
222       }
223       if (me->tls_authenticate) {           /* tls authentication only? */
224          sd->free_tls();                    /* yes, shutdown tls */
225       }
226    }
227    if (sd->recv() <= 0) {
228       auth_success = false;
229       goto auth_fatal;
230    }
231    sscanf(sd->msg, "3000 OK Hello %d", &sd_version);
232    /* At this point, we have successfully connected */
233
234 auth_fatal:
235    /* Destroy session key */
236    memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
237    stop_bsock_timer(tid);
238    /* Single thread all failures to avoid DOS */
239    if (!auth_success) {
240       P(mutex);
241       bmicrosleep(6, 0);
242       V(mutex);
243    }
244    return auth_success;
245 }