diff --git a/Readme-ja.md b/Readme-ja.md index 68cea1c..80886ad 100644 --- a/Readme-ja.md +++ b/Readme-ja.md @@ -19,7 +19,7 @@ TunProxyアプリを起動すると以下の画面が起動します。 ![Tun Proxy](images/TunProxy.png) * Proxy address (host:port) - * 接続先のプロキシサーバを ** IPアドレス:ポート番号 ** の形式で指定します。 + * 接続先のプロキシサーバを **IPアドレス:ポート番号** の形式で指定します。 IPアドレスはIPv4形式で記載する必要があります。 * [Start] ボタン @@ -35,7 +35,7 @@ TunProxyアプリを起動すると以下の画面が起動します。 VPNの接続設定を行います。 -![Menu Settings](images/Menu-Settings.png) ⇒ ![Menu Settings](images/Menu-Settings-sub.png) +![Menu Settings](images/Menu-Settings.png) ⇒ ![Menu Settings](images/Menu-Settings-app.png) Disallow Application と Allow Application の2つのモードがありますが、同時に指定することはできません。 このためどちらのモードで動作させたいかを選択する必要があります。 diff --git a/Readme.md b/Readme.md index 9982d8e..109cb57 100644 --- a/Readme.md +++ b/Readme.md @@ -19,7 +19,7 @@ When you start the TunProxy application, the following screen will be launched. ![Tun Proxy](images/TunProxy.png) * Proxy address (host:port) - * Specify the destination proxy server in the format ** IP address:port number **. + * Specify the destination proxy server in the format **IP address:port number**. The IP address must be described in IPv4 format. * [Start] button @@ -35,7 +35,7 @@ Application settings can be made from the menu icon (![Menu](images/Menu.png)) a Configure VPN service settings. -![Menu Settings](images/Menu-Settings.png) => ![Menu Settings](images/Menu-Settings-sub.png) +![Menu Settings](images/Menu-Settings.png) => ![Menu Settings](images/Menu-Settings-app.png) There are two modes, Disallow Application and Allow Application, but you can not specify them at the same time. Because of this you will have to choose whether you want to run in either mode. diff --git a/android_app/app/build.gradle b/android_app/app/build.gradle index e0fc71c..f0f4091 100644 --- a/android_app/app/build.gradle +++ b/android_app/app/build.gradle @@ -6,7 +6,7 @@ android { applicationId "tun.proxy" minSdkVersion 21 targetSdkVersion 27 - versionCode 100007 + versionCode 100008 versionName VERSION_NAME testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { diff --git a/android_app/app/src/main/AndroidManifest.xml b/android_app/app/src/main/AndroidManifest.xml index a190721..5104d7a 100644 --- a/android_app/app/src/main/AndroidManifest.xml +++ b/android_app/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ - diff --git a/android_app/app/src/main/java/tun/proxy/MainActivity.java b/android_app/app/src/main/java/tun/proxy/MainActivity.java index ea19a17..4eef299 100644 --- a/android_app/app/src/main/java/tun/proxy/MainActivity.java +++ b/android_app/app/src/main/java/tun/proxy/MainActivity.java @@ -170,7 +170,6 @@ public void run() { protected void onPause() { super.onPause(); statusHandler.removeCallbacks(statusRunnable); - unbindService(serviceConnection); } diff --git a/android_app/app/src/main/java/tun/proxy/MyApplication.java b/android_app/app/src/main/java/tun/proxy/MyApplication.java index 05d2236..e743b46 100644 --- a/android_app/app/src/main/java/tun/proxy/MyApplication.java +++ b/android_app/app/src/main/java/tun/proxy/MyApplication.java @@ -14,17 +14,18 @@ import java.util.Set; public class MyApplication extends Application { - private static Context context; + private static MyApplication instance; - public static Context getContext() { - return context; + public static MyApplication getInstance() { + return instance; } @Override public void onCreate() { super.onCreate(); - context = getApplicationContext(); + instance = this; } + // public byte [] getTrustCA() { // try { // X509Certificate cert = CertificateUtil.getCACertificate("/sdcard/", ""); @@ -40,22 +41,37 @@ public void onCreate() { // return null; // } - public int getVPNMode() { + public enum VPNMode {DISALLOW, ALLOW}; + +// public final String vpn_mode_key[] = {VPNMode.DISALLOW.name(), VPNMode.ALLOW.name()}; + + private final String pref_key[] = {"vpn_disallowed_application", "vpn_allowed_application"}; + + public VPNMode loadVPNMode() { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - String vpn_connection_mode = sharedPreferences.getString("vpn_connection_mode", String.valueOf(SimplePreferenceFragment.PackageListPreferenceFragment.VPNMode.DISALLOW.ordinal())); - return Integer.parseInt( vpn_connection_mode ); + String vpn_mode = sharedPreferences.getString("vpn_connection_mode", MyApplication.VPNMode.DISALLOW.name()); + return VPNMode.valueOf ( vpn_mode ); } - public Set getAllowedApplication() { - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - Set allowed_preference = sharedPreferences.getStringSet("vpn_allowed_application", new HashSet() ); - return allowed_preference; + public void storeVPNMode(VPNMode mode) { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + final SharedPreferences.Editor editor = prefs.edit(); + editor.putString("vpn_connection_mode", mode.name()); + return; } - public Set getDisallowedApplication() { - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - Set disallowed_preference = sharedPreferences.getStringSet("vpn_disallowed_application", new HashSet() ); - return disallowed_preference; + public Set loadVPNApplication(VPNMode mode) { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + Set preference = prefs.getStringSet(pref_key[mode.ordinal()], new HashSet() ); + return preference; + } + + public void storeVPNApplication(VPNMode mode, final Set set) { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + final SharedPreferences.Editor editor = prefs.edit(); + editor.putStringSet(pref_key[mode.ordinal()], set); + editor.commit(); + return ; } } diff --git a/android_app/app/src/main/java/tun/proxy/SimplePreferenceFragment.java b/android_app/app/src/main/java/tun/proxy/SimplePreferenceFragment.java index 4ef4566..ac4dba1 100644 --- a/android_app/app/src/main/java/tun/proxy/SimplePreferenceFragment.java +++ b/android_app/app/src/main/java/tun/proxy/SimplePreferenceFragment.java @@ -8,25 +8,19 @@ import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.preference.PreferenceScreen; +import android.preference.*; import android.view.MenuItem; -import java.util.ArrayList; -import java.util.EnumSet; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; -import tun.utils.CertificateUtil; - public class SimplePreferenceFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener { + public static final String VPN_CONNECTION_MODE = "vpn_connection_mode"; + public static final String VPN_DISALLOWED_APPLICATION_LIST = "vpn_disallowed_application_list"; + public static final String VPN_ALLOWED_APPLICATION_LIST = "vpn_allowed_application_list"; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -34,35 +28,34 @@ public void onCreate(Bundle savedInstanceState) { setHasOptionsMenu(true); /* Allowed / Disallowed Application */ - final ListPreference pkg_selection = (ListPreference) this.findPreference("vpn_connection_mode"); + final ListPreference pkg_selection = (ListPreference) this.findPreference(VPN_CONNECTION_MODE); pkg_selection.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object value) { - if (preference instanceof ListPreference) { - ListPreference listPreference = (ListPreference) preference; - int index = listPreference.findIndexOfValue((String) value); - - PreferenceScreen disallow = (PreferenceScreen) findPreference("disallowed_application_list"); - PreferenceScreen allow = (PreferenceScreen) findPreference("allowed_application_list"); - disallow.setEnabled(index == 0); - allow.setEnabled(index != 0); + if (preference instanceof ListPreference) { + ListPreference listPreference = (ListPreference) preference; + int index = listPreference.findIndexOfValue((String) value); + PreferenceScreen disallow = (PreferenceScreen) findPreference(VPN_DISALLOWED_APPLICATION_LIST); + PreferenceScreen allow = (PreferenceScreen) findPreference(VPN_ALLOWED_APPLICATION_LIST); + disallow.setEnabled(index == 0); + allow.setEnabled(index != 0); - // Set the summary to reflect the new value. - preference.setSummary(index >= 0 ? listPreference.getEntries()[index] : null); + // Set the summary to reflect the new value. + preference.setSummary(index >= 0 ? listPreference.getEntries()[index] : null); - } - return true; + } + return true; } }); pkg_selection.setSummary(pkg_selection.getEntry()); - PreferenceScreen disallow = (PreferenceScreen) findPreference("disallowed_application_list"); - PreferenceScreen allow = (PreferenceScreen) findPreference("allowed_application_list"); - disallow.setEnabled(Integer.parseInt(pkg_selection.getValue()) == 0); - allow.setEnabled(Integer.parseInt(pkg_selection.getValue()) != 0); + PreferenceScreen disallow = (PreferenceScreen) findPreference(VPN_DISALLOWED_APPLICATION_LIST); + PreferenceScreen allow = (PreferenceScreen) findPreference(VPN_ALLOWED_APPLICATION_LIST); + disallow.setEnabled(MyApplication.VPNMode.DISALLOW.name().equals(pkg_selection.getValue())); + allow.setEnabled(MyApplication.VPNMode.ALLOW.name().equals(pkg_selection.getValue())); - findPreference("allowed_application_list").setOnPreferenceClickListener(this); - findPreference("disallowed_application_list").setOnPreferenceClickListener(this); + findPreference(VPN_DISALLOWED_APPLICATION_LIST).setOnPreferenceClickListener(this); + findPreference(VPN_ALLOWED_APPLICATION_LIST).setOnPreferenceClickListener(this); } @@ -81,11 +74,11 @@ public boolean onOptionsItemSelected(MenuItem item) { public boolean onPreferenceClick(Preference preference) { // keyを見てクリックされたPreferenceを特定 switch (preference.getKey()) { - case "allowed_application_list": - transitionFragment(PackageListPreferenceFragment.newInstance(PackageListPreferenceFragment.VPNMode.ALLOW)); + case VPN_DISALLOWED_APPLICATION_LIST: + transitionFragment(PackageListPreferenceFragment.newInstance(MyApplication.VPNMode.DISALLOW)); break; - case "disallowed_application_list": - transitionFragment(PackageListPreferenceFragment.newInstance(PackageListPreferenceFragment.VPNMode.DISALLOW)); + case VPN_ALLOWED_APPLICATION_LIST: + transitionFragment(PackageListPreferenceFragment.newInstance(MyApplication.VPNMode.ALLOW)); break; } return false; @@ -102,13 +95,11 @@ private void transitionFragment(PreferenceFragment nextPreferenceFragment) { @TargetApi(Build.VERSION_CODES.HONEYCOMB) public static class PackageListPreferenceFragment extends PreferenceFragment { - enum VPNMode {DISALLOW, ALLOW}; - private VPNMode mode; + private MyApplication.VPNMode mode; private PreferenceScreen mRootPreferenceScreen; - private String pref_key[] = {"vpn_disallowed_application", "vpn_allowed_application"}; - public static PackageListPreferenceFragment newInstance(VPNMode mode) { + public static PackageListPreferenceFragment newInstance(MyApplication.VPNMode mode) { PackageListPreferenceFragment fragment = new PackageListPreferenceFragment(); fragment.mode = mode; return fragment; @@ -122,6 +113,12 @@ public void onCreate(Bundle savedInstanceState) { setPreferenceScreen(mRootPreferenceScreen); } + @Override + public void onPause() { + super.onPause(); + storeSelectedPackageSet(this.getSelectedPackageSet()); + } + @Override public void onResume() { super.onResume(); @@ -135,7 +132,7 @@ private void removeAllPreferenceScreen() { } private void buildPackagesPreferences() { - Context context = MyApplication.getContext().getApplicationContext(); + Context context = MyApplication.getInstance().getApplicationContext(); PackageManager pm = context.getPackageManager(); List installedPackages = pm.getInstalledPackages(PackageManager.GET_META_DATA); for (final PackageInfo pi : installedPackages) { @@ -157,7 +154,8 @@ private Set getSelectedPackageSet() { Preference pref = this.mRootPreferenceScreen.getPreference(i); if ((pref instanceof CheckBoxPreference)) { CheckBoxPreference pref_check = (CheckBoxPreference) pref; - if (pref_check.isChecked()) selected.add(pref_check.getSummary().toString()); + if (pref_check.isChecked()) + selected.add(pref_check.getSummary().toString()); } } return selected; @@ -175,24 +173,21 @@ private void setSelectedPackageSet(Set selected) { } private void loadSelectedPackage() { - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getActivity()); this.getArguments(); - Set selected = prefs.getStringSet( pref_key[mode.ordinal()], new HashSet()); + mode = MyApplication.getInstance().loadVPNMode(); + Set selected = MyApplication.getInstance().loadVPNApplication(mode); setSelectedPackageSet(selected); } private void storeSelectedPackageSet(final Set set) { - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); - final SharedPreferences.Editor editor = prefs.edit(); - editor.putStringSet(pref_key[mode.ordinal()], set); - editor.commit(); + MyApplication.getInstance().storeVPNMode(mode); + MyApplication.getInstance().storeVPNApplication(mode, set); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { - storeSelectedPackageSet(this.getSelectedPackageSet()); startActivity(new Intent(getActivity(), SimplePreferenceActivity.class)); return true; } diff --git a/android_app/app/src/main/java/tun/proxy/service/Tun2HttpVpnService.java b/android_app/app/src/main/java/tun/proxy/service/Tun2HttpVpnService.java index a4d1a7d..7a9c291 100644 --- a/android_app/app/src/main/java/tun/proxy/service/Tun2HttpVpnService.java +++ b/android_app/app/src/main/java/tun/proxy/service/Tun2HttpVpnService.java @@ -150,17 +150,17 @@ private Builder getBuilder() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { try { MyApplication app = (MyApplication) this.getApplication(); - if (app.getVPNMode() == 0) { - Set disallow = app.getDisallowedApplication(); + if (app.loadVPNMode() == MyApplication.VPNMode.DISALLOW) { + Set disallow = app.loadVPNApplication(MyApplication.VPNMode.DISALLOW); Log.d(TAG, "disallowed:" + disallow.size()); builder.addDisallowedApplication(Arrays.asList(disallow.toArray(new String[0]))); } else { - Set allow = app.getAllowedApplication(); + Set allow = app.loadVPNApplication(MyApplication.VPNMode.ALLOW); Log.d(TAG, "allowed:" + allow.size()); builder.addAllowedApplication(Arrays.asList(allow.toArray(new String[0]))); } } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } } diff --git a/android_app/app/src/main/java/tun/utils/CertificateUtil.java b/android_app/app/src/main/java/tun/utils/CertificateUtil.java index c9100ad..a541703 100644 --- a/android_app/app/src/main/java/tun/utils/CertificateUtil.java +++ b/android_app/app/src/main/java/tun/utils/CertificateUtil.java @@ -43,13 +43,13 @@ public static boolean findCAStore(String caName) { } } } catch(IOException e){ - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } catch(KeyStoreException e){ - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } catch(NoSuchAlgorithmException e){ - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } catch(CertificateException e){ - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } return found; } @@ -73,13 +73,13 @@ public static List getRootCAStore() { rootCAList.add( cert ); } } catch (IOException e) { - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } catch (KeyStoreException e) { - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } catch (CertificateException e) { - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } return rootCAList; } @@ -108,9 +108,9 @@ public static Map getRootCAMap(EnumSet Collections.sort( certList, new Comparator() { @Override public int compare(X509Certificate t1, X509Certificate t2) { - String t1cn = CertificateUtil.getCommonName( t1.getIssuerX500Principal().getName() ); - String t2cn = CertificateUtil.getCommonName( t2.getIssuerX500Principal().getName() ); - return t1cn.compareToIgnoreCase( t2cn ); + String t1cn = CertificateUtil.getCommonName( t1.getIssuerX500Principal().getName() ); + String t2cn = CertificateUtil.getCommonName( t2.getIssuerX500Principal().getName() ); + return t1cn.compareToIgnoreCase( t2cn ); } } ); // ソート後 @@ -126,13 +126,13 @@ public int compare(X509Certificate t1, X509Certificate t2) { rootCAMap.put( "entry", rootCANameList.toArray( new String[0] ) ); rootCAMap.put( "value", rootCAList.toArray( new String[0] ) ); } catch (IOException e) { - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } catch (KeyStoreException e) { - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } catch (CertificateException e) { - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } return rootCAMap; } @@ -140,7 +140,6 @@ public int compare(X509Certificate t1, X509Certificate t2) { public static String encode(byte b[]) { return new String( b, StandardCharsets.ISO_8859_1 ); } - public static byte[] decode(String s) { return s.getBytes( StandardCharsets.ISO_8859_1 ); } @@ -153,7 +152,7 @@ public static Intent trustRootCA(X509Certificate cert) { intent.putExtra( KeyChain.EXTRA_CERTIFICATE, cert.getEncoded() ); intent.putExtra( KeyChain.EXTRA_NAME, getCommonName(cert.getIssuerDN().getName())); } catch (CertificateEncodingException e) { - e.printStackTrace(); + Log.e( TAG, e.getMessage(), e); } return intent; } @@ -203,12 +202,12 @@ public static String getCommonName(String dn) { } public static String getOrganization(String dn) { - String cn = ""; + String on = ""; Matcher m = CA_ORGANIZATION.matcher( dn ); if (m.find()) { - cn = m.group( 1 ); + on = m.group( 1 ); } - return cn; + return on; } } diff --git a/android_app/app/src/main/java/tun/utils/IPUtil.java b/android_app/app/src/main/java/tun/utils/IPUtil.java index e424c69..e5862ae 100644 --- a/android_app/app/src/main/java/tun/utils/IPUtil.java +++ b/android_app/app/src/main/java/tun/utils/IPUtil.java @@ -1,6 +1,5 @@ package tun.utils; - import android.util.Log; import java.net.InetAddress; diff --git a/android_app/app/src/main/java/tun/utils/PackageUtil.java b/android_app/app/src/main/java/tun/utils/PackageUtil.java index 1bed65b..c743095 100644 --- a/android_app/app/src/main/java/tun/utils/PackageUtil.java +++ b/android_app/app/src/main/java/tun/utils/PackageUtil.java @@ -12,12 +12,9 @@ public class PackageUtil { public static Map getPackageMap() { final Map packageMap = new HashMap<>(); - Context context = MyApplication.getContext().getApplicationContext(); + Context context = MyApplication.getInstance().getApplicationContext(); PackageManager pm = context.getPackageManager(); List installedPackages = pm.getInstalledPackages( PackageManager.GET_META_DATA ); - for (final PackageInfo pi : installedPackages) { - - } Collections.sort( installedPackages, new Comparator() { @Override public int compare(PackageInfo t1, PackageInfo t2) { diff --git a/android_app/app/src/main/res/values/strings.xml b/android_app/app/src/main/res/values/strings.xml index f5b8522..1468717 100644 --- a/android_app/app/src/main/res/values/strings.xml +++ b/android_app/app/src/main/res/values/strings.xml @@ -24,8 +24,8 @@ Allowed Application - 0 - 1 + DISALLOW + ALLOW allowed application list diff --git a/android_app/app/src/main/res/xml/preferences.xml b/android_app/app/src/main/res/xml/preferences.xml index 6e199dc..52af5c8 100644 --- a/android_app/app/src/main/res/xml/preferences.xml +++ b/android_app/app/src/main/res/xml/preferences.xml @@ -9,23 +9,23 @@ + android:key="vpn_disallowed_application_list" + android:title="@string/pref_header_disallowed_application_list" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + android:key="vpn_allowed_application_list" + android:title="@string/pref_header_allowed_application_list" + android:layout_width="wrap_content" + android:layout_height="wrap_content" />