1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/manager/ssl/src/nsProtectedAuthThread.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,146 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "pk11func.h" 1.9 +#include "mozilla/DebugOnly.h" 1.10 +#include "mozilla/RefPtr.h" 1.11 +#include "nsCOMPtr.h" 1.12 +#include "PSMRunnable.h" 1.13 +#include "nsString.h" 1.14 +#include "nsReadableUtils.h" 1.15 +#include "nsPKCS11Slot.h" 1.16 +#include "nsProtectedAuthThread.h" 1.17 + 1.18 +using namespace mozilla; 1.19 +using namespace mozilla::psm; 1.20 + 1.21 +NS_IMPL_ISUPPORTS(nsProtectedAuthThread, nsIProtectedAuthThread) 1.22 + 1.23 +static void nsProtectedAuthThreadRunner(void *arg) 1.24 +{ 1.25 + PR_SetCurrentThreadName("Protected Auth"); 1.26 + 1.27 + nsProtectedAuthThread *self = static_cast<nsProtectedAuthThread *>(arg); 1.28 + self->Run(); 1.29 +} 1.30 + 1.31 +nsProtectedAuthThread::nsProtectedAuthThread() 1.32 +: mMutex("nsProtectedAuthThread.mMutex") 1.33 +, mIAmRunning(false) 1.34 +, mLoginReady(false) 1.35 +, mThreadHandle(nullptr) 1.36 +, mSlot(0) 1.37 +, mLoginResult(SECFailure) 1.38 +{ 1.39 + NS_INIT_ISUPPORTS(); 1.40 +} 1.41 + 1.42 +nsProtectedAuthThread::~nsProtectedAuthThread() 1.43 +{ 1.44 +} 1.45 + 1.46 +NS_IMETHODIMP nsProtectedAuthThread::Login(nsIObserver *aObserver) 1.47 +{ 1.48 + NS_ENSURE_ARG(aObserver); 1.49 + 1.50 + if (!mSlot) 1.51 + // We need pointer to the slot 1.52 + return NS_ERROR_FAILURE; 1.53 + 1.54 + MutexAutoLock lock(mMutex); 1.55 + 1.56 + if (mIAmRunning || mLoginReady) { 1.57 + return NS_OK; 1.58 + } 1.59 + 1.60 + if (aObserver) { 1.61 + // We must AddRef aObserver here on the main thread, because it probably 1.62 + // does not implement a thread-safe AddRef. 1.63 + mNotifyObserver = new NotifyObserverRunnable(aObserver, 1.64 + "operation-completed"); 1.65 + } 1.66 + 1.67 + mIAmRunning = true; 1.68 + 1.69 + mThreadHandle = PR_CreateThread(PR_USER_THREAD, nsProtectedAuthThreadRunner, static_cast<void*>(this), 1.70 + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); 1.71 + 1.72 + // bool thread_started_ok = (threadHandle != nullptr); 1.73 + // we might want to return "thread started ok" to caller in the future 1.74 + NS_ASSERTION(mThreadHandle, "Could not create nsProtectedAuthThreadRunner thread\n"); 1.75 + 1.76 + return NS_OK; 1.77 +} 1.78 + 1.79 +NS_IMETHODIMP nsProtectedAuthThread::GetTokenName(nsAString &_retval) 1.80 +{ 1.81 + MutexAutoLock lock(mMutex); 1.82 + 1.83 + // Get token name 1.84 + CopyUTF8toUTF16(nsDependentCString(PK11_GetTokenName(mSlot)), _retval); 1.85 + 1.86 + return NS_OK; 1.87 +} 1.88 + 1.89 +NS_IMETHODIMP nsProtectedAuthThread::GetSlot(nsIPKCS11Slot **_retval) 1.90 +{ 1.91 + RefPtr<nsPKCS11Slot> slot; 1.92 + { 1.93 + MutexAutoLock lock(mMutex); 1.94 + slot = new nsPKCS11Slot(mSlot); 1.95 + } 1.96 + 1.97 + return CallQueryInterface (slot.get(), _retval); 1.98 +} 1.99 + 1.100 +void nsProtectedAuthThread::SetParams(PK11SlotInfo* aSlot) 1.101 +{ 1.102 + MutexAutoLock lock(mMutex); 1.103 + 1.104 + mSlot = (aSlot) ? PK11_ReferenceSlot(aSlot) : 0; 1.105 +} 1.106 + 1.107 +SECStatus nsProtectedAuthThread::GetResult() 1.108 +{ 1.109 + return mLoginResult; 1.110 +} 1.111 + 1.112 +void nsProtectedAuthThread::Run(void) 1.113 +{ 1.114 + // Login with null password. This call will also do C_Logout() but 1.115 + // it is harmless here 1.116 + mLoginResult = PK11_CheckUserPassword(mSlot, 0); 1.117 + 1.118 + nsCOMPtr<nsIRunnable> notifyObserver; 1.119 + { 1.120 + MutexAutoLock lock(mMutex); 1.121 + 1.122 + mLoginReady = true; 1.123 + mIAmRunning = false; 1.124 + 1.125 + // Forget the slot 1.126 + if (mSlot) 1.127 + { 1.128 + PK11_FreeSlot(mSlot); 1.129 + mSlot = 0; 1.130 + } 1.131 + 1.132 + notifyObserver.swap(mNotifyObserver); 1.133 + } 1.134 + 1.135 + if (notifyObserver) { 1.136 + DebugOnly<nsresult> rv = NS_DispatchToMainThread(notifyObserver); 1.137 + NS_ASSERTION(NS_SUCCEEDED(rv), 1.138 + "failed to dispatch protected auth observer to main thread"); 1.139 + } 1.140 +} 1.141 + 1.142 +void nsProtectedAuthThread::Join() 1.143 +{ 1.144 + if (!mThreadHandle) 1.145 + return; 1.146 + 1.147 + PR_JoinThread(mThreadHandle); 1.148 + mThreadHandle = nullptr; 1.149 +}