Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.fptn.vpn.utils;
package org.fptn.vpn.enums;

public enum NetworkType {
WIFI, CELLULAR, ETHERNET, UNKNOWN
Expand Down
27 changes: 27 additions & 0 deletions app/src/main/java/org/fptn/vpn/enums/ObfuscationMethodEnum.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.fptn.vpn.enums;

import androidx.annotation.NonNull;

import lombok.Getter;

public enum ObfuscationMethodEnum {
NONE("None", 0),
TLS_APP_DATA("TLS App Data", 1),
TLS_APP_DATA_BASE_64("TLS App Data + base64", 2);

final String description;

@Getter
final int id;

ObfuscationMethodEnum(String description, int id) {
this.description = description;
this.id = id;
}

@NonNull
@Override
public String toString() {
return description;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
import org.fptn.vpn.database.model.FptnServerDto;
import org.fptn.vpn.enums.ConnectionState;
import org.fptn.vpn.enums.HandlerMessageTypes;
import org.fptn.vpn.enums.ObfuscationMethodEnum;
import org.fptn.vpn.services.websocket.WebSocketAlreadyShutdownException;
import org.fptn.vpn.services.websocket.WebSocketClientWrapper;
import org.fptn.vpn.utils.DataRateCalculator;
import org.fptn.vpn.utils.IPUtils;
import org.fptn.vpn.utils.NetworkType;
import org.fptn.vpn.enums.NetworkType;
import org.fptn.vpn.vpnclient.exception.ErrorCode;
import org.fptn.vpn.vpnclient.exception.PVNClientException;

Expand Down Expand Up @@ -101,7 +102,8 @@ public CustomVpnConnection(final CustomVpnService service,
final String currentIPAddress,
final NetworkType currentNetworkType,
final int maxReconnectCount,
int delayBetweenAttempts) throws PVNClientException {
final int delayBetweenAttempts,
final ObfuscationMethodEnum obfuscationMethod) throws PVNClientException {
this.service = service;
this.connectionId = connectionId;
this.fptnServerDto = fptnServerDto;
Expand All @@ -112,7 +114,8 @@ public CustomVpnConnection(final CustomVpnService service,
sniHostName,
this::onConnectionOpen,
this::onMessageReceived,
this::onConnectionFailure
this::onConnectionFailure,
obfuscationMethod
);
this.maxReconnectCount = maxReconnectCount;
this.delayBetweenAttempts = delayBetweenAttempts;
Expand Down
7 changes: 5 additions & 2 deletions app/src/main/java/org/fptn/vpn/services/CustomVpnService.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@
import org.fptn.vpn.database.model.FptnServerDto;
import org.fptn.vpn.enums.ConnectionState;
import org.fptn.vpn.enums.HandlerMessageTypes;
import org.fptn.vpn.enums.NetworkType;
import org.fptn.vpn.enums.ObfuscationMethodEnum;
import org.fptn.vpn.repository.FptnServerRepository;
import org.fptn.vpn.services.tile.FptnTileService;
import org.fptn.vpn.utils.NetworkType;
import org.fptn.vpn.utils.NetworkUtils;
import org.fptn.vpn.utils.NotificationUtils;
import org.fptn.vpn.utils.SharedPrefUtils;
Expand Down Expand Up @@ -455,6 +456,7 @@ private void connect(FptnServerDto fptnServerDto, String sniHostname) {
int delayBetweenAttempts = SharedPrefUtils.getDelayBetweenReconnect(this);

try {
ObfuscationMethodEnum obfuscationMethod = SharedPrefUtils.getObfuscationMethod(this);
CustomVpnConnection connection = new CustomVpnConnection(
this,
nextConnectionId.getAndIncrement(),
Expand All @@ -463,7 +465,8 @@ private void connect(FptnServerDto fptnServerDto, String sniHostname) {
currentIPAddress,
networkType,
maxReconnectCount,
delayBetweenAttempts);
delayBetweenAttempts,
obfuscationMethod);
connection.setConfigureVpnIntent(launchMainActivityPendingIntent);
connection.start();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.util.Log;

import org.fptn.vpn.enums.ObfuscationMethodEnum;
import org.fptn.vpn.services.websocket.callback.OnFailureCallback;
import org.fptn.vpn.services.websocket.callback.OnMessageReceivedCallback;
import org.fptn.vpn.services.websocket.callback.OnOpenCallback;
Expand All @@ -24,6 +25,7 @@ public class NativeWebSocketClientImpl {
private final OnOpenCallback onOpenCallback;
private final OnMessageReceivedCallback onMessageReceivedCallback;
private final OnFailureCallback onFailureCallback;
private final ObfuscationMethodEnum obfuscationMethod;

private long nativeHandle;

Expand All @@ -36,11 +38,17 @@ public NativeWebSocketClientImpl(
String md5ServerFingerprint,
OnOpenCallback onOpenCallback,
OnMessageReceivedCallback onMessageReceivedCallback,
OnFailureCallback onFailureCallback) throws PVNClientException {
OnFailureCallback onFailureCallback,
ObfuscationMethodEnum obfuscationMethod) throws PVNClientException {
this.onOpenCallback = onOpenCallback;
this.onMessageReceivedCallback = onMessageReceivedCallback;
this.onFailureCallback = onFailureCallback;
this.obfuscationMethod = obfuscationMethod;


// TODO: WHAT TO DO WITH OBFUSCATION METHOD?
// USE THIS
String obfuscation = obfuscationMethod.name(); // NONE, TLS_APP_DATA, TLS_APP_DATA_BASE_64
this.nativeHandle = nativeCreate(
host,
port,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.util.Log;

import org.fptn.vpn.database.model.FptnServerDto;
import org.fptn.vpn.enums.ObfuscationMethodEnum;
import org.fptn.vpn.services.websocket.callback.OnFailureCallback;
import org.fptn.vpn.services.websocket.callback.OnMessageReceivedCallback;
import org.fptn.vpn.services.websocket.callback.OnOpenCallback;
Expand All @@ -24,6 +25,7 @@ public class WebSocketClientWrapper {
private final OnMessageReceivedCallback onMessageReceivedCallback;
private final OnFailureCallback onFailureCallback;
private final NativeHttpsClientImpl nativeHttpsClient;
private final ObfuscationMethodEnum obfuscationMethod;

private NativeWebSocketClientImpl nativeWebSocketClient;

Expand All @@ -35,14 +37,16 @@ public WebSocketClientWrapper(FptnServerDto fptnServerDto,
String sniHostName,
OnOpenCallback onOpenCallback,
OnMessageReceivedCallback onMessageReceivedCallback,
OnFailureCallback onFailureCallback) {
OnFailureCallback onFailureCallback,
ObfuscationMethodEnum obfuscationMethod) {
this.fptnServerDto = fptnServerDto;
this.tunAddress = tunAddress;
this.sniHostName = sniHostName;
this.onOpenCallback = onOpenCallback;
this.onMessageReceivedCallback = onMessageReceivedCallback;
this.onFailureCallback = onFailureCallback;
this.nativeHttpsClient = new NativeHttpsClientImpl(fptnServerDto.host, fptnServerDto.port, this.sniHostName, fptnServerDto.md5ServerFingerprint);
this.obfuscationMethod = obfuscationMethod;
}

public synchronized void startWebSocket() throws PVNClientException, WebSocketAlreadyShutdownException {
Expand All @@ -61,7 +65,8 @@ public synchronized void startWebSocket() throws PVNClientException, WebSocketAl
fptnServerDto.md5ServerFingerprint,
onOpenCallback,
onMessageReceivedCallback,
onFailureCallback
onFailureCallback,
obfuscationMethod
);
Log.d(getTag(), "startWebSocket() nativeWebSocketClient.start() Thread.id: " + Thread.currentThread().getId());
nativeWebSocketClient.start();
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/org/fptn/vpn/utils/NetworkUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import android.net.NetworkRequest;
import android.util.Log;

import org.fptn.vpn.enums.NetworkType;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
Expand Down
16 changes: 12 additions & 4 deletions app/src/main/java/org/fptn/vpn/utils/SharedPrefUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import org.fptn.vpn.R;
import org.fptn.vpn.core.common.Constants;
import org.fptn.vpn.enums.ObfuscationMethodEnum;

public class SharedPrefUtils {
private static final String TAG = SharedPrefUtils.class.getSimpleName();
Expand Down Expand Up @@ -87,8 +87,6 @@ public static int getReconnectAttemptsCount(Context context) {
}

public static void saveReconnectAttemptsCount(Context context, int count) {
Log.d(TAG, "saveReconnectAttemptsCount: " + count);

SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.APPLICATION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
sharedPreferences.edit().putInt(Constants.RECONNECT_ATTEMPTS_COUNT_SHARED_PREF_KEY, count).apply();
}
Expand All @@ -100,8 +98,18 @@ public static int getDelayBetweenReconnect(Context context) {
}

public static void saveDelayBetweenReconnect(Context context, int delayInSeconds) {
Log.d(TAG, "saveDelayBetweenReconnect: " + delayInSeconds);
SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.APPLICATION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
sharedPreferences.edit().putInt(Constants.RECONNECT_DELAY_BETWEEN_SHARED_PREF_KEY, delayInSeconds).apply();
}


public static ObfuscationMethodEnum getObfuscationMethod(Context context) {
SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.APPLICATION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
return ObfuscationMethodEnum.valueOf(sharedPreferences.getString(Constants.OBFUSCATION_METHOD_SHARED_PREF_KEY, ObfuscationMethodEnum.NONE.name()));
}

public static void saveObfuscationMethod(Context context, ObfuscationMethodEnum obfuscationMethodEnum) {
SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.APPLICATION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
sharedPreferences.edit().putString(Constants.OBFUSCATION_METHOD_SHARED_PREF_KEY, obfuscationMethodEnum.name()).apply();
}
}
20 changes: 16 additions & 4 deletions app/src/main/java/org/fptn/vpn/views/SettingsActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

Expand All @@ -32,18 +33,19 @@
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModelProvider;

import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.textfield.TextInputEditText;

import org.fptn.vpn.R;
import org.fptn.vpn.enums.ObfuscationMethodEnum;
import org.fptn.vpn.services.tile.FptnTileService;
import org.fptn.vpn.utils.PermissionsUtils;
import org.fptn.vpn.utils.SharedPrefUtils;
import org.fptn.vpn.viewmodel.FptnServerViewModel;
import org.fptn.vpn.views.adapter.FptnServerAdapter;

import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.textfield.TextInputEditText;
import org.fptn.vpn.views.adapter.ObfuscationMethodAdapter;

import java.util.Optional;
import java.util.concurrent.Executors;

import lombok.Getter;

Expand Down Expand Up @@ -401,6 +403,13 @@ public void onStopTrackingTouch(SeekBar seekBar) {
seekBarDelayBetween.setProgress(0);
seekBarDelayBetween.setProgress(delayBetweenReconnect - 1);

/* Obfuscation method spinner*/
Spinner obfuscationMethodSpinner = dialogView.findViewById(R.id.obfuscation_method_spinner);
obfuscationMethodSpinner.setAdapter(new ObfuscationMethodAdapter());

ObfuscationMethodEnum obfuscationMethod = SharedPrefUtils.getObfuscationMethod(this);
obfuscationMethodSpinner.setSelection(obfuscationMethod.getId());

builder.setPositiveButton(getString(R.string.save_button), (dialog, which) -> {
Log.d(TAG, "experimentalFeaturesDialog: save");
SharedPrefUtils.saveReconnectOnChangeNetworkTypeEnabled(this, switchNetworkType.isChecked());
Expand All @@ -415,6 +424,9 @@ public void onStopTrackingTouch(SeekBar seekBar) {

int delayBetweenProgress = seekBarDelayBetween.getProgress();
SharedPrefUtils.saveDelayBetweenReconnect(this, delayBetweenProgress + 1);

ObfuscationMethodEnum selectedObfuscationMethod = (ObfuscationMethodEnum) obfuscationMethodSpinner.getSelectedItem();
SharedPrefUtils.saveObfuscationMethod(this, selectedObfuscationMethod);
});
builder.setNegativeButton(getString(R.string.cancel_button), (dialog, which) -> {
Log.d(TAG, "experimentalFeaturesDialog: cancel");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.fptn.vpn.views.adapter;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import org.fptn.vpn.R;
import org.fptn.vpn.enums.ObfuscationMethodEnum;

import lombok.Getter;

@Getter
public class ObfuscationMethodAdapter extends BaseAdapter {
private final ObfuscationMethodEnum[] values = ObfuscationMethodEnum.values();

public ObfuscationMethodAdapter() {
notifyDataSetChanged();
}

@Override
public int getCount() {
return values.length;
}

@Override
public Object getItem(int position) {
return values[position];
}

@Override
public long getItemId(int position) {
return values[position].getId();
}

@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.obfuscation_method_spinner_item, parent, false);
}

TextView label = view.findViewById(R.id.obfuscation_method_spinner_item_label);
label.setText(values[position].toString());
return view;
}
}
43 changes: 43 additions & 0 deletions app/src/main/res/layout/experimental_settings_dialog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,49 @@

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/protocol_settings_label"
android:textSize="18sp"
android:textStyle="italic|bold" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:gravity="center_vertical"
android:orientation="horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/obfuscation_method_label"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold" />

<Spinner
android:id="@+id/obfuscation_method_spinner"
android:layout_width="match_parent"
android:layout_height="48sp"
android:textColor="@color/white"
android:layout_marginStart="12sp"
android:textSize="16sp"
android:textStyle="bold" />

</LinearLayout>

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/res/layout/obfuscation_method_spinner_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/obfuscation_method_spinner_item_label"
style="?android:attr/spinnerItemStyle"
android:textSize="16sp"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:textAlignment="inherit"/>
2 changes: 2 additions & 0 deletions app/src/main/res/values-ru-rRU/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,6 @@ https://play.google.com/store/apps/details?id=org.fptn.vpn
<string name="tile_already_added">Плитка быстрых настроек была добавлена ранее</string>
<string name="tile_added_successfully">Плитка быстрых настроек добавлена</string>
<string name="tile_addition_failed">Плитка быстрых настроек не добавлена!</string>
<string name="protocol_settings_label">Настроки протокола:</string>
<string name="obfuscation_method_label">Маскировка:</string>
</resources>
Loading