From 7ad69e645000fc66951a79104b0ce5ac3478b9f3 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Fri, 18 May 2012 00:06:49 +0200 Subject: - Make Ipv6 support complete (minus tun-ipv6 warning) - Implement byte counter support in the log window - Fix spelling of secret (closes issue #22) - Replace "quot; with ", no idea what went wrong there (closes issue #21) --- openvpn/.gitignore | 1 + openvpn/src/compat/#compat-basename.c# | 50 -------------- openvpn/src/compat/#compat-inet_ntop.c# | 76 ---------------------- openvpn/src/compat/#compat.h# | 68 ------------------- openvpn/src/openvpn/console.c | 1 + res/layout/logwindow.xml | 17 +++++ res/values/strings.xml | 10 ++- res/xml/vpn_headers.xml | 14 ++-- res/xml/vpn_ipsettings.xml | 41 ++++-------- res/xml/vpn_routing.xml | 36 ++++++++++ src/de/blinkt/openvpn/FileSelectionFragment.java | 3 - src/de/blinkt/openvpn/LogWindow.java | 36 +++++++++- src/de/blinkt/openvpn/OpenVPN.java | 20 ++++++ src/de/blinkt/openvpn/OpenVpnManagementThread.java | 40 +++++++++++- src/de/blinkt/openvpn/Settings_IP.java | 19 +----- src/de/blinkt/openvpn/Settings_Routing.java | 73 +++++++++++++++++++++ src/de/blinkt/openvpn/VpnProfile.java | 35 +++++++++- 17 files changed, 279 insertions(+), 261 deletions(-) delete mode 100644 openvpn/src/compat/#compat-basename.c# delete mode 100644 openvpn/src/compat/#compat-inet_ntop.c# delete mode 100644 openvpn/src/compat/#compat.h# create mode 100644 res/layout/logwindow.xml create mode 100644 res/xml/vpn_routing.xml create mode 100644 src/de/blinkt/openvpn/Settings_Routing.java diff --git a/openvpn/.gitignore b/openvpn/.gitignore index 60b9433c..324accf7 100644 --- a/openvpn/.gitignore +++ b/openvpn/.gitignore @@ -49,3 +49,4 @@ doc/openvpn.8.html distro/rpm/openvpn.spec tests/t_client.sh src/openvpn/openvpn +xcopenvpn diff --git a/openvpn/src/compat/#compat-basename.c# b/openvpn/src/compat/#compat-basename.c# deleted file mode 100644 index a0576919..00000000 --- a/openvpn/src/compat/#compat-basename.c# +++ /dev/null @@ -1,50 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2011 - David Sommerseth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#elif defined(_MSC_VER) -#include "config-msvc.h" -#endif - -#ifndef HAVE_BASENAME - -#include "compat.h" -#include - -/* Modified version based on glibc-2.14.1 by Roland McGrath - * This version is extended to handle both / and \ in path names - */ -char * -basename (char *filename) -{ - char *p = strrchr (filename, '/'); - if (!p) { - /* If NULL, check for \ instead ... might be Windows a path */ - p = strrchr (filename, '\\'); - } - return p ? p + 1 : (char *) filename; -} - -#endif /* HAVE_BASENAME */ diff --git a/openvpn/src/compat/#compat-inet_ntop.c# b/openvpn/src/compat/#compat-inet_ntop.c# deleted file mode 100644 index 0d521425..00000000 --- a/openvpn/src/compat/#compat-inet_ntop.c# +++ /dev/null @@ -1,76 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2011 - David Sommerseth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#elif defined(_MSC_VER) -#include "config-msvc.h" -#endif - -#ifndef HAVE_INET_NTOP - -#include "compat.h" - -#ifdef WIN32 - -#include - -/* - * inet_ntop() and inet_pton() wrap-implementations using - * WSAAddressToString() and WSAStringToAddress() functions - * - * this is needed as long as we support running OpenVPN on WinXP - */ - -const char * -inet_ntop(int af, const void *src, char *dst, socklen_t size) -{ - struct sockaddr_storage ss; - unsigned long s = size; - - ZeroMemory(&ss, sizeof(ss)); - ss.ss_family = af; - - switch(af) { - case AF_INET: - ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; - break; - case AF_INET6: - ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src; - break; - default: - return NULL; - } - /* cannot direclty use &size because of strict aliasing rules */ - return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)? - dst : NULL; -} - -#else - -#error no emulation for inet_ntop - -#endif - -#endif diff --git a/openvpn/src/compat/#compat.h# b/openvpn/src/compat/#compat.h# deleted file mode 100644 index 021573eb..00000000 --- a/openvpn/src/compat/#compat.h# +++ /dev/null @@ -1,68 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2011 - David Sommerseth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef COMPAT_H -#define COMPAT_H - -#ifdef HAVE_WINSOCK2_H -#include -#endif - -#ifdef HAVE_WS2TCPIP_H -#include -#endif - -#ifdef HAVE_SYS_TIME_H -#include -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -#ifndef HAVE_DIRNAME -char * dirname(char *str); -#endif /* HAVE_DIRNAME */ - -#ifndef HAVE_BASENAME -char * basename(char *str); -#endif /* HAVE_BASENAME */ - -#ifndef HAVE_GETTIMEOFDAY -int gettimeofday (struct timeval *tv, void *tz); -#endif - -#ifndef HAVE_DAEMON -int daemon(int nochdir, int noclose); -#endif - -#ifndef HAVE_INET_NTOP -const char * inet_ntop(int af, const void *src, char *dst, socklen_t size); -#endif - -#ifndef HAVE_INET_PTON -int inet_pton(int af, const char *src, void *dst); -#endif - -#endif /* COMPAT_H */ diff --git a/openvpn/src/openvpn/console.c b/openvpn/src/openvpn/console.c index 2464e7e1..35372df7 100644 --- a/openvpn/src/openvpn/console.c +++ b/openvpn/src/openvpn/console.c @@ -232,6 +232,7 @@ get_console_input (const char *prompt, const bool echo, char *input, const int c } } #else + msg (M_ERR, "Requiring input from console: %s", prompt); msg (M_FATAL, "Sorry, but I can't get console input on this OS"); #endif return ret; diff --git a/res/layout/logwindow.xml b/res/layout/logwindow.xml new file mode 100644 index 00000000..4051c92c --- /dev/null +++ b/res/layout/logwindow.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 24332316..f0557545 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -125,7 +125,7 @@ Except TLS Server Checks the Remote Server Certificate CN against a String Certificate Hostname Check - Enter the String against which the remote Server is checked. Openvpn will use prefix matching. "Server" matches "Server-1" and "Server-2"\\nLeave empty to check the CN against the server hostname. + Enter the String against which the remote Server is checked. Openvpn will use prefix matching. "Server" matches "Server-1" and "Server-2"\\nLeave empty to check the CN against the server hostname. Remote Hostname(CN) Enables the TLS Key Authentication TLS Auth File @@ -145,7 +145,7 @@ Ignore routed pushed by the server. Redirects all Traffic over the VPN Use default Route - Enter custom routes. Only enter destination in CIDR format. "10.0.0.0/8 2002::/16" would direct the networks 10.0.0.0/8 and 2002::/16 over the VPN. + Enter custom routes. Only enter destination in CIDR format. "10.0.0.0/8 2002::/16" would direct the networks 10.0.0.0/8 and 2002::/16 over the VPN. Custom Routes Log verbosity level Allows authenticated packets from any IP @@ -216,5 +216,9 @@ "As openvpn is security sensitive a few notes about security are sensible. All data on the sdcard is inherently unsecure. Every app can read it (for example this program requires no special sd card rights). The data of this application can only be read by the application itself. By using the import option for cacert/cert/key in the file dialog the data is stored in the vpn profile. The vpn profiles are only accessable by this application. (Do not forget to delte the copies on the sdcard afterwards). Even though accessible only by this application the data is stil unecrypted. By rooting the telephone or other exploits it may be possible to retrieve the data. Saved passwords are stored in plain text as well. For pkcs12 files it is highly recommended that you import them into the android keystore." Import Error showing certificate selection - Got an excption trying to show the Android 4.0+ certificate selction dialog. This should never happens as this a standard feature of Android 4.0+. Maybe your Android ROM support for certificate storage is broken + Got an excption trying to show the Android 4.0+ certificate selction dialog. This should never happens as this a standard feature of Android 4.0+. Maybe your Android ROM support for certificate storage is broken + IPv4 + IPv6 + TODO + Waiting byte count message diff --git a/res/xml/vpn_headers.xml b/res/xml/vpn_headers.xml index c299d2a5..3762d445 100644 --- a/res/xml/vpn_headers.xml +++ b/res/xml/vpn_headers.xml @@ -2,27 +2,29 @@
+ android:tag="BasicSettings" + android:title="Basic Settings" />
+
-
-
+ android:title="@string/use_pull" /> - + android:title="@string/ipv6_address" /> + - - - - - - \ No newline at end of file diff --git a/res/xml/vpn_routing.xml b/res/xml/vpn_routing.xml new file mode 100644 index 00000000..ce19a500 --- /dev/null +++ b/res/xml/vpn_routing.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/de/blinkt/openvpn/FileSelectionFragment.java b/src/de/blinkt/openvpn/FileSelectionFragment.java index 41c7a1eb..c030bba0 100644 --- a/src/de/blinkt/openvpn/FileSelectionFragment.java +++ b/src/de/blinkt/openvpn/FileSelectionFragment.java @@ -29,9 +29,6 @@ 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 path = null; diff --git a/src/de/blinkt/openvpn/LogWindow.java b/src/de/blinkt/openvpn/LogWindow.java index 3455e385..2e2612d3 100644 --- a/src/de/blinkt/openvpn/LogWindow.java +++ b/src/de/blinkt/openvpn/LogWindow.java @@ -28,8 +28,9 @@ import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import de.blinkt.openvpn.OpenVPN.LogListener; +import de.blinkt.openvpn.OpenVPN.SpeedListener; -public class LogWindow extends ListActivity { +public class LogWindow extends ListActivity implements SpeedListener { private String[] mBconfig=null; @@ -190,6 +191,7 @@ public class LogWindow extends ListActivity { private LogWindowListAdapter ladapter; + private TextView mSpeedView; @Override public boolean onOptionsItemSelected(MenuItem item) { @@ -228,12 +230,23 @@ public class LogWindow extends ListActivity { return true; } + @Override + protected void onResume() { + super.onResume(); + OpenVPN.addSpeedListener(this); + } + @Override + protected void onStop() { + super.onStop(); + OpenVPN.removeSpeedListener(this); + } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setContentView(R.layout.logwindow); ListView lv = getListView(); lv.setOnItemLongClickListener(new OnItemLongClickListener() { @@ -249,12 +262,29 @@ public class LogWindow extends ListActivity { return true; } }); - //lv.setTextFilterEnabled(true); + ladapter = new LogWindowListAdapter(); lv.setAdapter(ladapter); + mSpeedView = (TextView) findViewById(R.id.speed); } - + @Override + public void updateSpeed(final String logmessage) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mSpeedView.setText(logmessage); + } + }); + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + OpenVPN.removeLogListener(ladapter); + } } diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java index 24281d13..1d9eb6e0 100644 --- a/src/de/blinkt/openvpn/OpenVPN.java +++ b/src/de/blinkt/openvpn/OpenVPN.java @@ -10,12 +10,16 @@ public class OpenVPN { public static LinkedList logbuffer = new LinkedList(); private static Vector logListener=new Vector(); + private static Vector speedListener=new Vector(); private static String[] mBconfig; public interface LogListener { void newLog(String logmessage); } + public interface SpeedListener { + void updateSpeed(String logmessage); + } synchronized static void logMessage(int level,String prefix, String message) { @@ -41,6 +45,16 @@ public class OpenVPN { logListener.remove(ll); } + + synchronized static void addSpeedListener(SpeedListener sl){ + speedListener.add(sl); + } + + synchronized static void removeSpeedListener(SpeedListener sl) { + speedListener.remove(sl); + } + + synchronized public static String[] getlogbuffer() { @@ -62,4 +76,10 @@ public class OpenVPN { } } + + public static void updateSpeedString(String msg) { + for (SpeedListener sl : speedListener) { + sl.updateSpeed(msg); + } + } } diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java index 753cd98a..b568bd60 100644 --- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java +++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java @@ -18,7 +18,10 @@ public class OpenVpnManagementThread implements Runnable { private LocalSocket mSocket; private VpnProfile mProfile; private OpenVpnService mOpenVPNService; - private LinkedList mFDList=new LinkedList(); + private LinkedList mFDList=new LinkedList(); + private int mBytecountinterval=2; + private long mLastIn=0; + private long mLastOut=0; private static Vector active=new Vector(); @@ -157,9 +160,11 @@ public class OpenVpnManagementThread implements Runnable { processPWCommand(argument); } else if (cmd.equals("HOLD")) { managmentCommand("hold release\n"); - //managmentCommand("log on\n"); + managmentCommand("bytecount " + mBytecountinterval + "\n"); } else if (cmd.equals("NEED-OK")) { processNeedCommand(argument); + } else if (cmd.equals("BYTECOUNT")){ + processByteCount(argument); } else if (cmd.equals("LOG")) { String[] args = argument.split(",",3); // 0 unix time stamp @@ -178,6 +183,37 @@ public class OpenVpnManagementThread implements Runnable { } } + 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)); + + long diffin = in - mLastIn; + long diffout = out - mLastOut; + + mLastIn=in; + mLastOut=out; + + String netstat = String.format("In: %8s, %8s/s Out %8s, %8s/s ", + humanReadableByteCount(in, false), + humanReadableByteCount(diffin, false), + humanReadableByteCount(out, false), + humanReadableByteCount(diffout, false)); + OpenVPN.updateSpeedString(netstat); + + + } + + // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java + public static String humanReadableByteCount(long bytes, boolean si) { + int unit = si ? 1000 : 1024; + if (bytes < unit) return bytes + " B"; + int exp = (int) (Math.log(bytes) / Math.log(unit)); + String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i"); + return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); + } + private void processNeedCommand(String argument) { int p1 =argument.indexOf('\''); int p2 = argument.indexOf('\'',p1+1); diff --git a/src/de/blinkt/openvpn/Settings_IP.java b/src/de/blinkt/openvpn/Settings_IP.java index dcdc10c0..f1e495c8 100644 --- a/src/de/blinkt/openvpn/Settings_IP.java +++ b/src/de/blinkt/openvpn/Settings_IP.java @@ -16,9 +16,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere private EditTextPreference mSearchdomain; private EditTextPreference mDNS1; private EditTextPreference mDNS2; - private EditTextPreference mCustomRoutes; - private CheckBoxPreference mUseDefaultRoute; - private CheckBoxPreference mRouteNoPull; private CheckBoxPreference mNobind; @Override @@ -41,9 +38,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere mSearchdomain =(EditTextPreference) findPreference("searchdomain"); mDNS1 = (EditTextPreference) findPreference("dns1"); mDNS2 = (EditTextPreference) findPreference("dns2"); - mCustomRoutes = (EditTextPreference) findPreference("customRoutes"); - mUseDefaultRoute = (CheckBoxPreference) findPreference("useDefaultRoute"); - mRouteNoPull = (CheckBoxPreference) findPreference("routenopull"); mNobind = (CheckBoxPreference) findPreference("nobind"); mIPv4.setOnPreferenceChangeListener(this); @@ -53,7 +47,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere mUsePull.setOnPreferenceChangeListener(this); mOverrideDNS.setOnPreferenceChangeListener(this); mSearchdomain.setOnPreferenceChangeListener(this); - mCustomRoutes.setOnPreferenceChangeListener(this); loadSettings(); } @@ -68,9 +61,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere mDNS2.setText(mProfile.mDNS2); mOverrideDNS.setChecked(mProfile.mOverrideDNS); mSearchdomain.setText(mProfile.mSearchDomain); - mUseDefaultRoute.setChecked(mProfile.mUseDefaultRoute); - mCustomRoutes.setText(mProfile.mCustomRoutes); - mRouteNoPull.setChecked(mProfile.mRoutenopull); mNobind.setChecked(mProfile.mNobind); // Sets Summary @@ -79,8 +69,7 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere onPreferenceChange(mDNS1, mDNS1.getText()); onPreferenceChange(mDNS2, mDNS2.getText()); onPreferenceChange(mSearchdomain, mSearchdomain.getText()); - onPreferenceChange(mCustomRoutes, mCustomRoutes.getText()); - + setDNSState(); } @@ -94,9 +83,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere mProfile.mDNS2 = mDNS2.getText(); mProfile.mOverrideDNS = mOverrideDNS.isChecked(); mProfile.mSearchDomain = mSearchdomain.getText(); - mProfile.mUseDefaultRoute = mUseDefaultRoute.isChecked(); - mProfile.mCustomRoutes = mCustomRoutes.getText(); - mProfile.mRoutenopull = mRouteNoPull.isChecked(); mProfile.mNobind = mNobind.isChecked(); } @@ -106,7 +92,7 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere Object newValue) { if(preference==mIPv4 || preference == mIPv6 || preference==mDNS1 || preference == mDNS2 - || preference == mSearchdomain || preference == mCustomRoutes + || preference == mSearchdomain ) preference.setSummary((String)newValue); @@ -125,7 +111,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere private void setDNSState() { boolean enabled; mOverrideDNS.setEnabled(mUsePull.isChecked()); - mRouteNoPull.setEnabled(mUsePull.isChecked()); if(!mUsePull.isChecked()) enabled =true; else if (mOverrideDNS.isChecked()) diff --git a/src/de/blinkt/openvpn/Settings_Routing.java b/src/de/blinkt/openvpn/Settings_Routing.java new file mode 100644 index 00000000..8305f4db --- /dev/null +++ b/src/de/blinkt/openvpn/Settings_Routing.java @@ -0,0 +1,73 @@ +package de.blinkt.openvpn; +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; + + +public class Settings_Routing extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { + private EditTextPreference mCustomRoutes; + private CheckBoxPreference mUseDefaultRoute; + private EditTextPreference mCustomRoutesv6; + private CheckBoxPreference mUseDefaultRoutev6; + private CheckBoxPreference mRouteNoPull; + + @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"); + mRouteNoPull = (CheckBoxPreference) findPreference("routenopull"); + + 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); + + mRouteNoPull.setChecked(mProfile.mRoutenopull); + + // 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(); + } + + @Override + public boolean onPreferenceChange(Preference preference, + Object newValue) { + if( preference == mCustomRoutes || preference == mCustomRoutesv6 ) + preference.setSummary((String)newValue); + + saveSettings(); + return true; + } + + +} \ No newline at end of file diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index a0f6db76..5cdff43d 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -91,6 +91,8 @@ public class VpnProfile implements Serializable{ public String mVerb="1"; public String mCipher=""; public boolean mNobind=false; + public boolean mUseDefaultRoutev6=true; + public String mCustomRoutesv6=""; public void clearDefaults() { @@ -231,7 +233,7 @@ public class VpnProfile implements Serializable{ if(mUseTLSAuth) { if(mAuthenticationType==TYPE_STATICKEYS) - cfg+=insertFileData("scecret",mTLSAuthFilename); + cfg+=insertFileData("secret",mTLSAuthFilename); else cfg+=insertFileData("tls-auth",mTLSAuthFilename); cfg+=" "; @@ -243,9 +245,12 @@ public class VpnProfile implements Serializable{ cfg+="\n"; } - // Basic Settings if(!mUsePull ) { - cfg +="ifconfig " + cidrToIPAndNetmask(mIPv4Address) + "\n"; + if(nonNull(mIPv4Address)) + cfg +="ifconfig " + cidrToIPAndNetmask(mIPv4Address) + "\n"; + + if(nonNull(mIPv6Address)) + cfg +="ifconfig-ipv6 " + mIPv6Address + "\n"; } if(mUsePull && mRoutenopull) @@ -258,6 +263,13 @@ public class VpnProfile implements Serializable{ cfg += "route " + route + "\n"; } + + if(mUseDefaultRoutev6) + cfg += "route-ipv6 ::/0\n"; + else + for(String route:getCustomRoutesv6()) { + cfg += "route-ipv6 " + route + "\n"; + } if(mOverrideDNS || !mUsePull) { if(!mDNS1.equals("") && mDNS1!=null) @@ -346,6 +358,23 @@ public class VpnProfile implements Serializable{ return cidrRoutes; } + private Collection getCustomRoutesv6() { + Vector cidrRoutes=new Vector(); + if(mCustomRoutesv6==null) { + // No routes set, return empty vector + return cidrRoutes; + } + for(String route:mCustomRoutesv6.split("[\n \t]")) { + if(!route.equals("")) { + cidrRoutes.add(route); + } + } + + return cidrRoutes; + } + + + private String cidrToIPAndNetmask(String route) { String[] parts = route.split("/"); -- cgit v1.2.3