From 1ae04c3850eb876c7f4d1956089741e747691b3a Mon Sep 17 00:00:00 2001 From: YuutaW <17158086+trumeet@users.noreply.github.com> Date: Thu, 16 May 2019 16:03:24 -0700 Subject: refactor: remove #Anti-Crack Signed-off-by: YuutaW <17158086+Trumeet@users.noreply.github.com> --- .../java/moe/yuuta/gplicense/LicenseChecker.java | 356 --------------------- 1 file changed, 356 deletions(-) delete mode 100644 app/src/main/java/moe/yuuta/gplicense/LicenseChecker.java (limited to 'app/src/main/java/moe/yuuta/gplicense/LicenseChecker.java') diff --git a/app/src/main/java/moe/yuuta/gplicense/LicenseChecker.java b/app/src/main/java/moe/yuuta/gplicense/LicenseChecker.java deleted file mode 100644 index e909aec..0000000 --- a/app/src/main/java/moe/yuuta/gplicense/LicenseChecker.java +++ /dev/null @@ -1,356 +0,0 @@ -package moe.yuuta.gplicense; - -import android.annotation.SuppressLint; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.RemoteException; -import android.provider.Settings.Secure; -import com.elvishew.xlog.Logger; -import com.elvishew.xlog.XLog; -import moe.yuuta.ext.*; -import moe.yuuta.gplicense.util.Base64; -import moe.yuuta.gplicense.util.Base64DecoderException; -import moe.yuuta.workmode.BuildConfig; - -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.X509EncodedKeySpec; -import java.util.*; - -/** - * Client library for Google Play license verifications. - *
- * The LicenseChecker is configured via a {@link Policy} which contains the logic to determine - * whether a user should have access to the application. For example, the Policy can define a - * threshold for allowable number of server or client failures before the library reports the user - * as not having access. - *
- * Must also provide the Base64-encoded RSA public key associated with your developer account. The
- * public key is obtainable from the publisher site.
- */
-public class LicenseChecker implements ConnCallback {
- private static final Logger logger = XLog.tag("LCK").build();
-
- private static final String KEY_FACTORY_ALGORITHM = "RSA";
-
- // Timeout value (in milliseconds) for calls to service.
- private static final int TIMEOUT_MS = 10 * 1000;
-
- private static final SecureRandom RANDOM = new SecureRandom();
- private static final boolean DEBUG_LICENSE_ERROR = BuildConfig.DEBUG;
-
- private IService mService;
-
- private PublicKey mPublicKey;
- private final Context mContext;
- private final Policy mPolicy;
- /**
- * A handler for running tasks on a background thread. We don't want license processing to block
- * the UI thread.
- */
- private Handler mHandler;
- private final String mPackageName;
- private final String mVersionCode;
- private final Set
- * NOTE: This call uses a trivially obfuscated string (base64-encoded). For best security, we
- * recommend obfuscating the string that is passed into bindService using another method of your
- * own devising.
- *
- * source string: "com.android.vending.licensing.IService"
- *
- *
- * @param callback
- */
- public synchronized void checkAccess(LicenseCheckerCallback callback) {
- // If we have a valid recent LICENSED response, we can skip asking
- // Market.
- if (mPolicy.allowAccess()) {
- logger.i("Using cached response");
- callback.allow(Policy.LICENSED);
- } else {
- LicenseValidator validator = new LicenseValidator(mPolicy, new NullDeviceLimiter(),
- callback, generateNonce(), mPackageName, mVersionCode);
-
- if (mService == null) {
- logger.i("Binding to service.");
- try {
- mConn = new LicServiceConn(this);
- boolean bindResult = mContext
- .bindService(
- new Intent(
- new String(
- // Base64 encoded -
- // com.android.vending.licensing.IService
- // Consider encoding this in another way in your
- // code to improve security
- Base64.decode(
- "Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U=")))
- // As of Android 5.0, implicit
- // Service Intents are no longer
- // allowed because it's not
- // possible for the user to
- // participate in disambiguating
- // them. This does mean we break
- // compatibility with Android
- // Cupcake devices with this
- // release, since setPackage was
- // added in Donut.
- .setPackage(
- new String(
- // Base64
- // encoded -
- // com.android.vending
- Base64.decode(
- "Y29tLmFuZHJvaWQudmVuZGluZw=="))),
- mConn, // ServiceConnection.
- Context.BIND_AUTO_CREATE);
- if (bindResult) {
- mPendingChecks.offer(validator);
- } else {
- logger.e("Could not bind to service.");
- handleServiceConnectionError(validator);
- }
- } catch (SecurityException e) {
- callback.applicationError(LicenseCheckerCallback.ERROR_MISSING_PERMISSION);
- } catch (Base64DecoderException e) {
- e.printStackTrace();
- }
- } else {
- mPendingChecks.offer(validator);
- runChecks();
- }
- }
- }
-
- private void runChecks() {
- LicenseValidator validator;
- while ((validator = mPendingChecks.poll()) != null) {
- try {
- logger.i("Executing on service for " + validator.getPackageName());
- mService.exec(
- validator.getNonce(), validator.getPackageName(),
- new IPCResultListener(new ResultListener(validator)));
- mChecksInProgress.add(validator);
- } catch (RemoteException e) {
- logger.w("RemoteException in exec call.", e);
- handleServiceConnectionError(validator);
- }
- }
- }
-
- private synchronized void finishCheck(LicenseValidator validator) {
- mChecksInProgress.remove(validator);
- if (mChecksInProgress.isEmpty()) {
- cleanupService();
- }
- }
-
- private class ResultListener implements ResultCallback {
- private final LicenseValidator mValidator;
- private Runnable mOnTimeout;
-
- public ResultListener(LicenseValidator validator) {
- mValidator = validator;
- mOnTimeout = () -> {
- logger.i("Check timed out.");
- handleServiceConnectionError(mValidator);
- finishCheck(mValidator);
- };
- startTimeout();
- }
-
- private static final int ERROR_CONTACTING_SERVER = 0x101;
- private static final int ERROR_INVALID_PACKAGE_NAME = 0x102;
- private static final int ERROR_NON_MATCHING_UID = 0x103;
-
- // Runs in IPC thread pool. Post it to the Handler, so we can guarantee
- // either this or the timeout runs.
- @Override
- public void verifyLicense(final int responseCode, final String signedData,
- final String signature) {
- mHandler.post(() -> {
- logger.i("Received response. (code: " + responseCode + ")");
- // Make sure it hasn't already timed out.
- if (mChecksInProgress.contains(mValidator)) {
- clearTimeout();
- mValidator.verify(mPublicKey, responseCode, signedData, signature);
- finishCheck(mValidator);
- }
- if (DEBUG_LICENSE_ERROR) {
- boolean logResponse;
- String stringError = null;
- switch (responseCode) {
- case ERROR_CONTACTING_SERVER:
- logResponse = true;
- stringError = "ERROR_CONTACTING_SERVER";
- break;
- case ERROR_INVALID_PACKAGE_NAME:
- logResponse = true;
- stringError = "ERROR_INVALID_PACKAGE_NAME";
- break;
- case ERROR_NON_MATCHING_UID:
- logResponse = true;
- stringError = "ERROR_NON_MATCHING_UID";
- break;
- default:
- logResponse = false;
- }
-
- if (logResponse) {
- @SuppressLint("HardwareIds") String android_id = Secure.getString(mContext.getContentResolver(),
- Secure.ANDROID_ID);
- Date date = new Date();
- logger.d("Server Failure: " + stringError);
- logger.d("Android ID: " + android_id);
- logger.d("Time: " + date.toGMTString());
- }
- }
-
- });
- }
-
- private void startTimeout() {
- logger.i("Start monitoring timeout.");
- mHandler.postDelayed(mOnTimeout, TIMEOUT_MS);
- }
-
- private void clearTimeout() {
- logger.i("Clearing timeout.");
- mHandler.removeCallbacks(mOnTimeout);
- }
- }
-
- @Override
- public synchronized void onServiceConnected(ComponentName name, IBinder service) {
- mService = IService.Stub.asInterface(service);
- runChecks();
- }
-
- @Override
- public synchronized void onServiceDisconnected(ComponentName name) {
- // Called when the connection with the service has been
- // unexpectedly disconnected. That is, Market crashed.
- // If there are any checks in progress, the timeouts will handle them.
- logger.w("Service unexpectedly disconnected.");
- mService = null;
- }
-
- /**
- * Generates policy response for service connection errors, as a result of disconnections or
- * timeouts.
- */
- private synchronized void handleServiceConnectionError(LicenseValidator validator) {
- mPolicy.processServerResponse(Policy.RETRY, null);
-
- if (mPolicy.allowAccess()) {
- validator.getCallback().allow(Policy.RETRY);
- } else {
- validator.getCallback().dontAllow(Policy.RETRY);
- }
- }
-
- /** Unbinds service if necessary and removes reference to it. */
- private void cleanupService() {
- if (mService != null) {
- try {
- mContext.unbindService(mConn);
- } catch (IllegalArgumentException e) {
- // Somehow we've already been unbound. This is a non-fatal
- // error.
- logger.e("Unable to unbind from licensing service (already unbound)");
- }
- mService = null;
- }
- }
-
- /**
- * Inform the library that the hostContext is about to be destroyed, so that any open connections
- * can be cleaned up.
- *
- * Failure to call this method can result in a crash under certain circumstances, such as during
- * screen rotation if an Activity requests the license check or when the user exits the
- * application.
- */
- public synchronized void onDestroy() {
- cleanupService();
- mHandler.getLooper().quit();
- }
-
- /** Generates a nonce (number used once). */
- private int generateNonce() {
- return RANDOM.nextInt();
- }
-
- /**
- * Get version code for the application package name.
- *
- * @param context
- * @param packageName application package name
- * @return the version code or empty string if package not found
- */
- private static String getVersionCode(Context context, String packageName) {
- try {
- return String.valueOf(
- context.getPackageManager().getPackageInfo(packageName, 0).versionCode);
- } catch (NameNotFoundException e) {
- logger.e("Package not found. could not get version code.");
- return "";
- }
- }
-}
\ No newline at end of file
--
cgit v1.2.3