1// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5module network.mojom;
6
7import "components/content_settings/core/common/content_settings.mojom";
8import "mojo/public/mojom/base/time.mojom";
9import "services/network/public/mojom/site_for_cookies.mojom";
10import "url/mojom/url.mojom";
11
12// Parameters for constructing a cookie manager.
13struct CookieManagerParams {
14  // Whether or not third party cookies should be blocked.
15  bool block_third_party_cookies = false;
16
17  // Content settings for cookies.
18  array<content_settings.mojom.ContentSettingPatternSource> settings;
19
20  // Schemes that unconditionally allow cookies from secure origins.
21  array<string> secure_origin_cookies_allowed_schemes;
22
23  // Schemes that unconditionally allow cookies from the same scheme.
24  array<string> matching_scheme_cookies_allowed_schemes;
25
26  // Schemes that unconditionally allow third party cookies.
27  array<string> third_party_cookies_allowed_schemes;
28
29  // Whether or not to allow cookies for file:// URLs. Can be overridden by
30  // CookieManager.AllowFileSchemeCookies().
31  bool allow_file_scheme_cookies = false;
32
33  // Content settings for which domains are allowed to use legacy cookie
34  // access rules.
35  array<content_settings.mojom.ContentSettingPatternSource>
36      settings_for_legacy_cookie_access;
37
38  // The type of CookieAccessDelegate to pass to the underlying CookieStore.
39  // If these params are not present, CookieManager defaults to using
40  // USE_CONTENT_SETTINGS.
41  CookieAccessDelegateType cookie_access_delegate_type = USE_CONTENT_SETTINGS;
42};
43
44enum CookieAccessDelegateType {
45  // Decides access semantics based on the content settings it was constructed
46  // with.
47  USE_CONTENT_SETTINGS,
48  // Always returns Legacy access semantics.
49  ALWAYS_LEGACY,
50};
51
52enum CookiePriority {
53  LOW,
54  MEDIUM,
55  HIGH
56};
57
58enum CookieSourceScheme {
59  kUnset,
60  kNonSecure,
61  kSecure,
62};
63
64// See https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00
65// and https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis for
66// information about same site cookie restrictions.
67// Keep in sync with net/cookies/cookie_constants.h.
68// Note: Don't renumber, as these values are persisted to a database.
69enum CookieSameSite {
70  UNSPECIFIED = -1,
71  NO_RESTRICTION = 0,
72  LAX_MODE = 1,
73  STRICT_MODE = 2,
74  // Reserved 3 (was EXTENDED_MODE), next number is 4.
75};
76
77enum ContextType {
78  CROSS_SITE,
79  SAME_SITE_LAX_METHOD_UNSAFE,
80  SAME_SITE_LAX,
81  SAME_SITE_STRICT
82};
83
84enum CrossSchemeness {
85  NONE,
86  INSECURE_SECURE,
87  SECURE_INSECURE
88};
89
90// Keep defaults here in sync with net/cookies/cookie_options.h.
91struct CookieSameSiteContext {
92  ContextType context = CROSS_SITE;
93  CrossSchemeness cross_schemeness = NONE;
94};
95
96// What rules to apply when determining whether access to a particular cookie is
97// allowed.
98// Keep in sync with net/cookies/cookie_constants.h.
99enum CookieAccessSemantics {
100  UNKNOWN = -1,
101  NONLEGACY = 0,
102  LEGACY,
103};
104
105// Keep defaults here in sync with net/cookies/cookie_options.cc.
106struct CookieOptions {
107  bool exclude_httponly = true;
108  CookieSameSiteContext same_site_cookie_context;
109  bool update_access_time = true;
110  bool return_excluded_cookies = false;
111};
112
113// See net/cookies/canonical_cookie.{h,cc} for documentation.
114// Keep defaults here in sync with those files.
115struct CanonicalCookie {
116  string name;
117  string value;
118  string domain;
119  string path;
120  mojo_base.mojom.Time creation;
121  mojo_base.mojom.Time expiry;
122  mojo_base.mojom.Time last_access;
123  bool secure = false;
124  bool httponly = false;
125  CookieSameSite site_restrictions = NO_RESTRICTION;
126  CookiePriority priority = MEDIUM;
127  CookieSourceScheme source_scheme = kUnset;
128};
129
130struct CookieInclusionStatus {
131  // Bitfield. Is defined in
132  // net::CanonicalCookie::CookieInclusionStatus::ExclusionReason.
133  uint32 exclusion_reasons;
134  // Bitfield. Is defined in
135  // net::CanonicalCookie::CookieInclusionStatus::WarningReason.
136  uint32 warning_reasons;
137};
138
139struct CookieWithStatus {
140  CanonicalCookie cookie;
141  CookieInclusionStatus status;
142};
143
144struct CookieAndLineWithStatus {
145  CanonicalCookie? cookie;
146  string cookie_string;
147  CookieInclusionStatus status;
148};
149
150// Keep values here in sync with net::CookieChangeCause.
151enum CookieChangeCause {
152  // The cookie was inserted.
153  INSERTED,
154  // The cookie was changed directly by a consumer's action.
155  EXPLICIT,
156  // The cookie was deleted, but no more details are known.
157  UNKNOWN_DELETION,
158  // The cookie was automatically removed due to an insert operation that
159  // overwrote it.
160  OVERWRITE,
161  // The cookie was automatically removed as it expired.
162  EXPIRED,
163  // The cookie was automatically evicted during garbage collection.
164  EVICTED,
165  // The cookie was overwritten with an already-expired expiration date.
166  EXPIRED_OVERWRITE
167};
168
169struct CookieChangeInfo {
170  // The cookie that changed, in its post-change state.
171  CanonicalCookie cookie;
172  // Access semantics of the cookie at the time of the change.
173  CookieAccessSemantics access_semantics;
174  CookieChangeCause cause;
175};
176
177// Session cookies are cookies that expire at the end of the browser session.
178// That is represented in canonical cookies by a null expiry time.
179enum CookieDeletionSessionControl {
180  IGNORE_CONTROL,
181  SESSION_COOKIES,
182  PERSISTENT_COOKIES,
183};
184
185// All existing filters are ANDed together.  I.e. if there is a value for
186// created_after_time and there's a value for including_domains, only cookies
187// in including_domains that have been created after the specified date would be
188// deleted.  A value for session_control of IGNORE_CONTROL is treated the same
189// as optional values not being present for the other filters.
190// If no filters are specified then all cookies will be deleted; this can be
191// thought of as there being a default "match everything" filter which is
192// ANDed in with all other filters.
193//
194// Note that whether a domain matches a cookie or not is somewhat nuanced.  For
195// the purposes of this filter:
196//      * The host/domain cookie distinction is ignored
197//      * A cookies effective domain is considered to be the top level registry
198//        (including private registries) for the domain stored in the cookie
199//        + the next entry down.  So the effective domain for x.y.google.com
200//        would be google.com, and the effective domain for x.google.co.uk would
201//        be google.co.uk.  See the function
202//        net::registry_controlled_domains::GetDomainAndRegistry for more
203//        details.
204//      * If a cookie does not have such a top level domain (e.g. IP address
205//        or private hostname), the domain specified in the cookie (the IP
206//        address or private hostname) is used.
207struct CookieDeletionFilter {
208  // Delete cookies created after a date.
209  mojo_base.mojom.Time? created_after_time;
210
211  // Delete cookies created before a date.
212  mojo_base.mojom.Time? created_before_time;
213
214  // Delete cookies whose domains are not listed.
215  array<string>? excluding_domains;
216
217  // Deletes cookies whose domains are listed.
218  array<string>? including_domains;
219
220  // Delete cookies with a particular name.
221  string? cookie_name;
222
223  // Delete cookies from a particular host.
224  string? host_name;
225
226  // Delete cookies which match the given URL.
227  // See https://tools.ietf.org/html/rfc6265, sections 5.1.{3,4} & 5.2.{5,6}
228  // for matching rules.  In general terms, secure cookies only match
229  // https URLs, the domain must match (the cookie domain must be a suffix
230  // of the URL domain), and the path must match (the cookie path must
231  // be a prefix of the URL path).  So
232  // a cookie with {domain: ".sub.example.com", path: "/path", secure}
233  // would be deleted if the URL passed was
234  // "https://www.sub.example.com/path/path2" but not if it was
235  // "http://www.example.com/x"--in fact, that cookie wouldn't be deleted
236  // if any of the secure/domain/path attributes in the URL were changed.
237  url.mojom.Url? url;
238
239  // Delete session/persistent cookies.
240  CookieDeletionSessionControl session_control = IGNORE_CONTROL;
241};
242
243interface CookieChangeListener {
244  // TODO(rdsmith): Should this be made a batch interface?
245  OnCookieChange(CookieChangeInfo change);
246};
247
248interface CookieRemoteAccessFilter {
249  AllowedAccess(url.mojom.Url url, SiteForCookies site_for_cookies) => (bool allowed);
250};
251
252interface CookieManager {
253  // TODO(rdsmith): Worthwhile specifying a sort order for the getters?
254
255  // Get all the cookies known to the service.
256  // Returned cookie list is sorted first by path length (longest first)
257  // and second by creation time.
258  // TODO(rdsmith): There are consumers that rely on this behavior, but
259  // for this function it doesn't make a lot of sense not to also sort
260  // on origin.  Should the returned cookies also be sorted by origin?
261  GetAllCookies() => (array<CanonicalCookie> cookies);
262
263  // Get all the cookies known to the service.
264  // Returned cookie list is sorted first by path length (longest first)
265  // and second by creation time.
266  // Additionally get a list of the CookieAccessSemantics that applies to each,
267  // if known. The |access_semantics_list| is guaranteed to be the same length
268  // as |cookies|, with each element in |cookies| having the access semantics
269  // which is given by the same index in |access_semantics_list|. If this method
270  // is not implemented in the underlying CookieStore, the returned
271  // |access_semantics_list| will just contain all UNKNOWNs. If it is
272  // supported, the access semantics values will have been determined by
273  // querying the CookieStore's CookieAccessDelegate.
274  GetAllCookiesWithAccessSemantics()
275      => (array<CanonicalCookie> cookies,
276          array<CookieAccessSemantics> access_semantics_list);
277
278  // Get all cookies for the specified URL and cookie options.
279  // Returned cookie list is sorted first by path length (longest first)
280  // and second by creation time. If the |return_excluded_cookies| option is set
281  // in the options, |excluded_cookies| with be a list of cookies that were
282  // blocked from being sent along with the reason each cookie was blocked. By
283  // default, that option is not set and |excluded_cookies| is an empty list.
284  GetCookieList(url.mojom.Url url, CookieOptions cookie_options)
285      => (array<CookieWithStatus> cookies,
286          array<CookieWithStatus> excluded_cookies);
287
288  // Set a cookie.  |source_scheme| is used to check whether existing secure
289  // cookies can be overwritten (secure cookies may be created from a
290  // non-secure source), and whether the scheme is permitted to use cookies in
291  // the first place.  |cookie_options| indicates whether http_only
292  // or SameSite cookies may be overwritten. If a cookie is not permitted to be
293  // set, |status| will indicate why it was blocked. If the cookie is permitted,
294  // |status| will be set to INCLUDE.
295  SetCanonicalCookie(CanonicalCookie cookie, string source_scheme,
296                     CookieOptions cookie_options)
297      => (CookieInclusionStatus status);
298
299  // Delete a cookie. Returns true if a cookie was deleted.
300  DeleteCanonicalCookie(CanonicalCookie cookie) => (bool success);
301
302  // Delete a set of cookies matching the passed filter.
303  // Returns the number of cookies deleted.
304  DeleteCookies(CookieDeletionFilter filter) => (uint32 num_deleted);
305
306  // Subscribes the given listener to changes to a cookie.
307  //
308  // The subscription is canceled by closing the CookieChangeListener's pipe.
309  //
310  // Note that if the caller may be racing with other uses of the cookie store,
311  // it should follow the subscription request with a probe of the relevant
312  // information about the tracked cookie, to make sure that a change to the
313  // cookie did not happen right before the listener was registered.
314  //
315  // If |name| is omitted then changes are returned for all cookies for |url|.
316  //
317  // TODO(rdsmith): Should this have a filter to register for a lot of
318  // notifications at once?  Maybe combine with the deletion filter?
319  // TODO(rdsmith): Describe the performance implications of using this method.
320  // The comments in CookieMonster::AddCallbackForCookie look pretty scary.
321  AddCookieChangeListener(
322      url.mojom.Url url,
323      string? name,
324      pending_remote<CookieChangeListener> listener);
325
326  // Subscribes the given listener to changes to this CookieManager's cookies.
327  //
328  // The subscription is canceled by closing the CookieChangeListener's pipe.
329  //
330  // TODO(rdsmith): Should this have a filter to register for a lot of
331  // notifications at once?  Maybe combine with the deletion filter?
332  AddGlobalChangeListener(
333      pending_remote<CookieChangeListener> notification_pointer);
334
335  // Clone the interface for use somewhere else.  After this call,
336  // requests to the same implementation may be posted to the other side
337  // of the pipe new_interface was configured on.
338  CloneInterface(pending_receiver<CookieManager> new_interface);
339
340  // Flush the backing store (if any) to disk.
341  FlushCookieStore() => ();
342
343  // Configure this CookieManager to allow/disallow setting cookies for file://
344  // URLs. If this is not called, the CookieManager follows
345  // CookieManagerParams.allow_file_scheme_cookies. This should be called before
346  // the first use of the backing store, otherwise this will have no effect on
347  // the CookieManager, returning false to indicate so.
348  AllowFileSchemeCookies(bool allow) => (bool success);
349
350  // Sets content settings for cookies. These are used to determine cookie
351  // access and cookie deletion behavior.
352  SetContentSettings(
353      array<content_settings.mojom.ContentSettingPatternSource> settings);
354
355  SetRemoteFilter(
356      pending_remote<CookieRemoteAccessFilter> remote_access_filter);
357
358  // Instructs the cookie store to not discard session only cookies on shutdown.
359  SetForceKeepSessionState();
360
361  // Enables/Disables blocking of third-party cookies.
362  BlockThirdPartyCookies(bool block);
363
364  // Sets content settings for which domains are allowed to use legacy cookie
365  // access rules.
366  SetContentSettingsForLegacyCookieAccess(
367      array<content_settings.mojom.ContentSettingPatternSource> settings);
368
369  // Sets content settings for which storage access grants exist. Will ack
370  // the caller with a callback when settings have been updated.
371  SetStorageAccessGrantSettings(
372      array<content_settings.mojom.ContentSettingPatternSource> settings) => ();
373};
374