Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/security/manager/ssl/nsProtectedAuthThread.cpp
Line
Count
Source (jump to first uncovered line)
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/. */
4
5
#include "PSMRunnable.h"
6
#include "mozilla/Assertions.h"
7
#include "mozilla/DebugOnly.h"
8
#include "mozilla/RefPtr.h"
9
#include "nsCOMPtr.h"
10
#include "GeckoProfiler.h"
11
#include "nsPKCS11Slot.h"
12
#include "nsProtectedAuthThread.h"
13
#include "nsReadableUtils.h"
14
#include "nsString.h"
15
#include "nsThreadUtils.h"
16
#include "pk11func.h"
17
18
using namespace mozilla;
19
using namespace mozilla::psm;
20
21
NS_IMPL_ISUPPORTS(nsProtectedAuthThread, nsIProtectedAuthThread)
22
23
static void nsProtectedAuthThreadRunner(void *arg)
24
0
{
25
0
    AUTO_PROFILER_REGISTER_THREAD("Protected Auth");
26
0
    NS_SetCurrentThreadName("Protected Auth");
27
0
28
0
    nsProtectedAuthThread *self = static_cast<nsProtectedAuthThread *>(arg);
29
0
    self->Run();
30
0
}
31
32
nsProtectedAuthThread::nsProtectedAuthThread()
33
: mMutex("nsProtectedAuthThread.mMutex")
34
, mIAmRunning(false)
35
, mLoginReady(false)
36
, mThreadHandle(nullptr)
37
, mSlot(0)
38
, mLoginResult(SECFailure)
39
0
{
40
0
}
41
42
nsProtectedAuthThread::~nsProtectedAuthThread()
43
0
{
44
0
}
45
46
NS_IMETHODIMP nsProtectedAuthThread::Login(nsIObserver *aObserver)
47
0
{
48
0
    NS_ENSURE_ARG(aObserver);
49
0
50
0
    if (!mSlot)
51
0
        // We need pointer to the slot
52
0
        return NS_ERROR_FAILURE;
53
0
54
0
    MutexAutoLock lock(mMutex);
55
0
56
0
    if (mIAmRunning || mLoginReady) {
57
0
        return NS_OK;
58
0
    }
59
0
60
0
    if (aObserver) {
61
0
      // We must AddRef aObserver here on the main thread, because it probably
62
0
      // does not implement a thread-safe AddRef.
63
0
      mNotifyObserver = new NotifyObserverRunnable(aObserver,
64
0
                                                   "operation-completed");
65
0
    }
66
0
67
0
    mIAmRunning = true;
68
0
69
0
    mThreadHandle = PR_CreateThread(PR_USER_THREAD, nsProtectedAuthThreadRunner, static_cast<void*>(this),
70
0
        PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
71
0
72
0
    // bool thread_started_ok = (threadHandle != nullptr);
73
0
    // we might want to return "thread started ok" to caller in the future
74
0
    MOZ_ASSERT(mThreadHandle,
75
0
               "Could not create nsProtectedAuthThreadRunner thread");
76
0
    return NS_OK;
77
0
}
78
79
NS_IMETHODIMP nsProtectedAuthThread::GetTokenName(nsAString &_retval)
80
0
{
81
0
    MutexAutoLock lock(mMutex);
82
0
83
0
    // Get token name
84
0
    CopyUTF8toUTF16(nsDependentCString(PK11_GetTokenName(mSlot)), _retval);
85
0
86
0
    return NS_OK;
87
0
}
88
89
NS_IMETHODIMP nsProtectedAuthThread::GetSlot(nsIPKCS11Slot **_retval)
90
0
{
91
0
    RefPtr<nsPKCS11Slot> slot;
92
0
    {
93
0
        MutexAutoLock lock(mMutex);
94
0
        slot = new nsPKCS11Slot(mSlot);
95
0
    }
96
0
97
0
    slot.forget(_retval);
98
0
    return NS_OK;
99
0
}
100
101
void nsProtectedAuthThread::SetParams(PK11SlotInfo* aSlot)
102
0
{
103
0
    MutexAutoLock lock(mMutex);
104
0
105
0
    mSlot = (aSlot) ? PK11_ReferenceSlot(aSlot) : 0;
106
0
}
107
108
SECStatus nsProtectedAuthThread::GetResult()
109
0
{
110
0
    return mLoginResult;
111
0
}
112
113
void nsProtectedAuthThread::Run(void)
114
0
{
115
0
    // Login with null password. This call will also do C_Logout() but
116
0
    // it is harmless here
117
0
    mLoginResult = PK11_CheckUserPassword(mSlot, 0);
118
0
119
0
    nsCOMPtr<nsIRunnable> notifyObserver;
120
0
    {
121
0
        MutexAutoLock lock(mMutex);
122
0
123
0
        mLoginReady = true;
124
0
        mIAmRunning = false;
125
0
126
0
        // Forget the slot
127
0
        if (mSlot)
128
0
        {
129
0
            PK11_FreeSlot(mSlot);
130
0
            mSlot = 0;
131
0
        }
132
0
133
0
        notifyObserver.swap(mNotifyObserver);
134
0
    }
135
0
136
0
    if (notifyObserver) {
137
0
        DebugOnly<nsresult> rv = NS_DispatchToMainThread(notifyObserver);
138
0
  MOZ_ASSERT(NS_SUCCEEDED(rv),
139
0
       "Failed to dispatch protected auth observer to main thread");
140
0
    }
141
0
}
142
143
void nsProtectedAuthThread::Join()
144
0
{
145
0
    if (!mThreadHandle)
146
0
        return;
147
0
148
0
    PR_JoinThread(mThreadHandle);
149
0
    mThreadHandle = nullptr;
150
0
}