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