mirror of
https://github.com/schwabe/ics-openvpn.git
synced 2024-09-20 12:02:28 +02:00
Add external API with security.
This commit is contained in:
parent
ad2256b6fe
commit
bde3a3f780
@ -18,8 +18,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="de.blinkt.openvpn"
|
||||
android:versionCode="65"
|
||||
android:versionName="0.5.36a" >
|
||||
android:versionCode="66"
|
||||
android:versionName="0.5.36b" >
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
@ -82,8 +82,13 @@
|
||||
</service>
|
||||
|
||||
<activity
|
||||
android:name=".api.GrantPermissionsActivity"
|
||||
android:permission="de.blinkt.openvpn.REMOTE_API" >
|
||||
android:name=".api.GrantPermissionsActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".api.ConfirmDialog" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
@ -152,6 +157,7 @@
|
||||
android:targetActivity=".LaunchVPN" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.CREATE_SHORTCUT" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
@ -164,4 +170,4 @@
|
||||
tools:ignore="ExportedContentProvider" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
57
res/layout/api_confirm.xml
Normal file
57
res/layout/api_confirm.xml
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="3mm">
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView android:id="@+id/icon"
|
||||
android:layout_width="@android:dimen/app_icon_size"
|
||||
android:layout_height="@android:dimen/app_icon_size"
|
||||
android:paddingRight="1mm"/>
|
||||
|
||||
<TextView android:id="@+id/prompt"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView android:id="@+id/warning"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="1mm"
|
||||
android:paddingBottom="1mm"
|
||||
android:text="@string/remote_warning"
|
||||
android:textSize="18sp"/>
|
||||
|
||||
<CheckBox android:id="@+id/check"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/remote_trust"
|
||||
android:textSize="20sp"
|
||||
android:checked="false"/>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
@ -277,5 +277,9 @@
|
||||
<string name="rdn_prefix">RDN prefix</string>
|
||||
<string name="tls_remote_deprecated">tls-remote (DEPRECATED)</string>
|
||||
<string name="help_translate">You can help translating by visiting http://crowdin.net/project/ics-openvpn/invite</string>
|
||||
<!-- Dialog title to identify the request from a VPN application. [CHAR LIMIT=60] -->
|
||||
<string name="prompt">%1$s attempts to control %2$s</string>
|
||||
<string name="remote_warning">By proceeding, you are giving the application permission to completely control OpenVPN for Android and to intercept all network traffic. <b> Do NOT accept unless you trust the application. </b> Otherwise, you run the risk of having your data compromised by malicious software."</string>
|
||||
<string name="remote_trust">I trust this application.</string>
|
||||
|
||||
</resources>
|
1
src/de/blinkt/openvpn/api/APIVpnProfile.aidl
Normal file
1
src/de/blinkt/openvpn/api/APIVpnProfile.aidl
Normal file
@ -0,0 +1 @@
|
||||
parcelable APIVpnProfile;
|
56
src/de/blinkt/openvpn/api/APIVpnProfile.java
Normal file
56
src/de/blinkt/openvpn/api/APIVpnProfile.java
Normal file
@ -0,0 +1,56 @@
|
||||
package de.blinkt.openvpn.api;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public class APIVpnProfile implements Parcelable {
|
||||
|
||||
public final String mUUID;
|
||||
public final String mName;
|
||||
public final boolean mUserEditable;
|
||||
|
||||
|
||||
|
||||
public APIVpnProfile(Parcel in) {
|
||||
mUUID = in.readString();
|
||||
mName = in.readString();
|
||||
if(in.readInt()==0)
|
||||
mUserEditable=false;
|
||||
else
|
||||
mUserEditable=true;
|
||||
}
|
||||
|
||||
public APIVpnProfile(String uuidString, String name, boolean userEditable) {
|
||||
mUUID=uuidString;
|
||||
mName = name;
|
||||
mUserEditable=userEditable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(mUUID);
|
||||
dest.writeString(mName);
|
||||
if(mUserEditable)
|
||||
dest.writeInt(0);
|
||||
else
|
||||
dest.writeInt(1);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<APIVpnProfile> CREATOR
|
||||
= new Parcelable.Creator<APIVpnProfile>() {
|
||||
public APIVpnProfile createFromParcel(Parcel in) {
|
||||
return new APIVpnProfile(in);
|
||||
}
|
||||
|
||||
public APIVpnProfile[] newArray(int size) {
|
||||
return new APIVpnProfile[size];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
123
src/de/blinkt/openvpn/api/ConfirmDialog.java
Normal file
123
src/de/blinkt/openvpn/api/ConfirmDialog.java
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package de.blinkt.openvpn.api;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AlertDialog.Builder;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnShowListener;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import de.blinkt.openvpn.R;
|
||||
|
||||
|
||||
public class ConfirmDialog extends Activity implements
|
||||
CompoundButton.OnCheckedChangeListener, DialogInterface.OnClickListener {
|
||||
private static final String TAG = "OpenVPNVpnConfirm";
|
||||
|
||||
private String mPackage;
|
||||
|
||||
private Button mButton;
|
||||
|
||||
private AlertDialog mAlert;
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
try {
|
||||
mPackage = getCallingPackage();
|
||||
if (mPackage==null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
PackageManager pm = getPackageManager();
|
||||
ApplicationInfo app = pm.getApplicationInfo(mPackage, 0);
|
||||
|
||||
View view = View.inflate(this, R.layout.api_confirm, null);
|
||||
((ImageView) view.findViewById(R.id.icon)).setImageDrawable(app.loadIcon(pm));
|
||||
((TextView) view.findViewById(R.id.prompt)).setText(
|
||||
getString(R.string.prompt, app.loadLabel(pm), getString(R.string.app)));
|
||||
((CompoundButton) view.findViewById(R.id.check)).setOnCheckedChangeListener(this);
|
||||
|
||||
|
||||
Builder builder = new AlertDialog.Builder(this);
|
||||
|
||||
builder.setView(view);
|
||||
|
||||
builder.setIconAttribute(android.R.attr.alertDialogIcon);
|
||||
builder.setTitle(android.R.string.dialog_alert_title);
|
||||
builder.setPositiveButton(android.R.string.ok,this);
|
||||
builder.setNegativeButton(android.R.string.cancel,this);
|
||||
|
||||
mAlert = builder.create();
|
||||
|
||||
mAlert.setOnShowListener (new OnShowListener() {
|
||||
|
||||
@Override
|
||||
public void onShow(DialogInterface dialog) {
|
||||
// TODO Auto-generated method stub
|
||||
mButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
mButton.setEnabled(false);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
//setCloseOnTouchOutside(false);
|
||||
|
||||
mAlert.show();
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "onResume", e);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton button, boolean checked) {
|
||||
mButton.setEnabled(checked);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
ExternalAppDatabase extapps = new ExternalAppDatabase(this);
|
||||
extapps.addApp(mPackage);
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
|
||||
if (which == DialogInterface.BUTTON_NEGATIVE) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
58
src/de/blinkt/openvpn/api/ExternalAppDatabase.java
Normal file
58
src/de/blinkt/openvpn/api/ExternalAppDatabase.java
Normal file
@ -0,0 +1,58 @@
|
||||
package de.blinkt.openvpn.api;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public class ExternalAppDatabase {
|
||||
|
||||
Context mContext;
|
||||
|
||||
public ExternalAppDatabase(Context c) {
|
||||
mContext =c;
|
||||
}
|
||||
|
||||
private final String PREFERENCES_KEY = "PREFERENCES_KEY";
|
||||
|
||||
boolean isAllowed(String packagename) {
|
||||
Set<String> allowedapps = getExtAppList();
|
||||
|
||||
return allowedapps.contains(packagename);
|
||||
|
||||
}
|
||||
|
||||
Set<String> getExtAppList() {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
Set<String> allowedapps = prefs.getStringSet(PREFERENCES_KEY, new HashSet<String>());
|
||||
return allowedapps;
|
||||
}
|
||||
|
||||
void addApp(String packagename)
|
||||
{
|
||||
Set<String> allowedapps = getExtAppList();
|
||||
allowedapps.add(packagename);
|
||||
saveExtAppList(allowedapps);
|
||||
}
|
||||
|
||||
private void saveExtAppList( Set<String> allowedapps) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
Editor prefedit = prefs.edit();
|
||||
prefedit.putStringSet(PREFERENCES_KEY, allowedapps);
|
||||
prefedit.apply();
|
||||
}
|
||||
|
||||
void clearAllApiApps() {
|
||||
saveExtAppList(new HashSet<String>());
|
||||
}
|
||||
|
||||
public void removeApp(String packagename) {
|
||||
Set<String> allowedapps = getExtAppList();
|
||||
allowedapps.remove(packagename);
|
||||
saveExtAppList(allowedapps);
|
||||
}
|
||||
|
||||
}
|
238
src/de/blinkt/openvpn/api/ExternalOpenVPNService.java
Normal file
238
src/de/blinkt/openvpn/api/ExternalOpenVPNService.java
Normal file
@ -0,0 +1,238 @@
|
||||
package de.blinkt.openvpn.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.net.VpnService;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import de.blinkt.openvpn.R;
|
||||
import de.blinkt.openvpn.VpnProfile;
|
||||
import de.blinkt.openvpn.core.ConfigParser;
|
||||
import de.blinkt.openvpn.core.ConfigParser.ConfigParseError;
|
||||
import de.blinkt.openvpn.core.OpenVPN;
|
||||
import de.blinkt.openvpn.core.OpenVPN.ConnectionStatus;
|
||||
import de.blinkt.openvpn.core.OpenVPN.StateListener;
|
||||
import de.blinkt.openvpn.core.OpenVpnService;
|
||||
import de.blinkt.openvpn.core.OpenVpnService.LocalBinder;
|
||||
import de.blinkt.openvpn.core.ProfileManager;
|
||||
import de.blinkt.openvpn.core.VPNLaunchHelper;
|
||||
|
||||
public class ExternalOpenVPNService extends Service implements StateListener {
|
||||
|
||||
final RemoteCallbackList<IOpenVPNStatusCallback> mCallbacks =
|
||||
new RemoteCallbackList<IOpenVPNStatusCallback>();
|
||||
|
||||
private OpenVpnService mService;
|
||||
private ExternalAppDatabase mExtAppDb;
|
||||
|
||||
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className,
|
||||
IBinder service) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
LocalBinder binder = (LocalBinder) service;
|
||||
mService = binder.getService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName arg0) {
|
||||
mService =null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
OpenVPN.addStateListener(this);
|
||||
mExtAppDb = new ExternalAppDatabase(this);
|
||||
|
||||
Intent intent = new Intent(getBaseContext(), OpenVpnService.class);
|
||||
intent.setAction(OpenVpnService.START_SERVICE);
|
||||
|
||||
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
private final IOpenVPNAPIService.Stub mBinder = new IOpenVPNAPIService.Stub() {
|
||||
private boolean checkOpenVPNPermission() throws SecurityRemoteException{
|
||||
PackageManager pm = getPackageManager();
|
||||
|
||||
for (String apppackage:mExtAppDb.getExtAppList()) {
|
||||
ApplicationInfo app;
|
||||
try {
|
||||
app = pm.getApplicationInfo(apppackage, 0);
|
||||
if (Binder.getCallingUid() == app.uid) {
|
||||
return true;
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
// App not found. Remove it from the list
|
||||
mExtAppDb.removeApp(apppackage);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
throw new SecurityException("Unauthorized OpenVPN API Caller");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<APIVpnProfile> getProfiles() throws RemoteException {
|
||||
checkOpenVPNPermission();
|
||||
|
||||
ProfileManager pm = ProfileManager.getInstance(getBaseContext());
|
||||
|
||||
List<APIVpnProfile> profiles = new LinkedList<APIVpnProfile>();
|
||||
|
||||
for(VpnProfile vp: pm.getProfiles())
|
||||
profiles.add(new APIVpnProfile(vp.getUUIDString(),vp.mName,vp.mUserEditable));
|
||||
|
||||
return profiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startProfile(String profileUUID) throws RemoteException {
|
||||
checkOpenVPNPermission();
|
||||
|
||||
Intent shortVPNIntent = new Intent(Intent.ACTION_MAIN);
|
||||
shortVPNIntent.setClass(getBaseContext(),de.blinkt.openvpn.LaunchVPN.class);
|
||||
shortVPNIntent.putExtra(de.blinkt.openvpn.LaunchVPN.EXTRA_KEY,profileUUID);
|
||||
shortVPNIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(shortVPNIntent);
|
||||
}
|
||||
|
||||
public void startVPN(String inlineconfig) throws RemoteException {
|
||||
checkOpenVPNPermission();
|
||||
|
||||
ConfigParser cp = new ConfigParser();
|
||||
try {
|
||||
cp.parseConfig(new StringReader(inlineconfig));
|
||||
VpnProfile vp = cp.convertProfile();
|
||||
if(vp.checkProfile(getApplicationContext()) != R.string.no_error_found)
|
||||
throw new RemoteException(getString(vp.checkProfile(getApplicationContext())));
|
||||
|
||||
|
||||
ProfileManager.setTemporaryProfile(vp);
|
||||
VPNLaunchHelper.startOpenVpn(vp, getBaseContext());
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RemoteException(e.getMessage());
|
||||
} catch (ConfigParseError e) {
|
||||
throw new RemoteException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addVPNProfile(String name, String config) throws RemoteException {
|
||||
checkOpenVPNPermission();
|
||||
|
||||
ConfigParser cp = new ConfigParser();
|
||||
try {
|
||||
cp.parseConfig(new StringReader(config));
|
||||
VpnProfile vp = cp.convertProfile();
|
||||
vp.mName = name;
|
||||
ProfileManager pm = ProfileManager.getInstance(getBaseContext());
|
||||
pm.addProfile(vp);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} catch (ConfigParseError e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Intent prepare(String packagename) {
|
||||
if (new ExternalAppDatabase(ExternalOpenVPNService.this).isAllowed(packagename))
|
||||
return null;
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(ExternalOpenVPNService.this, ConfirmDialog.class);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission() throws RemoteException {
|
||||
checkOpenVPNPermission();
|
||||
|
||||
return VpnService.prepare(ExternalOpenVPNService.this)==null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void registerStatusCallback(IOpenVPNStatusCallback cb)
|
||||
throws RemoteException {
|
||||
checkOpenVPNPermission();
|
||||
|
||||
if (cb != null) mCallbacks.register(cb);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterStatusCallback(IOpenVPNStatusCallback cb)
|
||||
throws RemoteException {
|
||||
checkOpenVPNPermission();
|
||||
|
||||
if (cb != null) mCallbacks.unregister(cb);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() throws RemoteException {
|
||||
checkOpenVPNPermission();
|
||||
|
||||
mService.getManagement().stopVPN();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mCallbacks.kill();
|
||||
unbindService(mConnection);
|
||||
OpenVPN.removeStateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(String state, String logmessage, int resid, ConnectionStatus level) {
|
||||
// Broadcast to all clients the new value.
|
||||
final int N = mCallbacks.beginBroadcast();
|
||||
for (int i=0; i<N; i++) {
|
||||
try {
|
||||
mCallbacks.getBroadcastItem(i).newStatus(state,logmessage);
|
||||
} catch (RemoteException e) {
|
||||
// The RemoteCallbackList will take care of removing
|
||||
// the dead object for us.
|
||||
}
|
||||
}
|
||||
mCallbacks.finishBroadcast();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
26
src/de/blinkt/openvpn/api/GrantPermissionsActivity.java
Normal file
26
src/de/blinkt/openvpn/api/GrantPermissionsActivity.java
Normal file
@ -0,0 +1,26 @@
|
||||
package de.blinkt.openvpn.api;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.VpnService;
|
||||
|
||||
public class GrantPermissionsActivity extends Activity {
|
||||
private static final int VPN_PREPARE = 0;
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
Intent i= VpnService.prepare(this);
|
||||
if(i==null)
|
||||
onActivityResult(VPN_PREPARE, RESULT_OK, null);
|
||||
else
|
||||
startActivityForResult(i, VPN_PREPARE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
setResult(resultCode);
|
||||
finish();
|
||||
}
|
||||
}
|
41
src/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl
Normal file
41
src/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl
Normal file
@ -0,0 +1,41 @@
|
||||
// IOpenVPNAPIService.aidl
|
||||
package de.blinkt.openvpn.api;
|
||||
|
||||
import de.blinkt.openvpn.api.APIVpnProfile;
|
||||
import de.blinkt.openvpn.api.IOpenVPNStatusCallback;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
interface IOpenVPNAPIService {
|
||||
List<APIVpnProfile> getProfiles();
|
||||
|
||||
void startProfile (String profileUUID);
|
||||
|
||||
/* Use a profile with all certificates etc. embedded */
|
||||
boolean addVPNProfile (String name, String config);
|
||||
|
||||
/* start a profile using an config */
|
||||
void startVPN (String inlineconfig);
|
||||
|
||||
/* This permission framework is used to avoid confused deputy style attack to the VPN
|
||||
* calling this will give null if the app is allowed to use the frame and null otherwise */
|
||||
Intent prepare (String packagename);
|
||||
|
||||
/* Tells the calling app wether we already have permission to avoid calling the activity/flicker */
|
||||
boolean hasPermission();
|
||||
|
||||
/* Disconnect the VPN */
|
||||
void disconnect();
|
||||
|
||||
/**
|
||||
* Registers to receive OpenVPN Status Updates
|
||||
*/
|
||||
void registerStatusCallback(IOpenVPNStatusCallback cb);
|
||||
|
||||
/**
|
||||
* Remove a previously registered callback interface.
|
||||
*/
|
||||
void unregisterStatusCallback(IOpenVPNStatusCallback cb);
|
||||
|
||||
}
|
13
src/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl
Normal file
13
src/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl
Normal file
@ -0,0 +1,13 @@
|
||||
package de.blinkt.openvpn.api;
|
||||
|
||||
/**
|
||||
* Example of a callback interface used by IRemoteService to send
|
||||
* synchronous notifications back to its clients. Note that this is a
|
||||
* one-way interface so the server does not block waiting for the client.
|
||||
*/
|
||||
oneway interface IOpenVPNStatusCallback {
|
||||
/**
|
||||
* Called when the service has a new status for you.
|
||||
*/
|
||||
void newStatus(String state, String message);
|
||||
}
|
12
src/de/blinkt/openvpn/api/SecurityRemoteException.java
Normal file
12
src/de/blinkt/openvpn/api/SecurityRemoteException.java
Normal file
@ -0,0 +1,12 @@
|
||||
package de.blinkt.openvpn.api;
|
||||
|
||||
import android.os.RemoteException;
|
||||
|
||||
public class SecurityRemoteException extends RemoteException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user