Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef HSTSPrimingListener_h__
8 : #define HSTSPrimingListener_h__
9 :
10 : #include "nsCOMPtr.h"
11 : #include "nsIChannelEventSink.h"
12 : #include "nsIInterfaceRequestor.h"
13 : #include "nsIStreamListener.h"
14 : #include "nsIThreadRetargetableStreamListener.h"
15 : #include "nsITimer.h"
16 :
17 : #include "mozilla/Attributes.h"
18 :
19 : class nsIPrincipal;
20 : class nsINetworkInterceptController;
21 : class nsIHstsPrimingCallback;
22 :
23 : namespace mozilla {
24 : namespace net {
25 :
26 : class HttpChannelParent;
27 : class nsHttpChannel;
28 :
29 : /*
30 : * How often do we send an HSTS priming request (over all requests)
31 : */
32 : enum HSTSPrimingRequest {
33 : // No HSTS priming request. The request is not mixed-content, or we have
34 : // already cached the result before nsMixedContentBlocker::ShouldLoad
35 : eHSTS_PRIMING_NO_REQUEST = 0,
36 : // Sent an HSTS priming request
37 : eHSTS_PRIMING_REQUEST_SENT = 1,
38 : // Channel marked for priming, but already had a cached result
39 : eHSTS_PRIMING_REQUEST_CACHED_HSTS = 2,
40 : // Channel marked for priming, but already had a cached result
41 : eHSTS_PRIMING_REQUEST_CACHED_NO_HSTS = 3,
42 : // An error occured setting up the the priming request channel. If the
43 : // priming channel failed in OnstopRequest, there is no HSTS, or the
44 : // channel is redirected, that is recorded by
45 : // MIXED_CONTENT_HSTS_PRIMING_RESULT.
46 : eHSTS_PRIMING_REQUEST_ERROR = 4,
47 : // The channel had no load info, so is ineligible for priming
48 : eHSTS_PRIMING_REQUEST_NO_LOAD_INFO = 5,
49 : // The request was marked for HSTS priming, but was upgraded by
50 : // NS_ShouldSecureUpgrade before HSTS priming was sent.
51 : eHSTS_PRIMING_REQUEST_ALREADY_UPGRADED = 6,
52 : };
53 :
54 : /*
55 : * How often do we get back an HSTS priming result which upgrades the connection to HTTPS?
56 : */
57 : enum HSTSPrimingResult {
58 : // This site has been seen before and won't be upgraded
59 : eHSTS_PRIMING_CACHED_NO_UPGRADE = 0,
60 : // This site has been seen before and will be upgraded
61 : eHSTS_PRIMING_CACHED_DO_UPGRADE = 1,
62 : // This site has been seen before and will be blocked
63 : eHSTS_PRIMING_CACHED_BLOCK = 2,
64 : // The request was already upgraded, probably through
65 : // upgrade-insecure-requests
66 : eHSTS_PRIMING_ALREADY_UPGRADED = 3,
67 : // HSTS priming is successful and the connection will be upgraded to HTTPS
68 : eHSTS_PRIMING_SUCCEEDED = 4,
69 : // When priming succeeds, but preferences require preservation of the order
70 : // of mixed-content and hsts, and mixed-content blocks the load
71 : eHSTS_PRIMING_SUCCEEDED_BLOCK = 5,
72 : // When priming succeeds, but preferences require preservation of the order
73 : // of mixed-content and hsts, and mixed-content allows the load over http
74 : eHSTS_PRIMING_SUCCEEDED_HTTP = 6,
75 : // HSTS priming failed, and the load is blocked by mixed-content
76 : eHSTS_PRIMING_FAILED_BLOCK = 7,
77 : // HSTS priming failed, and the load is allowed by mixed-content
78 : eHSTS_PRIMING_FAILED_ACCEPT = 8,
79 : // The HSTS Priming request timed out, and the load is blocked by
80 : // mixed-content
81 : eHSTS_PRIMING_TIMEOUT_BLOCK = 9,
82 : // The HSTS Priming request timed out, and the load is allowed by
83 : // mixed-content
84 : eHSTS_PRIMING_TIMEOUT_ACCEPT = 10,
85 : };
86 :
87 : //////////////////////////////////////////////////////////////////////////
88 : // Class used as streamlistener and notification callback when
89 : // doing the HEAD request for an HSTS Priming check. Needs to be an
90 : // nsIStreamListener in order to receive events from AsyncOpen2
91 : class HSTSPrimingListener final : public nsIStreamListener,
92 : public nsIInterfaceRequestor,
93 : public nsITimerCallback
94 : {
95 : public:
96 : explicit HSTSPrimingListener(nsIHstsPrimingCallback* aCallback);
97 :
98 : NS_DECL_ISUPPORTS
99 : NS_DECL_NSISTREAMLISTENER
100 : NS_DECL_NSIREQUESTOBSERVER
101 : NS_DECL_NSIINTERFACEREQUESTOR
102 : NS_DECL_NSITIMERCALLBACK
103 :
104 : private:
105 0 : ~HSTSPrimingListener() {}
106 :
107 : // Only nsHttpChannel can invoke HSTS priming
108 : friend class mozilla::net::nsHttpChannel;
109 :
110 : /**
111 : * Start the HSTS priming request. This will send an anonymous HEAD request to
112 : * the URI aRequestChannel is attempting to load. On success, the new HSTS
113 : * priming channel is allocated in aHSTSPrimingChannel.
114 : *
115 : * @param aRequestChannel the reference channel used to initialze the HSTS
116 : * priming channel
117 : * @param aCallback the callback stored to handle the results of HSTS priming.
118 : * @param aHSTSPrimingChannel if the new HSTS priming channel is allocated
119 : * successfully, it will be placed here.
120 : */
121 : static nsresult StartHSTSPriming(nsIChannel* aRequestChannel,
122 : nsIHstsPrimingCallback* aCallback);
123 :
124 : /**
125 : * Given a request, return NS_OK if it has resulted in a cached HSTS update.
126 : * We don't need to check for the header as that has already been done for us.
127 : */
128 : nsresult CheckHSTSPrimingRequestStatus(nsIRequest* aRequest);
129 :
130 : // send telemetry about how long HSTS priming requests take
131 : void ReportTiming(nsIHstsPrimingCallback* aCallback, nsresult aResult);
132 :
133 : /**
134 : * the nsIHttpChannel to notify with the result of HSTS priming.
135 : */
136 : nsCOMPtr<nsIHstsPrimingCallback> mCallback;
137 :
138 : /**
139 : * Keep a handle to the priming channel so we can cancel it on timeout
140 : */
141 : nsCOMPtr<nsIChannel> mPrimingChannel;
142 :
143 : /**
144 : * Keep a handle to the timer around so it can be canceled if we don't time
145 : * out.
146 : */
147 : nsCOMPtr<nsITimer> mHSTSPrimingTimer;
148 :
149 : /**
150 : * How long (in ms) before an HSTS Priming channel times out.
151 : * Preference: security.mixed_content.hsts_priming_request_timeout
152 : */
153 : static uint32_t sHSTSPrimingTimeout;
154 : };
155 :
156 :
157 : }} // mozilla::net
158 :
159 : #endif // HSTSPrimingListener_h__
|