1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2018-2018 Bareos GmbH & Co. KG
5
6 This program is Free Software; you can redistribute it and/or
7 modify it under the terms of version three of the GNU Affero General Public
8 License as published by the Free Software Foundation and included
9 in the file LICENSE.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Affero General Public License for more details.
15
16 You should have received a copy of the GNU Affero General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA.
20 */
21
22 #include "include/bareos.h"
23 #include "try_tls_handshake_as_a_server.h"
24
25 #include "lib/bsock_tcp.h"
26 #include "lib/configured_tls_policy_getter.h"
27 #include "lib/parse_conf.h"
28
29 enum class ConnectionHandshakeMode
30 {
31 PerformTlsHandshake,
32 PerformCleartextHandshake,
33 CloseConnection
34 };
35
GetHandshakeMode(BareosSocket * bs,const ConfigurationParser & config)36 static ConnectionHandshakeMode GetHandshakeMode(
37 BareosSocket* bs,
38 const ConfigurationParser& config)
39 {
40 bool cleartext_hello;
41 std::string client_name;
42 std::string r_code_str;
43 BareosVersionNumber version = BareosVersionNumber::kUndefined;
44
45 if (!bs->EvaluateCleartextBareosHello(cleartext_hello, client_name,
46 r_code_str, version)) {
47 Dmsg0(100, "Error occured when trying to peek cleartext hello\n");
48 return ConnectionHandshakeMode::CloseConnection;
49 }
50
51 bs->connected_daemon_version_ = static_cast<BareosVersionNumber>(version);
52
53 if (cleartext_hello) {
54 ConfiguredTlsPolicyGetter tls_policy_getter(config);
55 TlsPolicy tls_policy;
56 if (!tls_policy_getter.GetConfiguredTlsPolicyFromCleartextHello(
57 r_code_str, client_name, tls_policy)) {
58 Dmsg0(200, "Could not read out cleartext configuration\n");
59 return ConnectionHandshakeMode::CloseConnection;
60 }
61 Dmsg0(200, "TlsPolicy for %s is %u\n", client_name.c_str(), tls_policy);
62 if (r_code_str == std::string("R_CLIENT")) {
63 if (tls_policy == kBnetTlsRequired) {
64 return ConnectionHandshakeMode::CloseConnection;
65 } else { /* kBnetTlsNone or kBnetTlsEnabled */
66 return ConnectionHandshakeMode::PerformCleartextHandshake;
67 }
68 } else if (r_code_str == std::string("R_CONSOLE") &&
69 version < BareosVersionNumber::kRelease_18_2) {
70 return ConnectionHandshakeMode::PerformCleartextHandshake;
71 } else {
72 if (tls_policy == kBnetTlsNone) {
73 return ConnectionHandshakeMode::PerformCleartextHandshake;
74 } else {
75 Dmsg1(200,
76 "Connection to %s will be denied due to configuration mismatch\n",
77 client_name.c_str());
78 return ConnectionHandshakeMode::CloseConnection;
79 }
80 }
81 } else { /* not cleartext */
82 return ConnectionHandshakeMode::PerformTlsHandshake;
83 } /* if (cleartext_hello) */
84 }
85
TryTlsHandshakeAsAServer(BareosSocket * bs,ConfigurationParser * config)86 bool TryTlsHandshakeAsAServer(BareosSocket* bs, ConfigurationParser* config)
87 {
88 ASSERT(config);
89 ConnectionHandshakeMode mode = GetHandshakeMode(bs, *config);
90
91 bool success = false;
92
93 switch (mode) {
94 case ConnectionHandshakeMode::PerformTlsHandshake:
95 if (bs->DoTlsHandshakeAsAServer(config)) { success = true; }
96 break;
97 case ConnectionHandshakeMode::PerformCleartextHandshake:
98 /* do tls handshake later */
99 success = true;
100 break;
101 default:
102 case ConnectionHandshakeMode::CloseConnection:
103 success = false;
104 break;
105 }
106
107 return success;
108 }
109