Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "pk11func.h"
6 #include "mozilla/DebugOnly.h"
7 #include "mozilla/RefPtr.h"
8 #include "nsCOMPtr.h"
9 #include "PSMRunnable.h"
10 #include "nsString.h"
11 #include "nsReadableUtils.h"
12 #include "nsPKCS11Slot.h"
13 #include "nsProtectedAuthThread.h"
15 using namespace mozilla;
16 using namespace mozilla::psm;
18 NS_IMPL_ISUPPORTS(nsProtectedAuthThread, nsIProtectedAuthThread)
20 static void nsProtectedAuthThreadRunner(void *arg)
21 {
22 PR_SetCurrentThreadName("Protected Auth");
24 nsProtectedAuthThread *self = static_cast<nsProtectedAuthThread *>(arg);
25 self->Run();
26 }
28 nsProtectedAuthThread::nsProtectedAuthThread()
29 : mMutex("nsProtectedAuthThread.mMutex")
30 , mIAmRunning(false)
31 , mLoginReady(false)
32 , mThreadHandle(nullptr)
33 , mSlot(0)
34 , mLoginResult(SECFailure)
35 {
36 NS_INIT_ISUPPORTS();
37 }
39 nsProtectedAuthThread::~nsProtectedAuthThread()
40 {
41 }
43 NS_IMETHODIMP nsProtectedAuthThread::Login(nsIObserver *aObserver)
44 {
45 NS_ENSURE_ARG(aObserver);
47 if (!mSlot)
48 // We need pointer to the slot
49 return NS_ERROR_FAILURE;
51 MutexAutoLock lock(mMutex);
53 if (mIAmRunning || mLoginReady) {
54 return NS_OK;
55 }
57 if (aObserver) {
58 // We must AddRef aObserver here on the main thread, because it probably
59 // does not implement a thread-safe AddRef.
60 mNotifyObserver = new NotifyObserverRunnable(aObserver,
61 "operation-completed");
62 }
64 mIAmRunning = true;
66 mThreadHandle = PR_CreateThread(PR_USER_THREAD, nsProtectedAuthThreadRunner, static_cast<void*>(this),
67 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
69 // bool thread_started_ok = (threadHandle != nullptr);
70 // we might want to return "thread started ok" to caller in the future
71 NS_ASSERTION(mThreadHandle, "Could not create nsProtectedAuthThreadRunner thread\n");
73 return NS_OK;
74 }
76 NS_IMETHODIMP nsProtectedAuthThread::GetTokenName(nsAString &_retval)
77 {
78 MutexAutoLock lock(mMutex);
80 // Get token name
81 CopyUTF8toUTF16(nsDependentCString(PK11_GetTokenName(mSlot)), _retval);
83 return NS_OK;
84 }
86 NS_IMETHODIMP nsProtectedAuthThread::GetSlot(nsIPKCS11Slot **_retval)
87 {
88 RefPtr<nsPKCS11Slot> slot;
89 {
90 MutexAutoLock lock(mMutex);
91 slot = new nsPKCS11Slot(mSlot);
92 }
94 return CallQueryInterface (slot.get(), _retval);
95 }
97 void nsProtectedAuthThread::SetParams(PK11SlotInfo* aSlot)
98 {
99 MutexAutoLock lock(mMutex);
101 mSlot = (aSlot) ? PK11_ReferenceSlot(aSlot) : 0;
102 }
104 SECStatus nsProtectedAuthThread::GetResult()
105 {
106 return mLoginResult;
107 }
109 void nsProtectedAuthThread::Run(void)
110 {
111 // Login with null password. This call will also do C_Logout() but
112 // it is harmless here
113 mLoginResult = PK11_CheckUserPassword(mSlot, 0);
115 nsCOMPtr<nsIRunnable> notifyObserver;
116 {
117 MutexAutoLock lock(mMutex);
119 mLoginReady = true;
120 mIAmRunning = false;
122 // Forget the slot
123 if (mSlot)
124 {
125 PK11_FreeSlot(mSlot);
126 mSlot = 0;
127 }
129 notifyObserver.swap(mNotifyObserver);
130 }
132 if (notifyObserver) {
133 DebugOnly<nsresult> rv = NS_DispatchToMainThread(notifyObserver);
134 NS_ASSERTION(NS_SUCCEEDED(rv),
135 "failed to dispatch protected auth observer to main thread");
136 }
137 }
139 void nsProtectedAuthThread::Join()
140 {
141 if (!mThreadHandle)
142 return;
144 PR_JoinThread(mThreadHandle);
145 mThreadHandle = nullptr;
146 }