package com.aptoide.amethyst.webservices;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.SharedPreferences;
import android.content.UriMatcher;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import com.aptoide.amethyst.Aptoide;
import com.aptoide.amethyst.BuildConfig;
import com.aptoide.amethyst.preferences.SecurePreferences;
import com.aptoide.amethyst.utils.AptoideUtils;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;
import java.util.Map;
/**
* Created by j-pac on 29-01-2014.
*/
public class StubProvider extends ContentProvider {
//private static final String URL = "content://" + Constants.STUB_PROVIDER_AUTHORITY;
//private static final Uri CONTENT_URI = Uri.parse(URL);
private static final int TOKEN = 1;
private static final int REPO = 2;
private static final int PASSHASH = 3;
private static final int LOGIN_TYPE = 4;
private static final int LOGIN_NAME = 5;
private static final int CHANGE_PREFERENCE = 6;
private static final String BACKUP_PACKAGE = "pt.aptoide.backupapps";
private static final String BACKUP_SIGNATURE = "308203643082024ca0030201020204503fc625300d06092a864886f70d01010505003073310b30090603550406130270743110300e06035504081307556e6b6e6f776e310f300d060355040713064c6973626f6e31153013060355040a130c4361697861204d61676963613110300e060355040b13074170746f696465311830160603550403130f4475617274652053696c76656972613020170d3132303833303139353933335a180f32303934313031393139353933335a3073310b30090603550406130270743110300e06035504081307556e6b6e6f776e310f300d060355040713064c6973626f6e31153013060355040a130c4361697861204d61676963613110300e060355040b13074170746f696465311830160603550403130f4475617274652053696c766569726130820122300d06092a864886f70d01010105000382010f003082010a0282010100a7032cb40819b62cd596bc1c121951724e9a7d6612222d63dab58a18970339f77911b8e2a0665aa15efb051d4dd710c99e1fcaea006a651b7c113a71649c315e27122b9e0a214a240f34559394cca116c609d5bbf670ed85c7b983f0026154278bffd2b53d8aea4735ed99c39ea45db004c16bee078bb0b40e38ae510cacd1955a4e3eb90347d344cdcce07bddb89d9cd2077558914179a8157a87eac86e1b1a07a3f697a5f3f6512e276741d76bcc0c4809117c279fbd55d8c2b3d70468fbe4869394d9f2740bcccdf727da10c06de5c6a0d2f893bce078e058604726d32ab17e3b113a3dcbe0c22f2532738cae8cc5fa98c6b8306680b07ef8f0fca5d5910b0203010001300d06092a864886f70d01010505000382010100361152e42ece11bfd72e5795c9e91079b39c5280e30e3394671ca108fd7de9c3cebef2fc2f5ba752664ba44fcddaf49e91a1d7683cafdc11275fa7c1487ae78a659a8dae5d696cd93de810c67f127568dfa60c1962ec5ad2a3ea0560f75ad4a2ea9d388d4497b561242f090de2d3347dd32494ba6305735fa21d82f037f4355583fdfb1f46a56c19526969ba5f7f556cca9b9069cd9a9e3cd566d2b8c33138609e8794fb0abb11d33ed2c507f7f7df9ce24b3b64713ccdf2450bb5ec4efedba541dce271c8b3759b340b0467c06624cd3881b769a1d4a1b1fc0bec97d6b8561b032089ab8ca108595759bbd9b95fd43a3d28f518fb9d193125c8fa9b224f831c";
private static final String UPLOADER_PACKAGE = "pt.caixamagica.aptoide.uploader";
private static final String UPLOADER_SIGNATURE = "308205653082034ca00302010202044df76b53300d06092a864886f70d01010505003073310b30090603550406130270743110300e06035504081307556e6b6e6f776e310f300d060355040713064c6973626f6131153013060355040a130c4361697861204d61676963613110300e060355040b1307556e6b6e6f776e311830160603550403130f4475617274652053696c76656972613020170d3131303631343134303831395a180f32303933303830323134303831395a3073310b30090603550406130270743110300e06035504081307556e6b6e6f776e310f300d060355040713064c6973626f6131153013060355040a130c4361697861204d61676963613110300e060355040b1307556e6b6e6f776e311830160603550403130f4475617274652053696c766569726130820222300d06092a864886f70d01010105000382020f003082020a02820201026cfe7512fa0c40520971ee83e227208e072a1e1962a4fd0cd5c709e33dc45ce856e9ddc2b9a918394e96ec462d5fea2db81c443b9dbedd75a1031a1f1593b86eef83302f9ecdc0dfd227a3e11ccedb056e58c79b9177dbefba122a390dac88a90a317cb55a9171ab428b46c2e29b5d7fef2e823f5985b9c165a1edba7c82b4f8d5e3aa346996019cb8b7bcc768f5fdae15975add5e53c1fc022e4c99dababf3a80c5a09680ba4b8889cc4399940d92d11c289268d3f2671b98f871964f21c5870d9a1c72c8fbea65a637a06643f246e733fff37b7db4020fd2b6e7343fdbac2ddd20f8a48710d944d8f76432a3225f72c6a50c4e76247fb9256f294eeb9e24080ad28094fbfcfa6e4b5a85d652b1c5d967b39ee1272955a134a0ff1e89bb01f98d710204c72ca4c9dd44ecdd81358a8ef920fa371edd1bfc097c81678aa31b059b9218eba5c0ed2c209bd799a3ecab19e5e3b0e3d18029bf156b37e091969b4e5ae5024475b038b4d841e0e88580fd433154f606f1f7c14527f00509dd7448911e1ec44cb1e94f7dce59459e95438c4a245103d14fff047f97d14bf38f1802d84727b0f3aa98e02e8840892c629e303f76965e186de1d92263ec17e35aa224c33856d59095cf9195042ebfb5fd4703ef8add7ccf923640f266c22e432232f5c6b0873d99ebd509f9e66a77506eabef04ae1d9cf5edb40e13bc1cff39917da8b70203010001300d06092a864886f70d010105050003820202000069a29624d30983fdec4c4bf685f2f479214fda52e272a74ae8aee8bc7aae441ba79977cdd251cf5b21c56ee631dd1e17da28a2bd87d1190b4c1cc440140251e38af40aa694e6d3965c31b36ade9deccde0ca403639031f44f42e395b575a125cd210fd54e9ac760af1ed72c7b91f8f771074f6cafe0d28ab840510ee98a46eb84225be218ff6f90d036f47ec2e7dbfa067e9498cc633e5cab354ab86013b4d8047312643cdfbb6b3654dc26a87af0f4d83b2b0c6ad28d026483788daeda241c8e2631311e0e0d48c6f9284904cc4df114336c207e4c4f468f80f82f2d6917d8ec6b9e63fa2a0f126f668f8220667c92d26d55b5da7a4144b8693c0dec479a3c63b1d43eb96868eac1cb786e2f4b327bad553fc9ffe2dada3ab11bd6b1d7a623a92e821192b0dbcdabf0e4c361561bb5abb970d11e477050d56957fc8961106d2aaf1f209cbdde733a7a6e0577fd35d32f048e887b0e92c9415871e5b0d7458fe682256494b6c9443d04a076842d56374ee4c184a5c64a71c6818eafaa6dcbd66aae917907080d4895b7b0c941a4fae00be891666c0bdeb8b9331d0ff61d7ec2c26b80156aa64263e925dc9d84279bdb1e27e0403b57c14a1b2647a98c858ee20c92b967fb1eb963147fe390958e7c914fce69e1e2eb06139279b70a8eeabe99500ddf04223c3343e5c9b2722635856c65593aae9d2dbf3da704f79e8145f008e";
public static final String STUB_PROVIDER_AUTHORITY = "cm.aptoide.pt.StubProvider";
//private static final String DEBUG_SIGNATURE = "3082030d308201f5a0030201020204707f3269300d06092a864886f70d01010b05003037310b30090603550406130255533110300e060355040a1307416e64726f6964311630140603550403130d416e64726f6964204465627567301e170d3134303131333133313932345a170d3135303131333133313932345a3037310b30090603550406130255533110300e060355040a1307416e64726f6964311630140603550403130d416e64726f696420446562756730820122300d06092a864886f70d01010105000382010f003082010a0282010100a78ea962ea1e79728af241064212afc3b8114d77d271d37ba1d0cd6dbccba5d649379e3bc47bc22bd4703f5d919937e5319ad9698f915e9f051ce0cfabdaa51689e8c37dcb10aaa0f3434d91505c15a20fc483a44a006725ab6fecd9d8336383e37c13a86cc04f86be57a71375b373a2826d2690bddfa217116fe753f0cc39826b71e305780cf7c116a3b01caabf6daf06a311042ccd219b617f4ab9af37b499009234d7d0b2afba538002eff8f545b72e5e897fe3ebfd216885d5e0c446a3f5c9036e7ee091eaa70adabd9356b4288b7a74a98efc853397d68d12709a06477f64b1eb425e156492d0a72aebb431fdc6ee71dc4a316b91782223ce079cbe0d210203010001a321301f301d0603551d0e04160414e3d4ab84257fd096857ef6d116271a5af1ed4a4d300d06092a864886f70d01010b05000382010100a77160d2f1bcf0ddf5e304df44f77376d7f308a3c92df342188649608665737ec0f4045a29a9db17579d0fa26bc47b54aa90d92992a4b438b6fa054f6243faea70476c3f9ae3a2dfe4def49172c852c52cb0bf131e54b9f61a2d07f59f00a7bb3fd2d9d56bb5111798b0d13ff6a08fd7f6e28dc2f67eeddee190278517c0a545ee180dffef836bc55dc9eca0acc24f8b361a4a0b2f2d526251d258fe3bd27494d8da9e9dc7bc1e5f86868d63c2db7904c1fc295151ea001ee5ac7904463f6d8de4f18fd4c63b5aa0ad382057633d72701646d121c452f15bf78089254a89f2520de21cdebf14018679985fd988a83e7e0c4e34097ac9006df7f4162ff537be1c";
private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(STUB_PROVIDER_AUTHORITY, "token", TOKEN);
uriMatcher.addURI(STUB_PROVIDER_AUTHORITY, "repo", REPO);
uriMatcher.addURI(STUB_PROVIDER_AUTHORITY, "loginType", LOGIN_TYPE);
uriMatcher.addURI(STUB_PROVIDER_AUTHORITY, "passHash", PASSHASH);
uriMatcher.addURI(STUB_PROVIDER_AUTHORITY, "loginName", LOGIN_NAME);
uriMatcher.addURI(STUB_PROVIDER_AUTHORITY, "changePreference", CHANGE_PREFERENCE);
}
@Override
public boolean onCreate() {
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
AccountManager accountManager = AccountManager.get(getContext());
Account[] accounts = accountManager.getAccountsByType(Aptoide.getConfiguration().getAccountType());
if(accounts.length != 0) {
try {
int uid = Binder.getCallingUid();
PackageManager pm = getContext().getPackageManager();
String callerPackage = pm.getPackagesForUid(uid)[0];
String callerSignature = pm.getPackageInfo(callerPackage, PackageManager.GET_SIGNATURES).signatures[0].toCharsString();
Log.d("StubProvider", "callerPackage: " + callerPackage);
Log.d("StubProvider", "callerSignature: " + callerSignature);
if((callerPackage.equals(BACKUP_PACKAGE) && callerSignature.equals(BACKUP_SIGNATURE))
|| (callerPackage.equals(UPLOADER_PACKAGE) && callerSignature.equals(UPLOADER_SIGNATURE))) {
MatrixCursor mx;
switch (uriMatcher.match(uri)) {
case TOKEN:
SharedPreferences preferences = SecurePreferences.getInstance();
String token = preferences.getString("devtoken", "");
mx = new MatrixCursor(new String[]{"userToken"}, 1);
mx.addRow(new Object[]{token});
return mx;
case REPO:
String repo = PreferenceManager.getDefaultSharedPreferences(getContext()).getString("userRepo", "");
mx = new MatrixCursor(new String[]{"userRepo"}, 1);
mx.addRow(new Object[]{repo});
Log.d("StubProvider", "repo retrieved: " + repo);
return mx;
case PASSHASH:
String loginTypeCase = PreferenceManager.getDefaultSharedPreferences(getContext()).getString("loginType", "aptoide").toLowerCase(Locale.ENGLISH);
if(loginTypeCase.equals("aptoide")){
String passHash = null;
try {
passHash = AptoideUtils.Algorithms.computeSHA1sum(accountManager.getPassword(accounts[0]));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
mx = new MatrixCursor(new String[]{"userPass"}, 1);
mx.addRow(new String[]{passHash});
Log.d("StubProvider", "repo retrieved: " + passHash);
return mx;
}else if(loginTypeCase.equals("facebook") || loginTypeCase.equals("google")){
String passHash = null;
passHash = accountManager.getPassword(accounts[0]);
mx = new MatrixCursor(new String[]{"userPass"}, 1);
mx.addRow(new String[]{passHash});
Log.d("StubProvider", "repo retrieved: " + passHash);
return mx;
}
case LOGIN_TYPE:
String loginType = PreferenceManager.getDefaultSharedPreferences(getContext()).getString("loginType", "aptoide").toLowerCase(Locale.ENGLISH);
mx = new MatrixCursor(new String[]{"loginType"}, 1);
mx.addRow(new String[]{loginType});
return mx;
case LOGIN_NAME:
String loginName = PreferenceManager.getDefaultSharedPreferences(getContext()).getString("username", "").toLowerCase(Locale.ENGLISH);
mx = new MatrixCursor(new String[]{"loginName"}, 1);
mx.addRow(new String[]{loginName});
return mx;
}
}else{
Log.d("Failed to check signature", callerSignature + " vs " + BACKUP_SIGNATURE + " = " + (callerPackage.equals(BACKUP_PACKAGE) && callerSignature.equals(BACKUP_SIGNATURE)));
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Log.d("StubProvider", "returning null");
return null;
}
@Override
public String getType(Uri uri) {
return new String();
}
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int uid = Binder.getCallingUid();
PackageManager pm = getContext().getPackageManager();
String callerPackage = pm.getPackagesForUid(uid)[0];
Log.d("AptoideDebug", "Someone is trying to update preferences");
int result = pm.checkSignatures(callerPackage, getContext().getPackageName());
if(result == PackageManager.SIGNATURE_MATCH) {
switch (uriMatcher.match(uri)) {
case CHANGE_PREFERENCE:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor edit = preferences.edit();
int changed = 0;
for (final Map.Entry<String, Object> entry : values.valueSet()) {
Object value = entry.getValue();
if (value instanceof String) {
edit.putString(entry.getKey(), (String) value);
} else if (value instanceof Integer) {
edit.putInt(entry.getKey(), (Integer) value);
} else if (value instanceof Long) {
edit.putLong(entry.getKey(), (Long) value);
} else if (value instanceof Boolean) {
if(entry.getKey().equals("debugmode")){
Aptoide.DEBUG_MODE = (Boolean) entry.getValue();
}
edit.putBoolean(entry.getKey(), (Boolean) value);
} else if (value instanceof Float) {
edit.putFloat(entry.getKey(), (Float) value);
}
changed++;
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(Aptoide.getContext(), "Preference set: " + entry.getKey() + "=" + entry.getValue(), Toast.LENGTH_LONG).show();
}
});
}
Log.d("AptoideDebug", "Commited");
edit.commit();
return changed;
default:
return 0;
}
}
return 0;
}
}