VPN Door v1.1.7版本的 MD5 值为:8e8516bf04a4da7fe0cd7c86f42cb910

以下内容为反编译后的 CharonVpnService.java 源代码,内容仅作参考


package org.strongswan.android.logic;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.VpnService;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
import android.security.KeyChain;
import android.security.KeyChainException;
import android.system.OsConstants;
import android.util.Log;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import com.securesoft.vpndoor.BuildConfig;
import com.securesoft.vpndoor.MainActivity;
import com.securesoft.vpndoor.R;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedByInterruptException;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.SortedSet;
import org.strongswan.android.data.VpnProfile;
import org.strongswan.android.data.VpnProfileDataSource;
import org.strongswan.android.data.VpnType;
import org.strongswan.android.logic.VpnStateService;
import org.strongswan.android.logic.imc.ImcState;
import org.strongswan.android.logic.imc.RemediationInstruction;
import org.strongswan.android.utils.Constants;
import org.strongswan.android.utils.IPRange;
import org.strongswan.android.utils.IPRangeSet;
import org.strongswan.android.utils.SettingsWriter;
import org.strongswan.android.utils.Utils;
public class CharonVpnService extends VpnService implements Runnable, VpnStateService.VpnStateListener {
    public static final String DISCONNECT_ACTION = "org.strongswan.android.CharonVpnService.DISCONNECT";
    public static final String KEY_IS_RETRY = "retry";
    public static final String LOG_FILE = "charon.log";
    private static final String NOTIFICATION_CHANNEL = "org.strongswan.android.CharonVpnService.VPN_STATE_NOTIFICATION";
    static final int STATE_AUTH_ERROR = 3;
    static final int STATE_CERTIFICATE_UNAVAILABLE = 7;
    static final int STATE_CHILD_SA_DOWN = 2;
    static final int STATE_CHILD_SA_UP = 1;
    static final int STATE_GENERIC_ERROR = 8;
    static final int STATE_LOOKUP_ERROR = 5;
    static final int STATE_PEER_AUTH_ERROR = 4;
    static final int STATE_UNREACHABLE_ERROR = 6;
    private static final String TAG = "CharonVpnService";
    private static final String VPN_SERVICE_ACTION = "android.net.VpnService";
    public static final int VPN_STATE_NOTIFICATION_ID = 1;
    private String mAppDir;
    private Thread mConnectionHandler;
    private volatile String mCurrentCertificateAlias;
    private VpnProfile mCurrentProfile;
    private volatile String mCurrentUserCertificateAlias;
    private VpnProfileDataSource mDataSource;
    private Handler mHandler;
    private volatile boolean mIsDisconnecting;
    private String mLogFile;
    private VpnProfile mNextProfile;
    private volatile boolean mProfileUpdated;
    private VpnStateService mService;
    private volatile boolean mShowNotification;
    private volatile boolean mTerminate;
    private BuilderAdapter mBuilderAdapter = new BuilderAdapter();
    private final Object mServiceLock = new Object();
    private final ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            synchronized (CharonVpnService.this.mServiceLock) {
                CharonVpnService.this.mService = null;
            }
        }

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            synchronized (CharonVpnService.this.mServiceLock) {
                CharonVpnService.this.mService = ((VpnStateService.LocalBinder) iBinder).getService();
            }
            CharonVpnService.this.mService.registerListener(CharonVpnService.this);
            CharonVpnService.this.mConnectionHandler.start();
        }
    };

    public native void deinitializeCharon();

    public native boolean initializeCharon(BuilderAdapter builderAdapter, String str, String str2, boolean z);

    public native void initiate(String str);

    @Override
    public int onStartCommand(Intent intent, int i, int i2) {
        Bundle extras;
        if (intent != null) {
            boolean z = false;
            VpnProfile vpnProfile = null;
            if (VPN_SERVICE_ACTION.equals(intent.getAction())) {
                SharedPreferences defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
                String string = defaultSharedPreferences.getString(Constants.PREF_DEFAULT_VPN_PROFILE, null);
                if (string == null || string.equals(Constants.PREF_DEFAULT_VPN_PROFILE_MRU)) {
                    string = defaultSharedPreferences.getString(Constants.PREF_MRU_VPN_PROFILE, null);
                }
                vpnProfile = this.mDataSource.getVpnProfile(string);
            } else if (!DISCONNECT_ACTION.equals(intent.getAction()) && (extras = intent.getExtras()) != null && (vpnProfile = this.mDataSource.getVpnProfile(extras.getString(VpnProfileDataSource.KEY_UUID))) != null) {
                vpnProfile.setPassword(extras.getString(VpnProfileDataSource.KEY_PASSWORD));
                z = extras.getBoolean(KEY_IS_RETRY, false);
                PreferenceManager.getDefaultSharedPreferences(this).edit().putString(Constants.PREF_MRU_VPN_PROFILE, vpnProfile.getUUID().toString()).apply();
            }
            if (vpnProfile != null && !z) {
                deleteFile(LOG_FILE);
            }
            setNextProfile(vpnProfile);
            return 2;
        }
        return 2;
    }

    @Override
    public void onCreate() {
        this.mLogFile = getFilesDir().getAbsolutePath() + File.separator + LOG_FILE;
        this.mAppDir = getFilesDir().getAbsolutePath();
        this.mHandler = new Handler();
        VpnProfileDataSource vpnProfileDataSource = new VpnProfileDataSource(this);
        this.mDataSource = vpnProfileDataSource;
        vpnProfileDataSource.open();
        this.mConnectionHandler = new Thread(this);
        bindService(new Intent(this, VpnStateService.class), this.mServiceConnection, 1);
        createNotificationChannel();
    }

    @Override
    public void onRevoke() {
        setNextProfile(null);
    }

    @Override
    public void onDestroy() {
        this.mTerminate = true;
        setNextProfile(null);
        try {
            this.mConnectionHandler.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        VpnStateService vpnStateService = this.mService;
        if (vpnStateService != null) {
            vpnStateService.unregisterListener(this);
            unbindService(this.mServiceConnection);
        }
        this.mDataSource.close();
    }

    private void setNextProfile(VpnProfile vpnProfile) {
        synchronized (this) {
            this.mNextProfile = vpnProfile;
            this.mProfileUpdated = true;
            notifyAll();
        }
    }

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                while (!this.mProfileUpdated) {
                    try {
                        wait();
                    } catch (InterruptedException unused) {
                        stopCurrentConnection();
                        setState(VpnStateService.State.DISABLED);
                    }
                }
                this.mProfileUpdated = false;
                stopCurrentConnection();
                VpnProfile vpnProfile = this.mNextProfile;
                if (vpnProfile == null) {
                    setState(VpnStateService.State.DISABLED);
                    if (this.mTerminate) {
                        return;
                    }
                } else {
                    this.mCurrentProfile = vpnProfile;
                    this.mNextProfile = null;
                    this.mCurrentCertificateAlias = vpnProfile.getCertificateAlias();
                    this.mCurrentUserCertificateAlias = this.mCurrentProfile.getUserCertificateAlias();
                    startConnection(this.mCurrentProfile);
                    this.mIsDisconnecting = false;
                    SimpleFetcher.enable();
                    addNotification();
                    this.mBuilderAdapter.setProfile(this.mCurrentProfile);
                    if (initializeCharon(this.mBuilderAdapter, this.mLogFile, this.mAppDir, this.mCurrentProfile.getVpnType().has(VpnType.VpnTypeFeature.BYOD))) {
                        Log.i(TAG, "charon started");
                        if (this.mCurrentProfile.getVpnType().has(VpnType.VpnTypeFeature.USER_PASS) && this.mCurrentProfile.getPassword() == null) {
                            setError(VpnStateService.ErrorState.PASSWORD_MISSING);
                        } else {
                            SettingsWriter settingsWriter = new SettingsWriter();
                            settingsWriter.setValue("global.language", Locale.getDefault().getLanguage());
                            settingsWriter.setValue("global.mtu", this.mCurrentProfile.getMTU());
                            settingsWriter.setValue("global.nat_keepalive", this.mCurrentProfile.getNATKeepAlive());
                            settingsWriter.setValue("global.rsa_pss", Boolean.valueOf((this.mCurrentProfile.getFlags().intValue() & 16) != 0));
                            settingsWriter.setValue("global.crl", Boolean.valueOf((this.mCurrentProfile.getFlags().intValue() & 2) == 0));
                            settingsWriter.setValue("global.ocsp", Boolean.valueOf((this.mCurrentProfile.getFlags().intValue() & 4) == 0));
                            settingsWriter.setValue("connection.type", this.mCurrentProfile.getVpnType().getIdentifier());
                            settingsWriter.setValue("connection.server", this.mCurrentProfile.getGateway());
                            settingsWriter.setValue("connection.port", this.mCurrentProfile.getPort());
                            settingsWriter.setValue("connection.username", this.mCurrentProfile.getUsername());
                            settingsWriter.setValue("connection.password", this.mCurrentProfile.getPassword());
                            settingsWriter.setValue("connection.local_id", this.mCurrentProfile.getLocalId());
                            settingsWriter.setValue("connection.remote_id", this.mCurrentProfile.getRemoteId());
                            settingsWriter.setValue("connection.certreq", Boolean.valueOf((this.mCurrentProfile.getFlags().intValue() & 1) == 0));
                            settingsWriter.setValue("connection.strict_revocation", Boolean.valueOf((this.mCurrentProfile.getFlags().intValue() & 8) != 0));
                            settingsWriter.setValue("connection.ike_proposal", this.mCurrentProfile.getIkeProposal());
                            settingsWriter.setValue("connection.esp_proposal", this.mCurrentProfile.getEspProposal());
                            initiate(settingsWriter.serialize());
                        }
                    } else {
                        Log.e(TAG, "failed to start charon");
                        setError(VpnStateService.ErrorState.GENERIC_ERROR);
                        setState(VpnStateService.State.DISABLED);
                        this.mCurrentProfile = null;
                    }
                }
            }
        }
    }

    private void stopCurrentConnection() {
        synchronized (this) {
            if (this.mNextProfile != null && Build.VERSION.SDK_INT >= 21) {
                this.mBuilderAdapter.setProfile(this.mNextProfile);
                this.mBuilderAdapter.establishBlocking();
            }
            if (this.mCurrentProfile != null) {
                setState(VpnStateService.State.DISCONNECTING);
                this.mIsDisconnecting = true;
                SimpleFetcher.disable();
                deinitializeCharon();
                Log.i(TAG, "charon stopped");
                this.mCurrentProfile = null;
                if (this.mNextProfile == null) {
                    removeNotification();
                    this.mBuilderAdapter.closeBlocking();
                }
            }
        }
    }

    private void addNotification() {
        this.mHandler.post(new Runnable() {
            @Override
            public void run() {
                CharonVpnService.this.mShowNotification = true;
                CharonVpnService charonVpnService = CharonVpnService.this;
                charonVpnService.startForeground(1, charonVpnService.buildNotification(false));
            }
        });
    }

    private void removeNotification() {
        this.mHandler.post(new Runnable() {
            @Override
            public void run() {
                CharonVpnService.this.mShowNotification = false;
                CharonVpnService.this.stopForeground(true);
            }
        });
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= 26) {
            NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL, getString(R.string.permanent_notification_name), 2);
            notificationChannel.setDescription(getString(R.string.permanent_notification_description));
            notificationChannel.setLockscreenVisibility(-1);
            notificationChannel.setShowBadge(false);
            ((NotificationManager) getSystemService(NotificationManager.class)).createNotificationChannel(notificationChannel);
        }
    }

    public Notification buildNotification(boolean z) {
        boolean z2;
        VpnProfile profile = this.mService.getProfile();
        VpnStateService.State state = this.mService.getState();
        VpnStateService.ErrorState errorState = this.mService.getErrorState();
        String name = profile != null ? profile.getName() : "";
        NotificationCompat.Builder visibility = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL).setSmallIcon(R.drawable.door_notif).setCategory(NotificationCompat.CATEGORY_SERVICE).setVisibility(z ? 1 : 0);
        int i = R.string.state_disabled;
        if (errorState != VpnStateService.ErrorState.NO_ERROR) {
            i = this.mService.getErrorText();
            visibility.setSmallIcon(R.drawable.door_notif_warning);
            visibility.setColor(ContextCompat.getColor(this, R.color.error_text));
            if (!z && profile != null) {
                int retryIn = this.mService.getRetryIn();
                if (retryIn > 0) {
                    visibility.setContentText(getResources().getQuantityString(R.plurals.retry_in, retryIn, Integer.valueOf(retryIn)));
                    visibility.setProgress(this.mService.getRetryTimeout(), retryIn, false);
                }
                Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                intent.addFlags(268435456);
                visibility.addAction(R.drawable.door_notif_connecting, getString(R.string.retry), PendingIntent.getActivity(getApplicationContext(), 0, intent, 134217728));
                z2 = true;
            }
            z2 = false;
        } else {
            visibility.setProgress(0, 0, false);
            int i2 = AnonymousClass4.$SwitchMap$org$strongswan$android$logic$VpnStateService$State[state.ordinal()];
            if (i2 == 1) {
                i = R.string.state_connecting;
                visibility.setSmallIcon(R.drawable.door_notif_connecting);
                visibility.setColor(ContextCompat.getColor(this, R.color.warning_text));
            } else if (i2 != 2) {
                if (i2 == 3) {
                    i = R.string.state_disconnecting;
                }
                z2 = false;
            } else {
                i = R.string.state_connected;
                visibility.setColor(ContextCompat.getColor(this, R.color.success_text));
                visibility.setUsesChronometer(true);
            }
            z2 = true;
        }
        visibility.setContentTitle(getString(i));
        if (!z) {
            if (z2) {
                PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), 134217728);
            }
            if (errorState == VpnStateService.ErrorState.NO_ERROR) {
                visibility.setContentText(name);
            }
            visibility.setPublicVersion(buildNotification(true));
        }
        Intent launchIntentForPackage = getPackageManager().getLaunchIntentForPackage(BuildConfig.APPLICATION_ID);
        launchIntentForPackage.setFlags(335544320);
        visibility.setContentIntent(PendingIntent.getActivity(this, 0, launchIntentForPackage, 0));
        return visibility.build();
    }

    @Override
    public void stateChanged() {
        if (this.mShowNotification) {
            ((NotificationManager) getSystemService("notification")).notify(1, buildNotification(false));
        }
    }

    private void startConnection(VpnProfile vpnProfile) {
        synchronized (this.mServiceLock) {
            VpnStateService vpnStateService = this.mService;
            if (vpnStateService != null) {
                vpnStateService.startConnection(vpnProfile);
            }
        }
    }

    private void setState(VpnStateService.State state) {
        synchronized (this.mServiceLock) {
            VpnStateService vpnStateService = this.mService;
            if (vpnStateService != null) {
                vpnStateService.setState(state);
            }
        }
    }

    private void setError(VpnStateService.ErrorState errorState) {
        synchronized (this.mServiceLock) {
            VpnStateService vpnStateService = this.mService;
            if (vpnStateService != null) {
                vpnStateService.setError(errorState);
            }
        }
    }

    private void setImcState(ImcState imcState) {
        synchronized (this.mServiceLock) {
            VpnStateService vpnStateService = this.mService;
            if (vpnStateService != null) {
                vpnStateService.setImcState(imcState);
            }
        }
    }

    private void setErrorDisconnect(VpnStateService.ErrorState errorState) {
        synchronized (this.mServiceLock) {
            if (this.mService != null && !this.mIsDisconnecting) {
                this.mService.setError(errorState);
            }
        }
    }

    public void updateStatus(int i) {
        switch (i) {
            case 1:
                setState(VpnStateService.State.CONNECTED);
                return;
            case 2:
                if (this.mIsDisconnecting) {
                    return;
                }
                setState(VpnStateService.State.CONNECTING);
                return;
            case 3:
                setErrorDisconnect(VpnStateService.ErrorState.AUTH_FAILED);
                return;
            case 4:
                setErrorDisconnect(VpnStateService.ErrorState.PEER_AUTH_FAILED);
                return;
            case 5:
                setErrorDisconnect(VpnStateService.ErrorState.LOOKUP_FAILED);
                return;
            case 6:
                setErrorDisconnect(VpnStateService.ErrorState.UNREACHABLE);
                return;
            case 7:
                setErrorDisconnect(VpnStateService.ErrorState.CERTIFICATE_UNAVAILABLE);
                return;
            case 8:
                setErrorDisconnect(VpnStateService.ErrorState.GENERIC_ERROR);
                return;
            default:
                Log.e(TAG, "Unknown status code received");
                return;
        }
    }

    public void updateImcState(int i) {
        ImcState fromValue = ImcState.fromValue(i);
        if (fromValue != null) {
            setImcState(fromValue);
        }
    }

    public void addRemediationInstruction(String str) {
        for (RemediationInstruction remediationInstruction : RemediationInstruction.fromXml(str)) {
            synchronized (this.mServiceLock) {
                VpnStateService vpnStateService = this.mService;
                if (vpnStateService != null) {
                    vpnStateService.addRemediationInstruction(remediationInstruction);
                }
            }
        }
    }

    private byte[][] getTrustedCertificates() {
        ArrayList arrayList = new ArrayList();
        TrustedCertificateManager load = TrustedCertificateManager.getInstance().load();
        try {
            String str = this.mCurrentCertificateAlias;
            if (str != null) {
                X509Certificate cACertificateFromAlias = load.getCACertificateFromAlias(str);
                if (cACertificateFromAlias == null) {
                    return null;
                }
                arrayList.add(cACertificateFromAlias.getEncoded());
            } else {
                for (X509Certificate x509Certificate : load.getAllCACertificates().values()) {
                    arrayList.add(x509Certificate.getEncoded());
                }
            }
            return (byte[][]) arrayList.toArray(new byte[arrayList.size()]);
        } catch (CertificateEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    private byte[][] getUserCertificate() throws KeyChainException, InterruptedException, CertificateEncodingException {
        ArrayList arrayList = new ArrayList();
        X509Certificate[] certificateChain = KeyChain.getCertificateChain(getApplicationContext(), this.mCurrentUserCertificateAlias);
        if (certificateChain == null || certificateChain.length == 0) {
            return null;
        }
        for (X509Certificate x509Certificate : certificateChain) {
            arrayList.add(x509Certificate.getEncoded());
        }
        return (byte[][]) arrayList.toArray(new byte[arrayList.size()]);
    }

    private PrivateKey getUserKey() throws KeyChainException, InterruptedException {
        return KeyChain.getPrivateKey(getApplicationContext(), this.mCurrentUserCertificateAlias);
    }

    public class BuilderAdapter {
        private VpnService.Builder mBuilder;
        private BuilderCache mCache;
        private BuilderCache mEstablishedCache;
        private VpnProfile mProfile;
        private PacketDropper mDropper = new PacketDropper();
        private Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                if (message.what != 1) {
                    return;
                }
                CharonVpnService.this.stopSelf();
            }
        };

        public BuilderAdapter() {
        }

        public synchronized void setProfile(VpnProfile vpnProfile) {
            this.mProfile = vpnProfile;
            this.mBuilder = createBuilder(vpnProfile.getName());
            this.mCache = new BuilderCache(this.mProfile);
        }

        private VpnService.Builder createBuilder(String str) {
            VpnService.Builder builder = new VpnService.Builder(CharonVpnService.this);
            builder.setSession(str);
            Context applicationContext = CharonVpnService.this.getApplicationContext();
            builder.setConfigureIntent(PendingIntent.getActivity(applicationContext, 0, new Intent(applicationContext, MainActivity.class), 134217728));
            return builder;
        }

        public synchronized boolean addAddress(String str, int i) {
            try {
                this.mCache.addAddress(str, i);
            } catch (IllegalArgumentException unused) {
                return false;
            }
            return true;
        }

        public synchronized boolean addDnsServer(String str) {
            try {
                this.mCache.addDnsServer(str);
            } catch (IllegalArgumentException unused) {
                return false;
            }
            return true;
        }

        public synchronized boolean addRoute(String str, int i) {
            try {
                this.mCache.addRoute(str, i);
            } catch (IllegalArgumentException unused) {
                return false;
            }
            return true;
        }

        public synchronized boolean addSearchDomain(String str) {
            try {
                this.mBuilder.addSearchDomain(str);
            } catch (IllegalArgumentException unused) {
                return false;
            }
            return true;
        }

        public synchronized boolean setMtu(int i) {
            try {
                this.mCache.setMtu(i);
            } catch (IllegalArgumentException unused) {
                return false;
            }
            return true;
        }

        private synchronized ParcelFileDescriptor establishIntern() {
            try {
                this.mCache.applyData(this.mBuilder);
                ParcelFileDescriptor establish = this.mBuilder.establish();
                if (establish != null) {
                    closeBlocking();
                }
                if (establish == null) {
                    return null;
                }
                this.mBuilder = createBuilder(this.mProfile.getName());
                this.mEstablishedCache = this.mCache;
                this.mCache = new BuilderCache(this.mProfile);
                return establish;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        public synchronized int establish() {
            ParcelFileDescriptor establishIntern;
            establishIntern = establishIntern();
            return establishIntern != null ? establishIntern.detachFd() : -1;
        }

        public synchronized void establishBlocking() {
            this.mCache.addAddress("172.16.252.1", 32);
            this.mCache.addAddress("fd00::fd02:1", 128);
            this.mCache.addRoute("0.0.0.0", 0);
            this.mCache.addRoute("::", 0);
            this.mBuilder.addDnsServer("8.8.8.8");
            this.mBuilder.addDnsServer("2001:4860:4860::8888");
            this.mBuilder.setBlocking(true);
            ParcelFileDescriptor establishIntern = establishIntern();
            if (establishIntern != null) {
                this.mDropper.start(establishIntern);
            }
        }

        public synchronized void closeBlocking() {
            this.mDropper.stop();
        }

        public synchronized int establishNoDns() {
            if (this.mEstablishedCache == null) {
                return -1;
            }
            try {
                VpnService.Builder createBuilder = createBuilder(this.mProfile.getName());
                this.mEstablishedCache.applyData(createBuilder);
                ParcelFileDescriptor establish = createBuilder.establish();
                if (establish == null) {
                    return -1;
                }
                return establish.detachFd();
            } catch (Exception e) {
                e.printStackTrace();
                return -1;
            }
        }

        public class PacketDropper implements Runnable {
            private ParcelFileDescriptor mFd;
            private Thread mThread;

            private PacketDropper() {
            }

            public void start(ParcelFileDescriptor parcelFileDescriptor) {
                this.mFd = parcelFileDescriptor;
                Thread thread = new Thread(this);
                this.mThread = thread;
                thread.start();
            }

            public void stop() {
                if (this.mFd != null) {
                    try {
                        this.mThread.interrupt();
                        this.mThread.join();
                        this.mFd.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e2) {
                        e2.printStackTrace();
                    }
                    this.mFd = null;
                }
            }

            @Override
            public synchronized void run() {
                try {
                    FileInputStream fileInputStream = new FileInputStream(this.mFd.getFileDescriptor());
                    ByteBuffer allocate = ByteBuffer.allocate(BuilderAdapter.this.mCache.mMtu);
                    while (true) {
                        if (Build.VERSION.SDK_INT >= 24) {
                            int read = fileInputStream.getChannel().read(allocate);
                            allocate.clear();
                            if (read < 0) {
                                break;
                            }
                        } else {
                            boolean z = true;
                            if (fileInputStream.available() > 0) {
                                int read2 = fileInputStream.read(allocate.array());
                                allocate.clear();
                                if (read2 < 0 || Thread.interrupted()) {
                                    break;
                                }
                                z = false;
                            }
                            if (z) {
                                Thread.sleep(250L);
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException | ClosedByInterruptException unused) {
                }
            }
        }
    }

    public class BuilderCache {
        private final VpnProfile.SelectedAppsHandling mAppHandling;
        private boolean mDnsServersConfigured;
        private final IPRangeSet mExcludedSubnets;
        private boolean mIPv4Seen;
        private boolean mIPv6Seen;
        private int mMtu;
        private final SortedSet<String> mSelectedApps;
        private final int mSplitTunneling;
        private final List<IPRange> mAddresses = new ArrayList();
        private final List<IPRange> mRoutesIPv4 = new ArrayList();
        private final List<IPRange> mRoutesIPv6 = new ArrayList();
        private final IPRangeSet mIncludedSubnetsv4 = new IPRangeSet();
        private final IPRangeSet mIncludedSubnetsv6 = new IPRangeSet();
        private final List<InetAddress> mDnsServers = new ArrayList();

        public BuilderCache(VpnProfile vpnProfile) {
            String[] split;
            Iterator<IPRange> it = IPRangeSet.fromString(vpnProfile.getIncludedSubnets()).iterator();
            while (it.hasNext()) {
                IPRange next = it.next();
                if (next.getFrom() instanceof Inet4Address) {
                    this.mIncludedSubnetsv4.add(next);
                } else if (next.getFrom() instanceof Inet6Address) {
                    this.mIncludedSubnetsv6.add(next);
                }
            }
            this.mExcludedSubnets = IPRangeSet.fromString(vpnProfile.getExcludedSubnets());
            Integer splitTunneling = vpnProfile.getSplitTunneling();
            this.mSplitTunneling = splitTunneling != null ? splitTunneling.intValue() : 0;
            VpnProfile.SelectedAppsHandling selectedAppsHandling = vpnProfile.getSelectedAppsHandling();
            SortedSet<String> selectedAppsSet = vpnProfile.getSelectedAppsSet();
            this.mSelectedApps = selectedAppsSet;
            int i = AnonymousClass4.$SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling[selectedAppsHandling.ordinal()];
            if (i == 1) {
                selectedAppsHandling = VpnProfile.SelectedAppsHandling.SELECTED_APPS_EXCLUDE;
                selectedAppsSet.clear();
            } else if (i != 2) {
                if (i == 3) {
                    selectedAppsSet.remove(CharonVpnService.this.getPackageName());
                }
                this.mAppHandling = selectedAppsHandling;
                if (vpnProfile.getDnsServers() != null) {
                    for (String str : vpnProfile.getDnsServers().split("\\s+")) {
                        try {
                            this.mDnsServers.add(Utils.parseInetAddress(str));
                            recordAddressFamily(str);
                            this.mDnsServersConfigured = true;
                        } catch (UnknownHostException e) {
                            e.printStackTrace();
                        }
                    }
                }
                Integer mtu = vpnProfile.getMTU();
                this.mMtu = mtu != null ? 1500 : mtu.intValue();
            }
            selectedAppsSet.add(CharonVpnService.this.getPackageName());
            this.mAppHandling = selectedAppsHandling;
            if (vpnProfile.getDnsServers() != null) {
            }
            Integer mtu2 = vpnProfile.getMTU();
            this.mMtu = mtu2 != null ? 1500 : mtu2.intValue();
        }

        public void addAddress(String str, int i) {
            try {
                this.mAddresses.add(new IPRange(str, i));
                recordAddressFamily(str);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }

        public void addDnsServer(String str) {
            if (this.mDnsServersConfigured) {
                return;
            }
            try {
                this.mDnsServers.add(Utils.parseInetAddress(str));
                recordAddressFamily(str);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }

        public void addRoute(String str, int i) {
            try {
                if (isIPv6(str)) {
                    this.mRoutesIPv6.add(new IPRange(str, i));
                } else {
                    this.mRoutesIPv4.add(new IPRange(str, i));
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }

        public void setMtu(int i) {
            this.mMtu = i;
        }

        public void recordAddressFamily(String str) {
            try {
                if (isIPv6(str)) {
                    this.mIPv6Seen = true;
                } else {
                    this.mIPv4Seen = true;
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }

        public void applyData(VpnService.Builder builder) {
            for (IPRange iPRange : this.mAddresses) {
                builder.addAddress(iPRange.getFrom(), iPRange.getPrefix().intValue());
            }
            for (InetAddress inetAddress : this.mDnsServers) {
                builder.addDnsServer(inetAddress);
            }
            if ((this.mSplitTunneling & 1) == 0) {
                if (this.mIPv4Seen) {
                    IPRangeSet iPRangeSet = new IPRangeSet();
                    if (this.mIncludedSubnetsv4.size() > 0) {
                        iPRangeSet.add(this.mIncludedSubnetsv4);
                    } else {
                        iPRangeSet.addAll(this.mRoutesIPv4);
                    }
                    iPRangeSet.remove(this.mExcludedSubnets);
                    for (IPRange iPRange2 : iPRangeSet.subnets()) {
                        try {
                            builder.addRoute(iPRange2.getFrom(), iPRange2.getPrefix().intValue());
                        } catch (IllegalArgumentException e) {
                            if (!iPRange2.getFrom().isMulticastAddress()) {
                                throw e;
                            }
                        }
                    }
                } else if (Build.VERSION.SDK_INT >= 21) {
                    builder.allowFamily(OsConstants.AF_INET);
                }
            } else if (this.mIPv4Seen) {
                builder.addRoute("0.0.0.0", 0);
            }
            if ((this.mSplitTunneling & 2) == 0) {
                if (this.mIPv6Seen) {
                    IPRangeSet iPRangeSet2 = new IPRangeSet();
                    if (this.mIncludedSubnetsv6.size() > 0) {
                        iPRangeSet2.add(this.mIncludedSubnetsv6);
                    } else {
                        iPRangeSet2.addAll(this.mRoutesIPv6);
                    }
                    iPRangeSet2.remove(this.mExcludedSubnets);
                    for (IPRange iPRange3 : iPRangeSet2.subnets()) {
                        try {
                            builder.addRoute(iPRange3.getFrom(), iPRange3.getPrefix().intValue());
                        } catch (IllegalArgumentException e2) {
                            if (!iPRange3.getFrom().isMulticastAddress()) {
                                throw e2;
                            }
                        }
                    }
                } else if (Build.VERSION.SDK_INT >= 21) {
                    builder.allowFamily(OsConstants.AF_INET6);
                }
            } else if (this.mIPv6Seen) {
                builder.addRoute("::", 0);
            }
            if (this.mSelectedApps.size() > 0 && Build.VERSION.SDK_INT >= 21) {
                int i = AnonymousClass4.$SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling[this.mAppHandling.ordinal()];
                if (i == 2) {
                    for (String str : this.mSelectedApps) {
                        try {
                            builder.addDisallowedApplication(str);
                        } catch (PackageManager.NameNotFoundException unused) {
                        }
                    }
                } else if (i == 3) {
                    for (String str2 : this.mSelectedApps) {
                        try {
                            builder.addAllowedApplication(str2);
                        } catch (PackageManager.NameNotFoundException unused2) {
                        }
                    }
                }
            }
            builder.setMtu(this.mMtu);
        }

        private boolean isIPv6(String str) throws UnknownHostException {
            InetAddress parseInetAddress = Utils.parseInetAddress(str);
            return !(parseInetAddress instanceof Inet4Address) && (parseInetAddress instanceof Inet6Address);
        }
    }

    public static class AnonymousClass4 {
        static final int[] $SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling;
        static final int[] $SwitchMap$org$strongswan$android$logic$VpnStateService$State;

        static {
            int[] iArr = new int[VpnProfile.SelectedAppsHandling.values().length];
            $SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling = iArr;
            try {
                iArr[VpnProfile.SelectedAppsHandling.SELECTED_APPS_DISABLE.ordinal()] = 1;
            } catch (NoSuchFieldError unused) {
            }
            try {
                $SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling[VpnProfile.SelectedAppsHandling.SELECTED_APPS_EXCLUDE.ordinal()] = 2;
            } catch (NoSuchFieldError unused2) {
            }
            try {
                $SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling[VpnProfile.SelectedAppsHandling.SELECTED_APPS_ONLY.ordinal()] = 3;
            } catch (NoSuchFieldError unused3) {
            }
            int[] iArr2 = new int[VpnStateService.State.values().length];
            $SwitchMap$org$strongswan$android$logic$VpnStateService$State = iArr2;
            try {
                iArr2[VpnStateService.State.CONNECTING.ordinal()] = 1;
            } catch (NoSuchFieldError unused4) {
            }
            try {
                $SwitchMap$org$strongswan$android$logic$VpnStateService$State[VpnStateService.State.CONNECTED.ordinal()] = 2;
            } catch (NoSuchFieldError unused5) {
            }
            try {
                $SwitchMap$org$strongswan$android$logic$VpnStateService$State[VpnStateService.State.DISCONNECTING.ordinal()] = 3;
            } catch (NoSuchFieldError unused6) {
            }
        }
    }

    private static String getAndroidVersion() {
        String str = "Android " + Build.VERSION.RELEASE + " - " + Build.DISPLAY;
        if (Build.VERSION.SDK_INT >= 23) {
            return str + "/" + Build.VERSION.SECURITY_PATCH;
        }
        return str;
    }

    private static String getDeviceString() {
        return Build.MODEL + " - " + Build.BRAND + "/" + Build.PRODUCT + "/" + Build.MANUFACTURER;
    }
}