Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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.chromoting; | 5 package org.chromium.chromoting; |
| 6 | 6 |
| 7 import android.annotation.SuppressLint; | |
| 7 import android.app.Activity; | 8 import android.app.Activity; |
| 8 import android.content.ActivityNotFoundException; | 9 import android.content.ActivityNotFoundException; |
| 9 import android.content.ComponentName; | 10 import android.content.ComponentName; |
| 10 import android.content.Intent; | 11 import android.content.Intent; |
| 11 import android.content.pm.PackageManager; | 12 import android.content.pm.PackageManager; |
| 12 import android.net.Uri; | 13 import android.net.Uri; |
| 13 import android.text.TextUtils; | 14 import android.text.TextUtils; |
| 14 import android.util.Base64; | 15 import android.util.Base64; |
| 15 import android.util.Log; | 16 import android.util.Log; |
| 16 | 17 |
| 18 import java.io.FileInputStream; | |
| 19 import java.io.IOException; | |
| 17 import java.security.SecureRandom; | 20 import java.security.SecureRandom; |
| 18 import java.util.ArrayList; | 21 import java.util.ArrayList; |
| 19 | 22 |
| 20 /** | 23 /** |
| 21 * This class is responsible for fetching a third party token from the user usin g the OAuth2 | 24 * This class is responsible for fetching a third party token from the user usin g the OAuth2 |
| 22 * implicit flow. It directs the user to a third party login page located at |t okenUrl|. It relies | 25 * implicit flow. It directs the user to a third party login page located at |t okenUrl|. It relies |
| 23 * on the |ThirdPartyTokenFetcher$OAuthRedirectActivity| to intercept the access token from the | 26 * on the |ThirdPartyTokenFetcher$OAuthRedirectActivity| to intercept the access token from the |
| 24 * redirect at intent://|REDIRECT_URI_PATH|#Intent;...end; upon successful login . | 27 * redirect at intent://|REDIRECT_URI_PATH|#Intent;...end; upon successful login . |
| 25 */ | 28 */ |
| 26 public class ThirdPartyTokenFetcher { | 29 public class ThirdPartyTokenFetcher { |
| 27 /** Callback for receiving the token. */ | 30 /** Callback for receiving the token. */ |
| 28 public interface Callback { | 31 public interface Callback { |
| 29 void onTokenFetched(String code, String accessToken); | 32 void onTokenFetched(String code, String accessToken); |
| 30 } | 33 } |
| 31 | 34 |
| 32 /** The path of the Redirect URI. */ | 35 /** The path of the Redirect URI. */ |
| 33 private static final String REDIRECT_URI_PATH = "/oauthredirect/"; | 36 private static final String REDIRECT_URI_PATH = "/oauthredirect/"; |
| 34 | 37 |
| 35 /** | 38 /** |
| 36 * Request both the authorization code and access token from the server. Se e | 39 * Request both the authorization code and access token from the server. Se e |
| 37 * http://tools.ietf.org/html/rfc6749#section-3.1.1. | 40 * http://tools.ietf.org/html/rfc6749#section-3.1.1. |
| 38 */ | 41 */ |
| 39 private static final String RESPONSE_TYPE = "code token"; | 42 private static final String RESPONSE_TYPE = "code token"; |
| 40 | 43 |
| 44 /** Used to initialize the random number generator. */ | |
| 45 private static final int NUM_RANDOM_BYTES = 16; | |
| 46 | |
| 41 /** This is used to securely generate an opaque 128 bit for the |mState| var iable. */ | 47 /** This is used to securely generate an opaque 128 bit for the |mState| var iable. */ |
| 42 private static SecureRandom sSecureRandom = new SecureRandom(); | 48 @SuppressLint("TrulyRandom") |
| 49 private static SecureRandom sSecureRandom; | |
| 50 | |
| 51 static { | |
| 52 // Versions of SecureRandom from Android <= 4.3 do not seed themselves a s | |
| 53 // securely as possible. This workaround should suffice until the fixed version | |
| 54 // is deployed to all users. It reads random data from /dev/urandom, whi ch is as good as | |
| 55 // the platform can get. | |
| 56 sSecureRandom = new SecureRandom(); | |
| 57 sSecureRandom.setSeed(getRandomBytes(NUM_RANDOM_BYTES)); | |
|
kelvinp
2014/08/13 02:33:26
As discussed, maybe it is better to move the initi
Lambros
2014/08/13 23:48:51
Discussed offline. The refactoring to do this is n
| |
| 58 } | |
| 43 | 59 |
| 44 /** This is used to launch the third party login page in the browser. */ | 60 /** This is used to launch the third party login page in the browser. */ |
| 45 private Activity mContext; | 61 private Activity mContext; |
| 46 | 62 |
| 47 /** | 63 /** |
| 48 * An opaque value used by the client to maintain state between the request and callback. The | 64 * An opaque value used by the client to maintain state between the request and callback. The |
| 49 * authorization server includes this value when redirecting the user-agent back to the client. | 65 * authorization server includes this value when redirecting the user-agent back to the client. |
| 50 * The parameter is used for preventing cross-site request forgery. See | 66 * The parameter is used for preventing cross-site request forgery. See |
| 51 * http://tools.ietf.org/html/rfc6749#section-10.12. | 67 * http://tools.ietf.org/html/rfc6749#section-10.12. |
| 52 */ | 68 */ |
| 53 private final String mState; | 69 private final String mState; |
| 54 | 70 |
| 55 private final Callback mCallback; | 71 private final Callback mCallback; |
| 56 | 72 |
| 57 /** The list of TokenUrls allowed by the domain. */ | 73 /** The list of TokenUrls allowed by the domain. */ |
| 58 private final ArrayList<String> mTokenUrlPatterns; | 74 private final ArrayList<String> mTokenUrlPatterns; |
| 59 | 75 |
| 60 private final String mRedirectUriScheme; | 76 private final String mRedirectUriScheme; |
| 61 | 77 |
| 62 private final String mRedirectUri; | 78 private final String mRedirectUri; |
| 63 | 79 |
| 80 private static byte[] getRandomBytes(int numBytes) { | |
| 81 FileInputStream fis = null; | |
| 82 try { | |
| 83 fis = new FileInputStream("/dev/urandom"); | |
| 84 byte[] bytes = new byte[numBytes]; | |
| 85 if (bytes.length != fis.read(bytes)) { | |
| 86 throw new SecurityException("Failed to get enough random data.") ; | |
| 87 } | |
| 88 return bytes; | |
| 89 } catch (IOException e) { | |
| 90 throw new SecurityException("Error reading random data."); | |
| 91 } finally { | |
| 92 try { | |
| 93 if (fis != null) { | |
| 94 fis.close(); | |
| 95 } | |
| 96 } catch (IOException e) { | |
| 97 // Ignore exception closing the device. | |
| 98 } | |
| 99 } | |
| 100 } | |
| 101 | |
| 64 public ThirdPartyTokenFetcher(Activity context, | 102 public ThirdPartyTokenFetcher(Activity context, |
| 65 ArrayList<String> tokenUrlPatterns, | 103 ArrayList<String> tokenUrlPatterns, |
| 66 Callback callback) { | 104 Callback callback) { |
| 67 this.mContext = context; | 105 this.mContext = context; |
| 68 this.mState = generateXsrfToken(); | 106 this.mState = generateXsrfToken(); |
| 69 this.mCallback = callback; | 107 this.mCallback = callback; |
| 70 this.mTokenUrlPatterns = tokenUrlPatterns; | 108 this.mTokenUrlPatterns = tokenUrlPatterns; |
| 71 | 109 |
| 72 this.mRedirectUriScheme = context.getApplicationContext().getPackageName (); | 110 this.mRedirectUriScheme = context.getApplicationContext().getPackageName (); |
| 73 | 111 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 ComponentName component = new ComponentName( | 256 ComponentName component = new ComponentName( |
| 219 context.getApplicationContext(), | 257 context.getApplicationContext(), |
| 220 ThirdPartyTokenFetcher.OAuthRedirectActivity.class); | 258 ThirdPartyTokenFetcher.OAuthRedirectActivity.class); |
| 221 context.getPackageManager().setComponentEnabledSetting( | 259 context.getPackageManager().setComponentEnabledSetting( |
| 222 component, | 260 component, |
| 223 enabledState, | 261 enabledState, |
| 224 PackageManager.DONT_KILL_APP); | 262 PackageManager.DONT_KILL_APP); |
| 225 } | 263 } |
| 226 } | 264 } |
| 227 } | 265 } |
| OLD | NEW |