summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2018-04-23 00:05:22 +0200
committerArne Schwabe <arne@rfc2549.org>2018-04-23 00:05:36 +0200
commit6c0bf4d7a52dd6e60f368e454dab7c91487c97ff (patch)
treee96a5662f07a8c58630266d8276ea66bb069843b /main
parent869a0ce9cf26584edac321a2a7193bb8904888dc (diff)
Implement HTTP User/Password Authentication via UI (closes #861, #856)
Diffstat (limited to 'main')
-rw-r--r--main/build.gradle8
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java17
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/Connection.java9
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java40
-rw-r--r--main/src/main/java/de/blinkt/openvpn/fragments/ConnectionsAdapter.java61
-rw-r--r--main/src/main/res/layout/server_card.xml583
-rwxr-xr-xmain/src/main/res/values/strings.xml2
-rw-r--r--main/src/test/java/de/blinkt/openvpn/core/TestConfigParser.java16
8 files changed, 437 insertions, 299 deletions
diff --git a/main/build.gradle b/main/build.gradle
index cf677e5d..eb4566d8 100644
--- a/main/build.gradle
+++ b/main/build.gradle
@@ -19,10 +19,10 @@ repositories {
}
dependencies {
- implementation 'com.android.support.constraint:constraint-layout:1.0.2'
- implementation 'com.android.support:support-annotations:27.1.0'
- implementation 'com.android.support:cardview-v7:27.1.0'
- implementation 'com.android.support:recyclerview-v7:27.1.0'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.0'
+ implementation 'com.android.support:support-annotations:27.1.1'
+ implementation 'com.android.support:cardview-v7:27.1.1'
+ implementation 'com.android.support:recyclerview-v7:27.1.1'
// compile 'ch.acra:acra:4.5.0'
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.2'
diff --git a/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
index 883edf53..10fcb12a 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
@@ -332,6 +332,7 @@ public class ConfigParser {
"http-proxy-option",
"socks-proxy",
"socks-proxy-retry",
+ "http-proxy-user-pass",
"explicit-exit-notify",
};
@@ -810,7 +811,9 @@ public class ConfigParser {
conn.mProxyPort = proxy.get(2);
}
-
+ Vector<String> httpproxyauthhttp = getOption("http-proxy-user-pass", 1, 1);
+ if (httpproxyauthhttp!=null)
+ useEmbbedHttpAuth(conn, httpproxyauthhttp.get(1));
// Parse remote config
@@ -900,6 +903,16 @@ public class ConfigParser {
}
}
+ static public void useEmbbedHttpAuth(Connection c, String inlinedata) {
+ String data = VpnProfile.getEmbeddedContent(inlinedata);
+ String[] parts = data.split("\n");
+ if (parts.length >= 2) {
+ c.mProxyAuthUser = parts[0];
+ c.mProxyAuthPassword = parts[1];
+ c.mUseProxyAuth = true;
+ }
+ }
+
private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError {
for (String option : unsupportedOptions)
if (options.containsKey(option))
@@ -950,7 +963,7 @@ public class ConfigParser {
if (!ignoreThisOption(optionsline)) {
// Check if option had been inlined and inline again
if (optionsline.size() == 2 &&
- ("extra-certs".equals(optionsline.get(0)) || "http-proxy-user-pass".equals(optionsline.get(0)))) {
+ "extra-certs".equals(optionsline.get(0))) {
custom += VpnProfile.insertFileData(optionsline.get(0), optionsline.get(1));
} else {
for (String arg : optionsline)
diff --git a/main/src/main/java/de/blinkt/openvpn/core/Connection.java b/main/src/main/java/de/blinkt/openvpn/core/Connection.java
index 88748d1d..5f24ecb4 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/Connection.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/Connection.java
@@ -23,6 +23,10 @@ public class Connection implements Serializable, Cloneable {
public String mProxyName = "proxy.example.com";
public String mProxyPort = "8080";
+ public boolean mUseProxyAuth;
+ public String mProxyAuthUser = null;
+ public String mProxyAuthPassword = null;
+
public enum ProxyType {
NONE,
HTTP,
@@ -53,13 +57,16 @@ public class Connection implements Serializable, Cloneable {
if (isOpenVPN3 && mProxyType == ProxyType.HTTP)
{
cfg+=String.format(Locale.US,"http-proxy %s %s\n", mProxyName, mProxyPort);
+ if (mUseProxyAuth)
+ cfg+=String.format(Locale.US, "<http-proxy-user-pass>\n%s\n%s\n</http-proxy-user-pass>\n", mProxyAuthUser, mProxyAuthPassword);
}
-
if (!TextUtils.isEmpty(mCustomConfiguration) && mUseCustomConfig) {
cfg += mCustomConfiguration;
cfg += "\n";
}
+
+
return cfg;
}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
index c46fe727..e711d8ff 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
@@ -60,7 +60,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
private Runnable orbotStatusTimeOutRunnable = new Runnable() {
@Override
public void run() {
- sendProxyCMD(Connection.ProxyType.SOCKS5, "127.0.0.1", Integer.toString(OrbotHelper.SOCKS_PROXY_PORT_DEFAULT));
+ sendProxyCMD(Connection.ProxyType.SOCKS5, "127.0.0.1", Integer.toString(OrbotHelper.SOCKS_PROXY_PORT_DEFAULT), false);
OrbotHelper.get(mOpenVPNService).removeStatusCallback(statusCallback);
}
@@ -86,7 +86,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
@Override
public void onOrbotReady(Intent intent, String socksHost, int socksPort) {
mResumeHandler.removeCallbacks(orbotStatusTimeOutRunnable);
- sendProxyCMD(Connection.ProxyType.SOCKS5, socksHost, Integer.toString(socksPort));
+ sendProxyCMD(Connection.ProxyType.SOCKS5, socksHost, Integer.toString(socksPort), false);
OrbotHelper.get(mOpenVPNService).removeStatusCallback(this);
}
@@ -95,6 +95,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
VpnStatus.logWarning("Orbot integration for external applications is disabled. Waiting %ds before connecting to the default port. Enable external app integration in Orbot or use Socks v5 config instead of Orbot to avoid this delay.");
}
};
+ private transient Connection mCurrentProxyConnection;
public OpenVpnManagementThread(VpnProfile profile, OpenVPNService openVpnService) {
mProfile = profile;
@@ -428,14 +429,20 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
int connectionEntryNumber = Integer.parseInt(args[0]) - 1;
String proxyport = null;
String proxyname = null;
+ boolean proxyUseAuth = false;
if (mProfile.mConnections.length > connectionEntryNumber) {
Connection connection = mProfile.mConnections[connectionEntryNumber];
proxyType = connection.mProxyType;
proxyname = connection.mProxyName;
proxyport = connection.mProxyPort;
+ proxyUseAuth = connection.mUseProxyAuth;
+
+ // Use transient variable to remember http user/password
+ mCurrentProxyConnection = connection;
+
} else {
- VpnStatus.logError(String.format(Locale.ENGLISH, "OpenVPN is asking for a proxy of an unknonwn connection entry (%d)", connectionEntryNumber));
+ VpnStatus.logError(String.format(Locale.ENGLISH, "OpenVPN is asking for a proxy of an unknown connection entry (%d)", connectionEntryNumber));
}
// atuo detection of proxy
@@ -446,6 +453,8 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
proxyType = Connection.ProxyType.HTTP;
proxyname = isa.getHostName();
proxyport = String.valueOf(isa.getPort());
+ proxyUseAuth = false;
+
}
}
@@ -471,18 +480,20 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
orbotHelper.sendOrbotStartAndStatusBroadcast();
} else {
- sendProxyCMD(proxyType, proxyname, proxyport);
+ sendProxyCMD(proxyType, proxyname, proxyport, proxyUseAuth);
}
}
- private void sendProxyCMD(Connection.ProxyType proxyType, String proxyname, String proxyport) {
+ private void sendProxyCMD(Connection.ProxyType proxyType, String proxyname, String proxyport, boolean usePwAuth) {
if (proxyType != Connection.ProxyType.NONE && proxyname != null) {
VpnStatus.logInfo(R.string.using_proxy, proxyname, proxyname);
- String proxycmd = String.format(Locale.ENGLISH, "proxy %s %s %s\n",
+ String pwstr = usePwAuth ? " auto" : "";
+
+ String proxycmd = String.format(Locale.ENGLISH, "proxy %s %s %s%s\n",
proxyType == Connection.ProxyType.HTTP ? "HTTP" : "SOCKS",
- proxyname, proxyport);
+ proxyname, proxyport, pwstr);
managmentCommand(proxycmd);
} else {
managmentCommand("proxy NONE\n");
@@ -653,17 +664,26 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
String pw = null;
+ String username = null;
if (needed.equals("Private Key")) {
pw = mProfile.getPasswordPrivateKey();
} else if (needed.equals("Auth")) {
pw = mProfile.getPasswordAuth();
+ username = mProfile.mUsername;
- String usercmd = String.format("username '%s' %s\n",
- needed, VpnProfile.openVpnEscape(mProfile.mUsername));
- managmentCommand(usercmd);
+ } else if (needed.equals("HTTP Proxy")) {
+ if( mCurrentProxyConnection != null) {
+ pw = mCurrentProxyConnection.mProxyAuthPassword;
+ username = mCurrentProxyConnection.mProxyAuthUser;
+ }
}
if (pw != null) {
+ if (username !=null) {
+ String usercmd = String.format("username '%s' %s\n",
+ needed, VpnProfile.openVpnEscape(username));
+ managmentCommand(usercmd);
+ }
String cmd = String.format("password '%s' %s\n", needed, VpnProfile.openVpnEscape(pw));
managmentCommand(cmd);
} else {
diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/ConnectionsAdapter.java b/main/src/main/java/de/blinkt/openvpn/fragments/ConnectionsAdapter.java
index bb930eaf..9c4c80de 100644
--- a/main/src/main/java/de/blinkt/openvpn/fragments/ConnectionsAdapter.java
+++ b/main/src/main/java/de/blinkt/openvpn/fragments/ConnectionsAdapter.java
@@ -13,12 +13,7 @@ import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.RadioGroup;
-import android.widget.SeekBar;
-import android.widget.Switch;
+import android.widget.*;
import java.util.Arrays;
@@ -97,6 +92,10 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
break;
}
+ cH.mProxyAuthCb.setChecked(connection.mUseProxyAuth);
+ cH.mProxyAuthUser.setText(connection.mProxyAuthUser);
+ cH.mProxyAuthPassword.setText(connection.mProxyAuthPassword);
+
cH.mCustomOptionsLayout.setVisibility(connection.mUseCustomConfig ? View.VISIBLE : View.GONE);
cH.mCustomOptionText.setText(connection.mCustomConfiguration);
@@ -109,10 +108,14 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
private void setVisibilityProxyServer(ConnectionsHolder cH, Connection connection) {
int visible = (connection.mProxyType == Connection.ProxyType.HTTP || connection.mProxyType == Connection.ProxyType.SOCKS5) ? View.VISIBLE : View.GONE;
+ int authVisible = (connection.mProxyType == Connection.ProxyType.HTTP) ? View.VISIBLE : View.GONE;
cH.mProxyNameView.setVisibility(visible);
cH.mProxyPortNumberView.setVisibility(visible);
cH.mProxyNameLabel.setVisibility(visible);
+
+ cH.mProxyAuthLayout.setVisibility(authVisible);
+
}
private void removeRemote(int idx) {
@@ -185,6 +188,11 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
private final EditText mProxyNameView;
private final EditText mProxyPortNumberView;
private final View mProxyNameLabel;
+ private final View mProxyAuthLayout;
+ private final EditText mProxyAuthUser;
+ private final EditText mProxyAuthPassword;
+ private final CheckBox mProxyAuthCb;
+
private Connection mConnection; // Set to null on update
@@ -206,6 +214,10 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
mProxyPortNumberView = card.findViewById(R.id.proxyport);
mProxyNameLabel = card.findViewById(R.id.proxyserver_label);
+ mProxyAuthLayout = card.findViewById(R.id.proxyauthlayout);
+ mProxyAuthCb = card.findViewById(R.id.enable_proxy_auth);
+ mProxyAuthUser = card.findViewById(R.id.proxyuser);
+ mProxyAuthPassword = card.findViewById(R.id.proxypassword);
mConnectionsAdapter = connectionsAdapter;
@@ -215,7 +227,7 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
void addListeners() {
- mRemoteSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ mRemoteSwitch.setOnCheckedChangeListener((CompoundButton buttonView, boolean isChecked) -> {
if (mConnection != null) {
mConnection.mEnabled = isChecked;
mConnectionsAdapter.displayWarningIfNoneEnabled();
@@ -251,6 +263,14 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
}
});
+ mProxyAuthCb.setOnCheckedChangeListener((group, isChecked) ->
+ {
+ if (mConnection != null) {
+ mConnection.mUseProxyAuth = isChecked;
+ setVisibilityProxyServer(this, mConnection);
+ }
+ });
+
mCustomOptionText.addTextChangedListener(new OnTextChangedWatcher() {
@Override
public void afterTextChanged(Editable s) {
@@ -305,6 +325,33 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
}
});
+ mCustomOptionCB.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ if (mConnection != null) {
+ mConnection.mUseProxyAuth = isChecked;
+ }
+ });
+
+ mProxyAuthPassword.addTextChangedListener(new OnTextChangedWatcher() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (mConnection != null) {
+ mConnection.mProxyAuthPassword = s.toString();
+ }
+ }
+ });
+
+
+ mProxyAuthUser.addTextChangedListener(new OnTextChangedWatcher() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (mConnection != null) {
+ mConnection.mProxyAuthUser = s.toString();
+ }
+ }
+ });
+
+
+
mCustomOptionText.addTextChangedListener(new OnTextChangedWatcher() {
@Override
public void afterTextChanged(Editable s) {
diff --git a/main/src/main/res/layout/server_card.xml b/main/src/main/res/layout/server_card.xml
index 40655d1c..5d13cff0 100644
--- a/main/src/main/res/layout/server_card.xml
+++ b/main/src/main/res/layout/server_card.xml
@@ -4,356 +4,397 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:card_view="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="@dimen/stdpadding">
+ xmlns:card_view="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="@dimen/stdpadding">
<!-- A CardView that contains a TextView -->
<android.support.v7.widget.CardView
- android:id="@+id/card_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- card_view:cardCornerRadius="10dp">
+ android:id="@+id/card_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ card_view:cardCornerRadius="10dp">
<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:animateLayoutChanges="true"
- android:padding="5dp">
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:animateLayoutChanges="true"
+ android:padding="5dp">
<TextView
- android:id="@+id/port_label"
- style="@style/item"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_alignParentRight="true"
- android:text="@string/port"
- android:textAppearance="?android:attr/textAppearanceSmall" />
+ android:id="@+id/port_label"
+ style="@style/item"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
+ android:text="@string/port"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
<TextView
- android:layout_toLeftOf="@id/port_label"
- android:layout_toStartOf="@id/port_label"
- android:id="@+id/server_label"
- style="@style/item"
- android:text="@string/address"
- android:textAppearance="?android:attr/textAppearanceSmall" />
+ android:layout_toLeftOf="@id/port_label"
+ android:layout_toStartOf="@id/port_label"
+ android:id="@+id/server_label"
+ style="@style/item"
+ android:text="@string/address"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
<EditText
- android:id="@+id/portnumber"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_alignParentRight="true"
+ android:id="@+id/portnumber"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
- android:layout_below="@id/port_label"
- android:inputType="numberDecimal"
- android:text="1194"
- android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
- tools:ignore="HardcodedText" />
+ android:layout_below="@id/port_label"
+ android:inputType="numberDecimal"
+ android:text="1194"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
+ tools:ignore="HardcodedText"/>
<EditText
- android:id="@+id/servername"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"
- android:layout_below="@id/server_label"
- android:layout_toLeftOf="@id/portnumber"
- android:layout_toStartOf="@id/portnumber"
- android:inputType="textUri"
- android:singleLine="true"
- tools:text="openvpn.blinkt.de"
- android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
- tools:ignore="HardcodedText" />
+ android:id="@+id/servername"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
+ android:layout_below="@id/server_label"
+ android:layout_toLeftOf="@id/portnumber"
+ android:layout_toStartOf="@id/portnumber"
+ android:inputType="textUri"
+ android:singleLine="true"
+ tools:text="openvpn.blinkt.de"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
+ tools:ignore="HardcodedText"/>
<TextView
- android:id="@+id/protocol"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/servername"
- android:paddingTop="10dp"
- android:text="@string/protocol" />
+ android:id="@+id/protocol"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/servername"
+ android:paddingTop="10dp"
+ android:text="@string/protocol"/>
<RadioGroup
- android:id="@+id/udptcpradiogroup"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/protocol"
- android:orientation="horizontal"
- android:paddingStart="20dp"
- android:paddingEnd="20dp"
- android:paddingRight="20dp"
- android:paddingLeft="20dp">
-
- <RadioButton
- android:id="@+id/udp_proto"
+ android:id="@+id/udptcpradiogroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="UDP"
- tools:ignore="HardcodedText" />
+ android:layout_below="@id/protocol"
+ android:orientation="horizontal"
+ android:paddingStart="20dp"
+ android:paddingEnd="20dp"
+ android:paddingRight="20dp"
+ android:paddingLeft="20dp">
+
+ <RadioButton
+ android:id="@+id/udp_proto"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="UDP"
+ tools:ignore="HardcodedText"/>
<Space
- android:layout_width="20dp"
- android:layout_height="wrap_content" />
+ android:layout_width="20dp"
+ android:layout_height="wrap_content"/>
<RadioButton
- android:id="@+id/tcp_proto"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="TCP"
- tools:ignore="HardcodedText" />
+ android:id="@+id/tcp_proto"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="TCP"
+ tools:ignore="HardcodedText"/>
</RadioGroup>
-
- <!-- <TextView
- android:paddingTop="10dp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/udptcpradiogroup"
- android:id="@+id/proxytext"
- android:text="Proxy" />
-
- <RadioGroup
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:id="@+id/proxygroup"
- android:paddingLeft="20dp"
- android:layout_below="@id/proxytext">
-
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="None" />
-
- <Space
- android:layout_width="10dp"
- android:layout_height="wrap_content" />
-
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="HTTP" />
-
- <Space
- android:layout_width="10dp"
- android:layout_height="wrap_content" />
-
- <RadioButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Socks" />
- </RadioGroup> -->
-
-
<TextView
- android:id="@+id/proxy_label"
- android:layout_below="@id/udptcpradiogroup"
- android:text="@string/proxy"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
+ android:id="@+id/proxy_label"
+ android:layout_below="@id/udptcpradiogroup"
+ android:text="@string/proxy"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ />
<RadioGroup
- android:id="@+id/proxyradiogroup"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/proxy_label"
- android:orientation="horizontal"
- android:paddingStart="20dp"
- android:paddingEnd="20dp"
- android:paddingRight="20dp"
- android:paddingLeft="20dp">
- <RadioButton
- android:id="@+id/proxy_none"
+ android:id="@+id/proxyradiogroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/Use_no_proxy" />
+ android:layout_below="@id/proxy_label"
+ android:orientation="horizontal"
+ android:paddingStart="20dp"
+ android:paddingEnd="20dp"
+ android:paddingRight="20dp"
+ android:paddingLeft="20dp">
+ <RadioButton
+ android:id="@+id/proxy_none"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/Use_no_proxy"/>
<Space
- android:layout_width="10dp"
- android:layout_height="wrap_content" />
+ android:layout_width="10dp"
+ android:layout_height="wrap_content"/>
<RadioButton
- android:id="@+id/proxy_http"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="HTTP"
- tools:ignore="HardcodedText" />
+ android:id="@+id/proxy_http"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="HTTP"
+ tools:ignore="HardcodedText"/>
<Space
- android:layout_width="10dp"
- android:layout_height="wrap_content" />
+ android:layout_width="10dp"
+ android:layout_height="wrap_content"/>
<RadioButton
- android:id="@+id/proxy_socks"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Socksv5"
- tools:ignore="HardcodedText" />
+ android:id="@+id/proxy_socks"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Socksv5"
+ tools:ignore="HardcodedText"/>
<Space
- android:layout_width="10dp"
- android:layout_height="wrap_content" />
+ android:layout_width="10dp"
+ android:layout_height="wrap_content"/>
<RadioButton
- android:id="@+id/proxy_orbot"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/tor_orbot"
- />
+ android:id="@+id/proxy_orbot"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/tor_orbot"
+ />
+
</RadioGroup>
<TextView
- android:id="@+id/proxyport_label"
- style="@style/item"
- android:layout_below="@id/proxyradiogroup"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_alignParentRight="true"
- android:text="@string/port"
- android:textAppearance="?android:attr/textAppearanceSmall" />
+ android:id="@+id/proxyport_label"
+ style="@style/item"
+ android:layout_below="@id/proxyradiogroup"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
+ android:text="@string/port"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
<TextView
- android:layout_below="@id/proxyradiogroup"
- android:layout_toLeftOf="@id/proxyport_label"
- android:layout_toStartOf="@id/proxyport_label"
- android:id="@+id/proxyserver_label"
- android:paddingStart="20dp"
- android:paddingLeft="20dp"
- style="@style/item"
- android:text="@string/address"
- android:textAppearance="?android:attr/textAppearanceSmall"
- tools:ignore="RtlSymmetry" />
+ android:layout_below="@id/proxyradiogroup"
+ android:layout_toLeftOf="@id/proxyport_label"
+ android:layout_toStartOf="@id/proxyport_label"
+ android:id="@+id/proxyserver_label"
+ android:paddingStart="20dp"
+ android:paddingLeft="20dp"
+ style="@style/item"
+ android:text="@string/address"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ tools:ignore="RtlSymmetry"/>
<EditText
- android:id="@+id/proxyport"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_alignParentRight="true"
+ android:id="@+id/proxyport"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
- android:layout_below="@id/proxyport_label"
- android:inputType="numberDecimal"
- android:text="8080"
- android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
- tools:ignore="HardcodedText" />
+ android:layout_below="@id/proxyport_label"
+ android:inputType="numberDecimal"
+ android:text="8080"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
+ tools:ignore="HardcodedText"/>
<EditText
- android:id="@+id/proxyname"
- android:layout_marginLeft="20dp"
- android:layout_marginStart="20dp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"
- android:layout_below="@id/proxyserver_label"
- android:layout_toLeftOf="@id/proxyport"
- android:layout_toStartOf="@id/proxyport"
- android:inputType="textUri"
- android:singleLine="true"
- tools:text="proxy.blinkt.de"
- android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
- tools:ignore="HardcodedText" />
+ android:id="@+id/proxyname"
+ android:layout_marginLeft="20dp"
+ android:layout_marginStart="20dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
+ android:layout_below="@id/proxyserver_label"
+ android:layout_toLeftOf="@id/proxyport"
+ android:layout_toStartOf="@id/proxyport"
+ android:inputType="textUri"
+ android:singleLine="true"
+ tools:text="proxy.blinkt.de"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
+ tools:ignore="HardcodedText"/>
+
+ <android.support.constraint.ConstraintLayout
+ android:visibility="gone"
+ tools:visibility="visible"
+ android:id="@+id/proxyauthlayout"
+ android:layout_marginLeft="20dp"
+ android:layout_marginStart="20dp"
+
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_below="@id/proxyname">
+
+ <CheckBox
+ android:id="@+id/enable_proxy_auth"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/enableproxyauth"
+ card_view:layout_constraintTop_toTopOf="parent"
+ android:layout_marginTop="0dp" card_view:layout_constraintStart_toStartOf="parent"
+ />
+
+
+ <TextView
+ android:id="@+id/httpuser_label"
+ style="@style/item"
+ android:layout_width="wrap_content"
+ android:layout_height="17dp"
+ android:layout_below="@id/enable_proxy_auth"
+ android:text="@string/auth_username"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_marginTop="12dp"
+ card_view:layout_constraintTop_toBottomOf="@+id/enable_proxy_auth"
+ card_view:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
+ android:layout_marginStart="0dp"/>
+
+
+ <TextView
+ android:layout_toRightOf="@id/httpuser_label"
+ android:layout_toEndOf="@id/httpuser_label"
+ android:layout_below="@id/enable_proxy_auth"
+ android:layout_width="wrap_content"
+ android:id="@+id/httppassword_label"
+ style="@style/item"
+ android:text="@string/auth_pwquery"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ card_view:layout_constraintStart_toStartOf="@+id/proxypassword"
+ android:layout_height="wrap_content"
+ card_view:layout_constraintBottom_toBottomOf="@+id/httpuser_label"
+ />
+
+
+ <EditText
+ android:id="@+id/proxyuser"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_below="@id/httpuser_label"
+ android:inputType="text"
+ android:hint="username"
+ android:minEms="6"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
+ tools:ignore="HardcodedText"
+ android:layout_marginTop="8dp" card_view:layout_constraintTop_toBottomOf="@+id/httpuser_label"
+ card_view:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
+ android:layout_marginStart="8dp"/>
+
+
+ <EditText
+ android:id="@+id/proxypassword"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_below="@id/httppassword_label"
+ android:layout_toRightOf="@id/proxyuser"
+ android:minEms="6"
+ android:layout_toEndOf="@id/proxyuser"
+ android:inputType="textPassword"
+ android:singleLine="true"
+ tools:text="geheim"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
+ card_view:layout_constraintTop_toTopOf="@+id/proxyuser"
+ card_view:layout_constraintStart_toEndOf="@+id/proxyuser" android:layout_marginLeft="16dp"
+ android:layout_marginStart="8dp"/>
+
+ </android.support.constraint.ConstraintLayout>
<TextView
- android:id="@+id/connect_timeout_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/proxyname"
- android:paddingTop="10dp"
- android:text="@string/connect_timeout" />
+ android:id="@+id/connect_timeout_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/proxyauthlayout"
+ android:paddingTop="10dp"
+ android:text="@string/connect_timeout"/>
<EditText
- android:id="@+id/connect_timeout"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_alignParentEnd="true"
- android:layout_below="@+id/connect_timeout_label"
- android:ems="3"
- tools:text="232"
- android:gravity="end"
- android:inputType="numberDecimal" />
+ android:id="@+id/connect_timeout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"
+ android:layout_below="@+id/connect_timeout_label"
+ android:ems="3"
+ tools:text="232"
+ android:gravity="end"
+ android:inputType="numberDecimal"/>
<SeekBar
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/connect_silder"
- android:max="300"
- android:layout_alignBottom="@id/connect_timeout"
- android:layout_toLeftOf="@id/connect_timeout"
- android:layout_toStartOf="@id/connect_timeout"
- android:layout_below="@id/connect_timeout_label" />
-
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/connect_silder"
+ android:max="300"
+ android:layout_alignBottom="@id/connect_timeout"
+ android:layout_toLeftOf="@id/connect_timeout"
+ android:layout_toStartOf="@id/connect_timeout"
+ android:layout_below="@id/connect_timeout_label"/>
<CheckBox
- android:id="@+id/use_customoptions"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/connect_timeout"
- android:paddingTop="10dp"
- android:text="@string/custom_connection_options" />
+ android:id="@+id/use_customoptions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/connect_timeout"
+ android:paddingTop="10dp"
+ android:text="@string/custom_connection_options"/>
<LinearLayout
- android:id="@+id/custom_options_layout"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/use_customoptions"
- android:orientation="vertical"
- android:paddingRight="10dp"
- android:paddingEnd="10dp"
- android:paddingLeft="10dp"
- android:paddingStart="10dp">
-
- <TextView
- android:id="@+id/warnung_custom"
+ android:id="@+id/custom_options_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/custom_connection_options_warng" />
+ android:layout_below="@id/use_customoptions"
+ android:orientation="vertical"
+ android:paddingRight="10dp"
+ android:paddingEnd="10dp"
+ android:paddingLeft="10dp"
+ android:paddingStart="10dp">
+
+ <TextView
+ android:id="@+id/warnung_custom"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/custom_connection_options_warng"/>
<EditText
- android:id="@+id/customoptions"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:inputType="textMultiLine"
- android:lines="5" />
+ android:id="@+id/customoptions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textMultiLine"
+ android:lines="5"/>
</LinearLayout>
<Switch
- android:id="@+id/remoteSwitch"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignEnd="@+id/portnumber"
- android:layout_alignRight="@+id/portnumber"
- android:layout_below="@+id/portnumber"
- android:layout_gravity="right|bottom"
- android:text="@string/enabled_connection_entry" />
+ android:id="@+id/remoteSwitch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignEnd="@+id/portnumber"
+ android:layout_alignRight="@+id/portnumber"
+ android:layout_below="@+id/portnumber"
+ android:layout_gravity="right|bottom"
+ android:text="@string/enabled_connection_entry"/>
<ImageButton
- android:id="@+id/remove_connection"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignEnd="@+id/portnumber"
- android:layout_alignRight="@+id/portnumber"
- android:layout_below="@id/remoteSwitch"
- android:layout_margin="12dp"
- android:background="@drawable/ic_menu_delete_grey"
- android:contentDescription="@string/remove_connection_entry"
- android:padding="12dp" />
+ android:id="@+id/remove_connection"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignEnd="@+id/portnumber"
+ android:layout_alignRight="@+id/portnumber"
+ android:layout_below="@id/remoteSwitch"
+ android:layout_margin="12dp"
+ android:background="@drawable/ic_menu_delete_grey"
+ android:contentDescription="@string/remove_connection_entry"
+ android:padding="12dp"/>
</RelativeLayout>
diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml
index de436325..2426e501 100755
--- a/main/src/main/res/values/strings.xml
+++ b/main/src/main/res/values/strings.xml
@@ -473,5 +473,5 @@
<string name="no_orbotfound">Orbot application cannot be found. Please install Orbot or use manual Socks v5 integration.</string>
<string name="faq_remote_api_title">Remote API</string>
<string name="faq_remote_api">OpenVPN for Android supports two remote APIs, a sophisticated API using AIDL (remoteEXample in the git repository) and a simple one using Intents. &lt;p>Examples using adb shell and the intents. Replace profilname with your profile name&lt;p>&lt;p> adb shell am start-activity -a android.intent.action.MAIN de.blinkt.openvpn/.api.DisconnectVPN&lt;p> adb shell am start-activity -a android.intent.action.MAIN -e de.blinkt.openvpn.api.profileName Blinkt de.blinkt.openvpn/.api.ConnectVPN</string>
-
+ <string name ="enableproxyauth">Enable Proxy Authentication</string>
</resources>
diff --git a/main/src/test/java/de/blinkt/openvpn/core/TestConfigParser.java b/main/src/test/java/de/blinkt/openvpn/core/TestConfigParser.java
index 6615a8f0..3e5c9895 100644
--- a/main/src/test/java/de/blinkt/openvpn/core/TestConfigParser.java
+++ b/main/src/test/java/de/blinkt/openvpn/core/TestConfigParser.java
@@ -40,7 +40,8 @@ public class TestConfigParser {
ConfigParser cp = new ConfigParser();
cp.parseConfig(new StringReader(miniconfig + httpproxypass));
VpnProfile p = cp.convertProfile();
- Assert.assertTrue(p.mCustomConfigOptions.contains(httpproxypass));
+ Assert.assertFalse(p.mCustomConfigOptions.contains(httpproxypass));
+
}
@@ -124,9 +125,18 @@ public class TestConfigParser {
ConfigParser cp = new ConfigParser();
cp.parseConfig(new StringReader(proxy));
VpnProfile vp = cp.convertProfile();
- String config = vp.getConfigFile(RuntimeEnvironment.application, false);
+ String config = vp.getConfigFile(RuntimeEnvironment.application, true);
Assert.assertTrue(config.contains("username12"));
Assert.assertTrue(config.contains("http-proxy 1.2.3.4"));
- }
+
+ config = vp.getConfigFile(RuntimeEnvironment.application, false);
+
+ Assert.assertFalse(config.contains("username12"));
+ Assert.assertFalse(config.contains("http-proxy 1.2.3.4"));
+
+ Assert.assertTrue(vp.mConnections[0].mUseProxyAuth);
+ Assert.assertEquals(vp.mConnections[0].mProxyAuthUser, "username12");
+ Assert.assertEquals(vp.mConnections[0].mProxyAuthPassword, "password34");
+ }
}