rework cookies more

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/284/head
androidacy-user 1 year ago
parent 68a4c54ef8
commit 08e78d9577

@ -336,6 +336,8 @@ dependencies {
// ksp
implementation "com.google.devtools.ksp:symbol-processing-api:1.8.0-1.0.8"
implementation "androidx.security:security-crypto:1.1.0-alpha04"
}
if (hasSentryConfig) {

@ -3,6 +3,7 @@ package com.fox2code.mmm;
import static com.fox2code.mmm.utils.IntentHelper.getActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
@ -13,6 +14,8 @@ import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.fragment.app.FragmentActivity;
import androidx.security.crypto.EncryptedFile;
import androidx.security.crypto.MasterKey;
import com.fox2code.foxcompat.app.FoxActivity;
import com.fox2code.mmm.androidacy.AndroidacyRepoData;
@ -26,6 +29,9 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.materialswitch.MaterialSwitch;
import com.topjohnwu.superuser.internal.UiThreadHandler;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Objects;
import io.realm.Realm;
@ -328,5 +334,19 @@ public class SetupActivity extends FoxActivity implements LanguageActivity {
}
}
});
try {
String cookieFileName = "cookies";
File cookieFile = new File(MainApplication.getINSTANCE().getFilesDir(), cookieFileName);
String initialCookie = "is_foxmmm=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/; domain=\" + chain.request().url().host() + \"; SameSite=None; Secure;|foxmmm_version=" + BuildConfig.VERSION_CODE + "; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/; domain=\" + chain.request().url().host() + \"; SameSite=None; Secure;";
Context context = getApplicationContext();
MasterKey mainKeyAlias = new MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build();
EncryptedFile encryptedFile = new EncryptedFile.Builder(context, new File(MainApplication.getINSTANCE().getFilesDir(), cookieFileName), mainKeyAlias, EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB).build();
encryptedFile.openFileOutput().write(initialCookie.getBytes());
encryptedFile.openFileOutput().flush();
encryptedFile.openFileOutput().close();
} catch (GeneralSecurityException |
IOException e) {
Timber.e(e);
}
}
}

@ -7,24 +7,23 @@ package com.fox2code.mmm.utils.io;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.security.crypto.EncryptedFile;
import androidx.security.crypto.MasterKey;
import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.MainApplication;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.io.InputStream;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import timber.log.Timber;
/**
* This interceptor put all the Cookies in Preferences in the Request.
* Your implementation on how to get the Preferences may ary, but this will work 99% of the time.
*/
public class AddCookiesInterceptor implements Interceptor {
public static final String PREF_COOKIES = "PREF_COOKIES";
// We're storing our stuff in a database made just for cookies called PREF_COOKIES.
// I reccomend you do this, and don't change this default value.
private final Context context;
@ -37,9 +36,32 @@ public class AddCookiesInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
MasterKey mainKeyAlias;
String cookieFileName = "cookies";
byte[] plaintext;
try {
// create cookie file if it doesn't exist
mainKeyAlias = new MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build();
EncryptedFile encryptedFile = new EncryptedFile.Builder(context, new File(MainApplication.getINSTANCE().getFilesDir(), cookieFileName), mainKeyAlias, EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB).build();
InputStream inputStream;
inputStream = encryptedFile.openFileInput();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int nextByte = inputStream.read();
while (nextByte != -1) {
byteArrayOutputStream.write(nextByte);
nextByte = inputStream.read();
}
HashSet<String> preferences = (HashSet<String>) MainApplication.getSharedPreferences().getStringSet(PREF_COOKIES, new HashSet<>());
plaintext = byteArrayOutputStream.toByteArray();
inputStream.close();
} catch (
Exception e) {
Timber.e(e, "Error while reading cookies");
plaintext = new byte[0];
}
String[] preferences = new String(plaintext).split("\\|");
// Use the following if you need everything in one line.
// Some APIs die if you do it differently.
StringBuilder cookiestring = new StringBuilder();
@ -50,13 +72,7 @@ public class AddCookiesInterceptor implements Interceptor {
}
cookiestring.append(cookie).append(" ");
}
// if ccokiestring doesn't have is_foxmmm cookie, add a never expiring one for the current domain.
if (!cookiestring.toString().contains("is_foxmmm")) {
cookiestring.append("is_foxmmm=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/; domain=").append(chain.request().url().host()).append("; SameSite=None; Secure;");
}
if (BuildConfig.DEBUG_HTTP) {
Timber.d("Sending cookies: %s", cookiestring.toString());
}
Timber.d("Sending cookies: %s", cookiestring.toString());
builder.addHeader("Cookie", cookiestring.toString());
return chain.proceed(builder.build());

@ -6,14 +6,20 @@ package com.fox2code.mmm.utils.io;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import androidx.security.crypto.EncryptedFile;
import androidx.security.crypto.MasterKey;
import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.MainApplication;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.HashSet;
import okhttp3.Interceptor;
@ -22,9 +28,11 @@ import timber.log.Timber;
public class ReceivedCookiesInterceptor implements Interceptor {
private final Context context;
public ReceivedCookiesInterceptor(Context context) {
this.context = context;
} // AddCookiesInterceptor()
@NonNull
@SuppressLint({"MutatingSharedPrefs", "ApplySharedPref"})
@Override
@ -32,19 +40,48 @@ public class ReceivedCookiesInterceptor implements Interceptor {
Response originalResponse = chain.proceed(chain.request());
if (!originalResponse.headers("Set-Cookie").isEmpty()) {
HashSet<String> cookies = (HashSet<String>) MainApplication.getSharedPreferences().getStringSet("PREF_COOKIES", new HashSet<>());
MasterKey mainKeyAlias;
String cookieFileName = "cookies";
byte[] plaintext;
try {
mainKeyAlias = new MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build();
EncryptedFile encryptedFile = new EncryptedFile.Builder(context, new File(MainApplication.getINSTANCE().getFilesDir(), cookieFileName), mainKeyAlias, EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB).build();
InputStream inputStream = encryptedFile.openFileInput();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int nextByte = inputStream.read();
while (nextByte != -1) {
byteArrayOutputStream.write(nextByte);
nextByte = inputStream.read();
}
cookies.addAll(originalResponse.headers("Set-Cookie"));
if (!cookies.toString().contains("is_foxmmm")) {
cookies.add("is_foxmmm=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/; domain=" + chain.request().url().host() + "; SameSite=None; Secure;");
plaintext = byteArrayOutputStream.toByteArray();
inputStream.close();
} catch (
Exception e) {
e.printStackTrace();
plaintext = new byte[0];
}
SharedPreferences.Editor memes = MainApplication.getSharedPreferences().edit();
HashSet<String> cookies = new HashSet<>(Arrays.asList(new String(plaintext).split("\\|")));
HashSet<String> cookieSet = new HashSet<>(originalResponse.headers("Set-Cookie"));
if (BuildConfig.DEBUG_HTTP) {
Timber.d("Received cookies: %s", cookies);
Timber.d("Received cookies: %s", cookieSet);
}
// if we already have the cooki in cookies, remove the one in cookies
cookies.removeIf(cookie -> cookieSet.toString().contains(cookie.split(";")[0]));
// add the new cookies to the cookies
cookies.addAll(cookieSet);
// write the cookies to the file
try {
mainKeyAlias = new MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build();
EncryptedFile encryptedFile = new EncryptedFile.Builder(context, new File(MainApplication.getINSTANCE().getFilesDir(), cookieFileName), mainKeyAlias, EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB).build();
encryptedFile.openFileOutput().write(String.join("|", cookies).getBytes());
encryptedFile.openFileOutput().flush();
encryptedFile.openFileOutput().close();
Timber.d("Storing encrypted cookies: %s", String.join("|", cookies));
} catch (
GeneralSecurityException e) {
throw new IllegalStateException("Unable to get master key", e);
}
memes.putStringSet("PREF_COOKIES", cookies).apply();
memes.commit();
}
return originalResponse;

Loading…
Cancel
Save