summaryrefslogtreecommitdiff
path: root/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java')
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java235
1 files changed, 140 insertions, 95 deletions
diff --git a/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
index 4cf98da2..06822817 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
@@ -10,15 +10,18 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
-import java.util.UUID;
import de.blinkt.openvpn.VpnProfile;
@@ -30,9 +33,12 @@ public class ProfileManager {
private static ProfileManager instance;
private static VpnProfile mLastConnectedVpn = null;
- private HashMap<String, VpnProfile> profiles = new HashMap<>();
private static VpnProfile tmpprofile = null;
+ private HashMap<String, VpnProfile> profiles = new HashMap<>();
+
+ private ProfileManager() {
+ }
private static VpnProfile get(String key) {
if (tmpprofile != null && tmpprofile.getUUIDString().equals(key))
@@ -41,16 +47,12 @@ public class ProfileManager {
if (instance == null)
return null;
return instance.profiles.get(key);
-
- }
-
-
- private ProfileManager() {
}
private static void checkInstance(Context context) {
if (instance == null) {
instance = new ProfileManager();
+ ProfileEncryption.initMasterCryptAlias();
instance.loadVPNList(context);
}
}
@@ -65,7 +67,6 @@ public class ProfileManager {
Editor prefsedit = prefs.edit();
prefsedit.putString(LAST_CONNECTED_PROFILE, null);
prefsedit.apply();
-
}
/**
@@ -78,7 +79,6 @@ public class ProfileManager {
prefsedit.putString(LAST_CONNECTED_PROFILE, connectedProfile.getUUIDString());
prefsedit.apply();
mLastConnectedVpn = connectedProfile;
-
}
/**
@@ -94,6 +94,122 @@ public class ProfileManager {
return null;
}
+ public static void setTemporaryProfile(Context c, VpnProfile tmp) {
+ tmp.mTemporaryProfile = true;
+ ProfileManager.tmpprofile = tmp;
+ saveProfile(c, tmp);
+ }
+
+ public static boolean isTempProfile() {
+ return mLastConnectedVpn != null && mLastConnectedVpn == tmpprofile;
+ }
+
+ public static void saveProfile(Context context, VpnProfile profile) {
+ SharedPreferences prefs = Preferences.getDefaultSharedPreferences(context);
+ boolean preferEncryption = prefs.getBoolean("preferencryption", true);
+
+ profile.mVersion += 1;
+ ObjectOutputStream vpnFile;
+
+ String filename = profile.getUUID().toString();
+
+ if (profile.mTemporaryProfile)
+ filename = TEMPORARY_PROFILE_FILENAME;
+
+ File encryptedFileOld = context.getFileStreamPath(filename + ".cpold");
+
+ if (encryptedFileOld.exists())
+ {
+ encryptedFileOld.delete();
+ }
+
+ String deleteIfExists;
+ try {
+ FileOutputStream vpnFileOut;
+ if (preferEncryption && ProfileEncryption.encryptionEnabled()) {
+ File encryptedFile = context.getFileStreamPath(filename + ".cp");
+
+ if (encryptedFile.exists())
+ {
+ if (!encryptedFile.renameTo(encryptedFileOld))
+ {
+ VpnStatus.logInfo("Cannot rename " + encryptedFile);
+ }
+ }
+ vpnFileOut = ProfileEncryption.getEncryptedVpOutput(context, encryptedFile);
+ deleteIfExists = filename + ".vp";
+ if (encryptedFileOld.exists()) {
+ encryptedFileOld.delete();
+ }
+ }
+ else {
+ vpnFileOut = context.openFileOutput(filename + ".vp", Activity.MODE_PRIVATE);
+ deleteIfExists = filename + ".cp";
+ }
+
+ vpnFile = new ObjectOutputStream(vpnFileOut);
+
+ vpnFile.writeObject(profile);
+ vpnFile.flush();
+ vpnFile.close();
+
+ File delete = context.getFileStreamPath(deleteIfExists);
+ if (delete.exists())
+ {
+ //noinspection ResultOfMethodCallIgnored
+ delete.delete();
+ }
+
+
+ } catch (IOException | GeneralSecurityException e) {
+ VpnStatus.logException("saving VPN profile", e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static VpnProfile get(Context context, String profileUUID) {
+ return get(context, profileUUID, 0, 10);
+ }
+
+ public static VpnProfile get(Context context, String profileUUID, int version, int tries) {
+ checkInstance(context);
+ VpnProfile profile = get(profileUUID);
+ int tried = 0;
+ while ((profile == null || profile.mVersion < version) && (tried++ < tries)) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ignored) {
+ }
+ instance.loadVPNList(context);
+ profile = get(profileUUID);
+ }
+
+ if (tried > 5) {
+ int ver = profile == null ? -1 : profile.mVersion;
+ VpnStatus.logError(String.format(Locale.US, "Used x %d tries to get current version (%d/%d) of the profile", tried, ver, version));
+ }
+ return profile;
+ }
+
+ public static VpnProfile getLastConnectedVpn() {
+ return mLastConnectedVpn;
+ }
+
+ public static VpnProfile getAlwaysOnVPN(Context context) {
+ checkInstance(context);
+ SharedPreferences prefs = Preferences.getDefaultSharedPreferences(context);
+
+ String uuid = prefs.getString("alwaysOnVpn", null);
+ return get(uuid);
+
+ }
+
+ public static void updateLRU(Context c, VpnProfile profile) {
+ profile.mLastUsed = System.currentTimeMillis();
+ // LRU does not change the profile, no need for the service to refresh
+ if (profile != tmpprofile)
+ saveProfile(c, profile);
+ }
public Collection<VpnProfile> getProfiles() {
return profiles.values();
@@ -119,46 +235,12 @@ public class ProfileManager {
int counter = sharedprefs.getInt("counter", 0);
editor.putInt("counter", counter + 1);
editor.apply();
-
}
public void addProfile(VpnProfile profile) {
profiles.put(profile.getUUID().toString(), profile);
-
- }
-
- public static void setTemporaryProfile(Context c, VpnProfile tmp) {
- tmp.mTemporaryProfile = true;
- ProfileManager.tmpprofile = tmp;
- saveProfile(c, tmp);
- }
-
- public static boolean isTempProfile() {
- return mLastConnectedVpn != null && mLastConnectedVpn == tmpprofile;
- }
-
- public static void saveProfile(Context context, VpnProfile profile) {
-
- profile.mVersion += 1;
- ObjectOutputStream vpnFile;
-
- String filename = profile.getUUID().toString() + ".vp";
- if (profile.mTemporaryProfile)
- filename = TEMPORARY_PROFILE_FILENAME + ".vp";
-
- try {
- vpnFile = new ObjectOutputStream(context.openFileOutput(filename, Activity.MODE_PRIVATE));
-
- vpnFile.writeObject(profile);
- vpnFile.flush();
- vpnFile.close();
- } catch (IOException e) {
- VpnStatus.logException("saving VPN profile", e);
- throw new RuntimeException(e);
- }
}
-
private void loadVPNList(Context context) {
profiles = new HashMap<>();
SharedPreferences listpref = Preferences.getSharedPreferencesMulti(PREFS_NAME, context);
@@ -170,9 +252,20 @@ public class ProfileManager {
vlist.add(TEMPORARY_PROFILE_FILENAME);
for (String vpnentry : vlist) {
- ObjectInputStream vpnfile=null;
+ ObjectInputStream vpnfile = null;
try {
- vpnfile = new ObjectInputStream(context.openFileInput(vpnentry + ".vp"));
+ FileInputStream vpInput;
+ File encryptedPath = context.getFileStreamPath(vpnentry + ".cp");
+ File encryptedPathOld = context.getFileStreamPath(vpnentry + ".cpold");
+
+ if (encryptedPath.exists()) {
+ vpInput = ProfileEncryption.getEncryptedVpInput(context, encryptedPath);
+ } else if (encryptedPathOld.exists()) {
+ vpInput = ProfileEncryption.getEncryptedVpInput(context, encryptedPathOld);
+ } else {
+ vpInput = context.openFileInput(vpnentry + ".vp");
+ }
+ vpnfile = new ObjectInputStream(vpInput);
VpnProfile vp = ((VpnProfile) vpnfile.readObject());
// Sanity check
@@ -187,11 +280,11 @@ public class ProfileManager {
}
- } catch (IOException | ClassNotFoundException e) {
+ } catch (IOException | ClassNotFoundException | GeneralSecurityException e) {
if (!vpnentry.equals(TEMPORARY_PROFILE_FILENAME))
VpnStatus.logException("Loading VPN List", e);
} finally {
- if (vpnfile!=null) {
+ if (vpnfile != null) {
try {
vpnfile.close();
} catch (IOException e) {
@@ -202,7 +295,6 @@ public class ProfileManager {
}
}
-
public void removeProfile(Context context, VpnProfile profile) {
String vpnentry = profile.getUUID().toString();
profiles.remove(vpnentry);
@@ -212,51 +304,4 @@ public class ProfileManager {
mLastConnectedVpn = null;
}
-
- public static VpnProfile get(Context context, String profileUUID) {
- return get(context, profileUUID, 0, 10);
- }
-
- public static VpnProfile get(Context context, String profileUUID, int version, int tries) {
- checkInstance(context);
- VpnProfile profile = get(profileUUID);
- int tried = 0;
- while ((profile == null || profile.mVersion < version) && (tried++ < tries)) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException ignored) {
- }
- instance.loadVPNList(context);
- profile = get(profileUUID);
- int ver = profile == null ? -1 : profile.mVersion;
- }
-
- if (tried > 5)
-
- {
- int ver = profile == null ? -1 : profile.mVersion;
- VpnStatus.logError(String.format(Locale.US, "Used x %d tries to get current version (%d/%d) of the profile", tried, ver, version));
- }
- return profile;
- }
-
- public static VpnProfile getLastConnectedVpn() {
- return mLastConnectedVpn;
- }
-
- public static VpnProfile getAlwaysOnVPN(Context context) {
- checkInstance(context);
- SharedPreferences prefs = Preferences.getDefaultSharedPreferences(context);
-
- String uuid = prefs.getString("alwaysOnVpn", null);
- return get(uuid);
-
- }
-
- public static void updateLRU(Context c, VpnProfile profile) {
- profile.mLastUsed = System.currentTimeMillis();
- // LRU does not change the profile, no need for the service to refresh
- if (profile != tmpprofile)
- saveProfile(c, profile);
- }
}