├── .gitignore ├── app ├── build.gradle └── src │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ ├── com │ │ │ └── android │ │ │ │ └── galaxyvpn │ │ │ │ └── MainActivity.java │ │ └── org │ │ │ └── strongswan │ │ │ └── android │ │ │ ├── data │ │ │ ├── LogContentProvider.java │ │ │ ├── VpnProfile.java │ │ │ ├── VpnProfileDataSource.java │ │ │ └── VpnType.java │ │ │ ├── logic │ │ │ ├── CharonVpnService.java │ │ │ ├── NetworkManager.java │ │ │ ├── SimpleFetcher.java │ │ │ ├── StrongSwanApplication.java │ │ │ ├── TrustedCertificateManager.java │ │ │ ├── VpnStateService.java │ │ │ └── imc │ │ │ │ ├── AndroidImc.java │ │ │ │ ├── ImcState.java │ │ │ │ ├── RemediationInstruction.java │ │ │ │ ├── attributes │ │ │ │ ├── Attribute.java │ │ │ │ ├── AttributeType.java │ │ │ │ ├── DeviceIdAttribute.java │ │ │ │ ├── InstalledPackagesAttribute.java │ │ │ │ ├── PortFilterAttribute.java │ │ │ │ ├── PrivateEnterpriseNumber.java │ │ │ │ ├── ProductInformationAttribute.java │ │ │ │ ├── SettingsAttribute.java │ │ │ │ └── StringVersionAttribute.java │ │ │ │ └── collectors │ │ │ │ ├── Collector.java │ │ │ │ ├── DeviceIdCollector.java │ │ │ │ ├── InstalledPackagesCollector.java │ │ │ │ ├── PortFilterCollector.java │ │ │ │ ├── ProductInformationCollector.java │ │ │ │ ├── Protocol.java │ │ │ │ ├── SettingsCollector.java │ │ │ │ └── StringVersionCollector.java │ │ │ ├── security │ │ │ ├── LocalCertificateKeyStoreProvider.java │ │ │ ├── LocalCertificateKeyStoreSpi.java │ │ │ ├── LocalCertificateStore.java │ │ │ └── TrustedCertificateEntry.java │ │ │ ├── ui │ │ │ ├── CertificateDeleteConfirmationDialog.java │ │ │ ├── ImcStateFragment.java │ │ │ ├── LogActivity.java │ │ │ ├── LogFragment.java │ │ │ ├── MainActivity.java │ │ │ ├── RemediationInstructionFragment.java │ │ │ ├── RemediationInstructionsActivity.java │ │ │ ├── RemediationInstructionsFragment.java │ │ │ ├── SelectedApplicationsActivity.java │ │ │ ├── SelectedApplicationsListFragment.java │ │ │ ├── SettingsActivity.java │ │ │ ├── SettingsFragment.java │ │ │ ├── TrustedCertificateImportActivity.java │ │ │ ├── TrustedCertificateListFragment.java │ │ │ ├── TrustedCertificatesActivity.java │ │ │ ├── VpnProfileControlActivity.java │ │ │ ├── VpnProfileDetailActivity.java │ │ │ ├── VpnProfileImportActivity.java │ │ │ ├── VpnProfileListFragment.java │ │ │ ├── VpnProfileSelectActivity.java │ │ │ ├── VpnStateFragment.java │ │ │ ├── adapter │ │ │ │ ├── CertificateIdentitiesAdapter.java │ │ │ │ ├── RemediationInstructionAdapter.java │ │ │ │ ├── SelectedApplicationEntry.java │ │ │ │ ├── SelectedApplicationsAdapter.java │ │ │ │ ├── TrustedCertificateAdapter.java │ │ │ │ └── VpnProfileAdapter.java │ │ │ └── widget │ │ │ │ ├── CheckableLinearLayout.java │ │ │ │ └── TextInputLayoutHelper.java │ │ │ └── utils │ │ │ ├── BufferedByteWriter.java │ │ │ ├── Constants.java │ │ │ ├── IPRange.java │ │ │ ├── IPRangeSet.java │ │ │ ├── SettingsWriter.java │ │ │ └── Utils.java │ ├── jniLibs │ │ ├── arm64-v8a │ │ │ ├── libandroidbridge.so │ │ │ ├── libcharon.so │ │ │ ├── libimcv.so │ │ │ ├── libipsec.so │ │ │ ├── libstrongswan.so │ │ │ ├── libtnccs.so │ │ │ ├── libtncif.so │ │ │ └── libtpmtss.so │ │ ├── armeabi-v7a │ │ │ ├── libandroidbridge.so │ │ │ ├── libcharon.so │ │ │ ├── libimcv.so │ │ │ ├── libipsec.so │ │ │ ├── libstrongswan.so │ │ │ ├── libtnccs.so │ │ │ ├── libtncif.so │ │ │ └── libtpmtss.so │ │ ├── x86 │ │ │ ├── libandroidbridge.so │ │ │ ├── libcharon.so │ │ │ ├── libimcv.so │ │ │ ├── libipsec.so │ │ │ ├── libstrongswan.so │ │ │ ├── libtnccs.so │ │ │ ├── libtncif.so │ │ │ └── libtpmtss.so │ │ └── x86_64 │ │ │ ├── libandroidbridge.so │ │ │ ├── libcharon.so │ │ │ ├── libimcv.so │ │ │ ├── libipsec.so │ │ │ ├── libstrongswan.so │ │ │ ├── libtnccs.so │ │ │ ├── libtncif.so │ │ │ └── libtpmtss.so │ └── res │ │ ├── color │ │ └── checkable_text_color.xml │ │ ├── drawable-hdpi │ │ ├── ic_close_white_24dp.png │ │ ├── ic_launcher.png │ │ ├── ic_notification.png │ │ ├── ic_notification_connecting.png │ │ ├── ic_notification_disconnect.png │ │ ├── ic_notification_disconnected.png │ │ └── ic_notification_warning.png │ │ ├── drawable-mdpi │ │ ├── ic_close_white_24dp.png │ │ ├── ic_launcher.png │ │ ├── ic_notification.png │ │ ├── ic_notification_connecting.png │ │ ├── ic_notification_disconnect.png │ │ ├── ic_notification_disconnected.png │ │ └── ic_notification_warning.png │ │ ├── drawable-xhdpi │ │ ├── ic_close_white_24dp.png │ │ ├── ic_launcher.png │ │ ├── ic_notification.png │ │ ├── ic_notification_connecting.png │ │ ├── ic_notification_disconnect.png │ │ ├── ic_notification_disconnected.png │ │ └── ic_notification_warning.png │ │ ├── drawable │ │ ├── activated_background.xml │ │ ├── error_background.xml │ │ ├── remediation_instruction_background_large.xml │ │ └── state_background.xml │ │ ├── layout-large │ │ └── remediation_instructions.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── imc_state_fragment.xml │ │ ├── log_activity.xml │ │ ├── log_fragment.xml │ │ ├── log_list_item.xml │ │ ├── login_dialog.xml │ │ ├── main.xml │ │ ├── profile_detail_view.xml │ │ ├── profile_import_view.xml │ │ ├── profile_list_fragment.xml │ │ ├── profile_list_item.xml │ │ ├── remediation_instruction.xml │ │ ├── remediation_instruction_item.xml │ │ ├── remediation_instructions.xml │ │ ├── selected_application_item.xml │ │ ├── trusted_certificates_activity.xml │ │ ├── trusted_certificates_item.xml │ │ ├── two_line_button.xml │ │ ├── vpn_profile_select.xml │ │ └── vpn_state_fragment.xml │ │ ├── menu │ │ ├── certificates.xml │ │ ├── log.xml │ │ ├── main.xml │ │ ├── profile_edit.xml │ │ ├── profile_import.xml │ │ ├── profile_list.xml │ │ └── profile_list_context.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_shortcut.xml │ │ ├── mipmap-anydpi │ │ ├── ic_launcher.xml │ │ └── ic_shortcut.xml │ │ ├── mipmap-xxxhdpi-v26 │ │ ├── ic_launcher_bg.png │ │ ├── ic_launcher_fg.png │ │ ├── ic_shortcut_bg.png │ │ └── ic_shortcut_fg.png │ │ ├── values-de │ │ ├── arrays.xml │ │ └── strings.xml │ │ ├── values-pl │ │ ├── arrays.xml │ │ └── strings.xml │ │ ├── values-ru │ │ ├── arrays.xml │ │ └── strings.xml │ │ ├── values-ua │ │ ├── arrays.xml │ │ └── strings.xml │ │ ├── values-v15 │ │ └── styles.xml │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-zh-rCN │ │ ├── arrays.xml │ │ └── strings.xml │ │ ├── values-zh-rTW │ │ ├── arrays.xml │ │ └── strings.xml │ │ ├── values │ │ ├── arrays.xml │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── network_security_config.xml │ │ └── settings.xml │ └── test │ └── java │ └── org │ └── strongswan │ └── android │ └── test │ ├── BufferedByteWriterTest.java │ ├── IPRangeSetTest.java │ ├── IPRangeTest.java │ └── SettingsWriterTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | .idea/ 3 | build/ 4 | app/build/ 5 | app/src/main/libs 6 | app/src/main/obj 7 | *.iml 8 | local.properties 9 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | 6 | defaultConfig { 7 | applicationId "org.strongswan.android" 8 | minSdkVersion 15 9 | targetSdkVersion 28 10 | versionCode 69 11 | versionName "2.2.1" 12 | } 13 | 14 | // sourceSets.main { 15 | // jni.srcDirs = [] // disables the default ndk-build call (with on-the-fly Android.mk files) 16 | // jniLibs.srcDir 'src/main/libs' 17 | // } 18 | // 19 | // task buildNative(type: Exec) { 20 | // workingDir 'src/main/jni' 21 | // commandLine "${android.ndkDirectory}/ndk-build", '-j', Runtime.runtime.availableProcessors() 22 | // } 23 | // 24 | // task cleanNative(type: Exec) { 25 | // workingDir 'src/main/jni' 26 | // commandLine "${android.ndkDirectory}/ndk-build", 'clean' 27 | // } 28 | 29 | // tasks.withType(JavaCompile) { 30 | // compileTask -> compileTask.dependsOn buildNative 31 | // options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" 32 | // } 33 | 34 | //clean.dependsOn 'cleanNative' 35 | 36 | buildTypes { 37 | release { 38 | minifyEnabled false 39 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 40 | } 41 | } 42 | compileOptions { 43 | targetCompatibility 1.8 44 | sourceCompatibility 1.8 45 | } 46 | } 47 | 48 | dependencies { 49 | implementation 'androidx.appcompat:appcompat:1.1.0' 50 | implementation 'androidx.preference:preference:1.1.0' 51 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 52 | implementation 'com.google.android.material:material:1.0.0' 53 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 54 | testImplementation 'junit:junit:4.12' 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/data/LogContentProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.data; 17 | 18 | import java.io.File; 19 | import java.io.FileNotFoundException; 20 | import java.security.NoSuchAlgorithmException; 21 | import java.security.SecureRandom; 22 | import java.util.concurrent.ConcurrentHashMap; 23 | 24 | import org.strongswan.android.logic.CharonVpnService; 25 | 26 | import android.content.ContentProvider; 27 | import android.content.ContentValues; 28 | import android.database.Cursor; 29 | import android.database.MatrixCursor; 30 | import android.net.Uri; 31 | import android.os.ParcelFileDescriptor; 32 | import android.os.SystemClock; 33 | import android.provider.OpenableColumns; 34 | 35 | public class LogContentProvider extends ContentProvider 36 | { 37 | private static final String AUTHORITY = "org.strongswan.android.content.log"; 38 | /* an Uri is valid for 30 minutes */ 39 | private static final long URI_VALIDITY = 30 * 60 * 1000; 40 | private static ConcurrentHashMap mUris = new ConcurrentHashMap(); 41 | private File mLogFile; 42 | 43 | public LogContentProvider() 44 | { 45 | } 46 | 47 | @Override 48 | public boolean onCreate() 49 | { 50 | mLogFile = new File(getContext().getFilesDir(), CharonVpnService.LOG_FILE); 51 | return true; 52 | } 53 | 54 | /** 55 | * The log file can only be accessed by Uris created with this method 56 | * @return null if failed to create the Uri 57 | */ 58 | public static Uri createContentUri() 59 | { 60 | SecureRandom random; 61 | try 62 | { 63 | random = SecureRandom.getInstance("SHA1PRNG"); 64 | } 65 | catch (NoSuchAlgorithmException e) 66 | { 67 | return null; 68 | } 69 | Uri uri = Uri.parse("content://" + AUTHORITY + "/" + random.nextLong()); 70 | mUris.put(uri, SystemClock.uptimeMillis()); 71 | return uri; 72 | } 73 | 74 | @Override 75 | public String getType(Uri uri) 76 | { 77 | /* MIME type for our log file */ 78 | return "text/plain"; 79 | } 80 | 81 | @Override 82 | public Cursor query(Uri uri, String[] projection, String selection, 83 | String[] selectionArgs, String sortOrder) 84 | { 85 | /* this is called by apps to find out the name and size of the file. 86 | * since we only provide a single file this is simple to implement */ 87 | if (projection == null || projection.length < 1) 88 | { 89 | return null; 90 | } 91 | Long timestamp = mUris.get(uri); 92 | if (timestamp == null) 93 | { /* don't check the validity as this information is not really private */ 94 | return null; 95 | } 96 | MatrixCursor cursor = new MatrixCursor(projection, 1); 97 | if (OpenableColumns.DISPLAY_NAME.equals(cursor.getColumnName(0))) 98 | { 99 | cursor.newRow().add(CharonVpnService.LOG_FILE); 100 | } 101 | else if (OpenableColumns.SIZE.equals(cursor.getColumnName(0))) 102 | { 103 | cursor.newRow().add(mLogFile.length()); 104 | } 105 | else 106 | { 107 | return null; 108 | } 109 | return cursor; 110 | } 111 | 112 | @Override 113 | public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException 114 | { 115 | Long timestamp = mUris.get(uri); 116 | if (timestamp != null) 117 | { 118 | long elapsed = SystemClock.uptimeMillis() - timestamp; 119 | if (elapsed > 0 && elapsed < URI_VALIDITY) 120 | { /* we fail if clock wrapped, should happen rarely though */ 121 | return ParcelFileDescriptor.open(mLogFile, ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_ONLY); 122 | } 123 | mUris.remove(uri); 124 | } 125 | return super.openFile(uri, mode); 126 | } 127 | 128 | @Override 129 | public Uri insert(Uri uri, ContentValues values) 130 | { 131 | /* not supported */ 132 | return null; 133 | } 134 | 135 | @Override 136 | public int delete(Uri uri, String selection, String[] selectionArgs) 137 | { 138 | /* not supported */ 139 | return 0; 140 | } 141 | 142 | @Override 143 | public int update(Uri uri, ContentValues values, String selection, 144 | String[] selectionArgs) 145 | { 146 | /* not supported */ 147 | return 0; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/data/VpnType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2014 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.data; 17 | 18 | import java.util.EnumSet; 19 | 20 | public enum VpnType 21 | { 22 | /* the order here must match the items in R.array.vpn_types */ 23 | IKEV2_EAP("ikev2-eap", EnumSet.of(VpnTypeFeature.USER_PASS)), 24 | IKEV2_CERT("ikev2-cert", EnumSet.of(VpnTypeFeature.CERTIFICATE)), 25 | IKEV2_CERT_EAP("ikev2-cert-eap", EnumSet.of(VpnTypeFeature.USER_PASS, VpnTypeFeature.CERTIFICATE)), 26 | IKEV2_EAP_TLS("ikev2-eap-tls", EnumSet.of(VpnTypeFeature.CERTIFICATE)), 27 | IKEV2_BYOD_EAP("ikev2-byod-eap", EnumSet.of(VpnTypeFeature.USER_PASS, VpnTypeFeature.BYOD)); 28 | 29 | /** 30 | * Features of a VPN type. 31 | */ 32 | public enum VpnTypeFeature 33 | { 34 | /** client certificate is required */ 35 | CERTIFICATE, 36 | /** username and password are required */ 37 | USER_PASS, 38 | /** enable BYOD features */ 39 | BYOD; 40 | } 41 | 42 | private String mIdentifier; 43 | private EnumSet mFeatures; 44 | 45 | /** 46 | * Enum which provides additional information about the supported VPN types. 47 | * 48 | * @param id identifier used to store and transmit this specific type 49 | * @param features of the given VPN type 50 | * @param certificate true if a client certificate is required 51 | */ 52 | VpnType(String id, EnumSet features) 53 | { 54 | mIdentifier = id; 55 | mFeatures = features; 56 | } 57 | 58 | /** 59 | * The identifier used to store this value in the database 60 | * @return identifier 61 | */ 62 | public String getIdentifier() 63 | { 64 | return mIdentifier; 65 | } 66 | 67 | /** 68 | * Checks whether a feature is supported/required by this type of VPN. 69 | * 70 | * @return true if the feature is supported/required 71 | */ 72 | public boolean has(VpnTypeFeature feature) 73 | { 74 | return mFeatures.contains(feature); 75 | } 76 | 77 | /** 78 | * Get the enum entry with the given identifier. 79 | * 80 | * @param identifier get the enum entry with this identifier 81 | * @return the enum entry, or the default if not found 82 | */ 83 | public static VpnType fromIdentifier(String identifier) 84 | { 85 | for (VpnType type : VpnType.values()) 86 | { 87 | if (identifier.equals(type.mIdentifier)) 88 | { 89 | return type; 90 | } 91 | } 92 | return VpnType.IKEV2_EAP; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/SimpleFetcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2018 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.logic; 17 | 18 | import java.io.BufferedOutputStream; 19 | import java.io.ByteArrayOutputStream; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.io.OutputStream; 23 | import java.net.HttpURLConnection; 24 | import java.net.SocketTimeoutException; 25 | import java.net.URL; 26 | import java.util.ArrayList; 27 | import java.util.concurrent.CancellationException; 28 | import java.util.concurrent.ExecutionException; 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.concurrent.Future; 32 | import java.util.concurrent.TimeUnit; 33 | import java.util.concurrent.TimeoutException; 34 | 35 | import androidx.annotation.Keep; 36 | 37 | @Keep 38 | public class SimpleFetcher 39 | { 40 | private static ExecutorService mExecutor = Executors.newCachedThreadPool(); 41 | private static Object mLock = new Object(); 42 | private static ArrayList mFutures = new ArrayList<>(); 43 | private static boolean mDisabled; 44 | 45 | public static byte[] fetch(String uri, byte[] data, String contentType) 46 | { 47 | Future future; 48 | 49 | synchronized (mLock) 50 | { 51 | if (mDisabled) 52 | { 53 | return null; 54 | } 55 | future = mExecutor.submit(() -> { 56 | URL url = new URL(uri); 57 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 58 | conn.setConnectTimeout(10000); 59 | conn.setReadTimeout(10000); 60 | try 61 | { 62 | if (contentType != null) 63 | { 64 | conn.setRequestProperty("Content-Type", contentType); 65 | } 66 | if (data != null) 67 | { 68 | conn.setDoOutput(true); 69 | conn.setFixedLengthStreamingMode(data.length); 70 | OutputStream out = new BufferedOutputStream(conn.getOutputStream()); 71 | out.write(data); 72 | out.close(); 73 | } 74 | return streamToArray(conn.getInputStream()); 75 | } 76 | catch (SocketTimeoutException e) 77 | { 78 | return null; 79 | } 80 | finally 81 | { 82 | conn.disconnect(); 83 | } 84 | }); 85 | 86 | mFutures.add(future); 87 | } 88 | 89 | try 90 | { 91 | /* this enforces a timeout as the ones set on HttpURLConnection might not work reliably */ 92 | return future.get(10000, TimeUnit.MILLISECONDS); 93 | } 94 | catch (InterruptedException|ExecutionException|TimeoutException|CancellationException e) 95 | { 96 | return null; 97 | } 98 | finally 99 | { 100 | synchronized (mLock) 101 | { 102 | mFutures.remove(future); 103 | } 104 | } 105 | } 106 | 107 | /** 108 | * Enable fetching after it has been disabled. 109 | */ 110 | public static void enable() 111 | { 112 | synchronized (mLock) 113 | { 114 | mDisabled = false; 115 | } 116 | } 117 | 118 | /** 119 | * Disable the fetcher and abort any future requests. 120 | * 121 | * The native thread is not cancelable as it is working on an IKE_SA (cancelling the methods of 122 | * HttpURLConnection is not reliably possible anyway), so to abort while fetching we cancel the 123 | * Future (causing a return from fetch() immediately) and let the executor thread continue its 124 | * thing in the background. 125 | * 126 | * Also prevents future fetches until enabled again (e.g. if we aborted OCSP but would then 127 | * block in the subsequent fetch for a CRL). 128 | */ 129 | public static void disable() 130 | { 131 | synchronized (mLock) 132 | { 133 | mDisabled = true; 134 | for (Future future : mFutures) 135 | { 136 | future.cancel(true); 137 | } 138 | } 139 | } 140 | 141 | private static byte[] streamToArray(InputStream in) throws IOException 142 | { 143 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 144 | byte[] buf = new byte[1024]; 145 | int len; 146 | 147 | try 148 | { 149 | while ((len = in.read(buf)) != -1) 150 | { 151 | out.write(buf, 0, len); 152 | } 153 | return out.toByteArray(); 154 | } 155 | catch (IOException e) 156 | { 157 | e.printStackTrace(); 158 | } 159 | finally 160 | { 161 | in.close(); 162 | } 163 | return null; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/StrongSwanApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.logic; 17 | 18 | import java.security.Security; 19 | 20 | import org.strongswan.android.security.LocalCertificateKeyStoreProvider; 21 | import org.strongswan.android.ui.MainActivity; 22 | 23 | import android.app.Application; 24 | import android.content.Context; 25 | import android.os.Build; 26 | 27 | public class StrongSwanApplication extends Application 28 | { 29 | private static Context mContext; 30 | 31 | static { 32 | Security.addProvider(new LocalCertificateKeyStoreProvider()); 33 | } 34 | 35 | @Override 36 | public void onCreate() 37 | { 38 | super.onCreate(); 39 | StrongSwanApplication.mContext = getApplicationContext(); 40 | } 41 | 42 | /** 43 | * Returns the current application context 44 | * @return context 45 | */ 46 | public static Context getContext() 47 | { 48 | return StrongSwanApplication.mContext; 49 | } 50 | 51 | /* 52 | * The libraries are extracted to /data/data/org.strongswan.android/... 53 | * during installation. On newer releases most are loaded in JNI_OnLoad. 54 | */ 55 | static 56 | { 57 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) 58 | { 59 | System.loadLibrary("strongswan"); 60 | 61 | if (MainActivity.USE_BYOD) 62 | { 63 | System.loadLibrary("tpmtss"); 64 | System.loadLibrary("tncif"); 65 | System.loadLibrary("tnccs"); 66 | System.loadLibrary("imcv"); 67 | } 68 | 69 | System.loadLibrary("charon"); 70 | System.loadLibrary("ipsec"); 71 | } 72 | System.loadLibrary("androidbridge"); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/AndroidImc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.logic.imc; 17 | 18 | import org.strongswan.android.logic.imc.attributes.Attribute; 19 | import org.strongswan.android.logic.imc.attributes.AttributeType; 20 | import org.strongswan.android.logic.imc.collectors.Collector; 21 | import org.strongswan.android.logic.imc.collectors.DeviceIdCollector; 22 | import org.strongswan.android.logic.imc.collectors.InstalledPackagesCollector; 23 | import org.strongswan.android.logic.imc.collectors.PortFilterCollector; 24 | import org.strongswan.android.logic.imc.collectors.ProductInformationCollector; 25 | import org.strongswan.android.logic.imc.collectors.SettingsCollector; 26 | import org.strongswan.android.logic.imc.collectors.StringVersionCollector; 27 | 28 | import android.content.Context; 29 | 30 | public class AndroidImc 31 | { 32 | private final Context mContext; 33 | 34 | public AndroidImc(Context context) 35 | { 36 | mContext = context; 37 | } 38 | 39 | /** 40 | * Get a measurement (the binary encoding of the requested attribute) for 41 | * the given vendor specific attribute type. 42 | * 43 | * @param vendor vendor ID 44 | * @param type vendor specific attribute type 45 | * @return encoded attribute, or null if not available or failed 46 | */ 47 | public byte[] getMeasurement(int vendor, int type) 48 | { 49 | return getMeasurement(vendor, type, null); 50 | } 51 | 52 | /** 53 | * Get a measurement (the binary encoding of the requested attribute) for 54 | * the given vendor specific attribute type. 55 | * 56 | * @param vendor vendor ID 57 | * @param type vendor specific attribute type 58 | * @param args optional arguments for a measurement 59 | * @return encoded attribute, or null if not available or failed 60 | */ 61 | public byte[] getMeasurement(int vendor, int type, String[] args) 62 | { 63 | AttributeType attributeType = AttributeType.fromValues(vendor, type); 64 | Collector collector = null; 65 | 66 | switch (attributeType) 67 | { 68 | case IETF_PRODUCT_INFORMATION: 69 | collector = new ProductInformationCollector(); 70 | break; 71 | case IETF_STRING_VERSION: 72 | collector = new StringVersionCollector(); 73 | break; 74 | case IETF_PORT_FILTER: 75 | collector = new PortFilterCollector(); 76 | break; 77 | case IETF_INSTALLED_PACKAGES: 78 | collector = new InstalledPackagesCollector(mContext); 79 | break; 80 | case ITA_SETTINGS: 81 | collector = new SettingsCollector(mContext, args); 82 | break; 83 | case ITA_DEVICE_ID: 84 | collector = new DeviceIdCollector(mContext); 85 | break; 86 | default: 87 | break; 88 | } 89 | if (collector != null) 90 | { 91 | Attribute attribute = collector.getMeasurement(); 92 | if (attribute != null) 93 | { 94 | return attribute.getEncoding(); 95 | } 96 | } 97 | return null; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/ImcState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.logic.imc; 17 | 18 | public enum ImcState 19 | { 20 | UNKNOWN(0), 21 | ALLOW(1), 22 | BLOCK(2), 23 | ISOLATE(3); 24 | 25 | private final int mValue; 26 | 27 | private ImcState(int value) 28 | { 29 | mValue = value; 30 | } 31 | 32 | /** 33 | * Get the numeric value of the IMC state. 34 | * @return numeric value 35 | */ 36 | public int getValue() 37 | { 38 | return mValue; 39 | } 40 | 41 | /** 42 | * Get the enum entry from a numeric value, if defined 43 | * 44 | * @param value numeric value 45 | * @return the enum entry or null 46 | */ 47 | public static ImcState fromValue(int value) 48 | { 49 | for (ImcState state : ImcState.values()) 50 | { 51 | if (state.mValue == value) 52 | { 53 | return state; 54 | } 55 | } 56 | return null; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/attributes/Attribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.logic.imc.attributes; 17 | 18 | /** 19 | * Interface to be implemented by attribute classes 20 | */ 21 | public interface Attribute 22 | { 23 | /** 24 | * Returns the binary encoding of the attribute 25 | * @return binary encoding 26 | */ 27 | public byte[] getEncoding(); 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/attributes/AttributeType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.attributes; 19 | 20 | public enum AttributeType 21 | { 22 | /* IETF standard PA-TNC attribute types defined by RFC 5792 */ 23 | IETF_TESTING(PrivateEnterpriseNumber.IETF, 0), 24 | IETF_ATTRIBUTE_REQUEST(PrivateEnterpriseNumber.IETF, 1), 25 | IETF_PRODUCT_INFORMATION(PrivateEnterpriseNumber.IETF, 2), 26 | IETF_NUMERIC_VERSION(PrivateEnterpriseNumber.IETF, 3), 27 | IETF_STRING_VERSION(PrivateEnterpriseNumber.IETF, 4), 28 | IETF_OPERATIONAL_STATUS(PrivateEnterpriseNumber.IETF, 5), 29 | IETF_PORT_FILTER(PrivateEnterpriseNumber.IETF, 6), 30 | IETF_INSTALLED_PACKAGES(PrivateEnterpriseNumber.IETF, 7), 31 | IETF_PA_TNC_ERROR(PrivateEnterpriseNumber.IETF, 8), 32 | IETF_ASSESSMENT_RESULT(PrivateEnterpriseNumber.IETF, 9), 33 | IETF_REMEDIATION_INSTRUCTIONS(PrivateEnterpriseNumber.IETF, 10), 34 | IETF_FORWARDING_ENABLED(PrivateEnterpriseNumber.IETF, 11), 35 | IETF_FACTORY_DEFAULT_PWD_ENABLED(PrivateEnterpriseNumber.IETF, 12), 36 | IETF_RESERVED(PrivateEnterpriseNumber.IETF, 0xffffffff), 37 | /* ITA attributes */ 38 | ITA_SETTINGS(PrivateEnterpriseNumber.ITA, 4), 39 | ITA_DEVICE_ID(PrivateEnterpriseNumber.ITA, 8); 40 | 41 | private PrivateEnterpriseNumber mVendor; 42 | private int mType; 43 | 44 | /** 45 | * Enum type for vendor specific attributes (defined in their namespace) 46 | * 47 | * @param vendor private enterprise number of vendor 48 | * @param type vendor specific attribute type 49 | */ 50 | private AttributeType(PrivateEnterpriseNumber vendor, int type) 51 | { 52 | mVendor = vendor; 53 | mType = type; 54 | } 55 | 56 | /** 57 | * Get private enterprise number of vendor 58 | * 59 | * @return PEN 60 | */ 61 | public PrivateEnterpriseNumber getVendor() 62 | { 63 | return mVendor; 64 | } 65 | 66 | /** 67 | * Get vendor specific type 68 | * 69 | * @return type 70 | */ 71 | public int getType() 72 | { 73 | return mType; 74 | } 75 | 76 | /** 77 | * Get the enum entry from the given numeric values, if defined 78 | * 79 | * @param vendor vendor id 80 | * @param type vendor specific type 81 | * @return enum entry or null 82 | */ 83 | public static AttributeType fromValues(int vendor, int type) 84 | { 85 | PrivateEnterpriseNumber pen = PrivateEnterpriseNumber.fromValue(vendor); 86 | 87 | if (pen == null) 88 | { 89 | return null; 90 | } 91 | for (AttributeType attr : AttributeType.values()) 92 | { 93 | if (attr.mVendor == pen && attr.mType == type) 94 | { 95 | return attr; 96 | } 97 | } 98 | return null; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/attributes/DeviceIdAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.logic.imc.attributes; 17 | 18 | /** 19 | * ITA Device ID attribute 20 | * 21 | * 1 2 3 22 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 23 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 24 | * | Device ID (Variable Length) | 25 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 26 | */ 27 | public class DeviceIdAttribute implements Attribute 28 | { 29 | private String mDeviceId; 30 | 31 | /** 32 | * Set the device ID 33 | * @param version version number 34 | */ 35 | public void setDeviceId(String deviceId) 36 | { 37 | this.mDeviceId = deviceId; 38 | } 39 | 40 | @Override 41 | public byte[] getEncoding() 42 | { 43 | return mDeviceId.getBytes(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/attributes/InstalledPackagesAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.attributes; 19 | 20 | import java.util.LinkedList; 21 | 22 | import org.strongswan.android.utils.BufferedByteWriter; 23 | 24 | import android.util.Pair; 25 | 26 | /** 27 | * PA-TNC Installed Packages attribute (see section 4.2.7 of RFC 5792) 28 | * 29 | * 1 2 3 30 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 31 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 32 | * | Reserved | Package Count | 33 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 34 | * | Pkg Name Len | Package Name (Variable Length) | 35 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 36 | * | Version Len | Package Version Number (Variable Length) | 37 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 38 | */ 39 | public class InstalledPackagesAttribute implements Attribute 40 | { 41 | private final short RESERVED = 0; 42 | private final LinkedList> mPackages = new LinkedList>(); 43 | 44 | /** 45 | * Add an installed package to this attribute. 46 | * @param name name of the package 47 | * @param version version number of the package 48 | */ 49 | public void addPackage(String name, String version) 50 | { 51 | mPackages.add(new Pair(name, version)); 52 | } 53 | 54 | @Override 55 | public byte[] getEncoding() 56 | { 57 | BufferedByteWriter writer = new BufferedByteWriter(); 58 | writer.put16(RESERVED); 59 | writer.put16((short)mPackages.size()); 60 | for (Pair pair : mPackages) 61 | { 62 | writer.putLen8(pair.first.getBytes()); 63 | writer.putLen8(pair.second.getBytes()); 64 | } 65 | return writer.toByteArray(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/attributes/PortFilterAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.attributes; 19 | 20 | import java.util.LinkedList; 21 | 22 | import org.strongswan.android.logic.imc.collectors.Protocol; 23 | import org.strongswan.android.utils.BufferedByteWriter; 24 | 25 | import android.util.Pair; 26 | 27 | /** 28 | * PA-TNC Port Filter attribute (see section 4.2.6 of RFC 5792) 29 | * 30 | * 1 2 3 31 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 32 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 33 | * | Reserved |B| Protocol | Port Number | 34 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 35 | * | Reserved |B| Protocol | Port Number | 36 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 37 | */ 38 | public class PortFilterAttribute implements Attribute 39 | { 40 | private final LinkedList> mPorts = new LinkedList>(); 41 | 42 | /** 43 | * Add an open port with the given protocol and port number 44 | * @param protocol transport protocol 45 | * @param port port number 46 | */ 47 | public void addPort(Protocol protocol, short port) 48 | { 49 | mPorts.add(new Pair(protocol, port)); 50 | } 51 | 52 | @Override 53 | public byte[] getEncoding() 54 | { 55 | BufferedByteWriter writer = new BufferedByteWriter(); 56 | for (Pair port : mPorts) 57 | { 58 | /* we report open ports, so the BLOCKED flag is not set */ 59 | writer.put((byte)0); 60 | writer.put(port.first.getValue()); 61 | writer.put16(port.second); 62 | } 63 | return writer.toByteArray(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/attributes/PrivateEnterpriseNumber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.logic.imc.attributes; 17 | 18 | public enum PrivateEnterpriseNumber 19 | { 20 | IETF(0x000000), 21 | GOOGLE(0x002B79), 22 | ITA(0x00902a), 23 | UNASSIGNED(0xfffffe), 24 | RESERVED(0xffffff); 25 | 26 | private int mValue; 27 | 28 | /** 29 | * Enum for private enterprise numbers (PEN) as allocated by IANA 30 | * 31 | * @param value numeric value 32 | */ 33 | private PrivateEnterpriseNumber(int value) 34 | { 35 | mValue = value; 36 | } 37 | 38 | /** 39 | * Get the numeric value of a PEN 40 | * 41 | * @return numeric value 42 | */ 43 | public int getValue() 44 | { 45 | return mValue; 46 | } 47 | 48 | /** 49 | * Get the enum entry from a numeric value, if defined 50 | * 51 | * @param value numeric value 52 | * @return the enum entry or null 53 | */ 54 | public static PrivateEnterpriseNumber fromValue(int value) 55 | { 56 | for (PrivateEnterpriseNumber pen : PrivateEnterpriseNumber.values()) 57 | { 58 | if (pen.mValue == value) 59 | { 60 | return pen; 61 | } 62 | } 63 | return null; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/attributes/ProductInformationAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.attributes; 19 | 20 | import org.strongswan.android.utils.BufferedByteWriter; 21 | 22 | /** 23 | * PA-TNC Product Information attribute (see section 4.2.2 of RFC 5792) 24 | * 25 | * 1 2 3 26 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 27 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 28 | * | Product Vendor ID | Product ID | 29 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 30 | * | Product ID | Product Name (Variable Length) | 31 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 32 | */ 33 | public class ProductInformationAttribute implements Attribute 34 | { 35 | private final String PRODUCT_NAME = "Android"; 36 | private final short PRODUCT_ID = 0; 37 | 38 | @Override 39 | public byte[] getEncoding() 40 | { 41 | BufferedByteWriter writer = new BufferedByteWriter(); 42 | writer.put24(PrivateEnterpriseNumber.GOOGLE.getValue()); 43 | writer.put16(PRODUCT_ID); 44 | writer.put(PRODUCT_NAME.getBytes()); 45 | return writer.toByteArray(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/attributes/SettingsAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.attributes; 19 | 20 | import java.util.LinkedList; 21 | 22 | import org.strongswan.android.utils.BufferedByteWriter; 23 | 24 | import android.util.Pair; 25 | 26 | /** 27 | * ITA Settings attribute 28 | * 29 | * 1 2 3 30 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 31 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 32 | * | Settings Count | 33 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 34 | * | Name Length | Name (Variable Length) ~ 35 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 36 | * ~ Name (Variable Length) ~ 37 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 38 | * | Value Length | Value (Variable Length) ~ 39 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 40 | * ~ Value (Variable Length) ~ 41 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 42 | * | Name Length | Name (Variable Length) ~ 43 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 44 | * ~ Name (Variable Length) ~ 45 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 46 | * | Value Length | Value (Variable Length) ~ 47 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 48 | * ~ Value (Variable Length) ~ 49 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 50 | * ........................... 51 | */ 52 | public class SettingsAttribute implements Attribute 53 | { 54 | private final LinkedList> mSettings = new LinkedList>(); 55 | 56 | /** 57 | * Add a setting to this attribute. 58 | * @param name name of the setting 59 | * @param value value of the setting 60 | */ 61 | public void addSetting(String name, String value) 62 | { 63 | mSettings.add(new Pair(name, value)); 64 | } 65 | 66 | @Override 67 | public byte[] getEncoding() 68 | { 69 | BufferedByteWriter writer = new BufferedByteWriter(); 70 | writer.put32(mSettings.size()); 71 | for (Pair pair : mSettings) 72 | { 73 | writer.putLen16(pair.first.getBytes()); 74 | writer.putLen16(pair.second.getBytes()); 75 | } 76 | return writer.toByteArray(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/attributes/StringVersionAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.attributes; 19 | 20 | import org.strongswan.android.utils.BufferedByteWriter; 21 | 22 | /** 23 | * PA-TNC String Version attribute (see section 4.2.4 of RFC 5792) 24 | * 25 | * 1 2 3 26 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 27 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 28 | * | Version Len | Product Version Number (Variable Length) | 29 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 30 | * | Build Num Len | Internal Build Number (Variable Length) | 31 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 32 | * | Config. Len | Configuration Version Number (Variable Length)| 33 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 34 | */ 35 | public class StringVersionAttribute implements Attribute 36 | { 37 | private String mVersionNumber; 38 | private String mBuildNumber; 39 | 40 | /** 41 | * Set the product version number 42 | * @param version version number 43 | */ 44 | public void setProductVersionNumber(String version) 45 | { 46 | this.mVersionNumber = version; 47 | } 48 | 49 | /** 50 | * Set the internal build number 51 | * @param build build number 52 | */ 53 | public void setInternalBuildNumber(String build) 54 | { 55 | this.mBuildNumber = build; 56 | } 57 | 58 | @Override 59 | public byte[] getEncoding() 60 | { 61 | BufferedByteWriter writer = new BufferedByteWriter(); 62 | writer.putLen8(mVersionNumber.getBytes()); 63 | writer.putLen8(mBuildNumber.getBytes()); 64 | /* we don't provide a configuration number */ 65 | writer.put((byte)0); 66 | return writer.toByteArray(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/collectors/Collector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.logic.imc.collectors; 17 | 18 | import org.strongswan.android.logic.imc.attributes.Attribute; 19 | 20 | /** 21 | * Interface for measurement collectors 22 | */ 23 | public interface Collector 24 | { 25 | /** 26 | * This method shall return the result of a measurement, if available 27 | * @return attribute or null 28 | */ 29 | public abstract Attribute getMeasurement(); 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/collectors/DeviceIdCollector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.logic.imc.collectors; 17 | 18 | import org.strongswan.android.logic.imc.attributes.Attribute; 19 | import org.strongswan.android.logic.imc.attributes.DeviceIdAttribute; 20 | 21 | import android.content.ContentResolver; 22 | import android.content.Context; 23 | 24 | public class DeviceIdCollector implements Collector 25 | { 26 | private final ContentResolver mContentResolver; 27 | 28 | public DeviceIdCollector(Context context) 29 | { 30 | mContentResolver = context.getContentResolver(); 31 | } 32 | 33 | @Override 34 | public Attribute getMeasurement() 35 | { 36 | String id = android.provider.Settings.Secure.getString(mContentResolver, "android_id"); 37 | if (id != null) 38 | { 39 | DeviceIdAttribute attribute = new DeviceIdAttribute(); 40 | attribute.setDeviceId(id); 41 | return attribute; 42 | } 43 | return null; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/collectors/InstalledPackagesCollector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.collectors; 19 | 20 | import java.util.List; 21 | 22 | import org.strongswan.android.logic.imc.attributes.Attribute; 23 | import org.strongswan.android.logic.imc.attributes.InstalledPackagesAttribute; 24 | 25 | import android.content.Context; 26 | import android.content.pm.ApplicationInfo; 27 | import android.content.pm.PackageInfo; 28 | import android.content.pm.PackageManager; 29 | 30 | public class InstalledPackagesCollector implements Collector 31 | { 32 | private final PackageManager mPackageManager; 33 | 34 | public InstalledPackagesCollector(Context context) 35 | { 36 | mPackageManager = context.getPackageManager(); 37 | } 38 | 39 | @Override 40 | public Attribute getMeasurement() 41 | { 42 | InstalledPackagesAttribute attribute = new InstalledPackagesAttribute(); 43 | List packages = mPackageManager.getInstalledPackages(0); 44 | for (PackageInfo info : packages) 45 | { 46 | if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 || 47 | info.packageName == null || info.versionName == null) 48 | { /* ignore packages installed in the system image */ 49 | continue; 50 | } 51 | attribute.addPackage(info.packageName, info.versionName); 52 | } 53 | return attribute; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/collectors/PortFilterCollector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.collectors; 19 | 20 | import java.io.BufferedReader; 21 | import java.io.IOException; 22 | import java.io.InputStreamReader; 23 | import java.util.regex.Matcher; 24 | import java.util.regex.Pattern; 25 | 26 | import org.strongswan.android.logic.imc.attributes.Attribute; 27 | import org.strongswan.android.logic.imc.attributes.PortFilterAttribute; 28 | 29 | public class PortFilterCollector implements Collector 30 | { 31 | private static Pattern LISTEN = Pattern.compile("\\bLISTEN\\b"); 32 | private static Pattern PROTOCOL = Pattern.compile("\\b(tcp|udp)6?\\b"); 33 | private static Pattern PORT = Pattern.compile("[:]{1,3}(\\d{1,5})\\b(?!\\.)"); 34 | 35 | @Override 36 | public Attribute getMeasurement() 37 | { 38 | PortFilterAttribute attribute = null; 39 | try 40 | { 41 | Process netstat = Runtime.getRuntime().exec("netstat -n"); 42 | try 43 | { 44 | BufferedReader reader = new BufferedReader(new InputStreamReader(netstat.getInputStream())); 45 | String line; 46 | attribute = new PortFilterAttribute(); 47 | while ((line = reader.readLine()) != null) 48 | { 49 | if (!LISTEN.matcher(line).find()) 50 | { 51 | continue; 52 | } 53 | Matcher protocolMatcher = PROTOCOL.matcher(line); 54 | Matcher portMatcher = PORT.matcher(line); 55 | if (protocolMatcher.find() && portMatcher.find()) 56 | { 57 | Protocol protocol = Protocol.fromName(protocolMatcher.group()); 58 | if (protocol == null) 59 | { 60 | continue; 61 | } 62 | int port = Integer.parseInt(portMatcher.group(1)); 63 | attribute.addPort(protocol, (short)port); 64 | } 65 | } 66 | } 67 | finally 68 | { 69 | netstat.destroy(); 70 | } 71 | } 72 | catch (IOException e) 73 | { 74 | e.printStackTrace(); 75 | } 76 | return attribute; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/collectors/ProductInformationCollector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.collectors; 19 | 20 | import org.strongswan.android.logic.imc.attributes.Attribute; 21 | import org.strongswan.android.logic.imc.attributes.ProductInformationAttribute; 22 | 23 | public class ProductInformationCollector implements Collector 24 | { 25 | @Override 26 | public Attribute getMeasurement() 27 | { /* this is currently hardcoded in the attribute */ 28 | return new ProductInformationAttribute(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/collectors/Protocol.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.logic.imc.collectors; 17 | 18 | public enum Protocol 19 | { 20 | TCP((byte)6, "tcp", "tcp6"), 21 | UDP((byte)17, "udp", "udp6"); 22 | 23 | private final byte mValue; 24 | private String[] mNames; 25 | 26 | private Protocol(byte value, String... names) 27 | { 28 | mValue = value; 29 | mNames = names; 30 | } 31 | 32 | /** 33 | * Get the numeric value of the protocol. 34 | * @return numeric value 35 | */ 36 | public byte getValue() 37 | { 38 | return mValue; 39 | } 40 | 41 | /** 42 | * Get the protocol from the given protocol name, if found. 43 | * @param name protocol name (e.g. "udp" or "tcp") 44 | * @return enum entry or null 45 | */ 46 | public static Protocol fromName(String name) 47 | { 48 | for (Protocol protocol : Protocol.values()) 49 | { 50 | for (String keyword : protocol.mNames) 51 | { 52 | if (keyword.equalsIgnoreCase(name)) 53 | { 54 | return protocol; 55 | } 56 | } 57 | } 58 | return null; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/collectors/SettingsCollector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.collectors; 19 | 20 | import java.util.Locale; 21 | 22 | import org.strongswan.android.logic.imc.attributes.Attribute; 23 | import org.strongswan.android.logic.imc.attributes.SettingsAttribute; 24 | 25 | import android.content.ContentResolver; 26 | import android.content.Context; 27 | 28 | public class SettingsCollector implements Collector 29 | { 30 | private final ContentResolver mContentResolver; 31 | private final String[] mSettings; 32 | 33 | public SettingsCollector(Context context, String[] args) 34 | { 35 | mContentResolver = context.getContentResolver(); 36 | mSettings = args; 37 | } 38 | 39 | @Override 40 | public Attribute getMeasurement() 41 | { 42 | if (mSettings == null || mSettings.length == 0) 43 | { 44 | return null; 45 | } 46 | SettingsAttribute attribute = new SettingsAttribute(); 47 | for (String name : mSettings) 48 | { 49 | String value = android.provider.Settings.Secure.getString(mContentResolver, name.toLowerCase(Locale.US)); 50 | if (value == null) 51 | { 52 | value = android.provider.Settings.System.getString(mContentResolver, name.toLowerCase(Locale.US)); 53 | } 54 | if (value != null) 55 | { 56 | attribute.addSetting(name, value); 57 | } 58 | } 59 | return attribute; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/logic/imc/collectors/StringVersionCollector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * Copyright (C) 2012 Christoph Buehler 4 | * Copyright (C) 2012 Patrick Loetscher 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.logic.imc.collectors; 19 | 20 | import org.strongswan.android.logic.imc.attributes.Attribute; 21 | import org.strongswan.android.logic.imc.attributes.StringVersionAttribute; 22 | 23 | public class StringVersionCollector implements Collector 24 | { 25 | @Override 26 | public Attribute getMeasurement() 27 | { 28 | StringVersionAttribute attribute = new StringVersionAttribute(); 29 | attribute.setProductVersionNumber(android.os.Build.VERSION.RELEASE); 30 | attribute.setInternalBuildNumber(android.os.Build.DISPLAY); 31 | return attribute; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/security/LocalCertificateKeyStoreProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.security; 17 | 18 | import java.security.Provider; 19 | 20 | public class LocalCertificateKeyStoreProvider extends Provider 21 | { 22 | private static final long serialVersionUID = 3515038332469843219L; 23 | 24 | public LocalCertificateKeyStoreProvider() 25 | { 26 | super("LocalCertificateKeyStoreProvider", 1.0, "KeyStore provider for local certificates"); 27 | put("KeyStore.LocalCertificateStore", LocalCertificateKeyStoreSpi.class.getName()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/security/LocalCertificateKeyStoreSpi.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.security; 17 | 18 | import java.io.IOException; 19 | import java.io.InputStream; 20 | import java.io.OutputStream; 21 | import java.security.Key; 22 | import java.security.KeyStoreException; 23 | import java.security.KeyStoreSpi; 24 | import java.security.NoSuchAlgorithmException; 25 | import java.security.UnrecoverableKeyException; 26 | import java.security.cert.Certificate; 27 | import java.security.cert.CertificateException; 28 | import java.util.Collections; 29 | import java.util.Date; 30 | import java.util.Enumeration; 31 | 32 | public class LocalCertificateKeyStoreSpi extends KeyStoreSpi 33 | { 34 | private final LocalCertificateStore mStore = new LocalCertificateStore(); 35 | 36 | @Override 37 | public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException 38 | { 39 | return null; 40 | } 41 | 42 | @Override 43 | public Certificate[] engineGetCertificateChain(String alias) 44 | { 45 | return null; 46 | } 47 | 48 | @Override 49 | public Certificate engineGetCertificate(String alias) 50 | { 51 | return mStore.getCertificate(alias); 52 | } 53 | 54 | @Override 55 | public Date engineGetCreationDate(String alias) 56 | { 57 | return mStore.getCreationDate(alias); 58 | } 59 | 60 | @Override 61 | public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException 62 | { 63 | throw new UnsupportedOperationException(); 64 | } 65 | 66 | @Override 67 | public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException 68 | { 69 | throw new UnsupportedOperationException(); 70 | } 71 | 72 | @Override 73 | public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException 74 | { 75 | /* we ignore the given alias as the store calculates it on its own, 76 | * duplicates are replaced */ 77 | if (!mStore.addCertificate(cert)) 78 | { 79 | throw new KeyStoreException(); 80 | } 81 | } 82 | 83 | @Override 84 | public void engineDeleteEntry(String alias) throws KeyStoreException 85 | { 86 | mStore.deleteCertificate(alias); 87 | } 88 | 89 | @Override 90 | public Enumeration engineAliases() 91 | { 92 | return Collections.enumeration(mStore.aliases()); 93 | } 94 | 95 | @Override 96 | public boolean engineContainsAlias(String alias) 97 | { 98 | return mStore.containsAlias(alias); 99 | } 100 | 101 | @Override 102 | public int engineSize() 103 | { 104 | return mStore.aliases().size(); 105 | } 106 | 107 | @Override 108 | public boolean engineIsKeyEntry(String alias) 109 | { 110 | return false; 111 | } 112 | 113 | @Override 114 | public boolean engineIsCertificateEntry(String alias) 115 | { 116 | return engineContainsAlias(alias); 117 | } 118 | 119 | @Override 120 | public String engineGetCertificateAlias(Certificate cert) 121 | { 122 | return mStore.getCertificateAlias(cert); 123 | } 124 | 125 | @Override 126 | public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException 127 | { 128 | throw new UnsupportedOperationException(); 129 | } 130 | 131 | @Override 132 | public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException 133 | { 134 | if (stream != null) 135 | { 136 | throw new UnsupportedOperationException(); 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/CertificateDeleteConfirmationDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui; 17 | 18 | import android.app.Dialog; 19 | import android.content.Context; 20 | import android.content.DialogInterface; 21 | import android.os.Bundle; 22 | 23 | import org.strongswan.android.R; 24 | 25 | import androidx.appcompat.app.AlertDialog; 26 | import androidx.appcompat.app.AppCompatDialogFragment; 27 | 28 | /** 29 | * Class that displays a confirmation dialog to delete a selected local 30 | * certificate. 31 | */ 32 | public class CertificateDeleteConfirmationDialog extends AppCompatDialogFragment 33 | { 34 | public static final String ALIAS = "alias"; 35 | OnCertificateDeleteListener mListener; 36 | 37 | /** 38 | * Interface that can be implemented by parent activities to get the 39 | * alias of the certificate to delete, if the user confirms the deletion. 40 | */ 41 | public interface OnCertificateDeleteListener 42 | { 43 | public void onDelete(String alias); 44 | } 45 | 46 | @Override 47 | public void onAttach(Context context) 48 | { 49 | super.onAttach(context); 50 | if (context instanceof OnCertificateDeleteListener) 51 | { 52 | mListener = (OnCertificateDeleteListener)context; 53 | } 54 | } 55 | 56 | @Override 57 | public Dialog onCreateDialog(Bundle savedInstanceState) 58 | { 59 | return new AlertDialog.Builder(getActivity()) 60 | .setIcon(android.R.drawable.ic_dialog_alert) 61 | .setTitle(R.string.delete_certificate_question) 62 | .setMessage(R.string.delete_certificate) 63 | .setPositiveButton(R.string.delete_profile, new DialogInterface.OnClickListener() { 64 | @Override 65 | public void onClick(DialogInterface dialog, int whichButton) 66 | { 67 | if (mListener != null) 68 | { 69 | mListener.onDelete(getArguments().getString(ALIAS)); 70 | } 71 | } 72 | }) 73 | .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 74 | @Override 75 | public void onClick(DialogInterface dialog, int which) 76 | { 77 | dismiss(); 78 | } 79 | }).create(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/LogActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui; 17 | 18 | import android.content.Intent; 19 | import android.content.pm.PackageManager.NameNotFoundException; 20 | import android.os.Bundle; 21 | import android.view.Menu; 22 | import android.view.MenuItem; 23 | import android.widget.Toast; 24 | 25 | import org.strongswan.android.R; 26 | import org.strongswan.android.data.LogContentProvider; 27 | import org.strongswan.android.logic.CharonVpnService; 28 | 29 | import java.io.File; 30 | 31 | import androidx.appcompat.app.AppCompatActivity; 32 | 33 | public class LogActivity extends AppCompatActivity 34 | { 35 | @Override 36 | public void onCreate(Bundle savedInstanceState) 37 | { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.log_activity); 40 | 41 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 42 | } 43 | 44 | @Override 45 | public boolean onCreateOptionsMenu(Menu menu) 46 | { 47 | getMenuInflater().inflate(R.menu.log, menu); 48 | return true; 49 | } 50 | 51 | @Override 52 | public boolean onOptionsItemSelected(MenuItem item) 53 | { 54 | switch (item.getItemId()) 55 | { 56 | case android.R.id.home: 57 | finish(); 58 | return true; 59 | case R.id.menu_send_log: 60 | File logfile = new File(getFilesDir(), CharonVpnService.LOG_FILE); 61 | if (!logfile.exists() || logfile.length() == 0) 62 | { 63 | Toast.makeText(this, getString(R.string.empty_log), Toast.LENGTH_SHORT).show(); 64 | return true; 65 | } 66 | 67 | String version = ""; 68 | try 69 | { 70 | version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; 71 | } 72 | catch (NameNotFoundException e) 73 | { 74 | e.printStackTrace(); 75 | } 76 | 77 | Intent intent = new Intent(Intent.ACTION_SEND); 78 | intent.putExtra(Intent.EXTRA_EMAIL, new String[]{MainActivity.CONTACT_EMAIL}); 79 | intent.putExtra(Intent.EXTRA_SUBJECT, String.format(getString(R.string.log_mail_subject), version)); 80 | intent.setType("text/plain"); 81 | intent.putExtra(Intent.EXTRA_STREAM, LogContentProvider.createContentUri()); 82 | startActivity(Intent.createChooser(intent, getString(R.string.send_log))); 83 | return true; 84 | } 85 | return super.onOptionsItemSelected(item); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/RemediationInstructionFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013-2016 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui; 17 | 18 | import android.os.Bundle; 19 | import android.view.LayoutInflater; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | import android.widget.ArrayAdapter; 23 | import android.widget.FrameLayout; 24 | import android.widget.TextView; 25 | 26 | import org.strongswan.android.R; 27 | import org.strongswan.android.logic.imc.RemediationInstruction; 28 | 29 | import androidx.fragment.app.ListFragment; 30 | 31 | public class RemediationInstructionFragment extends ListFragment 32 | { 33 | public static final String ARG_REMEDIATION_INSTRUCTION = "instruction"; 34 | private RemediationInstruction mInstruction = null; 35 | private TextView mTitle; 36 | private TextView mDescription; 37 | private TextView mHeader; 38 | 39 | @Override 40 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 41 | { 42 | /* while the documentation recommends to include "@android:layout/list_content" to retain 43 | * the default functionality, this does not actually work with the ListFragment provided by 44 | * the support library as it builds the view manually and uses different IDs */ 45 | View layout = inflater.inflate(R.layout.remediation_instruction, container, false); 46 | FrameLayout list = (FrameLayout)layout.findViewById(R.id.list_container); 47 | list.addView(super.onCreateView(inflater, list, savedInstanceState)); 48 | return layout; 49 | } 50 | 51 | @Override 52 | public void onActivityCreated(Bundle savedInstanceState) 53 | { 54 | super.onActivityCreated(savedInstanceState); 55 | 56 | if (savedInstanceState != null) 57 | { 58 | mInstruction = savedInstanceState.getParcelable(ARG_REMEDIATION_INSTRUCTION); 59 | } 60 | /* show dividers only between list items */ 61 | getListView().setHeaderDividersEnabled(false); 62 | getListView().setFooterDividersEnabled(false); 63 | /* don't show loader while adapter is not set */ 64 | setListShown(true); 65 | mTitle = (TextView)getView().findViewById(R.id.title); 66 | mDescription = (TextView)getView().findViewById(R.id.description); 67 | mHeader = (TextView)getView().findViewById(R.id.list_header); 68 | } 69 | 70 | @Override 71 | public void onSaveInstanceState(Bundle outState) 72 | { 73 | super.onSaveInstanceState(outState); 74 | outState.putParcelable(ARG_REMEDIATION_INSTRUCTION, mInstruction); 75 | } 76 | 77 | @Override 78 | public void onStart() 79 | { 80 | super.onStart(); 81 | 82 | Bundle args = getArguments(); 83 | if (args != null) 84 | { 85 | mInstruction = args.getParcelable(ARG_REMEDIATION_INSTRUCTION); 86 | } 87 | updateView(mInstruction); 88 | } 89 | 90 | public void updateView(RemediationInstruction instruction) 91 | { 92 | mInstruction = instruction; 93 | if (mInstruction != null) 94 | { 95 | mTitle.setText(mInstruction.getTitle()); 96 | mDescription.setText(mInstruction.getDescription()); 97 | if (mInstruction.getHeader() != null) 98 | { 99 | mHeader.setText(mInstruction.getHeader()); 100 | setListAdapter(new ArrayAdapter(getActivity(), 101 | android.R.layout.simple_list_item_1, mInstruction.getItems())); 102 | } 103 | else 104 | { 105 | mHeader.setText(""); 106 | setListAdapter(null); 107 | } 108 | } 109 | else 110 | { 111 | mTitle.setText(""); 112 | mDescription.setText(""); 113 | mHeader.setText(""); 114 | setListAdapter(null); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/RemediationInstructionsActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui; 17 | 18 | import android.os.Bundle; 19 | import androidx.appcompat.app.AppCompatActivity; 20 | import android.view.MenuItem; 21 | 22 | import org.strongswan.android.R; 23 | import org.strongswan.android.logic.imc.RemediationInstruction; 24 | import org.strongswan.android.ui.RemediationInstructionsFragment.OnRemediationInstructionSelectedListener; 25 | 26 | import java.util.ArrayList; 27 | 28 | public class RemediationInstructionsActivity extends AppCompatActivity implements OnRemediationInstructionSelectedListener 29 | { 30 | @Override 31 | protected void onCreate(Bundle savedInstanceState) 32 | { 33 | super.onCreate(savedInstanceState); 34 | setContentView(R.layout.remediation_instructions); 35 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 36 | 37 | if (savedInstanceState != null) 38 | { /* only update if we're not restoring */ 39 | return; 40 | } 41 | RemediationInstructionsFragment frag = (RemediationInstructionsFragment)getSupportFragmentManager().findFragmentById(R.id.remediation_instructions_fragment); 42 | if (frag != null) 43 | { /* two-pane layout, update fragment */ 44 | Bundle extras = getIntent().getExtras(); 45 | ArrayList list = extras.getParcelableArrayList(RemediationInstructionsFragment.EXTRA_REMEDIATION_INSTRUCTIONS); 46 | frag.updateView(list); 47 | } 48 | else 49 | { /* one-pane layout, create fragment */ 50 | frag = new RemediationInstructionsFragment(); 51 | frag.setArguments(getIntent().getExtras()); 52 | getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, frag).commit(); 53 | } 54 | } 55 | 56 | @Override 57 | public boolean onOptionsItemSelected(MenuItem item) 58 | { 59 | switch (item.getItemId()) 60 | { 61 | case android.R.id.home: 62 | /* one-pane layout, pop possible fragment from stack, finish otherwise */ 63 | if (!getSupportFragmentManager().popBackStackImmediate()) 64 | { 65 | finish(); 66 | } 67 | getSupportActionBar().setTitle(getTitle()); 68 | return true; 69 | default: 70 | return super.onOptionsItemSelected(item); 71 | } 72 | } 73 | 74 | @Override 75 | public void onRemediationInstructionSelected(RemediationInstruction instruction) 76 | { 77 | RemediationInstructionFragment frag = (RemediationInstructionFragment)getSupportFragmentManager().findFragmentById(R.id.remediation_instruction_fragment); 78 | 79 | if (frag != null) 80 | { /* two-pane layout, update directly */ 81 | frag.updateView(instruction); 82 | } 83 | else 84 | { /* one-pane layout, replace fragment */ 85 | frag = new RemediationInstructionFragment(); 86 | Bundle args = new Bundle(); 87 | args.putParcelable(RemediationInstructionFragment.ARG_REMEDIATION_INSTRUCTION, instruction); 88 | frag.setArguments(args); 89 | 90 | getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, frag).addToBackStack(null).commit(); 91 | getSupportActionBar().setTitle(instruction.getTitle()); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/RemediationInstructionsFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui; 17 | 18 | import android.content.Context; 19 | import android.os.Bundle; 20 | import android.view.View; 21 | import android.widget.ListView; 22 | 23 | import org.strongswan.android.R; 24 | import org.strongswan.android.logic.imc.RemediationInstruction; 25 | import org.strongswan.android.ui.adapter.RemediationInstructionAdapter; 26 | 27 | import java.util.ArrayList; 28 | 29 | import androidx.fragment.app.ListFragment; 30 | 31 | public class RemediationInstructionsFragment extends ListFragment 32 | { 33 | public static final String EXTRA_REMEDIATION_INSTRUCTIONS = "instructions"; 34 | private static final String KEY_POSITION = "position"; 35 | private ArrayList mInstructions = null; 36 | private OnRemediationInstructionSelectedListener mListener; 37 | private RemediationInstructionAdapter mAdapter; 38 | private int mCurrentPosition = -1; 39 | 40 | /** 41 | * The activity containing this fragment should implement this interface 42 | */ 43 | public interface OnRemediationInstructionSelectedListener 44 | { 45 | public void onRemediationInstructionSelected(RemediationInstruction instruction); 46 | } 47 | 48 | @Override 49 | public void onActivityCreated(Bundle savedInstanceState) 50 | { 51 | super.onActivityCreated(savedInstanceState); 52 | 53 | if (savedInstanceState != null) 54 | { 55 | mInstructions = savedInstanceState.getParcelableArrayList(EXTRA_REMEDIATION_INSTRUCTIONS); 56 | mCurrentPosition = savedInstanceState.getInt(KEY_POSITION); 57 | } 58 | } 59 | 60 | @Override 61 | public void onSaveInstanceState(Bundle outState) 62 | { 63 | super.onSaveInstanceState(outState); 64 | outState.putParcelableArrayList(RemediationInstructionsFragment.EXTRA_REMEDIATION_INSTRUCTIONS, mInstructions); 65 | outState.putInt(KEY_POSITION, mCurrentPosition); 66 | } 67 | 68 | @Override 69 | public void onAttach(Context context) 70 | { 71 | super.onAttach(context); 72 | 73 | if (context instanceof OnRemediationInstructionSelectedListener) 74 | { 75 | mListener = (OnRemediationInstructionSelectedListener)context; 76 | } 77 | } 78 | 79 | @Override 80 | public void onStart() 81 | { 82 | super.onStart(); 83 | 84 | boolean two_pane = getFragmentManager().findFragmentById(R.id.remediation_instruction_fragment) != null; 85 | if (two_pane) 86 | { /* two-pane layout, make list items selectable */ 87 | getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); 88 | } 89 | 90 | Bundle args = getArguments(); 91 | if (mInstructions == null && args != null) 92 | { 93 | mInstructions = args.getParcelableArrayList(EXTRA_REMEDIATION_INSTRUCTIONS); 94 | } 95 | updateView(mInstructions); 96 | 97 | if (two_pane && mCurrentPosition == -1 && mInstructions.size() > 0) 98 | { /* two-pane layout, select first instruction */ 99 | mCurrentPosition = 0; 100 | mListener.onRemediationInstructionSelected(mInstructions.get(0)); 101 | } 102 | getListView().setItemChecked(mCurrentPosition, true); 103 | } 104 | 105 | @Override 106 | public void onListItemClick(ListView l, View v, int position, long id) 107 | { 108 | mCurrentPosition = position; 109 | mListener.onRemediationInstructionSelected(mInstructions.get(position)); 110 | getListView().setItemChecked(position, true); 111 | } 112 | 113 | public void updateView(ArrayList instructions) 114 | { 115 | if (mAdapter == null) 116 | { 117 | mAdapter = new RemediationInstructionAdapter(getActivity()); 118 | setListAdapter(mAdapter); 119 | } 120 | mInstructions = instructions; 121 | mAdapter.setData(mInstructions); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/SelectedApplicationsActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui; 17 | 18 | import android.content.Intent; 19 | import android.os.Bundle; 20 | import android.view.MenuItem; 21 | 22 | import org.strongswan.android.data.VpnProfileDataSource; 23 | 24 | import androidx.annotation.Nullable; 25 | import androidx.appcompat.app.ActionBar; 26 | import androidx.appcompat.app.AppCompatActivity; 27 | import androidx.fragment.app.FragmentManager; 28 | 29 | public class SelectedApplicationsActivity extends AppCompatActivity 30 | { 31 | private static final String LIST_TAG = "ApplicationList"; 32 | private SelectedApplicationsListFragment mApps; 33 | 34 | @Override 35 | protected void onCreate(@Nullable Bundle savedInstanceState) 36 | { 37 | super.onCreate(savedInstanceState); 38 | 39 | ActionBar actionBar = getSupportActionBar(); 40 | actionBar.setDisplayHomeAsUpEnabled(true); 41 | 42 | FragmentManager fm = getSupportFragmentManager(); 43 | mApps = (SelectedApplicationsListFragment)fm.findFragmentByTag(LIST_TAG); 44 | if (mApps == null) 45 | { 46 | mApps = new SelectedApplicationsListFragment(); 47 | fm.beginTransaction().add(android.R.id.content, mApps, LIST_TAG).commit(); 48 | } 49 | } 50 | 51 | @Override 52 | public boolean onOptionsItemSelected(MenuItem item) 53 | { 54 | switch (item.getItemId()) 55 | { 56 | case android.R.id.home: 57 | prepareResult(); 58 | finish(); 59 | return true; 60 | } 61 | return super.onOptionsItemSelected(item); 62 | } 63 | 64 | @Override 65 | public void onBackPressed() 66 | { 67 | prepareResult(); 68 | super.onBackPressed(); 69 | } 70 | 71 | private void prepareResult() 72 | { 73 | Intent data = new Intent(); 74 | data.putExtra(VpnProfileDataSource.KEY_SELECTED_APPS_LIST, mApps.getSelectedApplications()); 75 | setResult(RESULT_OK, data); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/SettingsActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui; 17 | 18 | import android.os.Bundle; 19 | import android.view.MenuItem; 20 | 21 | import androidx.appcompat.app.AppCompatActivity; 22 | 23 | public class SettingsActivity extends AppCompatActivity 24 | { 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) 28 | { 29 | super.onCreate(savedInstanceState); 30 | 31 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 32 | 33 | getSupportFragmentManager().beginTransaction() 34 | .replace(android.R.id.content, new SettingsFragment()) 35 | .commit(); 36 | } 37 | 38 | @Override 39 | public boolean onOptionsItemSelected(MenuItem item) 40 | { 41 | switch (item.getItemId()) 42 | { 43 | case android.R.id.home: 44 | finish(); 45 | return true; 46 | default: 47 | return super.onOptionsItemSelected(item); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/SettingsFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui; 17 | 18 | import android.content.SharedPreferences; 19 | import android.os.Build; 20 | import android.os.Bundle; 21 | 22 | import org.strongswan.android.R; 23 | import org.strongswan.android.data.VpnProfile; 24 | import org.strongswan.android.data.VpnProfileDataSource; 25 | 26 | import java.util.ArrayList; 27 | import java.util.Collections; 28 | import java.util.Comparator; 29 | import java.util.List; 30 | 31 | import androidx.preference.ListPreference; 32 | import androidx.preference.Preference; 33 | import androidx.preference.PreferenceFragmentCompat; 34 | import androidx.preference.PreferenceManager; 35 | 36 | import static org.strongswan.android.utils.Constants.PREF_DEFAULT_VPN_PROFILE; 37 | import static org.strongswan.android.utils.Constants.PREF_DEFAULT_VPN_PROFILE_MRU; 38 | 39 | public class SettingsFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener 40 | { 41 | private ListPreference mDefaultVPNProfile; 42 | 43 | @Override 44 | public void onCreatePreferences(Bundle bundle, String s) 45 | { 46 | setPreferencesFromResource(R.xml.settings, s); 47 | 48 | mDefaultVPNProfile = (ListPreference)findPreference(PREF_DEFAULT_VPN_PROFILE); 49 | mDefaultVPNProfile.setOnPreferenceChangeListener(this); 50 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) 51 | { 52 | mDefaultVPNProfile.setEnabled(false); 53 | } 54 | } 55 | 56 | @Override 57 | public void onResume() 58 | { 59 | super.onResume(); 60 | 61 | VpnProfileDataSource profiles = new VpnProfileDataSource(getActivity()); 62 | profiles.open(); 63 | 64 | List all = profiles.getAllVpnProfiles(); 65 | Collections.sort(all, new Comparator() { 66 | @Override 67 | public int compare(VpnProfile lhs, VpnProfile rhs) 68 | { 69 | return lhs.getName().compareToIgnoreCase(rhs.getName()); 70 | } 71 | }); 72 | 73 | ArrayList entries = new ArrayList<>(); 74 | ArrayList entryvalues = new ArrayList<>(); 75 | 76 | entries.add(getString(R.string.pref_default_vpn_profile_mru)); 77 | entryvalues.add(PREF_DEFAULT_VPN_PROFILE_MRU); 78 | 79 | for (VpnProfile profile : all) 80 | { 81 | entries.add(profile.getName()); 82 | entryvalues.add(profile.getUUID().toString()); 83 | } 84 | profiles.close(); 85 | 86 | if (entries.size() <= 1) 87 | { 88 | mDefaultVPNProfile.setEnabled(false); 89 | } 90 | else 91 | { 92 | mDefaultVPNProfile.setEnabled(true); 93 | mDefaultVPNProfile.setEntries(entries.toArray(new CharSequence[0])); 94 | mDefaultVPNProfile.setEntryValues(entryvalues.toArray(new CharSequence[0])); 95 | } 96 | 97 | SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity()); 98 | setCurrentProfileName(pref.getString(PREF_DEFAULT_VPN_PROFILE, PREF_DEFAULT_VPN_PROFILE_MRU)); 99 | } 100 | 101 | @Override 102 | public boolean onPreferenceChange(Preference preference, Object newValue) 103 | { 104 | if (preference == mDefaultVPNProfile) 105 | { 106 | setCurrentProfileName((String)newValue); 107 | } 108 | return true; 109 | } 110 | 111 | private void setCurrentProfileName(String uuid) 112 | { 113 | VpnProfileDataSource profiles = new VpnProfileDataSource(getActivity()); 114 | profiles.open(); 115 | 116 | if (!uuid.equals(PREF_DEFAULT_VPN_PROFILE_MRU)) 117 | { 118 | VpnProfile current = profiles.getVpnProfile(uuid); 119 | if (current != null) 120 | { 121 | mDefaultVPNProfile.setSummary(current.getName()); 122 | } 123 | else 124 | { 125 | mDefaultVPNProfile.setSummary(R.string.profile_not_found); 126 | } 127 | } 128 | else 129 | { 130 | mDefaultVPNProfile.setSummary(R.string.pref_default_vpn_profile_mru); 131 | } 132 | profiles.close(); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/VpnProfileSelectActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2018 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui; 17 | 18 | import android.content.Intent; 19 | import android.os.Bundle; 20 | 21 | import org.strongswan.android.R; 22 | import org.strongswan.android.data.VpnProfile; 23 | import org.strongswan.android.ui.VpnProfileListFragment.OnVpnProfileSelectedListener; 24 | 25 | import androidx.appcompat.app.AppCompatActivity; 26 | import androidx.core.content.pm.ShortcutInfoCompat; 27 | import androidx.core.content.pm.ShortcutManagerCompat; 28 | import androidx.core.graphics.drawable.IconCompat; 29 | 30 | public class VpnProfileSelectActivity extends AppCompatActivity implements OnVpnProfileSelectedListener 31 | { 32 | @Override 33 | protected void onCreate(Bundle savedInstanceState) 34 | { 35 | super.onCreate(savedInstanceState); 36 | setContentView(R.layout.vpn_profile_select); 37 | 38 | /* we should probably return a result also if the user clicks the back 39 | * button before selecting a profile */ 40 | setResult(RESULT_CANCELED); 41 | } 42 | 43 | @Override 44 | public void onVpnProfileSelected(VpnProfile profile) 45 | { 46 | Intent shortcut = new Intent(VpnProfileControlActivity.START_PROFILE); 47 | shortcut.putExtra(VpnProfileControlActivity.EXTRA_VPN_PROFILE_ID, profile.getUUID().toString()); 48 | 49 | ShortcutInfoCompat.Builder builder = new ShortcutInfoCompat.Builder(this, profile.getUUID().toString()); 50 | builder.setIntent(shortcut); 51 | builder.setShortLabel(profile.getName()); 52 | builder.setIcon(IconCompat.createWithResource(this, R.mipmap.ic_shortcut)); 53 | setResult(RESULT_OK, ShortcutManagerCompat.createShortcutResultIntent(this, builder.build())); 54 | finish(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/adapter/CertificateIdentitiesAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016-2019 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui.adapter; 17 | 18 | import android.content.Context; 19 | import android.widget.ArrayAdapter; 20 | 21 | import org.strongswan.android.security.TrustedCertificateEntry; 22 | 23 | public class CertificateIdentitiesAdapter extends ArrayAdapter 24 | { 25 | TrustedCertificateEntry mCertificate; 26 | 27 | public CertificateIdentitiesAdapter(Context context) 28 | { 29 | super(context, android.R.layout.simple_dropdown_item_1line); 30 | extractIdentities(); 31 | } 32 | 33 | /** 34 | * Set a new certificate for this adapter. 35 | * 36 | * @param certificate the certificate to extract identities from (null to clear) 37 | */ 38 | public void setCertificate(TrustedCertificateEntry certificate) 39 | { 40 | mCertificate = certificate; 41 | clear(); 42 | extractIdentities(); 43 | } 44 | 45 | private void extractIdentities() 46 | { 47 | if (mCertificate != null) 48 | { 49 | addAll(mCertificate.getSubjectAltNames()); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/adapter/RemediationInstructionAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui.adapter; 17 | 18 | import java.util.List; 19 | 20 | import org.strongswan.android.R; 21 | import org.strongswan.android.logic.imc.RemediationInstruction; 22 | 23 | import android.content.Context; 24 | import android.view.LayoutInflater; 25 | import android.view.View; 26 | import android.view.ViewGroup; 27 | import android.widget.ArrayAdapter; 28 | import android.widget.TextView; 29 | 30 | public class RemediationInstructionAdapter extends ArrayAdapter 31 | { 32 | public RemediationInstructionAdapter(Context context) 33 | { 34 | super(context, 0); 35 | } 36 | 37 | /** 38 | * Set new data for this adapter. 39 | * 40 | * @param data the new data (null to clear) 41 | */ 42 | public void setData(List data) 43 | { 44 | clear(); 45 | if (data != null) 46 | { 47 | addAll(data); 48 | } 49 | } 50 | 51 | @Override 52 | public View getView(int position, View convertView, ViewGroup parent) 53 | { 54 | View view; 55 | if (convertView != null) 56 | { 57 | view = convertView; 58 | } 59 | else 60 | { 61 | LayoutInflater inflater = LayoutInflater.from(getContext()); 62 | view = inflater.inflate(R.layout.remediation_instruction_item, parent, false); 63 | } 64 | RemediationInstruction item = getItem(position); 65 | TextView text = (TextView)view.findViewById(android.R.id.text1); 66 | text.setText(item.getTitle()); 67 | text = (TextView)view.findViewById(android.R.id.text2); 68 | text.setText(item.getDescription()); 69 | return view; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/adapter/SelectedApplicationEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui.adapter; 17 | 18 | import android.content.pm.ApplicationInfo; 19 | import android.content.pm.PackageManager; 20 | import android.graphics.drawable.Drawable; 21 | 22 | import java.text.Collator; 23 | 24 | import androidx.annotation.NonNull; 25 | 26 | public class SelectedApplicationEntry implements Comparable 27 | { 28 | private final ApplicationInfo mInfo; 29 | private final Drawable mIcon; 30 | private final String mName; 31 | private boolean mSelected; 32 | 33 | public SelectedApplicationEntry(PackageManager packageManager, ApplicationInfo info) 34 | { 35 | mInfo = info; 36 | CharSequence name = info.loadLabel(packageManager); 37 | mName = name == null ? info.packageName : name.toString(); 38 | mIcon = info.loadIcon(packageManager); 39 | } 40 | 41 | public void setSelected(boolean selected) 42 | { 43 | mSelected = selected; 44 | } 45 | 46 | public boolean isSelected() 47 | { 48 | return mSelected; 49 | } 50 | 51 | public ApplicationInfo getInfo() 52 | { 53 | return mInfo; 54 | } 55 | 56 | public Drawable getIcon() 57 | { 58 | return mIcon; 59 | } 60 | 61 | @Override 62 | public String toString() 63 | { 64 | return mName; 65 | } 66 | 67 | @Override 68 | public int compareTo(@NonNull SelectedApplicationEntry another) 69 | { 70 | return Collator.getInstance().compare(toString(), another.toString()); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/adapter/SelectedApplicationsAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui.adapter; 17 | 18 | import android.content.Context; 19 | import android.text.TextUtils; 20 | import android.view.LayoutInflater; 21 | import android.view.View; 22 | import android.view.ViewGroup; 23 | import android.widget.BaseAdapter; 24 | import android.widget.Filter; 25 | import android.widget.Filterable; 26 | import android.widget.ImageView; 27 | import android.widget.TextView; 28 | 29 | import org.strongswan.android.R; 30 | import org.strongswan.android.ui.widget.CheckableLinearLayout; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | public class SelectedApplicationsAdapter extends BaseAdapter implements Filterable 36 | { 37 | private Context mContext; 38 | private final Object mLock = new Object(); 39 | private List mData; 40 | private List mDataFiltered; 41 | private SelectedApplicationsFilter mFilter; 42 | 43 | public SelectedApplicationsAdapter(Context context) 44 | { 45 | mContext = context; 46 | mData = mDataFiltered = new ArrayList<>(); 47 | } 48 | 49 | /** 50 | * Set new data for this adapter. 51 | * 52 | * @param data the new data (null to clear) 53 | */ 54 | public void setData(List data) 55 | { 56 | synchronized (mLock) 57 | { 58 | mData.clear(); 59 | mDataFiltered = mData; 60 | if (data != null) 61 | { 62 | mData.addAll(data); 63 | } 64 | } 65 | notifyDataSetChanged(); 66 | } 67 | 68 | @Override 69 | public int getCount() 70 | { 71 | return mDataFiltered.size(); 72 | } 73 | 74 | @Override 75 | public SelectedApplicationEntry getItem(int position) 76 | { 77 | return mDataFiltered.get(position); 78 | } 79 | 80 | @Override 81 | public long getItemId(int position) 82 | { 83 | return mDataFiltered.get(position).toString().hashCode(); 84 | } 85 | 86 | @Override 87 | public View getView(int position, View convertView, ViewGroup parent) 88 | { 89 | View view; 90 | if (convertView != null) 91 | { 92 | view = convertView; 93 | } 94 | else 95 | { 96 | LayoutInflater inflater = LayoutInflater.from(mContext); 97 | view = inflater.inflate(R.layout.selected_application_item, parent, false); 98 | } 99 | SelectedApplicationEntry item = getItem(position); 100 | CheckableLinearLayout checkable = (CheckableLinearLayout)view; 101 | checkable.setChecked(item.isSelected()); 102 | ImageView icon = (ImageView)view.findViewById(R.id.app_icon); 103 | icon.setImageDrawable(item.getIcon()); 104 | TextView text = (TextView)view.findViewById(R.id.app_name); 105 | text.setText(item.toString()); 106 | return view; 107 | } 108 | 109 | @Override 110 | public Filter getFilter() 111 | { 112 | if (mFilter == null) 113 | { 114 | mFilter = new SelectedApplicationsFilter(); 115 | } 116 | return mFilter; 117 | } 118 | 119 | private class SelectedApplicationsFilter extends Filter 120 | { 121 | 122 | @Override 123 | protected FilterResults performFiltering(CharSequence constraint) 124 | { 125 | FilterResults results = new FilterResults(); 126 | ArrayList data, filtered; 127 | 128 | synchronized (mLock) 129 | { 130 | data = new ArrayList<>(mData); 131 | } 132 | 133 | if (TextUtils.isEmpty(constraint)) 134 | { 135 | filtered = data; 136 | } 137 | else 138 | { 139 | String filter = constraint.toString().toLowerCase(); 140 | filtered = new ArrayList<>(); 141 | for (SelectedApplicationEntry entry : data) 142 | { 143 | if (entry.toString().toLowerCase().contains(filter)) 144 | { 145 | filtered.add(entry); 146 | } 147 | } 148 | } 149 | results.values = filtered; 150 | results.count = filtered.size(); 151 | return results; 152 | } 153 | 154 | @Override 155 | @SuppressWarnings("unchecked") 156 | protected void publishResults(CharSequence constraint, FilterResults results) 157 | { 158 | mDataFiltered = (List)results.values; 159 | notifyDataSetChanged(); 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/adapter/TrustedCertificateAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui.adapter; 17 | 18 | import java.util.List; 19 | 20 | import org.strongswan.android.R; 21 | import org.strongswan.android.security.TrustedCertificateEntry; 22 | 23 | import android.content.Context; 24 | import android.view.LayoutInflater; 25 | import android.view.View; 26 | import android.view.ViewGroup; 27 | import android.widget.ArrayAdapter; 28 | import android.widget.TextView; 29 | 30 | public class TrustedCertificateAdapter extends ArrayAdapter 31 | { 32 | public TrustedCertificateAdapter(Context context) 33 | { 34 | super(context, R.layout.trusted_certificates_item); 35 | } 36 | 37 | /** 38 | * Set new data for this adapter. 39 | * 40 | * @param data the new data (null to clear) 41 | */ 42 | public void setData(List data) 43 | { 44 | clear(); 45 | if (data != null) 46 | { 47 | addAll(data); 48 | } 49 | } 50 | 51 | @Override 52 | public View getView(int position, View convertView, ViewGroup parent) 53 | { 54 | View view; 55 | if (convertView != null) 56 | { 57 | view = convertView; 58 | } 59 | else 60 | { 61 | LayoutInflater inflater = LayoutInflater.from(getContext()); 62 | view = inflater.inflate(R.layout.trusted_certificates_item, parent, false); 63 | } 64 | TrustedCertificateEntry item = getItem(position); 65 | TextView text = (TextView)view.findViewById(R.id.subject_primary); 66 | text.setText(item.getSubjectPrimary()); 67 | text = (TextView)view.findViewById(R.id.subject_secondary); 68 | text.setText(item.getSubjectSecondary()); 69 | return view; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/adapter/VpnProfileAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Tobias Brunner 3 | * Copyright (C) 2012 Giuliano Grassi 4 | * Copyright (C) 2012 Ralf Sager 5 | * HSR Hochschule fuer Technik Rapperswil 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2 of the License, or (at your 10 | * option) any later version. See . 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 | * for more details. 16 | */ 17 | 18 | package org.strongswan.android.ui.adapter; 19 | 20 | import android.content.Context; 21 | import android.view.LayoutInflater; 22 | import android.view.View; 23 | import android.view.ViewGroup; 24 | import android.widget.ArrayAdapter; 25 | import android.widget.TextView; 26 | 27 | import org.strongswan.android.R; 28 | import org.strongswan.android.data.VpnProfile; 29 | import org.strongswan.android.data.VpnType.VpnTypeFeature; 30 | 31 | import java.util.Collections; 32 | import java.util.Comparator; 33 | import java.util.List; 34 | 35 | public class VpnProfileAdapter extends ArrayAdapter 36 | { 37 | private final int resource; 38 | private final List items; 39 | 40 | public VpnProfileAdapter(Context context, int resource, 41 | List items) 42 | { 43 | super(context, resource, items); 44 | this.resource = resource; 45 | this.items = items; 46 | sortItems(); 47 | } 48 | 49 | @Override 50 | public View getView(int position, View convertView, ViewGroup parent) 51 | { 52 | View vpnProfileView; 53 | if (convertView != null) 54 | { 55 | vpnProfileView = convertView; 56 | } 57 | else 58 | { 59 | LayoutInflater inflater = LayoutInflater.from(getContext()); 60 | vpnProfileView = inflater.inflate(resource, null); 61 | } 62 | VpnProfile profile = getItem(position); 63 | TextView tv = (TextView)vpnProfileView.findViewById(R.id.profile_item_name); 64 | tv.setText(profile.getName()); 65 | tv = (TextView)vpnProfileView.findViewById(R.id.profile_item_gateway); 66 | tv.setText(getContext().getString(R.string.profile_gateway_label) + ": " + profile.getGateway()); 67 | tv = (TextView)vpnProfileView.findViewById(R.id.profile_item_username); 68 | if (profile.getVpnType().has(VpnTypeFeature.USER_PASS)) 69 | { /* if the view is reused we make sure it is visible */ 70 | tv.setVisibility(View.VISIBLE); 71 | tv.setText(getContext().getString(R.string.profile_username_label) + ": " + profile.getUsername()); 72 | } 73 | else if (profile.getVpnType().has(VpnTypeFeature.CERTIFICATE) && 74 | profile.getLocalId() != null) 75 | { 76 | tv.setVisibility(View.VISIBLE); 77 | tv.setText(getContext().getString(R.string.profile_local_id_label) + ": " + profile.getLocalId()); 78 | } 79 | else 80 | { 81 | tv.setVisibility(View.GONE); 82 | } 83 | tv = (TextView)vpnProfileView.findViewById(R.id.profile_item_certificate); 84 | if (profile.getVpnType().has(VpnTypeFeature.CERTIFICATE)) 85 | { 86 | tv.setText(getContext().getString(R.string.profile_user_certificate_label) + ": " + profile.getUserCertificateAlias()); 87 | tv.setVisibility(View.VISIBLE); 88 | } 89 | else 90 | { 91 | tv.setVisibility(View.GONE); 92 | } 93 | return vpnProfileView; 94 | } 95 | 96 | @Override 97 | public void notifyDataSetChanged() 98 | { 99 | sortItems(); 100 | super.notifyDataSetChanged(); 101 | } 102 | 103 | private void sortItems() 104 | { 105 | Collections.sort(this.items, new Comparator() { 106 | @Override 107 | public int compare(VpnProfile lhs, VpnProfile rhs) 108 | { 109 | return lhs.getName().compareToIgnoreCase(rhs.getName()); 110 | } 111 | }); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/ui/widget/CheckableLinearLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.ui.widget; 17 | 18 | import android.content.Context; 19 | import android.util.AttributeSet; 20 | import android.widget.Checkable; 21 | import android.widget.LinearLayout; 22 | 23 | import androidx.annotation.Nullable; 24 | 25 | public class CheckableLinearLayout extends LinearLayout implements Checkable 26 | { 27 | private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked}; 28 | private boolean mChecked; 29 | 30 | public CheckableLinearLayout(Context context, @Nullable AttributeSet attrs) 31 | { 32 | super(context, attrs); 33 | } 34 | 35 | @Override 36 | public void setChecked(boolean checked) 37 | { 38 | if (mChecked != checked) 39 | { 40 | mChecked = checked; 41 | refreshDrawableState(); 42 | } 43 | } 44 | 45 | @Override 46 | public boolean isChecked() 47 | { 48 | return mChecked; 49 | } 50 | 51 | @Override 52 | public void toggle() 53 | { 54 | setChecked(!mChecked); 55 | } 56 | 57 | @Override 58 | protected int[] onCreateDrawableState(int extraSpace) 59 | { 60 | final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 61 | if (isChecked()) 62 | { 63 | mergeDrawableStates(drawableState, CHECKED_STATE_SET); 64 | } 65 | return drawableState; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/utils/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016-2018 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.utils; 17 | 18 | public final class Constants 19 | { 20 | /** 21 | * Intent action used to notify about changes to the VPN profiles 22 | */ 23 | public static final String VPN_PROFILES_CHANGED = "org.strongswan.android.VPN_PROFILES_CHANGED"; 24 | 25 | /** 26 | * Used in the intent above to notify about edits or inserts of a VPN profile (long) 27 | */ 28 | public static final String VPN_PROFILES_SINGLE = "org.strongswan.android.VPN_PROFILES_SINGLE"; 29 | 30 | /** 31 | * Used in the intent above to notify about the deletion of multiple VPN profiles (array of longs) 32 | */ 33 | public static final String VPN_PROFILES_MULTIPLE = "org.strongswan.android.VPN_PROFILES_MULTIPLE"; 34 | 35 | /** 36 | * Limits for MTU 37 | */ 38 | public static final int MTU_MAX = 1500; 39 | public static final int MTU_MIN = 1280; 40 | 41 | /** 42 | * Limits for NAT-T keepalive 43 | */ 44 | public static final int NAT_KEEPALIVE_MAX = 120; 45 | public static final int NAT_KEEPALIVE_MIN = 10; 46 | 47 | /** 48 | * Preference key for default VPN profile 49 | */ 50 | public static final String PREF_DEFAULT_VPN_PROFILE = "pref_default_vpn_profile"; 51 | 52 | /** 53 | * Value used to signify that the most recently used profile should be used as default 54 | */ 55 | public static final String PREF_DEFAULT_VPN_PROFILE_MRU = "pref_default_vpn_profile_mru"; 56 | 57 | /** 58 | * Preference key to store the most recently used VPN profile 59 | */ 60 | public static final String PREF_MRU_VPN_PROFILE = "pref_mru_vpn_profile"; 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/utils/SettingsWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.utils; 17 | 18 | import java.util.Arrays; 19 | import java.util.LinkedHashMap; 20 | import java.util.Map.Entry; 21 | import java.util.regex.Pattern; 22 | 23 | 24 | /** 25 | * Simple generator for data/files that may be parsed by libstrongswan's 26 | * settings_t class. 27 | */ 28 | public class SettingsWriter 29 | { 30 | /** 31 | * Top-level section 32 | */ 33 | private final SettingsSection mTop = new SettingsSection(); 34 | 35 | /** 36 | * Set a string value 37 | * @param key 38 | * @param value 39 | * @return the writer 40 | */ 41 | public SettingsWriter setValue(String key, String value) 42 | { 43 | Pattern pattern = Pattern.compile("[^#{}=\"\\n\\t ]+"); 44 | if (key == null || !pattern.matcher(key).matches()) 45 | { 46 | return this; 47 | } 48 | String[] keys = key.split("\\."); 49 | SettingsSection section = mTop; 50 | section = findOrCreateSection(Arrays.copyOfRange(keys, 0, keys.length-1)); 51 | section.Settings.put(keys[keys.length-1], value); 52 | return this; 53 | } 54 | 55 | /** 56 | * Set an integer value 57 | * @param key 58 | * @param value 59 | * @return the writer 60 | */ 61 | public SettingsWriter setValue(String key, Integer value) 62 | { 63 | return setValue(key, value == null ? null : value.toString()); 64 | } 65 | 66 | /** 67 | * Set a boolean value 68 | * @param key 69 | * @param value 70 | * @return the writer 71 | */ 72 | public SettingsWriter setValue(String key, Boolean value) 73 | { 74 | return setValue(key, value == null ? null : value ? "1" : "0"); 75 | } 76 | 77 | /** 78 | * Serializes the settings to a string in the format understood by 79 | * libstrongswan's settings_t parser. 80 | * @return serialized settings 81 | */ 82 | public String serialize() 83 | { 84 | StringBuilder builder = new StringBuilder(); 85 | serializeSection(mTop, builder); 86 | return builder.toString(); 87 | } 88 | 89 | /** 90 | * Serialize the settings in a section and recursively serialize sub-sections 91 | * @param section 92 | * @param builder 93 | */ 94 | private void serializeSection(SettingsSection section, StringBuilder builder) 95 | { 96 | for (Entry setting : section.Settings.entrySet()) 97 | { 98 | builder.append(setting.getKey()).append('='); 99 | if (setting.getValue() != null) 100 | { 101 | builder.append("\"").append(escapeValue(setting.getValue())).append("\""); 102 | } 103 | builder.append('\n'); 104 | } 105 | 106 | for (Entry subsection : section.Sections.entrySet()) 107 | { 108 | builder.append(subsection.getKey()).append(" {\n"); 109 | serializeSection(subsection.getValue(), builder); 110 | builder.append("}\n"); 111 | } 112 | } 113 | 114 | /** 115 | * Escape value so it may be wrapped in " 116 | * @param value 117 | * @return 118 | */ 119 | private String escapeValue(String value) 120 | { 121 | return value.replace("\\", "\\\\").replace("\"", "\\\""); 122 | } 123 | 124 | /** 125 | * Find or create the nested sections with the given names 126 | * @param sections list of section names 127 | * @return final section 128 | */ 129 | private SettingsSection findOrCreateSection(String[] sections) 130 | { 131 | SettingsSection section = mTop; 132 | for (String name : sections) 133 | { 134 | SettingsSection subsection = section.Sections.get(name); 135 | if (subsection == null) 136 | { 137 | subsection = new SettingsSection(); 138 | section.Sections.put(name, subsection); 139 | } 140 | section = subsection; 141 | } 142 | return section; 143 | } 144 | 145 | /** 146 | * A section containing sub-sections and settings. 147 | */ 148 | private class SettingsSection 149 | { 150 | /** 151 | * Assigned key/value pairs 152 | */ 153 | LinkedHashMap Settings = new LinkedHashMap(); 154 | 155 | /** 156 | * Assigned sub-sections 157 | */ 158 | LinkedHashMap Sections = new LinkedHashMap(); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /app/src/main/java/org/strongswan/android/utils/Utils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2019 Tobias Brunner 3 | * HSR Hochschule fuer Technik Rapperswil 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. See . 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * for more details. 14 | */ 15 | 16 | package org.strongswan.android.utils; 17 | 18 | 19 | import java.net.InetAddress; 20 | import java.net.UnknownHostException; 21 | 22 | public class Utils 23 | { 24 | static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); 25 | 26 | /** 27 | * Converts the given byte array to a hexadecimal string encoding. 28 | * 29 | * @param bytes byte array to convert 30 | * @return hex string 31 | */ 32 | public static String bytesToHex(byte[] bytes) 33 | { 34 | char[] hex = new char[bytes.length * 2]; 35 | for (int i = 0; i < bytes.length; i++) 36 | { 37 | int value = bytes[i]; 38 | hex[i*2] = HEXDIGITS[(value & 0xf0) >> 4]; 39 | hex[i*2+1] = HEXDIGITS[ value & 0x0f]; 40 | } 41 | return new String(hex); 42 | } 43 | 44 | /** 45 | * Validate the given proposal string 46 | * 47 | * @param ike true for IKE, false for ESP 48 | * @param proposal proposal string 49 | * @return true if valid 50 | */ 51 | public native static boolean isProposalValid(boolean ike, String proposal); 52 | 53 | /** 54 | * Parse an IP address without doing a name lookup 55 | * 56 | * @param address IP address string 57 | * @return address bytes if valid 58 | */ 59 | private native static byte[] parseInetAddressBytes(String address); 60 | 61 | /** 62 | * Parse an IP address without doing a name lookup (as compared to InetAddress.fromName()) 63 | * 64 | * @param address IP address string 65 | * @return address if valid 66 | * @throws UnknownHostException if address is invalid 67 | */ 68 | public static InetAddress parseInetAddress(String address) throws UnknownHostException 69 | { 70 | byte[] bytes = parseInetAddressBytes(address); 71 | if (bytes == null) 72 | { 73 | throw new UnknownHostException(); 74 | } 75 | return InetAddress.getByAddress(bytes); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libandroidbridge.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/arm64-v8a/libandroidbridge.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libcharon.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/arm64-v8a/libcharon.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libimcv.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/arm64-v8a/libimcv.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libipsec.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/arm64-v8a/libipsec.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libstrongswan.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/arm64-v8a/libstrongswan.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libtnccs.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/arm64-v8a/libtnccs.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libtncif.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/arm64-v8a/libtncif.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libtpmtss.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/arm64-v8a/libtpmtss.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libandroidbridge.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/armeabi-v7a/libandroidbridge.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libcharon.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/armeabi-v7a/libcharon.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libimcv.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/armeabi-v7a/libimcv.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libipsec.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/armeabi-v7a/libipsec.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libstrongswan.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/armeabi-v7a/libstrongswan.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libtnccs.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/armeabi-v7a/libtnccs.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libtncif.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/armeabi-v7a/libtncif.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libtpmtss.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/armeabi-v7a/libtpmtss.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libandroidbridge.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86/libandroidbridge.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libcharon.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86/libcharon.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libimcv.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86/libimcv.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libipsec.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86/libipsec.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libstrongswan.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86/libstrongswan.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libtnccs.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86/libtnccs.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libtncif.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86/libtncif.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libtpmtss.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86/libtpmtss.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libandroidbridge.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86_64/libandroidbridge.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libcharon.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86_64/libcharon.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libimcv.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86_64/libimcv.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libipsec.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86_64/libipsec.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libstrongswan.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86_64/libstrongswan.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libtnccs.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86_64/libtnccs.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libtncif.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86_64/libtncif.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libtpmtss.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/jniLibs/x86_64/libtpmtss.so -------------------------------------------------------------------------------- /app/src/main/res/color/checkable_text_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_close_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-hdpi/ic_close_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-hdpi/ic_notification.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_notification_connecting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-hdpi/ic_notification_connecting.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_notification_disconnect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-hdpi/ic_notification_disconnect.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_notification_disconnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-hdpi/ic_notification_disconnected.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_notification_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-hdpi/ic_notification_warning.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_close_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-mdpi/ic_close_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-mdpi/ic_notification.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_notification_connecting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-mdpi/ic_notification_connecting.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_notification_disconnect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-mdpi/ic_notification_disconnect.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_notification_disconnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-mdpi/ic_notification_disconnected.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_notification_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-mdpi/ic_notification_warning.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_close_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-xhdpi/ic_close_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-xhdpi/ic_notification.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_notification_connecting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-xhdpi/ic_notification_connecting.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_notification_disconnect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-xhdpi/ic_notification_disconnect.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_notification_disconnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-xhdpi/ic_notification_disconnected.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_notification_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Babar-Bashir/Ikev2_Android_VPN/a41d07a0c0820bd7c6453fd9a878885d3b01027d/app/src/main/res/drawable-xhdpi/ic_notification_warning.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/activated_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 21 | 22 | 25 | 26 | 29 | 30 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/error_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/remediation_instruction_background_large.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/state_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout-large/remediation_instructions.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 28 | 29 | 35 | 36 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 |