From 8dbfc2cf65c808827058d426cf57932eb9eaefc4 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Tue, 20 Aug 2013 13:27:49 +0200 Subject: Rename OpenVPN class to a VPNStatus --HG-- rename : src/de/blinkt/openvpn/core/OpenVPN.java => src/de/blinkt/openvpn/core/VpnStatus.java --- src/de/blinkt/openvpn/LaunchVPN.java | 26 +- src/de/blinkt/openvpn/LogWindow.java | 24 +- src/de/blinkt/openvpn/VpnProfile.java | 16 +- .../blinkt/openvpn/api/ExternalOpenVPNService.java | 10 +- .../blinkt/openvpn/core/DeviceStateReceiver.java | 8 +- src/de/blinkt/openvpn/core/OpenVPN.java | 424 -------------------- src/de/blinkt/openvpn/core/OpenVPNThread.java | 22 +- .../openvpn/core/OpenVpnManagementThread.java | 34 +- src/de/blinkt/openvpn/core/OpenVpnService.java | 60 +-- src/de/blinkt/openvpn/core/ProxyDetection.java | 4 +- src/de/blinkt/openvpn/core/VPNLaunchHelper.java | 12 +- src/de/blinkt/openvpn/core/VpnStatus.java | 432 +++++++++++++++++++++ src/de/blinkt/openvpn/core/X509Utils.java | 2 +- .../blinkt/openvpn/fragments/SendDumpFragment.java | 4 +- 14 files changed, 542 insertions(+), 536 deletions(-) delete mode 100644 src/de/blinkt/openvpn/core/OpenVPN.java create mode 100644 src/de/blinkt/openvpn/core/VpnStatus.java (limited to 'src/de/blinkt') diff --git a/src/de/blinkt/openvpn/LaunchVPN.java b/src/de/blinkt/openvpn/LaunchVPN.java index 07cf323c..336de255 100644 --- a/src/de/blinkt/openvpn/LaunchVPN.java +++ b/src/de/blinkt/openvpn/LaunchVPN.java @@ -17,7 +17,6 @@ import android.os.Bundle; import android.os.Parcelable; import android.preference.PreferenceManager; import android.text.InputType; -import android.text.Layout; import android.text.TextUtils; import android.text.method.PasswordTransformationMethod; import android.view.View; @@ -26,11 +25,10 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.EditText; -import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; -import de.blinkt.openvpn.core.OpenVPN; -import de.blinkt.openvpn.core.OpenVPN.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; import de.blinkt.openvpn.core.ProfileManager; import de.blinkt.openvpn.core.VPNLaunchHelper; @@ -104,7 +102,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { profileToConnect = ProfileManager.getInstance(this).getProfileByName(shortcutName); if(profileToConnect ==null) { - OpenVPN.logError(R.string.shortcut_profile_notfound); + VpnStatus.logError(R.string.shortcut_profile_notfound); // show Log window to display error showLogWindow(); finish(); @@ -254,8 +252,8 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - OpenVPN.updateStateString("USER_VPN_PASSWORD_CANCELLED", "", R.string.state_user_vpn_password_cancelled, - ConnectionStatus.LEVEL_NOTCONNECTED); + VpnStatus.updateStateString("USER_VPN_PASSWORD_CANCELLED", "", R.string.state_user_vpn_password_cancelled, + ConnectionStatus.LEVEL_NOTCONNECTED); finish(); } }); @@ -271,8 +269,8 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { if(resultCode == Activity.RESULT_OK) { int needpw = mSelectedProfile.needUserPWInput(); if(needpw !=0) { - OpenVPN.updateStateString("USER_VPN_PASSWORD", "", R.string.state_user_vpn_password, - ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT); + VpnStatus.updateStateString("USER_VPN_PASSWORD", "", R.string.state_user_vpn_password, + ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT); askForPW(needpw); } else { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); @@ -284,8 +282,8 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { } } else if (resultCode == Activity.RESULT_CANCELED) { // User does not want us to start, so we just vanish - OpenVPN.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, - ConnectionStatus.LEVEL_NOTCONNECTED); + VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, + ConnectionStatus.LEVEL_NOTCONNECTED); finish(); } @@ -336,15 +334,15 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { if (intent != null) { - OpenVPN.updateStateString("USER_VPN_PERMISSION", "", R.string.state_user_vpn_password, - ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT); + VpnStatus.updateStateString("USER_VPN_PERMISSION", "", R.string.state_user_vpn_password, + ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT); // Start the query try { startActivityForResult(intent, START_VPN_PROFILE); } catch (ActivityNotFoundException ane) { // Shame on you Sony! At least one user reported that // an official Sony Xperia Arc S image triggers this exception - OpenVPN.logError(R.string.no_vpn_support_image); + VpnStatus.logError(R.string.no_vpn_support_image); showLogWindow(); } } else { diff --git a/src/de/blinkt/openvpn/LogWindow.java b/src/de/blinkt/openvpn/LogWindow.java index 10f3c0ab..7eadfe60 100644 --- a/src/de/blinkt/openvpn/LogWindow.java +++ b/src/de/blinkt/openvpn/LogWindow.java @@ -13,11 +13,11 @@ import android.text.format.DateFormat; import android.view.*; import android.widget.*; import android.widget.AdapterView.OnItemLongClickListener; -import de.blinkt.openvpn.core.OpenVPN; -import de.blinkt.openvpn.core.OpenVPN.ConnectionStatus; -import de.blinkt.openvpn.core.OpenVPN.LogItem; -import de.blinkt.openvpn.core.OpenVPN.LogListener; -import de.blinkt.openvpn.core.OpenVPN.StateListener; +import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus.LogItem; +import de.blinkt.openvpn.core.VpnStatus.LogListener; +import de.blinkt.openvpn.core.VpnStatus.StateListener; import de.blinkt.openvpn.core.OpenVpnService; import de.blinkt.openvpn.core.OpenVpnService.LocalBinder; import de.blinkt.openvpn.core.ProfileManager; @@ -77,14 +77,14 @@ public class LogWindow extends ListActivity implements StateListener { mHandler = new Handler(this); } - OpenVPN.addLogListener(this); + VpnStatus.addLogListener(this); } private void initLogBuffer() { myEntries.clear(); - Collections.addAll(myEntries, OpenVPN.getlogbuffer()); + Collections.addAll(myEntries, VpnStatus.getlogbuffer()); } String getLogStr() { @@ -224,8 +224,8 @@ public class LogWindow extends ListActivity implements StateListener { void clearLog() { // Actually is probably called from GUI Thread as result of the user // pressing a button. But better safe than sorry - OpenVPN.clearLog(); - OpenVPN.logMessage(0,"","Log cleared."); + VpnStatus.clearLog(); + VpnStatus.logMessage(0, "", "Log cleared."); mHandler.sendEmptyMessage(MESSAGE_CLEARLOG); } @@ -312,7 +312,7 @@ public class LogWindow extends ListActivity implements StateListener { @Override protected void onResume() { super.onResume(); - OpenVPN.addStateListener(this); + VpnStatus.addStateListener(this); Intent intent = new Intent(this, OpenVpnService.class); intent.setAction(OpenVpnService.START_SERVICE); @@ -367,7 +367,7 @@ public class LogWindow extends ListActivity implements StateListener { @Override protected void onStop() { super.onStop(); - OpenVPN.removeStateListener(this); + VpnStatus.removeStateListener(this); unbindService(mConnection); getPreferences(0).edit().putInt(LOGTIMEFORMAT, ladapter.mTimeFormat).apply(); @@ -424,7 +424,7 @@ public class LogWindow extends ListActivity implements StateListener { @Override protected void onDestroy() { - OpenVPN.removeLogListener(ladapter); + VpnStatus.removeLogListener(ladapter); super.onDestroy(); } diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index 138386ae..a8c6825f 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -14,7 +14,7 @@ import android.util.Base64; import android.widget.Toast; import de.blinkt.openvpn.core.NativeUtils; -import de.blinkt.openvpn.core.OpenVPN; +import de.blinkt.openvpn.core.VpnStatus; import de.blinkt.openvpn.core.OpenVpnService; import de.blinkt.openvpn.core.X509Utils; import org.spongycastle.util.io.pem.PemObject; @@ -549,7 +549,7 @@ public class VpnProfile implements Serializable { return getKeyStoreCertificates(context, 5); } - String[] getKeyStoreCertificates(Context context,int tries) { + synchronized String[] getKeyStoreCertificates(Context context,int tries) { PrivateKey privateKey = null; X509Certificate[] cachain; try { @@ -561,7 +561,7 @@ public class VpnProfile implements Serializable { cachain = KeyChain.getCertificateChain(context, mAlias); if (cachain.length <= 1 && !nonNull(mCaFilename)) { - OpenVPN.logMessage(0, "", context.getString(R.string.keychain_nocacert)); + VpnStatus.logMessage(0, "", context.getString(R.string.keychain_nocacert)); } else { StringWriter ksStringWriter = new StringWriter(); @@ -587,7 +587,7 @@ public class VpnProfile implements Serializable { caout= caoutWriter.toString(); } catch (Exception e) { - OpenVPN.logError("Could not read CA certificate" + e.getLocalizedMessage()); + VpnStatus.logError("Could not read CA certificate" + e.getLocalizedMessage()); } } @@ -625,10 +625,10 @@ public class VpnProfile implements Serializable { } catch (IOException e) { e.printStackTrace(); } catch (KeyChainException e) { - OpenVPN.logMessage(0, "", context.getString(R.string.keychain_access)); + VpnStatus.logMessage(0, "", context.getString(R.string.keychain_access)); if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { if (!mAlias.matches("^[a-zA-Z0-9]$")) { - OpenVPN.logError(R.string.jelly_keystore_alphanumeric_bug); + VpnStatus.logError(R.string.jelly_keystore_alphanumeric_bug); } } } catch (AssertionError e) { @@ -814,7 +814,7 @@ public class VpnProfile implements Serializable { err = e; } - OpenVPN.logError(R.string.error_rsa_sign, err.getClass().toString(), err.getLocalizedMessage()); + VpnStatus.logError(R.string.error_rsa_sign, err.getClass().toString(), err.getLocalizedMessage()); return null; @@ -852,7 +852,7 @@ public class VpnProfile implements Serializable { } catch (InvalidKeyException e) { err = e; } - OpenVPN.logError(R.string.error_rsa_sign, err.getClass().toString(), err.getLocalizedMessage()); + VpnStatus.logError(R.string.error_rsa_sign, err.getClass().toString(), err.getLocalizedMessage()); return null; diff --git a/src/de/blinkt/openvpn/api/ExternalOpenVPNService.java b/src/de/blinkt/openvpn/api/ExternalOpenVPNService.java index 35374c77..77374355 100644 --- a/src/de/blinkt/openvpn/api/ExternalOpenVPNService.java +++ b/src/de/blinkt/openvpn/api/ExternalOpenVPNService.java @@ -25,9 +25,9 @@ import de.blinkt.openvpn.R; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.ConfigParser; import de.blinkt.openvpn.core.ConfigParser.ConfigParseError; -import de.blinkt.openvpn.core.OpenVPN; -import de.blinkt.openvpn.core.OpenVPN.ConnectionStatus; -import de.blinkt.openvpn.core.OpenVPN.StateListener; +import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus.StateListener; import de.blinkt.openvpn.core.OpenVpnService; import de.blinkt.openvpn.core.OpenVpnService.LocalBinder; import de.blinkt.openvpn.core.ProfileManager; @@ -65,7 +65,7 @@ public class ExternalOpenVPNService extends Service implements StateListener { @Override public void onCreate() { super.onCreate(); - OpenVPN.addStateListener(this); + VpnStatus.addStateListener(this); mExtAppDb = new ExternalAppDatabase(this); Intent intent = new Intent(getBaseContext(), OpenVpnService.class); @@ -231,7 +231,7 @@ public class ExternalOpenVPNService extends Service implements StateListener { super.onDestroy(); mCallbacks.kill(); unbindService(mConnection); - OpenVPN.removeStateListener(this); + VpnStatus.removeStateListener(this); } class UpdateMessage { diff --git a/src/de/blinkt/openvpn/core/DeviceStateReceiver.java b/src/de/blinkt/openvpn/core/DeviceStateReceiver.java index 2c1db63c..8a148e10 100644 --- a/src/de/blinkt/openvpn/core/DeviceStateReceiver.java +++ b/src/de/blinkt/openvpn/core/DeviceStateReceiver.java @@ -9,7 +9,7 @@ import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.preference.PreferenceManager; import de.blinkt.openvpn.R; -import de.blinkt.openvpn.core.OpenVPN.ByteCountListener; +import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; import java.util.LinkedList; @@ -67,7 +67,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL if (windowtraffic < TRAFFIC_LIMIT) { screen = connectState.DISCONNECTED; - OpenVPN.logInfo(R.string.screenoff_pause, + VpnStatus.logInfo(R.string.screenoff_pause, OpenVpnService.humanReadableByteCount(TRAFFIC_LIMIT, false), TRAFFIC_WINDOW); mManagement.pause(getPauseReason()); @@ -109,7 +109,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL if (screenOffPause) { if (!ProfileManager.getLastConnectedVpn().mPersistTun) - OpenVPN.logError(R.string.screen_nopersistenttun); + VpnStatus.logError(R.string.screen_nopersistenttun); screen = connectState.PENDINGDISCONNECT; fillTrafficData(); @@ -203,7 +203,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL if (!netstatestring.equals(lastStateMsg)) - OpenVPN.logInfo(R.string.netstatus, netstatestring); + VpnStatus.logInfo(R.string.netstatus, netstatestring); lastStateMsg = netstatestring; } diff --git a/src/de/blinkt/openvpn/core/OpenVPN.java b/src/de/blinkt/openvpn/core/OpenVPN.java deleted file mode 100644 index af090204..00000000 --- a/src/de/blinkt/openvpn/core/OpenVPN.java +++ /dev/null @@ -1,424 +0,0 @@ -package de.blinkt.openvpn.core; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.Signature; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import de.blinkt.openvpn.R; - -import java.io.ByteArrayInputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.Locale; -import java.util.Vector; - -public class OpenVPN { - - - public static LinkedList logbuffer; - - private static Vector logListener; - private static Vector stateListener; - private static Vector byteCountListener; - - private static String mLaststatemsg=""; - - private static String mLaststate = "NOPROCESS"; - - private static int mLastStateresid=R.string.state_noprocess; - - private static long mlastByteCount[]={0,0,0,0}; - - - - 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 - } - - 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}; - - private static ConnectionStatus mLastLevel=ConnectionStatus.LEVEL_NOTCONNECTED; - - static { - logbuffer = new LinkedList(); - logListener = new Vector(); - stateListener = new Vector(); - byteCountListener = new Vector(); - logInformation(); - } - - - public static class LogItem implements Parcelable { - public static final int ERROR = 1; - public static final int INFO = 2; - public static final int VERBOSE = 3; - - private Object [] mArgs = null; - private String mMessage = null; - private int mRessourceId; - // Default log priority - int mLevel = INFO; - private long logtime = System.currentTimeMillis(); - - public LogItem(int ressourceId, Object[] args) { - mRessourceId = ressourceId; - mArgs = args; - } - - @Override - public int describeContents() { - return 0; - } - - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeArray(mArgs); - dest.writeString(mMessage); - dest.writeInt(mRessourceId); - dest.writeInt(mLevel); - dest.writeLong(logtime); - } - - public LogItem(Parcel in) { - mArgs = in.readArray(Object.class.getClassLoader()); - mMessage = in.readString(); - mRessourceId = in.readInt(); - mLevel = in.readInt(); - logtime = in.readLong(); - } - - 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(int loglevel,int ressourceId, Object[] args) { - mRessourceId = ressourceId; - mArgs = args; - mLevel = loglevel; - } - - - public LogItem(String message) { - mMessage = message; - } - - public LogItem(int loglevel, String msg) { - mLevel = loglevel; - mMessage = msg; - } - - - public LogItem(int loglevel, int ressourceId) { - mRessourceId =ressourceId; - mLevel = loglevel; - } - - public String getString(Context c) { - 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; - } - } - } - - // 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 - apksign = c.getString(R.string.built_by,cert.getSubjectX500Principal().getName()); - - PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0); - version = packageinfo.versionName; - - } catch (NameNotFoundException e) { - } catch (CertificateException e) { - } catch (NoSuchAlgorithmException e) { - } - - 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); - - } - - public long getLogtime() { - return logtime; - } - - - } - - private static final int MAXLOGENTRIES = 500; - - public static final String MANAGMENT_PREFIX = "M:"; - - - 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(int level,String prefix, String message) - { - newlogItem(new LogItem(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) { - case noNetwork: - OpenVPN.updateStateString("NONETWORK", "", R.string.state_nonetwork, ConnectionStatus.LEVEL_NONETWORK); - break; - case screenOff: - OpenVPN.updateStateString("SCREENOFF", "", R.string.state_screenoff, ConnectionStatus.LEVEL_VPNPAUSED); - break; - case userPause: - OpenVPN.updateStateString("USERPAUSE", "", R.string.state_userpause, ConnectionStatus.LEVEL_VPNPAUSED); - break; - } - - } - - 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; - - 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); - } - - - 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()]); - - } - - 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) { - mLaststate= state; - mLaststatemsg = msg; - mLastStateresid = resid; - mLastLevel = level; - - for (StateListener sl : stateListener) { - sl.updateState(state,msg,resid,level); - } - } - - public static void logInfo(String message) { - newlogItem(new LogItem(LogItem.INFO, message)); - } - - public static void logInfo(int ressourceId, Object... args) { - newlogItem(new LogItem(LogItem.INFO, ressourceId, args)); - } - - private synchronized static void newlogItem(LogItem logItem) { - logbuffer.addLast(logItem); - if(logbuffer.size()>MAXLOGENTRIES) - logbuffer.removeFirst(); - - for (LogListener ll : logListener) { - ll.newLog(logItem); - } - } - - public static void logError(String msg) { - newlogItem(new LogItem(LogItem.ERROR, msg)); - - } - - public static void logError(int ressourceId) { - newlogItem(new LogItem(LogItem.ERROR, ressourceId)); - } - public static void logError(int ressourceId, Object... args) { - newlogItem(new LogItem(LogItem.ERROR, ressourceId,args)); - } - - 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); - } - } - - - -} diff --git a/src/de/blinkt/openvpn/core/OpenVPNThread.java b/src/de/blinkt/openvpn/core/OpenVPNThread.java index 100990bb..da6a394a 100644 --- a/src/de/blinkt/openvpn/core/OpenVPNThread.java +++ b/src/de/blinkt/openvpn/core/OpenVPNThread.java @@ -3,8 +3,8 @@ package de.blinkt.openvpn.core; import android.util.Log; import de.blinkt.openvpn.R; import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.OpenVPN.ConnectionStatus; -import de.blinkt.openvpn.core.OpenVPN.LogItem; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus.LogItem; import java.io.*; import java.text.SimpleDateFormat; @@ -50,26 +50,26 @@ public class OpenVPNThread implements Runnable { if (mProcess!=null) exitvalue = mProcess.waitFor(); } catch ( IllegalThreadStateException ite) { - OpenVPN.logError("Illegal Thread state: " + ite.getLocalizedMessage()); + VpnStatus.logError("Illegal Thread state: " + ite.getLocalizedMessage()); } catch (InterruptedException ie) { - OpenVPN.logError("InterruptedException: " + ie.getLocalizedMessage()); + VpnStatus.logError("InterruptedException: " + ie.getLocalizedMessage()); } if( exitvalue != 0) - OpenVPN.logError("Process exited with exit value " + exitvalue); + VpnStatus.logError("Process exited with exit value " + exitvalue); - OpenVPN.updateStateString("NOPROCESS","No process running.", R.string.state_noprocess,ConnectionStatus.LEVEL_NOTCONNECTED); + VpnStatus.updateStateString("NOPROCESS", "No process running.", R.string.state_noprocess, ConnectionStatus.LEVEL_NOTCONNECTED); if(mDumpPath!=null) { try { BufferedWriter logout = new BufferedWriter(new FileWriter(mDumpPath + ".log")); SimpleDateFormat timeformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.GERMAN); - for(LogItem li :OpenVPN.getlogbuffer()){ + for(LogItem li : VpnStatus.getlogbuffer()){ String time = timeformat.format(new Date(li.getLogtime())); logout.write(time +" " + li.getString(mService) + "\n"); } logout.close(); - OpenVPN.logError(R.string.minidump_generated); + VpnStatus.logError(R.string.minidump_generated); } catch (IOException e) { - OpenVPN.logError("Writing minidump log: " +e.getLocalizedMessage()); + VpnStatus.logError("Writing minidump log: " + e.getLocalizedMessage()); } } @@ -111,12 +111,12 @@ public class OpenVPNThread implements Runnable { mDumpPath = logline.substring(DUMP_PATH_STRING.length()); - OpenVPN.logMessage(0, "P:", logline); + VpnStatus.logMessage(0, "P:", logline); } } catch (IOException e) { - OpenVPN.logMessage(0, "", "Error reading from output of OpenVPN process"+ e.getLocalizedMessage()); + VpnStatus.logMessage(0, "", "Error reading from output of OpenVPN process" + e.getLocalizedMessage()); e.printStackTrace(); stopProcess(); } diff --git a/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java index e2ac1526..7e436f79 100644 --- a/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull; import de.blinkt.openvpn.R; import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.OpenVPN.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; import java.io.FileDescriptor; import java.io.IOException; @@ -131,7 +131,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { try { fds = mSocket.getAncillaryFileDescriptors(); } catch (IOException e) { - OpenVPN.logMessage(0, "", "Error reading fds from socket" + e.getLocalizedMessage()); + VpnStatus.logMessage(0, "", "Error reading fds from socket" + e.getLocalizedMessage()); e.printStackTrace(); } if(fds!=null){ @@ -182,7 +182,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { exp.printStackTrace(); Log.d("Openvpn", "Failed to retrieve fd from socket: " + fd); - OpenVPN.logMessage(0, "", "Failed to retrieve fd from socket: " + exp.getLocalizedMessage()); + VpnStatus.logMessage(0, "", "Failed to retrieve fd from socket: " + exp.getLocalizedMessage()); } private String processInput(String pendingInput) { @@ -228,11 +228,11 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { // 0 unix time stamp // 1 log level N,I,E etc. // 2 log message - OpenVPN.logMessage(0, "", args[2]); + VpnStatus.logMessage(0, "", args[2]); } else if (cmd.equals("RSA_SIGN")) { processSignCommand(argument); } else { - OpenVPN.logMessage(0, "MGMT:", "Got unrecognized command" + command); + VpnStatus.logMessage(0, "MGMT:", "Got unrecognized command" + command); Log.i(TAG, "Got unrecognized command" + command); } } else if (command.startsWith("SUCCESS:")) { @@ -240,7 +240,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { return; } else { Log.i(TAG, "Got unrecognized line from managment" + command); - OpenVPN.logMessage(0, "MGMT:", "Got unrecognized line from management:" + command); + VpnStatus.logMessage(0, "MGMT:", "Got unrecognized line from management:" + command); } } private void handleHold() { @@ -249,7 +249,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } else { mWaitingForRelease=true; - OpenVPN.updateStatePause(lastPauseReason); + VpnStatus.updateStatePause(lastPauseReason); } @@ -292,7 +292,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { if(proxyaddr instanceof InetSocketAddress ){ InetSocketAddress isa = (InetSocketAddress) proxyaddr; - OpenVPN.logInfo(R.string.using_proxy, isa.getHostName(),isa.getPort()); + VpnStatus.logInfo(R.string.using_proxy, isa.getHostName(), isa.getPort()); String proxycmd = String.format(Locale.ENGLISH,"proxy HTTP %s %d\n", isa.getHostName(),isa.getPort()); managmentCommand(proxycmd); @@ -305,9 +305,9 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { String[] args = argument.split(",",3); String currentstate = args[1]; if(args[2].equals(",,")) - OpenVPN.updateStateString(currentstate,""); + VpnStatus.updateStateString(currentstate, ""); else - OpenVPN.updateStateString(currentstate,args[2]); + VpnStatus.updateStateString(currentstate, args[2]); } @@ -317,7 +317,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { long in = Long.parseLong(argument.substring(0, comma)); long out = Long.parseLong(argument.substring(comma+1)); - OpenVPN.updateByteCount(in,out); + VpnStatus.updateByteCount(in, out); } @@ -373,7 +373,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { if(!extra.equals("tun")) { // We only support tun String errmsg = String.format("Devicetype %s requested, but only tun is possible with the Android API, sorry!",extra); - OpenVPN.logMessage(0, "", errmsg ); + VpnStatus.logMessage(0, "", errmsg); return false; } @@ -416,7 +416,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } catch (IOException e) { exp =e; } - OpenVPN.logMessage(0, "", "Could not send fd over socket:" + exp.getLocalizedMessage()); + VpnStatus.logMessage(0, "", "Could not send fd over socket:" + exp.getLocalizedMessage()); exp.printStackTrace(); return false; @@ -439,7 +439,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { return; } } catch (StringIndexOutOfBoundsException sioob) { - OpenVPN.logMessage(0, "", "Could not parse management Password command: " + argument); + VpnStatus.logMessage(0, "", "Could not parse management Password command: " + argument); return; } @@ -457,7 +457,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { String cmd = String.format("password '%s' %s\n", needed, VpnProfile.openVpnEscape(pw)); managmentCommand(cmd); } else { - OpenVPN.logMessage(0, OpenVPN.MANAGMENT_PREFIX, String.format("Openvpn requires Authentication type '%s' but no password/key information available", needed)); + VpnStatus.logMessage(0, VpnStatus.MANAGMENT_PREFIX, String.format("Openvpn requires Authentication type '%s' but no password/key information available", needed)); } } @@ -466,7 +466,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { private void proccessPWFailed(String needed, String args) { - OpenVPN.updateStateString("AUTH_FAILED", needed + args,R.string.state_auth_failed,ConnectionStatus.LEVEL_AUTH_FAILED); + VpnStatus.updateStateString("AUTH_FAILED", needed + args, R.string.state_auth_failed, ConnectionStatus.LEVEL_AUTH_FAILED); } @@ -493,7 +493,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { else // If signalusr1 is called update the state string // if there is another for stopping - OpenVPN.updateStatePause(lastPauseReason); + VpnStatus.updateStatePause(lastPauseReason); } public void reconnect() { diff --git a/src/de/blinkt/openvpn/core/OpenVpnService.java b/src/de/blinkt/openvpn/core/OpenVpnService.java index e703e579..37c0d94f 100644 --- a/src/de/blinkt/openvpn/core/OpenVpnService.java +++ b/src/de/blinkt/openvpn/core/OpenVpnService.java @@ -17,9 +17,9 @@ import android.preference.PreferenceManager; import de.blinkt.openvpn.LogWindow; import de.blinkt.openvpn.R; import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.OpenVPN.ByteCountListener; -import de.blinkt.openvpn.core.OpenVPN.ConnectionStatus; -import de.blinkt.openvpn.core.OpenVPN.StateListener; +import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus.StateListener; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -27,7 +27,7 @@ import java.util.HashMap; import java.util.Locale; import java.util.Vector; -import static de.blinkt.openvpn.core.OpenVPN.ConnectionStatus.*; +import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.*; public class OpenVpnService extends VpnService implements StateListener, Callback, ByteCountListener { public static final String START_SERVICE = "de.blinkt.openvpn.START_SERVICE"; @@ -93,7 +93,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac private void endVpnService() { mProcessThread = null; - OpenVPN.removeByteCountListener(this); + VpnStatus.removeByteCountListener(this); unregisterDeviceStateReceiver(); ProfileManager.setConntectedVpnProfileDisconnected(this); if (!mStarting) { @@ -101,7 +101,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac if (!mNotificationAlwaysVisible) { stopSelf(); - OpenVPN.removeStateListener(this); + VpnStatus.removeStateListener(this); } } } @@ -235,13 +235,13 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac filter.addAction(Intent.ACTION_SCREEN_ON); mDeviceStateReceiver = new DeviceStateReceiver(magnagement); registerReceiver(mDeviceStateReceiver, filter); - OpenVPN.addByteCountListener(mDeviceStateReceiver); + VpnStatus.addByteCountListener(mDeviceStateReceiver); } synchronized void unregisterDeviceStateReceiver() { if (mDeviceStateReceiver != null) try { - OpenVPN.removeByteCountListener(mDeviceStateReceiver); + VpnStatus.removeByteCountListener(mDeviceStateReceiver); this.unregisterReceiver(mDeviceStateReceiver); } catch (IllegalArgumentException iae) { // I don't know why this happens: @@ -258,8 +258,8 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac if (intent != null && intent.getBooleanExtra(ALWAYS_SHOW_NOTIFICATION, false)) mNotificationAlwaysVisible = true; - OpenVPN.addStateListener(this); - OpenVPN.addByteCountListener(this); + VpnStatus.addStateListener(this); + VpnStatus.addByteCountListener(this); if (intent != null && PAUSE_VPN.equals(intent.getAction())) { if (mDeviceStateReceiver != null) @@ -329,7 +329,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac Thread mSocketManagerThread = new Thread(ovpnManagementThread, "OpenVPNManagementThread"); mSocketManagerThread.start(); mManagement = ovpnManagementThread; - OpenVPN.logInfo("started Socket Thread"); + VpnStatus.logInfo("started Socket Thread"); } } @@ -381,7 +381,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac this.unregisterReceiver(mDeviceStateReceiver); } // Just in case unregister for state - OpenVPN.removeStateListener(this); + VpnStatus.removeStateListener(this); } @@ -389,7 +389,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac Builder builder = new Builder(); if (mLocalIP == null && mLocalIPv6 == null) { - OpenVPN.logMessage(0, "", getString(R.string.opentun_no_ipaddr)); + VpnStatus.logMessage(0, "", getString(R.string.opentun_no_ipaddr)); return null; } @@ -397,7 +397,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac try { builder.addAddress(mLocalIP.mIp, mLocalIP.len); } catch (IllegalArgumentException iae) { - OpenVPN.logError(R.string.dns_add_error, mLocalIP, iae.getLocalizedMessage()); + VpnStatus.logError(R.string.dns_add_error, mLocalIP, iae.getLocalizedMessage()); return null; } } @@ -407,7 +407,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac try { builder.addAddress(ipv6parts[0], Integer.parseInt(ipv6parts[1])); } catch (IllegalArgumentException iae) { - OpenVPN.logError(R.string.dns_add_error, mLocalIPv6, iae.getLocalizedMessage()); + VpnStatus.logError(R.string.ip_add_error, mLocalIPv6, iae.getLocalizedMessage()); return null; } @@ -418,7 +418,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac try { builder.addDnsServer(dns); } catch (IllegalArgumentException iae) { - OpenVPN.logError(R.string.dns_add_error, dns, iae.getLocalizedMessage()); + VpnStatus.logError(R.string.dns_add_error, dns, iae.getLocalizedMessage()); } } @@ -430,7 +430,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac try { builder.addRoute(route.mIp, route.len); } catch (IllegalArgumentException ia) { - OpenVPN.logMessage(0, "", getString(R.string.route_rejected) + route + " " + ia.getLocalizedMessage()); + VpnStatus.logMessage(0, "", getString(R.string.route_rejected) + route + " " + ia.getLocalizedMessage()); } } @@ -439,18 +439,18 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac String[] v6parts = v6route.split("/"); builder.addRoute(v6parts[0], Integer.parseInt(v6parts[1])); } catch (IllegalArgumentException ia) { - OpenVPN.logMessage(0, "", getString(R.string.route_rejected) + v6route + " " + ia.getLocalizedMessage()); + VpnStatus.logMessage(0, "", getString(R.string.route_rejected) + v6route + " " + ia.getLocalizedMessage()); } } if (mDomain != null) builder.addSearchDomain(mDomain); - OpenVPN.logInfo(R.string.last_openvpn_tun_config); - OpenVPN.logInfo(R.string.local_ip_info, mLocalIP.mIp, mLocalIP.len, mLocalIPv6, mMtu); - OpenVPN.logInfo(R.string.dns_server_info, joinString(mDnslist), mDomain); - OpenVPN.logInfo(R.string.routes_info, joinString(mRoutes)); - OpenVPN.logInfo(R.string.routes_info6, joinString(mRoutesv6)); + VpnStatus.logInfo(R.string.last_openvpn_tun_config); + VpnStatus.logInfo(R.string.local_ip_info, mLocalIP.mIp, mLocalIP.len, mLocalIPv6, mMtu); + VpnStatus.logInfo(R.string.dns_server_info, joinString(mDnslist), mDomain); + VpnStatus.logInfo(R.string.routes_info, joinString(mRoutes)); + VpnStatus.logInfo(R.string.routes_info6, joinString(mRoutesv6)); String session = mProfile.mName; if (mLocalIP != null && mLocalIPv6 != null) @@ -462,7 +462,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac // No DNS Server, log a warning if (mDnslist.size() == 0) - OpenVPN.logInfo(R.string.warn_no_dns); + VpnStatus.logInfo(R.string.warn_no_dns); // Reset information mDnslist.clear(); @@ -477,9 +477,9 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac try { return builder.establish(); } catch (Exception e) { - OpenVPN.logMessage(0, "", getString(R.string.tun_open_error)); - OpenVPN.logMessage(0, "", getString(R.string.error) + e.getLocalizedMessage()); - OpenVPN.logMessage(0, "", getString(R.string.tun_error_helpful)); + VpnStatus.logMessage(0, "", getString(R.string.tun_open_error)); + VpnStatus.logMessage(0, "", getString(R.string.error) + e.getLocalizedMessage()); + VpnStatus.logMessage(0, "", getString(R.string.tun_error_helpful)); return null; } @@ -510,11 +510,11 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac public void addRoute(String dest, String mask) { CIDRIP route = new CIDRIP(dest, mask); if (route.len == 32 && !mask.equals("255.255.255.255")) { - OpenVPN.logMessage(0, "", getString(R.string.route_not_cidr, dest, mask)); + VpnStatus.logMessage(0, "", getString(R.string.route_not_cidr, dest, mask)); } if (route.normalise()) - OpenVPN.logMessage(0, "", getString(R.string.route_not_netip, dest, route.len, route.mIp)); + VpnStatus.logMessage(0, "", getString(R.string.route_not_netip, dest, route.len, route.mIp)); mRoutes.add(route); } @@ -544,7 +544,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac else mLocalIP.len = 31; } else { - OpenVPN.logMessage(0, "", getString(R.string.ip_not_cidr, local, netmask, mode)); + VpnStatus.logMessage(0, "", getString(R.string.ip_not_cidr, local, netmask, mode)); } } } diff --git a/src/de/blinkt/openvpn/core/ProxyDetection.java b/src/de/blinkt/openvpn/core/ProxyDetection.java index bc8bf293..4f66c503 100644 --- a/src/de/blinkt/openvpn/core/ProxyDetection.java +++ b/src/de/blinkt/openvpn/core/ProxyDetection.java @@ -27,9 +27,9 @@ public class ProxyDetection { } } catch (MalformedURLException e) { - OpenVPN.logError(R.string.getproxy_error,e.getLocalizedMessage()); + VpnStatus.logError(R.string.getproxy_error, e.getLocalizedMessage()); } catch (URISyntaxException e) { - OpenVPN.logError(R.string.getproxy_error,e.getLocalizedMessage()); + VpnStatus.logError(R.string.getproxy_error, e.getLocalizedMessage()); } return null; } diff --git a/src/de/blinkt/openvpn/core/VPNLaunchHelper.java b/src/de/blinkt/openvpn/core/VPNLaunchHelper.java index 7d14ee6b..f6e8e0e3 100644 --- a/src/de/blinkt/openvpn/core/VPNLaunchHelper.java +++ b/src/de/blinkt/openvpn/core/VPNLaunchHelper.java @@ -26,7 +26,7 @@ public class VPNLaunchHelper { mvpn = context.getAssets().open("minivpn." + Build.CPU_ABI); } catch (IOException errabi) { - OpenVPN.logInfo("Failed getting assets for archicture " + Build.CPU_ABI); + VpnStatus.logInfo("Failed getting assets for archicture " + Build.CPU_ABI); e2=errabi; mvpn = context.getAssets().open("minivpn." + Build.CPU_ABI2); @@ -45,7 +45,7 @@ public class VPNLaunchHelper { fout.close(); if(!mvpnout.setExecutable(true)) { - OpenVPN.logMessage(0, "","Failed to set minivpn executable"); + VpnStatus.logMessage(0, "", "Failed to set minivpn executable"); return false; } @@ -53,8 +53,8 @@ public class VPNLaunchHelper { return true; } catch (IOException e) { if(e2!=null) - OpenVPN.logMessage(0, "",e2.getLocalizedMessage()); - OpenVPN.logMessage(0, "",e.getLocalizedMessage()); + VpnStatus.logMessage(0, "", e2.getLocalizedMessage()); + VpnStatus.logMessage(0, "", e.getLocalizedMessage()); e.printStackTrace(); return false; } @@ -63,10 +63,10 @@ public class VPNLaunchHelper { public static void startOpenVpn(VpnProfile startprofile, Context context) { if(!writeMiniVPN(context)) { - OpenVPN.logMessage(0, "", "Error writing minivpn binary"); + VpnStatus.logMessage(0, "", "Error writing minivpn binary"); return; } - OpenVPN.logMessage(0, "", context.getString(R.string.building_configration)); + VpnStatus.logMessage(0, "", context.getString(R.string.building_configration)); Intent startVPN = startprofile.prepareIntent(context); if(startVPN!=null) diff --git a/src/de/blinkt/openvpn/core/VpnStatus.java b/src/de/blinkt/openvpn/core/VpnStatus.java new file mode 100644 index 00000000..86f0f727 --- /dev/null +++ b/src/de/blinkt/openvpn/core/VpnStatus.java @@ -0,0 +1,432 @@ +package de.blinkt.openvpn.core; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.Signature; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import de.blinkt.openvpn.R; + +import java.io.ByteArrayInputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Locale; +import java.util.UnknownFormatConversionException; +import java.util.Vector; + +public class VpnStatus { + + + public static LinkedList logbuffer; + + private static Vector logListener; + private static Vector stateListener; + private static Vector byteCountListener; + + private static String mLaststatemsg=""; + + private static String mLaststate = "NOPROCESS"; + + private static int mLastStateresid=R.string.state_noprocess; + + private static long mlastByteCount[]={0,0,0,0}; + + + + 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 + } + + 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}; + + private static ConnectionStatus mLastLevel=ConnectionStatus.LEVEL_NOTCONNECTED; + + static { + logbuffer = new LinkedList(); + logListener = new Vector(); + stateListener = new Vector(); + byteCountListener = new Vector(); + logInformation(); + } + + + public static class LogItem implements Parcelable { + public static final int ERROR = 1; + public static final int INFO = 2; + public static final int VERBOSE = 3; + + private Object [] mArgs = null; + private String mMessage = null; + private int mRessourceId; + // Default log priority + int mLevel = INFO; + private long logtime = System.currentTimeMillis(); + + public LogItem(int ressourceId, Object[] args) { + mRessourceId = ressourceId; + mArgs = args; + } + + @Override + public int describeContents() { + return 0; + } + + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeArray(mArgs); + dest.writeString(mMessage); + dest.writeInt(mRessourceId); + dest.writeInt(mLevel); + dest.writeLong(logtime); + } + + public LogItem(Parcel in) { + mArgs = in.readArray(Object.class.getClassLoader()); + mMessage = in.readString(); + mRessourceId = in.readInt(); + mLevel = in.readInt(); + logtime = in.readLong(); + } + + 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(int loglevel,int ressourceId, Object[] args) { + mRessourceId = ressourceId; + mArgs = args; + mLevel = loglevel; + } + + + public LogItem(String message) { + mMessage = message; + } + + public LogItem(int loglevel, String msg) { + mLevel = loglevel; + mMessage = msg; + } + + + public LogItem(int loglevel, int ressourceId) { + mRessourceId =ressourceId; + mLevel = loglevel; + } + + 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; + } + } + } catch (UnknownFormatConversionException e) { + if (c != null) + throw new UnknownFormatConversionException(e.getLocalizedMessage() + getString(null)); + else + throw e; + } + } + + // 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 + apksign = c.getString(R.string.built_by,cert.getSubjectX500Principal().getName()); + + PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0); + version = packageinfo.versionName; + + } catch (NameNotFoundException e) { + } catch (CertificateException e) { + } catch (NoSuchAlgorithmException e) { + } + + 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); + + } + + public long getLogtime() { + return logtime; + } + + + } + + private static final int MAXLOGENTRIES = 500; + + public static final String MANAGMENT_PREFIX = "M:"; + + + 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(int level,String prefix, String message) + { + newlogItem(new LogItem(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) { + case noNetwork: + VpnStatus.updateStateString("NONETWORK", "", R.string.state_nonetwork, ConnectionStatus.LEVEL_NONETWORK); + break; + case screenOff: + VpnStatus.updateStateString("SCREENOFF", "", R.string.state_screenoff, ConnectionStatus.LEVEL_VPNPAUSED); + break; + case userPause: + VpnStatus.updateStateString("USERPAUSE", "", R.string.state_userpause, ConnectionStatus.LEVEL_VPNPAUSED); + break; + } + + } + + 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; + + 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); + } + + + 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()]); + + } + + 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) { + mLaststate= state; + mLaststatemsg = msg; + mLastStateresid = resid; + mLastLevel = level; + + for (StateListener sl : stateListener) { + sl.updateState(state,msg,resid,level); + } + } + + public static void logInfo(String message) { + newlogItem(new LogItem(LogItem.INFO, message)); + } + + public static void logInfo(int ressourceId, Object... args) { + newlogItem(new LogItem(LogItem.INFO, ressourceId, args)); + } + + private synchronized static void newlogItem(LogItem logItem) { + logbuffer.addLast(logItem); + if(logbuffer.size()>MAXLOGENTRIES) + logbuffer.removeFirst(); + + for (LogListener ll : logListener) { + ll.newLog(logItem); + } + } + + public static void logError(String msg) { + newlogItem(new LogItem(LogItem.ERROR, msg)); + + } + + public static void logError(int ressourceId) { + newlogItem(new LogItem(LogItem.ERROR, ressourceId)); + } + public static void logError(int ressourceId, Object... args) { + newlogItem(new LogItem(LogItem.ERROR, ressourceId,args)); + } + + 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); + } + } + + + +} diff --git a/src/de/blinkt/openvpn/core/X509Utils.java b/src/de/blinkt/openvpn/core/X509Utils.java index efdda3ca..f6bd7774 100644 --- a/src/de/blinkt/openvpn/core/X509Utils.java +++ b/src/de/blinkt/openvpn/core/X509Utils.java @@ -67,7 +67,7 @@ public class X509Utils { return getCertificateFriendlyName(cert); } catch (Exception e) { - OpenVPN.logError("Could not read certificate" + e.getLocalizedMessage()); + VpnStatus.logError("Could not read certificate" + e.getLocalizedMessage()); } } return c.getString(R.string.cannotparsecert); diff --git a/src/de/blinkt/openvpn/fragments/SendDumpFragment.java b/src/de/blinkt/openvpn/fragments/SendDumpFragment.java index 020379ef..d43f6427 100644 --- a/src/de/blinkt/openvpn/fragments/SendDumpFragment.java +++ b/src/de/blinkt/openvpn/fragments/SendDumpFragment.java @@ -15,7 +15,7 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import de.blinkt.openvpn.R; -import de.blinkt.openvpn.core.OpenVPN; +import de.blinkt.openvpn.core.VpnStatus; public class SendDumpFragment extends Fragment { @@ -61,7 +61,7 @@ public class SendDumpFragment extends Fragment { File ldump = getLastestDump(getActivity()); if(ldump==null) { - OpenVPN.logError("No Minidump found!"); + VpnStatus.logError("No Minidump found!"); } uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/" + ldump.getName())); -- cgit v1.2.3