29
29
#include < ndbd_exit_codes.h>
30
30
31
31
#include < util/BaseString.hpp>
32
+ #include " util/TlsKeyManager.hpp"
32
33
#include < util/Vector.hpp>
33
34
#include < kernel/BlockNumbers.h>
34
35
#include < kernel/signaldata/DumpStateOrd.hpp>
@@ -51,7 +52,9 @@ class CommandInterpreter {
51
52
CommandInterpreter (const char * host,
52
53
const char * default_prompt,
53
54
int verbose,
54
- int connect_retry_delay);
55
+ int connect_retry_delay,
56
+ const char * tls_search_path,
57
+ int tls_start_type);
55
58
~CommandInterpreter ();
56
59
57
60
int setDefaultBackupPassword (const char backup_password[]);
@@ -146,12 +149,14 @@ class CommandInterpreter {
146
149
int *node_ids, int no_of_nodes);
147
150
int executeCreateNodeGroup (char * parameters);
148
151
int executeDropNodeGroup (char * parameters);
152
+ int executeStartTls ();
149
153
const char * get_current_prompt () const
150
154
{
151
155
// return the current prompt
152
156
return m_prompt;
153
157
}
154
158
public:
159
+ int test_tls ();
155
160
bool connect (bool interactive);
156
161
void disconnect (void );
157
162
@@ -175,6 +180,7 @@ class CommandInterpreter {
175
180
ExecuteFunction fun,
176
181
const char * param);
177
182
183
+ TlsKeyManager m_tlsKeyManager;
178
184
NdbMgmHandle m_mgmsrv;
179
185
NdbMgmHandle m_mgmsrv2;
180
186
const char *m_constr;
@@ -192,6 +198,7 @@ class CommandInterpreter {
192
198
bool m_always_encrypt_backup;
193
199
char m_onetime_backup_password[1024 ];
194
200
bool m_onetime_backup_password_set;
201
+ int m_tls_start_type;
195
202
};
196
203
197
204
NdbMutex* print_mutex;
@@ -203,10 +210,12 @@ NdbMutex* print_mutex;
203
210
#include " ndb_mgmclient.hpp"
204
211
205
212
Ndb_mgmclient::Ndb_mgmclient (const char *host, const char * default_prompt,
206
- int verbose, int connect_retry_delay)
213
+ int verbose, int connect_retry_delay,
214
+ const char * tls_search_path, int tls_start_type)
207
215
{
208
216
m_cmd= new CommandInterpreter (host, default_prompt,
209
- verbose, connect_retry_delay);
217
+ verbose, connect_retry_delay,
218
+ tls_search_path, tls_start_type);
210
219
}
211
220
Ndb_mgmclient::~Ndb_mgmclient ()
212
221
{
@@ -234,6 +243,11 @@ int Ndb_mgmclient::set_always_encrypt_backup(bool on) const
234
243
return m_cmd->setAlwaysEncryptBackup (on);
235
244
}
236
245
246
+ int Ndb_mgmclient::test_tls ()
247
+ {
248
+ return m_cmd->test_tls ();
249
+ }
250
+
237
251
/*
238
252
* The CommandInterpreter
239
253
*/
@@ -265,6 +279,7 @@ static const char* helpText =
265
279
" SHOW Print information about cluster\n "
266
280
" CREATE NODEGROUP <id>,<id>... Add a Nodegroup containing nodes\n "
267
281
" DROP NODEGROUP <NG> Drop nodegroup with id NG\n "
282
+ " START TLS Start TLS on connection\n "
268
283
" START BACKUP [<backup id>] [ENCRYPT [PASSWORD='<password>']] "
269
284
" [SNAPSHOTSTART | SNAPSHOTEND] [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n "
270
285
" Start backup "
@@ -722,7 +737,9 @@ convert(const char* s, int& val) {
722
737
*/
723
738
CommandInterpreter::CommandInterpreter (const char *host,
724
739
const char * default_prompt,
725
- int verbose, int connect_retry_delay) :
740
+ int verbose, int connect_retry_delay,
741
+ const char * tls_search_path,
742
+ int tls_start_type) :
726
743
m_constr(host),
727
744
m_connected(false ),
728
745
m_verbose(verbose),
@@ -734,8 +751,10 @@ CommandInterpreter::CommandInterpreter(const char *host,
734
751
m_prompt(default_prompt),
735
752
m_default_backup_password(nullptr ),
736
753
m_always_encrypt_backup(false ),
737
- m_onetime_backup_password_set(false )
754
+ m_onetime_backup_password_set(false ),
755
+ m_tls_start_type(tls_start_type)
738
756
{
757
+ m_tlsKeyManager.init_mgm_client (tls_search_path);
739
758
m_print_mutex= NdbMutex_Create ();
740
759
}
741
760
@@ -996,6 +1015,13 @@ event_thread_run(void* p)
996
1015
DBUG_RETURN (NULL );
997
1016
}
998
1017
1018
+ int
1019
+ CommandInterpreter::test_tls ()
1020
+ {
1021
+ m_try_reconnect = 1 ;
1022
+ return connect (false ) ? 0 : 1 ;
1023
+ }
1024
+
999
1025
bool
1000
1026
CommandInterpreter::connect (bool interactive)
1001
1027
{
@@ -1010,6 +1036,13 @@ CommandInterpreter::connect(bool interactive)
1010
1036
exit (-1 );
1011
1037
}
1012
1038
1039
+ if ((m_tls_start_type == CLIENT_TLS_STRICT) &&
1040
+ (m_tlsKeyManager.ctx () == nullptr ))
1041
+ {
1042
+ ndbout_c (" No valid certificate." );
1043
+ exit (-1 );
1044
+ }
1045
+
1013
1046
if (interactive) {
1014
1047
m_mgmsrv2 = ndb_mgm_create_handle ();
1015
1048
if (m_mgmsrv2 == NULL ) {
@@ -1045,6 +1078,29 @@ CommandInterpreter::connect(bool interactive)
1045
1078
DBUG_RETURN (m_connected); // couldn't connect, always false
1046
1079
}
1047
1080
1081
+ ndb_mgm_set_ssl_ctx (m_mgmsrv, m_tlsKeyManager.ctx ());
1082
+
1083
+ if (m_tls_start_type != CLIENT_TLS_DEFERRED)
1084
+ {
1085
+ if (ndb_mgm_start_tls (m_mgmsrv) != 0 )
1086
+ {
1087
+ if (interactive)
1088
+ {
1089
+ ndbout_c (" Connected to server, but failed to start TLS." );
1090
+ }
1091
+
1092
+ if (m_tls_start_type == CLIENT_TLS_STRICT)
1093
+ {
1094
+ printError ();
1095
+ ndb_mgm_destroy_handle (&m_mgmsrv);
1096
+ if (interactive)
1097
+ {
1098
+ ndb_mgm_destroy_handle (&m_mgmsrv2);
1099
+ }
1100
+ DBUG_RETURN (m_connected);
1101
+ }
1102
+ }
1103
+ }
1048
1104
1049
1105
const char *host= ndb_mgm_get_connected_host (m_mgmsrv);
1050
1106
unsigned port= ndb_mgm_get_connected_port (m_mgmsrv);
@@ -1056,6 +1112,10 @@ CommandInterpreter::connect(bool interactive)
1056
1112
{
1057
1113
DBUG_PRINT (" info" ,(" 2:ndb connected to Management Server ok at: %s:%d" ,
1058
1114
host, port));
1115
+ if (m_tls_start_type != CLIENT_TLS_DEFERRED)
1116
+ {
1117
+ ndb_mgm_start_tls (m_mgmsrv2);
1118
+ }
1059
1119
assert (m_event_thread == NULL );
1060
1120
assert (do_event_thread == 0 );
1061
1121
do_event_thread= 0 ;
@@ -1363,6 +1423,12 @@ CommandInterpreter::execute_impl(const char *_line, bool interactive)
1363
1423
executeClusterLog (allAfterFirstToken);
1364
1424
DBUG_RETURN (true );
1365
1425
}
1426
+ else if (native_strcasecmp (firstToken, " START" ) == 0 &&
1427
+ allAfterFirstToken != NULL &&
1428
+ native_strncasecmp (allAfterFirstToken, " TLS" , 3 ) == 0 ) {
1429
+ m_error = executeStartTls ();
1430
+ DBUG_RETURN (true );
1431
+ }
1366
1432
else if (native_strcasecmp (firstToken, " START" ) == 0 &&
1367
1433
allAfterFirstToken != NULL &&
1368
1434
native_strncasecmp (allAfterFirstToken, " BACKUP" , sizeof (" BACKUP" ) - 1 ) == 0 ){
@@ -2057,6 +2123,15 @@ CommandInterpreter::executeConnect(char* parameters, bool interactive)
2057
2123
return 0 ;
2058
2124
}
2059
2125
2126
+ int
2127
+ CommandInterpreter::executeStartTls ()
2128
+ {
2129
+ int result = ndb_mgm_start_tls (m_mgmsrv);
2130
+ if (result == 0 ) ndbout_c (" TLS started." );
2131
+ else printError ();
2132
+ return result;
2133
+ }
2134
+
2060
2135
// *****************************************************************************
2061
2136
// *****************************************************************************
2062
2137
void
0 commit comments