Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(232)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java

Issue 1894213003: android: Fix CanonicalCookie same_site field (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: visibility Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.cookies; 5 package org.chromium.chrome.browser.cookies;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.os.AsyncTask; 8 import android.os.AsyncTask;
9 9
10 import org.chromium.base.ImportantFileWriterAndroid; 10 import org.chromium.base.ImportantFileWriterAndroid;
11 import org.chromium.base.Log; 11 import org.chromium.base.Log;
12 import org.chromium.base.ThreadUtils; 12 import org.chromium.base.ThreadUtils;
13 import org.chromium.base.annotations.CalledByNative; 13 import org.chromium.base.annotations.CalledByNative;
14 import org.chromium.chrome.browser.profiles.Profile; 14 import org.chromium.chrome.browser.profiles.Profile;
15 import org.chromium.content.browser.crypto.CipherFactory; 15 import org.chromium.content.browser.crypto.CipherFactory;
16 import org.chromium.content.common.CleanupReference; 16 import org.chromium.content.common.CleanupReference;
17 17
18 import java.io.ByteArrayOutputStream;
19 import java.io.DataInputStream;
20 import java.io.DataOutputStream;
21 import java.io.EOFException;
22 import java.io.File; 18 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.IOException; 19 import java.io.IOException;
25 import java.util.ArrayList; 20 import java.util.ArrayList;
26 import java.util.List; 21 import java.util.List;
27 22
28 import javax.crypto.Cipher; 23 import javax.crypto.Cipher;
29 import javax.crypto.CipherInputStream;
30 import javax.crypto.CipherOutputStream;
31 24
32 /** 25 /**
33 * Responsible for fetching, (de)serializing, and restoring cookies between the CookieJar and an 26 * Responsible for fetching, (de)serializing, and restoring cookies between the CookieJar and an
34 * encrypted file storage. 27 * encrypted file storage.
35 */ 28 */
36 public class CookiesFetcher { 29 public class CookiesFetcher {
37 /** The default file name for the encrypted cookies storage. */ 30 /** The default file name for the encrypted cookies storage. */
38 private static final String DEFAULT_COOKIE_FILE_NAME = "COOKIES.DAT"; 31 private static final String DEFAULT_COOKIE_FILE_NAME = "COOKIES.DAT";
39 32
40 /** Used for logging. */ 33 /** Used for logging. */
41 private static final String TAG = "CookiesFetcher"; 34 private static final String TAG = "CookiesFetcher";
42 35
43 /**
44 * Used to confirm that the current cipher key matches the previously used c ipher key when
45 * restoring data. If this value cannot be read from the file, the file is likely garbage.
46 * TODO(acleung): May be use real cryptographic integrity checks on the whol e file, instead.
47 */
48 private static final String MAGIC_STRING = "c0Ok135";
49
50 /** Native-side pointer. */ 36 /** Native-side pointer. */
51 private final long mNativeCookiesFetcher; 37 private final long mNativeCookiesFetcher;
52 38
53 private final CleanupReference mCleanupReference; 39 private final CleanupReference mCleanupReference;
54 40
55 private final Context mContext; 41 private final Context mContext;
56 42
57 /** 43 /**
58 * Creates a new fetcher that can use to fetch cookies from cookie jar 44 * Creates a new fetcher that can use to fetch cookies from cookie jar
59 * or from a file. 45 * or from a file.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 } catch (RuntimeException e) { 98 } catch (RuntimeException e) {
113 e.printStackTrace(); 99 e.printStackTrace();
114 } 100 }
115 } 101 }
116 102
117 private static void restoreCookiesInternal(final Context context) { 103 private static void restoreCookiesInternal(final Context context) {
118 new AsyncTask<Void, Void, List<CanonicalCookie>>() { 104 new AsyncTask<Void, Void, List<CanonicalCookie>>() {
119 @Override 105 @Override
120 protected List<CanonicalCookie> doInBackground(Void... voids) { 106 protected List<CanonicalCookie> doInBackground(Void... voids) {
121 // Read cookies from disk on a background thread to avoid strict mode violations. 107 // Read cookies from disk on a background thread to avoid strict mode violations.
122 ArrayList<CanonicalCookie> cookies = new ArrayList<CanonicalCook ie>(); 108 List<CanonicalCookie> cookies = new ArrayList<CanonicalCookie>() ;
123 DataInputStream in = null;
124 try { 109 try {
125 Cipher cipher = CipherFactory.getInstance().getCipher(Cipher .DECRYPT_MODE); 110 Cipher cipher = CipherFactory.getInstance().getCipher(Cipher .DECRYPT_MODE);
126 if (cipher == null) { 111 if (cipher == null) {
127 // Something is wrong. Can't encrypt, don't restore cook ies. 112 // Something is wrong. Can't encrypt, don't restore cook ies.
128 return cookies; 113 return cookies;
129 } 114 }
115
130 File fileIn = new File(fetchFileName(context)); 116 File fileIn = new File(fetchFileName(context));
131 if (!fileIn.exists()) return cookies; // Nothing to read 117 if (!fileIn.exists()) return cookies; // Nothing to read
132 118 cookies = CanonicalCookie.readFromFileUnknownFormat(fileIn, cipher);
133 FileInputStream streamIn = new FileInputStream(fileIn);
134 in = new DataInputStream(new CipherInputStream(streamIn, cip her));
135 String check = in.readUTF();
136 if (!MAGIC_STRING.equals(check)) {
137 // Stale cookie file. Chrome might have crashed before i t
138 // can delete the old file.
139 return cookies;
140 }
141 try {
142 while (true) {
143 CanonicalCookie cookie = CanonicalCookie.createFromS tream(in);
144 cookies.add(cookie);
145 }
146 } catch (EOFException ignored) {
147 // We are done.
148 }
149 119
150 // The Cookie File should not be restored again. It'll be ov erwritten 120 // The Cookie File should not be restored again. It'll be ov erwritten
151 // on the next onPause. 121 // on the next onPause.
152 scheduleDeleteCookiesFile(context); 122 scheduleDeleteCookiesFile(context);
153 123
154 } catch (IOException e) { 124 } catch (IOException e) {
155 Log.w(TAG, "IOException during Cookie Restore"); 125 Log.w(TAG, "IOException during Cookie Restore", e);
156 } catch (Throwable t) { 126 } catch (Throwable t) {
157 Log.w(TAG, "Error restoring cookies.", t); 127 Log.w(TAG, "Error restoring cookies.", t);
158 } finally {
159 try {
160 if (in != null) in.close();
161 } catch (IOException e) {
162 Log.w(TAG, "IOException during Cooke Restore");
163 } catch (Throwable t) {
164 Log.w(TAG, "Error restoring cookies.", t);
165 }
166 } 128 }
167 return cookies; 129 return cookies;
168 } 130 }
169 131
170 @Override 132 @Override
171 protected void onPostExecute(List<CanonicalCookie> cookies) { 133 protected void onPostExecute(List<CanonicalCookie> cookies) {
172 // We can only access cookies and profiles on the UI thread. 134 // We can only access cookies and profiles on the UI thread.
173 for (CanonicalCookie cookie : cookies) { 135 for (CanonicalCookie cookie : cookies) {
174 nativeRestoreCookies(cookie.getUrl(), cookie.getName(), cook ie.getValue(), 136 nativeRestoreCookies(cookie.getUrl(), cookie.getName(), cook ie.getValue(),
175 cookie.getDomain(), cookie.getPath(), cookie.getCrea tionDate(), 137 cookie.getDomain(), cookie.getPath(), cookie.getCrea tionDate(),
176 cookie.getExpirationDate(), cookie.getLastAccessDate (), 138 cookie.getExpirationDate(), cookie.getLastAccessDate (),
177 cookie.isSecure(), cookie.isHttpOnly(), cookie.isSam eSite(), 139 cookie.isSecure(), cookie.isHttpOnly(), cookie.getSa meSite(),
178 cookie.getPriority()); 140 cookie.getPriority());
179 } 141 }
180 } 142 }
181 }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); 143 }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
182 } 144 }
183 145
184 /** 146 /**
185 * Ensure the incognito cookies are deleted when the incognito profile is go ne. 147 * Ensure the incognito cookies are deleted when the incognito profile is go ne.
186 * 148 *
187 * @param context Context for accessing the file system. 149 * @param context Context for accessing the file system.
(...skipping 24 matching lines...) Expand all
212 } 174 }
213 } 175 }
214 return null; 176 return null;
215 } 177 }
216 }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); 178 }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
217 } 179 }
218 180
219 @CalledByNative 181 @CalledByNative
220 private CanonicalCookie createCookie(String url, String name, String value, String domain, 182 private CanonicalCookie createCookie(String url, String name, String value, String domain,
221 String path, long creation, long expiration, long lastAccess, boolea n secure, 183 String path, long creation, long expiration, long lastAccess, boolea n secure,
222 boolean httpOnly, boolean sameSite, int priority) { 184 boolean httpOnly, int sameSite, int priority) {
223 return new CanonicalCookie(url, name, value, domain, path, creation, exp iration, lastAccess, 185 return new CanonicalCookie(url, name, value, domain, path, creation, exp iration, lastAccess,
224 secure, httpOnly, sameSite, priority); 186 secure, httpOnly, sameSite, priority);
225 } 187 }
226 188
227 @CalledByNative 189 @CalledByNative
228 private void onCookieFetchFinished(final CanonicalCookie[] cookies) { 190 private void onCookieFetchFinished(final CanonicalCookie[] cookies) {
229 // Cookies fetching requires operations with the profile and must be 191 // Cookies fetching requires operations with the profile and must be
230 // done in the main thread. Once that is done, do the save to disk 192 // done in the main thread. Once that is done, do the save to disk
231 // part in {@link AsyncTask} to avoid strict mode violations. 193 // part in {@link AsyncTask} to avoid strict mode violations.
232 new AsyncTask<Void, Void, Void>() { 194 new AsyncTask<Void, Void, Void>() {
233 @Override 195 @Override
234 protected Void doInBackground(Void... voids) { 196 protected Void doInBackground(Void... voids) {
235 saveFetchedCookiesToDisk(cookies); 197 saveFetchedCookiesToDisk(cookies);
236 return null; 198 return null;
237 } 199 }
238 }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); 200 }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
239 } 201 }
240 202
241 private void saveFetchedCookiesToDisk(CanonicalCookie[] cookies) { 203 private void saveFetchedCookiesToDisk(CanonicalCookie[] cookies) {
242 DataOutputStream out = null;
243 try { 204 try {
244 Cipher cipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT _MODE); 205 Cipher cipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT _MODE);
245 if (cipher == null) { 206 if (cipher == null) {
246 // Something is wrong. Can't encrypt, don't save cookies. 207 // Something is wrong. Can't encrypt, don't save cookies.
247 return; 208 return;
248 } 209 }
249 210
250 ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
251 CipherOutputStream cipherOut =
252 new CipherOutputStream(byteOut, cipher);
253 out = new DataOutputStream(cipherOut);
254
255 out.writeUTF(MAGIC_STRING);
256 for (CanonicalCookie cookie : cookies) {
257 cookie.saveToStream(out);
258 }
259 out.close();
260 ImportantFileWriterAndroid.writeFileAtomically( 211 ImportantFileWriterAndroid.writeFileAtomically(
261 fetchFileName(mContext), byteOut.toByteArray()); 212 fetchFileName(mContext), CanonicalCookie.writeToByteArray(ci pher, cookies));
262 out = null;
263 } catch (IOException e) { 213 } catch (IOException e) {
264 Log.w(TAG, "IOException during Cookie Fetch"); 214 Log.w(TAG, "IOException during Cookie Fetch");
265 } catch (Throwable t) { 215 } catch (Throwable t) {
266 Log.w(TAG, "Error storing cookies.", t); 216 Log.w(TAG, "Error storing cookies.", t);
267 } finally {
268 try {
269 if (out != null) out.close();
270 } catch (IOException e) {
271 Log.w(TAG, "IOException during Cookie Fetch");
272 }
273 } 217 }
274 } 218 }
275 219
276 private static final class DestroyRunnable implements Runnable { 220 private static final class DestroyRunnable implements Runnable {
277 private final long mNativeCookiesFetcher; 221 private final long mNativeCookiesFetcher;
278 222
279 private DestroyRunnable(long nativeCookiesFetcher) { 223 private DestroyRunnable(long nativeCookiesFetcher) {
280 mNativeCookiesFetcher = nativeCookiesFetcher; 224 mNativeCookiesFetcher = nativeCookiesFetcher;
281 } 225 }
282 226
283 @Override 227 @Override
284 public void run() { 228 public void run() {
285 if (mNativeCookiesFetcher != 0) nativeDestroy(mNativeCookiesFetcher) ; 229 if (mNativeCookiesFetcher != 0) nativeDestroy(mNativeCookiesFetcher) ;
286 } 230 }
287 } 231 }
288 232
289 @CalledByNative 233 @CalledByNative
290 private CanonicalCookie[] createCookiesArray(int size) { 234 private CanonicalCookie[] createCookiesArray(int size) {
291 return new CanonicalCookie[size]; 235 return new CanonicalCookie[size];
292 } 236 }
293 237
294 private native long nativeInit(); 238 private native long nativeInit();
295 private static native void nativeDestroy(long nativeCookiesFetcher); 239 private static native void nativeDestroy(long nativeCookiesFetcher);
296 private native void nativePersistCookies(long nativeCookiesFetcher); 240 private native void nativePersistCookies(long nativeCookiesFetcher);
297 private static native void nativeRestoreCookies(String url, String name, Str ing value, 241 private static native void nativeRestoreCookies(String url, String name, Str ing value,
298 String domain, String path, long creation, long expiration, long las tAccess, 242 String domain, String path, long creation, long expiration, long las tAccess,
299 boolean secure, boolean httpOnly, boolean sameSite, int priority); 243 boolean secure, boolean httpOnly, int sameSite, int priority);
300 } 244 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698