- auto length = int(userPassword.size());
- if (length > size) {
- length = size;
- }
- strncpy(password, userPassword.c_str(), size_t(length));
- return length;
-}
-
-struct SSLLock {
- explicit SSLLock(
- SSLContext::SSLLockType inLockType = SSLContext::LOCK_MUTEX) :
- lockType(inLockType) {
- }
-
- void lock() {
- if (lockType == SSLContext::LOCK_MUTEX) {
- mutex.lock();
- } else if (lockType == SSLContext::LOCK_SPINLOCK) {
- spinLock.lock();
- }
- // lockType == LOCK_NONE, no-op
- }
-
- void unlock() {
- if (lockType == SSLContext::LOCK_MUTEX) {
- mutex.unlock();
- } else if (lockType == SSLContext::LOCK_SPINLOCK) {
- spinLock.unlock();
- }
- // lockType == LOCK_NONE, no-op
- }
-
- SSLContext::SSLLockType lockType;
- folly::SpinLock spinLock{};
- std::mutex mutex;
-};
-
-// Statics are unsafe in environments that call exit().
-// If one thread calls exit() while another thread is
-// references a member of SSLContext, bad things can happen.
-// SSLContext runs in such environments.
-// Instead of declaring a static member we "new" the static
-// member so that it won't be destructed on exit().
-static std::unique_ptr<SSLLock[]>& locks() {
- static auto locksInst = new std::unique_ptr<SSLLock[]>();
- return *locksInst;
-}
-
-static std::map<int, SSLContext::SSLLockType>& lockTypes() {
- static auto lockTypesInst = new std::map<int, SSLContext::SSLLockType>();
- return *lockTypesInst;
-}
-
-static void callbackLocking(int mode, int n, const char*, int) {
- if (mode & CRYPTO_LOCK) {
- locks()[size_t(n)].lock();
- } else {
- locks()[size_t(n)].unlock();
- }
-}
-
-static unsigned long callbackThreadID() {
- return static_cast<unsigned long>(folly::getCurrentThreadID());
-}
-
-static CRYPTO_dynlock_value* dyn_create(const char*, int) {
- return new CRYPTO_dynlock_value;
-}
-
-static void dyn_lock(int mode,
- struct CRYPTO_dynlock_value* lock,
- const char*, int) {
- if (lock != nullptr) {
- if (mode & CRYPTO_LOCK) {
- lock->mutex.lock();
- } else {
- lock->mutex.unlock();
- }
- }
-}
-
-static void dyn_destroy(struct CRYPTO_dynlock_value* lock, const char*, int) {
- delete lock;
-}
-
-void SSLContext::setSSLLockTypes(std::map<int, SSLLockType> inLockTypes) {
- if (initialized_) {
- // We set the locks on initialization, so if we are already initialized
- // this would have no affect.
- LOG(INFO) << "Ignoring setSSLLockTypes after initialization";
- return;
- }
-
- lockTypes() = inLockTypes;
-}
-
-bool SSLContext::isSSLLockDisabled(int lockId) {
- const auto& sslLocks = lockTypes();
- const auto it = sslLocks.find(lockId);
- return it != sslLocks.end() &&
- it->second == SSLContext::SSLLockType::LOCK_NONE;