0
0
mirror of https://github.com/schwabe/ics-openvpn.git synced 2024-09-19 19:42:29 +02:00

Allow OpenVPNService to request VPN permission if it is missing

With other services no longer being able to easily request permissions
the service needs now its own way to request permissions.
This commit is contained in:
Arne Schwabe 2023-11-24 15:52:52 +01:00
parent 2544bd3963
commit a9e47acac0
3 changed files with 46 additions and 11 deletions

View File

@ -5,6 +5,7 @@
package de.blinkt.openvpn.core;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_CONNECTED;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT;
import static de.blinkt.openvpn.core.NetworkSpace.IpAddress;
@ -14,8 +15,6 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.UiModeManager;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@ -37,7 +36,6 @@ import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.system.OsConstants;
import android.text.TextUtils;
@ -528,6 +526,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
return START_REDELIVER_INTENT;
}
// Always show notification here to avoid problem with startForeground timeout
VpnStatus.logInfo(R.string.building_configration);
VpnStatus.updateStateString("VPN_GENERATE_CONFIG", "", R.string.building_configration, ConnectionStatus.LEVEL_START);
@ -596,6 +595,34 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
return mProfile;
}
private boolean checkVPNPermission(VpnProfile startprofile) {
if (prepare(this) == null)
return true;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder nbuilder = new Notification.Builder(this);
nbuilder.setAutoCancel(true);
int icon = android.R.drawable.ic_dialog_info;
nbuilder.setSmallIcon(icon);
Intent launchVPNIntent = new Intent(this, LaunchVPN.class);
launchVPNIntent.putExtra(LaunchVPN.EXTRA_KEY, startprofile.getUUIDString());
launchVPNIntent.putExtra(LaunchVPN.EXTRA_START_REASON, "OpenService lacks permission");
launchVPNIntent.putExtra(de.blinkt.openvpn.LaunchVPN.EXTRA_HIDELOG, true);
launchVPNIntent.addFlags(FLAG_ACTIVITY_NEW_TASK);
launchVPNIntent.setAction(Intent.ACTION_MAIN);
showNotification(getString(R.string.permission_requested),
"", NOTIFICATION_CHANNEL_USERREQ_ID, 0, LEVEL_WAITING_FOR_USER_INPUT, launchVPNIntent);
VpnStatus.updateStateString("USER_INPUT", "waiting for user input", R.string.permission_requested, LEVEL_WAITING_FOR_USER_INPUT, launchVPNIntent);
return false;
}
private void startOpenVPN(Intent intent, int startId) {
VpnProfile vp = fetchVPNProfile(intent);
if (vp == null) {
@ -603,6 +630,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
return;
}
if (!checkVPNPermission(vp))
return;
ProfileManager.setConnectedVpnProfile(this, mProfile);
VpnStatus.setConnectedVPNProfile(mProfile.getUUIDString());
keepVPNAlive.scheduleKeepVPNAliveJobService(this, vp);
@ -1353,7 +1383,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
public void trigger_sso(String info) {
String channel = NOTIFICATION_CHANNEL_USERREQ_ID;
String method = info.split(":", 2)[0];
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
@ -1414,12 +1443,15 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
// updateStateString trigger the notification of the VPN to be refreshed, save this intent
// to have that notification also this intent to be set
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
VpnStatus.updateStateString("USER_INPUT", "waiting for user input", reason, LEVEL_WAITING_FOR_USER_INPUT, intent);
nbuilder.setContentIntent(pIntent);
jbNotificationExtras(PRIORITY_MAX, nbuilder);
lpNotificationExtras(nbuilder, Notification.CATEGORY_STATUS);
String channel = NOTIFICATION_CHANNEL_USERREQ_ID;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//noinspection NewApi
nbuilder.setChannelId(channel);

View File

@ -120,9 +120,10 @@ public class StatusListener implements VpnStatus.LogListener {
};
private Context mContext;
private String pkgName = "(packageName not yet set)";
void init(Context c) {
pkgName = c.getPackageName();
Intent intent = new Intent(c, OpenVPNStatusService.class);
intent.setAction(OpenVPNService.START_SERVICE);
mCacheDir = c.getCacheDir();
@ -163,22 +164,23 @@ public class StatusListener implements VpnStatus.LogListener {
@Override
public void newLog(LogItem logItem) {
String tag = pkgName + "(OpenVPN)";
switch (logItem.getLogLevel()) {
case INFO:
Log.i("OpenVPN", logItem.getString(mContext));
Log.i(tag, logItem.getString(mContext));
break;
case DEBUG:
Log.d("OpenVPN", logItem.getString(mContext));
Log.d(tag, logItem.getString(mContext));
break;
case ERROR:
Log.e("OpenVPN", logItem.getString(mContext));
Log.e(tag, logItem.getString(mContext));
break;
case VERBOSE:
Log.v("OpenVPN", logItem.getString(mContext));
Log.v(tag, logItem.getString(mContext));
break;
case WARNING:
default:
Log.w("OpenVPN", logItem.getString(mContext));
Log.w(tag, logItem.getString(mContext));
break;
}

View File

@ -508,5 +508,6 @@
<string name="encrypt_profiles">Try to encrypt profiles on storage (if supported by Android OS)</string>
<string name="missing_notification_permission">Notification permission missing. This is used to display the status of the VPN and to notify about required user interaction like multi factor authorisation.\n\nClick this message to give the app notification permissions</string>
<string name="proxy_auth_username">Username</string>
<string name="permission_requested">Permission to start a VPN connection is required</string>
<string name="missing_vpn_permission_log">VPN Service is missing permission to connect a VPN. Requesting permission via notification.</string>
</resources>