/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#define BOOST_TEST_MODULE SecurityFromBufferTest
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/thread.hpp>
#include <stdexcept>
#include <fstream>
#include <memory>
#include <openssl/opensslv.h>
#include <thrift/transport/TSSLServerSocket.h>
#include <thrift/transport/TSSLSocket.h>
#include <thrift/transport/TTransport.h>
#include <vector>
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif

using apache::thrift::transport::TServerTransport;
using apache::thrift::transport::TSSLServerSocket;
using apache::thrift::transport::TSSLSocket;
using apache::thrift::transport::TSSLSocketFactory;
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
using apache::thrift::transport::TTransportFactory;

using std::bind;
using std::shared_ptr;

boost::filesystem::path keyDir;
boost::filesystem::path certFile(const std::string& filename) {
  return keyDir / filename;
}
std::string certString(const std::string& filename) {
  std::ifstream ifs(certFile(filename).string());
  if(!ifs.is_open() || !ifs.good()) {
    throw(std::runtime_error("Failed to open key file " + filename + " for reading"));
  }
  std::stringstream buffer;
  buffer << ifs.rdbuf();
  return buffer.str();
}
boost::mutex gMutex;

struct GlobalFixture {
  GlobalFixture() {
    using namespace boost::unit_test::framework;
    for (int i = 0; i < master_test_suite().argc; ++i) {
      BOOST_TEST_MESSAGE(boost::format("argv[%1%] = \"%2%\"") % i % master_test_suite().argv[i]);
    }

#ifdef __linux__
    // OpenSSL calls send() without MSG_NOSIGPIPE so writing to a socket that has
    // disconnected can cause a SIGPIPE signal...
    signal(SIGPIPE, SIG_IGN);
#endif

    TSSLSocketFactory::setManualOpenSSLInitialization(true);
    apache::thrift::transport::initializeOpenSSL();

    keyDir = boost::filesystem::current_path().parent_path().parent_path().parent_path() / "test" / "keys";
    if (!boost::filesystem::exists(certFile("server.crt"))) {
      keyDir = boost::filesystem::path(master_test_suite().argv[master_test_suite().argc - 1]);
      if (!boost::filesystem::exists(certFile("server.crt"))) {
        throw std::invalid_argument("The last argument to this test must be the directory containing the test certificate(s).");
      }
    }
  }

  virtual ~GlobalFixture() {
    apache::thrift::transport::cleanupOpenSSL();
#ifdef __linux__
    signal(SIGPIPE, SIG_DFL);
#endif
  }
};

#if (BOOST_VERSION >= 105900)
BOOST_GLOBAL_FIXTURE(GlobalFixture);
#else
BOOST_GLOBAL_FIXTURE(GlobalFixture)
#endif

struct SecurityFromBufferFixture {
  void server(apache::thrift::transport::SSLProtocol protocol) {
    try {
      boost::mutex::scoped_lock lock(mMutex);

      shared_ptr<TSSLSocketFactory> pServerSocketFactory;
      shared_ptr<TSSLServerSocket> pServerSocket;

      pServerSocketFactory.reset(new TSSLSocketFactory(static_cast<apache::thrift::transport::SSLProtocol>(protocol)));
      pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
      pServerSocketFactory->loadCertificateFromBuffer(certString("server.crt").c_str());
      pServerSocketFactory->loadPrivateKeyFromBuffer(certString("server.key").c_str());
      pServerSocketFactory->server(true);
      pServerSocket.reset(new TSSLServerSocket("localhost", 0, pServerSocketFactory));
      shared_ptr<TTransport> connectedClient;

      try {
        pServerSocket->listen();
        mPort = pServerSocket->getPort();
        mCVar.notify_one();
        lock.unlock();

        connectedClient = pServerSocket->accept();
        uint8_t buf[2];
        buf[0] = 'O';
        buf[1] = 'K';
        connectedClient->write(&buf[0], 2);
        connectedClient->flush();
      }

      catch (apache::thrift::transport::TTransportException& ex) {
        boost::mutex::scoped_lock lock(gMutex);
        BOOST_TEST_MESSAGE(boost::format("SRV %1% Exception: %2%") % boost::this_thread::get_id() % ex.what());
      }

      if (connectedClient) {
        connectedClient->close();
        connectedClient.reset();
      }

      pServerSocket->close();
      pServerSocket.reset();
    } catch (std::exception& ex) {
      BOOST_FAIL(boost::format("%1%: %2%") % typeid(ex).name() % ex.what());
    }
  }

  void client(apache::thrift::transport::SSLProtocol protocol) {
    try {
      shared_ptr<TSSLSocketFactory> pClientSocketFactory;
      shared_ptr<TSSLSocket> pClientSocket;

      try {
        pClientSocketFactory.reset(new TSSLSocketFactory(static_cast<apache::thrift::transport::SSLProtocol>(protocol)));
        pClientSocketFactory->authenticate(true);
        pClientSocketFactory->loadCertificateFromBuffer(certString("client.crt").c_str());
        pClientSocketFactory->loadPrivateKeyFromBuffer(certString("client.key").c_str());
        pClientSocketFactory->loadTrustedCertificatesFromBuffer(certString("CA.pem").c_str());
        pClientSocket = pClientSocketFactory->createSocket("localhost", mPort);
        pClientSocket->open();

        uint8_t buf[3];
        buf[0] = 0;
        buf[1] = 0;
        BOOST_CHECK_EQUAL(2, pClientSocket->read(&buf[0], 2));
        BOOST_CHECK_EQUAL(0, memcmp(&buf[0], "OK", 2));
        mConnected = true;
      } catch (apache::thrift::transport::TTransportException& ex) {
        boost::mutex::scoped_lock lock(gMutex);
        BOOST_TEST_MESSAGE(boost::format("CLI %1% Exception: %2%") % boost::this_thread::get_id() % ex.what());
      }

      if (pClientSocket) {
        pClientSocket->close();
        pClientSocket.reset();
      }
    } catch (std::exception& ex) {
      BOOST_FAIL(boost::format("%1%: %2%") % typeid(ex).name() % ex.what());
    }
  }

  static const char* protocol2str(size_t protocol) {
    static const char* strings[apache::thrift::transport::LATEST + 1]
        = {"SSLTLS", "SSLv2", "SSLv3", "TLSv1_0", "TLSv1_1", "TLSv1_2"};
    return strings[protocol];
  }

  boost::mutex mMutex;
  boost::condition_variable mCVar;
  int mPort;
  bool mConnected;
};

BOOST_FIXTURE_TEST_SUITE(BOOST_TEST_MODULE, SecurityFromBufferFixture)

BOOST_AUTO_TEST_CASE(ssl_security_matrix) {
  try {
    // matrix of connection success between client and server with different SSLProtocol selections
        static_assert(apache::thrift::transport::LATEST == 5, "Mismatch in assumed number of ssl protocols");
        bool ossl1 = OPENSSL_VERSION_MAJOR == 1;
        bool matrix[apache::thrift::transport::LATEST + 1][apache::thrift::transport::LATEST + 1] =
        {
    //   server    = SSLTLS   SSLv2    SSLv3    TLSv1_0  TLSv1_1  TLSv1_2
    // client
    /* SSLTLS  */  { true,    false,   false,   ossl1,   ossl1,   true    },
    /* SSLv2   */  { false,   false,   false,   false,   false,   false   },
    /* SSLv3   */  { false,   false,   true,    false,   false,   false   },
    /* TLSv1_0 */  { ossl1,   false,   false,   ossl1,   false,   false   },
    /* TLSv1_1 */  { ossl1,   false,   false,   false,   ossl1,   false   },
    /* TLSv1_2 */  { true,    false,   false,   false,   false,   true    }
        };

    for (size_t si = 0; si <= apache::thrift::transport::LATEST; ++si) {
      for (size_t ci = 0; ci <= apache::thrift::transport::LATEST; ++ci) {
        if (si == 1 || ci == 1) {
          // Skip all SSLv2 cases - protocol not supported
          continue;
        }

#ifdef OPENSSL_NO_SSL3
        if (si == 2 || ci == 2) {
          // Skip all SSLv3 cases - protocol not supported
          continue;
        }
#endif

        boost::mutex::scoped_lock lock(mMutex);

        BOOST_TEST_MESSAGE(boost::format("TEST: Server = %1%, Client = %2%") % protocol2str(si)
                           % protocol2str(ci));

        mConnected = false;
        // thread_group manages the thread lifetime - ignore the return value of create_thread
        boost::thread_group threads;
        (void)threads.create_thread(bind(&SecurityFromBufferFixture::server, this,
                                         static_cast<apache::thrift::transport::SSLProtocol>(si)));
        mCVar.wait(lock); // wait for listen() to succeed
        lock.unlock();
        (void)threads.create_thread(bind(&SecurityFromBufferFixture::client, this,
                                         static_cast<apache::thrift::transport::SSLProtocol>(ci)));
        threads.join_all();

        BOOST_CHECK_MESSAGE(mConnected == matrix[ci][si],
            boost::format("      Server = %1%, Client = %2% expected mConnected == %3% but was %4%")
                % protocol2str(si) % protocol2str(ci) % matrix[ci][si] % mConnected);
      }
    }
  } catch (std::exception& ex) {
    BOOST_FAIL(boost::format("%1%: %2%") % typeid(ex).name() % ex.what());
  }
}

BOOST_AUTO_TEST_SUITE_END()
