diff options
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.java | 235 |
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); - } } |