1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Defines the CookieAccountant class, which is responsible for observing
// and recording all cookie-related information generated by a particular
// IE browser session. It records and fires cookie change events, it provides
// access to session and persistent cookies.
#ifndef CEEE_IE_PLUGIN_BHO_COOKIE_ACCOUNTANT_H_
#define CEEE_IE_PLUGIN_BHO_COOKIE_ACCOUNTANT_H_
#include <string>
#include "app/win/iat_patch_function.h"
#include "base/lock.h"
#include "base/singleton.h"
#include "base/time.h"
#include "ceee/ie/plugin/bho/cookie_events_funnel.h"
#include "net/base/cookie_monster.h"
// The class that accounts for all cookie-related activity for a single IE
// browser session context. There should only need to be one of these allocated
// per process; use ProductionCookieAccountant instead of using this class
// directly.
class CookieAccountant {
public:
// Patch cookie-related functions to observe IE session cookies.
void PatchWininetFunctions();
// Record Set-Cookie changes coming from the HTTP response headers.
void RecordHttpResponseCookies(
const std::string& response_headers, const base::Time& current_time);
// An accessor for the singleton (useful for unit testing).
static CookieAccountant* GetInstance();
// InternetSetCookieExA function patch implementation for recording scripted
// cookie changes.
static DWORD WINAPI InternetSetCookieExAPatch(
LPCSTR lpszURL, LPCSTR lpszCookieName, LPCSTR lpszCookieData,
DWORD dwFlags, DWORD_PTR dwReserved);
// InternetSetCookieExW function patch implementation for recording scripted
// cookie changes.
static DWORD WINAPI InternetSetCookieExWPatch(
LPCWSTR lpszURL, LPCWSTR lpszCookieName, LPCWSTR lpszCookieData,
DWORD dwFlags, DWORD_PTR dwReserved);
protected:
// Exposed to subclasses mainly for unit testing purposes; production code
// should use the ProductionCookieAccountant class instead.
// Since this class has one instance per window, not per tab, we cannot
// queue the events sent to the broker. They don't need to be sent to the BHO
// because they don't need tab_id anyway.
CookieAccountant()
: broker_rpc_client_(true),
cookie_events_funnel_(&broker_rpc_client_),
patching_wininet_functions_(false) {
HRESULT hr = broker_rpc_client_.Connect(true);
DCHECK(SUCCEEDED(hr));
}
virtual ~CookieAccountant();
// Records the modification or creation of a cookie. Fires off a
// cookies.onChanged event to Chrome Frame.
virtual void RecordCookie(
const std::string& url, const std::string& cookie_data,
const base::Time& current_time);
// Unit test seam.
virtual CookieEventsFunnel& cookie_events_funnel() {
return cookie_events_funnel_;
}
// Function patches that allow us to intercept scripted cookie changes.
app::win::IATPatchFunction internet_set_cookie_ex_a_patch_;
app::win::IATPatchFunction internet_set_cookie_ex_w_patch_;
// Used to allow exactly one thread to attempt to apply function patches.
// We use this boolean instead of a simple lock so that threads that lose
// the race will return immediately instead of blocking on the lock.
// Protected by CookieAccountant::lock_.
bool patching_wininet_functions_;
// A lock that protects access to the function patches.
Lock lock_;
// Cached singleton instance. Useful for unit testing.
static CookieAccountant* singleton_instance_;
private:
// Helper functions for extracting cookie information from a scripted cookie
// being set, to pass to the cookie onChanged event.
// Sets the cookie domain for a script cookie event.
void SetScriptCookieDomain(
const net::CookieMonster::ParsedCookie& parsed_cookie,
cookie_api::CookieInfo* cookie);
// Sets the cookie path for a script cookie event.
void SetScriptCookiePath(
const net::CookieMonster::ParsedCookie& parsed_cookie,
cookie_api::CookieInfo* cookie);
// Sets the cookie expiration date for a script cookie event.
void SetScriptCookieExpirationDate(
const net::CookieMonster::ParsedCookie& parsed_cookie,
const base::Time& current_time,
cookie_api::CookieInfo* cookie);
// Sets the cookie store ID for a script cookie event.
void SetScriptCookieStoreId(cookie_api::CookieInfo* cookie);
// Broker RPC client.
BrokerRpcClient broker_rpc_client_;
// The funnel for sending cookie events to the broker.
CookieEventsFunnel cookie_events_funnel_;
DISALLOW_COPY_AND_ASSIGN(CookieAccountant);
};
// A singleton that initializes and keeps the CookieAccountant used by
// production code. This class is separate so that CookieAccountant can still
// be accessed for unit testing.
class ProductionCookieAccountant : public CookieAccountant {
public:
static ProductionCookieAccountant* GetInstance();
private:
// This ensures no construction is possible outside of the class itself.
friend struct DefaultSingletonTraits<ProductionCookieAccountant>;
DISALLOW_IMPLICIT_CONSTRUCTORS(ProductionCookieAccountant);
};
#endif // CEEE_IE_PLUGIN_BHO_COOKIE_ACCOUNTANT_H_
|