27
27
#include < iostream>
28
28
#include < string>
29
29
30
+ #include " util/ndb_openssl3_compat.h"
30
31
#include " util/require.h"
32
+ #include " util/TlsKeyManager.hpp"
31
33
#include < NDBT.hpp>
32
34
#include < NDBT_Test.hpp>
33
35
#include < portlib/NdbDir.hpp>
@@ -167,10 +169,8 @@ class Mgmd
167
169
return (m_proc != NULL );
168
170
}
169
171
170
- bool start_from_config_ini (const char * working_dir,
171
- const char * first_extra_arg = NULL , ...)
172
+ void common_args (NdbProcess::Args & args, const char * working_dir)
172
173
{
173
- NdbProcess::Args args;
174
174
args.add (" --no-defaults" );
175
175
args.add (" --configdir=" , working_dir);
176
176
args.add (" -f config.ini" );
@@ -181,6 +181,13 @@ class Mgmd
181
181
args.add (" --nodaemon" );
182
182
args.add (" --log-name=" , name ());
183
183
args.add (" --verbose" );
184
+ }
185
+
186
+ bool start_from_config_ini (const char * working_dir,
187
+ const char * first_extra_arg = NULL , ...)
188
+ {
189
+ NdbProcess::Args args;
190
+ common_args (args, working_dir);
184
191
185
192
if (first_extra_arg)
186
193
{
@@ -238,7 +245,7 @@ class Mgmd
238
245
return false ; // Can't kill with -9 -> fatal error
239
246
}
240
247
int ret;
241
- if (!m_proc->wait (ret, 300 ))
248
+ if (!m_proc->wait (ret, 1000 ))
242
249
{
243
250
fprintf (stderr, " Failed to wait for process %s\n " , name ());
244
251
return false ; // Can't wait after kill with -9 -> fatal error
@@ -387,20 +394,26 @@ class MgmdProcessList : public Vector<Mgmd*>
387
394
class Ndbd : public Mgmd
388
395
{
389
396
public:
390
- Ndbd (int nodeid) : Mgmd(nodeid)
397
+ Ndbd (int nodeid) : Mgmd(nodeid), m_args()
391
398
{
399
+ m_args.add (" --ndb-nodeid=" , m_nodeid);
400
+ m_args.add (" --foreground" );
392
401
m_name.assfmt (" ndbd_%d" , nodeid);
393
402
NDBT_find_ndbd (m_exe);
394
403
}
395
404
405
+ NdbProcess::Args & args () { return m_args; }
406
+
407
+ void set_connect_string (BaseString connect_string)
408
+ {
409
+ m_args.add (" -c" );
410
+ m_args.add (connect_string.c_str ());
411
+ }
412
+
396
413
bool start (const char *working_dir, BaseString connect_string)
397
414
{
398
- NdbProcess::Args args;
399
- args.add (" -c" );
400
- args.add (connect_string.c_str ());
401
- args.add (" --ndb-nodeid=" , m_nodeid);
402
- args.add (" --foreground" );
403
- return Mgmd::start (working_dir, args);
415
+ set_connect_string (connect_string);
416
+ return Mgmd::start (working_dir, m_args);
404
417
}
405
418
406
419
bool wait_started (NdbMgmHandle & mgm_handle,
@@ -435,6 +448,8 @@ class Ndbd : public Mgmd
435
448
return false ;
436
449
}
437
450
451
+ private:
452
+ NdbProcess::Args m_args;
438
453
};
439
454
440
455
static
@@ -447,9 +462,65 @@ bool create_CA(NDBT_Workingdir & wd, const BaseString &exe)
447
462
args.add (" --create-CA" );
448
463
args.add (" --CA-search-path=" , wd.path ());
449
464
NdbProcess * proc = NdbProcess::create (" Create CA" , exe, wd.path (), args);
450
- bool r = proc->wait (ret, 1000 );
465
+ bool r = proc->wait (ret, 3000 );
466
+ delete proc;
467
+
468
+ return (r && (ret == 0 ));
469
+ }
470
+
471
+ static
472
+ bool sign_tls_keys (NDBT_Workingdir & wd)
473
+ {
474
+ int ret;
475
+ BaseString cfg_path = path (wd.path (), " config.ini" , nullptr );
476
+
477
+ /* Find executable */
478
+ BaseString exe;
479
+ NDBT_find_sign_keys (exe);
480
+
481
+ /* Create CA */
482
+ if (! create_CA (wd, exe))
483
+ return false ;
484
+
485
+ /* Create keys and certificates for all nodes in config */
486
+ NdbProcess::Args args;
487
+ args.add (" --config-file=" , cfg_path.c_str ());
488
+ args.add (" --passphrase=" , " Trondheim" );
489
+ args.add (" --ndb-tls-search-path=" , wd.path ());
490
+ args.add (" --create-key" );
491
+ NdbProcess * proc = NdbProcess::create (" Create Keys" , exe, wd.path (), args);
492
+ bool r = proc->wait (ret, 3000 );
451
493
delete proc;
494
+ return (r && (ret == 0 ));
495
+ }
452
496
497
+ static
498
+ bool create_expired_cert (NDBT_Workingdir & wd)
499
+ {
500
+ int ret;
501
+
502
+ BaseString cfg_path = path (wd.path (), " config.ini" , nullptr );
503
+
504
+ /* Find executable */
505
+ BaseString exe;
506
+ NDBT_find_sign_keys (exe);
507
+
508
+ /* Create CA */
509
+ if (! create_CA (wd, exe))
510
+ return false ;
511
+
512
+ /* Create an expired certificate for a data node */
513
+ NdbProcess::Args args;
514
+ args.add (" --create-key" );
515
+ args.add (" --ndb-tls-search-path=" , wd.path ());
516
+ args.add (" --passphrase=" , " Trondheim" );
517
+ args.add (" -l" ); // no-config mode
518
+ args.add (" -t db" ); // type db
519
+ args.add (" --duration=" , " -50000" ); // negative seconds; already expired
520
+
521
+ NdbProcess * proc = NdbProcess::create (" Create Keys" , exe, wd.path (), args);
522
+ bool r = proc->wait (ret, 3000 );
523
+ delete proc;
453
524
return (r && (ret == 0 ));
454
525
}
455
526
@@ -1851,7 +1922,7 @@ runTestSshKeySigning(NDBT_Context* ctx, NDBT_Step* step)
1851
1922
args.add (" --create-key" );
1852
1923
args.add (" --remote-CA-host=" , " localhost" );
1853
1924
NdbProcess * proc = NdbProcess::create (" Create Keys" , exe, wd.path (), args);
1854
- bool r = proc->wait (ret, 1500 );
1925
+ bool r = proc->wait (ret, 3000 );
1855
1926
CHECK (r);
1856
1927
if (! r) proc->stop ();
1857
1928
delete proc;
@@ -1860,6 +1931,101 @@ runTestSshKeySigning(NDBT_Context* ctx, NDBT_Step* step)
1860
1931
return NDBT_OK;
1861
1932
}
1862
1933
1934
+ int
1935
+ runTestNdbdWithoutCert (NDBT_Context* ctx, NDBT_Step* step)
1936
+ {
1937
+ NDBT_Workingdir wd (" test_mgmd" ); // temporary working directory
1938
+ BaseString cfg_path = path (wd.path (), " config.ini" , nullptr );
1939
+
1940
+ Properties config = ConfigFactory::create ();
1941
+ Properties db;
1942
+ db.put (" RequireCertificate" , " true" );
1943
+ config.put (" DB Default" , & db);
1944
+
1945
+ CHECK (ConfigFactory::write_config_ini (config, cfg_path.c_str ()));
1946
+
1947
+ Mgmd mgmd (1 );
1948
+ Ndbd ndbd (2 );
1949
+
1950
+ CHECK (mgmd.start_from_config_ini (wd.path ())); // Start management node
1951
+ CHECK (mgmd.connect (config)); // Connect to management node
1952
+ CHECK (mgmd.wait_confirmed_config ()); // Wait for configuration
1953
+
1954
+ int exit_code; // Start ndbd; it will fail
1955
+ CHECK (ndbd.start (wd.path (), mgmd.connectstring (config)));
1956
+ CHECK (ndbd.wait (exit_code, 100 )); // should fail quickly
1957
+ require (exit_code == 255 );
1958
+
1959
+ CHECK (mgmd.stop ());
1960
+ return NDBT_OK;
1961
+ }
1962
+
1963
+ int
1964
+ runTestNdbdWithExpiredCert (NDBT_Context* ctx, NDBT_Step* step)
1965
+ {
1966
+ NDBT_Workingdir wd (" test_tls" ); // temporary working directory
1967
+
1968
+ BaseString cfg_path = path (wd.path (), " config.ini" , nullptr );
1969
+
1970
+ Properties config = ConfigFactory::create ();
1971
+ Properties db;
1972
+ db.put (" RequireCertificate" , " true" );
1973
+ config.put (" DB Default" , & db);
1974
+ CHECK (ConfigFactory::write_config_ini (config, cfg_path.c_str ()));
1975
+
1976
+ CHECK (create_expired_cert (wd));
1977
+
1978
+ Mgmd mgmd (1 );
1979
+ Ndbd ndbd (2 );
1980
+
1981
+ CHECK (mgmd.start_from_config_ini (wd.path ())); // Start management node
1982
+ CHECK (mgmd.connect (config)); // Connect to management node
1983
+ CHECK (mgmd.wait_confirmed_config ()); // Wait for configuration
1984
+
1985
+ ndbd.args ().add (" --ndb-tls-search-path=" , wd.path ());
1986
+ ndbd.start (wd.path (), mgmd.connectstring (config)); // Start data node
1987
+
1988
+ int exit_code;
1989
+ CHECK (ndbd.wait (exit_code, 100 )); // should fail quickly
1990
+ CHECK (exit_code == 255 );
1991
+
1992
+ CHECK (mgmd.stop ());
1993
+ return NDBT_OK;
1994
+ }
1995
+
1996
+ int
1997
+ runTestNdbdWithCert (NDBT_Context* ctx, NDBT_Step* step)
1998
+ {
1999
+ NDBT_Workingdir wd (" test_tls" ); // temporary working directory
2000
+
2001
+ BaseString cfg_path = path (wd.path (), " config.ini" , nullptr );
2002
+ Properties config = ConfigFactory::create ();
2003
+ Properties db;
2004
+ db.put (" RequireCertificate" , " true" );
2005
+ config.put (" DB Default" , & db);
2006
+ CHECK (ConfigFactory::write_config_ini (config, cfg_path.c_str ()));
2007
+
2008
+ CHECK (sign_tls_keys (wd));
2009
+
2010
+ Mgmd mgmd (1 );
2011
+ Ndbd ndbd (2 );
2012
+
2013
+ NdbProcess::Args mgmdArgs;
2014
+ mgmd.common_args (mgmdArgs, wd.path ());
2015
+ mgmdArgs.add (" --ndb-tls-search-path=" , wd.path ());
2016
+
2017
+ CHECK (mgmd.start (wd.path (), mgmdArgs)); // Start management node
2018
+ CHECK (mgmd.connect (config)); // Connect to management node
2019
+ CHECK (mgmd.wait_confirmed_config ()); // Wait for configuration
2020
+
2021
+ ndbd.args ().add (" --ndb-tls-search-path=" , wd.path ());
2022
+ ndbd.start (wd.path (), mgmd.connectstring (config)); // Start data node
2023
+ NdbMgmHandle handle = mgmd.handle ();
2024
+ CHECK (ndbd.wait_started (handle));
2025
+
2026
+ CHECK (mgmd.stop ());
2027
+ return NDBT_OK;
2028
+ }
1863
2029
1864
2030
NDBT_TESTSUITE (testMgmd);
1865
2031
DRIVER (DummyDriver); /* turn off use of NdbApi */
@@ -1955,12 +2121,33 @@ TESTCASE("MultiMGMDDisconnection",
1955
2121
INITIALIZER (runTestMultiMGMDDisconnection);
1956
2122
}
1957
2123
2124
+ #if OPENSSL_VERSION_NUMBER >= NDB_TLS_MINIMUM_OPENSSL
2125
+
1958
2126
TESTCASE (" SshKeySigning" ,
1959
2127
" Test remote key signing over ssh using ndb_sign_keys" )
1960
2128
{
1961
2129
INITIALIZER (runTestSshKeySigning);
1962
2130
}
1963
2131
2132
+ TESTCASE (" NdbdWithoutCertificate" ,
2133
+ " Test data node startup with TLS required but no certificate" )
2134
+ {
2135
+ INITIALIZER (runTestNdbdWithoutCert)
2136
+ }
2137
+
2138
+ TESTCASE (" NdbdWithExpiredCertificate" ,
2139
+ " Test data node startup with expired certificate" )
2140
+ {
2141
+ INITIALIZER (runTestNdbdWithExpiredCert)
2142
+ }
2143
+
2144
+ TESTCASE (" NdbdWithCertificate" , " Test data node startup with certificate" )
2145
+ {
2146
+ INITIALIZER (runTestNdbdWithCert)
2147
+ }
2148
+
2149
+ #endif
2150
+
1964
2151
NDBT_TESTSUITE_END (testMgmd)
1965
2152
1966
2153
int main(int argc, const char ** argv)
0 commit comments