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 
27 enum class ConnectionHandshakeMode {
28   PerformTlsHandshake,
29   PerformCleartextHandshake,
30   CloseConnection
31 };
32 
GetHandshakeMode(BareosSocket * bs,ConfigurationParser * config)33 static ConnectionHandshakeMode GetHandshakeMode(BareosSocket *bs,
34                                                 ConfigurationParser *config)
35 {
36   bool cleartext_hello;
37   std::string client_name;
38   std::string r_code_str;
39   BareosVersionNumber version = BareosVersionNumber::kUndefined;
40 
41   if (!bs->EvaluateCleartextBareosHello(cleartext_hello,
42                                         client_name,
43                                         r_code_str,
44                                         version)) {
45     Dmsg0(100, "Error occured when trying to peek cleartext hello\n");
46     return ConnectionHandshakeMode::CloseConnection;
47   }
48 
49   bs->connected_daemon_version_ = static_cast<BareosVersionNumber>(version);
50 
51   if (cleartext_hello) {
52     TlsPolicy tls_policy;
53     if (!config->GetConfiguredTlsPolicyFromCleartextHello(r_code_str, client_name, tls_policy)) {
54       Dmsg0(200, "Could not read out cleartext configuration\n");
55       return ConnectionHandshakeMode::CloseConnection;
56     }
57     if (r_code_str == std::string("R_CLIENT")) {
58       if (tls_policy == kBnetTlsRequired) {
59         return ConnectionHandshakeMode::CloseConnection;
60       } else { /* kBnetTlsNone or kBnetTlsEnabled */
61         return ConnectionHandshakeMode::PerformCleartextHandshake;
62       }
63     } else if (r_code_str == std::string("R_CONSOLE") && version < BareosVersionNumber::kRelease_18_2) {
64       return ConnectionHandshakeMode::PerformCleartextHandshake;
65     } else {
66       if (tls_policy == kBnetTlsNone) {
67         return ConnectionHandshakeMode::PerformCleartextHandshake;
68       } else {
69         Dmsg1(200, "Connection to %s will be denied due to configuration mismatch\n", client_name.c_str());
70         return ConnectionHandshakeMode::CloseConnection;
71       }
72     }
73   } else { /* not cleartext */
74     return ConnectionHandshakeMode::PerformTlsHandshake;
75   } /* if (cleartext_hello) */
76 }
77 
TryTlsHandshakeAsAServer(BareosSocket * bs,ConfigurationParser * config)78 bool TryTlsHandshakeAsAServer(BareosSocket *bs, ConfigurationParser *config)
79 {
80    ConnectionHandshakeMode mode = GetHandshakeMode(bs, config);
81 
82    bool success = false;
83 
84    switch(mode) {
85    case ConnectionHandshakeMode::PerformTlsHandshake:
86       if (bs->DoTlsHandshakeAsAServer(config)) {
87         success = true;
88       }
89       break;
90    case ConnectionHandshakeMode::PerformCleartextHandshake:
91       /* do tls handshake later */
92       success = true;
93       break;
94    default:
95    case ConnectionHandshakeMode::CloseConnection:
96       success = false;
97       break;
98    }
99 
100    return success;
101 }
102