2929#include < ndbd_exit_codes.h>
3030
3131#include < util/BaseString.hpp>
32+ #include " util/TlsKeyManager.hpp"
3233#include < util/Vector.hpp>
3334#include < kernel/BlockNumbers.h>
3435#include < kernel/signaldata/DumpStateOrd.hpp>
@@ -51,7 +52,9 @@ class CommandInterpreter {
5152 CommandInterpreter (const char * host,
5253 const char * default_prompt,
5354 int verbose,
54- int connect_retry_delay);
55+ int connect_retry_delay,
56+ const char * tls_search_path,
57+ int tls_start_type);
5558 ~CommandInterpreter ();
5659
5760 int setDefaultBackupPassword (const char backup_password[]);
@@ -146,12 +149,14 @@ class CommandInterpreter {
146149 int *node_ids, int no_of_nodes);
147150 int executeCreateNodeGroup (char * parameters);
148151 int executeDropNodeGroup (char * parameters);
152+ int executeStartTls ();
149153 const char * get_current_prompt () const
150154 {
151155 // return the current prompt
152156 return m_prompt;
153157 }
154158public:
159+ int test_tls ();
155160 bool connect (bool interactive);
156161 void disconnect (void );
157162
@@ -175,6 +180,7 @@ class CommandInterpreter {
175180 ExecuteFunction fun,
176181 const char * param);
177182
183+ TlsKeyManager m_tlsKeyManager;
178184 NdbMgmHandle m_mgmsrv;
179185 NdbMgmHandle m_mgmsrv2;
180186 const char *m_constr;
@@ -192,6 +198,7 @@ class CommandInterpreter {
192198 bool m_always_encrypt_backup;
193199 char m_onetime_backup_password[1024 ];
194200 bool m_onetime_backup_password_set;
201+ int m_tls_start_type;
195202};
196203
197204NdbMutex* print_mutex;
@@ -203,10 +210,12 @@ NdbMutex* print_mutex;
203210#include " ndb_mgmclient.hpp"
204211
205212Ndb_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)
207215{
208216 m_cmd= new CommandInterpreter (host, default_prompt,
209- verbose, connect_retry_delay);
217+ verbose, connect_retry_delay,
218+ tls_search_path, tls_start_type);
210219}
211220Ndb_mgmclient::~Ndb_mgmclient ()
212221{
@@ -234,6 +243,11 @@ int Ndb_mgmclient::set_always_encrypt_backup(bool on) const
234243 return m_cmd->setAlwaysEncryptBackup (on);
235244}
236245
246+ int Ndb_mgmclient::test_tls ()
247+ {
248+ return m_cmd->test_tls ();
249+ }
250+
237251/*
238252 * The CommandInterpreter
239253 */
@@ -265,6 +279,7 @@ static const char* helpText =
265279" SHOW Print information about cluster\n "
266280" CREATE NODEGROUP <id>,<id>... Add a Nodegroup containing nodes\n "
267281" DROP NODEGROUP <NG> Drop nodegroup with id NG\n "
282+ " START TLS Start TLS on connection\n "
268283" START BACKUP [<backup id>] [ENCRYPT [PASSWORD='<password>']] "
269284 " [SNAPSHOTSTART | SNAPSHOTEND] [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n "
270285" Start backup "
@@ -722,7 +737,9 @@ convert(const char* s, int& val) {
722737 */
723738CommandInterpreter::CommandInterpreter (const char *host,
724739 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) :
726743 m_constr(host),
727744 m_connected(false ),
728745 m_verbose(verbose),
@@ -734,8 +751,10 @@ CommandInterpreter::CommandInterpreter(const char *host,
734751 m_prompt(default_prompt),
735752 m_default_backup_password(nullptr ),
736753 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)
738756{
757+ m_tlsKeyManager.init_mgm_client (tls_search_path);
739758 m_print_mutex= NdbMutex_Create ();
740759}
741760
@@ -996,6 +1015,13 @@ event_thread_run(void* p)
9961015 DBUG_RETURN (NULL );
9971016}
9981017
1018+ int
1019+ CommandInterpreter::test_tls ()
1020+ {
1021+ m_try_reconnect = 1 ;
1022+ return connect (false ) ? 0 : 1 ;
1023+ }
1024+
9991025bool
10001026CommandInterpreter::connect (bool interactive)
10011027{
@@ -1010,6 +1036,13 @@ CommandInterpreter::connect(bool interactive)
10101036 exit (-1 );
10111037 }
10121038
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+
10131046 if (interactive) {
10141047 m_mgmsrv2 = ndb_mgm_create_handle ();
10151048 if (m_mgmsrv2 == NULL ) {
@@ -1045,6 +1078,29 @@ CommandInterpreter::connect(bool interactive)
10451078 DBUG_RETURN (m_connected); // couldn't connect, always false
10461079 }
10471080
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+ }
10481104
10491105 const char *host= ndb_mgm_get_connected_host (m_mgmsrv);
10501106 unsigned port= ndb_mgm_get_connected_port (m_mgmsrv);
@@ -1056,6 +1112,10 @@ CommandInterpreter::connect(bool interactive)
10561112 {
10571113 DBUG_PRINT (" info" ,(" 2:ndb connected to Management Server ok at: %s:%d" ,
10581114 host, port));
1115+ if (m_tls_start_type != CLIENT_TLS_DEFERRED)
1116+ {
1117+ ndb_mgm_start_tls (m_mgmsrv2);
1118+ }
10591119 assert (m_event_thread == NULL );
10601120 assert (do_event_thread == 0 );
10611121 do_event_thread= 0 ;
@@ -1363,6 +1423,12 @@ CommandInterpreter::execute_impl(const char *_line, bool interactive)
13631423 executeClusterLog (allAfterFirstToken);
13641424 DBUG_RETURN (true );
13651425 }
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+ }
13661432 else if (native_strcasecmp (firstToken, " START" ) == 0 &&
13671433 allAfterFirstToken != NULL &&
13681434 native_strncasecmp (allAfterFirstToken, " BACKUP" , sizeof (" BACKUP" ) - 1 ) == 0 ){
@@ -2057,6 +2123,15 @@ CommandInterpreter::executeConnect(char* parameters, bool interactive)
20572123 return 0 ;
20582124}
20592125
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+
20602135// *****************************************************************************
20612136// *****************************************************************************
20622137void
0 commit comments