summaryrefslogtreecommitdiff
path: root/app/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main')
-rw-r--r--app/src/main/AndroidManifest.xml4
-rw-r--r--app/src/main/java/de/blinkt/openvpn/LaunchVPN.java1
-rw-r--r--app/src/main/java/de/blinkt/openvpn/VpnProfile.java16
-rw-r--r--app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java10
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java13
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java31
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java8
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java (renamed from app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java)97
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java4
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java786
-rw-r--r--app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/EIP.java8
-rwxr-xr-xapp/src/main/res/values-ca/strings-icsopenvpn.xml2
-rwxr-xr-xapp/src/main/res/values-de/strings-icsopenvpn.xml4
-rwxr-xr-xapp/src/main/res/values-es/strings-icsopenvpn.xml7
-rwxr-xr-xapp/src/main/res/values-fr/strings-icsopenvpn.xml3
-rwxr-xr-xapp/src/main/res/values-hu/strings.xml6
-rwxr-xr-xapp/src/main/res/values-in/strings.xml6
-rwxr-xr-xapp/src/main/res/values-ja/strings-icsopenvpn.xml2
-rwxr-xr-xapp/src/main/res/values-pl/strings.xml6
-rwxr-xr-xapp/src/main/res/values-pt/strings-icsopenvpn.xml139
-rwxr-xr-xapp/src/main/res/values-pt/strings.xml6
-rwxr-xr-xapp/src/main/res/values-ru/strings-icsopenvpn.xml7
-rwxr-xr-xapp/src/main/res/values-sv/strings.xml6
-rwxr-xr-xapp/src/main/res/values-tr/strings.xml6
-rwxr-xr-xapp/src/main/res/values/strings-icsopenvpn.xml7
-rw-r--r--app/src/main/res/values/untranslatable.xml1139
28 files changed, 1874 insertions, 460 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0c55bf78..1fb6ad73 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -36,8 +36,8 @@
android:label="@string/app" >
<service
- android:name="de.blinkt.openvpn.core.OpenVpnService"
- android:permission="android.permission.BIND_VPN_SERVICE" >
+ android:name="de.blinkt.openvpn.core.OpenVPNService"
+ android:permission="android.permission.BIND_VPN_SERVICE">
<intent-filter>
<action android:name="android.net.VpnService" />
</intent-filter>
diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
index 3f80eef0..a424a489 100644
--- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
+++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
@@ -113,6 +113,7 @@ public class LaunchVPN extends Activity {
}
}
+
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
index d44d0f5a..6fec5f46 100644
--- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
+++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
@@ -47,7 +47,7 @@ import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import de.blinkt.openvpn.core.NativeUtils;
-import de.blinkt.openvpn.core.OpenVpnService;
+import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.VpnStatus;
import de.blinkt.openvpn.core.X509Utils;
@@ -69,6 +69,7 @@ public class VpnProfile implements Serializable {
private static final String OVPNCONFIGFILE = "android.conf";
public static final int MAXLOGLEVEL = 4;
public static final int CURRENT_PROFILE_VERSION = 2;
+ public static final int DEFAULT_MSSFIX_SIZE = 1450;
public static String DEFAULT_DNS1 = "8.8.8.8";
public static String DEFAULT_DNS2 = "8.8.4.4";
@@ -147,6 +148,9 @@ public class VpnProfile implements Serializable {
private int mProfileVersion;
public String mExcludedRoutes;
public String mExcludedRoutesv6;
+ public int mMssFix =0; // -1 is default,
+
+
public VpnProfile(String name) {
mUuid = UUID.randomUUID();
@@ -186,6 +190,7 @@ public class VpnProfile implements Serializable {
mCheckRemoteCN = false;
mPersistTun = false;
mAllowLocalLAN = true;
+ mMssFix = 0;
}
public UUID getUUID() {
@@ -389,6 +394,13 @@ public class VpnProfile implements Serializable {
}
+ if (mMssFix !=0){
+ if (mMssFix!=1450)
+ cfg+=String.format("mssfix %d\n", mMssFix, Locale.US);
+ else
+ cfg+="mssfix\n";
+ }
+
if (mNobind)
cfg += "nobind\n";
@@ -570,7 +582,7 @@ public class VpnProfile implements Serializable {
public Intent prepareIntent(Context context) {
String prefix = context.getPackageName();
- Intent intent = new Intent(context, OpenVpnService.class);
+ Intent intent = new Intent(context, OpenVPNService.class);
if (mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) {
if (getKeyStoreCertificates(context) == null)
diff --git a/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java b/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java
index 8e418053..5910173a 100644
--- a/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java
+++ b/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java
@@ -6,14 +6,14 @@ import android.content.*;
import android.os.IBinder;
import se.leap.bitmaskclient.R;
-import de.blinkt.openvpn.core.OpenVpnService;
+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;
+ protected OpenVPNService mService;
private ServiceConnection mConnection = new ServiceConnection() {
@@ -22,7 +22,7 @@ public class DisconnectVPN extends Activity implements DialogInterface.OnClickLi
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;
+ OpenVPNService.LocalBinder binder = (OpenVPNService.LocalBinder) service;
mService = binder.getService();
}
@@ -36,8 +36,8 @@ public class DisconnectVPN extends Activity implements DialogInterface.OnClickLi
@Override
protected void onResume() {
super.onResume();
- Intent intent = new Intent(this, OpenVpnService.class);
- intent.setAction(OpenVpnService.START_SERVICE);
+ Intent intent = new Intent(this, OpenVPNService.class);
+ intent.setAction(OpenVPNService.START_SERVICE);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
showDisconnectDialog();
}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
index d23b521f..9c3621e0 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
@@ -432,6 +432,19 @@ public class ConfigParser {
throw new ConfigParseError("Sorry. Only tun mode is supported. See the FAQ for more detail");
}
+ Vector<String> mssfix = getOption("mssfix",0,1);
+
+ if (mssfix!=null) {
+ if (mssfix.size()>=2) {
+ try {
+ np.mMssFix=Integer.parseInt(mssfix.get(1));
+ } catch(NumberFormatException e) {
+ throw new ConfigParseError("Argument to --mssfix has to be an integer");
+ }
+ } else {
+ np.mMssFix = VpnProfile.DEFAULT_MSSFIX_SIZE;
+ }
+ }
Vector<String> mode =getOption("mode",1,1);
diff --git a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java
index 18c5f1d9..0126d08e 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java
@@ -68,7 +68,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL
if (windowtraffic < TRAFFIC_LIMIT) {
screen = connectState.DISCONNECTED;
VpnStatus.logInfo(R.string.screenoff_pause,
- OpenVpnService.humanReadableByteCount(TRAFFIC_LIMIT, false), TRAFFIC_WINDOW);
+ OpenVPNService.humanReadableByteCount(TRAFFIC_LIMIT, false), TRAFFIC_WINDOW);
mManagement.pause(getPauseReason());
}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
index 1daa3433..485e5369 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
@@ -1,14 +1,37 @@
package de.blinkt.openvpn.core;
-
import android.app.Application;
-/**
- * Created by arne on 28.12.13.
- */
+/*
+import org.acra.ACRA;
+import org.acra.ReportingInteractionMode;
+import org.acra.annotation.ReportsCrashes;
+*/
+
+import se.leap.bitmaskclient.BuildConfig;
+import se.leap.bitmaskclient.R;
+import de.blinkt.openvpn.core.PRNGFixes;
+
+/*
+@ReportsCrashes(
+ formKey = "",
+ formUri = "http://reports.blinkt.de/report-icsopenvpn",
+ reportType = org.acra.sender.HttpSender.Type.JSON,
+ httpMethod = org.acra.sender.HttpSender.Method.PUT,
+ formUriBasicAuthLogin="report-icsopenvpn",
+ formUriBasicAuthPassword="Tohd4neiF9Ai!!!!111eleven",
+ mode = ReportingInteractionMode.TOAST,
+ resToastText = R.string.crash_toast_text
+)
+*/
public class ICSOpenVPNApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
PRNGFixes.apply();
+
+ if (BuildConfig.DEBUG) {
+ //ACRA.init(this);
+ }
}
+
}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java
index 81a17ef9..8c6cb1f5 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java
@@ -76,8 +76,8 @@ public class NetworkSpace {
netAddress = BigInteger.ZERO;
for (byte b : address.getAddress()) {
- s -= 16;
- netAddress = netAddress.add(BigInteger.valueOf(b).shiftLeft(s));
+ s -= 8;
+ netAddress = netAddress.add(BigInteger.valueOf((b & 0xFF)).shiftLeft(s));
}
}
@@ -152,12 +152,12 @@ public class NetworkSpace {
String getIPv6Address() {
if (BuildConfig.DEBUG) Assert.assertTrue (!isV4);
BigInteger r = netAddress;
- if (r.longValue() == 0)
+ if (r.compareTo(BigInteger.ZERO)==0 && networkMask==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()));
+ parts.add(0, String.format(Locale.US, "%x", r.mod(BigInteger.valueOf(0x10000)).longValue()));
r = r.shiftRight(16);
}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
index 0cf93de3..743e7cc5 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
@@ -40,14 +40,14 @@ import de.blinkt.openvpn.core.VpnStatus.StateListener;
import static de.blinkt.openvpn.core.NetworkSpace.ipAddress;
import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTED;
-import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED;
import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_NONETWORK;
+import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED;
import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET;
import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT;
-
import se.leap.bitmaskclient.Dashboard;
-public class OpenVpnService extends VpnService implements StateListener, Callback, ByteCountListener {
+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";
@@ -74,7 +74,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
private OpenVPNManagement mManagement;
private String mLastTunCfg;
private String mRemoteGW;
- private Object mProcessLock = new Object();
+ private final Object mProcessLock = new Object();
// 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) {
@@ -116,6 +116,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
synchronized (mProcessLock) {
mProcessThread = null;
}
+ mConnecttime = 0;
VpnStatus.removeByteCountListener(this);
unregisterDeviceStateReceiver();
ProfileManager.setConntectedVpnProfileDisconnected(this);
@@ -166,7 +167,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
mNotificationManager.notify(OPENVPN_STATUS, notification);
- // startForeground(OPENVPN_STATUS, notification);
+ //startForeground(OPENVPN_STATUS, notification);
}
private int getIconByConnectionStatus(ConnectionStatus level) {
@@ -212,7 +213,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
nbuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel,
getString(R.string.cancel_connection), disconnectPendingIntent);
- Intent pauseVPN = new Intent(this, OpenVpnService.class);
+ Intent pauseVPN = new Intent(this, OpenVPNService.class);
if (mDeviceStateReceiver == null || !mDeviceStateReceiver.isUserPaused()) {
pauseVPN.setAction(PAUSE_VPN);
PendingIntent pauseVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0);
@@ -308,23 +309,32 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
return START_REDELIVER_INTENT;
}
- if (intent == null)
- return START_NOT_STICKY;
-
+ String UUID = "UUID";
+ if (intent == null) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ android.util.Log.d("bitmaskclient", "UUID is " + prefs.getString(UUID, ""));
+ mProfile = ProfileManager.get(this, prefs.getString(UUID, ""));
+ android.util.Log.d("bitmaskclient", "mProfile is null? " + (mProfile == null));
+ if(mProfile != null)
+ intent = mProfile.prepareIntent(getBaseContext());
+ else
+ return START_NOT_STICKY;
+ }
+ if(mProfile != null)
+ android.util.Log.d("bitmaskclient", "mProfile != 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");
+ 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.
@@ -351,12 +361,13 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
// Start a new session by creating a new thread.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
-
+
mOvpn3 = prefs.getBoolean("ovpn3", false);
if (!"ovpn3".equals(BuildConfig.FLAVOR))
mOvpn3 = false;
+ prefs.edit().putString(UUID, profileUUID).commit();
// Open the Management Interface
if (!mOvpn3) {
@@ -399,13 +410,16 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
ProfileManager.setConnectedVpnProfile(this, mProfile);
- return START_NOT_STICKY;
+ if (mProfile.mPersistTun)
+ return START_STICKY;
+ else
+ return START_NOT_STICKY;
}
private OpenVPNManagement instantiateOpenVPN3Core() {
try {
Class cl = Class.forName("de.blinkt.openvpn.core.OpenVPNThreadv3");
- return (OpenVPNManagement) cl.getConstructor(OpenVpnService.class,VpnProfile.class).newInstance(this,mProfile);
+ return (OpenVPNManagement) cl.getConstructor(OpenVPNService.class,VpnProfile.class).newInstance(this,mProfile);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e) {
@@ -499,8 +513,15 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
}
}
-
- builder.setMtu(mMtu);
+ String release = Build.VERSION.RELEASE;
+ if ((Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT && !release.startsWith("4.4.3")
+ && !release.startsWith("4.4.4") && !release.startsWith("4.4.5") && !release.startsWith("4.4.6"))
+ && mMtu < 1280) {
+ VpnStatus.logInfo(String.format("Forcing MTU to 1280 instead of %d to workaround Android Bug #70916", mMtu));
+ builder.setMtu(1280);
+ } else {
+ builder.setMtu(mMtu);
+ }
Collection<ipAddress> positiveIPv4Routes = mRoutes.getPositiveIPList();
Collection<ipAddress> positiveIPv6Routes = mRoutesv6.getPositiveIPList();
@@ -702,23 +723,32 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
mDisplayBytecount = true;
mConnecttime = System.currentTimeMillis();
lowpriority = true;
- NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotificationManager.cancel(OPENVPN_STATUS);
- } else if(!mProfile.mPersistTun || mConnecttime == 0){
- mDisplayBytecount = false;
- String msg = getString(resid);
- String ticker = msg;
- showNotification(msg + " " + logmessage, ticker, lowpriority , 0, level);
- } else if(mProfile.mPersistTun && level == LEVEL_NONETWORK) {
- NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotificationManager.cancel(OPENVPN_STATUS);
- } else if(mProfile.mPersistTun && mConnecttime > 0) {
+ if(mProfile.mPersistTun) {
+ NotificationManager ns = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ ns.cancel(OPENVPN_STATUS);
+ return;
+ }
+ } else if (level == LEVEL_NONETWORK || level == LEVEL_NOTCONNECTED) {
+ NotificationManager ns = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ ns.cancel(OPENVPN_STATUS);
+ return;
+ } else if (level != LEVEL_NOTCONNECTED && mConnecttime > 0) {
mDisplayBytecount = false;
String msg = "Traffic is blocked until the VPN becomes active.";
- String ticker = msg;
+ String ticker = msg;
showNotification(msg, ticker, lowpriority , 0, level);
- }
+ return;
+ } else {
+ mDisplayBytecount = false;
+ }
+ // Other notifications are shown,
+ // This also mean we are no longer connected, ignore bytecount messages until next
+ // CONNECTED
+ // Does not work :(
+ String msg = getString(resid);
+ String ticker = msg;
+ showNotification(msg + " " + logmessage, ticker, lowpriority , 0, level);
}
}
@@ -738,6 +768,9 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
humanReadableByteCount(diffIn / OpenVPNManagement.mBytecountInterval, true),
humanReadableByteCount(out, false),
humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true));
+
+ boolean lowpriority = !mNotificationAlwaysVisible;
+ //showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED);
}
}
@@ -773,9 +806,9 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
}
public class LocalBinder extends Binder {
- public OpenVpnService getService() {
+ public OpenVPNService getService() {
// Return this instance of LocalService so clients can call public methods
- return OpenVpnService.this;
+ return OpenVPNService.this;
}
}
}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java
index 67c05e7d..5fa2ab9e 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java
@@ -33,11 +33,11 @@ public class OpenVPNThread implements Runnable {
private String[] mArgv;
private Process mProcess;
private String mNativeDir;
- private OpenVpnService mService;
+ private OpenVPNService mService;
private String mDumpPath;
private Map<String, String> mProcessEnv;
- public OpenVPNThread(OpenVpnService service,String[] argv, Map<String,String> processEnv, String nativelibdir)
+ public OpenVPNThread(OpenVPNService service,String[] argv, Map<String,String> processEnv, String nativelibdir)
{
mArgv = argv;
mNativeDir = nativelibdir;
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
index e6e5be25..e200f210 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
@@ -33,49 +33,50 @@ import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
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 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 boolean mReleaseHold = true;
+ private boolean mWaitingForRelease = false;
+ private long mLastHoldRelease = 0;
- private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
+ private static final Vector<OpenVpnManagementThread> active = new Vector<OpenVpnManagementThread>();
private LocalSocket mServerSocketLocal;
private pauseReason lastPauseReason = pauseReason.noNetwork;
- public OpenVpnManagementThread(VpnProfile profile, OpenVpnService openVpnService) {
- mProfile = profile;
- mOpenVPNService = openVpnService;
-
+ 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;
- }
+ 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;
+ int tries = 8;
- String socketName = (c.getCacheDir().getAbsolutePath() + "/" + "mgmtsocket");
+ String socketName = (c.getCacheDir().getAbsolutePath() + "/" + "mgmtsocket");
// The mServerSocketLocal is transferred to the LocalServerSocket, ignore warning
mServerSocketLocal = new LocalSocket();
- while(tries > 0 && !mServerSocketLocal.isConnected()) {
+ 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);
+ try {
+ Thread.sleep(300);
} catch (InterruptedException e1) {
}
@@ -95,165 +96,168 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
- public void managmentCommand(String cmd) {
+ 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
+ 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
+ @Override
+ public void run() {
+ byte[] buffer = new byte[2048];
+ // mSocket.setSoTimeout(5); // Setting a timeout cannot be that bad
- String pendingInput="";
- active.add(this);
+ String pendingInput = "";
+ synchronized (active) {
+ active.add(this);
+ }
- try {
- // Wait for a client to connect
- mSocket= mServerSocket.accept();
- InputStream instream = mSocket.getInputStream();
+ 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);
- }
+ while (true) {
+ int numbytesread = instream.read(buffer);
+ if (numbytesread == -1)
+ return;
- String input = new String(buffer,0,numbytesread,"UTF-8");
+ 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);
+ }
- pendingInput += input;
+ String input = new String(buffer, 0, numbytesread, "UTF-8");
- pendingInput=processInput(pendingInput);
+ pendingInput += input;
+ pendingInput = processInput(pendingInput);
- }
- } catch (IOException e) {
+ }
+ } catch (IOException e) {
if (!e.getMessage().equals("socket closed"))
VpnStatus.logException(e);
- }
- active.remove(this);
- }
+ }
+ synchronized (active) {
+ 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);
+ //! 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 :)
+ // You can even get more evil by parsing toString() and extract the int from that :)
- boolean result = mOpenVPNService.protect(fdint);
+ boolean result = mOpenVPNService.protect(fdint);
if (!result)
VpnStatus.logWarning("Could not protect VPN socket");
- //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;
- }
+ //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);
- }
+ VpnStatus.logException("Failed to retrieve fd from socket (" + fd + ")", exp);
+ }
- private String processInput(String pendingInput) {
+ 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;
- }
+ 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) {
+ 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];
+ String[] parts = command.split(":", 2);
+ String cmd = parts[0].substring(1);
+ String argument = parts[1];
- if(cmd.equals("INFO")) {
- /* Ignore greeting from management */
+ 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:")) {
+ } 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 if (command.startsWith("PROTECTFD: ")) {
FileDescriptor fdtoprotect = mFDList.pollFirst();
- if (fdtoprotect!=null)
+ if (fdtoprotect != null)
protectFileDescriptor(fdtoprotect);
- } else {
- Log.i(TAG, "Got unrecognized line from managment" + command);
- VpnStatus.logWarning("MGMT: Got unrecognized line from management:" + command);
- }
- }
+ } 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);
+ String[] args = argument.split(",", 4);
// 0 unix time stamp
// 1 log level N,I,E etc.
/*
@@ -287,109 +291,110 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
if (msg.startsWith("MANAGEMENT: CMD"))
ovpnlevel = Math.max(4, ovpnlevel);
- VpnStatus.logMessageOpenVPN(level,ovpnlevel, msg);
+ VpnStatus.logMessageOpenVPN(level, ovpnlevel, msg);
}
private void handleHold() {
- if(mReleaseHold) {
- releaseHoldCmd();
- } else {
- mWaitingForRelease=true;
+ if (mReleaseHold) {
+ releaseHoldCmd();
+ } else {
+ mWaitingForRelease = true;
VpnStatus.updateStatePause(lastPauseReason);
- }
- }
- private void releaseHoldCmd() {
- if ((System.currentTimeMillis()- mLastHoldRelease) < 5000) {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
+ }
+ }
+
+ private void releaseHoldCmd() {
+ if ((System.currentTimeMillis() - mLastHoldRelease) < 5000) {
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException ignored) {
}
-
- }
- mWaitingForRelease=false;
- mLastHoldRelease = System.currentTimeMillis();
- managmentCommand("hold release\n");
- managmentCommand("bytecount " + mBytecountInterval + "\n");
+
+ }
+ 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(" ");
+ }
+
+ 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(" ");
/*
buf_printf (&out, "%s %s %s dev %s", network, netmask, gateway, rgi->iface);
@@ -397,209 +402,208 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
buf_printf (&out, "%s %s %s", network, netmask, gateway);
*/
- if(routeparts.length==5) {
+ if (routeparts.length == 5) {
if (BuildConfig.DEBUG) Assert.assertEquals("dev", routeparts[3]);
mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], routeparts[4]);
- } else if (routeparts.length >= 3) {
+ } else if (routeparts.length >= 3) {
mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], null);
} else {
VpnStatus.logError("Unrecognized ROUTE cmd:" + Arrays.toString(routeparts) + " | " + argument);
}
- } else if (needed.equals("ROUTE6")) {
+ } 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")) {
+ 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);
+ 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;
- }
+ }
+
+ 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() {
+ synchronized (active) {
+ 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;
+ }
+ }
@Override
public void networkChange() {
- if(!mWaitingForRelease)
+ if (!mWaitingForRelease)
managmentCommand("network-change\n");
}
- public void signalusr1() {
- mReleaseHold=false;
+ public void signalusr1() {
+ mReleaseHold = false;
- if(!mWaitingForRelease)
- managmentCommand("signal SIGUSR1\n");
+ 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();
- }
+ public void reconnect() {
+ signalusr1();
+ releaseHold();
+ }
- private void processSignCommand(String b64data) {
+ private void processSignCommand(String b64data) {
- String signed_string = mProfile.getSignedData(b64data);
- if(signed_string==null) {
+ 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(signed_string);
managmentCommand("\nEND\n");
- }
+ }
- @Override
- public void pause (pauseReason reason) {
+ @Override
+ public void pause(pauseReason reason) {
lastPauseReason = reason;
- signalusr1();
- }
+ signalusr1();
+ }
- @Override
- public void resume() {
- releaseHold();
+ @Override
+ public void resume() {
+ releaseHold();
/* Reset the reason why we are disconnected */
lastPauseReason = pauseReason.noNetwork;
- }
+ }
- @Override
- public boolean stopVPN() {
- return stopOpenVPN();
- }
+ @Override
+ public boolean stopVPN() {
+ return stopOpenVPN();
+ }
}
diff --git a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java
index 6e592121..ca850533 100644
--- a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java
+++ b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java
@@ -53,7 +53,7 @@ import se.leap.bitmaskclient.R;
import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.activities.DisconnectVPN;
import de.blinkt.openvpn.core.OpenVPNManagement;
-import de.blinkt.openvpn.core.OpenVpnService;
+import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.ProfileManager;
import de.blinkt.openvpn.core.VpnStatus;
import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
@@ -61,7 +61,7 @@ import de.blinkt.openvpn.core.VpnStatus.LogItem;
import de.blinkt.openvpn.core.VpnStatus.LogListener;
import de.blinkt.openvpn.core.VpnStatus.StateListener;
-import static de.blinkt.openvpn.core.OpenVpnService.humanReadableByteCount;
+import static de.blinkt.openvpn.core.OpenVPNService.humanReadableByteCount;
import se.leap.bitmaskclient.Dashboard;
@@ -503,8 +503,8 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar.
super.onResume();
VpnStatus.addStateListener(this);
VpnStatus.addByteCountListener(this);
- Intent intent = new Intent(getActivity(), OpenVpnService.class);
- intent.setAction(OpenVpnService.START_SERVICE);
+ Intent intent = new Intent(getActivity(), OpenVPNService.class);
+ intent.setAction(OpenVPNService.START_SERVICE);
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java
index 43ad3c1f..43fe0b7c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/EIP.java
+++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java
@@ -38,8 +38,8 @@ import de.blinkt.openvpn.activities.DisconnectVPN;
import de.blinkt.openvpn.core.ConfigParser.ConfigParseError;
import de.blinkt.openvpn.core.ConfigParser;
import de.blinkt.openvpn.core.OpenVpnManagementThread;
-import de.blinkt.openvpn.core.OpenVpnService.LocalBinder;
-import de.blinkt.openvpn.core.OpenVpnService;
+import de.blinkt.openvpn.core.OpenVPNService.LocalBinder;
+import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.ProfileManager;
import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
import java.io.IOException;
@@ -73,7 +73,7 @@ import se.leap.bitmaskclient.R;
* Internet Proxy connection. Connections are started, stopped, and queried through
* this IntentService.
* Contains logic for parsing eip-service.json from the provider, configuring and selecting
- * gateways, and controlling {@link de.blinkt.openvpn.core.OpenVpnService} connections.
+ * gateways, and controlling {@link de.blinkt.openvpn.core.OpenVPNService} connections.
*
* @author Sean Leonard <meanderingcode@aetherislands.net>
* @author Parménides GV <parmegv@sdf.org>
@@ -105,7 +105,6 @@ public final class EIP extends IntentService {
private static Context context;
private static ResultReceiver mReceiver;
- private static OpenVpnService mVpnService;
private static boolean mBound = false;
// Used to store actions to "resume" onServiceConnection
private static String mPending = null;
@@ -467,7 +466,6 @@ public final class EIP extends IntentService {
cp.parseConfig(new StringReader(certSecretFromSharedPreferences()));
cp.parseConfig(new StringReader("remote-cert-tls server"));
cp.parseConfig(new StringReader("persist-tun"));
- Log.d(TAG, "persist-tun");
VpnProfile vp = cp.convertProfile();
//vp.mAuthenticationType=VpnProfile.TYPE_STATICKEYS;
mVpnProfile = vp;
diff --git a/app/src/main/res/values-ca/strings-icsopenvpn.xml b/app/src/main/res/values-ca/strings-icsopenvpn.xml
index 67db8022..7e74c198 100755
--- a/app/src/main/res/values-ca/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-ca/strings-icsopenvpn.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--Generated by crowdin.net-->
+<!--Generated by crowdin.com-->
<!-- Generated by crowdin.net -->
<resources>
diff --git a/app/src/main/res/values-de/strings-icsopenvpn.xml b/app/src/main/res/values-de/strings-icsopenvpn.xml
index bf115be5..5ece9326 100755
--- a/app/src/main/res/values-de/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-de/strings-icsopenvpn.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--Generated by crowdin.net-->
+<!--Generated by crowdin.com-->
<!-- Generated by crowdin.net -->
<resources>
@@ -156,7 +156,7 @@
<string name="converted_profile">Importiertes Profil</string>
<string name="converted_profile_i">Importiertes Profil %d</string>
<string name="broken_images">Fehlerhafte Images</string>
- <string name="broken_images_faq">&lt;p&gt;Von offiziellen HTC Firmwares ist bekannt, dass diese teilweise merkwürdige Routing Probleme haben, die dafür sorgen, dass der Verkehr nicht durch den Tunnel fließt. (Siehe auch &lt;a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\"&gt;Issue 18&lt;/a&gt; im Bug Tracker.)&lt;/p&gt;&lt;p&gt;Bei älteren Version der offiziellen SONY Firmwares für das Xperia arc S and Xperia Ray scheint der VPNService Support komplett zu fehlen. (Siehe auch &lt;a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\"&gt;Issue 29&lt;/a&gt; im Bug Tracker.)&lt;/p&gt;&lt;p&gt;Auf anderen (insbesondere Custom ROMS) fehlt teilweise das tun Kernel Modul oder die Rechte von /dev/tun sind falsch gesetzt. Auf einigen CM9 Firmware wird die \"/dev/tun Eigentümer setzen\" Option in den Allgemeinen Einstellungen benötigt.&lt;/p&gt;&lt;p&gt;Am wichtigsten ist aber, falls Sie eine fehlerhafte Firmware haben, melden Sie dies Ihrem Hersteller. Desto mehr Leute den Fehler dem Hersteller melden desto wahrscheinlicher werden Sie eine Fehlerkorrektur bekommen.&lt;/p&gt;</string>
+ <string name="broken_images_faq">&lt;p&gt;Von offiziellen HTC Firmwares ist bekannt, dass diese teilweise merkwürdige Routing Probleme haben, die dafür sorgen, dass der Verkehr nicht durch den Tunnel fließt. (Siehe auch &lt;a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\"&gt;Issue 18&lt;/a&gt; im Bug Tracker.)&lt;/p&gt;&lt;p&gt;Bei älteren Version der offiziellen SONY Firmwares für das Xperia arc S and Xperia Ray scheint der VPNService Support komplett zu fehlen. (Siehe auch &lt;a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\"&gt;Issue 29&lt;/a&gt; im Bug Tracker.)&lt;/p&gt;&lt;p&gt;Auf anderen (insbesondere Custom ROMS) fehlt teilweise das tun Kernel Modul oder die Rechte von /dev/tun sind falsch gesetzt. Auf einigen CM9 Firmware wird die \"/dev/tun Eigentümer setzen\" Option in den Allgemeinen Einstellungen benötigt.&lt;/p&gt;&lt;p&gt;Am wichtigsten ist aber, falls Sie eine fehlerhafte Firmware haben, melden Sie dies Ihrem Hersteller. Je mehr Leute den Fehler dem Hersteller melden, desto wahrscheinlicher werden Sie eine Fehlerkorrektur bekommen.&lt;/p&gt;</string>
<string name="pkcs12_file_encryption_key">PKCS12 Veschlüsslungspassword</string>
<string name="private_key_password">Passphrase privater Schlüssel</string>
<string name="password">Passwort</string>
diff --git a/app/src/main/res/values-es/strings-icsopenvpn.xml b/app/src/main/res/values-es/strings-icsopenvpn.xml
index e9b6ed81..399392bf 100755
--- a/app/src/main/res/values-es/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-es/strings-icsopenvpn.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--Generated by crowdin.net-->
+<!--Generated by crowdin.com-->
<!-- Generated by crowdin.net -->
<resources>
@@ -215,6 +215,7 @@
<string name="vpn_import_hint">Use el icono &lt;img src=\"ic_menu_archive\"/&gt; para importar un perfil existente (.ovpn or .conf) de tu tarjeta.</string>
<string name="faq_hint">Asegúrese de checar también las preguntas frecuentes. Hay una guía de inicio rápido.</string>
<string name="faq_routing_title">Configuración de enrutamiento o interfaz</string>
+ <string name="faq_routing">El enrutamiento y la configuración de la interfaz no se realiza a través de comandos tradicionales ifconfig / ruta, pero mediante el uso de la API VPNService. Esto resulta en una configuración de enrutamiento diferente que en otros sistemas operativos. La configuración del túnel VPN consta de la dirección IP y las redes que deben ser colocados de través de esta interfaz. Se necesita Especialmente hay dirección compañero de estudios o de gateway. Rutas especiales para llegar a la VPN Server (por ejemplo agregan al usar redirect-gateway) no son necesarios, ya sea. La aplicación, en consecuencia ignorará esta configuración al importar una configuración. La aplicación asegura con la API VPNService que la conexión con el servidor no se encamina a través del túnel VPN. Sólo redes especificando ser enrutados a través del túnel es compatible. La aplicación intenta detectar las redes que no deben ser enrutados a través de túnel (por ejemplo, la ruta xxxx aaaa net_gateway) y calcula un conjunto de rutas que excluye este rutas para emular el comportamiento de otras plataformas. Las ventanas de registro muestra la configuración de la VPNService al establecer una conexión.</string>
<string name="persisttun_summary">No regresar a modo sin conexión VPN cuando OpenVPN esta volviendose a conectar.</string>
<string name="persistent_tun_title">Tun persistente</string>
<string name="openvpn_log">Registro de OpenVPN</string>
@@ -314,4 +315,8 @@
<string name="blocklocal_summary">Las redes conectadas directamente a los interfaces locales no serán enrutadas a través de la VPN. Al desmarcar esta opción, todo el tráfico previsto para las redes locales será redirigido a la VPN.</string>
<string name="blocklocal_title">Evitar la VPN para las redes locales</string>
<string name="userpw_file">Archivo de Usuario/Contraseña</string>
+ <string name="imported_from_file">[Importado de:%s]</string>
+ <string name="files_missing_hint">Algunos archivos no se pudo encontrar. Por favor, seleccione los archivos que desea importar el perfil:</string>
+ <string name="openvpn_is_no_free_vpn">Para utilizar esta aplicación usted necesita un proveedor de servicio VPN / es un apoyo OpenVPN (a menudo proporcionados por su empleador). Echa un vistazo a http://community.openvpn.net/ para más información sobre OpenVPN y cómo configurar su propio servidor OpenVPN.</string>
+ <string name="import_log">Importar registros:</string>
</resources>
diff --git a/app/src/main/res/values-fr/strings-icsopenvpn.xml b/app/src/main/res/values-fr/strings-icsopenvpn.xml
index 34512801..a26ce445 100755
--- a/app/src/main/res/values-fr/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-fr/strings-icsopenvpn.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--Generated by crowdin.net-->
+<!--Generated by crowdin.com-->
<!-- Generated by crowdin.net -->
<resources>
@@ -216,6 +216,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces
<string name="vpn_import_hint">"Utilisez l\'icône &lt;img src=\"ic_menu_archive\"/&gt; pour importer un fichier profil (.opvpn ou .conf) de votre carte SD."</string>
<string name="faq_hint">"Veillez également à consulter la FAQ. Il s\'y trouve un guide de démarrage rapide."</string>
<string name="faq_routing_title">"Redirections / Configuration de l\'interface"</string>
+ <string name="faq_routing">The Routing and interface configuration is not done via traditional ifconfig/route commands but by using the VPNService API. This results in a different routing configuration than on other OSes. The configuration for the VPN tunnel consists of the IP address and the networks that should be routed over this interface. Especially no peer partner address or gateway address is needed. Special routes to reach the VPN Server (for example added when using redirect-gateway) are not needed either. The application will consequently ignore these settings when importing a configuration. The app ensures with the VPNService API that the connection to the server is not routed through the VPN tunnel. Only specifying networks to be routed via tunnel is supported. The app tries to detect networks that should not be routed over tunnel (e.g. route x.x.x.x y.y.y.y net_gateway) and calculates a route set that excludes this routes to emulate the behaviour of other platforms. The log windows shows the configuration of the VPNService upon establishing a connection.</string>
<string name="persisttun_summary">Ne pas couper la connexion VPN lors de la reconnexion d\'OpenVPN.</string>
<string name="persistent_tun_title">Persistance de l\'interface TUN</string>
<string name="openvpn_log">Log OpenVPN</string>
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
new file mode 100755
index 00000000..e362c81a
--- /dev/null
+++ b/app/src/main/res/values-hu/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<!-- Generated by crowdin.net -->
+<resources>
+ <string name="app">OpenVPN Androidhoz</string>
+</resources>
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
new file mode 100755
index 00000000..715057ae
--- /dev/null
+++ b/app/src/main/res/values-in/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<!-- Generated by crowdin.net -->
+<resources>
+ <string name="app">OpenVPN untuk Android</string>
+</resources>
diff --git a/app/src/main/res/values-ja/strings-icsopenvpn.xml b/app/src/main/res/values-ja/strings-icsopenvpn.xml
index c96b9b8e..d537e3d8 100755
--- a/app/src/main/res/values-ja/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-ja/strings-icsopenvpn.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--Generated by crowdin.net-->
+<!--Generated by crowdin.com-->
<!-- Generated by crowdin.net -->
<resources>
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
new file mode 100755
index 00000000..aa233bb7
--- /dev/null
+++ b/app/src/main/res/values-pl/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<!-- Generated by crowdin.net -->
+<resources>
+ <string name="app">OpenVPN dla Androida</string>
+</resources>
diff --git a/app/src/main/res/values-pt/strings-icsopenvpn.xml b/app/src/main/res/values-pt/strings-icsopenvpn.xml
new file mode 100755
index 00000000..30bf569e
--- /dev/null
+++ b/app/src/main/res/values-pt/strings-icsopenvpn.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Generated by crowdin.net -->
+<resources>
+
+ <string name="address">Endereço do Servidor:</string>
+ <string name="port">Porta:</string>
+ <string name="location">Localização</string>
+ <string name="cant_read_folder">Não foi possível ler o diretório</string>
+ <string name="select">Selecionar</string>
+ <string name="cancel">Cancelar</string>
+ <string name="no_data">Não há dados</string>
+ <string name="useLZO">Compressão LZO</string>
+ <string name="client_no_certificate">Sem Certificado</string>
+ <string name="client_certificate_title">Certificado do Cliente</string>
+ <string name="client_key_title">Chave do Certificado do Cliente</string>
+ <string name="client_pkcs12_title">Arquivo PKCS12</string>
+ <string name="ca_title">Certificado CA</string>
+ <string name="no_certificate">Você deve selecionar um certificado</string>
+ <string name="copyright_guicode">O código fonte e o rastreamento de incidentes estão disponíveis em http://code.google.com/p/ics-openvpn/</string>
+ <string name="copyright_others">Este programa utiliza os seguintes componentes; veja o código fonte para mais detalhes das licenças</string>
+ <string name="about">Sobre</string>
+ <string name="vpn_list_title">Perfis</string>
+ <string name="vpn_type">Tipo</string>
+ <string name="pkcs12pwquery">Senha do PKCS12</string>
+ <string name="file_select">Selecionar&#8230;</string>
+ <string name="file_nothing_selected">Você deve selecionar um arquivo</string>
+ <string name="useTLSAuth">Utilizar Autenticação TLS</string>
+ <string name="tls_direction">Direção TLS</string>
+ <string name="ipv6_dialog_tile">Entre o Endereço IPv6/CIDR (ex: 2000:dd::23/64)</string>
+ <string name="ipv4_dialog_title">Entre o endereço IPv4/CIDR (ex: 1.2.3.4/24)</string>
+ <string name="ipv4_address">Endereço IPv4</string>
+ <string name="ipv6_address">Endereço IPv6</string>
+ <string name="custom_option_warning">Insira as opções personalizadas para o OpenVPN. Utilize com cuidado. Observe também que muitas das opções relacionadas ao tun do OpenVPN não podem ser suportadas pelo design do VPNSettings. Contate o autor se você acha que uma opção importante está faltando.</string>
+ <string name="auth_username">Usuário</string>
+ <string name="auth_pwquery">Senha</string>
+ <string name="static_keys_info">Para a configuração estática as chaves de autenticação de TLS serão utilizadas como chaves estáticas</string>
+ <string name="configure_the_vpn">Configurar VPN</string>
+ <string name="menu_add_profile">Adicionar Perfil</string>
+ <string name="add_profile_name_prompt">Digite um nome que identifica o novo perfil</string>
+ <string name="duplicate_profile_name">Por favor, digite um nome de perfil único</string>
+ <string name="profilename">Nome do perfil</string>
+ <string name="no_keystore_cert_selected">Você deve selecionar um certificado de usuário</string>
+ <string name="no_error_found">Nenhum erro encontrado</string>
+ <string name="config_error_found">Erro na configuração</string>
+ <string name="ipv4_format_error">Erro ao analisar o endereço IPv4</string>
+ <string name="custom_route_format_error">Erro ao analisar as rotas personalizadas</string>
+ <string name="pw_query_hint">(deixe em branco para consulta sob demanda)</string>
+ <string name="vpn_shortcut">Atalho do OpenVPN</string>
+ <string name="vpn_launch_title">Conectar a VPN</string>
+ <string name="shortcut_profile_notfound">O perfil especificado no atalho não foi encontrado</string>
+ <string name="random_host_prefix">Prefixo de Host aleatório</string>
+ <string name="random_host_summary">Adiciona 6 caracteres aleatórios na frente do hostname</string>
+ <string name="custom_config_title">Habilitar opções personalizadas</string>
+ <string name="custom_config_summary">Opções personalizadas. Use com cuidado!</string>
+ <string name="route_rejected">Rota rejeitada pelo Android</string>
+ <string name="cancel_connection">Desconectar</string>
+ <string name="cancel_connection_long">Desconectar VPN</string>
+ <string name="clear_log">limpar log</string>
+ <string name="title_cancel">Cancelar confirmação</string>
+ <string name="cancel_connection_query">Desconectar a VPN conectada/cancelar a tentativa de conexão?</string>
+ <string name="remove_vpn">Remover VPN</string>
+ <string name="check_remote_tlscert">Verifica se o servidor usa um certificado com as extensões de servidor TLS (- servidor remoto-cert-TLS)</string>
+ <string name="check_remote_tlscert_title">Esperar certificado do servidor TLS</string>
+ <string name="remote_tlscn_check_summary">Verifica o DN Subject do certificado do servidor remoto</string>
+ <string name="remote_tlscn_check_title">Verificar o Hostname do Certificado</string>
+ <string name="enter_tlscn_dialog">Especificar a conta usada para verificar o certificado remoto DN (por exemplo, C = DE, L = Paderborn, UO = aviária operadoras IP, CN=openvpn.blinkt.de)\n\Especificar o DN completo ou o RDN (openvpn.blinkt.de no exemplo) ou um prefixo RDN para verification.\n\nWhen usando o prefixo RDN \"Servidor\" corresponde a \"Server-1\" e \"Server-2\" \n\nDeixando vazio, o campo de texto irá verificar o RDN contra o servidor hostname.\n\nPara mais detalhes consulte a página principal do 2.3.1+ OpenVPN sob — verificar-X509-nome</string>
+ <string name="enter_tlscn_title">Subject do certificado remoto</string>
+ <string name="tls_key_auth">Permite a Autenticação de Chave TLS</string>
+ <string name="tls_auth_file">Arquivo de Auth TLS</string>
+ <string name="pull_on_summary">Solicitações de endereços de IP, rotas e opções de sincronização do servidor.</string>
+ <string name="pull_off_summary">Nenhuma informação é solicitada do servidor. Configurações precisam ser especificadas abaixo.</string>
+ <string name="use_pull">Obter Configurações</string>
+ <string name="dns">DNS</string>
+ <string name="override_dns">Substituir as configurações de DNS pelo servidor</string>
+ <string name="dns_override_summary">Use seus próprios servidores de DNS</string>
+ <string name="searchdomain">Domínio de pesquisa</string>
+ <string name="dns1_summary">Servidor DNS a ser usado.</string>
+ <string name="dns_server">Servidor DNS</string>
+ <string name="secondary_dns_message">Servidor DNS secundário utilizado caso o servidor primário esteja inacessível.</string>
+ <string name="backup_dns">Servidor DNS alternativo</string>
+ <string name="ignored_pushed_routes">Ignorar rotas empurradas</string>
+ <string name="ignore_routes_summary">Ignorar rota empurrada pelo servidor.</string>
+ <string name="default_route_summary">Redireccionar todo o tráfego pela VPN</string>
+ <string name="use_default_title">Usar rota padrão</string>
+ <string name="custom_route_message">Digite rotas personalizadas. Apenas indique destino em formato CIDR. \"10.0.0.0 / 8 2002 :: / 16\" iria dirigir as redes 10.0.0.0 / 8 e 2002 :: / 16 sobre a VPN.</string>
+ <string name="custom_route_message_excluded">As rotas que não devem ser encaminhados pelo VPN. Use a mesma sintaxe para rotas incluídas.</string>
+ <string name="custom_routes_title">Rotas personalizadas</string>
+ <string name="custom_routes_title_excluded">Redes excluídas</string>
+ <string name="log_verbosity_level">Nível de complexidade do log</string>
+ <string name="float_summary">Permite pacotes autenticados a partir de qualquer IP</string>
+ <string name="float_title">Permitir servidor flutuante</string>
+ <string name="custom_options_title">Opções personalizadas</string>
+ <string name="edit_vpn">Editar configurações de VPN</string>
+ <string name="remove_vpn_query">Remover o perfil VPN \'%s\'?</string>
+ <string name="tun_error_helpful">Em algumas imagens ICS personalizado a permissão em / dev / tun pode estar errada, ou o módulo tun pode estar faltando completamente. Para imagens CM9 tente a opção correção propriedade sobre as configurações gerais</string>
+ <string name="tun_open_error">Falha ao abrir a interface de tun</string>
+ <string name="error">"Erro:"</string>
+ <string name="clear">Claro</string>
+ <string name="last_openvpn_tun_config">Abrindo a interface tun:</string>
+ <string name="local_ip_info">Local IPv4: %1$s/%2$d IPv6:%3$s MTU:%4$d</string>
+ <string name="dns_server_info">Servidor DNS: %1$s, domínio: %2$s</string>
+ <string name="routes_info_incl">Rotas: %1$s %2$s</string>
+ <string name="routes_info_excl">Rotas excluídas: %1$s %2$s</string>
+ <string name="routes_debug">Rotas VpnService instaladas: %1$s %2$s</string>
+ <string name="ip_not_cidr">Existem múltiplas informações de interface, %1$s e %2$s, a aplicação assume que o segundo endereço é um endereço \'peer\' do endereço remoto. Será usada uma máscara de rede /32 para o IP local. O modo estabelecido pela OpenVPN é \"%3$s\".</string>
+ <string name="route_not_cidr">Não consigo entender %1$s e %2$s como uma rota IP com máscara de rede CIDR, usando /32 como máscara de rede.</string>
+ <string name="route_not_netip">A rota %1$s/%2$s foi corrigida para %3$s/%2$s</string>
+ <string name="keychain_access">Não é possível aceder aos certificados \'Keychain Android\'. Isso pode ter sido causado por uma atualização de firmware ou uma restauração das configurações da app/app. Será necessário editar o perfil VPN e selecionar novamente o certificado nas configurações básicas para recriar a permissão e possibilitar o acesso ao certificado.</string>
+ <string name="version_info">%1$s %2$s</string>
+ <string name="send_logfile">Enviar arquivo de log</string>
+ <string name="send">Enviar</string>
+ <string name="ics_openvpn_log_file">Ficheiro de registo do ICS OpenVPN</string>
+ <string name="copied_entry">Entrada de registo copiada para a área de transferência</string>
+ <string name="tap_mode">Entrada de registo copiada para a área de transferência</string>
+ <string name="faq_tap_mode">A API VPN não permite o modo Tap em dispositivos sem acesso root. Desta forma não é possível oferecer suporte Tap nesta aplicação</string>
+ <string name="tap_faq2">Novamente? Você está brincando? Não, o modo tap não é suportado de maneira nenhuma e enviar mais emails a perguntar se eventualmente será, não irá ajudar.</string>
+ <string name="faq">Perguntas frequentes</string>
+ <string name="encryption">Encriptação</string>
+ <string name="menu_import_short">Importar</string>
+ <string name="import_vpn">Importar</string>
+ <string name="ipv4">IPv4</string>
+ <string name="ipv6">IPv6</string>
+ <string name="password">Senha</string>
+ <string name="generalsettings">Configurações</string>
+ <string name="advanced">Avançado</string>
+ <string name="ignore">Ignorar</string>
+ <string name="restart">Reiniciar</string>
+ <string name="state_connecting">Conectando</string>
+ <string name="state_auth">Autenticando</string>
+ <string name="state_connected">Conectado</string>
+ <string name="add">Add</string>
+ <string name="pauseVPN">Pausa VPN</string>
+ <string name="resumevpn">Retomar VPN</string>
+ <string name="uploaded_data">Upload</string>
+ <string name="downloaded_data">Download</string>
+ <string name="vpn_status">Vpn Status</string>
+ <string name="logview_options">Ver opções</string>
+</resources>
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
new file mode 100755
index 00000000..29eff2ba
--- /dev/null
+++ b/app/src/main/res/values-pt/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Generated by crowdin.net -->
+<resources>
+ <string name="app">OpenVPN para Android</string>
+</resources>
diff --git a/app/src/main/res/values-ru/strings-icsopenvpn.xml b/app/src/main/res/values-ru/strings-icsopenvpn.xml
index 999df70b..400269ec 100755
--- a/app/src/main/res/values-ru/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-ru/strings-icsopenvpn.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--Generated by crowdin.net-->
+<!--Generated by crowdin.com-->
<!-- Generated by crowdin.net -->
<resources>
@@ -215,6 +215,7 @@
<string name="vpn_import_hint">Используйте &lt;img src=\"ic_menu_archive\"/&gt; кнопку для импорта существующих профилей (.ovpn or .conf) с вашей карты памяти.</string>
<string name="faq_hint">Не забудьте заглянуть в FAQ. Также имеется краткое руководство.</string>
<string name="faq_routing_title">Конфигурация маршрутизации/интерфейса</string>
+ <string name="faq_routing">Конфигурация маршрутизации и интерфейса производится не через традиционные ifconfig/route команды, а с помощью VPNService API. Это приводит к созданию другой конфигурации маршрутизации, отличной от конфигураций, используемых на других ОС. Конфигурация VPN-туннеля состоит из IP-адресов и сетей, которые должны направляться через этот интерфейс. Никаких особых партнерских адресов или адресов шлюза не требуется. Также не требуются и специальные маршруты для соединения с VPN-сервером (например, добавленные при использовании redirect-gateway). Следовательно, приложение будет игнорировать эти параметры при импорте конфигурации. Приложение с помощью VPNService API гарантирует, что подключение к серверу не направляется через VPN-туннель. Поддерживается направление через туннель только определенных сетей. Приложение пытается определить сети, которые не должны быть направлены через туннель (например, маршрут x.x.x.x y.y.y.y net_gateway) и вычисляет список маршрутов, в который не включаются эти маршруты, чтобы эмулировать поведение других платформ. Окна журналов и логов показывают конфигурацию сервиса VPN после установления соединения.</string>
<string name="persisttun_summary">Не открывать диалог, когда происходит переподключение VPN.</string>
<string name="persistent_tun_title">Постоянный tun</string>
<string name="openvpn_log">OpenVPN Журнал</string>
@@ -291,6 +292,8 @@
<string name="vpnbehaviour">Поведение VPN</string>
<string name="allow_vpn_changes">Разрешить изменение VPN-профилей</string>
<string name="hwkeychain">Аппаратное хранилище ключей:</string>
+ <string name="permission_icon_app">Иконка приложения пытается использовать OpenVPN для Android</string>
+ <string name="faq_vpndialog43">«Начиная с Android 4.3, диалог подтверждения VPN-соединения защищен от приложений, \"накладывающихся поверх экрана». Это приводит к тому, что диалоговое окно подтверждения не реагирует на сенсорные нажатия. Если у вас имеется приложение, использующее наложения, то это может вызвать такое поведение. Если вы обнаружите где-либо такое приложение, свяжитесь с автором приложения. Эта проблема затрагивает все VPN приложения на Android 4.3 и более поздних версиях. Смотрите также &lt; a href = \"http://code.google.com/p/ics-openvpn/issues/detail?id=185\" &gt; Проблему 185 &lt; &gt; для получения дополнительных сведений»</string>
<string name="faq_vpndialog43_title">Окно подтверждения VPN для Android 4.3 и позже</string>
<string name="donatePlayStore">Также Вы можете выразить благодарность в виде пожертвования на Play Store:</string>
<string name="thanks_for_donation">Спасибо за пожертвование %s!</string>
@@ -308,8 +311,10 @@
<string name="unhandled_exception">Неопознання ошибка: %1$s\n\n%2$s</string>
<string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string>
<string name="faq_system_dialog_xposed">Если на Вашем устройстве установлены Рут права, Вы можете установить &lt;a href=\"http://xposed.info/\"&gt;Xposed framework&lt;/a&gt; и &lt;a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\"&gt;модуль автоматического подтверждения диалога подключения VPN&lt;/a&gt; на свой страх и риск</string>
+ <string name="full_licenses">Полные тексты лицензий</string>
<string name="blocklocal_summary">Сети напрямую доступные через локальный интерфейс не будут маршрутизированы через VPN. Отключите эту опцию чтобы направить трафик через VPN.</string>
<string name="blocklocal_title">Не использовать VPN для локальных адресов</string>
+ <string name="userpw_file">Файл логина и пароля</string>
<string name="imported_from_file">[Импортировано из: %s]</string>
<string name="files_missing_hint">Некоторые файлы не найдены. Выберите файлы для импорта в профиль:</string>
<string name="openvpn_is_no_free_vpn">Для использования данного приложения Вам необходим VPN провайдер/шлюз поддерживающий OpenVPN. Для получения информации по настройке собственного OpenVPN сервера: http://community.openvpn.net/</string>
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
new file mode 100755
index 00000000..9e2326bf
--- /dev/null
+++ b/app/src/main/res/values-sv/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<!-- Generated by crowdin.net -->
+<resources>
+ <string name="app">OpenVPN för Android</string>
+</resources>
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
new file mode 100755
index 00000000..1ab863d1
--- /dev/null
+++ b/app/src/main/res/values-tr/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<!-- Generated by crowdin.net -->
+<resources>
+ <string name="app">Android için OpenVPN</string>
+</resources>
diff --git a/app/src/main/res/values/strings-icsopenvpn.xml b/app/src/main/res/values/strings-icsopenvpn.xml
index 40698afa..aadbff32 100755
--- a/app/src/main/res/values/strings-icsopenvpn.xml
+++ b/app/src/main/res/values/strings-icsopenvpn.xml
@@ -254,7 +254,7 @@
<string name="start_vpn_ticker">Connecting to VPN %s</string>
<string name="jelly_keystore_alphanumeric_bug">Some versions of Android 4.1 have problems if the name of the keystore certificate contains non alphanumeric characters (like spaces, underscores or dashes). Try to reimport the certificate without special characters</string>
<string name="encryption_cipher">Encryption cipher</string>
- <string name="packet_auth">Packets authentication</string>
+ <string name="packet_auth">Packet authentication</string>
<string name="auth_dialog_title">Enter packet authentication method</string>
<string name="mobile_info_extended">Running on %1$s (%2$s) %3$s, Android API %4$d, version %5$s, %6$s</string>
<string name="built_by">built by %s</string>
@@ -319,4 +319,9 @@
<string name="openvpn_is_no_free_vpn">To use this app you need a VPN provider/VPN gateway supporting OpenVPN (often provided by your employer). Check out http://community.openvpn.net/ for more information on OpenVPN and how to setup your own OpenVPN server.</string>
<string name="import_log">Import log:</string>
<string name="ip_looks_like_subnet">Vpn topology \"%3$s\" specified but ifconfig %1$s %2$s looks more like an IP address with a network mask. Assuming \"subnet\" topology.</string>
+ <string name="mssfix_invalid_value">mssfix value has to be a integer between 0 and 9000</string>
+ <string name="mssfix_value_dialog">Announce to TCP sessions running over the tunnel that they should limit their send packet sizes such that after OpenVPN has encapsulated them, the resulting UDP packet size that OpenVPN sends to its peer will not exceed this number of bytes. (default is 1450)</string>
+ <string name="mssfix_checkbox">Override MSS value of TCP payload</string>
+ <string name="mssfix_dialogtitle">Set MSS of TCP payload</string>
+
</resources>
diff --git a/app/src/main/res/values/untranslatable.xml b/app/src/main/res/values/untranslatable.xml
index 90090c52..b45d5ae7 100644
--- a/app/src/main/res/values/untranslatable.xml
+++ b/app/src/main/res/values/untranslatable.xml
@@ -1311,4 +1311,1143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <string name="crash_toast_text">OpenVPN for Android crashed, crash reported</string>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
</resources> \ No newline at end of file