diff --git a/src/main/java/com/alterdekim/frida/config/ClientConfig.java b/src/main/java/com/alterdekim/frida/config/ClientConfig.java index adf3278..989ebf4 100644 --- a/src/main/java/com/alterdekim/frida/config/ClientConfig.java +++ b/src/main/java/com/alterdekim/frida/config/ClientConfig.java @@ -5,9 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.jetbrains.annotations.NotNull; -import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; import lombok.ToString; @ToString diff --git a/src/main/java/com/alterdekim/frida/config/Config.java b/src/main/java/com/alterdekim/frida/config/Config.java index 8ae17b9..c619022 100644 --- a/src/main/java/com/alterdekim/frida/config/Config.java +++ b/src/main/java/com/alterdekim/frida/config/Config.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.jetbrains.annotations.NotNull; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.ToString; diff --git a/src/main/java/com/alterdekim/fridaapp/activity/MainActivity.java b/src/main/java/com/alterdekim/fridaapp/activity/MainActivity.java index 23d3813..aac61b4 100644 --- a/src/main/java/com/alterdekim/fridaapp/activity/MainActivity.java +++ b/src/main/java/com/alterdekim/fridaapp/activity/MainActivity.java @@ -5,13 +5,9 @@ import android.content.Intent; import android.net.VpnService; import android.os.Bundle; import android.util.Log; -import android.view.LayoutInflater; import android.view.MenuItem; -import android.view.View; -import android.widget.CompoundButton; import android.widget.LinearLayout; import android.widget.PopupMenu; -import android.widget.TextView; import android.widget.Toast; import androidx.activity.EdgeToEdge; @@ -21,21 +17,15 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; -import androidx.room.Room; import com.alterdekim.fridaapp.R; import com.alterdekim.fridaapp.controller.ControllerId; import com.alterdekim.fridaapp.controller.ControllerManager; import com.alterdekim.fridaapp.controller.MainActivityController; import com.alterdekim.fridaapp.util.Util; -import com.alterdekim.fridaapp.room.AppDatabase; -import com.alterdekim.fridaapp.room.Config; import com.alterdekim.fridaapp.service.FridaService; -import com.google.android.material.switchmaterial.SwitchMaterial; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Iterator; import lombok.Getter; diff --git a/src/main/java/com/alterdekim/fridaapp/activity/SingleConfigActivity.java b/src/main/java/com/alterdekim/fridaapp/activity/SingleConfigActivity.java index 2fd7c71..5743fbd 100644 --- a/src/main/java/com/alterdekim/fridaapp/activity/SingleConfigActivity.java +++ b/src/main/java/com/alterdekim/fridaapp/activity/SingleConfigActivity.java @@ -1,5 +1,6 @@ package com.alterdekim.fridaapp.activity; +import android.content.Intent; import android.os.Bundle; import androidx.activity.EdgeToEdge; @@ -17,25 +18,46 @@ public class SingleConfigActivity extends AppCompatActivity { private static final String TAG = SingleConfigActivity.class.getSimpleName(); - private SingleConfigActivityController controller; - - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + EdgeToEdge.enable(this); setContentView(R.layout.activity_single_config); ControllerManager.putController(new SingleConfigActivityController()); - this.controller = (SingleConfigActivityController) ControllerManager.getController(ControllerId.SingleConfigActivityController); + SingleConfigActivityController controller = (SingleConfigActivityController) ControllerManager.getController(ControllerId.SingleConfigActivityController); + Intent intent = getIntent(); + String config_title = intent.getStringExtra("config_title"); + byte[] config_data = intent.getByteArrayExtra("config_data"); + + controller.onConfigDataAppeared(config_title, config_data); + controller.onCreateGUI(this); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); + /* + this.findViewById(R.id.add_app).setOnClickListener(view -> { + final PackageManager pm = this.getPackageManager(); + List apps = pm.getInstalledPackages(0); + AlertDialog.Builder builder = new AlertDialog.Builder(SingleConfigActivity.this) + .setTitle(R.string.choose_app); + View mRowList = getLayoutInflater().inflate(R.layout.row, null); + ListView mListView = mRowList.findViewById(R.id.list_view); + final ArrayAdapter names = new ArrayAdapter<>(SingleConfigActivity.this, android.R.layout.simple_list_item_1); + for( int i = 0; i < apps.size(); i++ ) { + names.add(pm.getApplicationLabel(apps.get(i).applicationInfo).toString()); + } + mListView.setAdapter(names); + names.notifyDataSetChanged(); + builder.setView(mRowList); + builder.create().show(); + }); */ } } \ No newline at end of file diff --git a/src/main/java/com/alterdekim/fridaapp/controller/MainActivityController.java b/src/main/java/com/alterdekim/fridaapp/controller/MainActivityController.java index 108ebea..49c097d 100644 --- a/src/main/java/com/alterdekim/fridaapp/controller/MainActivityController.java +++ b/src/main/java/com/alterdekim/fridaapp/controller/MainActivityController.java @@ -22,7 +22,9 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.google.android.material.switchmaterial.SwitchMaterial; import java.io.IOException; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.schedulers.Schedulers; @@ -44,6 +46,11 @@ public class MainActivityController implements IController { public void onCreateGUI(AppCompatActivity activity) { this.db = Room.databaseBuilder(activity.getApplicationContext(), AppDatabase.class, "def-db").build(); this.mainActivity = (MainActivity) activity; + Intent intent = new Intent(this.mainActivity, FridaService.class); + intent.putExtra("vpn_data", new byte[0]); + intent.putExtra("vpn_uid", -1); + intent.putExtra("vpn_state", false); + this.mainActivity.startService(intent); this.initConfigListGUI(); } @@ -59,17 +66,31 @@ public class MainActivityController implements IController { return; } Iterator iter = cl.iterator(); + List switches = new ArrayList<>(); while( iter.hasNext() ) { Config config = iter.next(); View cfg_instance = inflater.inflate(R.layout.single_config, this.mainActivity.getCfg_list(), false); this.mainActivity.getCfg_list().addView(cfg_instance); TextView view_name = cfg_instance.findViewById(R.id.config_name); SwitchMaterial view_switch = cfg_instance.findViewById(R.id.config_switch); + switches.add(view_switch); view_switch.setUseMaterialThemeColors(true); - view_switch.setOnCheckedChangeListener((compoundButton, b) -> toggleVpn(view_switch, config, b)); + view_switch.setOnCheckedChangeListener((compoundButton, b) -> { + if( b ) { + for (SwitchMaterial ss : switches) { + if (!ss.equals(view_switch)) { + Log.i(TAG, "DEACTIVATED"); + ss.setChecked(false); + } + } + } + toggleVpn(config, b); + }); view_name.setText(config.getTitle()); view_name.setOnClickListener(view -> { Intent intent = new Intent(this.mainActivity, SingleConfigActivity.class); + intent.putExtra("config_data", config.getData_raw()); + intent.putExtra("config_title", config.getTitle()); this.mainActivity.startActivity(intent); }); if( iter.hasNext() ) this.mainActivity.getCfg_list().addView(inflater.inflate(R.layout.single_divider, this.mainActivity.getCfg_list(), false)); @@ -81,11 +102,8 @@ public class MainActivityController implements IController { public void insertNewConfig(String name, byte[] config) { try { - com.alterdekim.frida.config.Config cfg = new ObjectMapper(new YAMLFactory()).setAnnotationIntrospector(new JacksonAnnotationIntrospector()).readValue(config, com.alterdekim.frida.config.Config.class); - Log.i(TAG, cfg.toString()); + new ObjectMapper(new YAMLFactory()).setAnnotationIntrospector(new JacksonAnnotationIntrospector()).readValue(config, com.alterdekim.frida.config.Config.class); } catch (IOException e) { - Log.e(TAG, "Can't parse config"); - e.printStackTrace(); Toast.makeText(this.mainActivity, R.string.config_adding_error, Toast.LENGTH_LONG).show(); return; } @@ -97,7 +115,7 @@ public class MainActivityController implements IController { .subscribe(); } - private void toggleVpn(SwitchMaterial view, Config config, boolean val) { + private void toggleVpn(Config config, boolean val) { Intent intent = new Intent(this.mainActivity, FridaService.class); intent.putExtra("vpn_data", config.getData_raw()); intent.putExtra("vpn_uid", config.getUid()); diff --git a/src/main/java/com/alterdekim/fridaapp/controller/SingleConfigActivityController.java b/src/main/java/com/alterdekim/fridaapp/controller/SingleConfigActivityController.java index d54a6da..5262b9e 100644 --- a/src/main/java/com/alterdekim/fridaapp/controller/SingleConfigActivityController.java +++ b/src/main/java/com/alterdekim/fridaapp/controller/SingleConfigActivityController.java @@ -1,11 +1,31 @@ package com.alterdekim.fridaapp.controller; +import android.content.res.Resources; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + import androidx.appcompat.app.AppCompatActivity; +import com.alterdekim.frida.config.Config; +import com.alterdekim.fridaapp.R; +import com.alterdekim.fridaapp.activity.SingleConfigActivity; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + +import java.io.IOException; + public class SingleConfigActivityController implements IController { private static final String TAG = SingleConfigActivityController.class.getSimpleName(); + private String config_title; + private Config config_data; + private SingleConfigActivity activity; + //private List appsList; + //private boolean isAllowedApps; + @Override public ControllerId getControllerId() { return ControllerId.SingleConfigActivityController; @@ -13,6 +33,47 @@ public class SingleConfigActivityController implements IController { @Override public void onCreateGUI(AppCompatActivity activity) { + this.activity = (SingleConfigActivity) activity; + //this.isAllowedApps = true; + TextView config_name = this.activity.findViewById(R.id.interface_name); + TextView public_key_text = this.activity.findViewById(R.id.public_key); + TextView address_text = this.activity.findViewById(R.id.address); + TextView endpoint = this.activity.findViewById(R.id.endpoint); + config_name.setText(this.config_title); + public_key_text.setText(this.config_data.getServer().getPublic_key()); + address_text.setText(this.config_data.getClient().getAddress()); + endpoint.setText(this.config_data.getServer().getEndpoint()); + + LinearLayout switch_allowed = this.activity.findViewById(R.id.switch_all); + LinearLayout switch_disallowed = this.activity.findViewById(R.id.switch_dis); + + Resources resources = this.activity.getResources(); + + switch_allowed.setOnClickListener(view -> { + view.setBackground(resources.getDrawable(R.drawable.layout_swl)); + ( (TextView) activity.findViewById(R.id.btn_text_dis) ).setTextColor(resources.getColor(R.color.switch_deselected)); + ( (TextView) activity.findViewById(R.id.btn_text_all) ).setTextColor(resources.getColor(R.color.switch_selected)); + switch_disallowed.setBackground(null); + //this.isAllowedApps = true; + }); + + switch_disallowed.setOnClickListener(view -> { + view.setBackground(resources.getDrawable(R.drawable.layout_swr)); + ( (TextView) activity.findViewById(R.id.btn_text_dis) ).setTextColor(resources.getColor(R.color.switch_selected)); + ( (TextView) activity.findViewById(R.id.btn_text_all) ).setTextColor(resources.getColor(R.color.switch_deselected)); + switch_allowed.setBackground(null); + //this.isAllowedApps = false; + }); + } + + public void onConfigDataAppeared(String title, byte[] data) { + this.config_title = title; + try { + this.config_data = new ObjectMapper(new YAMLFactory()).setAnnotationIntrospector(new JacksonAnnotationIntrospector()).readValue(data, Config.class); + } catch (IOException e) { + Toast.makeText(this.activity, R.string.config_open_error, Toast.LENGTH_LONG).show(); + this.activity.finish(); + } } } diff --git a/src/main/java/com/alterdekim/fridaapp/room/ConfigDAO.java b/src/main/java/com/alterdekim/fridaapp/room/ConfigDAO.java index 43e9442..4146838 100644 --- a/src/main/java/com/alterdekim/fridaapp/room/ConfigDAO.java +++ b/src/main/java/com/alterdekim/fridaapp/room/ConfigDAO.java @@ -10,7 +10,6 @@ import java.util.List; import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.core.Flowable; -import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; @Dao diff --git a/src/main/java/com/alterdekim/fridaapp/service/FridaService.java b/src/main/java/com/alterdekim/fridaapp/service/FridaService.java index 398eadb..06f58e9 100644 --- a/src/main/java/com/alterdekim/fridaapp/service/FridaService.java +++ b/src/main/java/com/alterdekim/fridaapp/service/FridaService.java @@ -34,6 +34,8 @@ public class FridaService extends VpnService { private final FridaLib lib = new FridaLib(); + private int uid = -1; + @Override public void onCreate() { Log.i(TAG, "Created"); @@ -100,14 +102,19 @@ public class FridaService extends VpnService { public int onStartCommand(Intent intent, int flags, int startId) { if( intent.getExtras() == null ) return START_STICKY; byte[] config = intent.getExtras().getByteArray("vpn_data"); - int uid = intent.getExtras().getInt("vpn_uid"); + int cfg_uid = intent.getExtras().getInt("vpn_uid"); boolean state = intent.getExtras().getBoolean("vpn_state"); if(!state) { this.lib.stop(); return START_STICKY; } + if(cfg_uid != this.uid && this.uid != -1) { + this.lib.stop(); + turnOff(); + } + this.uid = cfg_uid; setupVPN(config); - // TODO: different configs + this.vpnProcess = Flowable.fromRunnable(new NativeBinaryConnection(vpnInterface.detachFd(), Util.bytesToHex(config), lib, logPath)) .subscribeOn(Schedulers.newThread()) .observeOn(Schedulers.newThread()) diff --git a/src/main/java/com/alterdekim/fridaapp/util/Util.java b/src/main/java/com/alterdekim/fridaapp/util/Util.java index 458fc95..017d89d 100644 --- a/src/main/java/com/alterdekim/fridaapp/util/Util.java +++ b/src/main/java/com/alterdekim/fridaapp/util/Util.java @@ -5,12 +5,9 @@ import android.database.Cursor; import android.net.Uri; import android.provider.OpenableColumns; -import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Objects; public class Util { public static String readTextFromUri(Context context, Uri uri) throws IOException { diff --git a/src/main/res/layout/content_single.xml b/src/main/res/layout/content_single.xml index f0f8ba8..2ee8343 100644 --- a/src/main/res/layout/content_single.xml +++ b/src/main/res/layout/content_single.xml @@ -18,6 +18,7 @@ android:layout_height="wrap_content" android:layout_gravity="start" android:text="Name" + android:maxLines="1" android:textAllCaps="false" android:textColor="@color/grey" android:textSize="14sp" @@ -49,8 +50,10 @@ android:layout_height="wrap_content" android:layout_gravity="start" android:text="8x6qHHHgsa5nq82nd==" + android:textAlignment="viewStart" android:textAllCaps="false" android:textColor="@color/black" + android:maxLines="1" android:textSize="14sp" android:textStyle="normal" /> + + + + + diff --git a/src/main/res/values/colors.xml b/src/main/res/values/colors.xml index 454e8e0..26e09cd 100644 --- a/src/main/res/values/colors.xml +++ b/src/main/res/values/colors.xml @@ -4,4 +4,6 @@ #FFa9a9a9 #FFFFFFFF #731DD8 + #75757F + @color/white \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 6e7bde4..3b30715 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -3,5 +3,7 @@ Create from scratch Import from file Cannot add new config - SUCCESS! + Success! + Error occurred + Choose app \ No newline at end of file