From 27594eeae6f40a402bc3110f06d57975168e74e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 4 Jun 2015 19:20:15 +0200 Subject: ics-openvpn as a submodule! beautiful ics-openvpn is now officially on GitHub, and they track openssl and openvpn as submodules, so it's easier to update everything. Just a git submodule update --recursive. I've also set up soft links to native modules from ics-openvpn in app, so that we don't copy files in Gradle (which was causing problems with the submodules .git* files, not being copied). That makes the repo cleaner. --- .../main/java/de/blinkt/openvpn/core/CIDRIP.java | 1 + .../java/de/blinkt/openvpn/core/ConfigParser.java | 39 +- .../blinkt/openvpn/core/ICSOpenVPNApplication.java | 1 - .../de/blinkt/openvpn/core/OpenVPNService.java | 100 ++-- .../de/blinkt/openvpn/core/ProfileManager.java | 318 +++++------ .../de/blinkt/openvpn/core/VPNLaunchHelper.java | 5 +- .../java/de/blinkt/openvpn/core/VpnStatus.java | 598 +++++++++++---------- 7 files changed, 517 insertions(+), 545 deletions(-) (limited to 'app/src/main/java/de/blinkt/openvpn/core') diff --git a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java index e525abd5..94ed8a0b 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java +++ b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java @@ -54,6 +54,7 @@ class CIDRIP { } else { return false; } + } static long getInt(String ipaddr) { diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 5f5d486c..232c454b 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -31,6 +31,9 @@ public class ConfigParser { public static final String CONVERTED_PROFILE = "converted Profile"; private HashMap>> options = new HashMap>>(); private HashMap> meta = new HashMap>(); + private String auth_user_pass_file; + private String crl_verify_file; + public void parseConfig(Reader reader) throws IOException, ConfigParseError { @@ -114,6 +117,14 @@ public class ConfigParser { } + public String getAuthUserPassFile() { + return auth_user_pass_file; + } + + public String getCrlVerifyFile() { + return crl_verify_file; + } + enum linestate { initial, readin_single_quote, reading_quoted, reading_unquoted, done @@ -572,6 +583,7 @@ public class ConfigParser { options.put("remotetls", remotetls); Vector authuser = getOption("auth-user-pass", 0, 1); + if (authuser != null) { if (noauthtypeset) { np.mAuthenticationType = VpnProfile.TYPE_USERPASS; @@ -581,12 +593,24 @@ public class ConfigParser { np.mAuthenticationType = VpnProfile.TYPE_USERPASS_KEYSTORE; } if (authuser.size() > 1) { - // Set option value to password get to embed later. + if (!authuser.get(1).startsWith(VpnProfile.INLINE_TAG)) + auth_user_pass_file = authuser.get(1); np.mUsername = null; useEmbbedUserAuth(np, authuser.get(1)); } } + Vector crlfile = getOption("crl-verify", 1, 2); + if (crlfile != null) { + // If the 'dir' parameter is present just add it as custom option .. + np.mCustomConfigOptions += TextUtils.join(" ", crlfile) + "\n"; + if (crlfile.size() == 2) { + // Save the filename for the config converter to add later + crl_verify_file = crlfile.get(1); + } + } + + Pair conns = parseConnectionOptions(null); np.mConnections = conns.second; @@ -761,6 +785,16 @@ public class ConfigParser { } } + public static void removeCRLCustomOption(VpnProfile np) { + String lines[] = np.mCustomConfigOptions.split("\\r?\\n"); + Vector keeplines = new Vector<>(); + for (String l : lines) { + if (!l.startsWith("crl-verify ")) + keeplines.add(l); + } + np.mCustomConfigOptions = TextUtils.join("\n", keeplines); + } + private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError { for (String option : unsupportedOptions) if (options.containsKey(option)) @@ -772,7 +806,8 @@ public class ConfigParser { if (options.size() > 0) { - np.mCustomConfigOptions += "# These Options were found in the config file do not map to config settings:\n"; + np.mCustomConfigOptions = "# These options found in the config file do not map to config settings:\n" + + np.mCustomConfigOptions; for (Vector> option : options.values()) { diff --git a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java index 56a574dc..6e9e63c5 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java @@ -38,5 +38,4 @@ public class ICSOpenVPNApplication extends Application { //ACRA.init(this); } } - } diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index 3c1ec064..ed3a5446 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -16,7 +16,6 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.ConnectivityManager; -import android.net.NetworkRequest; import android.net.VpnService; import android.os.Binder; import android.os.Build; @@ -51,8 +50,6 @@ import static de.blinkt.openvpn.core.NetworkSpace.ipAddress; import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTED; import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET; import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT; -import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; -import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_NONETWORK; import se.leap.bitmaskclient.Dashboard; @@ -65,7 +62,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac private static final String RESUME_VPN = "se.leap.bitmaskclient.RESUME_VPN"; private static final int OPENVPN_STATUS = 1; private static boolean mNotificationAlwaysVisible = false; - private final Vector mDnslist = new Vector(); + private final Vector mDnslist = new Vector<>(); private final NetworkSpace mRoutes = new NetworkSpace(); private final NetworkSpace mRoutesv6 = new NetworkSpace(); private final IBinder mBinder = new LocalBinder(); @@ -84,7 +81,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac private String mLastTunCfg; private String mRemoteGW; private final Object mProcessLock = new Object(); - private LollipopDeviceStateListener mLollipopDeviceStateListener; // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java public static String humanReadableByteCount(long bytes, boolean mbit) { @@ -176,7 +172,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mNotificationManager.notify(OPENVPN_STATUS, notification); - //startForeground(OPENVPN_STATUS, notification); + startForeground(OPENVPN_STATUS, notification); } private int getIconByConnectionStatus(ConnectionStatus level) { @@ -238,13 +234,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac //ignore exception - } catch (NoSuchMethodException nsm) { - VpnStatus.logException(nsm); - } catch (IllegalArgumentException e) { - VpnStatus.logException(e); - } catch (IllegalAccessException e) { - VpnStatus.logException(e); - } catch (InvocationTargetException e) { + } catch (NoSuchMethodException | IllegalArgumentException | + InvocationTargetException | IllegalAccessException e) { VpnStatus.logException(e); } @@ -328,6 +319,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac /* The intent is null when the service has been restarted */ if (intent == null) { mProfile = ProfileManager.getLastConnectedProfile(this, false); + VpnStatus.logInfo(R.string.service_restarted); /* Got no profile, just stop */ if (mProfile == null) { @@ -415,7 +407,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } else { - HashMap env = new HashMap(); + HashMap env = new HashMap<>(); processThread = new OpenVPNThread(this, argv, env, nativeLibraryDirectory); } @@ -431,7 +423,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac ProfileManager.setConnectedVpnProfile(this, mProfile); /* TODO: At the moment we have no way to handle asynchronous PW input - * Fixing will also allow to handle challenge/responsee authentication */ + * Fixing will also allow to handle challenge/response authentication */ if (mProfile.needUserPWInput(true) != 0) return START_NOT_STICKY; @@ -442,17 +434,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac try { Class cl = Class.forName("de.blinkt.openvpn.core.OpenVPNThreadv3"); return (OpenVPNManagement) cl.getConstructor(OpenVPNService.class, VpnProfile.class).newInstance(this, mProfile); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { + } catch (IllegalArgumentException | InstantiationException | InvocationTargetException | + NoSuchMethodException | ClassNotFoundException | IllegalAccessException e ) { e.printStackTrace(); } return null; @@ -501,8 +484,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac VpnStatus.logInfo(R.string.last_openvpn_tun_config); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mProfile.mAllowLocalLAN) - { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mProfile.mAllowLocalLAN) { allowAllAFFamilies(builder); } @@ -576,6 +558,26 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } } + if ("samsung".equals(Build.BRAND) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mDnslist.size() >= 1) { + // Check if the first DNS Server is in the VPN range + try { + ipAddress dnsServer = new ipAddress(new CIDRIP(mDnslist.get(0), 32), true); + boolean dnsIncluded=false; + for (ipAddress net : positiveIPv4Routes) { + if (net.containsNet(dnsServer)) { + dnsIncluded = true; + } + } + if (!dnsIncluded) { + String samsungwarning = String.format("Warning Samsung Android 5.0+ devices ignore DNS servers outside the VPN range. To enable DNS add a custom route to your DNS Server (%s) or change to a DNS inside your VPN range", mDnslist.get(0)); + VpnStatus.logWarning(samsungwarning); + } + } catch (Exception e) { + VpnStatus.logError("Error parsing DNS Server IP: " + mDnslist.get(0)); + } + } + + if (mDomain != null) builder.addSearchDomain(mDomain); @@ -616,7 +618,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac try { //Debug.stopMethodTracing(); ParcelFileDescriptor tun = builder.establish(); - if (tun==null) + if (tun == null) throw new NullPointerException("Android establish() method returned null (Really broken network configuration?)"); return tun; } catch (Exception e) { @@ -636,22 +638,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac builder.allowFamily(OsConstants.AF_INET6); } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - void removeLollipopCMListener() { - ConnectivityManager cm = (ConnectivityManager) getBaseContext().getSystemService(CONNECTIVITY_SERVICE); - cm.unregisterNetworkCallback(mLollipopDeviceStateListener); - mLollipopDeviceStateListener = null; - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - void addLollipopCMListener() { - ConnectivityManager cm = (ConnectivityManager) getBaseContext().getSystemService(CONNECTIVITY_SERVICE); - NetworkRequest.Builder nrb = new NetworkRequest.Builder(); - - mLollipopDeviceStateListener = new LollipopDeviceStateListener(); - cm.registerNetworkCallback(nrb.build(), mLollipopDeviceStateListener); - } - private void addLocalNetworksToRoutes() { // Add local network interfaces @@ -667,11 +653,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac intf.startsWith("tun") || intf.startsWith("rmnet")) continue; - if (ipAddr==null || netMask == null) { + if (ipAddr == null || netMask == null) { VpnStatus.logError("Local routes are broken?! (Report to author) " + TextUtils.join("|", localRoutes)); continue; } - + if (ipAddr.equals(mLocalIP.mIp)) continue; @@ -854,21 +840,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mDisplayBytecount = true; mConnecttime = System.currentTimeMillis(); lowpriority = true; - if(mProfile.mPersistTun) { - NotificationManager ns = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - ns.cancel(OPENVPN_STATUS); - return; - } - } else if (level == LEVEL_NONETWORK || level == LEVEL_NOTCONNECTED) { - NotificationManager ns = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - ns.cancel(OPENVPN_STATUS); - return; - } else if (level != LEVEL_NOTCONNECTED && mConnecttime > 0) { - mDisplayBytecount = false; - String msg = "Traffic is blocked until the VPN becomes active."; - String ticker = msg; - showNotification(msg, ticker, lowpriority , 0, level); - return; } else { mDisplayBytecount = false; } @@ -878,8 +849,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac // CONNECTED // Does not work :( String msg = getString(resid); - String ticker = msg; - showNotification(msg + " " + logmessage, ticker, lowpriority, 0, level); + showNotification(msg + " " + logmessage, msg, lowpriority, 0, level); } } @@ -902,7 +872,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true)); boolean lowpriority = !mNotificationAlwaysVisible; - //showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED); + showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED); } } diff --git a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java index 1ebc0a57..086cdb44 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java @@ -5,11 +5,15 @@ package de.blinkt.openvpn.core; -import java.io.FileNotFoundException; +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.preference.PreferenceManager; + import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.io.StreamCorruptedException; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -17,213 +21,173 @@ import java.util.Set; import de.blinkt.openvpn.VpnProfile; -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.preference.PreferenceManager; - public class ProfileManager { - private static final String PREFS_NAME = "VPNList"; + private static final String PREFS_NAME = "VPNList"; + private static final String LAST_CONNECTED_PROFILE = "lastConnectedProfile"; + private static ProfileManager instance; + private static VpnProfile mLastConnectedVpn = null; + private HashMap profiles = new HashMap<>(); + private static VpnProfile tmpprofile = null; - private static final String LAST_CONNECTED_PROFILE = "lastConnectedProfile"; + private static VpnProfile get(String key) { + if (tmpprofile != null && tmpprofile.getUUIDString().equals(key)) + return tmpprofile; + if (instance == null) + return null; + return instance.profiles.get(key); + + } - private static ProfileManager instance; + private ProfileManager() { + } + private static void checkInstance(Context context) { + if (instance == null) { + instance = new ProfileManager(); + instance.loadVPNList(context); + } + } - private static VpnProfile mLastConnectedVpn=null; - private HashMap profiles=new HashMap(); - private static VpnProfile tmpprofile=null; + synchronized public static ProfileManager getInstance(Context context) { + checkInstance(context); + return instance; + } + public static void setConntectedVpnProfileDisconnected(Context c) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); + Editor prefsedit = prefs.edit(); + prefsedit.putString(LAST_CONNECTED_PROFILE, null); + prefsedit.apply(); - private static VpnProfile get(String key) { - if (tmpprofile!=null && tmpprofile.getUUIDString().equals(key)) - return tmpprofile; - - if(instance==null) - return null; - return instance.profiles.get(key); - - } + } + public static void setConnectedVpnProfile(Context c, VpnProfile connectedrofile) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); + Editor prefsedit = prefs.edit(); - - private ProfileManager() { } - - private static void checkInstance(Context context) { - if(instance == null) { - instance = new ProfileManager(); - instance.loadVPNList(context); - } - } + prefsedit.putString(LAST_CONNECTED_PROFILE, connectedrofile.getUUIDString()); + prefsedit.apply(); + mLastConnectedVpn = connectedrofile; - synchronized public static ProfileManager getInstance(Context context) { - checkInstance(context); - return instance; - } - - public static void setConntectedVpnProfileDisconnected(Context c) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); - Editor prefsedit = prefs.edit(); - prefsedit.putString(LAST_CONNECTED_PROFILE, null); - prefsedit.apply(); - - } + } - public static void setConnectedVpnProfile(Context c, VpnProfile connectedrofile) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); - Editor prefsedit = prefs.edit(); - - prefsedit.putString(LAST_CONNECTED_PROFILE, connectedrofile.getUUIDString()); - prefsedit.apply(); - mLastConnectedVpn=connectedrofile; - - } - - public static VpnProfile getLastConnectedProfile(Context c, boolean onBoot) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); + public static VpnProfile getLastConnectedProfile(Context c, boolean onBoot) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); - boolean useStartOnBoot = prefs.getBoolean("restartvpnonboot", false); + boolean useStartOnBoot = prefs.getBoolean("restartvpnonboot", false); if (onBoot && !useStartOnBoot) return null; - - String lastConnectedProfile = prefs.getString(LAST_CONNECTED_PROFILE, null); - if(lastConnectedProfile!=null) - return get(c, lastConnectedProfile); - else - return null; - } - - - - - public Collection getProfiles() { - return profiles.values(); - } - - public VpnProfile getProfileByName(String name) { - for (VpnProfile vpnp : profiles.values()) { - if(vpnp.getName().equals(name)) { - return vpnp; - } - } - return null; - } - - public void saveProfileList(Context context) { - SharedPreferences sharedprefs = context.getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE); - Editor editor = sharedprefs.edit(); - editor.putStringSet("vpnlist", profiles.keySet()); - - // For reasing I do not understand at all - // Android saves my prefs file only one time - // if I remove the debug code below :( - 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(VpnProfile tmp) { - ProfileManager.tmpprofile = tmp; - } - - - public void saveProfile(Context context,VpnProfile profile) { - // First let basic settings save its state - - ObjectOutputStream vpnfile; - try { - vpnfile = new ObjectOutputStream(context.openFileOutput((profile.getUUID().toString() + ".vp"),Activity.MODE_PRIVATE)); - - vpnfile.writeObject(profile); - vpnfile.flush(); - vpnfile.close(); - } catch (FileNotFoundException e) { - VpnStatus.logException("saving VPN profile", e); - throw new RuntimeException(e); - } catch (IOException e) { - VpnStatus.logException("saving VPN profile", e); - throw new RuntimeException(e); - } - } - - - private void loadVPNList(Context context) { - profiles = new HashMap(); - SharedPreferences listpref = context.getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE); - Set vlist = listpref.getStringSet("vpnlist", null); - Exception exp =null; - if(vlist==null){ - vlist = new HashSet(); - } - - for (String vpnentry : vlist) { - try { - ObjectInputStream vpnfile = new ObjectInputStream(context.openFileInput(vpnentry + ".vp")); - VpnProfile vp = ((VpnProfile) vpnfile.readObject()); - - // Sanity check - if(vp==null || vp.mName==null || vp.getUUID()==null) - continue; + String lastConnectedProfile = prefs.getString(LAST_CONNECTED_PROFILE, null); + if (lastConnectedProfile != null) + return get(c, lastConnectedProfile); + else + return null; + } - vp.upgradeProfile(); - profiles.put(vp.getUUID().toString(), vp); - } catch (StreamCorruptedException e) { - exp=e; - } catch (FileNotFoundException e) { - exp=e; - } catch (IOException e) { - exp=e; - } catch (ClassNotFoundException e) { - exp=e; - } - if(exp!=null) { - VpnStatus.logException("Loading VPN List",exp); - } - } - } + public Collection getProfiles() { + return profiles.values(); + } + + public VpnProfile getProfileByName(String name) { + for (VpnProfile vpnp : profiles.values()) { + if (vpnp.getName().equals(name)) { + return vpnp; + } + } + return null; + } + + public void saveProfileList(Context context) { + SharedPreferences sharedprefs = context.getSharedPreferences(PREFS_NAME, Activity.MODE_PRIVATE); + Editor editor = sharedprefs.edit(); + editor.putStringSet("vpnlist", profiles.keySet()); + + // For reasing I do not understand at all + // Android saves my prefs file only one time + // if I remove the debug code below :( + 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 int getNumberOfProfiles() { - return profiles.size(); - } + public static void setTemporaryProfile(VpnProfile tmp) { + ProfileManager.tmpprofile = tmp; + } + public void saveProfile(Context context, VpnProfile profile) { + ObjectOutputStream vpnfile; + try { + vpnfile = new ObjectOutputStream(context.openFileOutput((profile.getUUID().toString() + ".vp"), Activity.MODE_PRIVATE)); - public void removeProfile(Context context,VpnProfile profile) { - String vpnentry = profile.getUUID().toString(); - profiles.remove(vpnentry); - saveProfileList(context); - context.deleteFile(vpnentry + ".vp"); - if(mLastConnectedVpn==profile) - mLastConnectedVpn=null; - - } + 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 = context.getSharedPreferences(PREFS_NAME, Activity.MODE_PRIVATE); + Set vlist = listpref.getStringSet("vpnlist", null); + if (vlist == null) { + vlist = new HashSet<>(); + } + + for (String vpnentry : vlist) { + try { + ObjectInputStream vpnfile = new ObjectInputStream(context.openFileInput(vpnentry + ".vp")); + VpnProfile vp = ((VpnProfile) vpnfile.readObject()); + + // Sanity check + if (vp == null || vp.mName == null || vp.getUUID() == null) + continue; + + vp.upgradeProfile(); + profiles.put(vp.getUUID().toString(), vp); + } catch (IOException | ClassNotFoundException e) { + VpnStatus.logException("Loading VPN List", e); + } + } + } - public static VpnProfile get(Context context, String profileUUID) { - checkInstance(context); - return get(profileUUID); - } + public void removeProfile(Context context, VpnProfile profile) { + String vpnentry = profile.getUUID().toString(); + profiles.remove(vpnentry); + saveProfileList(context); + context.deleteFile(vpnentry + ".vp"); + if (mLastConnectedVpn == profile) + mLastConnectedVpn = null; + } + public static VpnProfile get(Context context, String profileUUID) { + checkInstance(context); + return get(profileUUID); + } - public static VpnProfile getLastConnectedVpn() { - return mLastConnectedVpn; - } + public static VpnProfile getLastConnectedVpn() { + return mLastConnectedVpn; + } } diff --git a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java index 73ed05bc..47cb633c 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java @@ -8,7 +8,6 @@ package de.blinkt.openvpn.core; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; import android.os.Build; import java.io.File; @@ -67,14 +66,14 @@ public class VPNLaunchHelper { public static String[] buildOpenvpnArgv(Context c) { - Vector args = new Vector(); + Vector args = new Vector<>(); // Add fixed paramenters //args.add("/data/data/de.blinkt.openvpn/lib/openvpn"); args.add(writeMiniVPN(c)); args.add("--config"); - args.add(c.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE); + args.add(getConfigFilePath(c)); return args.toArray(new String[args.size()]); } diff --git a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java index ffc8097d..dc3fa1c7 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -6,6 +6,7 @@ package de.blinkt.openvpn.core; import android.annotation.SuppressLint; +import android.app.Activity; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -14,10 +15,10 @@ import android.content.pm.Signature; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; -import se.leap.bitmaskclient.R; +import android.text.TextUtils; import java.io.ByteArrayInputStream; -import java.io.FileNotFoundException; +import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; import java.security.MessageDigest; @@ -32,28 +33,30 @@ import java.util.Locale; import java.util.UnknownFormatConversionException; import java.util.Vector; +import se.leap.bitmaskclient.R; + public class VpnStatus { - public static LinkedList logbuffer; + public static LinkedList logbuffer; - private static Vector logListener; - private static Vector stateListener; - private static Vector byteCountListener; + private static Vector logListener; + private static Vector stateListener; + private static Vector byteCountListener; - private static String mLaststatemsg=""; + private static String mLaststatemsg = ""; - private static String mLaststate = "NOPROCESS"; + private static String mLaststate = "NOPROCESS"; - private static int mLastStateresid=R.string.state_noprocess; + private static int mLastStateresid = R.string.state_noprocess; - private static long mlastByteCount[]={0,0,0,0}; + private static long mlastByteCount[] = {0, 0, 0, 0}; - public static void logException(LogLevel ll, String context, Exception e) { + public static void logException(LogLevel ll, String context, Exception e) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); LogItem li; - if (context !=null) { + if (context != null) { li = new LogItem(ll, R.string.unhandled_exception_context, e.getMessage(), sw.toString(), context); } else { li = new LogItem(ll, R.string.unhandled_exception, e.getMessage(), sw.toString()); @@ -71,18 +74,16 @@ public class VpnStatus { private static final int MAXLOGENTRIES = 1000; - public static final String MANAGMENT_PREFIX = "M:"; - public enum ConnectionStatus { LEVEL_CONNECTED, LEVEL_VPNPAUSED, LEVEL_CONNECTING_SERVER_REPLIED, LEVEL_CONNECTING_NO_SERVER_REPLY_YET, LEVEL_NONETWORK, - LEVEL_NOTCONNECTED, - LEVEL_AUTH_FAILED, - LEVEL_WAITING_FOR_USER_INPUT, - UNKNOWN_LEVEL + LEVEL_NOTCONNECTED, + LEVEL_AUTH_FAILED, + LEVEL_WAITING_FOR_USER_INPUT, + UNKNOWN_LEVEL } public enum LogLevel { @@ -93,6 +94,7 @@ public class VpnStatus { DEBUG(4); protected int mValue; + LogLevel(int value) { mValue = value; } @@ -103,59 +105,64 @@ public class VpnStatus { public static LogLevel getEnumByValue(int value) { switch (value) { - case 1: return INFO; - case 2: return ERROR; - case 3: return WARNING; - case 4: return DEBUG; - default: return null; + case 1: + return INFO; + case 2: + return ERROR; + case 3: + return WARNING; + case 4: + return DEBUG; + default: + return null; } } } // keytool -printcert -jarfile de.blinkt.openvpn_85.apk - public static final byte[] officalkey = {-58, -42, -44, -106, 90, -88, -87, -88, -52, -124, 84, 117, 66, 79, -112, -111, -46, 86, -37, 109}; - public static final byte[] officaldebugkey = {-99, -69, 45, 71, 114, -116, 82, 66, -99, -122, 50, -70, -56, -111, 98, -35, -65, 105, 82, 43}; - public static final byte[] amazonkey = {-116, -115, -118, -89, -116, -112, 120, 55, 79, -8, -119, -23, 106, -114, -85, -56, -4, 105, 26, -57}; + public static final byte[] officalkey = {-58, -42, -44, -106, 90, -88, -87, -88, -52, -124, 84, 117, 66, 79, -112, -111, -46, 86, -37, 109}; + public static final byte[] officaldebugkey = {-99, -69, 45, 71, 114, -116, 82, 66, -99, -122, 50, -70, -56, -111, 98, -35, -65, 105, 82, 43}; + public static final byte[] amazonkey = {-116, -115, -118, -89, -116, -112, 120, 55, 79, -8, -119, -23, 106, -114, -85, -56, -4, 105, 26, -57}; public static final byte[] fdroidkey = {-92, 111, -42, -46, 123, -96, -60, 79, -27, -31, 49, 103, 11, -54, -68, -27, 17, 2, 121, 104}; - private static ConnectionStatus mLastLevel=ConnectionStatus.LEVEL_NOTCONNECTED; + private static ConnectionStatus mLastLevel = ConnectionStatus.LEVEL_NOTCONNECTED; - static { - logbuffer = new LinkedList(); - logListener = new Vector(); - stateListener = new Vector(); - byteCountListener = new Vector(); - logInformation(); - } + static { + logbuffer = new LinkedList<>(); + logListener = new Vector<>(); + stateListener = new Vector<>(); + byteCountListener = new Vector<>(); + logInformation(); + } - public static class LogItem implements Parcelable { + public static class LogItem implements Parcelable { - private Object [] mArgs = null; - private String mMessage = null; - private int mRessourceId; - // Default log priority - LogLevel mLevel = LogLevel.INFO; - private long logtime = System.currentTimeMillis(); + private Object[] mArgs = null; + private String mMessage = null; + private int mRessourceId; + // Default log priority + LogLevel mLevel = LogLevel.INFO; + private long logtime = System.currentTimeMillis(); private int mVerbosityLevel = -1; - private LogItem(int ressourceId, Object[] args) { - mRessourceId = ressourceId; - mArgs = args; - } + private LogItem(int ressourceId, Object[] args) { + mRessourceId = ressourceId; + mArgs = args; + } public LogItem(LogLevel level, int verblevel, String message) { - mMessage=message; + mMessage = message; mLevel = level; mVerbosityLevel = verblevel; } @Override - public int describeContents() { - return 0; - } + public int describeContents() { + return 0; + } @Override @@ -169,65 +176,65 @@ public class VpnStatus { dest.writeLong(logtime); } - public LogItem(Parcel in) { - mArgs = in.readArray(Object.class.getClassLoader()); - mMessage = in.readString(); - mRessourceId = in.readInt(); - mLevel = LogLevel.getEnumByValue(in.readInt()); + public LogItem(Parcel in) { + mArgs = in.readArray(Object.class.getClassLoader()); + mMessage = in.readString(); + mRessourceId = in.readInt(); + mLevel = LogLevel.getEnumByValue(in.readInt()); mVerbosityLevel = in.readInt(); - logtime = in.readLong(); - } + logtime = in.readLong(); + } - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - public LogItem createFromParcel(Parcel in) { - return new LogItem(in); - } + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public LogItem createFromParcel(Parcel in) { + return new LogItem(in); + } - public LogItem[] newArray(int size) { - return new LogItem[size]; - } - }; + public LogItem[] newArray(int size) { + return new LogItem[size]; + } + }; - public LogItem(LogLevel loglevel,int ressourceId, Object... args) { + public LogItem(LogLevel loglevel, int ressourceId, Object... args) { mRessourceId = ressourceId; - mArgs =args; + mArgs = args; mLevel = loglevel; } - public LogItem(LogLevel loglevel, String msg) { - mLevel = loglevel; - mMessage = msg; - } + public LogItem(LogLevel loglevel, String msg) { + mLevel = loglevel; + mMessage = msg; + } - public LogItem(LogLevel loglevel, int ressourceId) { - mRessourceId =ressourceId; - mLevel = loglevel; - } + public LogItem(LogLevel loglevel, int ressourceId) { + mRessourceId = ressourceId; + mLevel = loglevel; + } - public String getString(Context c) { + public String getString(Context c) { try { - if(mMessage !=null) { - return mMessage; - } else { - if(c!=null) { - if(mRessourceId==R.string.mobile_info) - return getMobileInfoString(c); - if(mArgs == null) - return c.getString(mRessourceId); - else - return c.getString(mRessourceId,mArgs); - } else { - String str = String.format(Locale.ENGLISH,"Log (no context) resid %d", mRessourceId); - if(mArgs !=null) - for(Object o:mArgs) - str += "|" + o.toString(); - - return str; - } - } + if (mMessage != null) { + return mMessage; + } else { + if (c != null) { + if (mRessourceId == R.string.mobile_info) + return getMobileInfoString(c); + if (mArgs == null) + return c.getString(mRessourceId); + else + return c.getString(mRessourceId, mArgs); + } else { + String str = String.format(Locale.ENGLISH, "Log (no context) resid %d", mRessourceId); + if (mArgs != null) + str += TextUtils.join("|", mArgs); + + + return str; + } + } } catch (UnknownFormatConversionException e) { if (c != null) throw new UnknownFormatConversionException(e.getLocalizedMessage() + getString(null)); @@ -235,68 +242,66 @@ public class VpnStatus { throw e; } catch (java.util.FormatFlagsConversionMismatchException e) { if (c != null) - throw new FormatFlagsConversionMismatchException(e.getLocalizedMessage() + getString(null),e.getConversion()); + throw new FormatFlagsConversionMismatchException(e.getLocalizedMessage() + getString(null), e.getConversion()); else throw e; } - } + } - public LogLevel getLogLevel() - { + public LogLevel getLogLevel() { return mLevel; } // The lint is wrong here - @SuppressLint("StringFormatMatches") - private String getMobileInfoString(Context c) { - c.getPackageManager(); - String apksign="error getting package signature"; - - String version="error getting version"; - try { - Signature raw = c.getPackageManager().getPackageInfo(c.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0]; - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(raw.toByteArray())); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] der = cert.getEncoded(); - md.update(der); - byte[] digest = md.digest(); - - if (Arrays.equals(digest, officalkey)) - apksign = c.getString(R.string.official_build); - else if (Arrays.equals(digest, officaldebugkey)) - apksign = c.getString(R.string.debug_build); - else if (Arrays.equals(digest, amazonkey)) - apksign = "amazon version"; - else if (Arrays.equals(digest, fdroidkey)) + @SuppressLint("StringFormatMatches") + private String getMobileInfoString(Context c) { + c.getPackageManager(); + String apksign = "error getting package signature"; + + String version = "error getting version"; + try { + Signature raw = c.getPackageManager().getPackageInfo(c.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0]; + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(raw.toByteArray())); + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] der = cert.getEncoded(); + md.update(der); + byte[] digest = md.digest(); + + if (Arrays.equals(digest, officalkey)) + apksign = c.getString(R.string.official_build); + else if (Arrays.equals(digest, officaldebugkey)) + apksign = c.getString(R.string.debug_build); + else if (Arrays.equals(digest, amazonkey)) + apksign = "amazon version"; + else if (Arrays.equals(digest, fdroidkey)) apksign = "F-Droid built and signed version"; else - apksign = c.getString(R.string.built_by,cert.getSubjectX500Principal().getName()); + apksign = c.getString(R.string.built_by, cert.getSubjectX500Principal().getName()); - PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0); - version = packageinfo.versionName; + PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0); + version = packageinfo.versionName; - } catch (NameNotFoundException e) { - } catch (CertificateException e) { - } catch (NoSuchAlgorithmException e) { - } + } catch (NameNotFoundException | CertificateException | + NoSuchAlgorithmException ignored) { + } - Object[] argsext = Arrays.copyOf(mArgs, mArgs.length+2); - argsext[argsext.length-1]=apksign; - argsext[argsext.length-2]=version; + Object[] argsext = Arrays.copyOf(mArgs, mArgs.length + 2); + argsext[argsext.length - 1] = apksign; + argsext[argsext.length - 2] = version; - return c.getString(R.string.mobile_info_extended, argsext); + return c.getString(R.string.mobile_info_extended, argsext); - } + } - public long getLogtime() { - return logtime; - } + public long getLogtime() { + return logtime; + } public int getVerbosityLevel() { - if (mVerbosityLevel==-1) { + if (mVerbosityLevel == -1) { // Hack: // For message not from OpenVPN, report the status level as log level return mLevel.getInt(); @@ -305,90 +310,94 @@ public class VpnStatus { } } + public void saveLogToDisk(Context c) { + + new File(c.getCacheDir(), "log.xml"); + + + } + + public interface LogListener { + void newLog(LogItem logItem); + } + public interface StateListener { + void updateState(String state, String logmessage, int localizedResId, ConnectionStatus level); + } - public interface LogListener { - void newLog(LogItem logItem); - } - - public interface StateListener { - void updateState(String state, String logmessage, int localizedResId, ConnectionStatus level); - } - - public interface ByteCountListener { - void updateByteCount(long in, long out, long diffIn, long diffOut); - } - - public synchronized static void logMessage(LogLevel level,String prefix, String message) - { - newLogItem(new LogItem(level, prefix + message)); - - } - - public synchronized static void clearLog() { - logbuffer.clear(); - logInformation(); - } - - private static void logInformation() { - logInfo(R.string.mobile_info,Build.MODEL, Build.BOARD,Build.BRAND,Build.VERSION.SDK_INT); - } - - public synchronized static void addLogListener(LogListener ll){ - logListener.add(ll); - } - - public synchronized static void removeLogListener(LogListener ll) { - logListener.remove(ll); - } - - public synchronized static void addByteCountListener(ByteCountListener bcl) { - bcl.updateByteCount(mlastByteCount[0], mlastByteCount[1], mlastByteCount[2], mlastByteCount[3]); - byteCountListener.add(bcl); - } - - public synchronized static void removeByteCountListener(ByteCountListener bcl) { - byteCountListener.remove(bcl); - } - - - public synchronized static void addStateListener(StateListener sl){ - if(!stateListener.contains(sl)){ - stateListener.add(sl); - if(mLaststate!=null) - sl.updateState(mLaststate, mLaststatemsg, mLastStateresid, mLastLevel); - } - } - - private static int getLocalizedState(String state){ - if (state.equals("CONNECTING")) - return R.string.state_connecting; - else if (state.equals("WAIT")) - return R.string.state_wait; - else if (state.equals("AUTH")) - return R.string.state_auth; - else if (state.equals("GET_CONFIG")) - return R.string.state_get_config; - else if (state.equals("ASSIGN_IP")) - return R.string.state_assign_ip; - else if (state.equals("ADD_ROUTES")) - return R.string.state_add_routes; - else if (state.equals("CONNECTED")) - return R.string.state_connected; - else if (state.equals("DISCONNECTED")) - return R.string.state_disconnected; - else if (state.equals("RECONNECTING")) - return R.string.state_reconnecting; - else if (state.equals("EXITING")) - return R.string.state_exiting; - else if (state.equals("RESOLVE")) - return R.string.state_resolve; - else if (state.equals("TCP_CONNECT")) - return R.string.state_tcp_connect; - else - return R.string.unknown_state; - - } + public interface ByteCountListener { + void updateByteCount(long in, long out, long diffIn, long diffOut); + } + + public synchronized static void logMessage(LogLevel level, String prefix, String message) { + newLogItem(new LogItem(level, prefix + message)); + + } + + public synchronized static void clearLog() { + logbuffer.clear(); + logInformation(); + } + + private static void logInformation() { + logInfo(R.string.mobile_info, Build.MODEL, Build.BOARD, Build.BRAND, Build.VERSION.SDK_INT); + } + + public synchronized static void addLogListener(LogListener ll) { + logListener.add(ll); + } + + public synchronized static void removeLogListener(LogListener ll) { + logListener.remove(ll); + } + + public synchronized static void addByteCountListener(ByteCountListener bcl) { + bcl.updateByteCount(mlastByteCount[0], mlastByteCount[1], mlastByteCount[2], mlastByteCount[3]); + byteCountListener.add(bcl); + } + + public synchronized static void removeByteCountListener(ByteCountListener bcl) { + byteCountListener.remove(bcl); + } + + + public synchronized static void addStateListener(StateListener sl) { + if (!stateListener.contains(sl)) { + stateListener.add(sl); + if (mLaststate != null) + sl.updateState(mLaststate, mLaststatemsg, mLastStateresid, mLastLevel); + } + } + + private static int getLocalizedState(String state) { + if (state.equals("CONNECTING")) + return R.string.state_connecting; + else if (state.equals("WAIT")) + return R.string.state_wait; + else if (state.equals("AUTH")) + return R.string.state_auth; + else if (state.equals("GET_CONFIG")) + return R.string.state_get_config; + else if (state.equals("ASSIGN_IP")) + return R.string.state_assign_ip; + else if (state.equals("ADD_ROUTES")) + return R.string.state_add_routes; + else if (state.equals("CONNECTED")) + return R.string.state_connected; + else if (state.equals("DISCONNECTED")) + return R.string.state_disconnected; + else if (state.equals("RECONNECTING")) + return R.string.state_reconnecting; + else if (state.equals("EXITING")) + return R.string.state_exiting; + else if (state.equals("RESOLVE")) + return R.string.state_resolve; + else if (state.equals("TCP_CONNECT")) + return R.string.state_tcp_connect; + else + return R.string.unknown_state; + + } public static void updateStatePause(OpenVPNManagement.pauseReason pauseReason) { switch (pauseReason) { @@ -405,88 +414,84 @@ public class VpnStatus { } - private static ConnectionStatus getLevel(String state){ - String[] noreplyet = {"CONNECTING","WAIT", "RECONNECTING", "RESOLVE", "TCP_CONNECT"}; - String[] reply = {"AUTH","GET_CONFIG","ASSIGN_IP","ADD_ROUTES"}; - String[] connected = {"CONNECTED"}; - String[] notconnected = {"DISCONNECTED", "EXITING"}; - - for(String x:noreplyet) - if(state.equals(x)) - return ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET; - - for(String x:reply) - if(state.equals(x)) - return ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED; + private static ConnectionStatus getLevel(String state) { + String[] noreplyet = {"CONNECTING", "WAIT", "RECONNECTING", "RESOLVE", "TCP_CONNECT"}; + String[] reply = {"AUTH", "GET_CONFIG", "ASSIGN_IP", "ADD_ROUTES"}; + String[] connected = {"CONNECTED"}; + String[] notconnected = {"DISCONNECTED", "EXITING"}; - for(String x:connected) - if(state.equals(x)) - return ConnectionStatus.LEVEL_CONNECTED; + for (String x : noreplyet) + if (state.equals(x)) + return ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET; - for(String x:notconnected) - if(state.equals(x)) - return ConnectionStatus.LEVEL_NOTCONNECTED; + for (String x : reply) + if (state.equals(x)) + return ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED; - return ConnectionStatus.UNKNOWN_LEVEL; + for (String x : connected) + if (state.equals(x)) + return ConnectionStatus.LEVEL_CONNECTED; - } + for (String x : notconnected) + if (state.equals(x)) + return ConnectionStatus.LEVEL_NOTCONNECTED; + return ConnectionStatus.UNKNOWN_LEVEL; + } - public synchronized static void removeStateListener(StateListener sl) { - stateListener.remove(sl); - } + public synchronized static void removeStateListener(StateListener sl) { + stateListener.remove(sl); + } - synchronized public static LogItem[] getlogbuffer() { + synchronized public static LogItem[] getlogbuffer() { - // The stoned way of java to return an array from a vector - // brought to you by eclipse auto complete - return logbuffer.toArray(new LogItem[logbuffer.size()]); + // The stoned way of java to return an array from a vector + // brought to you by eclipse auto complete + return logbuffer.toArray(new LogItem[logbuffer.size()]); - } + } - public static void updateStateString (String state, String msg) { - int rid = getLocalizedState(state); - ConnectionStatus level = getLevel(state); - updateStateString(state, msg, rid, level); - } + public static void updateStateString(String state, String msg) { + int rid = getLocalizedState(state); + ConnectionStatus level = getLevel(state); + updateStateString(state, msg, rid, level); + } - public synchronized static void updateStateString(String state, String msg, int resid, ConnectionStatus level) { + public synchronized static void updateStateString(String state, String msg, int resid, ConnectionStatus level) { // Workound for OpenVPN doing AUTH and wait and being connected // Simply ignore these state if (mLastLevel == ConnectionStatus.LEVEL_CONNECTED && - (state.equals("WAIT") || state.equals("AUTH"))) - { - newLogItem(new LogItem((LogLevel.DEBUG), String.format("Ignoring OpenVPN Status in CONNECTED state (%s->%s): %s",state,level.toString(),msg))); + (state.equals("WAIT") || state.equals("AUTH"))) { + newLogItem(new LogItem((LogLevel.DEBUG), String.format("Ignoring OpenVPN Status in CONNECTED state (%s->%s): %s", state, level.toString(), msg))); return; } - mLaststate= state; - mLaststatemsg = msg; - mLastStateresid = resid; - mLastLevel = level; - + mLaststate = state; + mLaststatemsg = msg; + mLastStateresid = resid; + mLastLevel = level; for (StateListener sl : stateListener) { - sl.updateState(state,msg,resid,level); - } + sl.updateState(state, msg, resid, level); + } //newLogItem(new LogItem((LogLevel.DEBUG), String.format("New OpenVPN Status (%s->%s): %s",state,level.toString(),msg))); - } + } - public static void logInfo(String message) { - newLogItem(new LogItem(LogLevel.INFO, message)); - } + public static void logInfo(String message) { + newLogItem(new LogItem(LogLevel.INFO, message)); + } public static void logDebug(String message) { newLogItem(new LogItem(LogLevel.DEBUG, message)); } public static void logInfo(int resourceId, Object... args) { - newLogItem(new LogItem(LogLevel.INFO, resourceId, args)); - } + newLogItem(new LogItem(LogLevel.INFO, resourceId, args)); + } public static void logDebug(int resourceId, Object... args) { newLogItem(new LogItem(LogLevel.DEBUG, resourceId, args)); @@ -494,19 +499,19 @@ public class VpnStatus { private synchronized static void newLogItem(LogItem logItem) { - logbuffer.addLast(logItem); - if(logbuffer.size()>MAXLOGENTRIES) - logbuffer.removeFirst(); + logbuffer.addLast(logItem); + if (logbuffer.size() > MAXLOGENTRIES) + logbuffer.removeFirst(); - for (LogListener ll : logListener) { - ll.newLog(logItem); - } - } + for (LogListener ll : logListener) { + ll.newLog(logItem); + } + } - public static void logError(String msg) { - newLogItem(new LogItem(LogLevel.ERROR, msg)); + public static void logError(String msg) { + newLogItem(new LogItem(LogLevel.ERROR, msg)); - } + } public static void logWarning(int resourceId, Object... args) { newLogItem(new LogItem(LogLevel.WARNING, resourceId, args)); @@ -518,11 +523,12 @@ public class VpnStatus { public static void logError(int resourceId) { - newLogItem(new LogItem(LogLevel.ERROR, resourceId)); - } - public static void logError(int resourceId, Object... args) { - newLogItem(new LogItem(LogLevel.ERROR, resourceId, args)); - } + newLogItem(new LogItem(LogLevel.ERROR, resourceId)); + } + + public static void logError(int resourceId, Object... args) { + newLogItem(new LogItem(LogLevel.ERROR, resourceId, args)); + } public static void logMessageOpenVPN(LogLevel level, int ovpnlevel, String message) { newLogItem(new LogItem(level, ovpnlevel, message)); @@ -531,19 +537,17 @@ public class VpnStatus { public static synchronized void updateByteCount(long in, long out) { - long lastIn = mlastByteCount[0]; - long lastOut = mlastByteCount[1]; - long diffIn = mlastByteCount[2] = in - lastIn; - long diffOut = mlastByteCount[3] = out - lastOut; - - - - mlastByteCount = new long[] {in,out,diffIn,diffOut}; - for(ByteCountListener bcl:byteCountListener){ - bcl.updateByteCount(in, out, diffIn,diffOut); - } - } + long lastIn = mlastByteCount[0]; + long lastOut = mlastByteCount[1]; + long diffIn = mlastByteCount[2] = in - lastIn; + long diffOut = mlastByteCount[3] = out - lastOut; + + mlastByteCount = new long[]{in, out, diffIn, diffOut}; + for (ByteCountListener bcl : byteCountListener) { + bcl.updateByteCount(in, out, diffIn, diffOut); + } + } } -- cgit v1.2.3 From ffb6d2fe8ddd69f0e7239fa9505dc255eed6b348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 4 Jun 2015 20:17:43 +0200 Subject: Updated bitmask branch from ics-openvpn fork, second notification --- app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'app/src/main/java/de/blinkt/openvpn/core') diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index ed3a5446..f9cb9a86 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -172,7 +172,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mNotificationManager.notify(OPENVPN_STATUS, notification); - startForeground(OPENVPN_STATUS, notification); + //startForeground(OPENVPN_STATUS, notification); } private int getIconByConnectionStatus(ConnectionStatus level) { @@ -840,6 +840,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mDisplayBytecount = true; mConnecttime = System.currentTimeMillis(); lowpriority = true; + String ns = Context.NOTIFICATION_SERVICE; + NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); + mNotificationManager.cancel(OPENVPN_STATUS); } else { mDisplayBytecount = false; } @@ -849,7 +852,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac // CONNECTED // Does not work :( String msg = getString(resid); - showNotification(msg + " " + logmessage, msg, lowpriority, 0, level); + // showNotification(msg + " " + logmessage, msg, lowpriority, 0, level); } } @@ -872,7 +875,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true)); boolean lowpriority = !mNotificationAlwaysVisible; - showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED); + //showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED); } } -- cgit v1.2.3