1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 // To show that this test actually tests something, you can change
20 // MANUAL_OPENSSL_INIT to 0 to cause automatic OpenSSL init/cleanup,
21 // which will cause the test to fail
22 #define MANUAL_OPENSSL_INIT 1
23 #ifdef _WIN32
24 #include <winsock2.h>
25 #endif
26
27 #include <boost/test/unit_test.hpp>
28 #include <openssl/evp.h>
29 #include <thrift/transport/TSSLSocket.h>
30
31 using namespace apache::thrift::transport;
32
make_isolated_sslsocketfactory()33 void make_isolated_sslsocketfactory() {
34 // Here we create an isolated TSSLSocketFactory to ensure the
35 // constructor and destructor of TSSLSocketFactory get run. Thus
36 // without manual initialization normally OpenSSL would be
37 // uninitialized after this function.
38 TSSLSocketFactory factory;
39 }
40
openssl_init()41 void openssl_init() {
42 #if MANUAL_OPENSSL_INIT
43 TSSLSocketFactory::setManualOpenSSLInitialization(true);
44 initializeOpenSSL();
45 #endif
46 }
47
openssl_cleanup()48 void openssl_cleanup() {
49 #if MANUAL_OPENSSL_INIT
50 cleanupOpenSSL();
51 #endif
52 }
53
test_openssl_availability()54 void test_openssl_availability() {
55 // Check whether Thrift leaves OpenSSL functionality available after
56 // the last TSSLSocketFactory is destroyed when manual
57 // initialization is set
58 openssl_init();
59 make_isolated_sslsocketfactory();
60
61 // The following function is one that will fail if OpenSSL is
62 // uninitialized. It might also fail on very old versions of
63 // OpenSSL...
64 const EVP_MD* md = EVP_get_digestbyname("SHA256");
65 BOOST_CHECK(md != nullptr);
66 openssl_cleanup();
67 }
68
69 #ifdef BOOST_TEST_DYN_LINK
init_unit_test_suite()70 bool init_unit_test_suite() {
71 boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite();
72 suite->p_name.value = "OpenSSLManualInit";
73
74 suite->add(BOOST_TEST_CASE(test_openssl_availability));
75
76 return true;
77 }
78
main(int argc,char * argv[])79 int main( int argc, char* argv[] ) {
80 return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv);
81 }
82 #else
init_unit_test_suite(int argc,char * argv[])83 boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) {
84 THRIFT_UNUSED_VARIABLE(argc);
85 THRIFT_UNUSED_VARIABLE(argv);
86 boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite();
87 suite->p_name.value = "OpenSSLManualInit";
88
89 suite->add(BOOST_TEST_CASE(test_openssl_availability));
90
91 return nullptr;
92 }
93 #endif