1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsSecureBrowserUI.h"
8 #include "mozilla/Assertions.h"
9 #include "mozilla/Logging.h"
10 #include "mozilla/Unused.h"
11 #include "mozilla/dom/Document.h"
12 #include "nsContentUtils.h"
13 #include "nsIChannel.h"
14 #include "nsDocShell.h"
15 #include "nsIDocShellTreeItem.h"
16 #include "nsIInterfaceRequestorUtils.h"
17 #include "nsITransportSecurityInfo.h"
18 #include "nsIWebProgress.h"
19 #include "nsNetUtil.h"
20 #include "mozilla/dom/CanonicalBrowsingContext.h"
21 #include "mozilla/dom/WindowGlobalParent.h"
22 #include "mozilla/dom/Element.h"
23 #include "nsIBrowser.h"
25 using namespace mozilla
;
26 using namespace mozilla::dom
;
28 LazyLogModule
gSecureBrowserUILog("nsSecureBrowserUI");
30 nsSecureBrowserUI::nsSecureBrowserUI(CanonicalBrowsingContext
* aBrowsingContext
)
32 MOZ_ASSERT(NS_IsMainThread());
34 // The BrowsingContext will own the SecureBrowserUI object, we keep a weak
36 mBrowsingContextId
= aBrowsingContext
->Id();
39 NS_IMPL_ISUPPORTS(nsSecureBrowserUI
, nsISecureBrowserUI
,
40 nsISupportsWeakReference
)
43 nsSecureBrowserUI::GetState(uint32_t* aState
) {
44 MOZ_ASSERT(NS_IsMainThread());
45 NS_ENSURE_ARG(aState
);
47 MOZ_LOG(gSecureBrowserUILog
, LogLevel::Debug
,
48 ("GetState %p mState: %x", this, mState
));
53 void nsSecureBrowserUI::RecomputeSecurityFlags() {
54 // Our BrowsingContext either has a new WindowGlobalParent, or the
55 // existing one has mutated its security state.
56 // Recompute our security state and fire notifications to listeners
58 RefPtr
<WindowGlobalParent
> win
= GetCurrentWindow();
59 mState
= nsIWebProgressListener::STATE_IS_INSECURE
;
61 // Only https is considered secure (it is possible to have e.g. an http URI
62 // with a channel that has a securityInfo that indicates the connection is
63 // secure - e.g. h2/alt-svc or by visiting an http URI over an https proxy).
64 nsCOMPtr
<nsITransportSecurityInfo
> securityInfo
;
65 if (win
&& win
->GetIsSecure()) {
66 securityInfo
= win
->GetSecurityInfo();
68 MOZ_LOG(gSecureBrowserUILog
, LogLevel::Debug
,
69 (" we have a security info %p", securityInfo
.get()));
71 nsresult rv
= securityInfo
->GetSecurityState(&mState
);
73 // If the security state is STATE_IS_INSECURE, the TLS handshake never
74 // completed. Don't set any further state.
75 if (NS_SUCCEEDED(rv
) &&
76 mState
!= nsIWebProgressListener::STATE_IS_INSECURE
) {
77 MOZ_LOG(gSecureBrowserUILog
, LogLevel::Debug
,
78 (" set mTopLevelSecurityInfo"));
80 rv
= securityInfo
->GetIsExtendedValidation(&isEV
);
81 if (NS_SUCCEEDED(rv
) && isEV
) {
82 MOZ_LOG(gSecureBrowserUILog
, LogLevel::Debug
, (" is EV"));
83 mState
|= nsIWebProgressListener::STATE_IDENTITY_EV_TOPLEVEL
;
89 // Add upgraded-state flags when request has been
90 // upgraded with HTTPS-Only Mode
92 // Check if top-level load has been upgraded
93 uint32_t httpsOnlyStatus
= win
->HttpsOnlyStatus();
94 if (!(httpsOnlyStatus
& nsILoadInfo::HTTPS_ONLY_UNINITIALIZED
) &&
95 !(httpsOnlyStatus
& nsILoadInfo::HTTPS_ONLY_EXEMPT
)) {
96 mState
|= nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADED
;
98 if (httpsOnlyStatus
& nsILoadInfo::HTTPS_ONLY_UPGRADED_HTTPS_FIRST
) {
99 if (win
->GetDocumentURI()->SchemeIs("https")) {
100 mState
|= nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADED_FIRST
;
102 mState
|= nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADE_FAILED
;
105 // Add the secruity flags from the window
106 mState
|= win
->GetSecurityFlags();
109 // If we have loaded mixed content and this is a secure page,
110 // then clear secure flags and add broken instead.
111 static const uint32_t kLoadedMixedContentFlags
=
112 nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT
|
113 nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT
;
114 if (win
&& win
->GetIsSecure() && (mState
& kLoadedMixedContentFlags
)) {
115 // reset state security flag
116 mState
= mState
>> 4 << 4;
117 // set state security flag to broken, since there is mixed content
118 mState
|= nsIWebProgressListener::STATE_IS_BROKEN
;
121 RefPtr
<CanonicalBrowsingContext
> ctx
=
122 CanonicalBrowsingContext::Get(mBrowsingContextId
);
127 if (ctx
->GetDocShell()) {
128 nsDocShell
* nativeDocShell
= nsDocShell::Cast(ctx
->GetDocShell());
129 nativeDocShell
->nsDocLoader::OnSecurityChange(nullptr, mState
);
130 } else if (ctx
->GetWebProgress()) {
131 ctx
->GetWebProgress()->OnSecurityChange(nullptr, nullptr, mState
);
136 nsSecureBrowserUI::GetIsSecureContext(bool* aIsSecureContext
) {
137 MOZ_ASSERT(NS_IsMainThread());
138 NS_ENSURE_ARG(aIsSecureContext
);
140 if (WindowGlobalParent
* parent
= GetCurrentWindow()) {
141 *aIsSecureContext
= parent
->GetIsSecureContext();
143 *aIsSecureContext
= false;
149 nsSecureBrowserUI::GetSecInfo(nsITransportSecurityInfo
** result
) {
150 MOZ_ASSERT(NS_IsMainThread());
151 NS_ENSURE_ARG_POINTER(result
);
153 if (WindowGlobalParent
* parent
= GetCurrentWindow()) {
154 *result
= parent
->GetSecurityInfo();
156 NS_IF_ADDREF(*result
);
161 WindowGlobalParent
* nsSecureBrowserUI::GetCurrentWindow() {
162 RefPtr
<CanonicalBrowsingContext
> ctx
=
163 CanonicalBrowsingContext::Get(mBrowsingContextId
);
167 return ctx
->GetCurrentWindowGlobal();