summaryrefslogtreecommitdiff
path: root/src/de/blinkt/openvpn
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/blinkt/openvpn')
-rw-r--r--src/de/blinkt/openvpn/FileProvider.java140
-rw-r--r--src/de/blinkt/openvpn/LaunchVPN.java295
-rw-r--r--src/de/blinkt/openvpn/OnBootReceiver.java34
-rw-r--r--src/de/blinkt/openvpn/VpnProfile.java947
-rw-r--r--src/de/blinkt/openvpn/activities/ConfigConverter.java614
-rw-r--r--src/de/blinkt/openvpn/activities/CreateShortcuts.java154
-rw-r--r--src/de/blinkt/openvpn/activities/DisconnectVPN.java82
-rw-r--r--src/de/blinkt/openvpn/activities/FileSelect.java220
-rw-r--r--src/de/blinkt/openvpn/activities/LogWindow.java32
-rw-r--r--src/de/blinkt/openvpn/activities/MainActivity.java103
-rw-r--r--src/de/blinkt/openvpn/activities/VPNPreferences.java165
-rw-r--r--src/de/blinkt/openvpn/api/APIVpnProfile.aidl3
-rw-r--r--src/de/blinkt/openvpn/api/APIVpnProfile.java51
-rw-r--r--src/de/blinkt/openvpn/api/ConfirmDialog.java126
-rw-r--r--src/de/blinkt/openvpn/api/ExternalAppDatabase.java57
-rw-r--r--src/de/blinkt/openvpn/api/ExternalOpenVPNService.java317
-rw-r--r--src/de/blinkt/openvpn/api/GrantPermissionsActivity.java26
-rw-r--r--src/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl50
-rw-r--r--src/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl13
-rw-r--r--src/de/blinkt/openvpn/api/SecurityRemoteException.java12
-rw-r--r--src/de/blinkt/openvpn/core/CIDRIP.java70
-rw-r--r--src/de/blinkt/openvpn/core/ConfigParser.java762
-rw-r--r--src/de/blinkt/openvpn/core/DeviceStateReceiver.java239
-rw-r--r--src/de/blinkt/openvpn/core/GetRestrictionReceiver.java47
-rw-r--r--src/de/blinkt/openvpn/core/ICSOpenVPNApplication.java14
-rw-r--r--src/de/blinkt/openvpn/core/NativeUtils.java13
-rw-r--r--src/de/blinkt/openvpn/core/NetworkSpace.java274
-rw-r--r--src/de/blinkt/openvpn/core/OpenVPNManagement.java20
-rw-r--r--src/de/blinkt/openvpn/core/OpenVPNThread.java174
-rw-r--r--src/de/blinkt/openvpn/core/OpenVpnManagementThread.java580
-rw-r--r--src/de/blinkt/openvpn/core/OpenVpnService.java704
-rw-r--r--src/de/blinkt/openvpn/core/PRNGFixes.java334
-rw-r--r--src/de/blinkt/openvpn/core/ProfileManager.java222
-rw-r--r--src/de/blinkt/openvpn/core/ProxyDetection.java55
-rw-r--r--src/de/blinkt/openvpn/core/VPNLaunchHelper.java77
-rw-r--r--src/de/blinkt/openvpn/core/VpnStatus.java540
-rw-r--r--src/de/blinkt/openvpn/core/X509Utils.java155
-rw-r--r--src/de/blinkt/openvpn/fragments/AboutFragment.java297
-rw-r--r--src/de/blinkt/openvpn/fragments/FaqFragment.java36
-rw-r--r--src/de/blinkt/openvpn/fragments/FileSelectionFragment.java256
-rw-r--r--src/de/blinkt/openvpn/fragments/GeneralSettings.java123
-rw-r--r--src/de/blinkt/openvpn/fragments/InlineFileTab.java66
-rw-r--r--src/de/blinkt/openvpn/fragments/LogFragment.java668
-rw-r--r--src/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java48
-rw-r--r--src/de/blinkt/openvpn/fragments/SendDumpFragment.java94
-rw-r--r--src/de/blinkt/openvpn/fragments/Settings_Authentication.java212
-rw-r--r--src/de/blinkt/openvpn/fragments/Settings_Basic.java360
-rw-r--r--src/de/blinkt/openvpn/fragments/Settings_IP.java130
-rw-r--r--src/de/blinkt/openvpn/fragments/Settings_Obscure.java93
-rw-r--r--src/de/blinkt/openvpn/fragments/Settings_Routing.java88
-rw-r--r--src/de/blinkt/openvpn/fragments/ShowConfigFragment.java89
-rw-r--r--src/de/blinkt/openvpn/fragments/Utils.java195
-rw-r--r--src/de/blinkt/openvpn/fragments/VPNProfileList.java346
-rw-r--r--src/de/blinkt/openvpn/views/FileSelectLayout.java156
-rw-r--r--src/de/blinkt/openvpn/views/RemoteCNPreference.java141
-rw-r--r--src/de/blinkt/openvpn/views/SeekBarTicks.java69
56 files changed, 0 insertions, 11188 deletions
diff --git a/src/de/blinkt/openvpn/FileProvider.java b/src/de/blinkt/openvpn/FileProvider.java
deleted file mode 100644
index 9ffd6545..00000000
--- a/src/de/blinkt/openvpn/FileProvider.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package de.blinkt.openvpn;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import android.content.ContentProvider;
-import android.content.ContentProvider.PipeDataWriter;
-import android.content.ContentValues;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.ParcelFileDescriptor;
-import android.provider.OpenableColumns;
-import android.util.Log;
-import de.blinkt.openvpn.core.VpnStatus;
-
-/**
- * A very simple content provider that can serve arbitrary asset files from
- * our .apk.
- */
-public class FileProvider extends ContentProvider
-implements PipeDataWriter<InputStream> {
- @Override
- public boolean onCreate() {
- return true;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- try {
- File dumpfile = getFileFromURI(uri);
-
-
- MatrixCursor c = new MatrixCursor(projection);
-
- Object[] row = new Object[projection.length];
- int i=0;
- for (String r:projection) {
- if(r.equals(OpenableColumns.SIZE))
- row[i] = dumpfile.length();
- if(r.equals(OpenableColumns.DISPLAY_NAME))
- row[i] = dumpfile.getName();
- i++;
- }
- c.addRow(row);
- return c;
- } catch (FileNotFoundException e) {
- VpnStatus.logException(e);
- return null;
- }
-
-
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- // Don't support inserts.
- return null;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- // Don't support deletes.
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- // Don't support updates.
- return 0;
- }
-
- @Override
- public String getType(Uri uri) {
- // For this sample, assume all files are .apks.
- return "application/octet-stream";
- }
-
- @Override
- public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
- File dumpfile = getFileFromURI(uri);
-
- try {
-
- InputStream is = new FileInputStream(dumpfile);
- // Start a new thread that pipes the stream data back to the caller.
- return new AssetFileDescriptor(
- openPipeHelper(uri, null, null, is, this), 0,
- dumpfile.length());
- } catch (IOException e) {
- throw new FileNotFoundException("Unable to open minidump " + uri);
- }
- }
-
- private File getFileFromURI(Uri uri) throws FileNotFoundException {
- // Try to open an asset with the given name.
- String path = uri.getPath();
- if(path.startsWith("/"))
- path = path.replaceFirst("/", "");
-
- // I think this already random enough, no need for magic secure cookies
- // 1f9563a4-a1f5-2165-255f2219-111823ef.dmp
- if (!path.matches("^[0-9a-z-.]*(dmp|dmp.log)$"))
- throw new FileNotFoundException("url not in expect format " + uri);
- File cachedir = getContext().getCacheDir();
- return new File(cachedir,path);
- }
-
- @Override
- public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
- Bundle opts, InputStream args) {
- // Transfer data from the asset to the pipe the client is reading.
- byte[] buffer = new byte[8192];
- int n;
- FileOutputStream fout = new FileOutputStream(output.getFileDescriptor());
- try {
- while ((n=args.read(buffer)) >= 0) {
- fout.write(buffer, 0, n);
- }
- } catch (IOException e) {
- Log.i("OpenVPNFileProvider", "Failed transferring", e);
- } finally {
- try {
- args.close();
- } catch (IOException e) {
- }
- try {
- fout.close();
- } catch (IOException e) {
- }
- }
- }
-}
diff --git a/src/de/blinkt/openvpn/LaunchVPN.java b/src/de/blinkt/openvpn/LaunchVPN.java
deleted file mode 100644
index 7aed4e4a..00000000
--- a/src/de/blinkt/openvpn/LaunchVPN.java
+++ /dev/null
@@ -1,295 +0,0 @@
-package de.blinkt.openvpn;
-
-import java.io.IOException;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.VpnService;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.text.method.PasswordTransformationMethod;
-import android.view.View;
-import android.widget.*;
-
-import de.blinkt.openvpn.activities.LogWindow;
-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;
-
-/**
- * This Activity actually handles two stages of a launcher shortcut's life cycle.
- *
- * 1. Your application offers to provide shortcuts to the launcher. When
- * the user installs a shortcut, an activity within your application
- * generates the actual shortcut and returns it to the launcher, where it
- * is shown to the user as an icon.
- *
- * 2. Any time the user clicks on an installed shortcut, an intent is sent.
- * Typically this would then be handled as necessary by an activity within
- * your application.
- *
- * We handle stage 1 (creating a shortcut) by simply sending back the information (in the form
- * of an {@link android.content.Intent} that the launcher will use to create the shortcut.
- *
- * You can also implement this in an interactive way, by having your activity actually present
- * UI for the user to select the specific nature of the shortcut, such as a contact, picture, URL,
- * media item, or action.
- *
- * We handle stage 2 (responding to a shortcut) in this sample by simply displaying the contents
- * of the incoming {@link android.content.Intent}.
- *
- * In a real application, you would probably use the shortcut intent to display specific content
- * or start a particular operation.
- */
-public class LaunchVPN extends Activity {
-
- public static final String EXTRA_KEY = "de.blinkt.openvpn.shortcutProfileUUID";
- public static final String EXTRA_NAME = "de.blinkt.openvpn.shortcutProfileName";
- public static final String EXTRA_HIDELOG = "de.blinkt.openvpn.showNoLogWindow";
-
- private static final int START_VPN_PROFILE= 70;
-
-
- private ProfileManager mPM;
- private VpnProfile mSelectedProfile;
- private boolean mhideLog=false;
-
- private boolean mCmfixed=false;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- mPM =ProfileManager.getInstance(this);
-
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- // Resolve the intent
-
- final Intent intent = getIntent();
- final String action = intent.getAction();
-
- // If the intent is a request to create a shortcut, we'll do that and exit
-
-
- if(Intent.ACTION_MAIN.equals(action)) {
- // we got called to be the starting point, most likely a shortcut
- String shortcutUUID = intent.getStringExtra( EXTRA_KEY);
- String shortcutName = intent.getStringExtra( EXTRA_NAME);
- mhideLog = intent.getBooleanExtra(EXTRA_HIDELOG, false);
-
- VpnProfile profileToConnect = ProfileManager.get(this,shortcutUUID);
- if(shortcutName != null && profileToConnect ==null)
- profileToConnect = ProfileManager.getInstance(this).getProfileByName(shortcutName);
-
- if(profileToConnect ==null) {
- VpnStatus.logError(R.string.shortcut_profile_notfound);
- // show Log window to display error
- showLogWindow();
- finish();
- return;
- }
-
- mSelectedProfile = profileToConnect;
- launchVPN();
-
- }
- }
-
- private void askForPW(final int type) {
-
- final EditText entry = new EditText(this);
- final View userpwlayout = getLayoutInflater().inflate(R.layout.userpass, null);
-
- entry.setSingleLine();
- entry.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
- entry.setTransformationMethod(new PasswordTransformationMethod());
-
- AlertDialog.Builder dialog = new AlertDialog.Builder(this);
- dialog.setTitle("Need " + getString(type));
- dialog.setMessage("Enter the password for profile " + mSelectedProfile.mName);
-
- if (type == R.string.password) {
- ((EditText)userpwlayout.findViewById(R.id.username)).setText(mSelectedProfile.mUsername);
- ((EditText)userpwlayout.findViewById(R.id.password)).setText(mSelectedProfile.mPassword);
- ((CheckBox)userpwlayout.findViewById(R.id.save_password)).setChecked(!TextUtils.isEmpty(mSelectedProfile.mPassword));
- ((CheckBox)userpwlayout.findViewById(R.id.show_password)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (isChecked)
- ((EditText)userpwlayout.findViewById(R.id.password)).setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
- else
- ((EditText)userpwlayout.findViewById(R.id.password)).setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
- }
- });
-
- dialog.setView(userpwlayout);
- } else {
- dialog.setView(entry);
- }
-
- AlertDialog.Builder builder = dialog.setPositiveButton(android.R.string.ok,
- new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
-
- if (type == R.string.password) {
- mSelectedProfile.mUsername = ((EditText) userpwlayout.findViewById(R.id.username)).getText().toString();
-
- String pw = ((EditText) userpwlayout.findViewById(R.id.password)).getText().toString();
- if (((CheckBox) userpwlayout.findViewById(R.id.save_password)).isChecked()) {
- mSelectedProfile.mPassword=pw;
- } else {
- mSelectedProfile.mPassword=null;
- mSelectedProfile.mTransientPW = pw;
- }
- } else {
- mSelectedProfile.mTransientPCKS12PW = entry.getText().toString();
- }
- onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null);
-
- }
-
- });
- dialog.setNegativeButton(android.R.string.cancel,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- VpnStatus.updateStateString("USER_VPN_PASSWORD_CANCELLED", "", R.string.state_user_vpn_password_cancelled,
- ConnectionStatus.LEVEL_NOTCONNECTED);
- finish();
- }
- });
-
- dialog.create().show();
-
- }
- @Override
- protected void onActivityResult (int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if(requestCode==START_VPN_PROFILE) {
- if(resultCode == Activity.RESULT_OK) {
- int needpw = mSelectedProfile.needUserPWInput();
- if(needpw !=0) {
- 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);
- boolean showlogwindow = prefs.getBoolean("showlogwindow", true);
-
- if(!mhideLog && showlogwindow)
- showLogWindow();
- new startOpenVpnThread().start();
- }
- } else if (resultCode == Activity.RESULT_CANCELED) {
- // User does not want us to start, so we just vanish
- VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled,
- ConnectionStatus.LEVEL_NOTCONNECTED);
-
- finish();
- }
- }
- }
- void showLogWindow() {
-
- Intent startLW = new Intent(getBaseContext(),LogWindow.class);
- startLW.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
- startActivity(startLW);
-
- }
-
- void showConfigErrorDialog(int vpnok) {
- AlertDialog.Builder d = new AlertDialog.Builder(this);
- d.setTitle(R.string.config_error_found);
- d.setMessage(vpnok);
- d.setPositiveButton(android.R.string.ok, new OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- finish();
-
- }
- });
- d.show();
- }
-
- void launchVPN () {
- int vpnok = mSelectedProfile.checkProfile(this);
- if(vpnok!= R.string.no_error_found) {
- showConfigErrorDialog(vpnok);
- return;
- }
-
- Intent intent = VpnService.prepare(this);
- // Check if we want to fix /dev/tun
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- boolean usecm9fix = prefs.getBoolean("useCM9Fix", false);
- boolean loadTunModule = prefs.getBoolean("loadTunModule", false);
-
- if(loadTunModule)
- execeuteSUcmd("insmod /system/lib/modules/tun.ko");
-
- if(usecm9fix && !mCmfixed ) {
- execeuteSUcmd("chown system /dev/tun");
- }
-
-
- if (intent != null) {
- VpnStatus.updateStateString("USER_VPN_PERMISSION", "", R.string.state_user_vpn_permission,
- 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
- VpnStatus.logError(R.string.no_vpn_support_image);
- showLogWindow();
- }
- } else {
- onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null);
- }
-
- }
-
- private void execeuteSUcmd(String command) {
- ProcessBuilder pb = new ProcessBuilder("su","-c",command);
- try {
- Process p = pb.start();
- int ret = p.waitFor();
- if(ret ==0)
- mCmfixed=true;
- } catch (InterruptedException e) {
- VpnStatus.logException("SU command", e);
-
- } catch (IOException e) {
- VpnStatus.logException("SU command", e);
- }
- }
-
- private class startOpenVpnThread extends Thread {
-
- @Override
- public void run() {
- VPNLaunchHelper.startOpenVpn(mSelectedProfile, getBaseContext());
- finish();
-
- }
-
- }
-
-
-}
diff --git a/src/de/blinkt/openvpn/OnBootReceiver.java b/src/de/blinkt/openvpn/OnBootReceiver.java
deleted file mode 100644
index 32d14b1b..00000000
--- a/src/de/blinkt/openvpn/OnBootReceiver.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package de.blinkt.openvpn;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import de.blinkt.openvpn.core.ProfileManager;
-
-
-public class OnBootReceiver extends BroadcastReceiver {
-
- // Debug: am broadcast -a android.intent.action.BOOT_COMPLETED
- @Override
- public void onReceive(Context context, Intent intent) {
-
- final String action = intent.getAction();
-
- if(Intent.ACTION_BOOT_COMPLETED.equals(action)) {
- VpnProfile bootProfile = ProfileManager.getOnBootProfile(context);
- if(bootProfile != null) {
- launchVPN(bootProfile, context);
- }
- }
- }
-
- void launchVPN(VpnProfile profile, Context context) {
- Intent startVpnIntent = new Intent(Intent.ACTION_MAIN);
- startVpnIntent.setClass(context, LaunchVPN.class);
- startVpnIntent.putExtra(LaunchVPN.EXTRA_KEY,profile.getUUIDString());
- startVpnIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startVpnIntent.putExtra(LaunchVPN.EXTRA_HIDELOG, true);
-
- context.startActivity(startVpnIntent);
- }
-}
diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java
deleted file mode 100644
index 1ec34b51..00000000
--- a/src/de/blinkt/openvpn/VpnProfile.java
+++ /dev/null
@@ -1,947 +0,0 @@
-package de.blinkt.openvpn;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.preference.PreferenceManager;
-import android.security.KeyChain;
-import android.security.KeyChainException;
-import android.util.Base64;
-
-import de.blinkt.openvpn.core.NativeUtils;
-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;
-import org.spongycastle.util.io.pem.PemWriter;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import java.io.*;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Collection;
-import java.util.Locale;
-import java.util.UUID;
-import java.util.Vector;
-
-public class VpnProfile implements Serializable {
- // Note that this class cannot be moved to core where it belongs since
- // the profile loading depends on it being here
- // The Serializable documentation mentions that class name change are possible
- // but the how is unclear
- //
- transient public static final long MAX_EMBED_FILE_SIZE = 2048*1024; // 2048kB
- // Don't change this, not all parts of the program use this constant
- public static final String EXTRA_PROFILEUUID = "de.blinkt.openvpn.profileUUID";
- public static final String INLINE_TAG = "[[INLINE]]";
- public static final String DISPLAYNAME_TAG = "[[NAME]]";
- public static final String MINIVPN = "miniopenvpn";
- private static final long serialVersionUID = 7085688938959334563L;
- private static final String OVPNCONFIGFILE = "android.conf";
- public static final int MAXLOGLEVEL = 4;
- public static final int CURRENT_PROFILE_VERSION = 2;
- public static String DEFAULT_DNS1 = "8.8.8.8";
- public static String DEFAULT_DNS2 = "8.8.4.4";
-
- public transient String mTransientPW = null;
- public transient String mTransientPCKS12PW = null;
-
-
- public static final int TYPE_CERTIFICATES = 0;
- public static final int TYPE_PKCS12 = 1;
- public static final int TYPE_KEYSTORE = 2;
- public static final int TYPE_USERPASS = 3;
- public static final int TYPE_STATICKEYS = 4;
- public static final int TYPE_USERPASS_CERTIFICATES = 5;
- public static final int TYPE_USERPASS_PKCS12 = 6;
- public static final int TYPE_USERPASS_KEYSTORE = 7;
- public static final int X509_VERIFY_TLSREMOTE = 0;
- public static final int X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING = 1;
- public static final int X509_VERIFY_TLSREMOTE_DN = 2;
- public static final int X509_VERIFY_TLSREMOTE_RDN = 3;
- public static final int X509_VERIFY_TLSREMOTE_RDN_PREFIX = 4;
- // variable named wrong and should haven beeen transient
- // but needs to keep wrong name to guarante loading of old
- // profiles
- public transient boolean profileDleted = false;
- public int mAuthenticationType = TYPE_KEYSTORE;
- public String mName;
- public String mAlias;
- public String mClientCertFilename;
- public String mTLSAuthDirection = "";
- public String mTLSAuthFilename;
- public String mClientKeyFilename;
- public String mCaFilename;
- public boolean mUseLzo = true;
- public String mServerPort = "1194";
- public boolean mUseUdp = true;
- public String mPKCS12Filename;
- public String mPKCS12Password;
- public boolean mUseTLSAuth = false;
- public String mServerName = "openvpn.blinkt.de";
- public String mDNS1 = DEFAULT_DNS1;
- public String mDNS2 = DEFAULT_DNS2;
- public String mIPv4Address;
- public String mIPv6Address;
- public boolean mOverrideDNS = false;
- public String mSearchDomain = "blinkt.de";
- public boolean mUseDefaultRoute = true;
- public boolean mUsePull = true;
- public String mCustomRoutes;
- public boolean mCheckRemoteCN = false;
- public boolean mExpectTLSCert = true;
- public String mRemoteCN = "";
- public String mPassword = "";
- public String mUsername = "";
- public boolean mRoutenopull = false;
- public boolean mUseRandomHostname = false;
- public boolean mUseFloat = false;
- public boolean mUseCustomConfig = false;
- public String mCustomConfigOptions = "";
- public String mVerb = "1"; //ignored
- public String mCipher = "";
- public boolean mNobind = false;
- public boolean mUseDefaultRoutev6 = true;
- public String mCustomRoutesv6 = "";
- public String mKeyPassword = "";
- public boolean mPersistTun = false;
- public String mConnectRetryMax = "5";
- public String mConnectRetry = "5";
- public boolean mUserEditable = true;
- public String mAuth = "";
- public int mX509AuthType = X509_VERIFY_TLSREMOTE_RDN;
- private transient PrivateKey mPrivateKey;
- // Public attributes, since I got mad with getter/setter
- // set members to default values
- private UUID mUuid;
- public boolean mAllowLocalLAN;
- private int mProfileVersion;
- public String mExcludedRoutes;
- public String mExcludedRoutesv6;
-
- public VpnProfile(String name) {
- mUuid = UUID.randomUUID();
- mName = name;
- mProfileVersion = CURRENT_PROFILE_VERSION;
- }
-
- public static String openVpnEscape(String unescaped) {
- if (unescaped == null)
- return null;
- String escapedString = unescaped.replace("\\", "\\\\");
- escapedString = escapedString.replace("\"", "\\\"");
- escapedString = escapedString.replace("\n", "\\n");
-
- if (escapedString.equals(unescaped) && !escapedString.contains(" ") && !escapedString.contains("#"))
- return unescaped;
- else
- return '"' + escapedString + '"';
- }
-
- public void clearDefaults() {
- mServerName = "unknown";
- mUsePull = false;
- mUseLzo = false;
- mUseDefaultRoute = false;
- mUseDefaultRoutev6 = false;
- mExpectTLSCert = false;
- mPersistTun = false;
- mAllowLocalLAN = true;
- }
-
- public UUID getUUID() {
- return mUuid;
-
- }
-
- public String getName() {
- if (mName==null)
- return "No profile name";
- return mName;
- }
-
- public void upgradeProfile(){
- if(mProfileVersion< 2) {
- /* default to the behaviour the OS used */
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
- mAllowLocalLAN = true;
- else
- mAllowLocalLAN = false;
- }
-
- mProfileVersion= CURRENT_PROFILE_VERSION;
- }
-
- public String getConfigFile(Context context, boolean configForOvpn3) {
-
- File cacheDir = context.getCacheDir();
- String cfg = "";
-
- // Enable managment interface
- cfg += "# Enables connection to GUI\n";
- cfg += "management ";
-
- cfg += cacheDir.getAbsolutePath() + "/" + "mgmtsocket";
- cfg += " unix\n";
- cfg += "management-client\n";
- // Not needed, see updated man page in 2.3
- //cfg += "management-signal\n";
- cfg += "management-query-passwords\n";
- cfg += "management-hold\n\n";
- cfg += getVersionEnvString(context);
-
- cfg += "machine-readable-output\n";
-
-
- boolean useTLSClient = (mAuthenticationType != TYPE_STATICKEYS);
-
- if (useTLSClient && mUsePull)
- cfg += "client\n";
- else if (mUsePull)
- cfg += "pull\n";
- else if (useTLSClient)
- cfg += "tls-client\n";
-
-
- //cfg += "verb " + mVerb + "\n";
- cfg += "verb " + MAXLOGLEVEL + "\n";
-
- if (mConnectRetryMax == null) {
- mConnectRetryMax = "5";
- }
-
- if (!mConnectRetryMax.equals("-1"))
- cfg += "connect-retry-max " + mConnectRetryMax + "\n";
-
- if (mConnectRetry == null)
- mConnectRetry = "5";
-
-
- cfg += "connect-retry " + mConnectRetry + "\n";
-
- cfg += "resolv-retry 60\n";
-
-
- // We cannot use anything else than tun
- cfg += "dev tun\n";
-
- // Server Address
- cfg += "remote ";
- cfg += mServerName;
- cfg += " ";
- cfg += mServerPort;
- if (mUseUdp)
- cfg += " udp\n";
- else
- cfg += " tcp-client\n";
-
-
- switch (mAuthenticationType) {
- case VpnProfile.TYPE_USERPASS_CERTIFICATES:
- cfg += "auth-user-pass\n";
- case VpnProfile.TYPE_CERTIFICATES:
- // Ca
- cfg += insertFileData("ca", mCaFilename);
-
- // Client Cert + Key
- cfg += insertFileData("key", mClientKeyFilename);
- cfg += insertFileData("cert", mClientCertFilename);
-
- break;
- case VpnProfile.TYPE_USERPASS_PKCS12:
- cfg += "auth-user-pass\n";
- case VpnProfile.TYPE_PKCS12:
- cfg += insertFileData("pkcs12", mPKCS12Filename);
- break;
-
- case VpnProfile.TYPE_USERPASS_KEYSTORE:
- cfg += "auth-user-pass\n";
- case VpnProfile.TYPE_KEYSTORE:
- if (!configForOvpn3) {
- String[] ks = getKeyStoreCertificates(context);
- cfg += "### From Keystore ####\n";
- if (ks != null) {
- cfg += "<ca>\n" + ks[0] + "\n</ca>\n";
- if (ks[1] != null)
- cfg += "<extra-certs>\n" + ks[1] + "\n</extra-certs>\n";
- cfg += "<cert>\n" + ks[2] + "\n</cert>\n";
- cfg += "management-external-key\n";
- } else {
- cfg += context.getString(R.string.keychain_access) + "\n";
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN)
- if (!mAlias.matches("^[a-zA-Z0-9]$"))
- cfg += context.getString(R.string.jelly_keystore_alphanumeric_bug) + "\n";
- }
- }
- break;
- case VpnProfile.TYPE_USERPASS:
- cfg += "auth-user-pass\n";
- cfg += insertFileData("ca", mCaFilename);
- }
-
- if (mUseLzo) {
- cfg += "comp-lzo\n";
- }
-
- if (mUseTLSAuth) {
- if (mAuthenticationType == TYPE_STATICKEYS)
- cfg += insertFileData("secret", mTLSAuthFilename);
- else
- cfg += insertFileData("tls-auth", mTLSAuthFilename);
-
- if (nonNull(mTLSAuthDirection)) {
- cfg += "key-direction ";
- cfg += mTLSAuthDirection;
- cfg += "\n";
- }
-
- }
-
- if (!mUsePull) {
- if (nonNull(mIPv4Address))
- cfg += "ifconfig " + cidrToIPAndNetmask(mIPv4Address) + "\n";
-
- if (nonNull(mIPv6Address))
- cfg += "ifconfig-ipv6 " + mIPv6Address + "\n";
- }
-
- if (mUsePull && mRoutenopull)
- cfg += "route-nopull\n";
-
- String routes = "";
- int numroutes = 0;
- if (mUseDefaultRoute)
- routes += "route 0.0.0.0 0.0.0.0 vpn_gateway\n";
- else
- {
- for (String route : getCustomRoutes(mCustomRoutes)) {
- routes += "route " + route + " vpn_gateway\n";
- numroutes++;
- }
-
- for (String route: getCustomRoutes(mExcludedRoutes)) {
- routes += "route " + route + " net_gateway";
- }
- }
-
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT && !mAllowLocalLAN)
- cfg+="redirect-private block-local\n";
- else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && mAllowLocalLAN)
- cfg+="redirect-private unblock-local\n";
-
-
- if (mUseDefaultRoutev6)
- cfg += "route-ipv6 ::/0\n";
- else
- for (String route : getCustomRoutesv6(mCustomRoutesv6)) {
- routes += "route-ipv6 " + route + "\n";
- numroutes++;
- }
-
- // Round number to next 100
- if (numroutes > 90) {
- numroutes = ((numroutes / 100) + 1) * 100;
- cfg += "# A lot of routes are set, increase max-routes\n";
- cfg += "max-routes " + numroutes + "\n";
- }
- cfg += routes;
-
- if (mOverrideDNS || !mUsePull) {
- if (nonNull(mDNS1))
- cfg += "dhcp-option DNS " + mDNS1 + "\n";
- if (nonNull(mDNS2))
- cfg += "dhcp-option DNS " + mDNS2 + "\n";
- if (nonNull(mSearchDomain))
- cfg += "dhcp-option DOMAIN " + mSearchDomain + "\n";
-
- }
-
- if (mNobind)
- cfg += "nobind\n";
-
-
- // Authentication
- if (mAuthenticationType != TYPE_STATICKEYS) {
- if (mCheckRemoteCN) {
- if (mRemoteCN == null || mRemoteCN.equals(""))
- cfg += "verify-x509-name " + mServerName + " name\n";
- else
- switch (mX509AuthType) {
-
- // 2.2 style x509 checks
- case X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING:
- cfg += "compat-names no-remapping\n";
- case X509_VERIFY_TLSREMOTE:
- cfg += "tls-remote " + openVpnEscape(mRemoteCN) + "\n";
- break;
-
- case X509_VERIFY_TLSREMOTE_RDN:
- cfg += "verify-x509-name " + openVpnEscape(mRemoteCN) + " name\n";
- break;
-
- case X509_VERIFY_TLSREMOTE_RDN_PREFIX:
- cfg += "verify-x509-name " + openVpnEscape(mRemoteCN) + " name-prefix\n";
- break;
-
- case X509_VERIFY_TLSREMOTE_DN:
- cfg += "verify-x509-name " + openVpnEscape(mRemoteCN) + "\n";
- break;
- }
- }
- if (mExpectTLSCert)
- cfg += "remote-cert-tls server\n";
- }
-
- if (nonNull(mCipher)) {
- cfg += "cipher " + mCipher + "\n";
- }
-
- if (nonNull(mAuth)) {
- cfg += "auth " + mAuth + "\n";
- }
-
- // Obscure Settings dialog
- if (mUseRandomHostname)
- cfg += "#my favorite options :)\nremote-random-hostname\n";
-
- if (mUseFloat)
- cfg += "float\n";
-
- if (mPersistTun) {
- cfg += "persist-tun\n";
- cfg += "# persist-tun also enables pre resolving to avoid DNS resolve problem\n";
- cfg += "preresolve\n";
- }
-
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- boolean usesystemproxy = prefs.getBoolean("usesystemproxy", true);
- if (usesystemproxy) {
- cfg += "# Use system proxy setting\n";
- cfg += "management-query-proxy\n";
- }
-
-
- if (mUseCustomConfig) {
- cfg += "# Custom configuration options\n";
- cfg += "# You are on your on own here :)\n";
- cfg += mCustomConfigOptions;
- cfg += "\n";
-
- }
-
-
- return cfg;
- }
-
- private String getVersionEnvString(Context c) {
- String version = "unknown";
- try {
- PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0);
- version = packageinfo.versionName;
- } catch (PackageManager.NameNotFoundException e) {
- VpnStatus.logException(e);
- }
- return String.format(Locale.US, "setenv IV_GUI_VER \"%s %s\"\n", c.getPackageName(), version);
-
- }
-
- //! Put inline data inline and other data as normal escaped filename
- private String insertFileData(String cfgentry, String filedata) {
- if (filedata == null) {
- // TODO: generate good error
- return String.format("%s %s\n", cfgentry, "missing");
- } else if (isEmbedded(filedata)) {
- String dataWithOutHeader = getEmbeddedContent(filedata);
- return String.format(Locale.ENGLISH, "<%s>\n%s\n</%s>\n", cfgentry, dataWithOutHeader, cfgentry);
- } else {
- return String.format(Locale.ENGLISH, "%s %s\n", cfgentry, openVpnEscape(filedata));
- }
- }
-
- private boolean nonNull(String val) {
- if (val == null || val.equals(""))
- return false;
- else
- return true;
- }
-
- private Collection<String> getCustomRoutes(String routes) {
- Vector<String> cidrRoutes = new Vector<String>();
- if (routes == null) {
- // No routes set, return empty vector
- return cidrRoutes;
- }
- for (String route : routes.split("[\n \t]")) {
- if (!route.equals("")) {
- String cidrroute = cidrToIPAndNetmask(route);
- if (cidrroute == null)
- return null;
-
- cidrRoutes.add(cidrroute);
- }
- }
-
- return cidrRoutes;
- }
-
- private Collection<String> getCustomRoutesv6(String routes) {
- Vector<String> cidrRoutes = new Vector<String>();
- if (routes == null) {
- // No routes set, return empty vector
- return cidrRoutes;
- }
- for (String route : routes.split("[\n \t]")) {
- if (!route.equals("")) {
- cidrRoutes.add(route);
- }
- }
-
- return cidrRoutes;
- }
-
- private String cidrToIPAndNetmask(String route) {
- String[] parts = route.split("/");
-
- // No /xx, assume /32 as netmask
- if (parts.length == 1)
- parts = (route + "/32").split("/");
-
- if (parts.length != 2)
- return null;
- int len;
- try {
- len = Integer.parseInt(parts[1]);
- } catch (NumberFormatException ne) {
- return null;
- }
- if (len < 0 || len > 32)
- return null;
-
-
- long nm = 0xffffffffl;
- nm = (nm << (32 - len)) & 0xffffffffl;
-
- String netmask = String.format(Locale.ENGLISH, "%d.%d.%d.%d", (nm & 0xff000000) >> 24, (nm & 0xff0000) >> 16, (nm & 0xff00) >> 8, nm & 0xff);
- return parts[0] + " " + netmask;
- }
-
- private String[] buildOpenvpnArgv(File cacheDir) {
- Vector<String> args = new Vector<String>();
-
- // Add fixed paramenters
- //args.add("/data/data/de.blinkt.openvpn/lib/openvpn");
- args.add(cacheDir.getAbsolutePath() + "/" + VpnProfile.MINIVPN);
-
- args.add("--config");
- args.add(cacheDir.getAbsolutePath() + "/" + OVPNCONFIGFILE);
-
-
- return args.toArray(new String[args.size()]);
- }
-
- public Intent prepareIntent(Context context) {
- String prefix = context.getPackageName();
-
- Intent intent = new Intent(context, OpenVpnService.class);
-
- if (mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) {
- if (getKeyStoreCertificates(context) == null)
- return null;
- }
-
- intent.putExtra(prefix + ".ARGV", buildOpenvpnArgv(context.getCacheDir()));
- intent.putExtra(prefix + ".profileUUID", mUuid.toString());
-
- ApplicationInfo info = context.getApplicationInfo();
- intent.putExtra(prefix + ".nativelib", info.nativeLibraryDir);
-
- try {
- FileWriter cfg = new FileWriter(context.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE);
- cfg.write(getConfigFile(context, false));
- cfg.flush();
- cfg.close();
- } catch (IOException e) {
- VpnStatus.logException(e);
- }
-
- return intent;
- }
-
- String[] getKeyStoreCertificates(Context context) {
- return getKeyStoreCertificates(context, 5);
- }
-
- public static String getDisplayName(String embeddedFile) {
- int start = DISPLAYNAME_TAG.length();
- int end = embeddedFile.indexOf(INLINE_TAG);
- return embeddedFile.substring(start,end);
- }
-
- public static String getEmbeddedContent(String data)
- {
- if (!data.contains(INLINE_TAG))
- return data;
-
- int start = data.indexOf(INLINE_TAG) + INLINE_TAG.length();
- return data.substring(start);
- }
-
- public static boolean isEmbedded(String data) {
- if (data==null)
- return false;
- if(data.startsWith(INLINE_TAG) || data.startsWith(DISPLAYNAME_TAG))
- return true;
- else
- return false;
- }
-
-
- class NoCertReturnedException extends Exception {
- public NoCertReturnedException (String msg) {
- super(msg);
- }
- }
-
- synchronized String[] getKeyStoreCertificates(Context context,int tries) {
- PrivateKey privateKey = null;
- X509Certificate[] cachain;
- Exception exp=null;
- try {
- privateKey = KeyChain.getPrivateKey(context, mAlias);
- mPrivateKey = privateKey;
-
- String keystoreChain = null;
-
-
- cachain = KeyChain.getCertificateChain(context, mAlias);
- if(cachain == null)
- throw new NoCertReturnedException("No certificate returned from Keystore");
-
- if (cachain.length <= 1 && !nonNull(mCaFilename)) {
- VpnStatus.logMessage(VpnStatus.LogLevel.ERROR, "", context.getString(R.string.keychain_nocacert));
- } else {
- StringWriter ksStringWriter = new StringWriter();
-
- PemWriter pw = new PemWriter(ksStringWriter);
- for (int i = 1; i < cachain.length; i++) {
- X509Certificate cert = cachain[i];
- pw.writeObject(new PemObject("CERTIFICATE", cert.getEncoded()));
- }
- pw.close();
- keystoreChain = ksStringWriter.toString();
- }
-
-
- String caout = null;
- if (nonNull(mCaFilename)) {
- try {
- Certificate cacert = X509Utils.getCertificateFromFile(mCaFilename);
- StringWriter caoutWriter = new StringWriter();
- PemWriter pw = new PemWriter(caoutWriter);
-
- pw.writeObject(new PemObject("CERTIFICATE", cacert.getEncoded()));
- pw.close();
- caout= caoutWriter.toString();
-
- } catch (Exception e) {
- VpnStatus.logError("Could not read CA certificate" + e.getLocalizedMessage());
- }
- }
-
-
- StringWriter certout = new StringWriter();
-
-
- if (cachain.length >= 1) {
- X509Certificate usercert = cachain[0];
-
- PemWriter upw = new PemWriter(certout);
- upw.writeObject(new PemObject("CERTIFICATE", usercert.getEncoded()));
- upw.close();
-
- }
- String user = certout.toString();
-
-
- String ca, extra;
- if(caout==null) {
- ca =keystoreChain;
- extra=null;
- } else {
- ca = caout;
- extra=keystoreChain;
- }
-
- return new String[]{ca, extra, user};
- } catch (InterruptedException e) {
- exp=e;
- } catch (FileNotFoundException e) {
- exp=e;
- } catch (CertificateException e) {
- exp=e;
- } catch (IOException e) {
- exp=e;
- } catch (KeyChainException e) {
- exp=e;
- } catch (NoCertReturnedException e) {
- exp =e;
- } catch (IllegalArgumentException e) {
- exp =e;
- } catch (AssertionError e) {
- if (tries ==0)
- return null;
- VpnStatus.logError(String.format("Failure getting Keystore Keys (%s), retrying",e.getLocalizedMessage()));
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e1) {
- VpnStatus.logException(e1);
- }
- return getKeyStoreCertificates(context, tries-1);
- }
- if (exp != null) {
- exp.printStackTrace();
- VpnStatus.logError(R.string.keyChainAccessError, exp.getLocalizedMessage());
-
- VpnStatus.logError(R.string.keychain_access);
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) {
- if (!mAlias.matches("^[a-zA-Z0-9]$")) {
- VpnStatus.logError(R.string.jelly_keystore_alphanumeric_bug);
- }
- }
- }
- return null;
- }
-
- //! Return an error if somethign is wrong
- public int checkProfile(Context context) {
- if (mAuthenticationType == TYPE_KEYSTORE || mAuthenticationType == TYPE_USERPASS_KEYSTORE) {
- if (mAlias == null)
- return R.string.no_keystore_cert_selected;
- }
-
- if (!mUsePull || mAuthenticationType == TYPE_STATICKEYS) {
- if (mIPv4Address == null || cidrToIPAndNetmask(mIPv4Address) == null)
- return R.string.ipv4_format_error;
- }
- if (!mUseDefaultRoute && (getCustomRoutes(mCustomRoutes) == null || getCustomRoutes(mExcludedRoutes) ==null))
- return R.string.custom_route_format_error;
-
- // Everything okay
- return R.string.no_error_found;
-
- }
-
- //! Openvpn asks for a "Private Key", this should be pkcs12 key
- //
- public String getPasswordPrivateKey() {
- if (mTransientPCKS12PW != null) {
- String pwcopy = mTransientPCKS12PW;
- mTransientPCKS12PW = null;
- return pwcopy;
- }
- switch (mAuthenticationType) {
- case TYPE_PKCS12:
- case TYPE_USERPASS_PKCS12:
- return mPKCS12Password;
-
- case TYPE_CERTIFICATES:
- case TYPE_USERPASS_CERTIFICATES:
- return mKeyPassword;
-
- case TYPE_USERPASS:
- case TYPE_STATICKEYS:
- default:
- return null;
- }
- }
-
- boolean isUserPWAuth() {
- switch (mAuthenticationType) {
- case TYPE_USERPASS:
- case TYPE_USERPASS_CERTIFICATES:
- case TYPE_USERPASS_KEYSTORE:
- case TYPE_USERPASS_PKCS12:
- return true;
- default:
- return false;
-
- }
- }
-
- public boolean requireTLSKeyPassword() {
- if (!nonNull(mClientKeyFilename))
- return false;
-
- String data = "";
- if (isEmbedded(mClientKeyFilename))
- data = mClientKeyFilename;
- else {
- char[] buf = new char[2048];
- FileReader fr;
- try {
- fr = new FileReader(mClientKeyFilename);
- int len = fr.read(buf);
- while (len > 0) {
- data += new String(buf, 0, len);
- len = fr.read(buf);
- }
- fr.close();
- } catch (FileNotFoundException e) {
- return false;
- } catch (IOException e) {
- return false;
- }
-
- }
-
- if (data.contains("Proc-Type: 4,ENCRYPTED"))
- return true;
- else if (data.contains("-----BEGIN ENCRYPTED PRIVATE KEY-----"))
- return true;
- else
- return false;
- }
-
- public int needUserPWInput() {
- if ((mAuthenticationType == TYPE_PKCS12 || mAuthenticationType == TYPE_USERPASS_PKCS12) &&
- (mPKCS12Password == null || mPKCS12Password.equals(""))) {
- if (mTransientPCKS12PW == null)
- return R.string.pkcs12_file_encryption_key;
- }
-
- if (mAuthenticationType == TYPE_CERTIFICATES || mAuthenticationType == TYPE_USERPASS_CERTIFICATES) {
- if (requireTLSKeyPassword() && !nonNull(mKeyPassword))
- if (mTransientPCKS12PW == null) {
- return R.string.private_key_password;
- }
- }
-
- if (isUserPWAuth() && !(nonNull(mUsername) && (nonNull(mPassword) || mTransientPW != null))) {
- return R.string.password;
- }
- return 0;
- }
-
- public String getPasswordAuth() {
- if (mTransientPW != null) {
- String pwcopy = mTransientPW;
- mTransientPW = null;
- return pwcopy;
- } else {
- return mPassword;
- }
- }
-
- // Used by the Array Adapter
- @Override
- public String toString() {
- return mName;
- }
-
- public String getUUIDString() {
- return mUuid.toString();
- }
-
- public PrivateKey getKeystoreKey() {
- return mPrivateKey;
- }
-
- public String getSignedData(String b64data) {
- PrivateKey privkey = getKeystoreKey();
- Exception err;
-
- byte[] data = Base64.decode(b64data, Base64.DEFAULT);
-
- // The Jelly Bean *evil* Hack
- // 4.2 implements the RSA/ECB/PKCS1PADDING in the OpenSSLprovider
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) {
- return processSignJellyBeans(privkey, data);
- }
-
-
- try {
-
-
- Cipher rsasinger = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
-
- rsasinger.init(Cipher.ENCRYPT_MODE, privkey);
-
- byte[] signed_bytes = rsasinger.doFinal(data);
- return Base64.encodeToString(signed_bytes, Base64.NO_WRAP);
-
- } catch (NoSuchAlgorithmException e) {
- err = e;
- } catch (InvalidKeyException e) {
- err = e;
- } catch (NoSuchPaddingException e) {
- err = e;
- } catch (IllegalBlockSizeException e) {
- err = e;
- } catch (BadPaddingException e) {
- err = e;
- }
-
- VpnStatus.logError(R.string.error_rsa_sign, err.getClass().toString(), err.getLocalizedMessage());
-
- return null;
-
- }
-
- private String processSignJellyBeans(PrivateKey privkey, byte[] data) {
- Exception err;
- try {
- Method getKey = privkey.getClass().getSuperclass().getDeclaredMethod("getOpenSSLKey");
- getKey.setAccessible(true);
-
- // Real object type is OpenSSLKey
- Object opensslkey = getKey.invoke(privkey);
-
- getKey.setAccessible(false);
-
- Method getPkeyContext = opensslkey.getClass().getDeclaredMethod("getPkeyContext");
-
- // integer pointer to EVP_pkey
- getPkeyContext.setAccessible(true);
- int pkey = (Integer) getPkeyContext.invoke(opensslkey);
- getPkeyContext.setAccessible(false);
-
- // 112 with TLS 1.2 (172 back with 4.3), 36 with TLS 1.0
- byte[] signed_bytes = NativeUtils.rsasign(data, pkey);
- return Base64.encodeToString(signed_bytes, Base64.NO_WRAP);
-
- } catch (NoSuchMethodException e) {
- err = e;
- } catch (IllegalArgumentException e) {
- err = e;
- } catch (IllegalAccessException e) {
- err = e;
- } catch (InvocationTargetException e) {
- err = e;
- } catch (InvalidKeyException e) {
- err = e;
- }
- VpnStatus.logError(R.string.error_rsa_sign, err.getClass().toString(), err.getLocalizedMessage());
-
- return null;
-
- }
-
-
-}
-
-
-
-
diff --git a/src/de/blinkt/openvpn/activities/ConfigConverter.java b/src/de/blinkt/openvpn/activities/ConfigConverter.java
deleted file mode 100644
index cc84076d..00000000
--- a/src/de/blinkt/openvpn/activities/ConfigConverter.java
+++ /dev/null
@@ -1,614 +0,0 @@
-
-package de.blinkt.openvpn.activities;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
-import android.app.ListActivity;
-import android.content.ActivityNotFoundException;
-import android.content.Intent;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.os.Environment;
-import android.provider.OpenableColumns;
-import android.security.KeyChain;
-import android.security.KeyChainAliasCallback;
-import android.text.TextUtils;
-import android.util.Base64;
-import android.util.Log;
-import android.view.*;
-import android.widget.ArrayAdapter;
-import android.widget.CheckBox;
-import android.widget.LinearLayout;
-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.ProfileManager;
-import de.blinkt.openvpn.fragments.Utils;
-import de.blinkt.openvpn.views.FileSelectLayout;
-import junit.framework.Assert;
-
-import java.io.*;
-import java.util.*;
-
-import static de.blinkt.openvpn.views.FileSelectLayout.FileSelectCallback;
-
-public class ConfigConverter extends ListActivity implements FileSelectCallback {
-
- public static final String IMPORT_PROFILE = "de.blinkt.openvpn.IMPORT_PROFILE";
- private static final int RESULT_INSTALLPKCS12 = 7;
- private static final int CHOOSE_FILE_OFFSET = 1000;
- public static final String VPNPROFILE = "vpnProfile";
-
- private VpnProfile mResult;
- private transient ArrayAdapter<String> mArrayAdapter;
-
- private transient List<String> mPathsegments;
-
- private String mAliasName = null;
-
-
- private Map<Utils.FileType, FileSelectLayout> fileSelectMap = new HashMap<Utils.FileType, FileSelectLayout>();
- private String mEmbeddedPwFile;
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == R.id.cancel) {
- setResult(Activity.RESULT_CANCELED);
- finish();
- } else if (item.getItemId() == R.id.ok) {
- if (mResult == null) {
- log("Importing the config had error, cannot save it");
- return true;
- }
-
- Intent in = installPKCS12();
-
- if (in != null)
- startActivityForResult(in, RESULT_INSTALLPKCS12);
- else
- saveProfile();
-
- return true;
- }
-
- return super.onOptionsItemSelected(item);
-
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- if (mResult != null)
- outState.putSerializable(VPNPROFILE, mResult);
- outState.putString("mAliasName", mAliasName);
-
- String[] logentries = new String[mArrayAdapter.getCount()];
- for (int i = 0; i < mArrayAdapter.getCount(); i++) {
- logentries[i] = mArrayAdapter.getItem(i);
- }
- outState.putStringArray("logentries", logentries);
-
- int[] fileselects = new int[fileSelectMap.size()];
- int k = 0;
- for (Utils.FileType key : fileSelectMap.keySet()) {
- fileselects[k] = key.getValue();
- k++;
- }
- outState.putIntArray("fileselects", fileselects);
- outState.putString("pwfile",mEmbeddedPwFile);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent result) {
- if (requestCode == RESULT_INSTALLPKCS12 && resultCode == Activity.RESULT_OK) {
- showCertDialog();
- }
-
- if (resultCode == Activity.RESULT_OK && requestCode >= CHOOSE_FILE_OFFSET) {
- Utils.FileType type = Utils.FileType.getFileTypeByValue(requestCode - CHOOSE_FILE_OFFSET);
-
-
- FileSelectLayout fs = fileSelectMap.get(type);
- fs.parseResponse(result, this);
-
- String data = fs.getData();
-
- switch (type) {
- case USERPW_FILE:
- mEmbeddedPwFile = data;
- break;
- case PKCS12:
- mResult.mPKCS12Filename = data;
- break;
- case TLS_AUTH_FILE:
- mResult.mTLSAuthFilename = data;
- break;
- case CA_CERTIFICATE:
- mResult.mCaFilename = data;
- break;
- case CLIENT_CERTIFICATE:
- mResult.mClientCertFilename = data;
- break;
- case KEYFILE:
- mResult.mClientKeyFilename = data;
- break;
- default:
- Assert.fail();
- }
- }
-
- super.onActivityResult(requestCode, resultCode, result);
- }
-
- private void saveProfile() {
- Intent result = new Intent();
- ProfileManager vpl = ProfileManager.getInstance(this);
-
- if (!TextUtils.isEmpty(mEmbeddedPwFile))
- ConfigParser.useEmbbedUserAuth(mResult, mEmbeddedPwFile);
-
- vpl.addProfile(mResult);
- vpl.saveProfile(this, mResult);
- vpl.saveProfileList(this);
- result.putExtra(VpnProfile.EXTRA_PROFILEUUID, mResult.getUUID().toString());
- setResult(Activity.RESULT_OK, result);
- finish();
- }
-
- public void showCertDialog() {
- try {
- KeyChain.choosePrivateKeyAlias(this,
- new KeyChainAliasCallback() {
-
- public void alias(String alias) {
- // Credential alias selected. Remember the alias selection for future use.
- mResult.mAlias = alias;
- saveProfile();
- }
-
-
- },
- new String[]{"RSA"}, // List of acceptable key types. null for any
- null, // issuer, null for any
- mResult.mServerName, // host name of server requesting the cert, null if unavailable
- -1, // port of server requesting the cert, -1 if unavailable
- mAliasName); // alias to preselect, null if unavailable
- } catch (ActivityNotFoundException anf) {
- Builder ab = new AlertDialog.Builder(this);
- ab.setTitle(R.string.broken_image_cert_title);
- ab.setMessage(R.string.broken_image_cert);
- ab.setPositiveButton(android.R.string.ok, null);
- ab.show();
- }
- }
-
-
- private Intent installPKCS12() {
-
- if (!((CheckBox) findViewById(R.id.importpkcs12)).isChecked()) {
- setAuthTypeToEmbeddedPKCS12();
- return null;
-
- }
- String pkcs12datastr = mResult.mPKCS12Filename;
- if (VpnProfile.isEmbedded(pkcs12datastr)) {
- Intent inkeyIntent = KeyChain.createInstallIntent();
-
- pkcs12datastr = VpnProfile.getEmbeddedContent(pkcs12datastr);
-
-
- byte[] pkcs12data = Base64.decode(pkcs12datastr, Base64.DEFAULT);
-
-
- inkeyIntent.putExtra(KeyChain.EXTRA_PKCS12, pkcs12data);
-
- if (mAliasName.equals(""))
- mAliasName = null;
-
- if (mAliasName != null) {
- inkeyIntent.putExtra(KeyChain.EXTRA_NAME, mAliasName);
- }
- return inkeyIntent;
-
- }
- return null;
- }
-
-
- private void setAuthTypeToEmbeddedPKCS12() {
- if (VpnProfile.isEmbedded(mResult.mPKCS12Filename)) {
- if (mResult.mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE)
- mResult.mAuthenticationType = VpnProfile.TYPE_USERPASS_PKCS12;
-
- if (mResult.mAuthenticationType == VpnProfile.TYPE_KEYSTORE)
- mResult.mAuthenticationType = VpnProfile.TYPE_PKCS12;
-
- }
- }
-
-
- private String getUniqueProfileName(String possibleName) {
-
- int i = 0;
-
- ProfileManager vpl = ProfileManager.getInstance(this);
-
- String newname = possibleName;
-
- // Default to
- if (mResult.mName != null && !ConfigParser.CONVERTED_PROFILE.equals(mResult.mName))
- newname = mResult.mName;
-
- while (newname == null || vpl.getProfileByName(newname) != null) {
- i++;
- if (i == 1)
- newname = getString(R.string.converted_profile);
- else
- newname = getString(R.string.converted_profile_i, i);
- }
-
- return newname;
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.import_menu, menu);
- return true;
- }
-
- private String embedFile(String filename, Utils.FileType type) {
- if (filename == null)
- return null;
-
- // Already embedded, nothing to do
- if (VpnProfile.isEmbedded(filename))
- return filename;
-
- File possibleFile = findFile(filename, type);
- if (possibleFile == null)
- return filename;
- else
- return readFileContent(possibleFile, type == Utils.FileType.PKCS12);
-
- }
-
- private File findFile(String filename, Utils.FileType fileType) {
- File foundfile = findFileRaw(filename);
-
- if (foundfile == null && filename != null && !filename.equals("")) {
- log(R.string.import_could_not_open, filename);
- addFileSelectDialog(fileType);
- }
-
-
- return foundfile;
- }
-
- private void addFileSelectDialog(Utils.FileType type) {
- int titleRes = 0;
- String value = null;
- switch (type) {
- case KEYFILE:
- titleRes = R.string.client_key_title;
- if (mResult != null)
- value = mResult.mClientKeyFilename;
- break;
- case CLIENT_CERTIFICATE:
- titleRes = R.string.client_certificate_title;
- if (mResult != null)
- value = mResult.mClientCertFilename;
- break;
- case CA_CERTIFICATE:
- titleRes = R.string.ca_title;
- if (mResult != null)
- value = mResult.mCaFilename;
- break;
- case TLS_AUTH_FILE:
- titleRes = R.string.tls_auth_file;
- if (mResult != null)
- value = mResult.mTLSAuthFilename;
- break;
- case PKCS12:
- titleRes = R.string.client_pkcs12_title;
- if (mResult != null)
- value = mResult.mPKCS12Filename;
- break;
-
- case USERPW_FILE:
- titleRes = R.string.userpw_file;
- value = mEmbeddedPwFile;
- break;
-
- }
-
- boolean isCert = type == Utils.FileType.CA_CERTIFICATE || type == Utils.FileType.CLIENT_CERTIFICATE;
- FileSelectLayout fl = new FileSelectLayout(this, getString(titleRes), isCert);
- fileSelectMap.put(type, fl);
- fl.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-
- ((LinearLayout) findViewById(R.id.config_convert_root)).addView(fl, 2);
- findViewById(R.id.files_missing_hint).setVisibility(View.VISIBLE);
- fl.setData(value, this);
- int i = getFileLayoutOffset(type);
- fl.setCaller(this, i, type);
-
- }
-
- private int getFileLayoutOffset(Utils.FileType type) {
- return CHOOSE_FILE_OFFSET + type.getValue();
- }
-
-
- private File findFileRaw(String filename) {
- if (filename == null || filename.equals(""))
- return null;
-
- // Try diffent path relative to /mnt/sdcard
- File sdcard = Environment.getExternalStorageDirectory();
- File root = new File("/");
-
- HashSet<File> dirlist = new HashSet<File>();
-
- for (int i = mPathsegments.size() - 1; i >= 0; i--) {
- String path = "";
- for (int j = 0; j <= i; j++) {
- path += "/" + mPathsegments.get(j);
- }
- // Do a little hackish dance for the Android File Importer
- // /document/primary:ovpn/openvpn-imt.conf
-
-
- if (path.indexOf(':') != -1) {
- String possibleDir = path.substring(path.indexOf(':') + 1, path.length());
- possibleDir = possibleDir.substring(0, possibleDir.lastIndexOf('/'));
-
-
- dirlist.add(new File(sdcard, possibleDir));
-
- }
- dirlist.add(new File(path));
-
-
- }
- dirlist.add(sdcard);
- dirlist.add(root);
-
-
- String[] fileparts = filename.split("/");
- for (File rootdir : dirlist) {
- String suffix = "";
- for (int i = fileparts.length - 1; i >= 0; i--) {
- if (i == fileparts.length - 1)
- suffix = fileparts[i];
- else
- suffix = fileparts[i] + "/" + suffix;
-
- File possibleFile = new File(rootdir, suffix);
- if (!possibleFile.canRead())
- continue;
-
- // read the file inline
- return possibleFile;
-
- }
- }
- return null;
- }
-
- String readFileContent(File possibleFile, boolean base64encode) {
- byte[] filedata;
- try {
- filedata = readBytesFromFile(possibleFile);
- } catch (IOException e) {
- log(e.getLocalizedMessage());
- return null;
- }
-
- String data;
- if (base64encode) {
- data = Base64.encodeToString(filedata, Base64.DEFAULT);
- } else {
- data = new String(filedata);
-
- }
-
- return VpnProfile.DISPLAYNAME_TAG + possibleFile.getName() + VpnProfile.INLINE_TAG + data;
-
- }
-
-
- private byte[] readBytesFromFile(File file) throws IOException {
- InputStream input = new FileInputStream(file);
-
- long len = file.length();
- if (len > VpnProfile.MAX_EMBED_FILE_SIZE)
- throw new IOException("File size of file to import too large.");
-
- // Create the byte array to hold the data
- byte[] bytes = new byte[(int) len];
-
- // Read in the bytes
- int offset = 0;
- int bytesRead = 0;
- while (offset < bytes.length
- && (bytesRead = input.read(bytes, offset, bytes.length - offset)) >= 0) {
- offset += bytesRead;
- }
-
- input.close();
- return bytes;
- }
-
- void embedFiles() {
- // This where I would like to have a c++ style
- // void embedFile(std::string & option)
-
- if (mResult.mPKCS12Filename != null) {
- File pkcs12file = findFileRaw(mResult.mPKCS12Filename);
- if (pkcs12file != null) {
- mAliasName = pkcs12file.getName().replace(".p12", "");
- } else {
- mAliasName = "Imported PKCS12";
- }
- }
-
-
- mResult.mCaFilename = embedFile(mResult.mCaFilename, Utils.FileType.CA_CERTIFICATE);
- mResult.mClientCertFilename = embedFile(mResult.mClientCertFilename, Utils.FileType.CLIENT_CERTIFICATE);
- mResult.mClientKeyFilename = embedFile(mResult.mClientKeyFilename, Utils.FileType.KEYFILE);
- mResult.mTLSAuthFilename = embedFile(mResult.mTLSAuthFilename, Utils.FileType.TLS_AUTH_FILE);
- mResult.mPKCS12Filename = embedFile(mResult.mPKCS12Filename, Utils.FileType.PKCS12);
- mEmbeddedPwFile = embedFile(mResult.mPassword, Utils.FileType.USERPW_FILE);
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
-
- setContentView(R.layout.config_converter);
-
- mArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
- getListView().setAdapter(mArrayAdapter);
-
- super.onCreate(savedInstanceState);
-
-
- if (savedInstanceState != null && savedInstanceState.containsKey(VPNPROFILE)) {
- mResult = (VpnProfile) savedInstanceState.getSerializable(VPNPROFILE);
- mAliasName = savedInstanceState.getString("mAliasName");
- mEmbeddedPwFile = savedInstanceState.getString("pwfile");
- mArrayAdapter.addAll(savedInstanceState.getStringArray("logentries"));
- for (int k : savedInstanceState.getIntArray("fileselects")) {
- addFileSelectDialog(Utils.FileType.getFileTypeByValue(k));
- }
-
- return;
- }
-
-
- final android.content.Intent intent = getIntent();
-
- if (intent != null) {
- final android.net.Uri data = intent.getData();
- if (data != null) {
- //log(R.string.import_experimental);
- log(R.string.importing_config, data.toString());
- try {
- String possibleName = null;
- if (data.getScheme().equals("file") ||
- data.getLastPathSegment().endsWith(".ovpn") ||
- data.getLastPathSegment().endsWith(".conf")) {
- possibleName = data.getLastPathSegment();
- if (possibleName.lastIndexOf('/') != -1)
- possibleName = possibleName.substring(possibleName.lastIndexOf('/') + 1);
-
- }
- InputStream is = getContentResolver().openInputStream(data);
- mPathsegments = data.getPathSegments();
-
-
- Cursor cursor = getContentResolver().query(data, null, null, null, null);
- try {
-
-
- if (cursor!=null && cursor.moveToFirst()) {
- int cidx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
-
- if (cidx != -1) {
- String displayName = cursor.getString(cidx);
- if (displayName != null)
- possibleName = displayName;
- }
- cidx = cursor.getColumnIndex("mime_type");
- if (cidx != -1) {
- log("Opening Mime TYPE: " + cursor.getString(cidx));
- }
- }
- } finally {
- if(cursor!=null)
- cursor.close();
- }
- if (possibleName != null) {
- possibleName = possibleName.replace(".ovpn", "");
- possibleName = possibleName.replace(".conf", "");
- }
-
- doImport(is, possibleName);
-
- } catch (FileNotFoundException e) {
- log(R.string.import_content_resolve_error);
- }
- }
-
- // We parsed the intent, relay on saved instance for restoring
- setIntent(null);
- }
-
-
- }
-
-
- @Override
- protected void onStart() {
- super.onStart();
-
-
- }
-
- private void log(String logmessage) {
- mArrayAdapter.add(logmessage);
- }
-
- private void doImport(InputStream is, String newName) {
- ConfigParser cp = new ConfigParser();
- try {
- InputStreamReader isr = new InputStreamReader(is);
-
- cp.parseConfig(isr);
- VpnProfile vp = cp.convertProfile();
- mResult = vp;
- embedFiles();
- displayWarnings();
- mResult.mName = getUniqueProfileName(newName);
-
- log(R.string.import_done);
- return;
-
- } catch (IOException e) {
- log(R.string.error_reading_config_file);
- log(e.getLocalizedMessage());
- } catch (ConfigParseError e) {
- log(R.string.error_reading_config_file);
- log(e.getLocalizedMessage());
- }
- mResult = null;
-
- }
-
- private void displayWarnings() {
- if (mResult.mUseCustomConfig) {
- log(R.string.import_warning_custom_options);
- String copt = mResult.mCustomConfigOptions;
- if (copt.startsWith("#")) {
- int until = copt.indexOf('\n');
- copt = copt.substring(until + 1);
- }
-
- log(copt);
- }
-
- if (mResult.mAuthenticationType == VpnProfile.TYPE_KEYSTORE ||
- mResult.mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) {
- findViewById(R.id.importpkcs12).setVisibility(View.VISIBLE);
- }
-
- }
-
- private void log(int ressourceId, Object... formatArgs) {
- log(getString(ressourceId, formatArgs));
- }
-
-
-}
diff --git a/src/de/blinkt/openvpn/activities/CreateShortcuts.java b/src/de/blinkt/openvpn/activities/CreateShortcuts.java
deleted file mode 100644
index 53a829ff..00000000
--- a/src/de/blinkt/openvpn/activities/CreateShortcuts.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package de.blinkt.openvpn.activities;
-
-import android.app.ListActivity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-import de.blinkt.openvpn.LaunchVPN;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-import de.blinkt.openvpn.core.ProfileManager;
-
-import java.util.Collection;
-import java.util.Vector;
-
-/**
- * This Activity actually handles two stages of a launcher shortcut's life cycle.
- *
- * 1. Your application offers to provide shortcuts to the launcher. When
- * the user installs a shortcut, an activity within your application
- * generates the actual shortcut and returns it to the launcher, where it
- * is shown to the user as an icon.
- *
- * 2. Any time the user clicks on an installed shortcut, an intent is sent.
- * Typically this would then be handled as necessary by an activity within
- * your application.
- *
- * We handle stage 1 (creating a shortcut) by simply sending back the information (in the form
- * of an {@link android.content.Intent} that the launcher will use to create the shortcut.
- *
- * You can also implement this in an interactive way, by having your activity actually present
- * UI for the user to select the specific nature of the shortcut, such as a contact, picture, URL,
- * media item, or action.
- *
- * We handle stage 2 (responding to a shortcut) in this sample by simply displaying the contents
- * of the incoming {@link android.content.Intent}.
- *
- * In a real application, you would probably use the shortcut intent to display specific content
- * or start a particular operation.
- */
-public class CreateShortcuts extends ListActivity implements OnItemClickListener {
-
-
- private static final int START_VPN_PROFILE= 70;
-
-
- private ProfileManager mPM;
- private VpnProfile mSelectedProfile;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- mPM =ProfileManager.getInstance(this);
-
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- // Resolve the intent
-
- createListView();
- }
-
- private void createListView() {
- ListView lv = getListView();
- //lv.setTextFilterEnabled(true);
-
- Collection<VpnProfile> vpnList = mPM.getProfiles();
-
- Vector<String> vpnNames=new Vector<String>();
- for (VpnProfile vpnProfile : vpnList) {
- vpnNames.add(vpnProfile.mName);
- }
-
-
-
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,vpnNames);
- lv.setAdapter(adapter);
-
- lv.setOnItemClickListener(this);
- }
-
- /**
- * This function creates a shortcut and returns it to the caller. There are actually two
- * intents that you will send back.
- *
- * The first intent serves as a container for the shortcut and is returned to the launcher by
- * setResult(). This intent must contain three fields:
- *
- * <ul>
- * <li>{@link android.content.Intent#EXTRA_SHORTCUT_INTENT} The shortcut intent.</li>
- * <li>{@link android.content.Intent#EXTRA_SHORTCUT_NAME} The text that will be displayed with
- * the shortcut.</li>
- * <li>{@link android.content.Intent#EXTRA_SHORTCUT_ICON} The shortcut's icon, if provided as a
- * bitmap, <i>or</i> {@link android.content.Intent#EXTRA_SHORTCUT_ICON_RESOURCE} if provided as
- * a drawable resource.</li>
- * </ul>
- *
- * If you use a simple drawable resource, note that you must wrapper it using
- * {@link android.content.Intent.ShortcutIconResource}, as shown below. This is required so
- * that the launcher can access resources that are stored in your application's .apk file. If
- * you return a bitmap, such as a thumbnail, you can simply put the bitmap into the extras
- * bundle using {@link android.content.Intent#EXTRA_SHORTCUT_ICON}.
- *
- * The shortcut intent can be any intent that you wish the launcher to send, when the user
- * clicks on the shortcut. Typically this will be {@link android.content.Intent#ACTION_VIEW}
- * with an appropriate Uri for your content, but any Intent will work here as long as it
- * triggers the desired action within your Activity.
- * @param profile
- */
- private void setupShortcut(VpnProfile profile) {
- // First, set up the shortcut intent. For this example, we simply create an intent that
- // will bring us directly back to this activity. A more typical implementation would use a
- // data Uri in order to display a more specific result, or a custom action in order to
- // launch a specific operation.
-
- Intent shortcutIntent = new Intent(Intent.ACTION_MAIN);
- shortcutIntent.setClass(this, LaunchVPN.class);
- shortcutIntent.putExtra(LaunchVPN.EXTRA_KEY,profile.getUUID().toString());
-
- // Then, set up the container intent (the response to the caller)
-
- Intent intent = new Intent();
- intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
- intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, profile.getName());
- Parcelable iconResource = Intent.ShortcutIconResource.fromContext(
- this, R.drawable.icon);
- intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
-
- // Now, return the result to the launcher
-
- setResult(RESULT_OK, intent);
- }
-
-
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- String profileName = ((TextView) view).getText().toString();
-
- VpnProfile profile = mPM.getProfileByName(profileName);
-
- setupShortcut(profile);
- finish();
- }
-
-}
diff --git a/src/de/blinkt/openvpn/activities/DisconnectVPN.java b/src/de/blinkt/openvpn/activities/DisconnectVPN.java
deleted file mode 100644
index c2d4c599..00000000
--- a/src/de/blinkt/openvpn/activities/DisconnectVPN.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package de.blinkt.openvpn.activities;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.*;
-import android.os.IBinder;
-
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.core.OpenVpnService;
-import de.blinkt.openvpn.core.ProfileManager;
-
-/**
- * Created by arne on 13.10.13.
- */
-public class DisconnectVPN extends Activity implements DialogInterface.OnClickListener{
- protected OpenVpnService mService;
-
- private ServiceConnection mConnection = new ServiceConnection() {
-
-
- @Override
- public void onServiceConnected(ComponentName className,
- IBinder service) {
- // We've bound to LocalService, cast the IBinder and get LocalService instance
- OpenVpnService.LocalBinder binder = (OpenVpnService.LocalBinder) service;
- mService = binder.getService();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName arg0) {
- mService =null;
- }
-
- };
-
- @Override
- protected void onResume() {
- super.onResume();
- Intent intent = new Intent(this, OpenVpnService.class);
- intent.setAction(OpenVpnService.START_SERVICE);
- bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
- showDisconnectDialog();
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- unbindService(mConnection);
- }
-
- // if (getIntent() !=null && OpenVpnService.DISCONNECT_VPN.equals(getIntent().getAction()))
-
- // setIntent(null);
-
- /*
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- setIntent(intent);
- }
- */
-
- private void showDisconnectDialog() {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.title_cancel);
- builder.setMessage(R.string.cancel_connection_query);
- builder.setNegativeButton(android.R.string.no, this);
- builder.setPositiveButton(android.R.string.yes,this);
-
- builder.show();
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (which == DialogInterface.BUTTON_POSITIVE) {
- ProfileManager.setConntectedVpnProfileDisconnected(this);
- if (mService != null && mService.getManagement() != null)
- mService.getManagement().stopVPN();
- }
- finish();
- }
-}
diff --git a/src/de/blinkt/openvpn/activities/FileSelect.java b/src/de/blinkt/openvpn/activities/FileSelect.java
deleted file mode 100644
index 511dc736..00000000
--- a/src/de/blinkt/openvpn/activities/FileSelect.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package de.blinkt.openvpn.activities;
-
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
-import android.app.Fragment;
-import android.app.FragmentTransaction;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Base64;
-
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-import de.blinkt.openvpn.fragments.FileSelectionFragment;
-import de.blinkt.openvpn.fragments.InlineFileTab;
-
-public class FileSelect extends Activity {
- public static final String RESULT_DATA = "RESULT_PATH";
- public static final String START_DATA = "START_DATA";
- public static final String WINDOW_TITLE = "WINDOW_TILE";
- public static final String NO_INLINE_SELECTION = "de.blinkt.openvpn.NO_INLINE_SELECTION";
- public static final String SHOW_CLEAR_BUTTON = "de.blinkt.openvpn.SHOW_CLEAR_BUTTON";
- public static final String DO_BASE64_ENCODE = "de.blinkt.openvpn.BASE64ENCODE";
-
- private FileSelectionFragment mFSFragment;
- private InlineFileTab mInlineFragment;
- private String mData;
- private Tab inlineFileTab;
- private Tab fileExplorerTab;
- private boolean mNoInline;
- private boolean mShowClear;
- private boolean mBase64Encode;
-
-
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.file_dialog);
-
- mData = getIntent().getStringExtra(START_DATA);
- if(mData==null)
- mData=Environment.getExternalStorageDirectory().getPath();
-
- String title = getIntent().getStringExtra(WINDOW_TITLE);
- int titleId = getIntent().getIntExtra(WINDOW_TITLE, 0);
- if(titleId!=0)
- title =getString(titleId);
- if(title!=null)
- setTitle(title);
-
- mNoInline = getIntent().getBooleanExtra(NO_INLINE_SELECTION, false);
- mShowClear = getIntent().getBooleanExtra(SHOW_CLEAR_BUTTON, false);
- mBase64Encode = getIntent().getBooleanExtra(DO_BASE64_ENCODE, false);
-
- ActionBar bar = getActionBar();
- bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
- fileExplorerTab = bar.newTab().setText(R.string.file_explorer_tab);
- inlineFileTab = bar.newTab().setText(R.string.inline_file_tab);
-
- mFSFragment = new FileSelectionFragment();
- fileExplorerTab.setTabListener(new MyTabsListener<FileSelectionFragment>(this, mFSFragment));
- bar.addTab(fileExplorerTab);
-
- if(!mNoInline) {
- mInlineFragment = new InlineFileTab();
- inlineFileTab.setTabListener(new MyTabsListener<InlineFileTab>(this, mInlineFragment));
- bar.addTab(inlineFileTab);
- } else {
- mFSFragment.setNoInLine();
- }
-
-
- }
-
- public boolean showClear() {
- if(mData == null || mData.equals(""))
- return false;
- else
- return mShowClear;
- }
-
- protected class MyTabsListener<T extends Fragment> implements ActionBar.TabListener
- {
- private Fragment mFragment;
- private boolean mAdded=false;
-
- public MyTabsListener( Activity activity, Fragment fragment){
- this.mFragment = fragment;
- }
-
- public void onTabSelected(Tab tab, FragmentTransaction ft) {
- // Check if the fragment is already initialized
- if (!mAdded) {
- // If not, instantiate and add it to the activity
- ft.add(android.R.id.content, mFragment);
- mAdded =true;
- } else {
- // If it exists, simply attach it in order to show it
- ft.attach(mFragment);
- }
- }
-
- @Override
- public void onTabUnselected(Tab tab, FragmentTransaction ft) {
- ft.detach(mFragment);
- }
-
- @Override
- public void onTabReselected(Tab tab, FragmentTransaction ft) {
-
- }
- }
-
- public void importFile(String path) {
- File ifile = new File(path);
- Exception fe = null;
- try {
-
- String data = "";
-
- byte[] fileData = readBytesFromFile(ifile) ;
- if(mBase64Encode)
- data += Base64.encodeToString(fileData, Base64.DEFAULT);
- else
- data += new String(fileData);
-
- mData =data;
-
- /*
- mInlineFragment.setData(data);
- getActionBar().selectTab(inlineFileTab); */
- saveInlineData(ifile.getName(), data);
- } catch (FileNotFoundException e) {
- fe = e;
- } catch (IOException e) {
- fe =e;
- }
- if(fe!=null) {
- Builder ab = new AlertDialog.Builder(this);
- ab.setTitle(R.string.error_importing_file);
- ab.setMessage(getString(R.string.import_error_message) + "\n" + fe.getLocalizedMessage());
- ab.setPositiveButton(android.R.string.ok, null);
- ab.show();
- }
- }
-
- static private byte[] readBytesFromFile(File file) throws IOException {
- InputStream input = new FileInputStream(file);
-
- long len= file.length();
- if (len > VpnProfile.MAX_EMBED_FILE_SIZE)
- throw new IOException("selected file size too big to embed into profile");
-
- // Create the byte array to hold the data
- byte[] bytes = new byte[(int) len];
-
- // Read in the bytes
- int offset = 0;
- int bytesRead = 0;
- while (offset < bytes.length
- && (bytesRead=input.read(bytes, offset, bytes.length-offset)) >= 0) {
- offset += bytesRead;
- }
-
- input.close();
- return bytes;
- }
-
-
- public void setFile(String path) {
- Intent intent = new Intent();
- intent.putExtra(RESULT_DATA, path);
- setResult(Activity.RESULT_OK,intent);
- finish();
- }
-
- public String getSelectPath() {
- if(VpnProfile.isEmbedded(mData))
- return mData;
- else
- return Environment.getExternalStorageDirectory().getPath();
- }
-
- public CharSequence getInlineData() {
- if(VpnProfile.isEmbedded(mData))
- return VpnProfile.getEmbeddedContent(mData);
- else
- return "";
- }
-
- public void clearData() {
- Intent intent = new Intent();
- intent.putExtra(RESULT_DATA, (String)null);
- setResult(Activity.RESULT_OK,intent);
- finish();
-
- }
-
- public void saveInlineData(String fileName, String string) {
- Intent intent = new Intent();
-
- if(fileName==null)
- intent.putExtra(RESULT_DATA, VpnProfile.INLINE_TAG + string);
- else
- intent.putExtra(RESULT_DATA,VpnProfile.DISPLAYNAME_TAG + fileName + VpnProfile.INLINE_TAG + string);
- setResult(Activity.RESULT_OK, intent);
- finish();
-
- }
-}
diff --git a/src/de/blinkt/openvpn/activities/LogWindow.java b/src/de/blinkt/openvpn/activities/LogWindow.java
deleted file mode 100644
index 27197035..00000000
--- a/src/de/blinkt/openvpn/activities/LogWindow.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package de.blinkt.openvpn.activities;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.MenuItem;
-
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.fragments.LogFragment;
-
-/**
- * Created by arne on 13.10.13.
- */
-public class LogWindow extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.log_window);
- getActionBar().setDisplayHomeAsUpEnabled(true);
-
- if (savedInstanceState == null) {
- getFragmentManager().beginTransaction()
- .add(R.id.container, new LogFragment())
- .commit();
- }
-
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- return super.onOptionsItemSelected(item);
- }
-}
diff --git a/src/de/blinkt/openvpn/activities/MainActivity.java b/src/de/blinkt/openvpn/activities/MainActivity.java
deleted file mode 100644
index b32c80cc..00000000
--- a/src/de/blinkt/openvpn/activities/MainActivity.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package de.blinkt.openvpn.activities;
-
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentTransaction;
-import android.content.Intent;
-
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.fragments.*;
-
-
-public class MainActivity extends Activity {
-
- protected void onCreate(android.os.Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- ActionBar bar = getActionBar();
- bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-
- Tab vpnListTab = bar.newTab().setText(R.string.vpn_list_title);
- Tab generalTab = bar.newTab().setText(R.string.generalsettings);
- Tab faqtab = bar.newTab().setText(R.string.faq);
- Tab abouttab = bar.newTab().setText(R.string.about);
-
- vpnListTab.setTabListener(new TabListener<VPNProfileList>("profiles", VPNProfileList.class));
- generalTab.setTabListener(new TabListener<GeneralSettings>("settings", GeneralSettings.class));
- faqtab.setTabListener(new TabListener<FaqFragment>("faq", FaqFragment.class));
- abouttab.setTabListener(new TabListener<AboutFragment>("about", AboutFragment.class));
-
- bar.addTab(vpnListTab);
- bar.addTab(generalTab);
- bar.addTab(faqtab);
- bar.addTab(abouttab);
-
- if (false) {
- Tab logtab = bar.newTab().setText("Log");
- logtab.setTabListener(new TabListener<LogFragment>("log", LogFragment.class));
- bar.addTab(logtab);
- }
-
- if(SendDumpFragment.getLastestDump(this)!=null) {
- Tab sendDump = bar.newTab().setText(R.string.crashdump);
- sendDump.setTabListener(new TabListener<SendDumpFragment>("crashdump",SendDumpFragment.class));
- bar.addTab(sendDump);
- }
-
- }
-
- protected class TabListener<T extends Fragment> implements ActionBar.TabListener
- {
- private Fragment mFragment;
- private String mTag;
- private Class<T> mClass;
-
- public TabListener(String tag, Class<T> clz) {
- mTag = tag;
- mClass = clz;
-
- // Check to see if we already have a fragment for this tab, probably
- // from a previously saved state. If so, deactivate it, because our
- // initial state is that a tab isn't shown.
- mFragment = getFragmentManager().findFragmentByTag(mTag);
- if (mFragment != null && !mFragment.isDetached()) {
- FragmentTransaction ft = getFragmentManager().beginTransaction();
- ft.detach(mFragment);
- ft.commit();
- }
- }
-
- public void onTabSelected(Tab tab, FragmentTransaction ft) {
- if (mFragment == null) {
- mFragment = Fragment.instantiate(MainActivity.this, mClass.getName());
- ft.add(android.R.id.content, mFragment, mTag);
- } else {
- ft.attach(mFragment);
- }
- }
-
- public void onTabUnselected(Tab tab, FragmentTransaction ft) {
- if (mFragment != null) {
- ft.detach(mFragment);
- }
- }
-
-
- @Override
- public void onTabReselected(Tab tab, FragmentTransaction ft) {
-
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- System.out.println(data);
-
-
- }
-
-
-}
diff --git a/src/de/blinkt/openvpn/activities/VPNPreferences.java b/src/de/blinkt/openvpn/activities/VPNPreferences.java
deleted file mode 100644
index 1ebb16b2..00000000
--- a/src/de/blinkt/openvpn/activities/VPNPreferences.java
+++ /dev/null
@@ -1,165 +0,0 @@
-package de.blinkt.openvpn.activities;
-
-import java.util.List;
-
-import android.annotation.TargetApi;
-import android.app.AlertDialog;
-import android.app.Fragment;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Build;
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceFragment;
-import android.view.Menu;
-import android.view.MenuItem;
-
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-import de.blinkt.openvpn.core.ProfileManager;
-import de.blinkt.openvpn.fragments.Settings_Authentication;
-import de.blinkt.openvpn.fragments.Settings_Basic;
-import de.blinkt.openvpn.fragments.Settings_IP;
-import de.blinkt.openvpn.fragments.Settings_Obscure;
-import de.blinkt.openvpn.fragments.Settings_Routing;
-import de.blinkt.openvpn.fragments.ShowConfigFragment;
-import de.blinkt.openvpn.fragments.VPNProfileList;
-
-
-public class VPNPreferences extends PreferenceActivity {
-
- static final Class validFragments[] = new Class[] {
- Settings_Authentication.class, Settings_Basic.class, Settings_IP.class,
- Settings_Obscure.class, Settings_Routing.class, ShowConfigFragment.class
- };
-
- private String mProfileUUID;
- private VpnProfile mProfile;
-
- public VPNPreferences() {
- super();
- }
-
-
- @TargetApi(Build.VERSION_CODES.KITKAT)
- @Override
- protected boolean isValidFragment(String fragmentName) {
- for (Class c: validFragments)
- if (c.getName().equals(fragmentName))
- return true;
- return false;
-
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- outState.putString(getIntent().getStringExtra(getPackageName() + ".profileUUID"),mProfileUUID);
- super.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- Intent intent = getIntent();
-
-
- if(intent!=null) {
- String profileUUID = intent.getStringExtra(getPackageName() + ".profileUUID");
- if(profileUUID==null) {
- Bundle initialArguments = getIntent().getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
- profileUUID = initialArguments.getString(getPackageName() + ".profileUUID");
- }
- if(profileUUID!=null){
-
- mProfileUUID = profileUUID;
- mProfile = ProfileManager.get(this,mProfileUUID);
-
- }
- }
- // When a profile is deleted from a category fragment in hadset mod we need to finish
- // this activity as well when returning
- if (mProfile==null || mProfile.profileDleted) {
- setResult(VPNProfileList.RESULT_VPN_DELETED);
- finish();
- }
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- mProfileUUID = getIntent().getStringExtra(getPackageName() + ".profileUUID");
- if(savedInstanceState!=null){
- String savedUUID = savedInstanceState.getString(getPackageName() + ".profileUUID");
- if(savedUUID!=null)
- mProfileUUID=savedUUID;
- }
-
- mProfile = ProfileManager.get(this,mProfileUUID);
- if(mProfile!=null) {
- setTitle(getString(R.string.edit_profile_title, mProfile.getName()));
- }
- super.onCreate(savedInstanceState);
- }
-
-
-
- @Override
- public void onBuildHeaders(List<Header> target) {
- loadHeadersFromResource(R.xml.vpn_headers, target);
- for (Header header : target) {
- if(header.fragmentArguments==null)
- header.fragmentArguments = new Bundle();
- header.fragmentArguments.putString(getPackageName() + ".profileUUID",mProfileUUID);
- }
- }
-
- @Override
- public void onBackPressed() {
- setResult(RESULT_OK, getIntent());
- super.onBackPressed();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if(item.getItemId() == R.id.remove_vpn)
- askProfileRemoval();
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
-
- getMenuInflater().inflate(R.menu.vpnpreferences_menu, menu);
-
- return super.onCreateOptionsMenu(menu);
- }
-
- private void askProfileRemoval() {
- AlertDialog.Builder dialog = new AlertDialog.Builder(this);
- dialog.setTitle("Confirm deletion");
- dialog.setMessage(getString(R.string.remove_vpn_query, mProfile.mName));
-
- dialog.setPositiveButton(android.R.string.yes,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- removeProfile(mProfile);
- }
-
- });
- dialog.setNegativeButton(android.R.string.no,null);
- dialog.create().show();
- }
-
- protected void removeProfile(VpnProfile profile) {
- ProfileManager.getInstance(this).removeProfile(this,profile);
- setResult(VPNProfileList.RESULT_VPN_DELETED);
- finish();
-
- }
-}
-
diff --git a/src/de/blinkt/openvpn/api/APIVpnProfile.aidl b/src/de/blinkt/openvpn/api/APIVpnProfile.aidl
deleted file mode 100644
index f6799659..00000000
--- a/src/de/blinkt/openvpn/api/APIVpnProfile.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package de.blinkt.openvpn.api;
-
-parcelable APIVpnProfile;
diff --git a/src/de/blinkt/openvpn/api/APIVpnProfile.java b/src/de/blinkt/openvpn/api/APIVpnProfile.java
deleted file mode 100644
index f5591764..00000000
--- a/src/de/blinkt/openvpn/api/APIVpnProfile.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package de.blinkt.openvpn.api;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class APIVpnProfile implements Parcelable {
-
- public final String mUUID;
- public final String mName;
- public final boolean mUserEditable;
-
- public APIVpnProfile(Parcel in) {
- mUUID = in.readString();
- mName = in.readString();
- mUserEditable = in.readInt() != 0;
- }
-
- public APIVpnProfile(String uuidString, String name, boolean userEditable) {
- mUUID=uuidString;
- mName = name;
- mUserEditable=userEditable;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mUUID);
- dest.writeString(mName);
- if(mUserEditable)
- dest.writeInt(0);
- else
- dest.writeInt(1);
- }
-
- public static final Parcelable.Creator<APIVpnProfile> CREATOR
- = new Parcelable.Creator<APIVpnProfile>() {
- public APIVpnProfile createFromParcel(Parcel in) {
- return new APIVpnProfile(in);
- }
-
- public APIVpnProfile[] newArray(int size) {
- return new APIVpnProfile[size];
- }
- };
-
-
-}
diff --git a/src/de/blinkt/openvpn/api/ConfirmDialog.java b/src/de/blinkt/openvpn/api/ConfirmDialog.java
deleted file mode 100644
index bcab79ed..00000000
--- a/src/de/blinkt/openvpn/api/ConfirmDialog.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package de.blinkt.openvpn.api;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnShowListener;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.TextView;
-import de.blinkt.openvpn.R;
-
-
-public class ConfirmDialog extends Activity implements
-CompoundButton.OnCheckedChangeListener, DialogInterface.OnClickListener {
- private static final String TAG = "OpenVPNVpnConfirm";
-
- private String mPackage;
-
- private Button mButton;
-
- private AlertDialog mAlert;
-
- @Override
- protected void onResume() {
- super.onResume();
- try {
- mPackage = getCallingPackage();
- if (mPackage==null) {
- finish();
- return;
- }
-
-
- PackageManager pm = getPackageManager();
- ApplicationInfo app = pm.getApplicationInfo(mPackage, 0);
-
- View view = View.inflate(this, R.layout.api_confirm, null);
- ((ImageView) view.findViewById(R.id.icon)).setImageDrawable(app.loadIcon(pm));
- ((TextView) view.findViewById(R.id.prompt)).setText(
- getString(R.string.prompt, app.loadLabel(pm), getString(R.string.app)));
- ((CompoundButton) view.findViewById(R.id.check)).setOnCheckedChangeListener(this);
-
-
- Builder builder = new AlertDialog.Builder(this);
-
- builder.setView(view);
-
- builder.setIconAttribute(android.R.attr.alertDialogIcon);
- builder.setTitle(android.R.string.dialog_alert_title);
- builder.setPositiveButton(android.R.string.ok,this);
- builder.setNegativeButton(android.R.string.cancel,this);
-
- mAlert = builder.create();
- mAlert.setCanceledOnTouchOutside(false);
-
- mAlert.setOnShowListener (new OnShowListener() {
-
- @Override
- public void onShow(DialogInterface dialog) {
- mButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
- mButton.setEnabled(false);
-
- }
- });
-
- //setCloseOnTouchOutside(false);
-
- mAlert.show();
-
- } catch (Exception e) {
- Log.e(TAG, "onResume", e);
- finish();
- }
- }
-
- @Override
- public void onBackPressed() {
- setResult(RESULT_CANCELED);
- finish();
- }
-
- @Override
- public void onCheckedChanged(CompoundButton button, boolean checked) {
- mButton.setEnabled(checked);
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
-
- if (which == DialogInterface.BUTTON_POSITIVE) {
- ExternalAppDatabase extapps = new ExternalAppDatabase(this);
- extapps.addApp(mPackage);
- setResult(RESULT_OK);
- finish();
- }
-
- if (which == DialogInterface.BUTTON_NEGATIVE) {
- setResult(RESULT_CANCELED);
- finish();
- }
- }
-
-}
-
diff --git a/src/de/blinkt/openvpn/api/ExternalAppDatabase.java b/src/de/blinkt/openvpn/api/ExternalAppDatabase.java
deleted file mode 100644
index 02c369b1..00000000
--- a/src/de/blinkt/openvpn/api/ExternalAppDatabase.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package de.blinkt.openvpn.api;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.preference.PreferenceManager;
-
-public class ExternalAppDatabase {
-
- Context mContext;
-
- public ExternalAppDatabase(Context c) {
- mContext =c;
- }
-
- private final String PREFERENCES_KEY = "PREFERENCES_KEY";
-
- boolean isAllowed(String packagename) {
- Set<String> allowedapps = getExtAppList();
-
- return allowedapps.contains(packagename);
-
- }
-
- public Set<String> getExtAppList() {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
- return prefs.getStringSet(PREFERENCES_KEY, new HashSet<String>());
- }
-
- void addApp(String packagename)
- {
- Set<String> allowedapps = getExtAppList();
- allowedapps.add(packagename);
- saveExtAppList(allowedapps);
- }
-
- private void saveExtAppList( Set<String> allowedapps) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
- Editor prefedit = prefs.edit();
- prefedit.putStringSet(PREFERENCES_KEY, allowedapps);
- prefedit.apply();
- }
-
- public void clearAllApiApps() {
- saveExtAppList(new HashSet<String>());
- }
-
- public void removeApp(String packagename) {
- Set<String> allowedapps = getExtAppList();
- allowedapps.remove(packagename);
- saveExtAppList(allowedapps);
- }
-
-}
diff --git a/src/de/blinkt/openvpn/api/ExternalOpenVPNService.java b/src/de/blinkt/openvpn/api/ExternalOpenVPNService.java
deleted file mode 100644
index 928a85eb..00000000
--- a/src/de/blinkt/openvpn/api/ExternalOpenVPNService.java
+++ /dev/null
@@ -1,317 +0,0 @@
-package de.blinkt.openvpn.api;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.lang.ref.WeakReference;
-import java.util.LinkedList;
-import java.util.List;
-
-import android.annotation.TargetApi;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.VpnService;
-import android.os.*;
-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.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;
-import de.blinkt.openvpn.core.VPNLaunchHelper;
-
-@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
-public class ExternalOpenVPNService extends Service implements StateListener {
-
- private static final int SEND_TOALL = 0;
-
- final RemoteCallbackList<IOpenVPNStatusCallback> mCallbacks =
- new RemoteCallbackList<IOpenVPNStatusCallback>();
-
- private OpenVpnService mService;
- private ExternalAppDatabase mExtAppDb;
-
-
- private ServiceConnection mConnection = new ServiceConnection() {
-
-
- @Override
- public void onServiceConnected(ComponentName className,
- IBinder service) {
- // We've bound to LocalService, cast the IBinder and get LocalService instance
- LocalBinder binder = (LocalBinder) service;
- mService = binder.getService();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName arg0) {
- mService = null;
- }
-
- };
-
- @Override
- public void onCreate() {
- super.onCreate();
- VpnStatus.addStateListener(this);
- mExtAppDb = new ExternalAppDatabase(this);
-
- Intent intent = new Intent(getBaseContext(), OpenVpnService.class);
- intent.setAction(OpenVpnService.START_SERVICE);
-
- bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
- mHandler.setService(this);
- }
-
- private final IOpenVPNAPIService.Stub mBinder = new IOpenVPNAPIService.Stub() {
-
- private void checkOpenVPNPermission() throws SecurityRemoteException {
- PackageManager pm = getPackageManager();
-
- for (String apppackage : mExtAppDb.getExtAppList()) {
- ApplicationInfo app;
- try {
- app = pm.getApplicationInfo(apppackage, 0);
- if (Binder.getCallingUid() == app.uid) {
- return;
- }
- } catch (NameNotFoundException e) {
- // App not found. Remove it from the list
- mExtAppDb.removeApp(apppackage);
- }
-
- }
- throw new SecurityException("Unauthorized OpenVPN API Caller");
- }
-
- @Override
- public List<APIVpnProfile> getProfiles() throws RemoteException {
- checkOpenVPNPermission();
-
- ProfileManager pm = ProfileManager.getInstance(getBaseContext());
-
- List<APIVpnProfile> profiles = new LinkedList<APIVpnProfile>();
-
- for (VpnProfile vp : pm.getProfiles())
- profiles.add(new APIVpnProfile(vp.getUUIDString(), vp.mName, vp.mUserEditable));
-
- return profiles;
- }
-
- @Override
- public void startProfile(String profileUUID) throws RemoteException {
- checkOpenVPNPermission();
-
- Intent shortVPNIntent = new Intent(Intent.ACTION_MAIN);
- shortVPNIntent.setClass(getBaseContext(), de.blinkt.openvpn.LaunchVPN.class);
- shortVPNIntent.putExtra(de.blinkt.openvpn.LaunchVPN.EXTRA_KEY, profileUUID);
- shortVPNIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(shortVPNIntent);
- }
-
- public void startVPN(String inlineconfig) throws RemoteException {
- checkOpenVPNPermission();
-
- ConfigParser cp = new ConfigParser();
- try {
- cp.parseConfig(new StringReader(inlineconfig));
- VpnProfile vp = cp.convertProfile();
- if (vp.checkProfile(getApplicationContext()) != R.string.no_error_found)
- throw new RemoteException(getString(vp.checkProfile(getApplicationContext())));
-
-
- ProfileManager.setTemporaryProfile(vp);
- VPNLaunchHelper.startOpenVpn(vp, getBaseContext());
-
-
- } catch (IOException e) {
- throw new RemoteException(e.getMessage());
- } catch (ConfigParseError e) {
- throw new RemoteException(e.getMessage());
- }
- }
-
- @Override
- public boolean addVPNProfile(String name, String config) throws RemoteException {
- checkOpenVPNPermission();
-
- ConfigParser cp = new ConfigParser();
- try {
- cp.parseConfig(new StringReader(config));
- VpnProfile vp = cp.convertProfile();
- vp.mName = name;
- ProfileManager pm = ProfileManager.getInstance(getBaseContext());
- pm.addProfile(vp);
- } catch (IOException e) {
- VpnStatus.logException(e);
- return false;
- } catch (ConfigParseError e) {
- VpnStatus.logException(e);
- return false;
- }
-
- return true;
- }
-
-
- @Override
- public Intent prepare(String packagename) {
- if (new ExternalAppDatabase(ExternalOpenVPNService.this).isAllowed(packagename))
- return null;
-
- Intent intent = new Intent();
- intent.setClass(ExternalOpenVPNService.this, ConfirmDialog.class);
- return intent;
- }
-
- @Override
- public Intent prepareVPNService() throws RemoteException {
- checkOpenVPNPermission();
-
- if (VpnService.prepare(ExternalOpenVPNService.this) == null)
- return null;
- else
- return new Intent(getBaseContext(), GrantPermissionsActivity.class);
- }
-
-
- @Override
- public void registerStatusCallback(IOpenVPNStatusCallback cb)
- throws RemoteException {
- checkOpenVPNPermission();
-
- if (cb != null) {
- cb.newStatus(mMostRecentState.vpnUUID, mMostRecentState.state,
- mMostRecentState.logmessage, mMostRecentState.level.name());
- mCallbacks.register(cb);
- }
-
-
- }
-
- @Override
- public void unregisterStatusCallback(IOpenVPNStatusCallback cb)
- throws RemoteException {
- checkOpenVPNPermission();
-
- if (cb != null)
- mCallbacks.unregister(cb);
- }
-
- @Override
- public void disconnect() throws RemoteException {
- checkOpenVPNPermission();
- if (mService != null && mService.getManagement() != null)
- mService.getManagement().stopVPN();
- }
-
- @Override
- public void pause() throws RemoteException {
- checkOpenVPNPermission();
- if (mService != null)
- mService.userPause(true);
- }
-
- @Override
- public void resume() throws RemoteException {
- checkOpenVPNPermission();
- if (mService != null)
- mService.userPause(false);
-
- }
- };
-
-
- private UpdateMessage mMostRecentState;
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mCallbacks.kill();
- unbindService(mConnection);
- VpnStatus.removeStateListener(this);
- }
-
- class UpdateMessage {
- public String state;
- public String logmessage;
- public ConnectionStatus level;
- public String vpnUUID;
-
- public UpdateMessage(String state, String logmessage, ConnectionStatus level) {
- this.state = state;
- this.logmessage = logmessage;
- this.level = level;
- }
- }
-
- @Override
- public void updateState(String state, String logmessage, int resid, ConnectionStatus level) {
- mMostRecentState = new UpdateMessage(state, logmessage, level);
- if (ProfileManager.getLastConnectedVpn() != null)
- mMostRecentState.vpnUUID = ProfileManager.getLastConnectedVpn().getUUIDString();
-
- Message msg = mHandler.obtainMessage(SEND_TOALL, mMostRecentState);
- msg.sendToTarget();
-
- }
-
- private static final OpenVPNServiceHandler mHandler = new OpenVPNServiceHandler();
-
-
- static class OpenVPNServiceHandler extends Handler {
- WeakReference<ExternalOpenVPNService> service = null;
-
- private void setService(ExternalOpenVPNService eos) {
- service = new WeakReference<ExternalOpenVPNService>(eos);
- }
-
- @Override
- public void handleMessage(Message msg) {
-
- RemoteCallbackList<IOpenVPNStatusCallback> callbacks;
- switch (msg.what) {
- case SEND_TOALL:
- if (service == null || service.get() == null)
- return;
-
- callbacks = service.get().mCallbacks;
-
-
- // Broadcast to all clients the new value.
- final int N = callbacks.beginBroadcast();
- for (int i = 0; i < N; i++) {
- try {
- sendUpdate(callbacks.getBroadcastItem(i), (UpdateMessage) msg.obj);
- } catch (RemoteException e) {
- // The RemoteCallbackList will take care of removing
- // the dead object for us.
- }
- }
- callbacks.finishBroadcast();
- break;
- }
- }
-
- private void sendUpdate(IOpenVPNStatusCallback broadcastItem,
- UpdateMessage um) throws RemoteException {
- broadcastItem.newStatus(um.vpnUUID, um.state, um.logmessage, um.level.name());
- }
- }
-
-
-} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/api/GrantPermissionsActivity.java b/src/de/blinkt/openvpn/api/GrantPermissionsActivity.java
deleted file mode 100644
index 659ec24b..00000000
--- a/src/de/blinkt/openvpn/api/GrantPermissionsActivity.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package de.blinkt.openvpn.api;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.VpnService;
-
-public class GrantPermissionsActivity extends Activity {
- private static final int VPN_PREPARE = 0;
-
- @Override
- protected void onStart() {
- super.onStart();
- Intent i= VpnService.prepare(this);
- if(i==null)
- onActivityResult(VPN_PREPARE, RESULT_OK, null);
- else
- startActivityForResult(i, VPN_PREPARE);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- setResult(resultCode);
- finish();
- }
-}
diff --git a/src/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl b/src/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl
deleted file mode 100644
index 794e3aad..00000000
--- a/src/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl
+++ /dev/null
@@ -1,50 +0,0 @@
-// IOpenVPNAPIService.aidl
-package de.blinkt.openvpn.api;
-
-import de.blinkt.openvpn.api.APIVpnProfile;
-import de.blinkt.openvpn.api.IOpenVPNStatusCallback;
-
-import android.content.Intent;
-import android.os.ParcelFileDescriptor;
-
-interface IOpenVPNAPIService {
- List<APIVpnProfile> getProfiles();
-
- void startProfile (String profileUUID);
-
- /** Use a profile with all certificates etc. embedded */
- boolean addVPNProfile (String name, String config);
-
- /** start a profile using an config */
- void startVPN (String inlineconfig);
-
- /** This permission framework is used to avoid confused deputy style attack to the VPN
- * calling this will give null if the app is allowed to use the external API and an Intent
- * that can be launched to request permissions otherwise */
- Intent prepare (String packagename);
-
- /** Used to trigger to the Android VPN permission dialog (VPNService.prepare()) in advance,
- * if this return null OpenVPN for ANdroid already has the permissions otherwise you can start the returned Intent
- * to let OpenVPN for Android request the permission */
- Intent prepareVPNService ();
-
- /* Disconnect the VPN */
- void disconnect();
-
- /* Pause the VPN (same as using the pause feature in the notifcation bar) */
- void pause();
-
- /* Resume the VPN (same as using the pause feature in the notifcation bar) */
- void resume();
-
- /**
- * Registers to receive OpenVPN Status Updates
- */
- void registerStatusCallback(IOpenVPNStatusCallback cb);
-
- /**
- * Remove a previously registered callback interface.
- */
- void unregisterStatusCallback(IOpenVPNStatusCallback cb);
-
-} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl b/src/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl
deleted file mode 100644
index 1dfa1381..00000000
--- a/src/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.blinkt.openvpn.api;
-
-/**
- * Example of a callback interface used by IRemoteService to send
- * synchronous notifications back to its clients. Note that this is a
- * one-way interface so the server does not block waiting for the client.
- */
-oneway interface IOpenVPNStatusCallback {
- /**
- * Called when the service has a new status for you.
- */
- void newStatus(String uuid, String state, String message, String level);
-}
diff --git a/src/de/blinkt/openvpn/api/SecurityRemoteException.java b/src/de/blinkt/openvpn/api/SecurityRemoteException.java
deleted file mode 100644
index e6011aa3..00000000
--- a/src/de/blinkt/openvpn/api/SecurityRemoteException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package de.blinkt.openvpn.api;
-
-import android.os.RemoteException;
-
-public class SecurityRemoteException extends RemoteException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
-}
diff --git a/src/de/blinkt/openvpn/core/CIDRIP.java b/src/de/blinkt/openvpn/core/CIDRIP.java
deleted file mode 100644
index 960e7d11..00000000
--- a/src/de/blinkt/openvpn/core/CIDRIP.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import java.util.Locale;
-
-class CIDRIP {
- String mIp;
- int len;
-
-
- public CIDRIP(String ip, String mask) {
- mIp = ip;
- long netmask = getInt(mask);
-
- // Add 33. bit to ensure the loop terminates
- netmask += 1l << 32;
-
- int lenZeros = 0;
- while ((netmask & 0x1) == 0) {
- lenZeros++;
- netmask = netmask >> 1;
- }
- // Check if rest of netmask is only 1s
- if (netmask != (0x1ffffffffl >> lenZeros)) {
- // Asume no CIDR, set /32
- len = 32;
- } else {
- len = 32 - lenZeros;
- }
-
- }
-
- public CIDRIP(String address, int prefix_length) {
- len = prefix_length;
- mIp = address;
- }
-
- @Override
- public String toString() {
- return String.format(Locale.ENGLISH, "%s/%d", mIp, len);
- }
-
- public boolean normalise() {
- long ip = getInt(mIp);
-
- long newip = ip & (0xffffffffl << (32 - len));
- if (newip != ip) {
- mIp = String.format("%d.%d.%d.%d", (newip & 0xff000000) >> 24, (newip & 0xff0000) >> 16, (newip & 0xff00) >> 8, newip & 0xff);
- return true;
- } else {
- return false;
- }
- }
-
- static long getInt(String ipaddr) {
- String[] ipt = ipaddr.split("\\.");
- long ip = 0;
-
- ip += Long.parseLong(ipt[0]) << 24;
- ip += Integer.parseInt(ipt[1]) << 16;
- ip += Integer.parseInt(ipt[2]) << 8;
- ip += Integer.parseInt(ipt[3]);
-
- return ip;
- }
-
- public long getInt() {
- return getInt(mIp);
- }
-
-} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/core/ConfigParser.java b/src/de/blinkt/openvpn/core/ConfigParser.java
deleted file mode 100644
index 22cc5dce..00000000
--- a/src/de/blinkt/openvpn/core/ConfigParser.java
+++ /dev/null
@@ -1,762 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import de.blinkt.openvpn.VpnProfile;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Vector;
-
-//! Openvpn Config FIle Parser, probably not 100% accurate but close enough
-
-// And remember, this is valid :)
-// --<foo>
-// bar
-// </foo>
-public class ConfigParser {
-
-
- public static final String CONVERTED_PROFILE = "converted Profile";
- private HashMap<String, Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>();
- private HashMap<String, Vector<String>> meta = new HashMap<String, Vector<String>>();
-
-
- private boolean extraRemotesAsCustom=false;
-
- public void parseConfig(Reader reader) throws IOException, ConfigParseError {
-
-
- BufferedReader br =new BufferedReader(reader);
-
- while (true){
- String line = br.readLine();
- if(line==null)
- break;
-
- // Check for OpenVPN Access Server Meta information
- if (line.startsWith("# OVPN_ACCESS_SERVER_")) {
- Vector<String> metaarg = parsemeta(line);
- meta.put(metaarg.get(0),metaarg);
- continue;
- }
- Vector<String> args = parseline(line);
-
- if(args.size() ==0)
- continue;
-
-
- if(args.get(0).startsWith("--"))
- args.set(0, args.get(0).substring(2));
-
- checkinlinefile(args,br);
-
- String optionname = args.get(0);
- if(!options.containsKey(optionname)) {
- options.put(optionname, new Vector<Vector<String>>());
- }
- options.get(optionname).add(args);
- }
- }
-
- private Vector<String> parsemeta(String line) {
- String meta = line.split("#\\sOVPN_ACCESS_SERVER_", 2)[1];
- String[] parts = meta.split("=",2);
- Vector<String> rval = new Vector<String>();
- Collections.addAll(rval, parts);
- return rval;
-
- }
-
- private void checkinlinefile(Vector<String> args, BufferedReader br) throws IOException, ConfigParseError {
- String arg0 = args.get(0).trim();
- // CHeck for <foo>
- if(arg0.startsWith("<") && arg0.endsWith(">")) {
- String argname = arg0.substring(1, arg0.length()-1);
- String inlinefile = VpnProfile.INLINE_TAG;
-
- String endtag = String.format("</%s>",argname);
- do {
- String line = br.readLine();
- if(line==null){
- throw new ConfigParseError(String.format("No endtag </%s> for starttag <%s> found",argname,argname));
- }
- if(line.trim().equals(endtag))
- break;
- else {
- inlinefile+=line;
- inlinefile+= "\n";
- }
- } while(true);
-
- args.clear();
- args.add(argname);
- args.add(inlinefile);
- }
-
- }
-
- enum linestate {
- initial,
- readin_single_quote
- , reading_quoted, reading_unquoted, done}
-
- private boolean space(char c) {
- // I really hope nobody is using zero bytes inside his/her config file
- // to sperate parameter but here we go:
- return Character.isWhitespace(c) || c == '\0';
-
- }
-
- public class ConfigParseError extends Exception {
- private static final long serialVersionUID = -60L;
-
- public ConfigParseError(String msg) {
- super(msg);
- }
- }
-
-
- // adapted openvpn's parse function to java
- private Vector<String> parseline(String line) throws ConfigParseError {
- Vector<String> parameters = new Vector<String>();
-
- if (line.length()==0)
- return parameters;
-
-
- linestate state = linestate.initial;
- boolean backslash = false;
- char out=0;
-
- int pos=0;
- String currentarg="";
-
- do {
- // Emulate the c parsing ...
- char in;
- if(pos < line.length())
- in = line.charAt(pos);
- else
- in = '\0';
-
- if (!backslash && in == '\\' && state != linestate.readin_single_quote)
- {
- backslash = true;
- }
- else
- {
- if (state == linestate.initial)
- {
- if (!space (in))
- {
- if (in == ';' || in == '#') /* comment */
- break;
- if (!backslash && in == '\"')
- state = linestate.reading_quoted;
- else if (!backslash && in == '\'')
- state = linestate.readin_single_quote;
- else
- {
- out = in;
- state = linestate.reading_unquoted;
- }
- }
- }
- else if (state == linestate.reading_unquoted)
- {
- if (!backslash && space (in))
- state = linestate.done;
- else
- out = in;
- }
- else if (state == linestate.reading_quoted)
- {
- if (!backslash && in == '\"')
- state = linestate.done;
- else
- out = in;
- }
- else if (state == linestate.readin_single_quote)
- {
- if (in == '\'')
- state = linestate.done;
- else
- out = in;
- }
-
- if (state == linestate.done)
- {
- /* ASSERT (parm_len > 0); */
- state = linestate.initial;
- parameters.add(currentarg);
- currentarg = "";
- out =0;
- }
-
- if (backslash && out!=0)
- {
- if (!(out == '\\' || out == '\"' || space (out)))
- {
- throw new ConfigParseError("Options warning: Bad backslash ('\\') usage");
- }
- }
- backslash = false;
- }
-
- /* store parameter character */
- if (out!=0)
- {
- currentarg+=out;
- }
- } while (pos++ < line.length());
-
- return parameters;
- }
-
-
- final String[] unsupportedOptions = { "config",
- "connection",
- "proto-force",
- "remote-random",
- "tls-server"
-
- };
-
- // Ignore all scripts
- // in most cases these won't work and user who wish to execute scripts will
- // figure out themselves
- final String[] ignoreOptions = { "tls-client",
- "askpass",
- "auth-nocache",
- "up",
- "down",
- "route-up",
- "ipchange",
- "route-up",
- "route-pre-down",
- "auth-user-pass-verify",
- "dhcp-release",
- "dhcp-renew",
- "dh",
- "group",
- "ip-win32",
- "management-hold",
- "management",
- "management-client",
- "management-query-remote",
- "management-query-passwords",
- "management-query-proxy",
- "management-external-key",
- "management-forget-disconnect",
- "management-signal",
- "management-log-cache",
- "management-up-down",
- "management-client-user",
- "management-client-group",
- "pause-exit",
- "plugin",
- "machine-readable-output",
- "persist-key",
- "register-dns",
- "route-delay",
- "route-gateway",
- "route-metric",
- "route-method",
- "status",
- "script-security",
- "show-net-up",
- "suppress-timestamps",
- "tmp-dir",
- "tun-ipv6",
- "topology",
- "user",
- "win-sys",
-
- };
-
- final String[][] ignoreOptionsWithArg =
- {
- {"setenv", "IV_GUI_VER"},
- {"setenv", "IV_OPENVPN_GUI_VERSION"}
- };
-
- final String[] connectionOptions = {
- "local",
- "remote",
- "float",
- "port",
-// "connect-retry",
- "connect-timeout",
- "connect-retry-max",
- "link-mtu",
- "tun-mtu",
- "tun-mtu-extra",
- "fragment",
- "mtu-disc",
- "local-port",
- "remote-port",
- "bind",
- "nobind",
- "proto",
- "http-proxy",
- "http-proxy-retry",
- "http-proxy-timeout",
- "http-proxy-option",
- "socks-proxy",
- "socks-proxy-retry",
- "explicit-exit-notify",
- "mssfix"
- };
-
-
- // This method is far too long
- public VpnProfile convertProfile() throws ConfigParseError{
- boolean noauthtypeset=true;
- VpnProfile np = new VpnProfile(CONVERTED_PROFILE);
- // Pull, client, tls-client
- np.clearDefaults();
-
- if(options.containsKey("client") || options.containsKey("pull")) {
- np.mUsePull=true;
- options.remove("pull");
- options.remove("client");
- }
-
- Vector<String> secret = getOption("secret", 1, 2);
- if(secret!=null)
- {
- np.mAuthenticationType=VpnProfile.TYPE_STATICKEYS;
- noauthtypeset=false;
- np.mUseTLSAuth=true;
- np.mTLSAuthFilename=secret.get(1);
- if(secret.size()==3)
- np.mTLSAuthDirection=secret.get(2);
-
- }
-
- Vector<Vector<String>> routes = getAllOption("route", 1, 4);
- if(routes!=null) {
- String routeopt = "";
- String routeExcluded = "";
- for(Vector<String> route:routes){
- String netmask = "255.255.255.255";
- String gateway = "vpn_gateway";
-
- if(route.size() >= 3)
- netmask = route.get(2);
- if (route.size() >= 4)
- gateway = route.get(3);
-
- String net = route.get(1);
- try {
- CIDRIP cidr = new CIDRIP(net, netmask);
- if (gateway.equals("net_gateway"))
- routeExcluded += cidr.toString() + " ";
- else
- routeopt+=cidr.toString() + " ";
- } catch (ArrayIndexOutOfBoundsException aioob) {
- throw new ConfigParseError("Could not parse netmask of route " + netmask);
- } catch (NumberFormatException ne) {
- throw new ConfigParseError("Could not parse netmask of route " + netmask);
- }
-
- }
- np.mCustomRoutes=routeopt;
- np.mExcludedRoutes=routeExcluded;
- }
-
- Vector<Vector<String>> routesV6 = getAllOption("route-ipv6", 1, 4);
- if (routesV6!=null) {
- String customIPv6Routes = "";
- for (Vector<String> route:routesV6){
- customIPv6Routes += route.get(1) + " ";
- }
-
- np.mCustomRoutesv6 = customIPv6Routes;
- }
-
- // Also recognize tls-auth [inline] direction ...
- Vector<Vector<String>> tlsauthoptions = getAllOption("tls-auth", 1, 2);
- if(tlsauthoptions!=null) {
- for(Vector<String> tlsauth:tlsauthoptions) {
- if(tlsauth!=null)
- {
- if(!tlsauth.get(1).equals("[inline]")) {
- np.mTLSAuthFilename=tlsauth.get(1);
- np.mUseTLSAuth=true;
- }
- if(tlsauth.size()==3)
- np.mTLSAuthDirection=tlsauth.get(2);
- }
- }
- }
-
- Vector<String> direction = getOption("key-direction", 1, 1);
- if(direction!=null)
- np.mTLSAuthDirection=direction.get(1);
-
- Vector<Vector<String>> defgw = getAllOption("redirect-gateway", 0, 5);
- if(defgw != null)
- {
- np.mUseDefaultRoute=true;
- checkRedirectParameters(np, defgw);
- }
-
- Vector<Vector<String>> redirectPrivate = getAllOption("redirect-private",0,5);
- if (redirectPrivate != null)
- {
- checkRedirectParameters(np,redirectPrivate);
- }
- Vector<String> dev =getOption("dev",1,1);
- Vector<String> devtype =getOption("dev-type",1,1);
-
- if ((devtype != null && devtype.get(1).equals("tun")) ||
- (dev != null && dev.get(1).startsWith("tun")) ||
- (devtype == null && dev == null)) {
- //everything okay
- } else {
- throw new ConfigParseError("Sorry. Only tun mode is supported. See the FAQ for more detail");
- }
-
-
-
- Vector<String> mode =getOption("mode",1,1);
- if (mode != null){
- if(!mode.get(1).equals("p2p"))
- throw new ConfigParseError("Invalid mode for --mode specified, need p2p");
- }
-
- Vector<String> port = getOption("port", 1,1);
- if(port!=null){
- np.mServerPort = port.get(1);
- }
-
- Vector<String> rport = getOption("rport", 1,1);
- if(port!=null){
- np.mServerPort = port.get(1);
- }
-
- Vector<String> proto = getOption("proto", 1,1);
- if(proto!=null){
- np.mUseUdp=isUdpProto(proto.get(1));
- }
-
- // Parse remote config
- Vector<Vector<String>> remotes = getAllOption("remote",1,3);
-
- if(remotes!=null && remotes.size()>=1 ) {
- Vector<String> remote = remotes.get(0);
- switch (remote.size()) {
- case 4:
- np.mUseUdp=isUdpProto(remote.get(3));
- case 3:
- np.mServerPort = remote.get(2);
- case 2:
- np.mServerName = remote.get(1);
- }
- }
-
-
-
- Vector<Vector<String>> dhcpoptions = getAllOption("dhcp-option", 2, 2);
- if(dhcpoptions!=null) {
- for(Vector<String> dhcpoption:dhcpoptions) {
- String type=dhcpoption.get(1);
- String arg = dhcpoption.get(2);
- if(type.equals("DOMAIN")) {
- np.mSearchDomain=dhcpoption.get(2);
- } else if(type.equals("DNS")) {
- np.mOverrideDNS=true;
- if(np.mDNS1.equals(VpnProfile.DEFAULT_DNS1))
- np.mDNS1=arg;
- else
- np.mDNS2=arg;
- }
- }
- }
-
- Vector<String> ifconfig = getOption("ifconfig", 2, 2);
- if(ifconfig!=null) {
- try {
- CIDRIP cidr = new CIDRIP(ifconfig.get(1), ifconfig.get(2));
- np.mIPv4Address=cidr.toString();
- } catch (NumberFormatException nfe) {
- throw new ConfigParseError("Could not pase ifconfig IP address: " + nfe.getLocalizedMessage());
- }
-
- }
-
- if(getOption("remote-random-hostname", 0, 0)!=null)
- np.mUseRandomHostname=true;
-
- if(getOption("float", 0, 0)!=null)
- np.mUseFloat=true;
-
- if(getOption("comp-lzo", 0, 1)!=null)
- np.mUseLzo=true;
-
- Vector<String> cipher = getOption("cipher", 1, 1);
- if(cipher!=null)
- np.mCipher= cipher.get(1);
-
- Vector<String> auth = getOption("auth", 1, 1);
- if(auth!=null)
- np.mAuth = auth.get(1);
-
-
- Vector<String> ca = getOption("ca",1,1);
- if(ca!=null){
- np.mCaFilename = ca.get(1);
- }
-
- Vector<String> cert = getOption("cert",1,1);
- if(cert!=null){
- np.mClientCertFilename = cert.get(1);
- np.mAuthenticationType = VpnProfile.TYPE_CERTIFICATES;
- noauthtypeset=false;
- }
- Vector<String> key= getOption("key",1,1);
- if(key!=null)
- np.mClientKeyFilename=key.get(1);
-
- Vector<String> pkcs12 = getOption("pkcs12",1,1);
- if(pkcs12!=null) {
- np.mPKCS12Filename = pkcs12.get(1);
- np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE;
- noauthtypeset=false;
- }
-
-
- Vector<String> compatnames = getOption("compat-names",1,2);
- Vector<String> nonameremapping = getOption("no-name-remapping",1,1);
- Vector<String> tlsremote = getOption("tls-remote",1,1);
- if(tlsremote!=null){
- np.mRemoteCN = tlsremote.get(1);
- np.mCheckRemoteCN=true;
- np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE;
-
- if((compatnames!=null && compatnames.size() > 2) ||
- (nonameremapping!=null))
- np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING;
- }
-
- Vector<String> verifyx509name = getOption("verify-x509-name",1,2);
- if(verifyx509name!=null){
- np.mRemoteCN = verifyx509name.get(1);
- np.mCheckRemoteCN=true;
- if(verifyx509name.size()>2) {
- if (verifyx509name.get(2).equals("name"))
- np.mX509AuthType=VpnProfile.X509_VERIFY_TLSREMOTE_RDN;
- else if (verifyx509name.get(2).equals("name-prefix"))
- np.mX509AuthType=VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX;
- else
- throw new ConfigParseError("Unknown parameter to x509-verify-name: " + verifyx509name.get(2) );
- } else {
- np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_DN;
- }
-
- }
-
-
- Vector<String> verb = getOption("verb",1,1);
- if(verb!=null){
- np.mVerb=verb.get(1);
- }
-
-
- if(getOption("nobind", 0, 0) != null)
- np.mNobind=true;
-
- if(getOption("persist-tun", 0,0) != null)
- np.mPersistTun=true;
-
- Vector<String> connectretry = getOption("connect-retry", 1, 1);
- if(connectretry!=null)
- np.mConnectRetry =connectretry.get(1);
-
- Vector<String> connectretrymax = getOption("connect-retry-max", 1, 1);
- if(connectretrymax!=null)
- np.mConnectRetryMax =connectretrymax.get(1);
-
- Vector<Vector<String>> remotetls = getAllOption("remote-cert-tls", 1, 1);
- if(remotetls!=null)
- if(remotetls.get(0).get(1).equals("server"))
- np.mExpectTLSCert=true;
- else
- options.put("remotetls",remotetls);
-
- Vector<String> authuser = getOption("auth-user-pass",0,1);
- if(authuser !=null){
- if(noauthtypeset) {
- np.mAuthenticationType=VpnProfile.TYPE_USERPASS;
- } else if(np.mAuthenticationType==VpnProfile.TYPE_CERTIFICATES) {
- np.mAuthenticationType=VpnProfile.TYPE_USERPASS_CERTIFICATES;
- } else if(np.mAuthenticationType==VpnProfile.TYPE_KEYSTORE) {
- np.mAuthenticationType=VpnProfile.TYPE_USERPASS_KEYSTORE;
- }
- if(authuser.size()>1) {
- // Set option value to password get to get cance to embed later.
- np.mUsername=null;
- np.mPassword=authuser.get(1);
- useEmbbedUserAuth(np,authuser.get(1));
- }
- }
-
- // Parse OpenVPN Access Server extra
- Vector<String> friendlyname = meta.get("FRIENDLY_NAME");
- if(friendlyname !=null && friendlyname.size() > 1)
- np.mName=friendlyname.get(1);
-
-
- Vector<String> ocusername = meta.get("USERNAME");
- if(ocusername !=null && ocusername.size() > 1)
- np.mUsername=ocusername.get(1);
-
- // Check the other options
- if(remotes !=null && remotes.size()>1 && extraRemotesAsCustom) {
- // first is already added
- remotes.remove(0);
- np.mCustomConfigOptions += getOptionStrings(remotes);
- np.mUseCustomConfig=true;
-
- }
- checkIgnoreAndInvalidOptions(np);
- fixup(np);
-
- return np;
- }
-
- private void checkRedirectParameters(VpnProfile np, Vector<Vector<String>> defgw) {
- for (Vector<String> redirect: defgw)
- for (int i=1;i<redirect.size();i++){
- if (defgw.get(i).equals("block-local"))
- np.mAllowLocalLAN=false;
- else if (defgw.get(i).equals("unblock-local"))
- np.mAllowLocalLAN=true;
- }
- }
-
- public void useExtraRemotesAsCustom(boolean b) {
- this.extraRemotesAsCustom = b;
- }
-
- private boolean isUdpProto(String proto) throws ConfigParseError {
- boolean isudp;
- if(proto.equals("udp") || proto.equals("udp6"))
- isudp=true;
- else if (proto.equals("tcp-client") ||
- proto.equals("tcp") ||
- proto.equals("tcp6") ||
- proto.endsWith("tcp6-client"))
- isudp =false;
- else
- throw new ConfigParseError("Unsupported option to --proto " + proto);
- return isudp;
- }
-
- static public void useEmbbedUserAuth(VpnProfile np,String inlinedata)
- {
- String data = VpnProfile.getEmbeddedContent(inlinedata);
- String[] parts = data.split("\n");
- if(parts.length >= 2) {
- np.mUsername=parts[0];
- np.mPassword=parts[1];
- }
- }
-
- private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError {
- for(String option:unsupportedOptions)
- if(options.containsKey(option))
- throw new ConfigParseError(String.format("Unsupported Option %s encountered in config file. Aborting",option));
-
- for(String option:ignoreOptions)
- // removing an item which is not in the map is no error
- options.remove(option);
-
-
-
-
- if(options.size()> 0) {
- np.mCustomConfigOptions += "# These Options were found in the config file do not map to config settings:\n";
-
- for(Vector<Vector<String>> option:options.values()) {
-
- np.mCustomConfigOptions += getOptionStrings(option);
-
- }
- np.mUseCustomConfig=true;
-
- }
- }
-
-
- boolean ignoreThisOption(Vector<String> option) {
- for (String[] ignoreOption : ignoreOptionsWithArg) {
-
- if (option.size() < ignoreOption.length)
- continue;
-
- boolean ignore = true;
- for (int i = 0; i < ignoreOption.length; i++) {
- if (!ignoreOption[i].equals(option.get(i)))
- ignore = false;
- }
- if (ignore)
- return true;
-
- }
- return false;
- }
-
- private String getOptionStrings(Vector<Vector<String>> option) {
- String custom = "";
- for (Vector<String> optionsline : option) {
- if (!ignoreThisOption(optionsline)) {
- for (String arg : optionsline)
- custom += VpnProfile.openVpnEscape(arg) + " ";
- custom += "\n";
- }
- }
- return custom;
- }
-
-
- private void fixup(VpnProfile np) {
- if(np.mRemoteCN.equals(np.mServerName)) {
- np.mRemoteCN="";
- }
- }
-
- private Vector<String> getOption(String option, int minarg, int maxarg) throws ConfigParseError {
- Vector<Vector<String>> alloptions = getAllOption(option, minarg, maxarg);
- if(alloptions==null)
- return null;
- else
- return alloptions.lastElement();
- }
-
-
- private Vector<Vector<String>> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError {
- Vector<Vector<String>> args = options.get(option);
- if(args==null)
- return null;
-
- for(Vector<String> optionline:args)
-
- if(optionline.size()< (minarg+1) || optionline.size() > maxarg+1) {
- String err = String.format(Locale.getDefault(),"Option %s has %d parameters, expected between %d and %d",
- option,optionline.size()-1,minarg,maxarg );
- throw new ConfigParseError(err);
- }
- options.remove(option);
- return args;
- }
-
-}
-
-
-
-
diff --git a/src/de/blinkt/openvpn/core/DeviceStateReceiver.java b/src/de/blinkt/openvpn/core/DeviceStateReceiver.java
deleted file mode 100644
index 250edf42..00000000
--- a/src/de/blinkt/openvpn/core/DeviceStateReceiver.java
+++ /dev/null
@@ -1,239 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.State;
-import android.preference.PreferenceManager;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.core.VpnStatus.ByteCountListener;
-
-import java.util.LinkedList;
-
-import static de.blinkt.openvpn.core.OpenVPNManagement.pauseReason;
-
-public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountListener {
- private int lastNetwork = -1;
- private OpenVPNManagement mManagement;
-
- // Window time in s
- private final int TRAFFIC_WINDOW = 60;
- // Data traffic limit in bytes
- private final long TRAFFIC_LIMIT = 64 * 1024;
-
-
- connectState network = connectState.DISCONNECTED;
- connectState screen = connectState.SHOULDBECONNECTED;
- connectState userpause = connectState.SHOULDBECONNECTED;
-
- private String lastStateMsg = null;
-
- enum connectState {
- SHOULDBECONNECTED,
- PENDINGDISCONNECT,
- DISCONNECTED
- }
-
- static class Datapoint {
- private Datapoint(long t, long d) {
- timestamp = t;
- data = d;
- }
-
- long timestamp;
- long data;
- }
-
- LinkedList<Datapoint> trafficdata = new LinkedList<DeviceStateReceiver.Datapoint>();
-
- @Override
- public void updateByteCount(long in, long out, long diffIn, long diffOut) {
- if (screen != connectState.PENDINGDISCONNECT)
- return;
-
- long total = diffIn + diffOut;
- trafficdata.add(new Datapoint(System.currentTimeMillis(), total));
-
- while (trafficdata.getFirst().timestamp <= (System.currentTimeMillis() - TRAFFIC_WINDOW * 1000)) {
- trafficdata.removeFirst();
- }
-
- long windowtraffic = 0;
- for (Datapoint dp : trafficdata)
- windowtraffic += dp.data;
-
- if (windowtraffic < TRAFFIC_LIMIT) {
- screen = connectState.DISCONNECTED;
- VpnStatus.logInfo(R.string.screenoff_pause,
- OpenVpnService.humanReadableByteCount(TRAFFIC_LIMIT, false), TRAFFIC_WINDOW);
-
- mManagement.pause(getPauseReason());
- }
- }
-
-
- public void userPause(boolean pause) {
- if (pause) {
- userpause = connectState.DISCONNECTED;
- // Check if we should disconnect
- mManagement.pause(getPauseReason());
- } else {
- boolean wereConnected = shouldBeConnected();
- userpause = connectState.SHOULDBECONNECTED;
- if (shouldBeConnected() && !wereConnected)
- mManagement.resume();
- else
- // Update the reason why we currently paused
- mManagement.pause(getPauseReason());
- }
- }
-
- public DeviceStateReceiver(OpenVPNManagement magnagement) {
- super();
- mManagement = magnagement;
- }
-
-
- @Override
- public void onReceive(Context context, Intent intent) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-
-
- if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
- networkStateChange(context);
- } else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
- boolean screenOffPause = prefs.getBoolean("screenoff", false);
-
- if (screenOffPause) {
- if (!ProfileManager.getLastConnectedVpn().mPersistTun)
- VpnStatus.logError(R.string.screen_nopersistenttun);
-
- screen = connectState.PENDINGDISCONNECT;
- fillTrafficData();
- if (network == connectState.DISCONNECTED || userpause == connectState.DISCONNECTED)
- screen = connectState.DISCONNECTED;
- }
- } else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
- // Network was disabled because screen off
- boolean connected = shouldBeConnected();
- screen = connectState.SHOULDBECONNECTED;
-
- /* should be connected has changed because the screen is on now, connect the VPN */
- if (shouldBeConnected() != connected)
- mManagement.resume();
- else if (!shouldBeConnected())
- /*Update the reason why we are still paused */
- mManagement.pause(getPauseReason());
-
- }
- }
-
-
- private void fillTrafficData() {
- trafficdata.add(new Datapoint(System.currentTimeMillis(), TRAFFIC_LIMIT));
- }
-
-
- public void networkStateChange(Context context) {
- NetworkInfo networkInfo = getCurrentNetworkInfo(context);
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- boolean sendusr1 = prefs.getBoolean("netchangereconnect", true);
-
-
- String netstatestring;
- if (networkInfo == null) {
- netstatestring = "not connected";
- } else {
- String subtype = networkInfo.getSubtypeName();
- if (subtype == null)
- subtype = "";
- String extrainfo = networkInfo.getExtraInfo();
- if (extrainfo == null)
- extrainfo = "";
-
- /*
- if(networkInfo.getType()==android.net.ConnectivityManager.TYPE_WIFI) {
- WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
- WifiInfo wifiinfo = wifiMgr.getConnectionInfo();
- extrainfo+=wifiinfo.getBSSID();
-
- subtype += wifiinfo.getNetworkId();
- }*/
-
-
- netstatestring = String.format("%2$s %4$s to %1$s %3$s", networkInfo.getTypeName(),
- networkInfo.getDetailedState(), extrainfo, subtype);
- }
-
- if (networkInfo != null && networkInfo.getState() == State.CONNECTED) {
- int newnet = networkInfo.getType();
- network = connectState.SHOULDBECONNECTED;
-
- if (sendusr1 && lastNetwork != newnet) {
- if (screen == connectState.PENDINGDISCONNECT)
- screen = connectState.DISCONNECTED;
-
- if (shouldBeConnected()) {
- if (lastNetwork == -1) {
- mManagement.resume();
- } else {
- mManagement.reconnect();
- }
- }
-
-
- lastNetwork = newnet;
- }
- } else if (networkInfo == null) {
- // Not connected, stop openvpn, set last connected network to no network
- lastNetwork = -1;
- if (sendusr1) {
- network = connectState.DISCONNECTED;
-
- // Set screen state to be disconnected if disconnect pending
- if (screen == connectState.PENDINGDISCONNECT)
- screen = connectState.DISCONNECTED;
-
- mManagement.pause(getPauseReason());
- }
- }
-
-
- if (!netstatestring.equals(lastStateMsg))
- VpnStatus.logInfo(R.string.netstatus, netstatestring);
- lastStateMsg = netstatestring;
-
- }
-
- public boolean isUserPaused() {
- return userpause == connectState.DISCONNECTED;
- }
-
- private boolean shouldBeConnected() {
- return (screen == connectState.SHOULDBECONNECTED && userpause == connectState.SHOULDBECONNECTED &&
- network == connectState.SHOULDBECONNECTED);
- }
-
- private pauseReason getPauseReason() {
- if (userpause == connectState.DISCONNECTED)
- return pauseReason.userPause;
-
- if (screen == connectState.DISCONNECTED)
- return pauseReason.screenOff;
-
- if (network == connectState.DISCONNECTED)
- return pauseReason.noNetwork;
-
- return pauseReason.userPause;
- }
-
- private NetworkInfo getCurrentNetworkInfo(Context context) {
- ConnectivityManager conn = (ConnectivityManager)
- context.getSystemService(Context.CONNECTIVITY_SERVICE);
-
- return conn.getActiveNetworkInfo();
- }
-}
diff --git a/src/de/blinkt/openvpn/core/GetRestrictionReceiver.java b/src/de/blinkt/openvpn/core/GetRestrictionReceiver.java
deleted file mode 100644
index 7f8498d5..00000000
--- a/src/de/blinkt/openvpn/core/GetRestrictionReceiver.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.RestrictionEntry;
-import android.os.Build;
-import android.os.Bundle;
-
-import java.util.ArrayList;
-
-import de.blinkt.openvpn.R;
-
-/**
- * Created by arne on 25.07.13.
- */
-@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
-public class GetRestrictionReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(final Context context, Intent intent) {
- final PendingResult result = goAsync();
-
- new Thread() {
- @Override
- public void run() {
- final Bundle extras = new Bundle();
-
- ArrayList<RestrictionEntry> restrictionEntries = initRestrictions(context);
-
- extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS_LIST, restrictionEntries);
- result.setResult(Activity.RESULT_OK,null,extras);
- result.finish();
- }
- }.run();
- }
-
- private ArrayList<RestrictionEntry> initRestrictions(Context context) {
- ArrayList<RestrictionEntry> restrictions = new ArrayList<RestrictionEntry>();
- RestrictionEntry allowChanges = new RestrictionEntry("allow_changes",false);
- allowChanges.setTitle(context.getString(R.string.allow_vpn_changes));
- restrictions.add(allowChanges);
-
- return restrictions;
- }
-}
diff --git a/src/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/src/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
deleted file mode 100644
index 1daa3433..00000000
--- a/src/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import android.app.Application;
-
-/**
- * Created by arne on 28.12.13.
- */
-public class ICSOpenVPNApplication extends Application {
- @Override
- public void onCreate() {
- super.onCreate();
- PRNGFixes.apply();
- }
-}
diff --git a/src/de/blinkt/openvpn/core/NativeUtils.java b/src/de/blinkt/openvpn/core/NativeUtils.java
deleted file mode 100644
index a2c4796d..00000000
--- a/src/de/blinkt/openvpn/core/NativeUtils.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import java.security.InvalidKeyException;
-
-public class NativeUtils {
- public static native byte[] rsasign(byte[] input,int pkey) throws InvalidKeyException;
- static native void jniclose(int fdint);
-
- static {
- System.loadLibrary("stlport_shared");
- System.loadLibrary("opvpnutil");
- }
-}
diff --git a/src/de/blinkt/openvpn/core/NetworkSpace.java b/src/de/blinkt/openvpn/core/NetworkSpace.java
deleted file mode 100644
index c7d09065..00000000
--- a/src/de/blinkt/openvpn/core/NetworkSpace.java
+++ /dev/null
@@ -1,274 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import android.os.Build;
-import android.text.TextUtils;
-
-import java.math.BigInteger;
-import java.net.Inet6Address;
-import java.util.*;
-
-public class NetworkSpace {
-
-
- static class ipAddress implements Comparable<ipAddress> {
- private BigInteger netAddress;
- public int networkMask;
- private boolean included;
- private boolean isV4;
-
-
- @Override
- public int compareTo(ipAddress another) {
- int comp = getFirstAddress().compareTo(another.getFirstAddress());
- if (comp != 0)
- return comp;
-
- // bigger mask means smaller address block
- if (networkMask > another.networkMask)
- return -1;
- else if (another.networkMask == networkMask)
- return 0;
- else
- return 1;
-
-
- }
-
- public ipAddress(CIDRIP ip, boolean include) {
- included = include;
- netAddress = BigInteger.valueOf(ip.getInt());
- networkMask = ip.len;
- isV4 = true;
- }
-
- public ipAddress(Inet6Address address, int mask, boolean include) {
- networkMask = mask;
- included = include;
-
- int s = 128;
-
- netAddress = BigInteger.ZERO;
- for (byte b : address.getAddress()) {
- s -= 16;
- netAddress = netAddress.add(BigInteger.valueOf(b).shiftLeft(s));
- }
- }
-
- public BigInteger getLastAddress() {
- return getMaskedAddress(true);
- }
-
-
- public BigInteger getFirstAddress() {
- return getMaskedAddress(false);
- }
-
-
- private BigInteger getMaskedAddress(boolean one) {
- BigInteger numAddress = netAddress;
-
- int numBits;
- if (isV4) {
- numBits = 32 - networkMask;
- } else {
- numBits = 128 - networkMask;
- }
-
- for (int i = 0; i < numBits; i++) {
- if (one)
- numAddress = numAddress.setBit(i);
- else
- numAddress = numAddress.clearBit(i);
- }
- return numAddress;
- }
-
-
- @Override
- public String toString() {
- //String in = included ? "+" : "-";
- if (isV4)
- return String.format(Locale.US,"%s/%d", getIPv4Address(), networkMask);
- else
- return String.format(Locale.US, "%s/%d", getIPv6Address(), networkMask);
- }
-
- ipAddress(BigInteger baseAddress, int mask, boolean included, boolean isV4) {
- this.netAddress = baseAddress;
- this.networkMask = mask;
- this.included = included;
- this.isV4 = isV4;
- }
-
-
- public ipAddress[] split() {
- ipAddress firsthalf = new ipAddress(getFirstAddress(), networkMask + 1, included, isV4);
- ipAddress secondhalf = new ipAddress(firsthalf.getLastAddress().add(BigInteger.ONE), networkMask + 1, included, isV4);
- assert secondhalf.getLastAddress().equals(getLastAddress());
- return new ipAddress[]{firsthalf, secondhalf};
- }
-
- String getIPv4Address() {
- assert (isV4);
- assert (netAddress.longValue() <= 0xffffffffl);
- assert (netAddress.longValue() >= 0);
- long ip = netAddress.longValue();
- return String.format(Locale.US, "%d.%d.%d.%d", (ip >> 24) % 256, (ip >> 16) % 256, (ip >> 8) % 256, ip % 256);
- }
-
- String getIPv6Address() {
- assert (!isV4);
- BigInteger r = netAddress;
- if (r.longValue() == 0)
- return "::";
-
- Vector<String> parts = new Vector<String>();
- while (r.compareTo(BigInteger.ZERO) == 1) {
- parts.add(0, String.format(Locale.US, "%x", r.mod(BigInteger.valueOf(256)).longValue()));
- r = r.shiftRight(16);
- }
-
- return TextUtils.join(":", parts);
- }
-
- public boolean containsNet(ipAddress network) {
- return getFirstAddress().compareTo(network.getFirstAddress()) != 1 &&
- getLastAddress().compareTo(network.getLastAddress()) != -1;
- }
- }
-
-
- TreeSet<ipAddress> mIpAddresses = new TreeSet<ipAddress>();
-
-
- public Collection<ipAddress> getNetworks(boolean included) {
- Vector<ipAddress> ips = new Vector<ipAddress>();
- for (ipAddress ip : mIpAddresses) {
- if (ip.included == included)
- ips.add(ip);
- }
- return ips;
- }
-
- public void clear() {
- mIpAddresses.clear();
- }
-
-
- void addIP(CIDRIP cidrIp, boolean include) {
-
- mIpAddresses.add(new ipAddress(cidrIp, include));
- }
-
- void addIPv6(Inet6Address address, int mask, boolean included) {
- mIpAddresses.add(new ipAddress(address, mask, included));
- }
-
- TreeSet<ipAddress> generateIPList() {
- TreeSet<ipAddress> ipsSorted = new TreeSet<ipAddress>(mIpAddresses);
- Iterator<ipAddress> it = ipsSorted.iterator();
-
- ipAddress currentNet = null;
- if (it.hasNext())
- currentNet = it.next();
- while (it.hasNext()) {
- // Check if it and the next of it are compatbile
- ipAddress nextNet = it.next();
-
- assert currentNet != null;
- if (currentNet.getLastAddress().compareTo(nextNet.getFirstAddress()) == -1) {
- // Everything good, no overlapping nothing to do
- currentNet = nextNet;
- } else {
- // This network is smaller or equal to the next but has the same base address
- if (currentNet.getFirstAddress().equals(nextNet.getFirstAddress()) && currentNet.networkMask >= nextNet.networkMask) {
- if (currentNet.included == nextNet.included) {
- ipsSorted.remove(currentNet);
- } else {
-
- // our currentnet is included in next and nextnet needs to be split
- ipsSorted.remove(nextNet);
- ipAddress[] newNets = nextNet.split();
-
- if (newNets[0].getLastAddress().equals(currentNet.getLastAddress())) {
- assert (newNets[0].networkMask == currentNet.networkMask);
- // Don't add the lower half that would conflict with currentNet
- } else {
- ipsSorted.add(newNets[0]);
- }
-
- ipsSorted.add(newNets[1]);
- }
- } else {
- assert (currentNet.networkMask < nextNet.networkMask);
- assert (nextNet.getFirstAddress().compareTo(currentNet.getFirstAddress()) == 1);
- // This network is bigger than the next and last ip of current >= next
- assert (currentNet.getLastAddress().compareTo(nextNet.getLastAddress()) != -1);
-
- if (currentNet.included == nextNet.included) {
- ipsSorted.remove(nextNet);
- } else {
- ipsSorted.remove(currentNet);
- ipAddress[] newNets = currentNet.split();
-
- ipsSorted.add(newNets[0]);
-
- if (newNets[1].networkMask == nextNet.networkMask) {
- assert (newNets[1].getFirstAddress().equals(nextNet.getFirstAddress()));
- assert (newNets[1].getLastAddress().equals(currentNet.getLastAddress()));
- } else {
- ipsSorted.add(newNets[1]);
- }
- }
- }
- // Reset iterator
- it = ipsSorted.iterator();
- currentNet = it.next();
- }
-
- }
-
- return ipsSorted;
- }
-
- Collection<ipAddress> getPositiveIPList() {
- TreeSet<ipAddress> ipsSorted = generateIPList();
-
- Vector<ipAddress> ips = new Vector<ipAddress>();
- for (ipAddress ia : ipsSorted) {
- if (ia.included)
- ips.add(ia);
- }
-
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
- // Include postive routes from the original set under < 4.4 since these might overrule the local
- // network but only if no smaller negative route exists
- for(ipAddress origIp: mIpAddresses){
- if (!origIp.included)
- continue;
-
- // The netspace exists
- if(ipsSorted.contains(origIp))
- continue;
-
- boolean skipIp=false;
- // If there is any smaller net that is excluded we may not add the positive route back
- for (ipAddress calculatedIp: ipsSorted) {
- if(!calculatedIp.included && origIp.containsNet(calculatedIp)) {
- skipIp=true;
- break;
- }
- }
- if (skipIp)
- continue;
-
- // It is safe to include the IP
- ips.add(origIp);
- }
-
- }
-
- return ips;
- }
-
-}
diff --git a/src/de/blinkt/openvpn/core/OpenVPNManagement.java b/src/de/blinkt/openvpn/core/OpenVPNManagement.java
deleted file mode 100644
index ce8d38c2..00000000
--- a/src/de/blinkt/openvpn/core/OpenVPNManagement.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package de.blinkt.openvpn.core;
-
-public interface OpenVPNManagement {
- enum pauseReason {
- noNetwork,
- userPause,
- screenOff
- }
-
- int mBytecountInterval =2;
-
- void reconnect();
-
- void pause(pauseReason reason);
-
- void resume();
-
- boolean stopVPN();
-
-}
diff --git a/src/de/blinkt/openvpn/core/OpenVPNThread.java b/src/de/blinkt/openvpn/core/OpenVPNThread.java
deleted file mode 100644
index dacd41c9..00000000
--- a/src/de/blinkt/openvpn/core/OpenVPNThread.java
+++ /dev/null
@@ -1,174 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import android.util.Log;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
-import de.blinkt.openvpn.core.VpnStatus.LogItem;
-
-import java.io.*;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class OpenVPNThread implements Runnable {
- private static final String DUMP_PATH_STRING = "Dump path: ";
- private static final String TAG = "OpenVPN";
- public static final int M_FATAL = (1 << 4);
- public static final int M_NONFATAL = (1 << 5);
- public static final int M_WARN = (1 << 6);
- public static final int M_DEBUG = (1 << 7);
- private String[] mArgv;
- private Process mProcess;
- private String mNativeDir;
- private OpenVpnService mService;
- private String mDumpPath;
- private Map<String, String> mProcessEnv;
-
- public OpenVPNThread(OpenVpnService service,String[] argv, Map<String,String> processEnv, String nativelibdir)
- {
- mArgv = argv;
- mNativeDir = nativelibdir;
- mService = service;
- mProcessEnv = processEnv;
- }
-
- public void stopProcess() {
- mProcess.destroy();
- }
-
-
-
- @Override
- public void run() {
- try {
- Log.i(TAG, "Starting openvpn");
- startOpenVPNThreadArgs(mArgv, mProcessEnv);
- Log.i(TAG, "Giving up");
- } catch (Exception e) {
- VpnStatus.logException("Starting OpenVPN Thread" ,e);
- Log.e(TAG, "OpenVPNThread Got " + e.toString());
- } finally {
- int exitvalue = 0;
- try {
- if (mProcess!=null)
- exitvalue = mProcess.waitFor();
- } catch ( IllegalThreadStateException ite) {
- VpnStatus.logError("Illegal Thread state: " + ite.getLocalizedMessage());
- } catch (InterruptedException ie) {
- VpnStatus.logError("InterruptedException: " + ie.getLocalizedMessage());
- }
- if( exitvalue != 0)
- VpnStatus.logError("Process exited with exit value " + exitvalue);
-
- 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 : VpnStatus.getlogbuffer()){
- String time = timeformat.format(new Date(li.getLogtime()));
- logout.write(time +" " + li.getString(mService) + "\n");
- }
- logout.close();
- VpnStatus.logError(R.string.minidump_generated);
- } catch (IOException e) {
- VpnStatus.logError("Writing minidump log: " + e.getLocalizedMessage());
- }
- }
-
- mService.processDied();
- Log.i(TAG, "Exiting");
- }
- }
-
- private void startOpenVPNThreadArgs(String[] argv, Map<String, String> env) {
- LinkedList<String> argvlist = new LinkedList<String>();
-
- Collections.addAll(argvlist, argv);
-
- ProcessBuilder pb = new ProcessBuilder(argvlist);
- // Hack O rama
-
- String lbpath = genLibraryPath(argv, pb);
-
- pb.environment().put("LD_LIBRARY_PATH", lbpath);
-
- // Add extra variables
- for(Entry<String,String> e:env.entrySet()){
- pb.environment().put(e.getKey(), e.getValue());
- }
- pb.redirectErrorStream(true);
- try {
- mProcess = pb.start();
- // Close the output, since we don't need it
- mProcess.getOutputStream().close();
- InputStream in = mProcess.getInputStream();
- BufferedReader br = new BufferedReader(new InputStreamReader(in));
-
- while(true) {
- String logline = br.readLine();
- if(logline==null)
- return;
-
- if (logline.startsWith(DUMP_PATH_STRING))
- mDumpPath = logline.substring(DUMP_PATH_STRING.length());
-
-
- // 1380308330.240114 18000002 Send to HTTP proxy: 'X-Online-Host: bla.blabla.com'
-
- Pattern p = Pattern.compile("(\\d+).(\\d+) ([0-9a-f])+ (.*)");
- Matcher m = p.matcher(logline);
- if(m.matches()) {
- int flags = Integer.parseInt(m.group(3),16);
- String msg = m.group(4);
- int logLevel = flags & 0x0F;
-
- VpnStatus.LogLevel logStatus = VpnStatus.LogLevel.INFO;
-
- if ((flags & M_FATAL) != 0)
- logStatus = VpnStatus.LogLevel.ERROR;
- else if ((flags & M_NONFATAL)!=0)
- logStatus = VpnStatus.LogLevel.WARNING;
- else if ((flags & M_WARN)!=0)
- logStatus = VpnStatus.LogLevel.WARNING;
- else if ((flags & M_DEBUG)!=0)
- logStatus = VpnStatus.LogLevel.VERBOSE;
-
- if (msg.startsWith("MANAGEMENT: CMD"))
- logLevel = Math.max(4, logLevel);
-
-
- VpnStatus.logMessageOpenVPN(logStatus,logLevel,msg);
- } else {
- VpnStatus.logInfo("P:" + logline);
- }
- }
-
-
- } catch (IOException e) {
- VpnStatus.logException("Error reading from output of OpenVPN process" , e);
- stopProcess();
- }
-
-
- }
-
- private String genLibraryPath(String[] argv, ProcessBuilder pb) {
- // Hack until I find a good way to get the real library path
- String applibpath = argv[0].replace("/cache/" + VpnProfile.MINIVPN , "/lib");
-
- String lbpath = pb.environment().get("LD_LIBRARY_PATH");
- if(lbpath==null)
- lbpath = applibpath;
- else
- lbpath = lbpath + ":" + applibpath;
-
- if (!applibpath.equals(mNativeDir)) {
- lbpath = lbpath + ":" + mNativeDir;
- }
- return lbpath;
- }
-}
diff --git a/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java
deleted file mode 100644
index 5fa70cc8..00000000
--- a/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java
+++ /dev/null
@@ -1,580 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.net.LocalServerSocket;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.os.ParcelFileDescriptor;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-import org.jetbrains.annotations.NotNull;
-
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.Locale;
-import java.util.Vector;
-
-public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
-
- private static final String TAG = "openvpn";
- private LocalSocket mSocket;
- private VpnProfile mProfile;
- private OpenVpnService mOpenVPNService;
- private LinkedList<FileDescriptor> mFDList=new LinkedList<FileDescriptor>();
- private LocalServerSocket mServerSocket;
- private boolean mReleaseHold=true;
- private boolean mWaitingForRelease=false;
- private long mLastHoldRelease=0;
-
- private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
- private LocalSocket mServerSocketLocal;
-
- private pauseReason lastPauseReason = pauseReason.noNetwork;
-
- public OpenVpnManagementThread(VpnProfile profile, OpenVpnService openVpnService) {
- mProfile = profile;
- mOpenVPNService = openVpnService;
-
-
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(openVpnService);
- boolean managemeNetworkState = prefs.getBoolean("netchangereconnect", true);
- if(managemeNetworkState)
- mReleaseHold=false;
-
- }
-
- public boolean openManagementInterface(@NotNull Context c) {
- // Could take a while to open connection
- int tries=8;
-
- String socketName = (c.getCacheDir().getAbsolutePath() + "/" + "mgmtsocket");
- // The mServerSocketLocal is transferred to the LocalServerSocket, ignore warning
-
- mServerSocketLocal = new LocalSocket();
-
- while(tries > 0 && !mServerSocketLocal.isConnected()) {
- try {
- mServerSocketLocal.bind(new LocalSocketAddress(socketName,
- LocalSocketAddress.Namespace.FILESYSTEM));
- } catch (IOException e) {
- // wait 300 ms before retrying
- try { Thread.sleep(300);
- } catch (InterruptedException e1) {
- }
-
- }
- tries--;
- }
-
- try {
-
- mServerSocket = new LocalServerSocket(mServerSocketLocal.getFileDescriptor());
- return true;
- } catch (IOException e) {
- VpnStatus.logException(e);
- }
- return false;
-
-
- }
-
- public void managmentCommand(String cmd) {
- try {
- if(mSocket!=null && mSocket.getOutputStream() !=null) {
- mSocket.getOutputStream().write(cmd.getBytes());
- mSocket.getOutputStream().flush();
- }
- }catch (IOException e) {
- // Ignore socket stack traces
- }
- }
-
-
- @Override
- public void run() {
- byte [] buffer =new byte[2048];
- // mSocket.setSoTimeout(5); // Setting a timeout cannot be that bad
-
- String pendingInput="";
- active.add(this);
-
- try {
- // Wait for a client to connect
- mSocket= mServerSocket.accept();
- InputStream instream = mSocket.getInputStream();
- // Close the management socket after client connected
-
- mServerSocket.close();
- // Closing one of the two sockets also closes the other
- //mServerSocketLocal.close();
-
- while(true) {
- int numbytesread = instream.read(buffer);
- if(numbytesread==-1)
- return;
-
- FileDescriptor[] fds = null;
- try {
- fds = mSocket.getAncillaryFileDescriptors();
- } catch (IOException e) {
- VpnStatus.logException("Error reading fds from socket", e);
- }
- if(fds!=null){
- Collections.addAll(mFDList, fds);
- }
-
- String input = new String(buffer,0,numbytesread,"UTF-8");
-
- pendingInput += input;
-
- pendingInput=processInput(pendingInput);
-
-
-
- }
- } catch (IOException e) {
- if (!e.getMessage().equals("socket closed"))
- VpnStatus.logException(e);
- }
- active.remove(this);
- }
-
- //! Hack O Rama 2000!
- private void protectFileDescriptor(FileDescriptor fd) {
- Exception exp;
- try {
- Method getInt = FileDescriptor.class.getDeclaredMethod("getInt$");
- int fdint = (Integer) getInt.invoke(fd);
-
- // You can even get more evil by parsing toString() and extract the int from that :)
-
- mOpenVPNService.protect(fdint);
-
- //ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(fdint);
- //pfd.close();
- NativeUtils.jniclose(fdint);
- return;
- } catch (NoSuchMethodException e) {
- exp =e;
- } catch (IllegalArgumentException e) {
- exp =e;
- } catch (IllegalAccessException e) {
- exp =e;
- } catch (InvocationTargetException e) {
- exp =e;
- } catch (NullPointerException e) {
- exp =e;
- }
-
- Log.d("Openvpn", "Failed to retrieve fd from socket: " + fd);
- VpnStatus.logException("Failed to retrieve fd from socket (" + fd + ")" , exp);
- }
-
- private String processInput(String pendingInput) {
-
-
- while(pendingInput.contains("\n")) {
- String[] tokens = pendingInput.split("\\r?\\n", 2);
- processCommand(tokens[0]);
- if(tokens.length == 1)
- // No second part, newline was at the end
- pendingInput="";
- else
- pendingInput=tokens[1];
- }
- return pendingInput;
- }
-
-
- private void processCommand(String command) {
- //Log.i(TAG, "Line from managment" + command);
-
-
- if (command.startsWith(">") && command.contains(":")) {
- String[] parts = command.split(":",2);
- String cmd = parts[0].substring(1);
- String argument = parts[1];
-
-
- if(cmd.equals("INFO")) {
- /* Ignore greeting from management */
- return;
- }else if (cmd.equals("PASSWORD")) {
- processPWCommand(argument);
- } else if (cmd.equals("HOLD")) {
- handleHold();
- } else if (cmd.equals("NEED-OK")) {
- processNeedCommand(argument);
- } else if (cmd.equals("BYTECOUNT")){
- processByteCount(argument);
- } else if (cmd.equals("STATE")) {
- processState(argument);
- } else if (cmd.equals("PROXY")) {
- processProxyCMD(argument);
- } else if (cmd.equals("LOG")) {
- processLogMessage(argument);
- } else if (cmd.equals("RSA_SIGN")) {
- processSignCommand(argument);
- } else {
- VpnStatus.logWarning("MGMT: Got unrecognized command" + command);
- Log.i(TAG, "Got unrecognized command" + command);
- }
- } else if (command.startsWith("SUCCESS:")) {
- /* Ignore this kind of message too */
- return;
- } else {
- Log.i(TAG, "Got unrecognized line from managment" + command);
- VpnStatus.logWarning("MGMT: Got unrecognized line from management:" + command);
- }
- }
-
- private void processLogMessage(String argument) {
- String[] args = argument.split(",",4);
- // 0 unix time stamp
- // 1 log level N,I,E etc.
- /*
- (b) zero or more message flags in a single string:
- I -- informational
- F -- fatal error
- N -- non-fatal error
- W -- warning
- D -- debug, and
- */
- // 2 log message
-
- Log.d("OpenVPN", argument);
-
- VpnStatus.LogLevel level;
- if (args[1].equals("I")) {
- level = VpnStatus.LogLevel.INFO;
- } else if (args[1].equals("W")) {
- level = VpnStatus.LogLevel.WARNING;
- } else if (args[1].equals("D")) {
- level = VpnStatus.LogLevel.VERBOSE;
- } else if (args[1].equals("F")) {
- level = VpnStatus.LogLevel.ERROR;
- } else {
- level = VpnStatus.LogLevel.INFO;
- }
-
- int ovpnlevel = Integer.parseInt(args[2]) & 0x0F;
- String msg = args[3];
-
- if (msg.startsWith("MANAGEMENT: CMD"))
- ovpnlevel = Math.max(4, ovpnlevel);
-
- VpnStatus.logMessageOpenVPN(level,ovpnlevel, msg);
- }
-
- private void handleHold() {
- if(mReleaseHold) {
- releaseHoldCmd();
- } else {
- mWaitingForRelease=true;
-
- VpnStatus.updateStatePause(lastPauseReason);
-
-
- }
- }
- private void releaseHoldCmd() {
- if ((System.currentTimeMillis()- mLastHoldRelease) < 5000) {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- }
-
- }
- mWaitingForRelease=false;
- mLastHoldRelease = System.currentTimeMillis();
- managmentCommand("hold release\n");
- managmentCommand("bytecount " + mBytecountInterval + "\n");
- managmentCommand("state on\n");
- //managmentCommand("log on all\n");
- }
-
- public void releaseHold() {
- mReleaseHold=true;
- if(mWaitingForRelease)
- releaseHoldCmd();
-
- }
-
- private void processProxyCMD(String argument) {
- String[] args = argument.split(",",3);
- SocketAddress proxyaddr = ProxyDetection.detectProxy(mProfile);
-
-
- if(args.length >= 2) {
- String proto = args[1];
- if(proto.equals("UDP")) {
- proxyaddr=null;
- }
- }
-
- if(proxyaddr instanceof InetSocketAddress ){
- InetSocketAddress isa = (InetSocketAddress) proxyaddr;
-
- 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);
- } else {
- managmentCommand("proxy NONE\n");
- }
-
- }
- private void processState(String argument) {
- String[] args = argument.split(",",3);
- String currentstate = args[1];
-
- if(args[2].equals(",,"))
- VpnStatus.updateStateString(currentstate, "");
- else
- VpnStatus.updateStateString(currentstate, args[2]);
- }
-
-
- private void processByteCount(String argument) {
- // >BYTECOUNT:{BYTES_IN},{BYTES_OUT}
- int comma = argument.indexOf(',');
- long in = Long.parseLong(argument.substring(0, comma));
- long out = Long.parseLong(argument.substring(comma+1));
-
- VpnStatus.updateByteCount(in, out);
-
- }
-
-
-
- private void processNeedCommand(String argument) {
- int p1 =argument.indexOf('\'');
- int p2 = argument.indexOf('\'',p1+1);
-
- String needed = argument.substring(p1+1, p2);
- String extra = argument.split(":",2)[1];
-
- String status = "ok";
-
-
- if (needed.equals("PROTECTFD")) {
- FileDescriptor fdtoprotect = mFDList.pollFirst();
- protectFileDescriptor(fdtoprotect);
- } else if (needed.equals("DNSSERVER")) {
- mOpenVPNService.addDNS(extra);
- }else if (needed.equals("DNSDOMAIN")){
- mOpenVPNService.setDomain(extra);
- } else if (needed.equals("ROUTE")) {
- String[] routeparts = extra.split(" ");
-
- if(routeparts.length>3) {
- assert(routeparts[3].equals("dev"));
- mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], routeparts[4]);
- } else {
- mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], null);
- }
-
- } else if (needed.equals("ROUTE6")) {
- String[] routeparts = extra.split(" ");
- mOpenVPNService.addRoutev6(routeparts[0],routeparts[1]);
- } else if (needed.equals("IFCONFIG")) {
- String[] ifconfigparts = extra.split(" ");
- int mtu = Integer.parseInt(ifconfigparts[2]);
- mOpenVPNService.setLocalIP(ifconfigparts[0], ifconfigparts[1],mtu,ifconfigparts[3]);
- } else if (needed.equals("IFCONFIG6")) {
- mOpenVPNService.setLocalIPv6(extra);
-
- } else if (needed.equals("PERSIST_TUN_ACTION")) {
- // check if tun cfg stayed the same
- status = mOpenVPNService.getTunReopenStatus();
- } else if (needed.equals("OPENTUN")) {
- if(sendTunFD(needed,extra))
- return;
- else
- status="cancel";
- // This not nice or anything but setFileDescriptors accepts only FilDescriptor class :(
-
- } else {
- Log.e(TAG,"Unkown needok command " + argument);
- return;
- }
-
- String cmd = String.format("needok '%s' %s\n", needed, status);
- managmentCommand(cmd);
- }
-
- private boolean sendTunFD (String needed, String extra) {
- Exception exp;
- if(!extra.equals("tun")) {
- // We only support tun
- VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!",extra));
-
- return false;
- }
- ParcelFileDescriptor pfd = mOpenVPNService.openTun();
- if(pfd==null)
- return false;
-
- Method setInt;
- int fdint = pfd.getFd();
- try {
- setInt = FileDescriptor.class.getDeclaredMethod("setInt$",int.class);
- FileDescriptor fdtosend = new FileDescriptor();
-
- setInt.invoke(fdtosend,fdint);
-
- FileDescriptor[] fds = {fdtosend};
- mSocket.setFileDescriptorsForSend(fds);
-
- // Trigger a send so we can close the fd on our side of the channel
- // The API documentation fails to mention that it will not reset the file descriptor to
- // be send and will happily send the file descriptor on every write ...
- String cmd = String.format("needok '%s' %s\n", needed, "ok");
- managmentCommand(cmd);
-
- // Set the FileDescriptor to null to stop this mad behavior
- mSocket.setFileDescriptorsForSend(null);
-
- pfd.close();
-
- return true;
- } catch (NoSuchMethodException e) {
- exp =e;
- } catch (IllegalArgumentException e) {
- exp =e;
- } catch (IllegalAccessException e) {
- exp =e;
- } catch (InvocationTargetException e) {
- exp =e;
- } catch (IOException e) {
- exp =e;
- }
- VpnStatus.logException("Could not send fd over socket" , exp);
-
- return false;
- }
-
- private void processPWCommand(String argument) {
- //argument has the form Need 'Private Key' password
- // or ">PASSWORD:Verification Failed: '%s' ['%s']"
- String needed;
-
-
-
- try{
-
- int p1 = argument.indexOf('\'');
- int p2 = argument.indexOf('\'',p1+1);
- needed = argument.substring(p1+1, p2);
- if (argument.startsWith("Verification Failed")) {
- proccessPWFailed(needed, argument.substring(p2+1));
- return;
- }
- } catch (StringIndexOutOfBoundsException sioob) {
- VpnStatus.logError("Could not parse management Password command: " + argument);
- return;
- }
-
- String pw=null;
-
- if(needed.equals("Private Key")) {
- pw = mProfile.getPasswordPrivateKey();
- } else if (needed.equals("Auth")) {
- String usercmd = String.format("username '%s' %s\n",
- needed, VpnProfile.openVpnEscape(mProfile.mUsername));
- managmentCommand(usercmd);
- pw = mProfile.getPasswordAuth();
- }
- if(pw!=null) {
- String cmd = String.format("password '%s' %s\n", needed, VpnProfile.openVpnEscape(pw));
- managmentCommand(cmd);
- } else {
- VpnStatus.logError(String.format("Openvpn requires Authentication type '%s' but no password/key information available", needed));
- }
-
- }
-
-
-
-
- private void proccessPWFailed(String needed, String args) {
- VpnStatus.updateStateString("AUTH_FAILED", needed + args, R.string.state_auth_failed, ConnectionStatus.LEVEL_AUTH_FAILED);
- }
-
-
- private static boolean stopOpenVPN() {
- boolean sendCMD=false;
- for (OpenVpnManagementThread mt: active){
- mt.managmentCommand("signal SIGINT\n");
- sendCMD=true;
- try {
- if(mt.mSocket !=null)
- mt.mSocket.close();
- } catch (IOException e) {
- // Ignore close error on already closed socket
- }
- }
- return sendCMD;
- }
-
- public void signalusr1() {
- mReleaseHold=false;
-
- if(!mWaitingForRelease)
- managmentCommand("signal SIGUSR1\n");
- else
- // If signalusr1 is called update the state string
- // if there is another for stopping
- VpnStatus.updateStatePause(lastPauseReason);
- }
-
- public void reconnect() {
- signalusr1();
- releaseHold();
- }
-
- private void processSignCommand(String b64data) {
-
- String signed_string = mProfile.getSignedData(b64data);
- if(signed_string==null) {
- managmentCommand("rsa-sig\n");
- managmentCommand("\nEND\n");
- stopOpenVPN();
- return;
- }
- managmentCommand("rsa-sig\n");
- managmentCommand(signed_string);
- managmentCommand("\nEND\n");
- }
-
- @Override
- public void pause (pauseReason reason) {
- lastPauseReason = reason;
- signalusr1();
- }
-
- @Override
- public void resume() {
- releaseHold();
- /* Reset the reason why we are disconnected */
- lastPauseReason = pauseReason.noNetwork;
- }
-
- @Override
- public boolean stopVPN() {
- return stopOpenVPN();
- }
-}
diff --git a/src/de/blinkt/openvpn/core/OpenVpnService.java b/src/de/blinkt/openvpn/core/OpenVpnService.java
deleted file mode 100644
index 49f315a3..00000000
--- a/src/de/blinkt/openvpn/core/OpenVpnService.java
+++ /dev/null
@@ -1,704 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import android.Manifest.permission;
-import android.annotation.TargetApi;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.net.ConnectivityManager;
-import android.net.VpnService;
-import android.os.*;
-import android.os.Handler.Callback;
-import android.preference.PreferenceManager;
-import android.text.TextUtils;
-import de.blinkt.openvpn.activities.DisconnectVPN;
-import de.blinkt.openvpn.activities.LogWindow;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-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;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Vector;
-
-import static de.blinkt.openvpn.core.NetworkSpace.*;
-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";
- public static final String START_SERVICE_STICKY = "de.blinkt.openvpn.START_SERVICE_STICKY";
- public static final String ALWAYS_SHOW_NOTIFICATION = "de.blinkt.openvpn.NOTIFICATION_ALWAYS_VISIBLE";
- public static final String DISCONNECT_VPN = "de.blinkt.openvpn.DISCONNECT_VPN";
- private static final String PAUSE_VPN = "de.blinkt.openvpn.PAUSE_VPN";
- private static final String RESUME_VPN = "de.blinkt.openvpn.RESUME_VPN";
- private static final int OPENVPN_STATUS = 1;
- private static boolean mNotificationAlwaysVisible = false;
- private final Vector<String> mDnslist = new Vector<String>();
- private final NetworkSpace mRoutes = new NetworkSpace();
- private final NetworkSpace mRoutesv6 = new NetworkSpace();
- private final IBinder mBinder = new LocalBinder();
- private Thread mProcessThread = null;
- private VpnProfile mProfile;
- private String mDomain = null;
- private CIDRIP mLocalIP = null;
- private int mMtu;
- private String mLocalIPv6 = null;
- private DeviceStateReceiver mDeviceStateReceiver;
- private boolean mDisplayBytecount = false;
- private boolean mStarting = false;
- private long mConnecttime;
- private boolean mOvpn3 = false;
- private OpenVPNManagement mManagement;
- private String mLastTunCfg;
- private String mRemoteGW;
-
- // 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) {
- if (mbit)
- bytes = bytes * 8;
- int unit = mbit ? 1000 : 1024;
- if (bytes < unit)
- return bytes + (mbit ? " bit" : " B");
-
- int exp = (int) (Math.log(bytes) / Math.log(unit));
- String pre = (mbit ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (mbit ? "" : "");
- if (mbit)
- return String.format(Locale.getDefault(), "%.1f %sbit", bytes / Math.pow(unit, exp), pre);
- else
- return String.format(Locale.getDefault(), "%.1f %sB", bytes / Math.pow(unit, exp), pre);
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- String action = intent.getAction();
- if (action != null && action.equals(START_SERVICE))
- return mBinder;
- else
- return super.onBind(intent);
- }
-
- @Override
- public void onRevoke() {
- mManagement.stopVPN();
- endVpnService();
- }
-
- // Similar to revoke but do not try to stop process
- public void processDied() {
- endVpnService();
- }
-
- private void endVpnService() {
- mProcessThread = null;
- VpnStatus.removeByteCountListener(this);
- unregisterDeviceStateReceiver();
- ProfileManager.setConntectedVpnProfileDisconnected(this);
- if (!mStarting) {
- stopForeground(!mNotificationAlwaysVisible);
-
- if (!mNotificationAlwaysVisible) {
- stopSelf();
- VpnStatus.removeStateListener(this);
- }
- }
- }
-
- private void showNotification(String msg, String tickerText, boolean lowpriority, long when, ConnectionStatus status) {
- String ns = Context.NOTIFICATION_SERVICE;
- NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
-
-
- int icon = getIconByConnectionStatus(status);
-
- android.app.Notification.Builder nbuilder = new Notification.Builder(this);
-
- if (mProfile != null)
- nbuilder.setContentTitle(getString(R.string.notifcation_title, mProfile.mName));
- else
- nbuilder.setContentTitle(getString(R.string.notifcation_title_notconnect));
-
- nbuilder.setContentText(msg);
- nbuilder.setOnlyAlertOnce(true);
- nbuilder.setOngoing(true);
- nbuilder.setContentIntent(getLogPendingIntent());
- nbuilder.setSmallIcon(icon);
-
-
- if (when != 0)
- nbuilder.setWhen(when);
-
-
- // Try to set the priority available since API 16 (Jellybean)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
- jbNotificationExtras(lowpriority, nbuilder);
-
- if (tickerText != null && !tickerText.equals(""))
- nbuilder.setTicker(tickerText);
-
- @SuppressWarnings("deprecation")
- Notification notification = nbuilder.getNotification();
-
-
- mNotificationManager.notify(OPENVPN_STATUS, notification);
- startForeground(OPENVPN_STATUS, notification);
- }
-
- private int getIconByConnectionStatus(ConnectionStatus level) {
- switch (level) {
- case LEVEL_CONNECTED:
- return R.drawable.ic_stat_vpn;
- case LEVEL_AUTH_FAILED:
- case LEVEL_NONETWORK:
- case LEVEL_NOTCONNECTED:
- return R.drawable.ic_stat_vpn_offline;
- case LEVEL_CONNECTING_NO_SERVER_REPLY_YET:
- case LEVEL_WAITING_FOR_USER_INPUT:
- return R.drawable.ic_stat_vpn_outline;
- case LEVEL_CONNECTING_SERVER_REPLIED:
- return R.drawable.ic_stat_vpn_empty_halo;
- case LEVEL_VPNPAUSED:
- return android.R.drawable.ic_media_pause;
- case UNKNOWN_LEVEL:
- default:
- return R.drawable.ic_stat_vpn;
-
- }
- }
-
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private void jbNotificationExtras(boolean lowpriority,
- android.app.Notification.Builder nbuilder) {
- try {
- if (lowpriority) {
- Method setpriority = nbuilder.getClass().getMethod("setPriority", int.class);
- // PRIORITY_MIN == -2
- setpriority.invoke(nbuilder, -2);
-
- Method setUsesChronometer = nbuilder.getClass().getMethod("setUsesChronometer", boolean.class);
- setUsesChronometer.invoke(nbuilder, true);
-
- }
-
- Intent disconnectVPN = new Intent(this, DisconnectVPN.class);
- disconnectVPN.setAction(DISCONNECT_VPN);
- PendingIntent disconnectPendingIntent = PendingIntent.getActivity(this, 0, disconnectVPN, 0);
-
- nbuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel,
- getString(R.string.cancel_connection), disconnectPendingIntent);
-
- Intent pauseVPN = new Intent(this, OpenVpnService.class);
- if (mDeviceStateReceiver == null || !mDeviceStateReceiver.isUserPaused()) {
- pauseVPN.setAction(PAUSE_VPN);
- PendingIntent pauseVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0);
- nbuilder.addAction(android.R.drawable.ic_media_pause,
- getString(R.string.pauseVPN), pauseVPNPending);
-
- } else {
- pauseVPN.setAction(RESUME_VPN);
- PendingIntent resumeVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0);
- nbuilder.addAction(android.R.drawable.ic_media_play,
- getString(R.string.resumevpn), resumeVPNPending);
- }
-
-
- //ignore exception
- } catch (NoSuchMethodException nsm) {
- VpnStatus.logException(nsm);
- } catch (IllegalArgumentException e) {
- VpnStatus.logException(e);
- } catch (IllegalAccessException e) {
- VpnStatus.logException(e);
- } catch (InvocationTargetException e) {
- VpnStatus.logException(e);
- }
-
- }
-
- PendingIntent getLogPendingIntent() {
- // Let the configure Button show the Log
- Intent intent = new Intent(getBaseContext(), LogWindow.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
- PendingIntent startLW = PendingIntent.getActivity(this, 0, intent, 0);
- intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
- return startLW;
-
- }
-
- synchronized void registerDeviceStateReceiver(OpenVPNManagement magnagement) {
- // Registers BroadcastReceiver to track network connection changes.
- IntentFilter filter = new IntentFilter();
- filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- filter.addAction(Intent.ACTION_SCREEN_ON);
- mDeviceStateReceiver = new DeviceStateReceiver(magnagement);
- registerReceiver(mDeviceStateReceiver, filter);
- VpnStatus.addByteCountListener(mDeviceStateReceiver);
- }
-
- synchronized void unregisterDeviceStateReceiver() {
- if (mDeviceStateReceiver != null)
- try {
- VpnStatus.removeByteCountListener(mDeviceStateReceiver);
- this.unregisterReceiver(mDeviceStateReceiver);
- } catch (IllegalArgumentException iae) {
- // I don't know why this happens:
- // java.lang.IllegalArgumentException: Receiver not registered: de.blinkt.openvpn.NetworkSateReceiver@41a61a10
- // Ignore for now ...
- iae.printStackTrace();
- }
- mDeviceStateReceiver = null;
- }
-
- public void userPause(boolean shouldBePaused) {
- if (mDeviceStateReceiver != null)
- mDeviceStateReceiver.userPause(shouldBePaused);
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
-
- if (intent != null && intent.getBooleanExtra(ALWAYS_SHOW_NOTIFICATION, false))
- mNotificationAlwaysVisible = true;
-
- VpnStatus.addStateListener(this);
- VpnStatus.addByteCountListener(this);
-
- if (intent != null && PAUSE_VPN.equals(intent.getAction())) {
- if (mDeviceStateReceiver != null)
- mDeviceStateReceiver.userPause(true);
- return START_NOT_STICKY;
- }
-
- if (intent != null && RESUME_VPN.equals(intent.getAction())) {
- if (mDeviceStateReceiver != null)
- mDeviceStateReceiver.userPause(false);
- return START_NOT_STICKY;
- }
-
-
- if (intent != null && START_SERVICE.equals(intent.getAction()))
- return START_NOT_STICKY;
- if (intent != null && START_SERVICE_STICKY.equals(intent.getAction())) {
- return START_REDELIVER_INTENT;
- }
-
- assert (intent != null);
-
- // Extract information from the intent.
- String prefix = getPackageName();
- String[] argv = intent.getStringArrayExtra(prefix + ".ARGV");
- String nativelibdir = intent.getStringExtra(prefix + ".nativelib");
- String profileUUID = intent.getStringExtra(prefix + ".profileUUID");
-
- mProfile = ProfileManager.get(this, profileUUID);
-
- String startTitle = getString(R.string.start_vpn_title, mProfile.mName);
- String startTicker = getString(R.string.start_vpn_ticker, mProfile.mName);
- showNotification(startTitle, startTicker,
- false, 0, LEVEL_CONNECTING_NO_SERVER_REPLY_YET);
-
- // Set a flag that we are starting a new VPN
- mStarting = true;
- // Stop the previous session by interrupting the thread.
- if (mManagement != null && mManagement.stopVPN())
- // an old was asked to exit, wait 1s
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
-
-
- if (mProcessThread != null) {
- mProcessThread.interrupt();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
- }
- // An old running VPN should now be exited
- mStarting = false;
-
- // Start a new session by creating a new thread.
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
-
- mOvpn3 = prefs.getBoolean("ovpn3", false);
- mOvpn3 = false;
-
-
- // Open the Management Interface
- if (!mOvpn3) {
-
- // start a Thread that handles incoming messages of the managment socket
- OpenVpnManagementThread ovpnManagementThread = new OpenVpnManagementThread(mProfile, this);
- if (ovpnManagementThread.openManagementInterface(this)) {
-
- Thread mSocketManagerThread = new Thread(ovpnManagementThread, "OpenVPNManagementThread");
- mSocketManagerThread.start();
- mManagement = ovpnManagementThread;
- VpnStatus.logInfo("started Socket Thread");
- } else {
- return START_NOT_STICKY;
- }
- }
-
-
- Runnable processThread;
- if (mOvpn3) {
-
- OpenVPNManagement mOpenVPN3 = instantiateOpenVPN3Core();
- processThread = (Runnable) mOpenVPN3;
- mManagement = mOpenVPN3;
-
-
- } else {
- HashMap<String, String> env = new HashMap<String, String>();
- processThread = new OpenVPNThread(this, argv, env, nativelibdir);
- }
-
- mProcessThread = new Thread(processThread, "OpenVPNProcessThread");
- mProcessThread.start();
-
- if (mDeviceStateReceiver != null)
- unregisterDeviceStateReceiver();
-
- registerDeviceStateReceiver(mManagement);
-
-
- ProfileManager.setConnectedVpnProfile(this, mProfile);
-
- return START_NOT_STICKY;
- }
-
- private OpenVPNManagement instantiateOpenVPN3Core() {
- return null;
- }
-
- @Override
- public void onDestroy() {
- if (mProcessThread != null) {
- mManagement.stopVPN();
-
- mProcessThread.interrupt();
- }
- if (mDeviceStateReceiver != null) {
- this.unregisterReceiver(mDeviceStateReceiver);
- }
- // Just in case unregister for state
- VpnStatus.removeStateListener(this);
-
- }
-
- private String getTunConfigString() {
- // The format of the string is not important, only that
- // two identical configurations produce the same result
- String cfg = "TUNCFG UNQIUE STRING ips:";
-
- if (mLocalIP != null)
- cfg += mLocalIP.toString();
- if (mLocalIPv6 != null)
- cfg += mLocalIPv6.toString();
-
- cfg += "routes: " + TextUtils.join("|", mRoutes.getNetworks(true)) + TextUtils.join("|", mRoutesv6.getNetworks(true));
- cfg += "excl. routes:" + TextUtils.join("|", mRoutes.getNetworks(false)) + TextUtils.join("|", mRoutesv6.getNetworks(false));
- cfg += "dns: " + TextUtils.join("|", mDnslist);
- cfg += "domain: " + mDomain;
- cfg += "mtu: " + mMtu;
- return cfg;
- }
-
- public ParcelFileDescriptor openTun() {
- Builder builder = new Builder();
-
- if (mLocalIP == null && mLocalIPv6 == null) {
- VpnStatus.logError(getString(R.string.opentun_no_ipaddr));
- return null;
- }
-
- if (mLocalIP != null) {
- try {
- builder.addAddress(mLocalIP.mIp, mLocalIP.len);
- } catch (IllegalArgumentException iae) {
- VpnStatus.logError(R.string.dns_add_error, mLocalIP, iae.getLocalizedMessage());
- return null;
- }
- }
-
- if (mLocalIPv6 != null) {
- String[] ipv6parts = mLocalIPv6.split("/");
- try {
- builder.addAddress(ipv6parts[0], Integer.parseInt(ipv6parts[1]));
- } catch (IllegalArgumentException iae) {
- VpnStatus.logError(R.string.ip_add_error, mLocalIPv6, iae.getLocalizedMessage());
- return null;
- }
-
- }
-
-
- for (String dns : mDnslist) {
- try {
- builder.addDnsServer(dns);
- } catch (IllegalArgumentException iae) {
- VpnStatus.logError(R.string.dns_add_error, dns, iae.getLocalizedMessage());
- }
- }
-
-
- builder.setMtu(mMtu);
-
-
- for (NetworkSpace.ipAddress route : mRoutes.getPositiveIPList()) {
- try {
- builder.addRoute(route.getIPv4Address(), route.networkMask);
- } catch (IllegalArgumentException ia) {
- VpnStatus.logError(getString(R.string.route_rejected) + route + " " + ia.getLocalizedMessage());
- }
- }
-
- for (NetworkSpace.ipAddress route6 : mRoutesv6.getPositiveIPList()) {
- try {
- builder.addRoute(route6.getIPv6Address(), route6.networkMask);
- } catch (IllegalArgumentException ia) {
- VpnStatus.logError(getString(R.string.route_rejected) + route6 + " " + ia.getLocalizedMessage());
- }
- }
-
- if (mDomain != null)
- builder.addSearchDomain(mDomain);
-
- 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, TextUtils.join(", ", mDnslist), mDomain);
- VpnStatus.logInfo(R.string.routes_info_incl, TextUtils.join(", ", mRoutes.getNetworks(true)), TextUtils.join(", ", mRoutesv6.getNetworks(true)));
- VpnStatus.logInfo(R.string.routes_info_excl, TextUtils.join(", ", mRoutes.getNetworks(false)),TextUtils.join(", ", mRoutesv6.getNetworks(false)));
- VpnStatus.logDebug(R.string.routes_debug, TextUtils.join(", ", mRoutes.getPositiveIPList()), TextUtils.join(", ", mRoutesv6.getPositiveIPList()));
-
- String session = mProfile.mName;
- if (mLocalIP != null && mLocalIPv6 != null)
- session = getString(R.string.session_ipv6string, session, mLocalIP, mLocalIPv6);
- else if (mLocalIP != null)
- session = getString(R.string.session_ipv4string, session, mLocalIP);
-
- builder.setSession(session);
-
- // No DNS Server, log a warning
- if (mDnslist.size() == 0)
- VpnStatus.logInfo(R.string.warn_no_dns);
-
- mLastTunCfg = getTunConfigString();
-
- // Reset information
- mDnslist.clear();
- mRoutes.clear();
- mRoutesv6.clear();
- mLocalIP = null;
- mLocalIPv6 = null;
- mDomain = null;
-
- builder.setConfigureIntent(getLogPendingIntent());
-
- try {
- return builder.establish();
- } catch (Exception e) {
- VpnStatus.logError(R.string.tun_open_error);
- VpnStatus.logError(getString(R.string.error) + e.getLocalizedMessage());
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- VpnStatus.logError(R.string.tun_error_helpful);
- }
- return null;
- }
-
- }
-
- public void addDNS(String dns) {
- mDnslist.add(dns);
- }
-
- public void setDomain(String domain) {
- if (mDomain == null) {
- mDomain = domain;
- }
- }
-
- public void addRoute (String dest, String mask, String gateway, String device) {
- CIDRIP route = new CIDRIP(dest, mask);
- boolean include = isAndroidTunDevice(device);
-
- NetworkSpace.ipAddress gatewayIP = new NetworkSpace.ipAddress(new CIDRIP(gateway, 32),false);
-
- NetworkSpace.ipAddress localNet = new NetworkSpace.ipAddress(mLocalIP,true);
- if (localNet.containsNet(gatewayIP))
- include=true;
-
- if (gateway!= null &&
- (gateway.equals("255.255.255.255") || gateway.equals(mRemoteGW)))
- include=true;
-
-
- if (route.len == 32 && !mask.equals("255.255.255.255")) {
- VpnStatus.logWarning(R.string.route_not_cidr, dest, mask);
- }
-
- if (route.normalise())
- VpnStatus.logWarning(R.string.route_not_netip, dest, route.len, route.mIp);
-
- mRoutes.addIP(route, include);
- }
-
- public void addRoutev6(String network, String device) {
- String[] v6parts = network.split("/");
- boolean included = isAndroidTunDevice(device);
-
- // Tun is opened after ROUTE6, no device name may be present
-
- try {
- Inet6Address ip = (Inet6Address) InetAddress.getAllByName(v6parts[0])[0];
- int mask = Integer.parseInt(v6parts[1]);
- mRoutesv6.addIPv6(ip, mask, included);
-
- } catch (UnknownHostException e) {
- VpnStatus.logException(e);
- }
-
-
- }
-
- private boolean isAndroidTunDevice(String device) {
- return device!=null &&
- (device.startsWith("tun") || "(null)".equals(device) || "vpnservice-tun".equals(device));
- }
-
- public void setMtu(int mtu) {
- mMtu = mtu;
- }
-
- public void setLocalIP(CIDRIP cdrip) {
- mLocalIP = cdrip;
- }
-
- public void setLocalIP(String local, String netmask, int mtu, String mode) {
- mLocalIP = new CIDRIP(local, netmask);
- mMtu = mtu;
-
- if (mLocalIP.len == 32 && !netmask.equals("255.255.255.255")) {
- // get the netmask as IP
- long netint = CIDRIP.getInt(netmask);
- if (Math.abs(netint - mLocalIP.getInt()) == 1) {
- if ("net30".equals(mode))
- mLocalIP.len = 30;
- else
- mLocalIP.len = 31;
- } else {
- VpnStatus.logWarning(R.string.ip_not_cidr, local, netmask, mode);
- }
- }
-
- if ("p2p".equals(mode))
- mRemoteGW=netmask;
- else
- mRemoteGW=null;
-
- }
-
- public void setLocalIPv6(String ipv6addr) {
- mLocalIPv6 = ipv6addr;
- }
-
- @Override
- public void updateState(String state, String logmessage, int resid, ConnectionStatus level) {
- // If the process is not running, ignore any state,
- // Notification should be invisible in this state
- doSendBroadcast(state, level);
- if (mProcessThread == null && !mNotificationAlwaysVisible)
- return;
-
- // Display byte count only after being connected
-
- {
- if (level == LEVEL_WAITING_FOR_USER_INPUT) {
- // The user is presented a dialog of some kind, no need to inform the user
- // with a notifcation
- return;
- } else if (level == LEVEL_CONNECTED) {
- mDisplayBytecount = true;
- mConnecttime = System.currentTimeMillis();
- } else {
- mDisplayBytecount = false;
- }
-
- // Other notifications are shown,
- // This also mean we are no longer connected, ignore bytecount messages until next
- // CONNECTED
- String ticker = getString(resid);
- showNotification(getString(resid) + " " + logmessage, ticker, false, 0, level);
-
- }
- }
-
- private void doSendBroadcast(String state, ConnectionStatus level) {
- Intent vpnstatus = new Intent();
- vpnstatus.setAction("de.blinkt.openvpn.VPN_STATUS");
- vpnstatus.putExtra("status", level.toString());
- vpnstatus.putExtra("detailstatus", state);
- sendBroadcast(vpnstatus, permission.ACCESS_NETWORK_STATE);
- }
-
- @Override
- public void updateByteCount(long in, long out, long diffIn, long diffOut) {
- if (mDisplayBytecount) {
- String netstat = String.format(getString(R.string.statusline_bytecount),
- humanReadableByteCount(in, false),
- humanReadableByteCount(diffIn / OpenVPNManagement.mBytecountInterval, true),
- humanReadableByteCount(out, false),
- humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true));
-
- boolean lowpriority = !mNotificationAlwaysVisible;
- showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED);
- }
-
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- Runnable r = msg.getCallback();
- if (r != null) {
- r.run();
- return true;
- } else {
- return false;
- }
- }
-
- public OpenVPNManagement getManagement() {
- return mManagement;
- }
-
- public String getTunReopenStatus() {
- String currentConfiguration = getTunConfigString();
- if (currentConfiguration.equals(mLastTunCfg))
- return "NOACTION";
- else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
- return "OPEN_AFTER_CLOSE";
- else
- return "OPEN_BEFORE_CLOSE";
- }
-
- public class LocalBinder extends Binder {
- public OpenVpnService getService() {
- // Return this instance of LocalService so clients can call public methods
- return OpenVpnService.this;
- }
- }
-}
diff --git a/src/de/blinkt/openvpn/core/PRNGFixes.java b/src/de/blinkt/openvpn/core/PRNGFixes.java
deleted file mode 100644
index dd420371..00000000
--- a/src/de/blinkt/openvpn/core/PRNGFixes.java
+++ /dev/null
@@ -1,334 +0,0 @@
-package de.blinkt.openvpn.core;/*
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will Google be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, as long as the origin is not misrepresented.
- */
-
-import android.os.Build;
-import android.os.Process;
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.SecureRandom;
-import java.security.SecureRandomSpi;
-import java.security.Security;
-
-/**
- * Fixes for the output of the default PRNG having low entropy.
- *
- * The fixes need to be applied via {@link #apply()} before any use of Java
- * Cryptography Architecture primitives. A good place to invoke them is in the
- * application's {@code onCreate}.
- */
-public final class PRNGFixes {
-
- private static final int VERSION_CODE_JELLY_BEAN = 16;
- private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18;
- private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL =
- getBuildFingerprintAndDeviceSerial();
-
- /** Hidden constructor to prevent instantiation. */
- private PRNGFixes() {}
-
- /**
- * Applies all fixes.
- *
- * @throws SecurityException if a fix is needed but could not be applied.
- */
- public static void apply() {
- applyOpenSSLFix();
- installLinuxPRNGSecureRandom();
- }
-
- /**
- * Applies the fix for OpenSSL PRNG having low entropy. Does nothing if the
- * fix is not needed.
- *
- * @throws SecurityException if the fix is needed but could not be applied.
- */
- private static void applyOpenSSLFix() throws SecurityException {
- if ((Build.VERSION.SDK_INT < VERSION_CODE_JELLY_BEAN)
- || (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2)) {
- // No need to apply the fix
- return;
- }
-
- try {
- // Mix in the device- and invocation-specific seed.
- Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
- .getMethod("RAND_seed", byte[].class)
- .invoke(null, generateSeed());
-
- // Mix output of Linux PRNG into OpenSSL's PRNG
- int bytesRead = (Integer) Class.forName(
- "org.apache.harmony.xnet.provider.jsse.NativeCrypto")
- .getMethod("RAND_load_file", String.class, long.class)
- .invoke(null, "/dev/urandom", 1024);
- if (bytesRead != 1024) {
- throw new IOException(
- "Unexpected number of bytes read from Linux PRNG: "
- + bytesRead);
- }
- } catch (Exception e) {
- throw new SecurityException("Failed to seed OpenSSL PRNG", e);
- }
- }
-
- /**
- * Installs a Linux PRNG-backed {@code SecureRandom} implementation as the
- * default. Does nothing if the implementation is already the default or if
- * there is not need to install the implementation.
- *
- * @throws SecurityException if the fix is needed but could not be applied.
- */
- private static void installLinuxPRNGSecureRandom()
- throws SecurityException {
- if (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2) {
- // No need to apply the fix
- return;
- }
-
- // Install a Linux PRNG-based SecureRandom implementation as the
- // default, if not yet installed.
- Provider[] secureRandomProviders =
- Security.getProviders("SecureRandom.SHA1PRNG");
- if ((secureRandomProviders == null)
- || (secureRandomProviders.length < 1)
- || (!LinuxPRNGSecureRandomProvider.class.equals(
- secureRandomProviders[0].getClass()))) {
- Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1);
- }
-
- // Assert that new SecureRandom() and
- // SecureRandom.getInstance("SHA1PRNG") return a SecureRandom backed
- // by the Linux PRNG-based SecureRandom implementation.
- SecureRandom rng1 = new SecureRandom();
- if (!LinuxPRNGSecureRandomProvider.class.equals(
- rng1.getProvider().getClass())) {
- throw new SecurityException(
- "new SecureRandom() backed by wrong Provider: "
- + rng1.getProvider().getClass());
- }
-
- SecureRandom rng2;
- try {
- rng2 = SecureRandom.getInstance("SHA1PRNG");
- } catch (NoSuchAlgorithmException e) {
- throw new SecurityException("SHA1PRNG not available", e);
- }
- if (!LinuxPRNGSecureRandomProvider.class.equals(
- rng2.getProvider().getClass())) {
- throw new SecurityException(
- "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong"
- + " Provider: " + rng2.getProvider().getClass());
- }
- }
-
- /**
- * {@code Provider} of {@code SecureRandom} engines which pass through
- * all requests to the Linux PRNG.
- */
- private static class LinuxPRNGSecureRandomProvider extends Provider {
-
- public LinuxPRNGSecureRandomProvider() {
- super("LinuxPRNG",
- 1.0,
- "A Linux-specific random number provider that uses"
- + " /dev/urandom");
- // Although /dev/urandom is not a SHA-1 PRNG, some apps
- // explicitly request a SHA1PRNG SecureRandom and we thus need to
- // prevent them from getting the default implementation whose output
- // may have low entropy.
- put("SecureRandom.SHA1PRNG", LinuxPRNGSecureRandom.class.getName());
- put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
- }
- }
-
- /**
- * {@link SecureRandomSpi} which passes all requests to the Linux PRNG
- * ({@code /dev/urandom}).
- */
- public static class LinuxPRNGSecureRandom extends SecureRandomSpi {
-
- /*
- * IMPLEMENTATION NOTE: Requests to generate bytes and to mix in a seed
- * are passed through to the Linux PRNG (/dev/urandom). Instances of
- * this class seed themselves by mixing in the current time, PID, UID,
- * build fingerprint, and hardware serial number (where available) into
- * Linux PRNG.
- *
- * Concurrency: Read requests to the underlying Linux PRNG are
- * serialized (on sLock) to ensure that multiple threads do not get
- * duplicated PRNG output.
- */
-
- private static final File URANDOM_FILE = new File("/dev/urandom");
-
- private static final Object sLock = new Object();
-
- /**
- * Input stream for reading from Linux PRNG or {@code null} if not yet
- * opened.
- *
- * @GuardedBy("sLock")
- */
- private static DataInputStream sUrandomIn;
-
- /**
- * Output stream for writing to Linux PRNG or {@code null} if not yet
- * opened.
- *
- * @GuardedBy("sLock")
- */
- private static OutputStream sUrandomOut;
-
- /**
- * Whether this engine instance has been seeded. This is needed because
- * each instance needs to seed itself if the client does not explicitly
- * seed it.
- */
- private boolean mSeeded;
-
- @Override
- protected void engineSetSeed(byte[] bytes) {
- try {
- OutputStream out;
- synchronized (sLock) {
- out = getUrandomOutputStream();
- }
- out.write(bytes);
- out.flush();
- } catch (IOException e) {
- // On a small fraction of devices /dev/urandom is not writable.
- // Log and ignore.
- Log.w(PRNGFixes.class.getSimpleName(),
- "Failed to mix seed into " + URANDOM_FILE);
- } finally {
- mSeeded = true;
- }
- }
-
- @Override
- protected void engineNextBytes(byte[] bytes) {
- if (!mSeeded) {
- // Mix in the device- and invocation-specific seed.
- engineSetSeed(generateSeed());
- }
-
- try {
- DataInputStream in;
- synchronized (sLock) {
- in = getUrandomInputStream();
- }
- synchronized (in) {
- in.readFully(bytes);
- }
- } catch (IOException e) {
- throw new SecurityException(
- "Failed to read from " + URANDOM_FILE, e);
- }
- }
-
- @Override
- protected byte[] engineGenerateSeed(int size) {
- byte[] seed = new byte[size];
- engineNextBytes(seed);
- return seed;
- }
-
- private DataInputStream getUrandomInputStream() {
- synchronized (sLock) {
- if (sUrandomIn == null) {
- // NOTE: Consider inserting a BufferedInputStream between
- // DataInputStream and FileInputStream if you need higher
- // PRNG output performance and can live with future PRNG
- // output being pulled into this process prematurely.
- try {
- sUrandomIn = new DataInputStream(
- new FileInputStream(URANDOM_FILE));
- } catch (IOException e) {
- throw new SecurityException("Failed to open "
- + URANDOM_FILE + " for reading", e);
- }
- }
- return sUrandomIn;
- }
- }
-
- private OutputStream getUrandomOutputStream() throws IOException {
- synchronized (sLock) {
- if (sUrandomOut == null) {
- sUrandomOut = new FileOutputStream(URANDOM_FILE);
- }
- return sUrandomOut;
- }
- }
- }
-
- /**
- * Generates a device- and invocation-specific seed to be mixed into the
- * Linux PRNG.
- */
- private static byte[] generateSeed() {
- try {
- ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream();
- DataOutputStream seedBufferOut =
- new DataOutputStream(seedBuffer);
- seedBufferOut.writeLong(System.currentTimeMillis());
- seedBufferOut.writeLong(System.nanoTime());
- seedBufferOut.writeInt(Process.myPid());
- seedBufferOut.writeInt(Process.myUid());
- seedBufferOut.write(BUILD_FINGERPRINT_AND_DEVICE_SERIAL);
- seedBufferOut.close();
- return seedBuffer.toByteArray();
- } catch (IOException e) {
- throw new SecurityException("Failed to generate seed", e);
- }
- }
-
- /**
- * Gets the hardware serial number of this device.
- *
- * @return serial number or {@code null} if not available.
- */
- private static String getDeviceSerialNumber() {
- // We're using the Reflection API because Build.SERIAL is only available
- // since API Level 9 (Gingerbread, Android 2.3).
- try {
- return (String) Build.class.getField("SERIAL").get(null);
- } catch (Exception ignored) {
- return null;
- }
- }
-
- private static byte[] getBuildFingerprintAndDeviceSerial() {
- StringBuilder result = new StringBuilder();
- String fingerprint = Build.FINGERPRINT;
- if (fingerprint != null) {
- result.append(fingerprint);
- }
- String serial = getDeviceSerialNumber();
- if (serial != null) {
- result.append(serial);
- }
- try {
- return result.toString().getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("UTF-8 encoding not supported");
- }
- }
-} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/core/ProfileManager.java b/src/de/blinkt/openvpn/core/ProfileManager.java
deleted file mode 100644
index 4cfbcc8e..00000000
--- a/src/de/blinkt/openvpn/core/ProfileManager.java
+++ /dev/null
@@ -1,222 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import java.io.FileNotFoundException;
-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;
-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 ONBOOTPROFILE = "onBootProfile";
-
-
-
- private static ProfileManager instance;
-
-
-
- private static VpnProfile mLastConnectedVpn=null;
- private HashMap<String,VpnProfile> profiles=new HashMap<String, VpnProfile>();
- private static VpnProfile tmpprofile=null;
-
-
- 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 ProfileManager() { }
-
- private static void checkInstance(Context context) {
- if(instance == null) {
- instance = new ProfileManager();
- instance.loadVPNList(context);
- }
- }
-
- 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(ONBOOTPROFILE, null);
- prefsedit.apply();
-
- }
-
- public static void setConnectedVpnProfile(Context c, VpnProfile connectedrofile) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
- Editor prefsedit = prefs.edit();
-
- prefsedit.putString(ONBOOTPROFILE, connectedrofile.getUUIDString());
- prefsedit.apply();
- mLastConnectedVpn=connectedrofile;
-
- }
-
- public static VpnProfile getOnBootProfile(Context c) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
-
- boolean useStartOnBoot = prefs.getBoolean("restartvpnonboot", false);
-
-
- String mBootProfileUUID = prefs.getString(ONBOOTPROFILE,null);
- if(useStartOnBoot && mBootProfileUUID!=null)
- return get(c, mBootProfileUUID);
- else
- return null;
- }
-
-
-
-
- public Collection<VpnProfile> 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<String, VpnProfile>();
- SharedPreferences listpref = context.getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE);
- Set<String> vlist = listpref.getStringSet("vpnlist", null);
- Exception exp =null;
- if(vlist==null){
- vlist = new HashSet<String>();
- }
-
- 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 (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 int getNumberOfProfiles() {
- return profiles.size();
- }
-
-
-
- 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;
- }
-
-}
diff --git a/src/de/blinkt/openvpn/core/ProxyDetection.java b/src/de/blinkt/openvpn/core/ProxyDetection.java
deleted file mode 100644
index 4f66c503..00000000
--- a/src/de/blinkt/openvpn/core/ProxyDetection.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import java.net.InetSocketAddress;
-import java.net.MalformedURLException;
-import java.net.Proxy;
-import java.net.ProxySelector;
-import java.net.SocketAddress;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.List;
-
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-
-public class ProxyDetection {
- static SocketAddress detectProxy(VpnProfile vp) {
- // Construct a new url with https as protocol
- try {
- URL url = new URL(String.format("https://%s:%s",vp.mServerName,vp.mServerPort));
- Proxy proxy = getFirstProxy(url);
-
- if(proxy==null)
- return null;
- SocketAddress addr = proxy.address();
- if (addr instanceof InetSocketAddress) {
- return addr;
- }
-
- } catch (MalformedURLException e) {
- VpnStatus.logError(R.string.getproxy_error, e.getLocalizedMessage());
- } catch (URISyntaxException e) {
- VpnStatus.logError(R.string.getproxy_error, e.getLocalizedMessage());
- }
- return null;
- }
-
- static Proxy getFirstProxy(URL url) throws URISyntaxException {
- System.setProperty("java.net.useSystemProxies", "true");
-
- List<Proxy> proxylist = ProxySelector.getDefault().select(url.toURI());
-
-
- if (proxylist != null) {
- for (Proxy proxy: proxylist) {
- SocketAddress addr = proxy.address();
-
- if (addr != null) {
- return proxy;
- }
- }
-
- }
- return null;
- }
-} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/core/VPNLaunchHelper.java b/src/de/blinkt/openvpn/core/VPNLaunchHelper.java
deleted file mode 100644
index 5f1efb5f..00000000
--- a/src/de/blinkt/openvpn/core/VPNLaunchHelper.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-
-public class VPNLaunchHelper {
- static private boolean writeMiniVPN(Context context) {
- File mvpnout = new File(context.getCacheDir(),VpnProfile.MINIVPN);
- if (mvpnout.exists() && mvpnout.canExecute())
- return true;
-
- IOException e2 = null;
-
- try {
- InputStream mvpn;
-
- try {
- mvpn = context.getAssets().open("minivpn." + Build.CPU_ABI);
- }
- catch (IOException errabi) {
- VpnStatus.logInfo("Failed getting assets for archicture " + Build.CPU_ABI);
- e2=errabi;
- mvpn = context.getAssets().open("minivpn." + Build.CPU_ABI2);
-
- }
-
-
- FileOutputStream fout = new FileOutputStream(mvpnout);
-
- byte buf[]= new byte[4096];
-
- int lenread = mvpn.read(buf);
- while(lenread> 0) {
- fout.write(buf, 0, lenread);
- lenread = mvpn.read(buf);
- }
- fout.close();
-
- if(!mvpnout.setExecutable(true)) {
- VpnStatus.logError("Failed to set minivpn executable");
- return false;
- }
-
-
- return true;
- } catch (IOException e) {
- if(e2!=null)
- VpnStatus.logException(e2);
- VpnStatus.logException(e);
-
- return false;
- }
- }
-
-
- public static void startOpenVpn(VpnProfile startprofile, Context context) {
- if(!writeMiniVPN(context)) {
- VpnStatus.logError("Error writing minivpn binary");
- return;
- }
-
- VpnStatus.logInfo(R.string.building_configration);
-
- Intent startVPN = startprofile.prepareIntent(context);
- if(startVPN!=null)
- context.startService(startVPN);
-
- }
-}
diff --git a/src/de/blinkt/openvpn/core/VpnStatus.java b/src/de/blinkt/openvpn/core/VpnStatus.java
deleted file mode 100644
index d146aef8..00000000
--- a/src/de/blinkt/openvpn/core/VpnStatus.java
+++ /dev/null
@@ -1,540 +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.io.FileNotFoundException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-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.FormatFlagsConversionMismatchException;
-import java.util.LinkedList;
-import java.util.Locale;
-import java.util.UnknownFormatConversionException;
-import java.util.Vector;
-
-public class VpnStatus {
-
-
- public static LinkedList<LogItem> logbuffer;
-
- private static Vector<LogListener> logListener;
- private static Vector<StateListener> stateListener;
- private static Vector<ByteCountListener> 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 static void logException(LogLevel ll, String context, Exception e) {
- StringWriter sw = new StringWriter();
- e.printStackTrace(new PrintWriter(sw));
- LogItem li;
- 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());
- }
- newLogItem(li);
- }
-
- public static void logException(Exception e) {
- logException(LogLevel.ERROR, null, e);
- }
-
- public static void logException(String context, Exception e) {
- logException(LogLevel.ERROR, context, e);
- }
-
- 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
- }
-
- public enum LogLevel {
- INFO(2),
- ERROR(-2),
- WARNING(1),
- VERBOSE(3),
- DEBUG(4);
-
- protected int mValue;
- LogLevel(int value) {
- mValue = value;
- }
-
- public int getInt() {
- return mValue;
- }
-
- 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;
- }
- }
- }
-
- // 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[] 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;
-
- static {
- logbuffer = new LinkedList<LogItem>();
- logListener = new Vector<VpnStatus.LogListener>();
- stateListener = new Vector<VpnStatus.StateListener>();
- byteCountListener = new Vector<VpnStatus.ByteCountListener>();
- logInformation();
- }
-
-
- 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 int mVerbosityLevel = -1;
-
- private LogItem(int ressourceId, Object[] args) {
- mRessourceId = ressourceId;
- mArgs = args;
- }
-
- public LogItem(LogLevel level, int verblevel, String message) {
- mMessage=message;
- mLevel = level;
- mVerbosityLevel = verblevel;
- }
-
- @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.getInt());
- dest.writeInt(mVerbosityLevel);
-
- dest.writeLong(logtime);
- }
-
- 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();
- }
-
- public static final Parcelable.Creator<LogItem> CREATOR
- = new Parcelable.Creator<LogItem>() {
- public LogItem createFromParcel(Parcel in) {
- return new LogItem(in);
- }
-
- public LogItem[] newArray(int size) {
- return new LogItem[size];
- }
- };
-
- public LogItem(LogLevel loglevel,int ressourceId, Object... args) {
- mRessourceId = ressourceId;
- mArgs =args;
- mLevel = loglevel;
- }
-
-
- public LogItem(LogLevel loglevel, String msg) {
- mLevel = loglevel;
- mMessage = msg;
- }
-
-
- public LogItem(LogLevel 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;
- } catch (java.util.FormatFlagsConversionMismatchException e) {
- if (c != null)
- throw new FormatFlagsConversionMismatchException(e.getLocalizedMessage() + getString(null),e.getConversion());
- else
- throw e;
- }
-
- }
-
- 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))
- apksign = "F-Droid built and signed 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;
- }
-
-
- public int getVerbosityLevel() {
- if (mVerbosityLevel==-1) {
- // Hack:
- // For message not from OpenVPN, report the status level as log level
- return mLevel.getInt();
- }
- return mVerbosityLevel;
- }
- }
-
-
-
- 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 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) {
- // 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)));
- return;
- }
-
- mLaststate= state;
- mLaststatemsg = msg;
- mLastStateresid = resid;
- mLastLevel = level;
-
-
-
- for (StateListener sl : stateListener) {
- 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(int resourceId, Object... args) {
- newLogItem(new LogItem(LogLevel.INFO, resourceId, args));
- }
-
- public static void logDebug(int resourceId, Object... args) {
- newLogItem(new LogItem(LogLevel.DEBUG, resourceId, 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(LogLevel.ERROR, msg));
-
- }
-
- public static void logWarning(int resourceId, Object... args) {
- newLogItem(new LogItem(LogLevel.WARNING, resourceId, args));
- }
-
- public static void logWarning(String msg) {
- newLogItem(new LogItem(LogLevel.WARNING, msg));
- }
-
-
- 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));
- }
-
- public static void logMessageOpenVPN(LogLevel level, int ovpnlevel, String message) {
- newLogItem(new LogItem(level, ovpnlevel, message));
-
- }
-
-
- 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
deleted file mode 100644
index da1e4ed5..00000000
--- a/src/de/blinkt/openvpn/core/X509Utils.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package de.blinkt.openvpn.core;
-
-import android.content.Context;
-import android.text.TextUtils;
-
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-import org.spongycastle.util.io.pem.PemObject;
-import org.spongycastle.util.io.pem.PemReader;
-
-
-import javax.security.auth.x500.X500Principal;
-import java.io.*;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.Hashtable;
-
-public class X509Utils {
- public static Certificate getCertificateFromFile(String certfilename) throws FileNotFoundException, CertificateException {
- CertificateFactory certFact = CertificateFactory.getInstance("X.509");
-
- InputStream inStream;
-
- if(VpnProfile.isEmbedded(certfilename)) {
- // The java certifcate reader is ... kind of stupid
- // It does NOT ignore chars before the --BEGIN ...
- int subIndex = certfilename.indexOf("-----BEGIN CERTIFICATE-----");
- subIndex = Math.max(0,subIndex);
- inStream = new ByteArrayInputStream(certfilename.substring(subIndex).getBytes());
-
-
- } else {
- inStream = new FileInputStream(certfilename);
- }
-
-
- return certFact.generateCertificate(inStream);
- }
-
- public static PemObject readPemObjectFromFile (String keyfilename) throws IOException {
-
- Reader inStream;
-
- if(VpnProfile.isEmbedded(keyfilename))
- inStream = new StringReader(VpnProfile.getEmbeddedContent(keyfilename));
- else
- inStream = new FileReader(new File(keyfilename));
-
- PemReader pr = new PemReader(inStream);
- PemObject r = pr.readPemObject();
- pr.close();
- return r;
- }
-
-
-
-
- public static String getCertificateFriendlyName (Context c, String filename) {
- if(!TextUtils.isEmpty(filename)) {
- try {
- X509Certificate cert = (X509Certificate) getCertificateFromFile(filename);
-
- return getCertificateFriendlyName(cert);
-
- } catch (Exception e) {
- VpnStatus.logError("Could not read certificate" + e.getLocalizedMessage());
- }
- }
- return c.getString(R.string.cannotparsecert);
- }
-
- public static String getCertificateFriendlyName(X509Certificate cert) {
- X500Principal principal = cert.getSubjectX500Principal();
- byte[] encodedSubject = principal.getEncoded();
- String friendlyName=null;
-
- /* Hack so we do not have to ship a whole Spongy/bouncycastle */
- Exception exp=null;
- try {
- Class X509NameClass = Class.forName("com.android.org.bouncycastle.asn1.x509.X509Name");
- Method getInstance = X509NameClass.getMethod("getInstance",Object.class);
-
- Hashtable defaultSymbols = (Hashtable) X509NameClass.getField("DefaultSymbols").get(X509NameClass);
-
- if (!defaultSymbols.containsKey("1.2.840.113549.1.9.1"))
- defaultSymbols.put("1.2.840.113549.1.9.1","eMail");
-
- Object subjectName = getInstance.invoke(X509NameClass, encodedSubject);
-
- Method toString = X509NameClass.getMethod("toString",boolean.class,Hashtable.class);
-
- friendlyName= (String) toString.invoke(subjectName,true,defaultSymbols);
-
- } catch (ClassNotFoundException e) {
- exp =e ;
- } catch (NoSuchMethodException e) {
- exp =e;
- } catch (InvocationTargetException e) {
- exp =e;
- } catch (IllegalAccessException e) {
- exp =e;
- } catch (NoSuchFieldException e) {
- exp =e;
- }
- if (exp!=null)
- VpnStatus.logException("Getting X509 Name from certificate", exp);
-
- /* Fallback if the reflection method did not work */
- if(friendlyName==null)
- friendlyName = principal.getName();
-
-
- // Really evil hack to decode email address
- // See: http://code.google.com/p/android/issues/detail?id=21531
-
- String[] parts = friendlyName.split(",");
- for (int i=0;i<parts.length;i++){
- String part = parts[i];
- if (part.startsWith("1.2.840.113549.1.9.1=#16")) {
- parts[i] = "email=" + ia5decode(part.replace("1.2.840.113549.1.9.1=#16", ""));
- }
- }
- friendlyName = TextUtils.join(",", parts);
- return friendlyName;
- }
-
- public static boolean isPrintableChar(char c) {
- Character.UnicodeBlock block = Character.UnicodeBlock.of( c );
- return (!Character.isISOControl(c)) &&
- block != null &&
- block != Character.UnicodeBlock.SPECIALS;
- }
-
- private static String ia5decode(String ia5string) {
- String d = "";
- for (int i=1;i<ia5string.length();i=i+2) {
- String hexstr = ia5string.substring(i-1,i+1);
- char c = (char) Integer.parseInt(hexstr,16);
- if (isPrintableChar(c)) {
- d+=c;
- } else if (i==1 && (c==0x12 || c==0x1b)) {
- ; // ignore
- } else {
- d += "\\x" + hexstr;
- }
- }
- return d;
- }
-
-
-}
diff --git a/src/de/blinkt/openvpn/fragments/AboutFragment.java b/src/de/blinkt/openvpn/fragments/AboutFragment.java
deleted file mode 100644
index 61fcb581..00000000
--- a/src/de/blinkt/openvpn/fragments/AboutFragment.java
+++ /dev/null
@@ -1,297 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.app.Fragment;
-import android.app.PendingIntent;
-import android.content.*;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.text.Html;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.TextUtils;
-import android.text.method.LinkMovementMethod;
-import android.text.style.ClickableSpan;
-import android.util.Log;
-import android.util.Pair;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.webkit.WebView;
-import android.widget.TextView;
-import com.android.vending.billing.IInAppBillingService;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.core.VpnStatus;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.util.*;
-
-public class AboutFragment extends Fragment implements View.OnClickListener {
-
- public static final String INAPPITEM_TYPE_INAPP = "inapp";
- public static final String RESPONSE_CODE = "RESPONSE_CODE";
- private static final int DONATION_CODE = 12;
- private static final int BILLING_RESPONSE_RESULT_OK = 0;
- private static final String RESPONSE_BUY_INTENT = "BUY_INTENT";
- private static final String[] donationSkus = { "donation1eur", "donation2eur", "donation5eur", "donation10eur",
- "donation1337eur","donation23eur","donation25eur",};
- IInAppBillingService mService;
- Hashtable<View, String> viewToProduct = new Hashtable<View, String>();
- ServiceConnection mServiceConn = new ServiceConnection() {
- @Override
- public void onServiceDisconnected(ComponentName name) {
- mService = null;
- }
-
- @Override
- public void onServiceConnected(ComponentName name,
- IBinder service) {
- mService = IInAppBillingService.Stub.asInterface(service);
- initGooglePlayDonation();
-
- }
- };
-
- private void initGooglePlayDonation() {
- new Thread("queryGMSInApp") {
- @Override
- public void run() {
- initGMSDonateOptions();
- }
- }.start();
- }
-
- private TextView gmsTextView;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().bindService(new
- Intent("com.android.vending.billing.InAppBillingService.BIND"),
- mServiceConn, Context.BIND_AUTO_CREATE);
-
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (mServiceConn != null) {
- getActivity().unbindService(mServiceConn);
- }
-
- }
-
- private void initGMSDonateOptions() {
- try {
- int billingSupported = mService.isBillingSupported(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP);
- if (billingSupported != BILLING_RESPONSE_RESULT_OK) {
- Log.i("OpenVPN", "Play store billing not supported");
- return;
- }
-
- ArrayList skuList = new ArrayList();
- Collections.addAll(skuList, donationSkus);
- Bundle querySkus = new Bundle();
- querySkus.putStringArrayList("ITEM_ID_LIST", skuList);
-
- Bundle ownedItems = mService.getPurchases(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP, null);
-
-
- if (ownedItems.getInt(RESPONSE_CODE) != BILLING_RESPONSE_RESULT_OK)
- return;
-
- final ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
-
- Bundle skuDetails = mService.getSkuDetails(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP, querySkus);
-
-
- if (skuDetails.getInt(RESPONSE_CODE) != BILLING_RESPONSE_RESULT_OK)
- return;
-
- final ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
-
- if (getActivity() != null) {
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- createPlayBuyOptions(ownedSkus, responseList);
-
- }
- });
- }
-
- } catch (RemoteException e) {
- VpnStatus.logException(e);
- }
- }
-
- private static class SkuResponse {
- String title;
- String price;
-
- SkuResponse(String p, String t)
- {
- title=t;
- price=p;
- }
- }
-
-
-
- private void createPlayBuyOptions(ArrayList<String> ownedSkus, ArrayList<String> responseList) {
- try {
- Vector<Pair<String,String>> gdonation = new Vector<Pair<String, String>>();
-
- gdonation.add(new Pair<String, String>(getString(R.string.donatePlayStore),null));
- HashMap<String, SkuResponse> responseMap = new HashMap<String, SkuResponse>();
- for (String thisResponse : responseList) {
- JSONObject object = new JSONObject(thisResponse);
- responseMap.put(
- object.getString("productId"),
- new SkuResponse(
- object.getString("price"),
- object.getString("title")));
-
- }
- for (String sku: donationSkus)
- if (responseMap.containsKey(sku))
- gdonation.add(getSkuTitle(sku,
- responseMap.get(sku).title, responseMap.get(sku).price, ownedSkus));
-
- String gmsTextString="";
- for(int i=0;i<gdonation.size();i++) {
- if(i==1)
- gmsTextString+= " ";
- else if(i>1)
- gmsTextString+= ", ";
- gmsTextString+=gdonation.elementAt(i).first;
- }
- SpannableString gmsText = new SpannableString(gmsTextString);
-
-
- int lStart = 0;
- int lEnd=0;
- for(Pair<String, String> item:gdonation){
- lEnd = lStart + item.first.length();
- if (item.second!=null) {
- final String mSku = item.second;
- ClickableSpan cspan = new ClickableSpan()
- {
- @Override
- public void onClick(View widget) {
- triggerBuy(mSku);
- }
- };
- gmsText.setSpan(cspan,lStart,lEnd,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- lStart = lEnd+2; // Account for ", " between items
- }
-
- if(gmsTextView !=null) {
- gmsTextView.setText(gmsText);
- gmsTextView.setMovementMethod(LinkMovementMethod.getInstance());
- gmsTextView.setVisibility(View.VISIBLE);
- }
-
- } catch (JSONException e) {
- VpnStatus.logException("Parsing Play Store IAP",e);
- }
-
- }
-
- private Pair<String,String> getSkuTitle(final String sku, String title, String price, ArrayList<String> ownedSkus) {
- String text;
- if (ownedSkus.contains(sku))
- return new Pair<String,String>(getString(R.string.thanks_for_donation, price),null);
-
- if (price.contains("€")|| price.contains("\u20ac")) {
- text= title;
- } else {
- text = String.format(Locale.getDefault(), "%s (%s)", title, price);
- }
- //return text;
- return new Pair<String,String>(price, sku);
-
- }
-
- private void triggerBuy(String sku) {
- try {
- Bundle buyBundle
- = mService.getBuyIntent(3, getActivity().getPackageName(),
- sku, INAPPITEM_TYPE_INAPP, "Thanks for the donation! :)");
-
-
- if (buyBundle.getInt(RESPONSE_CODE) == BILLING_RESPONSE_RESULT_OK) {
- PendingIntent buyIntent = (PendingIntent) buyBundle.getParcelable(RESPONSE_BUY_INTENT);
- getActivity().startIntentSenderForResult(buyIntent.getIntentSender(), DONATION_CODE, new Intent(),
- 0, 0, 0);
- }
-
- } catch (RemoteException e) {
- VpnStatus.logException(e);
- } catch (IntentSender.SendIntentException e) {
- VpnStatus.logException(e);
- }
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View v = inflater.inflate(R.layout.about, container, false);
- TextView ver = (TextView) v.findViewById(R.id.version);
-
- String version;
- String name = "Openvpn";
- try {
- PackageInfo packageinfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0);
- version = packageinfo.versionName;
- name = getString(R.string.app);
- } catch (NameNotFoundException e) {
- version = "error fetching version";
- }
-
-
- ver.setText(getString(R.string.version_info, name, version));
-
- TextView paypal = (TextView) v.findViewById(R.id.donatestring);
-
- String donatetext = getActivity().getString(R.string.donatewithpaypal);
- Spanned htmltext = Html.fromHtml(donatetext);
- paypal.setText(htmltext);
- paypal.setMovementMethod(LinkMovementMethod.getInstance());
- gmsTextView = (TextView) v.findViewById(R.id.donategms);
- /* recreating view without onCreate/onDestroy cycle */
- if (mService!=null)
- initGooglePlayDonation();
-
- TextView translation = (TextView) v.findViewById(R.id.translation);
-
- // Don't print a text for myself
- if (getString(R.string.translationby).contains("Arne Schwabe"))
- translation.setText("");
- else
- translation.setText(R.string.translationby);
-
- WebView wv = (WebView)v.findViewById(R.id.webView);
- wv.loadUrl("file:///android_asset/full_licenses.html");
-
- return v;
- }
-
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- if (mService!=null)
- initGooglePlayDonation();
- }
-
-
- @Override
- public void onClick(View v) {
-
- }
-}
diff --git a/src/de/blinkt/openvpn/fragments/FaqFragment.java b/src/de/blinkt/openvpn/fragments/FaqFragment.java
deleted file mode 100644
index 238ad952..00000000
--- a/src/de/blinkt/openvpn/fragments/FaqFragment.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.app.Fragment;
-import android.os.Bundle;
-import android.text.Html;
-import android.text.method.LinkMovementMethod;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import de.blinkt.openvpn.R;
-
-public class FaqFragment extends Fragment {
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View v= inflater.inflate(R.layout.faq, container, false);
-
- insertHtmlEntry(v,R.id.broken_images_faq,R.string.broken_images_faq);
- insertHtmlEntry(v,R.id.faq_howto,R.string.faq_howto);
- insertHtmlEntry(v, R.id.baterry_consumption, R.string.baterry_consumption);
- insertHtmlEntry(v, R.id.faq_tethering, R.string.faq_tethering);
- insertHtmlEntry(v, R.id.faq_vpndialog43, R.string.faq_vpndialog43);
- insertHtmlEntry(v, R.id.faq_system_dialog_xposed, R.string.faq_system_dialog_xposed);
- return v;
- }
-
- private void insertHtmlEntry (View v, int viewId, int stringId) {
- TextView faqitem = (TextView) v.findViewById(viewId);
- faqitem.setText(Html.fromHtml(getActivity().getString(stringId)));
- faqitem.setMovementMethod(LinkMovementMethod.getInstance());
-
- }
-
-}
diff --git a/src/de/blinkt/openvpn/fragments/FileSelectionFragment.java b/src/de/blinkt/openvpn/fragments/FileSelectionFragment.java
deleted file mode 100644
index 84e065a5..00000000
--- a/src/de/blinkt/openvpn/fragments/FileSelectionFragment.java
+++ /dev/null
@@ -1,256 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.TreeMap;
-
-import android.app.AlertDialog;
-import android.app.ListFragment;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ListView;
-import android.widget.SimpleAdapter;
-import android.widget.TextView;
-import de.blinkt.openvpn.activities.FileSelect;
-import de.blinkt.openvpn.R;
-
-public class FileSelectionFragment extends ListFragment {
-
- private static final String ITEM_KEY = "key";
- private static final String ITEM_IMAGE = "image";
- private static final String ROOT = "/";
-
-
- private List<String> path = null;
- private TextView myPath;
- private ArrayList<HashMap<String, Object>> mList;
-
- private Button selectButton;
-
-
- private String parentPath;
- private String currentPath = ROOT;
-
-
- private String[] formatFilter = null;
-
- private File selectedFile;
- private HashMap<String, Integer> lastPositions = new HashMap<String, Integer>();
- private String mStartPath;
- private CheckBox mInlineImport;
- private Button mClearButton;
- private boolean mHideImport=false;
-
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View v = inflater.inflate(R.layout.file_dialog_main, container,false);
-
- myPath = (TextView) v.findViewById(R.id.path);
-
- mInlineImport = (CheckBox) v.findViewById(R.id.doinline);
-
- if(mHideImport) {
- mInlineImport.setVisibility(View.GONE);
- mInlineImport.setChecked(false);
- }
-
-
-
- selectButton = (Button) v.findViewById(R.id.fdButtonSelect);
- selectButton.setEnabled(false);
- selectButton.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- if (selectedFile != null) {
- if(mInlineImport.isChecked())
-
- ((FileSelect) getActivity()).importFile(selectedFile.getPath());
- else
- ((FileSelect) getActivity()).setFile(selectedFile.getPath());
- }
- }
- });
-
- mClearButton = (Button) v.findViewById(R.id.fdClear);
- mClearButton.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- ((FileSelect) getActivity()).clearData();
- }
- });
- if(!((FileSelect) getActivity()).showClear()) {
- mClearButton.setVisibility(View.GONE);
- mClearButton.setEnabled(false);
- }
-
- return v;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mStartPath = ((FileSelect) getActivity()).getSelectPath();
- getDir(mStartPath);
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
- private void getDir(String dirPath) {
-
- boolean useAutoSelection = dirPath.length() < currentPath.length();
-
- Integer position = lastPositions.get(parentPath);
-
- getDirImpl(dirPath);
-
- if (position != null && useAutoSelection) {
- getListView().setSelection(position);
- }
-
- }
-
- /**
- * Monta a estrutura de arquivos e diretorios filhos do diretorio fornecido.
- *
- * @param dirPath
- * Diretorio pai.
- */
- private void getDirImpl(final String dirPath) {
-
- currentPath = dirPath;
-
- final List<String> item = new ArrayList<String>();
- path = new ArrayList<String>();
- mList = new ArrayList<HashMap<String, Object>>();
-
- File f = new File(currentPath);
- File[] files = f.listFiles();
- if (files == null) {
- currentPath = ROOT;
- f = new File(currentPath);
- files = f.listFiles();
- }
-
- myPath.setText(getText(R.string.location) + ": " + currentPath);
-
- if (!currentPath.equals(ROOT)) {
-
- item.add(ROOT);
- addItem(ROOT, R.drawable.ic_root_folder_am);
- path.add(ROOT);
-
- item.add("../");
- addItem("../", R.drawable.ic_root_folder_am);
- path.add(f.getParent());
- parentPath = f.getParent();
-
- }
-
- TreeMap<String, String> dirsMap = new TreeMap<String, String>();
- TreeMap<String, String> dirsPathMap = new TreeMap<String, String>();
- TreeMap<String, String> filesMap = new TreeMap<String, String>();
- TreeMap<String, String> filesPathMap = new TreeMap<String, String>();
- for (File file : files) {
- if (file.isDirectory()) {
- String dirName = file.getName();
- dirsMap.put(dirName, dirName);
- dirsPathMap.put(dirName, file.getPath());
- } else {
- final String fileName = file.getName();
- final String fileNameLwr = fileName.toLowerCase(Locale.getDefault());
- // se ha um filtro de formatos, utiliza-o
- if (formatFilter != null) {
- boolean contains = false;
- for (String aFormatFilter : formatFilter) {
- final String formatLwr = aFormatFilter.toLowerCase(Locale.getDefault());
- if (fileNameLwr.endsWith(formatLwr)) {
- contains = true;
- break;
- }
- }
- if (contains) {
- filesMap.put(fileName, fileName);
- filesPathMap.put(fileName, file.getPath());
- }
- // senao, adiciona todos os arquivos
- } else {
- filesMap.put(fileName, fileName);
- filesPathMap.put(fileName, file.getPath());
- }
- }
- }
- item.addAll(dirsMap.tailMap("").values());
- item.addAll(filesMap.tailMap("").values());
- path.addAll(dirsPathMap.tailMap("").values());
- path.addAll(filesPathMap.tailMap("").values());
-
- SimpleAdapter fileList = new SimpleAdapter(getActivity(), mList, R.layout.file_dialog_row, new String[] {
- ITEM_KEY, ITEM_IMAGE }, new int[] { R.id.fdrowtext, R.id.fdrowimage });
-
- for (String dir : dirsMap.tailMap("").values()) {
- addItem(dir, R.drawable.ic_root_folder_am);
- }
-
- for (String file : filesMap.tailMap("").values()) {
- addItem(file, R.drawable.ic_doc_generic_am);
- }
-
- fileList.notifyDataSetChanged();
-
- setListAdapter(fileList);
-
- }
-
- private void addItem(String fileName, int imageId) {
- HashMap<String, Object> item = new HashMap<String, Object>();
- item.put(ITEM_KEY, fileName);
- item.put(ITEM_IMAGE, imageId);
- mList.add(item);
- }
-
-
- @Override
- public void onListItemClick(ListView l, View v, int position, long id) {
-
- File file = new File(path.get(position));
-
- if (file.isDirectory()) {
- selectButton.setEnabled(false);
-
- if (file.canRead()) {
- lastPositions.put(currentPath, position);
- getDir(path.get(position));
- } else {
- new AlertDialog.Builder(getActivity()).setIcon(R.drawable.icon)
- .setTitle("[" + file.getName() + "] " + getText(R.string.cant_read_folder))
- .setPositiveButton("OK", null).show();
- }
- } else {
- selectedFile = file;
- v.setSelected(true);
- selectButton.setEnabled(true);
- }
- }
-
- public void setNoInLine() {
- mHideImport=true;
-
- }
-
-}
diff --git a/src/de/blinkt/openvpn/fragments/GeneralSettings.java b/src/de/blinkt/openvpn/fragments/GeneralSettings.java
deleted file mode 100644
index 2e486dfe..00000000
--- a/src/de/blinkt/openvpn/fragments/GeneralSettings.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package de.blinkt.openvpn.fragments;
-import java.io.File;
-
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Build;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.PreferenceCategory;
-import android.preference.PreferenceFragment;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.api.ExternalAppDatabase;
-
-public class GeneralSettings extends PreferenceFragment implements OnPreferenceClickListener, OnClickListener {
-
- private ExternalAppDatabase mExtapp;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
-
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.general_settings);
-
-
- PreferenceCategory devHacks = (PreferenceCategory) findPreference("device_hacks");
-
-
- Preference loadtun = findPreference("loadTunModule");
- if(!isTunModuleAvailable()) {
- loadtun.setEnabled(false);
- devHacks.removePreference(loadtun);
- }
-
- CheckBoxPreference cm9hack = (CheckBoxPreference) findPreference("useCM9Fix");
- if (!cm9hack.isChecked() && (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1)) {
- devHacks.removePreference(cm9hack);
- }
-
- mExtapp = new ExternalAppDatabase(getActivity());
- Preference clearapi = findPreference("clearapi");
- clearapi.setOnPreferenceClickListener(this);
-
-
- if(devHacks.getPreferenceCount()==0)
- getPreferenceScreen().removePreference(devHacks);
-
- setClearApiSummary();
- }
-
- private void setClearApiSummary() {
- Preference clearapi = findPreference("clearapi");
-
- if(mExtapp.getExtAppList().isEmpty()) {
- clearapi.setEnabled(false);
- clearapi.setSummary(R.string.no_external_app_allowed);
- } else {
- clearapi.setEnabled(true);
- clearapi.setSummary(getString(R.string.allowed_apps,getExtAppList(", ")));
- }
- }
-
- private String getExtAppList(String delim) {
- ApplicationInfo app;
- PackageManager pm = getActivity().getPackageManager();
-
- String applist=null;
- for (String packagename : mExtapp.getExtAppList()) {
- try {
- app = pm.getApplicationInfo(packagename, 0);
- if (applist==null)
- applist = "";
- else
- applist += delim;
- applist+=app.loadLabel(pm);
-
- } catch (NameNotFoundException e) {
- // App not found. Remove it from the list
- mExtapp.removeApp(packagename);
- }
- }
-
- return applist;
- }
-
- private boolean isTunModuleAvailable() {
- // Check if the tun module exists on the file system
- return new File("/system/lib/modules/tun.ko").length() > 10;
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- if(preference.getKey().equals("clearapi")){
- Builder builder = new AlertDialog.Builder(getActivity());
- builder.setPositiveButton(R.string.clear, this);
- builder.setNegativeButton(android.R.string.cancel, null);
- builder.setMessage(getString(R.string.clearappsdialog,getExtAppList("\n")));
- builder.show();
- }
-
- return true;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if( which == Dialog.BUTTON_POSITIVE){
- mExtapp.clearAllApiApps();
- setClearApiSummary();
- }
- }
-
-
-
-} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/fragments/InlineFileTab.java b/src/de/blinkt/openvpn/fragments/InlineFileTab.java
deleted file mode 100644
index bea22442..00000000
--- a/src/de/blinkt/openvpn/fragments/InlineFileTab.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.app.Fragment;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
-import de.blinkt.openvpn.activities.FileSelect;
-import de.blinkt.openvpn.R;
-
-public class InlineFileTab extends Fragment
-{
-
- private static final int MENU_SAVE = 0;
- private EditText mInlineData;
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- mInlineData.setText(((FileSelect)getActivity()).getInlineData());
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState)
- {
-
- View v = inflater.inflate(R.layout.file_dialog_inline, container, false);
- mInlineData =(EditText) v.findViewById(R.id.inlineFileData);
- return v;
- }
-
- public void setData(String data) {
- if(mInlineData!=null)
- mInlineData.setText(data);
-
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- menu.add(0, MENU_SAVE, 0, "Use inline data")
- .setIcon(android.R.drawable.ic_menu_save)
- .setAlphabeticShortcut('u')
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM
- | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if(item.getItemId()==MENU_SAVE){
- ((FileSelect)getActivity()).saveInlineData(null, mInlineData.getText().toString());
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
-} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/fragments/LogFragment.java b/src/de/blinkt/openvpn/fragments/LogFragment.java
deleted file mode 100644
index 8530be34..00000000
--- a/src/de/blinkt/openvpn/fragments/LogFragment.java
+++ /dev/null
@@ -1,668 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.app.*;
-import android.content.*;
-import android.database.DataSetObserver;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Handler.Callback;
-import android.os.IBinder;
-import android.os.Message;
-import android.text.SpannableString;
-import android.text.format.DateFormat;
-import android.text.style.ImageSpan;
-import android.view.*;
-import android.widget.*;
-import android.widget.AdapterView.OnItemLongClickListener;
-import de.blinkt.openvpn.*;
-import de.blinkt.openvpn.activities.DisconnectVPN;
-import de.blinkt.openvpn.activities.MainActivity;
-import de.blinkt.openvpn.activities.VPNPreferences;
-import de.blinkt.openvpn.core.OpenVPNManagement;
-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;
-import org.jetbrains.annotations.Nullable;
-
-import java.text.SimpleDateFormat;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Locale;
-import java.util.Vector;
-
-import static de.blinkt.openvpn.core.OpenVpnService.humanReadableByteCount;
-
-public class LogFragment extends ListFragment implements StateListener, SeekBar.OnSeekBarChangeListener, RadioGroup.OnCheckedChangeListener, VpnStatus.ByteCountListener {
- private static final String LOGTIMEFORMAT = "logtimeformat";
- private static final int START_VPN_CONFIG = 0;
- private static final String VERBOSITYLEVEL = "verbositylevel";
- protected OpenVpnService mService;
- private ServiceConnection mConnection = new ServiceConnection() {
-
-
- @Override
- public void onServiceConnected(ComponentName className,
- IBinder service) {
- // We've bound to LocalService, cast the IBinder and get LocalService instance
- LocalBinder binder = (LocalBinder) service;
- mService = binder.getService();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName arg0) {
- mService =null;
- }
-
- };
-
- private SeekBar mLogLevelSlider;
- private LinearLayout mOptionsLayout;
- private RadioGroup mTimeRadioGroup;
- private TextView mUpStatus;
- private TextView mDownStatus;
- private TextView mConnectStatus;
- private boolean mShowOptionsLayout;
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- ladapter.setLogLevel(progress+1);
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
-
- @Override
- public void onCheckedChanged(RadioGroup group, int checkedId) {
- switch (checkedId) {
- case R.id.radioISO:
- ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_ISO);
- break;
- case R.id.radioNone:
- ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_NONE);
- break;
- case R.id.radioShort:
- ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_SHORT);
- break;
-
- }
- }
-
- @Override
- public void updateByteCount(long in, long out, long diffIn, long diffOut) {
- //%2$s/s %1$s - ↑%4$s/s %3$s
- final String down = String.format("%2$s/s %1$s", humanReadableByteCount(in, false), humanReadableByteCount(diffIn / OpenVPNManagement.mBytecountInterval, true));
- final String up = String.format("%2$s/s %1$s", humanReadableByteCount(out, false), humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true));
-
- if (mUpStatus != null && mDownStatus != null) {
- if (getActivity() != null) {
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mUpStatus.setText(up);
- mDownStatus.setText(down);
- }
- });
- }
- }
-
- }
-
-
- class LogWindowListAdapter implements ListAdapter, LogListener, Callback {
-
- private static final int MESSAGE_NEWLOG = 0;
-
- private static final int MESSAGE_CLEARLOG = 1;
-
- private static final int MESSAGE_NEWTS = 2;
- private static final int MESSAGE_NEWLOGLEVEL = 3;
-
- public static final int TIME_FORMAT_NONE = 0;
- public static final int TIME_FORMAT_SHORT = 1;
- public static final int TIME_FORMAT_ISO = 2;
- private static final int MAX_STORED_LOG_ENTRIES = 1000;
-
- private Vector<LogItem> allEntries=new Vector<LogItem>();
-
- private Vector<LogItem> currentLevelEntries=new Vector<LogItem>();
-
- private Handler mHandler;
-
- private Vector<DataSetObserver> observers=new Vector<DataSetObserver>();
-
- private int mTimeFormat=0;
- private int mLogLevel=3;
-
-
- public LogWindowListAdapter() {
- initLogBuffer();
- if (mHandler == null) {
- mHandler = new Handler(this);
- }
-
- VpnStatus.addLogListener(this);
- }
-
-
-
- private void initLogBuffer() {
- allEntries.clear();
- Collections.addAll(allEntries, VpnStatus.getlogbuffer());
- initCurrentMessages();
- }
-
- String getLogStr() {
- String str = "";
- for(LogItem entry:allEntries) {
- str+=getTime(entry, TIME_FORMAT_ISO) + entry.getString(getActivity()) + '\n';
- }
- return str;
- }
-
-
- private void shareLog() {
- Intent shareIntent = new Intent(Intent.ACTION_SEND);
- shareIntent.putExtra(Intent.EXTRA_TEXT, getLogStr());
- shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.ics_openvpn_log_file));
- shareIntent.setType("text/plain");
- startActivity(Intent.createChooser(shareIntent, "Send Logfile"));
- }
-
- @Override
- public void registerDataSetObserver(DataSetObserver observer) {
- observers.add(observer);
-
- }
-
- @Override
- public void unregisterDataSetObserver(DataSetObserver observer) {
- observers.remove(observer);
- }
-
- @Override
- public int getCount() {
- return currentLevelEntries.size();
- }
-
- @Override
- public Object getItem(int position) {
- return currentLevelEntries.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return ((Object)currentLevelEntries.get(position)).hashCode();
- }
-
- @Override
- public boolean hasStableIds() {
- return true;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- TextView v;
- if(convertView==null)
- v = new TextView(getActivity());
- else
- v = (TextView) convertView;
-
- LogItem le = currentLevelEntries.get(position);
- String msg = le.getString(getActivity());
- String time = getTime(le, mTimeFormat);
- msg = time + msg;
-
- int spanStart = time.length();
-
- SpannableString t = new SpannableString(msg);
-
- //t.setSpan(getSpanImage(le,(int)v.getTextSize()),spanStart,spanStart+1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
- v.setText(t);
- return v;
- }
-
- private String getTime(LogItem le, int time) {
- if (time != TIME_FORMAT_NONE) {
- Date d = new Date(le.getLogtime());
- java.text.DateFormat timeformat;
- if (time== TIME_FORMAT_ISO)
- timeformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
- else
- timeformat = DateFormat.getTimeFormat(getActivity());
-
- return timeformat.format(d) + " ";
-
- } else {
- return "";
- }
-
- }
-
- private ImageSpan getSpanImage(LogItem li, int imageSize) {
- int imageRes = android.R.drawable.ic_menu_call;
-
- switch (li.getLogLevel()) {
- case ERROR:
- imageRes = android.R.drawable.ic_notification_clear_all;
- break;
- case INFO:
- imageRes = android.R.drawable.ic_menu_compass;
- break;
- case VERBOSE:
- imageRes = android.R.drawable.ic_menu_info_details;
- break;
- case WARNING:
- imageRes = android.R.drawable.ic_menu_camera;
- break;
- }
-
- Drawable d = getResources().getDrawable(imageRes);
-
-
- //d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
- d.setBounds(0, 0, imageSize, imageSize);
- ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BOTTOM);
-
- return span;
- }
-
- @Override
- public int getItemViewType(int position) {
- return 0;
- }
-
- @Override
- public int getViewTypeCount() {
- return 1;
- }
-
- @Override
- public boolean isEmpty() {
- return currentLevelEntries.isEmpty();
-
- }
-
- @Override
- public boolean areAllItemsEnabled() {
- return true;
- }
-
- @Override
- public boolean isEnabled(int position) {
- return true;
- }
-
- @Override
- public void newLog(LogItem logMessage) {
- Message msg = Message.obtain();
- assert (msg!=null);
- msg.what=MESSAGE_NEWLOG;
- Bundle bundle=new Bundle();
- bundle.putParcelable("logmessage", logMessage);
- msg.setData(bundle);
- mHandler.sendMessage(msg);
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- // We have been called
- if(msg.what==MESSAGE_NEWLOG) {
-
- LogItem logMessage = msg.getData().getParcelable("logmessage");
- if(addLogMessage(logMessage))
- for (DataSetObserver observer : observers) {
- observer.onChanged();
- }
- } else if (msg.what == MESSAGE_CLEARLOG) {
- for (DataSetObserver observer : observers) {
- observer.onInvalidated();
- }
- initLogBuffer();
- } else if (msg.what == MESSAGE_NEWTS) {
- for (DataSetObserver observer : observers) {
- observer.onInvalidated();
- }
- } else if (msg.what == MESSAGE_NEWLOGLEVEL) {
- initCurrentMessages();
-
- for (DataSetObserver observer: observers) {
- observer.onChanged();
- }
-
- }
-
- return true;
- }
-
- private void initCurrentMessages() {
- currentLevelEntries.clear();
- for(LogItem li: allEntries) {
- if (li.getVerbosityLevel() <= mLogLevel ||
- mLogLevel == VpnProfile.MAXLOGLEVEL)
- currentLevelEntries.add(li);
- }
- }
-
- /**
- *
- * @param logmessage
- * @return True if the current entries have changed
- */
- private boolean addLogMessage(LogItem logmessage) {
- allEntries.add(logmessage);
-
- if (allEntries.size() > MAX_STORED_LOG_ENTRIES) {
- Vector<LogItem> oldAllEntries = allEntries;
- allEntries = new Vector<LogItem>(allEntries.size());
- for (int i=50;i<oldAllEntries.size();i++) {
- allEntries.add(oldAllEntries.elementAt(i));
- }
- initCurrentMessages();
- return true;
- } else {
- if (logmessage.getVerbosityLevel() <= mLogLevel) {
- currentLevelEntries.add(logmessage);
- return true;
- } else {
- return false;
- }
- }
- }
-
- void clearLog() {
- // Actually is probably called from GUI Thread as result of the user
- // pressing a button. But better safe than sorry
- VpnStatus.clearLog();
- VpnStatus.logInfo(R.string.logCleared);
- mHandler.sendEmptyMessage(MESSAGE_CLEARLOG);
- }
-
-
-
- public void setTimeFormat(int newTimeFormat) {
- mTimeFormat= newTimeFormat;
- mHandler.sendEmptyMessage(MESSAGE_NEWTS);
- }
-
- public void setLogLevel(int logLevel) {
- mLogLevel = logLevel;
- mHandler.sendEmptyMessage(MESSAGE_NEWLOGLEVEL);
- }
-
- }
-
-
-
- private LogWindowListAdapter ladapter;
- private TextView mSpeedView;
-
-
-
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if(item.getItemId()==R.id.clearlog) {
- ladapter.clearLog();
- return true;
- } else if(item.getItemId()==R.id.cancel){
- Intent intent = new Intent(getActivity(),DisconnectVPN.class);
- startActivity(intent);
- return true;
- } else if(item.getItemId()==R.id.send) {
- ladapter.shareLog();
- } else if(item.getItemId()==R.id.edit_vpn) {
- VpnProfile lastConnectedprofile = ProfileManager.getLastConnectedVpn();
-
- if(lastConnectedprofile!=null) {
- Intent vprefintent = new Intent(getActivity(),VPNPreferences.class)
- .putExtra(VpnProfile.EXTRA_PROFILEUUID,lastConnectedprofile.getUUIDString());
- startActivityForResult(vprefintent,START_VPN_CONFIG);
- } else {
- Toast.makeText(getActivity(), R.string.log_no_last_vpn, Toast.LENGTH_LONG).show();
- }
- } else if(item.getItemId() == R.id.toggle_time) {
- showHideOptionsPanel();
- } else if(item.getItemId() == android.R.id.home) {
- // This is called when the Home (Up) button is pressed
- // in the Action Bar.
- Intent parentActivityIntent = new Intent(getActivity(), MainActivity.class);
- parentActivityIntent.addFlags(
- Intent.FLAG_ACTIVITY_CLEAR_TOP |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(parentActivityIntent);
- getActivity().finish();
- return true;
-
- }
- return super.onOptionsItemSelected(item);
-
- }
-
- private void showHideOptionsPanel() {
- boolean optionsVisible = (mOptionsLayout.getVisibility() != View.GONE);
-
- ObjectAnimator anim;
- if (optionsVisible) {
- anim = ObjectAnimator.ofFloat(mOptionsLayout,"alpha",1.0f, 0f);
- anim.addListener(collapseListener);
-
- } else {
- mOptionsLayout.setVisibility(View.VISIBLE);
- anim = ObjectAnimator.ofFloat(mOptionsLayout,"alpha", 0f, 1.0f);
- //anim = new TranslateAnimation(0.0f, 0.0f, mOptionsLayout.getHeight(), 0.0f);
-
- }
-
- //anim.setInterpolator(new AccelerateInterpolator(1.0f));
- //anim.setDuration(300);
- //mOptionsLayout.startAnimation(anim);
- anim.start();
-
- }
-
- AnimatorListenerAdapter collapseListener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animator) {
- mOptionsLayout.setVisibility(View.GONE);
- }
-
- };
-
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- inflater.inflate(R.menu.logmenu, menu);
- if (getResources().getBoolean(R.bool.logSildersAlwaysVisible))
- menu.removeItem(R.id.toggle_time);
- }
-
-
- @Override
- public void onResume() {
- super.onResume();
- VpnStatus.addStateListener(this);
- VpnStatus.addByteCountListener(this);
- Intent intent = new Intent(getActivity(), OpenVpnService.class);
- intent.setAction(OpenVpnService.START_SERVICE);
-
- getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
-
-
-
- }
-
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == START_VPN_CONFIG && resultCode== Activity.RESULT_OK) {
- String configuredVPN = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID);
-
- final VpnProfile profile = ProfileManager.get(getActivity(),configuredVPN);
- ProfileManager.getInstance(getActivity()).saveProfile(getActivity(), profile);
- // Name could be modified, reset List adapter
-
- AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
- dialog.setTitle(R.string.configuration_changed);
- dialog.setMessage(R.string.restart_vpn_after_change);
-
-
- dialog.setPositiveButton(R.string.restart,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Intent intent = new Intent(getActivity(), LaunchVPN.class);
- intent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUIDString());
- intent.setAction(Intent.ACTION_MAIN);
- startActivity(intent);
- }
-
-
- });
- dialog.setNegativeButton(R.string.ignore, null);
- dialog.create().show();
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- @Override
- public void onStop() {
- super.onStop();
- VpnStatus.removeStateListener(this);
- VpnStatus.removeByteCountListener(this);
-
- if(mService!=null)
- getActivity().unbindService(mConnection);
- getActivity().getPreferences(0).edit().putInt(LOGTIMEFORMAT, ladapter.mTimeFormat)
- .putInt(VERBOSITYLEVEL, ladapter.mLogLevel).apply();
-
- }
-
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- ListView lv = getListView();
-
- lv.setOnItemLongClickListener(new OnItemLongClickListener() {
-
- @Override
- public boolean onItemLongClick(AdapterView<?> parent, View view,
- int position, long id) {
- ClipboardManager clipboard = (ClipboardManager)
- getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
- ClipData clip = ClipData.newPlainText("Log Entry",((TextView) view).getText());
- clipboard.setPrimaryClip(clip);
- Toast.makeText(getActivity(), R.string.copied_entry, Toast.LENGTH_SHORT).show();
- return true;
- }
- });
- }
-
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View v = inflater.inflate(R.layout.log_fragment, container, false);
-
- setHasOptionsMenu(true);
-
- ladapter = new LogWindowListAdapter();
- ladapter.mTimeFormat = getActivity().getPreferences(0).getInt(LOGTIMEFORMAT, 0);
- int logLevel = getActivity().getPreferences(0).getInt(VERBOSITYLEVEL, 0);
- ladapter.setLogLevel(logLevel);
-
- setListAdapter(ladapter);
-
- mTimeRadioGroup = (RadioGroup) v.findViewById(R.id.timeFormatRadioGroup);
- mTimeRadioGroup.setOnCheckedChangeListener(this);
-
- if(ladapter.mTimeFormat== LogWindowListAdapter.TIME_FORMAT_ISO) {
- mTimeRadioGroup.check(R.id.radioISO);
- } else if (ladapter.mTimeFormat == LogWindowListAdapter.TIME_FORMAT_NONE) {
- mTimeRadioGroup.check(R.id.radioNone);
- } else if (ladapter.mTimeFormat == LogWindowListAdapter.TIME_FORMAT_SHORT) {
- mTimeRadioGroup.check(R.id.radioShort);
- }
-
- mSpeedView = (TextView) v.findViewById(R.id.speed);
-
- mOptionsLayout = (LinearLayout) v.findViewById(R.id.logOptionsLayout);
- mLogLevelSlider = (SeekBar) v.findViewById(R.id.LogLevelSlider);
- mLogLevelSlider.setMax(VpnProfile.MAXLOGLEVEL-1);
- mLogLevelSlider.setProgress(logLevel-1);
-
- mLogLevelSlider.setOnSeekBarChangeListener(this);
-
- if(getResources().getBoolean(R.bool.logSildersAlwaysVisible))
- mOptionsLayout.setVisibility(View.VISIBLE);
-
- mUpStatus = (TextView) v.findViewById(R.id.speedUp);
- mDownStatus = (TextView) v.findViewById(R.id.speedDown);
- mConnectStatus = (TextView) v.findViewById(R.id.speedStatus);
- if (mShowOptionsLayout)
- mOptionsLayout.setVisibility(View.VISIBLE);
- return v;
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- if(getResources().getBoolean(R.bool.logSildersAlwaysVisible)) {
- mShowOptionsLayout=true;
- if (mOptionsLayout!= null)
- mOptionsLayout.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- //getActionBar().setDisplayHomeAsUpEnabled(true);
-
- }
-
-
- @Override
- public void updateState(final String status, final String logMessage, final int resId, final ConnectionStatus level) {
- if (isAdded()) {
- getActivity().runOnUiThread(new Runnable() {
-
- @Override
- public void run() {
- String prefix = getString(resId) + ":";
- if (status.equals("BYTECOUNT") || status.equals("NOPROCESS"))
- prefix = "";
- if (resId == R.string.unknown_state)
- prefix += status;
- if (mSpeedView != null)
- mSpeedView.setText(prefix + logMessage);
-
- if (mConnectStatus != null)
- mConnectStatus.setText(getString(resId));
- }
- });
- }
- }
-
-
- @Override
- public void onDestroy() {
- VpnStatus.removeLogListener(ladapter);
- super.onDestroy();
- }
-
-}
diff --git a/src/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java b/src/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java
deleted file mode 100644
index f23a50db..00000000
--- a/src/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.os.Bundle;
-import android.preference.PreferenceFragment;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-import de.blinkt.openvpn.core.ProfileManager;
-
-public abstract class OpenVpnPreferencesFragment extends PreferenceFragment {
-
- protected VpnProfile mProfile;
-
- protected abstract void loadSettings();
- protected abstract void saveSettings();
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- String profileUUID = getArguments().getString(getActivity().getPackageName() + ".profileUUID");
- mProfile = ProfileManager.get(getActivity(),profileUUID);
- getActivity().setTitle(getString(R.string.edit_profile_title, mProfile.getName()));
-
- }
-
- @Override
- public void onPause() {
- super.onPause();
- saveSettings();
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- if(savedInstanceState!=null) {
- String profileUUID=savedInstanceState.getString(VpnProfile.EXTRA_PROFILEUUID);
- mProfile = ProfileManager.get(getActivity(),profileUUID);
- loadSettings();
- }
- }
-
- @Override
- public void onSaveInstanceState (Bundle outState) {
- super.onSaveInstanceState(outState);
- saveSettings();
- outState.putString(VpnProfile.EXTRA_PROFILEUUID, mProfile.getUUIDString());
- }
-}
diff --git a/src/de/blinkt/openvpn/fragments/SendDumpFragment.java b/src/de/blinkt/openvpn/fragments/SendDumpFragment.java
deleted file mode 100644
index d43f6427..00000000
--- a/src/de/blinkt/openvpn/fragments/SendDumpFragment.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import java.io.File;
-import java.util.ArrayList;
-
-import android.app.Fragment;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.Uri;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.core.VpnStatus;
-
-public class SendDumpFragment extends Fragment {
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
-
- View v = inflater.inflate(R.layout.fragment_senddump, container, false);
- v.findViewById(R.id.senddump).setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- emailMiniDumps();
- }
- });
- return v;
- }
-
- public void emailMiniDumps()
- {
- //need to "send multiple" to get more than one attachment
- final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
- emailIntent.setType("*/*");
- emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
- new String[]{"Arne Schwabe <arne@rfc2549.org>"});
-
- String version;
- String name="ics-openvpn";
- try {
- PackageInfo packageinfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0);
- version = packageinfo.versionName;
- name = packageinfo.applicationInfo.name;
- } catch (NameNotFoundException e) {
- version = "error fetching version";
- }
-
-
- emailIntent.putExtra(Intent.EXTRA_SUBJECT, String.format("%s %s Minidump",name,version));
-
- emailIntent.putExtra(Intent.EXTRA_TEXT, "Please describe the issue you have experienced");
-
- ArrayList<Uri> uris = new ArrayList<Uri>();
-
- File ldump = getLastestDump(getActivity());
- if(ldump==null) {
- VpnStatus.logError("No Minidump found!");
- }
-
- uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/" + ldump.getName()));
- uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/" + ldump.getName() + ".log"));
-
- emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
- startActivity(emailIntent);
- }
-
- static public File getLastestDump(Context c) {
- long newestDumpTime=0;
- File newestDumpFile=null;
-
- for(File f:c.getCacheDir().listFiles()) {
- if(!f.getName().endsWith(".dmp"))
- continue;
-
- if (newestDumpTime < f.lastModified()) {
- newestDumpTime = f.lastModified();
- newestDumpFile=f;
- }
- }
- // Ignore old dumps
- //if(System.currentTimeMillis() - 48 * 60 * 1000 > newestDumpTime )
- //return null;
-
- return newestDumpFile;
- }
-}
diff --git a/src/de/blinkt/openvpn/fragments/Settings_Authentication.java b/src/de/blinkt/openvpn/fragments/Settings_Authentication.java
deleted file mode 100644
index 236d7947..00000000
--- a/src/de/blinkt/openvpn/fragments/Settings_Authentication.java
+++ /dev/null
@@ -1,212 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Build;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.EditTextPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceChangeListener;
-import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.SwitchPreference;
-import android.util.Pair;
-import de.blinkt.openvpn.activities.FileSelect;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.core.VpnStatus;
-import de.blinkt.openvpn.views.RemoteCNPreference;
-import de.blinkt.openvpn.VpnProfile;
-
-import java.io.IOException;
-
-
-public class Settings_Authentication extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener, OnPreferenceClickListener {
- private static final int SELECT_TLS_FILE = 23223232;
- private static final int SELECT_TLS_FILE_KITKAT = SELECT_TLS_FILE +1;
- private CheckBoxPreference mExpectTLSCert;
- private CheckBoxPreference mCheckRemoteCN;
- private RemoteCNPreference mRemoteCN;
- private ListPreference mTLSAuthDirection;
- private Preference mTLSAuthFile;
- private SwitchPreference mUseTLSAuth;
- private EditTextPreference mCipher;
- private String mTlsAuthFileData;
- private EditTextPreference mAuth;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.vpn_authentification);
-
- mExpectTLSCert = (CheckBoxPreference) findPreference("remoteServerTLS");
- mCheckRemoteCN = (CheckBoxPreference) findPreference("checkRemoteCN");
- mRemoteCN = (RemoteCNPreference) findPreference("remotecn");
- mRemoteCN.setOnPreferenceChangeListener(this);
-
- mUseTLSAuth = (SwitchPreference) findPreference("useTLSAuth" );
- mTLSAuthFile = findPreference("tlsAuthFile");
- mTLSAuthDirection = (ListPreference) findPreference("tls_direction");
-
-
- mTLSAuthFile.setOnPreferenceClickListener(this);
-
- mCipher =(EditTextPreference) findPreference("cipher");
- mCipher.setOnPreferenceChangeListener(this);
-
- mAuth =(EditTextPreference) findPreference("auth");
- mAuth.setOnPreferenceChangeListener(this);
-
- loadSettings();
-
- }
-
- @Override
- protected void loadSettings() {
-
- mExpectTLSCert.setChecked(mProfile.mExpectTLSCert);
- mCheckRemoteCN.setChecked(mProfile.mCheckRemoteCN);
- mRemoteCN.setDN(mProfile.mRemoteCN);
- mRemoteCN.setAuthType(mProfile.mX509AuthType);
- onPreferenceChange(mRemoteCN,
- new Pair<Integer, String>(mProfile.mX509AuthType, mProfile.mRemoteCN));
-
- mUseTLSAuth.setChecked(mProfile.mUseTLSAuth);
- mTlsAuthFileData= mProfile.mTLSAuthFilename;
- setTlsAuthSummary(mTlsAuthFileData);
- mTLSAuthDirection.setValue(mProfile.mTLSAuthDirection);
- mCipher.setText(mProfile.mCipher);
- onPreferenceChange(mCipher, mProfile.mCipher);
- mAuth.setText(mProfile.mAuth);
- onPreferenceChange(mAuth, mProfile.mAuth);
-
- if (mProfile.mAuthenticationType == VpnProfile.TYPE_STATICKEYS) {
- mExpectTLSCert.setEnabled(false);
- mCheckRemoteCN.setEnabled(false);
- mUseTLSAuth.setChecked(true);
- } else {
- mExpectTLSCert.setEnabled(true);
- mCheckRemoteCN.setEnabled(true);
-
- }
- }
-
- @Override
- protected void saveSettings() {
- mProfile.mExpectTLSCert=mExpectTLSCert.isChecked();
- mProfile.mCheckRemoteCN=mCheckRemoteCN.isChecked();
- mProfile.mRemoteCN=mRemoteCN.getCNText();
- mProfile.mX509AuthType=mRemoteCN.getAuthtype();
-
- mProfile.mUseTLSAuth = mUseTLSAuth.isChecked();
- mProfile.mTLSAuthFilename = mTlsAuthFileData;
-
- if(mTLSAuthDirection.getValue()==null)
- mProfile.mTLSAuthDirection=null;
- else
- mProfile.mTLSAuthDirection = mTLSAuthDirection.getValue();
-
- if(mCipher.getText()==null)
- mProfile.mCipher=null;
- else
- mProfile.mCipher = mCipher.getText();
-
- if(mAuth.getText()==null)
- mProfile.mAuth = null;
- else
- mProfile.mAuth = mAuth.getText();
-
- }
-
-
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if(preference==mRemoteCN) {
- @SuppressWarnings("unchecked")
- int authtype = ((Pair<Integer, String>) newValue).first;
- @SuppressWarnings("unchecked")
- String dn = ((Pair<Integer, String>) newValue).second;
-
- if ("".equals(dn))
- preference.setSummary(getX509String(VpnProfile.X509_VERIFY_TLSREMOTE_RDN, mProfile.mServerName));
- else
- preference.setSummary(getX509String(authtype,dn));
-
- } else if (preference == mCipher || preference == mAuth) {
- preference.setSummary((CharSequence) newValue);
- }
- return true;
- }
- private CharSequence getX509String(int authtype, String dn) {
- String ret ="";
- switch (authtype) {
- case VpnProfile.X509_VERIFY_TLSREMOTE:
- case VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING:
- ret+="tls-remote ";
- break;
-
- case VpnProfile.X509_VERIFY_TLSREMOTE_DN:
- ret="dn: ";
- break;
-
- case VpnProfile.X509_VERIFY_TLSREMOTE_RDN:
- ret="rdn: ";
- break;
-
- case VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX:
- ret="rdn prefix: ";
- break;
- }
- return ret + dn;
- }
-
- void startFileDialog() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- Intent startFC = Utils.getFilePickerIntent (Utils.FileType.TLS_AUTH_FILE);
- startActivityForResult(startFC, SELECT_TLS_FILE_KITKAT);
- } else {
- Intent startFC = new Intent(getActivity(), FileSelect.class);
- startFC.putExtra(FileSelect.START_DATA, mTlsAuthFileData);
- startFC.putExtra(FileSelect.WINDOW_TITLE, R.string.tls_auth_file);
- startActivityForResult(startFC, SELECT_TLS_FILE);
- }
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- startFileDialog();
- return true;
-
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if(requestCode==SELECT_TLS_FILE && resultCode == Activity.RESULT_OK){
- String result = data.getStringExtra(FileSelect.RESULT_DATA);
- mTlsAuthFileData=result;
- setTlsAuthSummary(result);
- } else if (requestCode == SELECT_TLS_FILE_KITKAT && resultCode == Activity.RESULT_OK) {
- try {
- mTlsAuthFileData= Utils.getFilePickerResult(Utils.FileType.TLS_AUTH_FILE,data,getActivity());
- setTlsAuthSummary(mTlsAuthFileData);
- } catch (IOException e) {
- VpnStatus.logException(e);
- }
- }
- }
-
- private void setTlsAuthSummary(String result) {
- if(result==null)
- result = getString(R.string.no_certificate);
- if(result.startsWith(VpnProfile.INLINE_TAG))
- mTLSAuthFile.setSummary(R.string.inline_file_data);
- else if (result.startsWith(VpnProfile.DISPLAYNAME_TAG))
- mExpectTLSCert.setSummary(getString(R.string.imported_from_file, VpnProfile.getDisplayName(result)));
- else
- mTLSAuthFile.setSummary(result);
- }
-} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/fragments/Settings_Basic.java b/src/de/blinkt/openvpn/fragments/Settings_Basic.java
deleted file mode 100644
index 4145c65f..00000000
--- a/src/de/blinkt/openvpn/fragments/Settings_Basic.java
+++ /dev/null
@@ -1,360 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
-import android.app.Fragment;
-import android.content.ActivityNotFoundException;
-import android.content.Intent;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Handler.Callback;
-import android.os.Message;
-import android.security.KeyChain;
-import android.security.KeyChainAliasCallback;
-import android.security.KeyChainException;
-import android.util.SparseArray;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.ToggleButton;
-import de.blinkt.openvpn.views.FileSelectLayout;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-import de.blinkt.openvpn.R.id;
-import de.blinkt.openvpn.core.ProfileManager;
-import de.blinkt.openvpn.core.X509Utils;
-
-import java.security.cert.X509Certificate;
-
-public class Settings_Basic extends Fragment implements View.OnClickListener, OnItemSelectedListener, Callback, FileSelectLayout.FileSelectCallback {
- private static final int CHOOSE_FILE_OFFSET = 1000;
- private static final int UPDATE_ALIAS = 20;
-
- private TextView mServerAddress;
- private TextView mServerPort;
- private FileSelectLayout mClientCert;
- private FileSelectLayout mCaCert;
- private FileSelectLayout mClientKey;
- private TextView mAliasName;
- private TextView mAliasCertificate;
- private CheckBox mUseLzo;
- private ToggleButton mTcpUdp;
- private Spinner mType;
- private FileSelectLayout mpkcs12;
- private TextView mPKCS12Password;
- private Handler mHandler;
- private EditText mUserName;
- private EditText mPassword;
- private View mView;
- private VpnProfile mProfile;
- private EditText mProfileName;
- private EditText mKeyPassword;
-
- private SparseArray<FileSelectLayout> fileselects = new SparseArray<FileSelectLayout>();
-
-
-
- private void addFileSelectLayout (FileSelectLayout fsl, Utils.FileType type) {
- int i = fileselects.size() + CHOOSE_FILE_OFFSET;
- fileselects.put(i, fsl);
- fsl.setCaller(this, i, type);
- }
-
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- String profileUuid = getArguments().getString(getActivity().getPackageName() + ".profileUUID");
- mProfile=ProfileManager.get(getActivity(),profileUuid);
- getActivity().setTitle(getString(R.string.edit_profile_title, mProfile.getName()));
- }
-
-
- private void setKeystoreCertficate()
- {
- new Thread() {
- public void run() {
- String certstr="";
- try {
- X509Certificate cert = KeyChain.getCertificateChain(getActivity(), mProfile.mAlias)[0];
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
- {
- if (isInHardwareKeystore())
- certstr+=getString(R.string.hwkeychain);
- }
- }
-
- certstr+=X509Utils.getCertificateFriendlyName(cert);
- } catch (Exception e) {
- certstr="Could not get certificate from Keystore: " +e.getLocalizedMessage();
- }
-
- final String certStringCopy=certstr;
- getActivity().runOnUiThread(new Runnable() {
-
- @Override
- public void run() {
- mAliasCertificate.setText(certStringCopy);
- }
- });
-
- }
- }.start();
- }
-
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
- private boolean isInHardwareKeystore() throws KeyChainException, InterruptedException {
- String algorithm = KeyChain.getPrivateKey(getActivity(), mProfile.mAlias).getAlgorithm();
- return KeyChain.isBoundKeyAlgorithm(algorithm);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
-
- mView = inflater.inflate(R.layout.basic_settings,container,false);
-
- mProfileName = (EditText) mView.findViewById(R.id.profilename);
- mServerAddress = (TextView) mView.findViewById(R.id.address);
- mServerPort = (TextView) mView.findViewById(R.id.port);
- mClientCert = (FileSelectLayout) mView.findViewById(R.id.certselect);
- mClientKey = (FileSelectLayout) mView.findViewById(R.id.keyselect);
- mCaCert = (FileSelectLayout) mView.findViewById(R.id.caselect);
- mpkcs12 = (FileSelectLayout) mView.findViewById(R.id.pkcs12select);
- mUseLzo = (CheckBox) mView.findViewById(R.id.lzo);
- mTcpUdp = (ToggleButton) mView.findViewById(id.tcpudp);
- mType = (Spinner) mView.findViewById(R.id.type);
- mPKCS12Password = (TextView) mView.findViewById(R.id.pkcs12password);
- mAliasName = (TextView) mView.findViewById(R.id.aliasname);
- mAliasCertificate = (TextView) mView.findViewById(id.alias_certificate);
-
- mUserName = (EditText) mView.findViewById(R.id.auth_username);
- mPassword = (EditText) mView.findViewById(R.id.auth_password);
- mKeyPassword = (EditText) mView.findViewById(R.id.key_password);
-
- addFileSelectLayout(mCaCert, Utils.FileType.CA_CERTIFICATE);
- addFileSelectLayout(mClientCert, Utils.FileType.CLIENT_CERTIFICATE);
- addFileSelectLayout(mClientKey, Utils.FileType.KEYFILE);
- addFileSelectLayout(mpkcs12, Utils.FileType.PKCS12);
- mCaCert.setShowClear();
-
- mType.setOnItemSelectedListener(this);
-
- mView.findViewById(R.id.select_keystore_button).setOnClickListener(this);
-
-
- if (mHandler == null) {
- mHandler = new Handler(this);
- }
-
- return mView;
- }
-
-
- @Override
- public void onStart() {
- super.onStart();
- String profileUuid =getArguments().getString(getActivity().getPackageName() + ".profileUUID");
- mProfile=ProfileManager.get(getActivity(),profileUuid);
- loadPreferences();
-
- }
-
- @Override
- public void onActivityResult(int request, int result, Intent data) {
- if (result == Activity.RESULT_OK && request >= CHOOSE_FILE_OFFSET) {
-
- FileSelectLayout fsl = fileselects.get(request);
- fsl.parseResponse(data, getActivity());
-
- savePreferences();
-
- // Private key files may result in showing/hiding the private key password dialog
- if(fsl==mClientKey) {
- changeType(mType.getSelectedItemPosition());
- }
- }
-
- }
-
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- if (parent == mType) {
- changeType(position);
- }
- }
- @Override
- public void onPause() {
- super.onPause();
- savePreferences();
- }
-
-
-
- private void changeType(int type){
- // hide everything
- mView.findViewById(R.id.pkcs12).setVisibility(View.GONE);
- mView.findViewById(R.id.certs).setVisibility(View.GONE);
- mView.findViewById(R.id.statickeys).setVisibility(View.GONE);
- mView.findViewById(R.id.keystore).setVisibility(View.GONE);
- mView.findViewById(R.id.cacert).setVisibility(View.GONE);
- mView.findViewById(R.id.userpassword).setVisibility(View.GONE);
- mView.findViewById(R.id.key_password_layout).setVisibility(View.GONE);
-
- // Fall through are by design
- switch(type) {
- case VpnProfile.TYPE_USERPASS_CERTIFICATES:
- mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
- case VpnProfile.TYPE_CERTIFICATES:
- mView.findViewById(R.id.certs).setVisibility(View.VISIBLE);
- mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE);
- if(mProfile.requireTLSKeyPassword())
- mView.findViewById(R.id.key_password_layout).setVisibility(View.VISIBLE);
- break;
-
- case VpnProfile.TYPE_USERPASS_PKCS12:
- mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
- case VpnProfile.TYPE_PKCS12:
- mView.findViewById(R.id.pkcs12).setVisibility(View.VISIBLE);
- break;
-
- case VpnProfile.TYPE_STATICKEYS:
- mView.findViewById(R.id.statickeys).setVisibility(View.VISIBLE);
- break;
-
- case VpnProfile.TYPE_USERPASS_KEYSTORE:
- mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
- case VpnProfile.TYPE_KEYSTORE:
- mView.findViewById(R.id.keystore).setVisibility(View.VISIBLE);
- mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE);
- break;
-
- case VpnProfile.TYPE_USERPASS:
- mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
- mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE);
- break;
- }
-
-
- }
-
- private void loadPreferences() {
- mProfileName.setText(mProfile.mName);
- mClientCert.setData(mProfile.mClientCertFilename, getActivity());
- mClientKey.setData(mProfile.mClientKeyFilename, getActivity());
- mCaCert.setData(mProfile.mCaFilename, getActivity());
-
- mUseLzo.setChecked(mProfile.mUseLzo);
- mServerPort.setText(mProfile.mServerPort);
- mServerAddress.setText(mProfile.mServerName);
- mTcpUdp.setChecked(mProfile.mUseUdp);
- mType.setSelection(mProfile.mAuthenticationType);
- mpkcs12.setData(mProfile.mPKCS12Filename, getActivity());
- mPKCS12Password.setText(mProfile.mPKCS12Password);
- mUserName.setText(mProfile.mUsername);
- mPassword.setText(mProfile.mPassword);
- mKeyPassword.setText(mProfile.mKeyPassword);
-
- setAlias();
-
- }
-
- void savePreferences() {
-
- mProfile.mName = mProfileName.getText().toString();
- mProfile.mCaFilename = mCaCert.getData();
- mProfile.mClientCertFilename = mClientCert.getData();
- mProfile.mClientKeyFilename = mClientKey.getData();
-
- mProfile.mUseLzo = mUseLzo.isChecked();
- mProfile.mServerPort =mServerPort.getText().toString();
- mProfile.mServerName = mServerAddress.getText().toString();
- mProfile.mUseUdp = mTcpUdp.isChecked();
-
- mProfile.mAuthenticationType = mType.getSelectedItemPosition();
- mProfile.mPKCS12Filename = mpkcs12.getData();
- mProfile.mPKCS12Password = mPKCS12Password.getText().toString();
-
- mProfile.mPassword = mPassword.getText().toString();
- mProfile.mUsername = mUserName.getText().toString();
- mProfile.mKeyPassword = mKeyPassword.getText().toString();
-
- }
-
-
- private void setAlias() {
- if(mProfile.mAlias == null) {
- mAliasName.setText(R.string.client_no_certificate);
- mAliasCertificate.setText("");
- } else {
- mAliasCertificate.setText("Loading certificate from Keystore...");
- mAliasName.setText(mProfile.mAlias);
- setKeystoreCertficate();
- }
- }
-
- public void showCertDialog () {
- try {
- KeyChain.choosePrivateKeyAlias(getActivity(),
- new KeyChainAliasCallback() {
-
- public void alias(String alias) {
- // Credential alias selected. Remember the alias selection for future use.
- mProfile.mAlias=alias;
- mHandler.sendEmptyMessage(UPDATE_ALIAS);
- }
-
-
- },
- new String[] {"RSA"}, // List of acceptable key types. null for any
- null, // issuer, null for any
- mProfile.mServerName, // host name of server requesting the cert, null if unavailable
- -1, // port of server requesting the cert, -1 if unavailable
- mProfile.mAlias); // alias to preselect, null if unavailable
- } catch (ActivityNotFoundException anf) {
- Builder ab = new AlertDialog.Builder(getActivity());
- ab.setTitle(R.string.broken_image_cert_title);
- ab.setMessage(R.string.broken_image_cert);
- ab.setPositiveButton(android.R.string.ok, null);
- ab.show();
- }
- }
-
- @Override
- public void onClick(View v) {
- if (v == mView.findViewById(R.id.select_keystore_button)) {
- showCertDialog();
- }
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- savePreferences();
- if(mProfile!=null) {
- outState.putString(getActivity().getPackageName() + "profileUUID", mProfile.getUUID().toString());
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- }
-
-
- @Override
- public boolean handleMessage(Message msg) {
- setAlias();
- return true;
- }
-
-
-}
diff --git a/src/de/blinkt/openvpn/fragments/Settings_IP.java b/src/de/blinkt/openvpn/fragments/Settings_IP.java
deleted file mode 100644
index 16e3a5c4..00000000
--- a/src/de/blinkt/openvpn/fragments/Settings_IP.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package de.blinkt.openvpn.fragments;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.EditTextPreference;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceChangeListener;
-import android.preference.PreferenceManager;
-import android.preference.SwitchPreference;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-
-public class Settings_IP extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener {
- private EditTextPreference mIPv4;
- private EditTextPreference mIPv6;
- private SwitchPreference mUsePull;
- private CheckBoxPreference mOverrideDNS;
- private EditTextPreference mSearchdomain;
- private EditTextPreference mDNS1;
- private EditTextPreference mDNS2;
- private CheckBoxPreference mNobind;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
-
- // Make sure default values are applied. In a real app, you would
- // want this in a shared function that is used to retrieve the
- // SharedPreferences wherever they are needed.
- PreferenceManager.setDefaultValues(getActivity(),
- R.xml.vpn_ipsettings, false);
-
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.vpn_ipsettings);
- mIPv4 = (EditTextPreference) findPreference("ipv4_address");
- mIPv6 = (EditTextPreference) findPreference("ipv6_address");
- mUsePull = (SwitchPreference) findPreference("usePull");
- mOverrideDNS = (CheckBoxPreference) findPreference("overrideDNS");
- mSearchdomain =(EditTextPreference) findPreference("searchdomain");
- mDNS1 = (EditTextPreference) findPreference("dns1");
- mDNS2 = (EditTextPreference) findPreference("dns2");
- mNobind = (CheckBoxPreference) findPreference("nobind");
-
- mIPv4.setOnPreferenceChangeListener(this);
- mIPv6.setOnPreferenceChangeListener(this);
- mDNS1.setOnPreferenceChangeListener(this);
- mDNS2.setOnPreferenceChangeListener(this);
- mUsePull.setOnPreferenceChangeListener(this);
- mOverrideDNS.setOnPreferenceChangeListener(this);
- mSearchdomain.setOnPreferenceChangeListener(this);
-
- loadSettings();
- }
-
- @Override
- protected void loadSettings() {
-
- mUsePull.setChecked(mProfile.mUsePull);
- mIPv4.setText(mProfile.mIPv4Address);
- mIPv6.setText(mProfile.mIPv6Address);
- mDNS1.setText(mProfile.mDNS1);
- mDNS2.setText(mProfile.mDNS2);
- mOverrideDNS.setChecked(mProfile.mOverrideDNS);
- mSearchdomain.setText(mProfile.mSearchDomain);
- mNobind.setChecked(mProfile.mNobind);
- if (mProfile.mAuthenticationType == VpnProfile.TYPE_STATICKEYS)
- mUsePull.setChecked(false);
-
- // Sets Summary
- onPreferenceChange(mIPv4, mIPv4.getText());
- onPreferenceChange(mIPv6, mIPv6.getText());
- onPreferenceChange(mDNS1, mDNS1.getText());
- onPreferenceChange(mDNS2, mDNS2.getText());
- onPreferenceChange(mSearchdomain, mSearchdomain.getText());
-
- setDNSState();
- }
-
-
- @Override
- protected void saveSettings() {
- mProfile.mUsePull = mUsePull.isChecked();
- mProfile.mIPv4Address = mIPv4.getText();
- mProfile.mIPv6Address = mIPv6.getText();
- mProfile.mDNS1 = mDNS1.getText();
- mProfile.mDNS2 = mDNS2.getText();
- mProfile.mOverrideDNS = mOverrideDNS.isChecked();
- mProfile.mSearchDomain = mSearchdomain.getText();
- mProfile.mNobind = mNobind.isChecked();
-
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference,
- Object newValue) {
- if(preference==mIPv4 || preference == mIPv6
- || preference==mDNS1 || preference == mDNS2
- || preference == mSearchdomain
- )
-
- preference.setSummary((String)newValue);
-
- if(preference== mUsePull || preference == mOverrideDNS)
- if(preference==mOverrideDNS) {
- // Set so the function gets the right value
- mOverrideDNS.setChecked((Boolean) newValue);
- }
- setDNSState();
-
- saveSettings();
- return true;
- }
-
- private void setDNSState() {
- boolean enabled;
- mOverrideDNS.setEnabled(mUsePull.isChecked());
- if(!mUsePull.isChecked())
- enabled =true;
- else
- enabled = mOverrideDNS.isChecked();
-
- mDNS1.setEnabled(enabled);
- mDNS2.setEnabled(enabled);
- mSearchdomain.setEnabled(enabled);
-
-
- }
-
-
- } \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/fragments/Settings_Obscure.java b/src/de/blinkt/openvpn/fragments/Settings_Obscure.java
deleted file mode 100644
index 0e8f1a02..00000000
--- a/src/de/blinkt/openvpn/fragments/Settings_Obscure.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.EditTextPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceChangeListener;
-import de.blinkt.openvpn.R;
-
-public class Settings_Obscure extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener {
- private CheckBoxPreference mUseRandomHostName;
- private CheckBoxPreference mUseFloat;
- private CheckBoxPreference mUseCustomConfig;
- private EditTextPreference mCustomConfig;
- private ListPreference mLogverbosity;
- private CheckBoxPreference mPersistent;
- private ListPreference mConnectretrymax;
- private EditTextPreference mConnectretry;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.vpn_obscure);
-
- mUseRandomHostName = (CheckBoxPreference) findPreference("useRandomHostname");
- mUseFloat = (CheckBoxPreference) findPreference("useFloat");
- mUseCustomConfig = (CheckBoxPreference) findPreference("enableCustomOptions");
- mCustomConfig = (EditTextPreference) findPreference("customOptions");
- mPersistent = (CheckBoxPreference) findPreference("usePersistTun");
- mConnectretrymax = (ListPreference) findPreference("connectretrymax");
- mConnectretry = (EditTextPreference) findPreference("connectretry");
-
- mConnectretrymax.setOnPreferenceChangeListener(this);
- mConnectretrymax.setSummary("%s");
-
- mConnectretry.setOnPreferenceChangeListener(this);
-
-
- loadSettings();
-
- }
-
- protected void loadSettings() {
- mUseRandomHostName.setChecked(mProfile.mUseRandomHostname);
- mUseFloat.setChecked(mProfile.mUseFloat);
- mUseCustomConfig.setChecked(mProfile.mUseCustomConfig);
- mCustomConfig.setText(mProfile.mCustomConfigOptions);
- mPersistent.setChecked(mProfile.mPersistTun);
-
- mConnectretrymax.setValue(mProfile.mConnectRetryMax);
- onPreferenceChange(mConnectretrymax, mProfile.mConnectRetryMax);
-
- mConnectretry.setText(mProfile.mConnectRetry);
- onPreferenceChange(mConnectretry, mProfile.mConnectRetry);
- }
-
-
- protected void saveSettings() {
- mProfile.mUseRandomHostname = mUseRandomHostName.isChecked();
- mProfile.mUseFloat = mUseFloat.isChecked();
- mProfile.mUseCustomConfig = mUseCustomConfig.isChecked();
- mProfile.mCustomConfigOptions = mCustomConfig.getText();
- mProfile.mConnectRetryMax = mConnectretrymax.getValue();
- mProfile.mPersistTun = mPersistent.isChecked();
- mProfile.mConnectRetry = mConnectretry.getText();
- }
-
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference == mConnectretrymax) {
- if(newValue==null) {
- newValue="5";
- }
- mConnectretrymax.setDefaultValue(newValue);
-
- for(int i=0;i<mConnectretrymax.getEntryValues().length;i++){
- if(mConnectretrymax.getEntryValues().equals(newValue))
- mConnectretrymax.setSummary(mConnectretrymax.getEntries()[i]);
- }
-
- } else if (preference == mConnectretry) {
- if(newValue==null || newValue=="")
- newValue="5";
- mConnectretry.setSummary(String.format("%s s" , newValue));
- }
-
- return true;
- }
-
-} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/fragments/Settings_Routing.java b/src/de/blinkt/openvpn/fragments/Settings_Routing.java
deleted file mode 100644
index c6f0dcf8..00000000
--- a/src/de/blinkt/openvpn/fragments/Settings_Routing.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package de.blinkt.openvpn.fragments;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.EditTextPreference;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceChangeListener;
-import de.blinkt.openvpn.R;
-
-
-public class Settings_Routing extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener {
- private EditTextPreference mCustomRoutes;
- private CheckBoxPreference mUseDefaultRoute;
- private EditTextPreference mCustomRoutesv6;
- private CheckBoxPreference mUseDefaultRoutev6;
- private CheckBoxPreference mRouteNoPull;
- private CheckBoxPreference mLocalVPNAccess;
- private EditTextPreference mExcludedRoutes;
- private EditTextPreference mExcludedRoutesv6;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.vpn_routing);
- mCustomRoutes = (EditTextPreference) findPreference("customRoutes");
- mUseDefaultRoute = (CheckBoxPreference) findPreference("useDefaultRoute");
- mCustomRoutesv6 = (EditTextPreference) findPreference("customRoutesv6");
- mUseDefaultRoutev6 = (CheckBoxPreference) findPreference("useDefaultRoutev6");
- mExcludedRoutes = (EditTextPreference) findPreference("excludedRoutes");
- mExcludedRoutesv6 = (EditTextPreference) findPreference("excludedRoutesv6");
-
- mRouteNoPull = (CheckBoxPreference) findPreference("routenopull");
- mLocalVPNAccess = (CheckBoxPreference) findPreference("unblockLocal");
-
- mCustomRoutes.setOnPreferenceChangeListener(this);
- mCustomRoutesv6.setOnPreferenceChangeListener(this);
-
- loadSettings();
- }
-
- @Override
- protected void loadSettings() {
-
- mUseDefaultRoute.setChecked(mProfile.mUseDefaultRoute);
- mUseDefaultRoutev6.setChecked(mProfile.mUseDefaultRoutev6);
-
- mCustomRoutes.setText(mProfile.mCustomRoutes);
- mCustomRoutesv6.setText(mProfile.mCustomRoutesv6);
-
- mExcludedRoutes.setText(mProfile.mExcludedRoutes);
- mExcludedRoutes.setText(mProfile.mExcludedRoutesv6);
-
- mRouteNoPull.setChecked(mProfile.mRoutenopull);
- mLocalVPNAccess.setChecked(mProfile.mAllowLocalLAN);
-
- // Sets Summary
- onPreferenceChange(mCustomRoutes, mCustomRoutes.getText());
- onPreferenceChange(mCustomRoutesv6, mCustomRoutesv6.getText());
- mRouteNoPull.setEnabled(mProfile.mUsePull);
- }
-
-
- @Override
- protected void saveSettings() {
- mProfile.mUseDefaultRoute = mUseDefaultRoute.isChecked();
- mProfile.mUseDefaultRoutev6 = mUseDefaultRoutev6.isChecked();
- mProfile.mCustomRoutes = mCustomRoutes.getText();
- mProfile.mCustomRoutesv6 = mCustomRoutesv6.getText();
- mProfile.mRoutenopull = mRouteNoPull.isChecked();
- mProfile.mAllowLocalLAN =mLocalVPNAccess.isChecked();
- mProfile.mExcludedRoutes = mExcludedRoutes.getText();
- mProfile.mExcludedRoutesv6 = mExcludedRoutesv6.getText();
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference,
- Object newValue) {
- if( preference == mCustomRoutes || preference == mCustomRoutesv6
- || preference == mExcludedRoutes || preference == mExcludedRoutesv6)
- preference.setSummary((String)newValue);
-
- saveSettings();
- return true;
- }
-
-
-} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/fragments/ShowConfigFragment.java b/src/de/blinkt/openvpn/fragments/ShowConfigFragment.java
deleted file mode 100644
index bf673288..00000000
--- a/src/de/blinkt/openvpn/fragments/ShowConfigFragment.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.app.Fragment;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-import de.blinkt.openvpn.core.ProfileManager;
-
-
-public class ShowConfigFragment extends Fragment {
- private String configtext;
- public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
- {
- String profileUUID = getArguments().getString(getActivity().getPackageName() + ".profileUUID");
- final VpnProfile vp = ProfileManager.get(getActivity(),profileUUID);
- View v=inflater.inflate(R.layout.viewconfig, container,false);
- final TextView cv = (TextView) v.findViewById(R.id.configview);
-
- int check=vp.checkProfile(getActivity());
- if(check!=R.string.no_error_found) {
- cv.setText(check);
- configtext = getString(check);
- }
- else {
- // Run in own Thread since Keystore does not like to be queried from the main thread
-
- cv.setText("Generating config...");
- startGenConfig(vp, cv);
- }
- return v;
- }
-
- private void startGenConfig(final VpnProfile vp, final TextView cv) {
-
- new Thread() {
- public void run() {
- final String cfg=vp.getConfigFile(getActivity(),false);
- configtext= cfg;
- getActivity().runOnUiThread(new Runnable() {
-
- @Override
- public void run() {
- cv.setText(cfg);
- }
- });
-
-
- }
- }.start();
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- inflater.inflate(R.menu.configmenu, menu);
- }
-
- private void shareConfig() {
- Intent shareIntent = new Intent(Intent.ACTION_SEND);
- shareIntent.putExtra(Intent.EXTRA_TEXT, configtext);
- shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.export_config_title));
- shareIntent.setType("text/plain");
- startActivity(Intent.createChooser(shareIntent, "Export Configfile"));
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- final int itemId = item.getItemId();
- if (itemId == R.id.sendConfig) {
- shareConfig();
- return true;
- } else {
- return super.onOptionsItemSelected(item);
- }
- }
-}
diff --git a/src/de/blinkt/openvpn/fragments/Utils.java b/src/de/blinkt/openvpn/fragments/Utils.java
deleted file mode 100644
index 9117f158..00000000
--- a/src/de/blinkt/openvpn/fragments/Utils.java
+++ /dev/null
@@ -1,195 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Build;
-import android.provider.OpenableColumns;
-import android.util.Base64;
-import android.util.Log;
-import android.webkit.MimeTypeMap;
-import de.blinkt.openvpn.VpnProfile;
-import junit.framework.Assert;
-
-import java.io.*;
-import java.util.TreeSet;
-import java.util.Vector;
-
-public class Utils {
-
- @TargetApi(Build.VERSION_CODES.KITKAT)
- public static Intent getFilePickerIntent(FileType fileType) {
- Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT);
- i.addCategory(Intent.CATEGORY_OPENABLE);
- TreeSet<String> supportedMimeTypes = new TreeSet<String>();
- Vector<String> extensions = new Vector<String>();
-
- switch (fileType) {
- case PKCS12:
- i.setType("application/x-pkcs12");
- supportedMimeTypes.add("application/x-pkcs12");
- extensions.add("p12");
- extensions.add("pfx");
- break;
- case CLIENT_CERTIFICATE:
- case CA_CERTIFICATE:
- i.setType("application/x-pem-file");
- supportedMimeTypes.add("application/x-x509-ca-cert");
- supportedMimeTypes.add("application/x-x509-user-cert");
- supportedMimeTypes.add("application/x-pem-file");
- supportedMimeTypes.add("text/plain");
-
- extensions.add("pem");
- extensions.add("crt");
- break;
- case KEYFILE:
- i.setType("application/x-pem-file");
- supportedMimeTypes.add("application/x-pem-file");
- supportedMimeTypes.add("application/pkcs8");
-
- // Google drive ....
- supportedMimeTypes.add("application/x-iwork-keynote-sffkey");
- extensions.add("key");
- break;
-
- case TLS_AUTH_FILE:
- i.setType("text/plain");
-
- // Backup ....
- supportedMimeTypes.add("application/pkcs8");
- // Google Drive is kind of crazy .....
- supportedMimeTypes.add("application/x-iwork-keynote-sffkey");
-
- extensions.add("txt");
- extensions.add("key");
- break;
-
- case OVPN_CONFIG:
- i.setType("application/x-openvpn-profile");
- supportedMimeTypes.add("application/x-openvpn-profile");
- supportedMimeTypes.add("application/openvpn-profile");
- supportedMimeTypes.add("application/ovpn");
- supportedMimeTypes.add("text/plain");
- extensions.add("ovpn");
- extensions.add("conf");
- break;
-
- case USERPW_FILE:
- i.setType("text/plain");
- supportedMimeTypes.add("text/plain");
- break;
- }
-
- MimeTypeMap mtm = MimeTypeMap.getSingleton();
-
- for (String ext : extensions) {
- String mimeType = mtm.getMimeTypeFromExtension(ext);
- if (mimeType != null)
- supportedMimeTypes.add(mimeType);
- }
-
- // Always add this as fallback
- supportedMimeTypes.add("application/octet-stream");
-
- i.putExtra(Intent.EXTRA_MIME_TYPES, supportedMimeTypes.toArray(new String[supportedMimeTypes.size()]));
- return i;
- }
-
- public enum FileType {
- PKCS12(0),
- CLIENT_CERTIFICATE(1),
- CA_CERTIFICATE(2),
- OVPN_CONFIG(3),
- KEYFILE(4),
- TLS_AUTH_FILE(5),
- USERPW_FILE(6);
-
- private int value;
-
- FileType(int i) {
- value = i;
- }
-
- public static FileType getFileTypeByValue(int value) {
- switch (value) {
- case 0:
- return PKCS12;
- case 1:
- return CLIENT_CERTIFICATE;
- case 2:
- return CA_CERTIFICATE;
- case 3:
- return OVPN_CONFIG;
- case 4:
- return KEYFILE;
- case 5:
- return TLS_AUTH_FILE;
- case 6:
- return USERPW_FILE;
- default:
- return null;
- }
- }
-
- public int getValue() {
- return value;
- }
- }
-
- static private byte[] readBytesFromStream(InputStream input) throws IOException {
-
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-
- int nRead;
- byte[] data = new byte[16384];
-
- while ((nRead = input.read(data, 0, data.length)) != -1) {
- buffer.write(data, 0, nRead);
- }
-
- buffer.flush();
- input.close();
- return buffer.toByteArray();
- }
-
- public static String getFilePickerResult(FileType ft, Intent result, Context c) throws IOException {
-
- Uri uri = result.getData();
- if (uri == null)
- return null;
-
- byte[] fileData = readBytesFromStream(c.getContentResolver().openInputStream(uri));
- String newData = null;
-
- Cursor cursor = c.getContentResolver().query(uri, null, null, null, null);
-
- String prefix = "";
- try {
- if (cursor!=null && cursor.moveToFirst()) {
- int cidx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
- if (cidx != -1) {
- String displayName = cursor.getString(cidx);
-
- if (!displayName.contains(VpnProfile.INLINE_TAG) && !displayName.contains(VpnProfile.DISPLAYNAME_TAG))
- prefix = VpnProfile.DISPLAYNAME_TAG + displayName;
- }
- }
- } finally {
- if(cursor!=null)
- cursor.close();
- }
-
- switch (ft) {
- case PKCS12:
- newData = Base64.encodeToString(fileData, Base64.DEFAULT);
- break;
- default:
- newData = new String(fileData, "UTF-8");
- break;
- }
-
- return prefix + VpnProfile.INLINE_TAG + newData;
- }
-}
diff --git a/src/de/blinkt/openvpn/fragments/VPNProfileList.java b/src/de/blinkt/openvpn/fragments/VPNProfileList.java
deleted file mode 100644
index b26f3505..00000000
--- a/src/de/blinkt/openvpn/fragments/VPNProfileList.java
+++ /dev/null
@@ -1,346 +0,0 @@
-package de.blinkt.openvpn.fragments;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.ListFragment;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.text.Html;
-import android.text.Html.ImageGetter;
-import android.view.*;
-import android.view.View.OnClickListener;
-import android.webkit.MimeTypeMap;
-import android.widget.ArrayAdapter;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.Toast;
-import de.blinkt.openvpn.*;
-import de.blinkt.openvpn.activities.ConfigConverter;
-import de.blinkt.openvpn.activities.FileSelect;
-import de.blinkt.openvpn.activities.VPNPreferences;
-import de.blinkt.openvpn.core.ProfileManager;
-
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.TreeSet;
-
-public class VPNProfileList extends ListFragment {
-
- public final static int RESULT_VPN_DELETED = Activity.RESULT_FIRST_USER;
-
- private static final int MENU_ADD_PROFILE = Menu.FIRST;
-
- private static final int START_VPN_CONFIG = 92;
- private static final int SELECT_PROFILE = 43;
- private static final int IMPORT_PROFILE = 231;
- private static final int FILE_PICKER_RESULT = 392;
-
- private static final int MENU_IMPORT_PROFILE = Menu.FIRST +1;
-
-
- class VPNArrayAdapter extends ArrayAdapter<VpnProfile> {
-
- public VPNArrayAdapter(Context context, int resource,
- int textViewResourceId) {
- super(context, resource, textViewResourceId);
- }
-
- @Override
- public View getView(final int position, View convertView, ViewGroup parent) {
- View v = super.getView(position, convertView, parent);
-
- View titleview = v.findViewById(R.id.vpn_list_item_left);
- titleview.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- VpnProfile profile =(VpnProfile) getListAdapter().getItem(position);
- startVPN(profile);
- }
- });
-
- View settingsview = v.findViewById(R.id.quickedit_settings);
- settingsview.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- VpnProfile editProfile = (VpnProfile) getListAdapter().getItem(position);
- editVPN(editProfile);
-
- }
- });
-
- return v;
- }
- }
-
-
-
-
-
-
-
-
- private ArrayAdapter<VpnProfile> mArrayadapter;
-
- protected VpnProfile mEditProfile=null;
-
-
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
-
- }
-
-
- class MiniImageGetter implements ImageGetter {
-
-
- @Override
- public Drawable getDrawable(String source) {
- Drawable d=null;
- if ("ic_menu_add".equals(source))
- d = getActivity().getResources().getDrawable(android.R.drawable.ic_menu_add);
- else if("ic_menu_archive".equals(source))
- d = getActivity().getResources().getDrawable(R.drawable.ic_menu_archive);
-
-
-
- if(d!=null) {
- d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
- return d;
- }else{
- return null;
- }
- }
- }
-
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View v = inflater.inflate(R.layout.vpn_profile_list, container,false);
-
- TextView newvpntext = (TextView) v.findViewById(R.id.add_new_vpn_hint);
- TextView importvpntext = (TextView) v.findViewById(R.id.import_vpn_hint);
-
-
-
- newvpntext.setText(Html.fromHtml(getString(R.string.add_new_vpn_hint),new MiniImageGetter(),null));
- importvpntext.setText(Html.fromHtml(getString(R.string.vpn_import_hint),new MiniImageGetter(),null));
-
-
-
- return v;
-
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- setListAdapter();
- }
-
- static class VpnProfileNameComparator implements Comparator<VpnProfile> {
-
- @Override
- public int compare(VpnProfile lhs, VpnProfile rhs) {
- if (lhs == rhs)
- // Catches also both null
- return 0;
-
- if (lhs == null)
- return -1;
- if (rhs == null)
- return 1;
-
- if (lhs.mName == null)
- return -1;
- if (rhs.mName == null)
- return 1;
-
- return lhs.mName.compareTo(rhs.mName);
- }
-
- }
-
- private void setListAdapter() {
- mArrayadapter = new VPNArrayAdapter(getActivity(),R.layout.vpn_list_item,R.id.vpn_item_title);
- Collection<VpnProfile> allvpn = getPM().getProfiles();
-
- TreeSet<VpnProfile> sortedset = new TreeSet<VpnProfile>(new VpnProfileNameComparator());
- sortedset.addAll(allvpn);
- mArrayadapter.addAll(sortedset);
-
- setListAdapter(mArrayadapter);
- }
-
-
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- menu.add(0, MENU_ADD_PROFILE, 0 , R.string.menu_add_profile)
- .setIcon(android.R.drawable.ic_menu_add)
- .setAlphabeticShortcut('a')
- .setTitleCondensed(getActivity().getString(R.string.add))
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-
- menu.add(0, MENU_IMPORT_PROFILE, 0, R.string.menu_import)
- .setIcon(R.drawable.ic_menu_archive)
- .setAlphabeticShortcut('i')
- .setTitleCondensed(getActivity().getString(R.string.menu_import_short))
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT );
- }
-
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- final int itemId = item.getItemId();
- if (itemId == MENU_ADD_PROFILE) {
- onAddProfileClicked();
- return true;
- } else if (itemId == MENU_IMPORT_PROFILE) {
- if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
- startFilePicker();
- else
- startImportConfig();
-
- return true;
- } else {
- return super.onOptionsItemSelected(item);
- }
- }
-
- @TargetApi(Build.VERSION_CODES.KITKAT)
- private void startFilePicker() {
- Intent i = Utils.getFilePickerIntent(Utils.FileType.OVPN_CONFIG);
- startActivityForResult(i, FILE_PICKER_RESULT);
- }
-
- private void startImportConfig() {
- Intent intent = new Intent(getActivity(),FileSelect.class);
- intent.putExtra(FileSelect.NO_INLINE_SELECTION, true);
- intent.putExtra(FileSelect.WINDOW_TITLE, R.string.import_configuration_file);
- startActivityForResult(intent, SELECT_PROFILE);
- }
-
-
-
-
-
- private void onAddProfileClicked() {
- Context context = getActivity();
- if (context != null) {
- final EditText entry = new EditText(context);
- entry.setSingleLine();
-
- AlertDialog.Builder dialog = new AlertDialog.Builder(context);
- dialog.setTitle(R.string.menu_add_profile);
- dialog.setMessage(R.string.add_profile_name_prompt);
- dialog.setView(entry);
-
-
- dialog.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- String name = entry.getText().toString();
- if (getPM().getProfileByName(name)==null) {
- VpnProfile profile = new VpnProfile(name);
- addProfile(profile);
- editVPN(profile);
- } else {
- Toast.makeText(getActivity(), R.string.duplicate_profile_name, Toast.LENGTH_LONG).show();
- }
- }
-
-
- });
- dialog.setNegativeButton(android.R.string.cancel, null);
- dialog.create().show();
- }
-
- }
-
- private void addProfile(VpnProfile profile) {
- getPM().addProfile(profile);
- getPM().saveProfileList(getActivity());
- getPM().saveProfile(getActivity(),profile);
- mArrayadapter.add(profile);
- }
-
- private ProfileManager getPM() {
- return ProfileManager.getInstance(getActivity());
- }
-
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if(resultCode == RESULT_VPN_DELETED){
- if(mArrayadapter != null && mEditProfile !=null)
- mArrayadapter.remove(mEditProfile);
- }
-
- if(resultCode != Activity.RESULT_OK)
- return;
-
- if (requestCode == START_VPN_CONFIG) {
- String configuredVPN = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID);
-
- VpnProfile profile = ProfileManager.get(getActivity(),configuredVPN);
- getPM().saveProfile(getActivity(), profile);
- // Name could be modified, reset List adapter
- setListAdapter();
-
- } else if(requestCode== SELECT_PROFILE) {
- String fileData = data.getStringExtra(FileSelect.RESULT_DATA);
- Uri uri = new Uri.Builder().path(fileData).scheme("file").build();
-
- startConfigImport(uri);
- } else if(requestCode == IMPORT_PROFILE) {
- String profileUUID = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID);
- mArrayadapter.add(ProfileManager.get(getActivity(), profileUUID));
- } else if(requestCode == FILE_PICKER_RESULT) {
- if (data != null) {
- Uri uri = data.getData();
- startConfigImport(uri);
- }
- }
-
- }
-
- private void startConfigImport(Uri uri) {
- Intent startImport = new Intent(getActivity(),ConfigConverter.class);
- startImport.setAction(ConfigConverter.IMPORT_PROFILE);
- startImport.setData(uri);
- startActivityForResult(startImport, IMPORT_PROFILE);
- }
-
-
- private void editVPN(VpnProfile profile) {
- mEditProfile =profile;
- Intent vprefintent = new Intent(getActivity(),VPNPreferences.class)
- .putExtra(getActivity().getPackageName() + ".profileUUID", profile.getUUID().toString());
-
- startActivityForResult(vprefintent,START_VPN_CONFIG);
- }
-
- private void startVPN(VpnProfile profile) {
-
- getPM().saveProfile(getActivity(), profile);
-
- Intent intent = new Intent(getActivity(),LaunchVPN.class);
- intent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUID().toString());
- intent.setAction(Intent.ACTION_MAIN);
- startActivity(intent);
- }
-}
diff --git a/src/de/blinkt/openvpn/views/FileSelectLayout.java b/src/de/blinkt/openvpn/views/FileSelectLayout.java
deleted file mode 100644
index 362777e4..00000000
--- a/src/de/blinkt/openvpn/views/FileSelectLayout.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package de.blinkt.openvpn.views;
-
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-import de.blinkt.openvpn.activities.FileSelect;
-import de.blinkt.openvpn.core.VpnStatus;
-import de.blinkt.openvpn.core.X509Utils;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import de.blinkt.openvpn.fragments.Utils;
-
-import java.io.*;
-
-import static android.os.Build.*;
-
-
-public class FileSelectLayout extends LinearLayout implements OnClickListener {
-
- public void parseResponse(Intent data, Context c) {
- if (VERSION.SDK_INT < VERSION_CODES.KITKAT) {
- String fileData = data.getStringExtra(FileSelect.RESULT_DATA);
- setData(fileData, c);
- } else if (data != null) {
- try {
- String newData = Utils.getFilePickerResult(fileType, data, c);
- if (newData!=null)
- setData(newData, c);
-
- } catch (IOException e) {
- VpnStatus.logException(e);
- }
-
-
- }
- }
-
- public interface FileSelectCallback {
-
- String getString(int res);
-
- void startActivityForResult(Intent startFC, int mTaskId);
- }
-
- private boolean mIsCertificate;
- private TextView mDataView;
- private String mData;
- private FileSelectCallback mFragment;
- private int mTaskId;
- private Button mSelectButton;
- private Utils.FileType fileType;
- private String mTitle;
- private boolean mShowClear;
- private TextView mDataDetails;
-
- public FileSelectLayout(Context context, AttributeSet attrset) {
- super(context, attrset);
-
- TypedArray ta = context.obtainStyledAttributes(attrset, R.styleable.FileSelectLayout);
-
- setupViews(ta.getString(R.styleable.FileSelectLayout_title), ta.getBoolean(R.styleable.FileSelectLayout_certificate, true));
-
- ta.recycle();
- }
-
- public FileSelectLayout (Context context, String title, boolean isCerticate)
- {
- super(context);
-
- setupViews(title, isCerticate);
-
- }
-
- private void setupViews(String title, boolean isCertificate) {
- inflate(getContext(), R.layout.file_select, this);
-
- mTitle = title;
- mIsCertificate = isCertificate;
-
- TextView tview = (TextView) findViewById(R.id.file_title);
- tview.setText(mTitle);
-
- mDataView = (TextView) findViewById(R.id.file_selected_item);
- mDataDetails = (TextView) findViewById(R.id.file_selected_description);
- mSelectButton = (Button) findViewById(R.id.file_select_button);
- mSelectButton.setOnClickListener(this);
- }
-
-
- public void setCaller(FileSelectCallback fragment, int i, Utils.FileType ft) {
- mTaskId = i;
- mFragment = fragment;
- fileType = ft;
- }
-
- public void getCertificateFileDialog() {
- Intent startFC = new Intent(getContext(), FileSelect.class);
- startFC.putExtra(FileSelect.START_DATA, mData);
- startFC.putExtra(FileSelect.WINDOW_TITLE, mTitle);
- if (fileType == Utils.FileType.PKCS12)
- startFC.putExtra(FileSelect.DO_BASE64_ENCODE, true);
- if (mShowClear)
- startFC.putExtra(FileSelect.SHOW_CLEAR_BUTTON, true);
-
- mFragment.startActivityForResult(startFC, mTaskId);
- }
-
-
- public String getData() {
- return mData;
- }
-
- public void setData(String data, Context c) {
- mData = data;
- if (data == null) {
- mDataView.setText(c.getString(R.string.no_data));
- mDataDetails.setText("");
- } else {
- if (mData.startsWith(VpnProfile.DISPLAYNAME_TAG)) {
- mDataView.setText(c.getString(R.string.imported_from_file, VpnProfile.getDisplayName(mData)));
- } else if (mData.startsWith(VpnProfile.INLINE_TAG))
- mDataView.setText(R.string.inline_file_data);
- else
- mDataView.setText(data);
- if (mIsCertificate)
- mDataDetails.setText(X509Utils.getCertificateFriendlyName(c, data));
- }
-
- }
-
- @Override
- public void onClick(View v) {
- if (v == mSelectButton) {
- if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
- Intent startFilePicker = Utils.getFilePickerIntent(fileType);
- mFragment.startActivityForResult(startFilePicker, mTaskId);
- } else {
- getCertificateFileDialog();
- }
- }
- }
-
-
-
-
- public void setShowClear() {
- mShowClear = true;
- }
-
-}
diff --git a/src/de/blinkt/openvpn/views/RemoteCNPreference.java b/src/de/blinkt/openvpn/views/RemoteCNPreference.java
deleted file mode 100644
index 388f892b..00000000
--- a/src/de/blinkt/openvpn/views/RemoteCNPreference.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package de.blinkt.openvpn.views;
-
-import android.content.Context;
-import android.preference.DialogPreference;
-import android.util.AttributeSet;
-import android.util.Pair;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.EditText;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import de.blinkt.openvpn.R;
-import de.blinkt.openvpn.VpnProfile;
-
-public class RemoteCNPreference extends DialogPreference {
-
-
- private Spinner mSpinner;
- private EditText mEditText;
- private int mDNType;
- private String mDn;
- private TextView mRemoteTLSNote;
- //private ScrollView mScrollView;
-
- public RemoteCNPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- setDialogLayoutResource(R.layout.tlsremote);
-
- }
-
- @Override
- protected void onBindDialogView(View view) {
-
- super.onBindDialogView(view);
-
- mEditText = (EditText) view.findViewById(R.id.tlsremotecn);
- mSpinner = (Spinner) view.findViewById(R.id.x509verifytype);
- mRemoteTLSNote = (TextView) view.findViewById(R.id.tlsremotenote);
- //mScrollView = (ScrollView) view.findViewById(R.id.tlsremotescroll);
- if(mDn!=null)
- mEditText.setText(mDn);
-
- populateSpinner();
-
- }
-
-
-
- public String getCNText() {
- return mDn;
- }
-
- public int getAuthtype() {
- return mDNType;
- }
-
- public void setDN(String dn) {
- mDn = dn;
- if(mEditText!=null)
- mEditText.setText(dn);
- }
-
- public void setAuthType(int x509authtype) {
- mDNType = x509authtype;
- if (mSpinner!=null)
- populateSpinner();
- }
-
- @Override
- protected void onDialogClosed(boolean positiveResult) {
- super.onDialogClosed(positiveResult);
-
- if (positiveResult) {
- String dn = mEditText.getText().toString();
- int authtype = getAuthTypeFromSpinner();
- if (callChangeListener(new Pair<Integer, String>(authtype, dn))) {
- mDn = dn;
- mDNType = authtype;
- }
- }
- }
-
- private void populateSpinner() {
- ArrayAdapter<String> authtypes = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item);
- authtypes.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-
- authtypes.add(getContext().getString(R.string.complete_dn));
- authtypes.add(getContext().getString(R.string.rdn));
- authtypes.add(getContext().getString(R.string.rdn_prefix));
- if ((mDNType == VpnProfile.X509_VERIFY_TLSREMOTE || mDNType == VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING)
- && !(mDn==null || "".equals(mDn))) {
- authtypes.add(getContext().getString(R.string.tls_remote_deprecated));
- mRemoteTLSNote.setVisibility(View.VISIBLE);
- } else {
- mRemoteTLSNote.setVisibility(View.GONE);
- }
- mSpinner.setAdapter(authtypes);
- mSpinner.setSelection(getSpinnerPositionFromAuthTYPE());
- }
-
- private int getSpinnerPositionFromAuthTYPE() {
- switch (mDNType) {
- case VpnProfile.X509_VERIFY_TLSREMOTE_DN:
- return 0;
- case VpnProfile.X509_VERIFY_TLSREMOTE_RDN:
- return 1;
- case VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX:
- return 2;
- case VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING:
- case VpnProfile.X509_VERIFY_TLSREMOTE:
- if (mDn==null || "".equals(mDn))
- return 1;
- else
- return 3;
-
-
- default:
- return 0;
- }
- }
-
- private int getAuthTypeFromSpinner() {
- int pos = mSpinner.getSelectedItemPosition();
- switch (pos) {
- case 0:
- return VpnProfile.X509_VERIFY_TLSREMOTE_DN;
- case 1:
- return VpnProfile.X509_VERIFY_TLSREMOTE_RDN;
- case 2:
- return VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX;
- case 3:
- // This is the tls-remote entry, only visible if mDntype is a
- // tls-remote type
- return mDNType;
- default:
- return VpnProfile.X509_VERIFY_TLSREMOTE;
- }
- }
-
-}
diff --git a/src/de/blinkt/openvpn/views/SeekBarTicks.java b/src/de/blinkt/openvpn/views/SeekBarTicks.java
deleted file mode 100644
index 88e8e164..00000000
--- a/src/de/blinkt/openvpn/views/SeekBarTicks.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package de.blinkt.openvpn.views;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.ViewConfiguration;
-import android.widget.SeekBar;
-
-public class SeekBarTicks extends SeekBar {
- private Paint mTickPaint;
- private float mTickHeight;
-
- private float tickHeightRatio = 0.6f;
-
- public SeekBarTicks(Context context, AttributeSet attrs) {
- super (context, attrs);
-
- initTicks (context, attrs, android.R.attr.seekBarStyle);
- }
-
-
- public SeekBarTicks(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- initTicks (context, attrs, defStyle);
-
- /*mTickHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
- tickHeightDP,
- ctx.getResources().getDisplayMetrics()); */
- }
-
- private void initTicks(Context context, AttributeSet attrs, int defStyle) {
- TypedArray a = context.obtainStyledAttributes(attrs,
- new int[] { android.R.attr.secondaryProgress }, defStyle, 0);
-
-
- int tickColor = a.getColor(0, android.R.color.black);
- mTickPaint = new Paint();
- mTickPaint.setColor( context.getResources().getColor(tickColor));
- a.recycle();
- }
-
-
- @Override
- protected synchronized void onDraw(Canvas canvas) {
- drawTicks(canvas);
- super.onDraw(canvas);
- }
-
- private void drawTicks(Canvas canvas) {
-
- final int available = getWidth() - getPaddingLeft() - getPaddingRight();
- final int availableHeight = getHeight() - getPaddingBottom() - getPaddingTop();
-
- int extrapadding = (int) ((availableHeight- (availableHeight * tickHeightRatio))/2);
-
- int tickSpacing = available / (getMax() );
-
- for (int i = 1; i < getMax(); i++) {
- final float x = getPaddingLeft() + i * tickSpacing;
-
- canvas.drawLine(x, getPaddingTop()+extrapadding, x, getHeight()-getPaddingBottom()-extrapadding, mTickPaint);
- }
- }
-}