1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 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 caller
21 *
22 * Written by Kern Sibbald, October 2000
23 *
24 */
25
26
27 #include "bacula.h"
28 #include "stored.h"
29
30 extern STORES *me; /* our Global resource */
31
32 const int dbglvl = 50;
33
34 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
35
SDAuthenticateDIR(JCR * jcr)36 SDAuthenticateDIR::SDAuthenticateDIR(JCR *jcr):
37 AuthenticateBase(jcr, jcr->dir_bsock, dtSrv, dcSD, dcDIR)
38 {
39 }
40
41 /*
42 * Authenticate the Director
43 */
authenticate_director()44 bool SDAuthenticateDIR::authenticate_director()
45 {
46 BSOCK *dir = jcr->dir_bsock;
47 DIRRES *director = jcr->director;
48
49 DecodeRemoteTLSPSKNeed(bsock->tlspsk_remote);
50
51 /* TLS Requirement */
52 CalcLocalTLSNeedFromRes(director->tls_enable, director->tls_require,
53 director->tls_authenticate, director->tls_verify_peer,
54 director->tls_allowed_cns, director->tls_ctx,
55 director->tls_psk_enable, director->psk_ctx, director->password);
56
57 /* Timeout authentication after 10 mins */
58 StartAuthTimeout();
59
60 /* Challenge the director */
61 if (!ServerCramMD5Authenticate(password)) {
62 goto auth_fatal;
63 }
64
65 this->auth_success = HandleTLS();
66
67 auth_fatal:
68 if (auth_success) {
69 return send_hello_ok(dir);
70 }
71 send_sorry(dir);
72 bmicrosleep(5, 0);
73 return false;
74 }
75
76 class SDAuthenticateFD: public AuthenticateBase
77 {
78 public:
SDAuthenticateFD(JCR * jcr,BSOCK * bsock)79 SDAuthenticateFD(JCR *jcr, BSOCK *bsock):
80 AuthenticateBase(jcr, bsock, dtSrv, dcSD, dcFD)
81 {
82 }
~SDAuthenticateFD()83 virtual ~SDAuthenticateFD() {};
84 int authenticate_filed(int FDVersion);
85 };
86
authenticate_filed(JCR * jcr,BSOCK * fd,int FDVersion)87 int authenticate_filed(JCR *jcr, BSOCK *fd, int FDVersion)
88 {
89 return SDAuthenticateFD(jcr, fd).authenticate_filed(FDVersion);
90 }
91
authenticate_filed(int FDVersion)92 int SDAuthenticateFD::authenticate_filed(int FDVersion)
93 {
94 BSOCK *fd = bsock;
95
96 DecodeRemoteTLSPSKNeed(bsock->tlspsk_remote);
97 /* TLS Requirement */
98 CalcLocalTLSNeedFromRes(me->tls_enable, me->tls_require, me->tls_authenticate,
99 me->tls_verify_peer, me->tls_allowed_cns, me->tls_ctx,
100 me->tls_psk_enable, me->psk_ctx, jcr->sd_auth_key);
101
102 /* Timeout authentication after 10 mins */
103 StartAuthTimeout();
104
105 /* Challenge the FD */
106 if (!ServerCramMD5Authenticate(jcr->sd_auth_key)) {
107 goto auth_fatal;
108 }
109
110 this->auth_success = HandleTLS();
111
112 auth_fatal:
113 /* Version 5 of the protocol is a bit special, it is used by both 6.0.0
114 * Enterprise version and 7.0.x Community version, but do not support the
115 * same level of features. As nobody is using the 6.0.0 release, we can
116 * be pretty sure that the FD in version 5 is a community FD.
117 */
118 if (auth_success && (FDVersion >= 9 || FDVersion == 5)) {
119 send_hello_ok(fd);
120 }
121 return auth_success;
122 }
123
124 class SDAuthenticateSD: public AuthenticateBase
125 {
126 public:
SDAuthenticateSD(JCR * jcr)127 SDAuthenticateSD(JCR *jcr):
128 AuthenticateBase(jcr, jcr->store_bsock, dtCli, dcSD, dcSD) {
129 /* TLS Requirement */
130 CalcLocalTLSNeedFromRes(me->tls_enable, me->tls_require, me->tls_authenticate,
131 me->tls_verify_peer, me->tls_allowed_cns, me->tls_ctx,
132 me->tls_psk_enable, me->psk_ctx, jcr->sd_auth_key);
133 }
~SDAuthenticateSD()134 virtual ~SDAuthenticateSD() {};
135 bool authenticate_storagedaemon();
136 };
137
138
send_hello_and_authenticate_sd(JCR * jcr,char * Job)139 bool send_hello_and_authenticate_sd(JCR *jcr, char *Job)
140 {
141 SDAuthenticateSD auth(jcr);
142 /* TODO disable PSK/TLS when the SD talk to itself */
143 if (!send_hello_sd(jcr, Job, auth.GetTLSPSKLocalNeed())) {
144 return false;
145 }
146 return auth.authenticate_storagedaemon();
147 }
148
149 /*
150 * First prove our identity to the Storage daemon, then
151 * make him prove his identity.
152 */
authenticate_storagedaemon()153 bool SDAuthenticateSD::authenticate_storagedaemon()
154 {
155 BSOCK *sd = jcr->store_bsock;
156 int sd_version = 0;
157
158 /* Timeout authentication after 10 mins */
159 StartAuthTimeout();
160
161 /* Challenge the FD */
162 if (!ClientCramMD5Authenticate(jcr->sd_auth_key)) {
163 goto auth_fatal;
164 }
165
166 this->auth_success = HandleTLS();
167
168 if (!auth_success) {
169 goto auth_fatal;
170 }
171
172 if (sd->recv() <= 0) {
173 auth_success = false;
174 goto auth_fatal;
175 }
176 sscanf(sd->msg, "3000 OK Hello %d", &sd_version);
177 if (sd_version >= 1 && me->comm_compression) {
178 sd->set_compress();
179 } else {
180 sd->clear_compress();
181 Dmsg0(050, "*** No FD compression with SD\n");
182 }
183
184 /* At this point, we have successfully connected */
185
186 auth_fatal:
187 /* Destroy session key */
188 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
189 /* Single thread all failures to avoid DOS */
190 if (!auth_success) {
191 P(mutex);
192 bmicrosleep(6, 0);
193 V(mutex);
194 }
195 return auth_success;
196 }
197