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