diff options
17 files changed, 354 insertions, 14 deletions
| diff --git a/build.gradle b/build.gradle index 8ca83b77..ca14f438 100644 --- a/build.gradle +++ b/build.gradle @@ -39,6 +39,15 @@ android {              assets.srcDirs = ['assets']          } +        xposedmodule { +            manifest.srcFile 'xposed/AndroidManifest.xml' +            java.srcDirs = ['xposed/src'] +            resources.srcDirs = ['xposed/src'] +            aidl.srcDirs = ['xposed/src'] +            renderscript.srcDirs = ['xposed/src'] +            res.srcDirs = ['xposed/res'] +            assets.srcDirs = ['xposed/assets'] +        }      } diff --git a/openvpn/src/openvpn/socket.c b/openvpn/src/openvpn/socket.c index ee44ad3c..f6af489e 100644 --- a/openvpn/src/openvpn/socket.c +++ b/openvpn/src/openvpn/socket.c @@ -1191,6 +1191,7 @@ resolve_remote (struct link_socket *sock,  	      unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags);  	      int retry = 0;  	      int status = -1; +              struct addrinfo* ai;                if (proto_is_dgram(sock->info.proto))                    flags |= GETADDR_DATAGRAM; @@ -1229,20 +1230,20 @@ resolve_remote (struct link_socket *sock,  		  ASSERT (0);  		} -		  struct addrinfo* ai; -		  status = openvpn_getaddrinfo (flags, sock->remote_host, sock->remote_port, -                                               retry, signal_received, sock->info.af, &ai); -		  if(status == 0) { -                          sock->info.lsa->remote_list = ai; -                          sock->info.lsa->current_remote = ai; - -			  dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", -					flags, -					phase, -					retry, -					signal_received ? *signal_received : -1, -					status); -		  } +	      status = openvpn_getaddrinfo (flags, sock->remote_host, sock->remote_port, +					    retry, signal_received, sock->info.af, &ai); + +	      if(status == 0) { +		sock->info.lsa->remote_list = ai; +		sock->info.lsa->current_remote = ai; + +		dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", +		      flags, +		      phase, +		      retry, +		      signal_received ? *signal_received : -1, +		      status); +	      }  	      if (signal_received)  		{  		  if (*signal_received) diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..a81923f4 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':vpndialogxposed' diff --git a/vpndialogxposed/AndroidManifest.xml b/vpndialogxposed/AndroidManifest.xmlBinary files differ new file mode 100755 index 00000000..23a64bdd --- /dev/null +++ b/vpndialogxposed/AndroidManifest.xml diff --git a/vpndialogxposed/src/main/AndroidManifest.xml b/vpndialogxposed/src/main/AndroidManifest.xml new file mode 100644 index 00000000..d34264c7 --- /dev/null +++ b/vpndialogxposed/src/main/AndroidManifest.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" +    package="de.blinkt.vpndialogxposed" +    android:versionCode="1" +    android:versionName="1.0" > + +    <uses-sdk +        android:minSdkVersion="14" +        android:targetSdkVersion="17" /> + +    <application +        android:allowBackup="true" +        android:icon="@drawable/ic_launcher" +        android:label="@string/app_name" +        android:theme="@style/AppTheme" > + +        <meta-data android:value="true" android:name="xposedmodule"/> +        <meta-data android:value="2.0*" android:name="xposedminversion"/> +        <meta-data android:value="Allows OpenVPN for Android to establish a VPN connection without confirmation dialog" android:name="xposeddescription"/> +    </application> + +</manifest> diff --git a/vpndialogxposed/src/main/assets/xposed_init b/vpndialogxposed/src/main/assets/xposed_init new file mode 100644 index 00000000..b228b31c --- /dev/null +++ b/vpndialogxposed/src/main/assets/xposed_init @@ -0,0 +1 @@ +de.blinkt.vpndialogxposed.VpnDialogPatcher diff --git a/vpndialogxposed/src/main/java/de/blinkt/vpndialogxposed/IConnectivityManager.java b/vpndialogxposed/src/main/java/de/blinkt/vpndialogxposed/IConnectivityManager.java new file mode 100644 index 00000000..9b26283e --- /dev/null +++ b/vpndialogxposed/src/main/java/de/blinkt/vpndialogxposed/IConnectivityManager.java @@ -0,0 +1,105 @@ +/* + * This file is auto-generated.  DO NOT MODIFY. + * Original file: /Users/arne/software/icsopenvpn/vpndialogxposed/src/main/aidl/android/net/IConnectivityManager.aidl + */ +package de.blinkt.vpndialogxposed; +/** + * Interface that answers queries about, and allows changing, the + * state of network connectivity. + */ + +/** + * {@hide} + */ +public interface IConnectivityManager extends android.os.IInterface { +    public boolean prepareVpn(java.lang.String oldPackage, java.lang.String newPackage) throws android.os.RemoteException; + +    /** Local-side IPC implementation stub class. */ +    public static abstract class Stub extends android.os.Binder implements IConnectivityManager { +        static final int TRANSACTION_prepareVpn = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); +        private static final java.lang.String DESCRIPTOR = "android.net.IConnectivityManager"; + +        /** Construct the stub at attach it to the interface. */ +        public Stub() { +            this.attachInterface(this, DESCRIPTOR); +        } + +        /** +         * Cast an IBinder object into an android.net.IConnectivityManager interface, +         * generating a proxy if needed. +         */ +        public static IConnectivityManager asInterface(android.os.IBinder obj) { +            if ((obj == null)) { +                return null; +            } +            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); +            if (((iin != null) && (iin instanceof IConnectivityManager))) { +                return ((IConnectivityManager) iin); +            } +            return new IConnectivityManager.Stub.Proxy(obj); +        } + +        @Override +        public android.os.IBinder asBinder() { +            return this; +        } + +        @Override +        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { +            switch (code) { +                case INTERFACE_TRANSACTION: { +                    reply.writeString(DESCRIPTOR); +                    return true; +                } +                case TRANSACTION_prepareVpn: { +                    data.enforceInterface(DESCRIPTOR); +                    java.lang.String _arg0; +                    _arg0 = data.readString(); +                    java.lang.String _arg1; +                    _arg1 = data.readString(); +                    boolean _result = this.prepareVpn(_arg0, _arg1); +                    reply.writeNoException(); +                    reply.writeInt(((_result) ? (1) : (0))); +                    return true; +                } +            } +            return super.onTransact(code, data, reply, flags); +        } + +        private static class Proxy implements IConnectivityManager { +            private android.os.IBinder mRemote; + +            Proxy(android.os.IBinder remote) { +                mRemote = remote; +            } + +            @Override +            public android.os.IBinder asBinder() { +                return mRemote; +            } + +            public java.lang.String getInterfaceDescriptor() { +                return DESCRIPTOR; +            } + +            @Override +            public boolean prepareVpn(java.lang.String oldPackage, java.lang.String newPackage) throws android.os.RemoteException { +                android.os.Parcel _data = android.os.Parcel.obtain(); +                android.os.Parcel _reply = android.os.Parcel.obtain(); +                boolean _result; +                try { +                    _data.writeInterfaceToken(DESCRIPTOR); +                    _data.writeString(oldPackage); +                    _data.writeString(newPackage); +                    mRemote.transact(Stub.TRANSACTION_prepareVpn, _data, _reply, 0); +                    _reply.readException(); +                    _result = (0 != _reply.readInt()); +                } finally { +                    _reply.recycle(); +                    _data.recycle(); +                } +                return _result; +            } +        } +    } +} diff --git a/vpndialogxposed/src/main/java/de/blinkt/vpndialogxposed/VpnDialogPatcher.java b/vpndialogxposed/src/main/java/de/blinkt/vpndialogxposed/VpnDialogPatcher.java new file mode 100644 index 00000000..74cd97e4 --- /dev/null +++ b/vpndialogxposed/src/main/java/de/blinkt/vpndialogxposed/VpnDialogPatcher.java @@ -0,0 +1,66 @@ +package de.blinkt.vpndialogxposed; + +import android.app.Activity; +import android.content.Context; +import android.os.IBinder; +import android.widget.Toast; +import de.robv.android.xposed.IXposedHookLoadPackage; +import de.robv.android.xposed.XC_MethodHook; +import de.robv.android.xposed.XposedBridge; +import de.robv.android.xposed.XposedHelpers; +import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; + +import java.lang.reflect.Method; + +public class VpnDialogPatcher implements IXposedHookLoadPackage { +    @Override +    public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable { +        if (!lpparam.packageName.equals("com.android.vpndialogs")) +            return; + + +        XposedBridge.log("Got VPN Dialog"); + +        XposedHelpers.findAndHookMethod("com.android.vpndialogs.ConfirmDialog", lpparam.classLoader, +                "onResume", new XC_MethodHook() { +            @Override +            protected void afterHookedMethod(MethodHookParam param) throws Throwable { + +               // IConnectivityManager mService = IConnectivityManager.Stub.asInterface( +                //        ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); + +                try { + +                    /*Class servicemanager = Class.forName("android.os.ServiceManager"); +                    Method getService = servicemanager.getMethod("getService",String.class); + +                    IConnectivityManager mService = IConnectivityManager.Stub.asInterface( +                            (IBinder) getService.invoke(servicemanager, Context.CONNECTIVITY_SERVICE)); +                            */ + +                    Object mService = XposedHelpers.getObjectField(param.thisObject, "mService"); + +                    String mPackage = ((Activity) param.thisObject).getCallingPackage(); + +                     // App is already allowed do nothing +                    if (mService.prepareVpn(mPackage, null)) { +                        return; +                    } + +                    if (mPackage.equals("de.blinkt.openvpn")) { +                        mService.prepareVpn(null, mPackage); +                        Toast.makeText((Context)param.thisObject,"Allowed de.blinkt.openvpn",Toast.LENGTH_LONG).show(); +                    } + +                } catch (Exception e) { +                    e.printStackTrace(); + +                } + +            } + + +        }); + +    } +} diff --git a/vpndialogxposed/src/main/res/drawable-hdpi/ic_launcher.png b/vpndialogxposed/src/main/res/drawable-hdpi/ic_launcher.pngBinary files differ new file mode 100644 index 00000000..a134d5fa --- /dev/null +++ b/vpndialogxposed/src/main/res/drawable-hdpi/ic_launcher.png diff --git a/vpndialogxposed/src/main/res/drawable-mdpi/ic_launcher.png b/vpndialogxposed/src/main/res/drawable-mdpi/ic_launcher.pngBinary files differ new file mode 100644 index 00000000..ad6d2155 --- /dev/null +++ b/vpndialogxposed/src/main/res/drawable-mdpi/ic_launcher.png diff --git a/vpndialogxposed/src/main/res/drawable-xhdpi/ic_launcher.png b/vpndialogxposed/src/main/res/drawable-xhdpi/ic_launcher.pngBinary files differ new file mode 100644 index 00000000..10d3c009 --- /dev/null +++ b/vpndialogxposed/src/main/res/drawable-xhdpi/ic_launcher.png diff --git a/vpndialogxposed/src/main/res/drawable-xxhdpi/ic_launcher.png b/vpndialogxposed/src/main/res/drawable-xxhdpi/ic_launcher.pngBinary files differ new file mode 100644 index 00000000..22db1531 --- /dev/null +++ b/vpndialogxposed/src/main/res/drawable-xxhdpi/ic_launcher.png diff --git a/vpndialogxposed/src/main/res/layout/activity_main.xml b/vpndialogxposed/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..efcbf18d --- /dev/null +++ b/vpndialogxposed/src/main/res/layout/activity_main.xml @@ -0,0 +1,16 @@ +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +    xmlns:tools="http://schemas.android.com/tools" +    android:layout_width="match_parent" +    android:layout_height="match_parent" +    android:paddingLeft="@dimen/activity_horizontal_margin" +    android:paddingRight="@dimen/activity_horizontal_margin" +    android:paddingTop="@dimen/activity_vertical_margin" +    android:paddingBottom="@dimen/activity_vertical_margin" +    tools:context=".MainActivity"> + +    <TextView +        android:layout_width="wrap_content" +        android:layout_height="wrap_content" +        android:text="@string/hello_world" /> + +</RelativeLayout> diff --git a/vpndialogxposed/src/main/res/menu/main.xml b/vpndialogxposed/src/main/res/menu/main.xml new file mode 100644 index 00000000..f3b10b6c --- /dev/null +++ b/vpndialogxposed/src/main/res/menu/main.xml @@ -0,0 +1,6 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android"> +    <item android:id="@+id/action_settings" +        android:title="@string/action_settings" +        android:orderInCategory="100" +        android:showAsAction="never" /> +</menu> diff --git a/vpndialogxposed/src/main/res/values/strings.xml b/vpndialogxposed/src/main/res/values/strings.xml new file mode 100644 index 00000000..f233e945 --- /dev/null +++ b/vpndialogxposed/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + +    <string name="app_name">VpnDialog Xposed Module</string> +    <string name="action_settings">Settings</string> +    <string name="hello_world">Hello world!</string> + +</resources> diff --git a/vpndialogxposed/src/main/res/values/styles.xml b/vpndialogxposed/src/main/res/values/styles.xml new file mode 100644 index 00000000..6ce89c7b --- /dev/null +++ b/vpndialogxposed/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ +<resources> + +    <!-- +        Base application theme, dependent on API level. This theme is replaced +        by AppBaseTheme from res/values-vXX/styles.xml on newer devices. +    --> +    <style name="AppBaseTheme" parent="android:Theme.Light"> +        <!-- +            Theme customizations available in newer API levels can go in +            res/values-vXX/styles.xml, while customizations related to +            backward-compatibility can go here. +        --> +    </style> + +    <!-- Application theme. --> +    <style name="AppTheme" parent="AppBaseTheme"> +        <!-- All customizations that are NOT specific to a particular API-level can go here. --> +    </style> + +</resources> diff --git a/vpndialogxposed/vpndialogxposed.iml b/vpndialogxposed/vpndialogxposed.iml new file mode 100644 index 00000000..a1c6e847 --- /dev/null +++ b/vpndialogxposed/vpndialogxposed.iml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module external.linked.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4"> +  <component name="FacetManager"> +    <facet type="android" name="Android"> +      <configuration> +        <option name="SELECTED_BUILD_VARIANT" value="Debug" /> +        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> +        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleTest" /> +        <option name="SOURCE_GEN_TASK_NAME" value="TODO" /> +        <option name="ALLOW_USER_CONFIGURATION" value="false" /> +        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> +        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> +        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" /> +      </configuration> +    </facet> +    <facet type="android-gradle" name="Android-Gradle"> +      <configuration> +        <option name="GRADLE_PROJECT_PATH" value=":vpndialogxposed" /> +      </configuration> +    </facet> +  </component> +  <component name="NewModuleRootManager" inherit-compiler-output="false"> +    <output url="file://$MODULE_DIR$/build/classes/debug" /> +    <exclude-output /> +    <content url="file://$MODULE_DIR$"> +      <sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/build/source/r/test" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/build/source/rs/test" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/build/res/rs/test" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/main/res" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" /> +      <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/aidl" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/assets" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/java" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/jni" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/rs" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" isTestSource="true" /> +      <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/resources" isTestSource="true" /> +      <excludeFolder url="file://$MODULE_DIR$/build/apk" /> +      <excludeFolder url="file://$MODULE_DIR$/build/assets" /> +      <excludeFolder url="file://$MODULE_DIR$/build/bundles" /> +      <excludeFolder url="file://$MODULE_DIR$/build/classes" /> +      <excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" /> +      <excludeFolder url="file://$MODULE_DIR$/build/exploded-bundles" /> +      <excludeFolder url="file://$MODULE_DIR$/build/incremental" /> +      <excludeFolder url="file://$MODULE_DIR$/build/libs" /> +      <excludeFolder url="file://$MODULE_DIR$/build/manifests" /> +      <excludeFolder url="file://$MODULE_DIR$/build/symbols" /> +      <excludeFolder url="file://$MODULE_DIR$/build/tmp" /> +    </content> +    <orderEntry type="jdk" jdkName="Android 4.2.2" jdkType="Android SDK" /> +    <orderEntry type="sourceFolder" forTests="false" /> +    <orderEntry type="library" exported="" name="annotations-12.0" level="project" /> +    <orderEntry type="module-library"> +      <library> +        <CLASSES> +          <root url="jar://$MODULE_DIR$/libs/XposedBridgeApi.jar!/" /> +        </CLASSES> +        <JAVADOC /> +        <SOURCES> +          <root url="jar://$MODULE_DIR$/libs/XposedBridgeApi.jar!/" /> +        </SOURCES> +      </library> +    </orderEntry> +  </component> +</module> + | 
