├── .gitignore ├── DHCPv6-Client-Android.iml ├── DHCPv6Client.iml ├── LICENSE ├── README.markdown ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── libs │ ├── RootTools.jar │ └── systembartint-1.0.4.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── org │ │ └── daduke │ │ └── realmar │ │ └── dhcpv6client │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── aidl │ └── com │ │ └── android │ │ └── vending │ │ └── billing │ │ └── IInAppBillingService.aidl │ ├── app_icon-web.png │ ├── drawable_plus-web.png │ ├── ic_about-web.png │ ├── ic_donate-web.png │ ├── ic_home-web.png │ ├── ic_install-web.png │ ├── ic_invoke-web.png │ ├── ic_menu-web.png │ ├── ic_settings-web.png │ ├── ic_support-web.png │ ├── ic_uninstall-web.png │ ├── java │ └── org │ │ └── daduke │ │ └── realmar │ │ └── dhcpv6client │ │ ├── AboutFragment.java │ │ ├── App.java │ │ ├── AppIntegrity.java │ │ ├── BillingPublicKey.EXAMPLE │ │ ├── BroadcastIntentReceiver.java │ │ ├── Constants.java │ │ ├── CustomDHCPv6Fragment.java │ │ ├── CustomListViewAdpater.java │ │ ├── DHCPv6Integrity.java │ │ ├── DoStartup.java │ │ ├── DonationFragment.java │ │ ├── GenerateClientConfig.java │ │ ├── GetIPv6Address.java │ │ ├── InstallDHCPv6Client.java │ │ ├── IpCollector.java │ │ ├── MainActivity.java │ │ ├── MainFragment.java │ │ ├── Misc.java │ │ ├── MsgBoxes.java │ │ ├── NavItem.java │ │ ├── PostBootComplete.java │ │ ├── SUCalls.java │ │ ├── SettingsAdvancedAddInterfacesFragment.java │ │ ├── SettingsAdvancedFragment.java │ │ ├── SettingsFragment.java │ │ ├── SupportFragment.java │ │ ├── SystemIntegrity.java │ │ ├── UIMenu.java │ │ ├── UninstallDHCPv6Client.java │ │ └── util │ │ ├── IabBroadcastReceiver.java │ │ ├── IabException.java │ │ ├── IabHelper.java │ │ ├── IabResult.java │ │ ├── Inventory.java │ │ ├── Purchase.java │ │ ├── Security.java │ │ └── SkuDetails.java │ └── res │ ├── animator │ ├── fade_in.xml │ └── fade_out.xml │ ├── layout │ ├── about_fragment.xml │ ├── activity_main.xml │ ├── activity_settings_advanced.xml │ ├── activity_settings_advanced_add.xml │ ├── custom_dhcpv6_fragment.xml │ ├── custom_list_view_item.xml │ ├── custom_list_view_seperator.xml │ ├── main_fragment.xml │ ├── nav_header.xml │ ├── settings_activity.xml │ ├── support_fragment.xml │ └── toolbar.xml │ ├── menu │ ├── about_activity.xml │ ├── client_main.xml │ ├── custom_dhcpv6_menu.xml │ ├── settings_activity.xml │ ├── settings_advanced_add_menu.xml │ ├── settings_advanced_menu.xml │ └── support_activity.xml │ ├── mipmap-hdpi │ ├── app_icon.png │ ├── drawable_plus.png │ ├── ic_about.png │ ├── ic_donate.png │ ├── ic_home.png │ ├── ic_install.png │ ├── ic_invoke.png │ ├── ic_launcher.png │ ├── ic_menu.png │ ├── ic_settings.png │ ├── ic_support.png │ └── ic_uninstall.png │ ├── mipmap-mdpi │ ├── app_icon.png │ ├── drawable_plus.png │ ├── ic_about.png │ ├── ic_donate.png │ ├── ic_home.png │ ├── ic_install.png │ ├── ic_invoke.png │ ├── ic_launcher.png │ ├── ic_menu.png │ ├── ic_settings.png │ ├── ic_support.png │ └── ic_uninstall.png │ ├── mipmap-xhdpi │ ├── app_icon.png │ ├── drawable_plus.png │ ├── ic_about.png │ ├── ic_donate.png │ ├── ic_home.png │ ├── ic_install.png │ ├── ic_invoke.png │ ├── ic_launcher.png │ ├── ic_menu.png │ ├── ic_settings.png │ ├── ic_support.png │ └── ic_uninstall.png │ ├── mipmap-xxhdpi │ ├── app_icon.png │ ├── drawable_plus.png │ ├── ic_about.png │ ├── ic_donate.png │ ├── ic_home.png │ ├── ic_install.png │ ├── ic_invoke.png │ ├── ic_launcher.png │ ├── ic_menu.png │ ├── ic_settings.png │ ├── ic_support.png │ └── ic_uninstall.png │ ├── mipmap-xxxhdpi │ ├── app_icon.png │ ├── drawable_plus.png │ ├── ic_about.png │ ├── ic_donate.png │ ├── ic_home.png │ ├── ic_install.png │ ├── ic_invoke.png │ ├── ic_menu.png │ ├── ic_settings.png │ ├── ic_support.png │ └── ic_uninstall.png │ ├── raw │ ├── .no_delete │ ├── dhcpv6_base.zip │ └── dhcpv6_update.zip │ ├── values-w820dp │ └── dimens.xml │ ├── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ ├── donate.xml │ ├── preferences.xml │ ├── preferences_advanced.xml │ └── preferences_advanced_add_interfaces.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── install.sh └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | .DS_Store 4 | /build 5 | /captures 6 | Testing.java 7 | BillingPublicKey.java 8 | Misc/* 9 | *.sw* 10 | app-release.apk 11 | .idea/* 12 | *.iws 13 | /out/ 14 | .idea_modules/ 15 | atlassian-ide-plugin.xml 16 | com_crashlytics_export_strings.xml 17 | crashlytics.properties 18 | crashlytics-build.properties 19 | fabric.properties 20 | -------------------------------------------------------------------------------- /DHCPv6-Client-Android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /DHCPv6Client.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Get an IPv6 address using DHCPv6 on your Android device. Be future-proof. 2 | Copyright (C) 2015 Anastassios Martakos 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | Contact the developer of this program: customer.realmar@gmail.com 18 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # [DEPRECATED] Use [Mygod/DHCPv6-Client-Android](https://github.com/Mygod/DHCPv6-Client-Android) instead! 2 | 3 | I no longer maintain this project. Please use [MyGod's fork](https://github.com/Mygod/DHCPv6-Client-Android) 4 | instead. Not only is their version maintained but also comes with *massive improvements*: 5 | 6 | - Supports Android 5.0+, this app struggles with [Nougat](https://github.com/realmar/DHCPv6-Client-Android/issues/8) 7 | - Completely systemless and doesn't require Busybox; (no extra steps for install/uninstall) 8 | - No closed source components and licensed in Apache 2.0; 9 | - Modern codebase 10 | 11 | You can get MyGod's fork here: 12 | 13 | 14 | 15 | [XDA Labs](https://labs.xda-developers.com/store/app/be.mygod.dhcpv6client) 16 | 17 | [GitHub](https://github.com/Mygod/DHCPv6-Client-Android) 18 | 19 | DHCPv6 Client 20 | ============= 21 | 22 | Description 23 | ----------- 24 | This app requires ROOT PREMISSIONS because of the following reasons: 25 | - the wide-dhcpv6 client uses the privileged port 546 26 | - the client needs to configure network interfaces 27 | 28 | Android doesn't support DHCPv6 out of the box, because Google doesn't want to implement this feature. For some people (especially universities and corporations) this is a serious issue, because they require control over their IPv6 addresses. 29 | 30 | This app fixes this issue. It requests an IPv6 address using DHCPv6 and makes your Android future-proof. 31 | 32 | For a full explanation on how this app works please refer to the xda-developer thread. 33 | 34 | Discussion: http://forum.xda-developers.com/android/apps-games/app-dhcpv6-client-t3176443 35 | Download: https://play.google.com/store/apps/details?id=org.daduke.realmar.dhcpv6client 36 | 37 | Google Issue Thread: https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=32621 38 | 39 | Third Party Software 40 | -------------------- 41 | I use the DHCPv6 client binary from wide-dhcpv6 (http://wide-dhcpv6.sourceforge.net/). I didn't compile this binary by myself. Instead I've taken it from the Fairphone source (https://www.fairphone.com/). I also use Fairphone's scripts around this binary. 42 | 43 | wide-dhcpv6 is licensed under the BSD License 44 | 45 | Fairphones source contains open source software including software released under the GNU General Public License (GPL) version 2 and Library/Lesser General Public License version 2/2.1. 46 | 47 | Those binaries and scripts will be downloaded an put in the right folder when executing install.sh 48 | 49 | Installation 50 | ------------ 51 | - Run install.sh 52 | 53 | Known Issues 54 | ------------ 55 | ### DHCPv6 Client ask me everytime if I want to install the client 56 | Update or reinstall busybox 57 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion '25.0.0' 6 | 7 | defaultConfig { 8 | applicationId "org.daduke.realmar.dhcpv6client" 9 | minSdkVersion 16 10 | targetSdkVersion 25 11 | versionCode 31 12 | versionName "1.6" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:25.0.0' 25 | compile files('libs/RootTools.jar') 26 | compile 'eu.chainfire:libsuperuser:1.0.0.+' 27 | compile 'com.android.support:design:25.0.0' 28 | compile files('libs/systembartint-1.0.4.jar') 29 | } 30 | -------------------------------------------------------------------------------- /app/libs/RootTools.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/libs/RootTools.jar -------------------------------------------------------------------------------- /app/libs/systembartint-1.0.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/libs/systembartint-1.0.4.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /scratch/android_studio/android_sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/org/daduke/realmar/dhcpv6client/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/app_icon-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/app_icon-web.png -------------------------------------------------------------------------------- /app/src/main/drawable_plus-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/drawable_plus-web.png -------------------------------------------------------------------------------- /app/src/main/ic_about-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/ic_about-web.png -------------------------------------------------------------------------------- /app/src/main/ic_donate-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/ic_donate-web.png -------------------------------------------------------------------------------- /app/src/main/ic_home-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/ic_home-web.png -------------------------------------------------------------------------------- /app/src/main/ic_install-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/ic_install-web.png -------------------------------------------------------------------------------- /app/src/main/ic_invoke-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/ic_invoke-web.png -------------------------------------------------------------------------------- /app/src/main/ic_menu-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/ic_menu-web.png -------------------------------------------------------------------------------- /app/src/main/ic_settings-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/ic_settings-web.png -------------------------------------------------------------------------------- /app/src/main/ic_support-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/ic_support-web.png -------------------------------------------------------------------------------- /app/src/main/ic_uninstall-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realmar/DHCPv6-Client-Android/d80e071040ca24e189a3014805f90e88b1a0bb19/app/src/main/ic_uninstall-web.png -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/AboutFragment.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Fragment; 4 | import android.os.Bundle; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | 10 | /** 11 | * Created by Anastassios Martakos on 9/22/15. 12 | */ 13 | public class AboutFragment extends Fragment { 14 | @Override 15 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 16 | Bundle savedInstanceState) { 17 | // Inflate the layout for this fragment 18 | return inflater.inflate(R.layout.about_fragment, container, false); 19 | } 20 | 21 | @Override 22 | public void onStart() { 23 | super.onStart(); 24 | String version_name = "not available"; 25 | 26 | try { 27 | version_name = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0).versionName; 28 | }catch(Exception e) { 29 | } 30 | 31 | TextView about_version_name = (TextView) getView().findViewById(R.id.about_version_name); 32 | version_name = "App Version: " + version_name; 33 | 34 | about_version_name.setText(version_name); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/App.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Application; 4 | import android.content.IntentFilter; 5 | import android.net.ConnectivityManager; 6 | 7 | /** 8 | * @author Mygod 9 | */ 10 | public class App extends Application { 11 | @Override 12 | public void onCreate() { 13 | super.onCreate(); 14 | registerReceiver(new BroadcastIntentReceiver(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/AppIntegrity.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.preference.PreferenceManager; 6 | 7 | /** 8 | * Created by Anastassios Martakos on 8/14/15. 9 | */ 10 | public class AppIntegrity { 11 | public static void check_shared_preferences(Context context) { 12 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(context); 13 | 14 | SharedPreferences.Editor editor = shared_preferences.edit(); 15 | 16 | if(!shared_preferences.contains(Constants.PREF_ENABLE)) { editor.putBoolean(Constants.PREF_ENABLE, true); } 17 | if(!shared_preferences.contains(Constants.PREF_DEBUG)) { editor.putBoolean(Constants.PREF_DEBUG, false); } 18 | if(!shared_preferences.contains(Constants.PREF_WLAN)) { editor.putBoolean(Constants.PREF_WLAN, true); } 19 | if(!shared_preferences.contains(Constants.PREF_MOBILE)) { editor.putBoolean(Constants.PREF_MOBILE, false); } 20 | if(!shared_preferences.contains(Constants.PREF_ALL)) { editor.putBoolean(Constants.PREF_ALL, false); } 21 | if(!shared_preferences.contains(Constants.DHCP6C_CONF)) { editor.putString(Constants.DHCP6C_CONF, "null"); } 22 | if(!shared_preferences.contains(Constants.DHCP6CDNS_CONF)) { editor.putString(Constants.DHCP6CDNS_CONF, "null"); } 23 | if(!shared_preferences.contains(Constants.SHOW_ARCH_WARNING)) { editor.putBoolean(Constants.SHOW_ARCH_WARNING, true); } 24 | 25 | editor.commit(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/BillingPublicKey.EXAMPLE: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | /** 4 | * Created by Anastassios Martakos on 9/22/15. 5 | */ 6 | public class BillingPublicKey { 7 | public static String BILLING_PUBLIC_KEY = ""; 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/BroadcastIntentReceiver.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | /** 8 | * Created by Anastassios Martakos on 7/30/15. 9 | */ 10 | 11 | 12 | public class BroadcastIntentReceiver extends BroadcastReceiver { 13 | private boolean do_all = false; 14 | 15 | @Override 16 | public void onReceive(Context context, Intent intent) { 17 | if("android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction())) { 18 | do_all = GetIPv6Address.PreGetIPv6Address(context, do_all); 19 | }else if("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) { 20 | new PostBootComplete(context, do_all).execute(); 21 | } 22 | 23 | Misc.send_ui_request_refresh_ips(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/Constants.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | /** 4 | * Created by Anastassios Martakos on 8/7/15. 5 | */ 6 | public class Constants { 7 | // In-App Billing (for donation) 8 | 9 | public static final String DONATION_001 = "donation_001"; 10 | public static final String DONATION_005 = "donation_005"; 11 | public static final String DONATION_010 = "donation_010"; 12 | 13 | public static final String LAST_STATE = "network_last_state"; 14 | public static final String LAST_SSID = "network_last_ssid"; 15 | public static final String ADDITIONAL_INTERFACES = "additional_interfaces"; 16 | public static final String PREF_ALL = "pref_all"; 17 | 18 | public static final String PREF_ENABLE = "pref_enable"; 19 | public static final String IS_INSTALLED = "is_installed"; 20 | public static final String IS_INSTALLED_UPDATE = "is_installed_update"; 21 | public static final String PREF_DEBUG = "pref_debug"; 22 | public static final String PREF_WLAN = "pref_wlan"; 23 | public static final String PREF_MOBILE = "pref_mobile"; 24 | 25 | public static final String DHCP6C_CONF = "dhcp6c_conf"; 26 | public static final String DHCP6CDNS_CONF = "dhcp6cdns_conf"; 27 | 28 | public static final String ARCH_ARMV8 = "armv8"; 29 | public static final String ARCH_X86 = "x86"; 30 | 31 | public static final String SHOW_ARCH_WARNING = "arch_warning"; 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/CustomDHCPv6Fragment.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Fragment; 4 | import android.os.Bundle; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.Button; 9 | import android.widget.CheckBox; 10 | import android.widget.LinearLayout; 11 | import android.widget.Toast; 12 | 13 | import java.util.ArrayList; 14 | 15 | /** 16 | * Created by Anastassios Martakos on 8/7/15. 17 | */ 18 | 19 | public class CustomDHCPv6Fragment extends Fragment { 20 | private Button invoke_button; 21 | 22 | @Override 23 | public void onStart() { 24 | super.onStart(); 25 | 26 | create_interface_menu(); 27 | 28 | invoke_button = (Button) getView().findViewById(R.id.button_invoke_dhcpv6); 29 | invoke_button.setOnClickListener(new View.OnClickListener() { 30 | @Override 31 | public void onClick(View v) { 32 | custom_invoke_dhcpv6(); 33 | } 34 | }); 35 | } 36 | 37 | @Override 38 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 39 | Bundle savedInstanceState) { 40 | // Inflate the layout for this fragment 41 | return inflater.inflate(R.layout.custom_dhcpv6_fragment, container, false); 42 | } 43 | 44 | private void create_interface_menu() { 45 | ArrayList interfaces = Misc.get_all_interfaces(); 46 | 47 | LinearLayout linear_layout = (LinearLayout) getView().findViewById(R.id.cust_selection); 48 | 49 | for(Object inter_face : interfaces) { 50 | CheckBox check_box = new CheckBox(getActivity()); 51 | 52 | check_box.setText(inter_face.toString()); 53 | check_box.setChecked(false); 54 | 55 | linear_layout.addView(check_box); 56 | } 57 | } 58 | 59 | private void custom_invoke_dhcpv6() { 60 | ArrayList interfaces_to_process = new ArrayList(); 61 | 62 | LinearLayout linear_layout = (LinearLayout) getView().findViewById(R.id.cust_selection); 63 | 64 | int interface_count = linear_layout.getChildCount(); 65 | 66 | for(int i = 0; i < interface_count; i++) { 67 | CheckBox check_box = (CheckBox) linear_layout.getChildAt(i); 68 | if(check_box.isChecked()) { 69 | interfaces_to_process.add(check_box.getText().toString()); 70 | } 71 | 72 | check_box.setChecked(false); 73 | } 74 | 75 | for(String inter_face : interfaces_to_process) { 76 | Toast.makeText(getActivity(), getString(R.string.trying_ipv6) + inter_face, Toast.LENGTH_SHORT).show(); 77 | new GetIPv6Address(inter_face).execute(); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/CustomListViewAdpater.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.TextView; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Anastassios Martakos on 8/12/15. 14 | */ 15 | public class CustomListViewAdpater extends BaseAdapter { 16 | private ArrayList ip_array; 17 | private LayoutInflater inflater; 18 | private static final int TYPE_PERSON = 0; 19 | private static final int TYPE_DIVIDER = 1; 20 | 21 | public CustomListViewAdpater(Context context, ArrayList ip_array) { 22 | this.ip_array = ip_array; 23 | this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 24 | } 25 | 26 | @Override 27 | public int getCount() { 28 | return ip_array.size(); 29 | } 30 | 31 | @Override 32 | public long getItemId(int position) { 33 | return position; 34 | } 35 | 36 | @Override 37 | public Object getItem(int position) { 38 | return ip_array.get(position); 39 | } 40 | 41 | @Override 42 | public int getViewTypeCount() { 43 | // TYPE_PERSON and TYPE_DIVIDER 44 | return 2; 45 | } 46 | 47 | @Override 48 | public int getItemViewType(int position) { 49 | if (getItem(position) instanceof IpCollector) { 50 | return TYPE_PERSON; 51 | } 52 | 53 | return TYPE_DIVIDER; 54 | } 55 | 56 | @Override 57 | public boolean isEnabled(int position) { 58 | return (getItemViewType(position) == TYPE_PERSON); 59 | } 60 | 61 | @Override 62 | public View getView(int position, View convertView, ViewGroup parent) { 63 | int type = getItemViewType(position); 64 | if (convertView == null) { 65 | switch (type) { 66 | case TYPE_PERSON: 67 | convertView = inflater.inflate(R.layout.custom_list_view_item, parent, false); 68 | break; 69 | case TYPE_DIVIDER: 70 | convertView = inflater.inflate(R.layout.custom_list_view_seperator, parent, false); 71 | break; 72 | } 73 | } 74 | 75 | switch (type) { 76 | case TYPE_PERSON: 77 | IpCollector person = (IpCollector)getItem(position); 78 | TextView ip = (TextView)convertView.findViewById(R.id.list_view_item); 79 | ip.setText(person.getIp()); 80 | break; 81 | case TYPE_DIVIDER: 82 | TextView title = (TextView)convertView.findViewById(R.id.list_view_seperator); 83 | String titleString = (String)getItem(position); 84 | title.setText(titleString); 85 | break; 86 | } 87 | 88 | return convertView; 89 | } 90 | } -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/DHCPv6Integrity.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.preference.PreferenceManager; 6 | import android.util.Log; 7 | 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.FileNotFoundException; 11 | import java.io.FileOutputStream; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.io.OutputStream; 15 | import java.math.BigInteger; 16 | import java.security.MessageDigest; 17 | import java.security.NoSuchAlgorithmException; 18 | import java.util.ArrayList; 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | import java.util.zip.ZipEntry; 22 | import java.util.zip.ZipInputStream; 23 | 24 | /** 25 | * Created by Anastassios Martakos on 13.08.2015. 26 | */ 27 | public class DHCPv6Integrity { 28 | private static final String TAG = "DHCPv6Integrity"; 29 | 30 | private static String[] required_files = { 31 | "/system/bin/dhcp6c", 32 | // "/system/etc/wide-dhcpv6/dhcp6c.conf", 33 | "/system/etc/wide-dhcpv6/dhcp6c.script", 34 | // "/system/etc/wide-dhcpv6/dhcp6cDNS.conf", 35 | "/system/etc/wide-dhcpv6/dhcp6cctlkey" 36 | }; 37 | 38 | private static String[] required_files_update = { 39 | "/system/bin/dhcp6ctl", 40 | // "/system/bin/dhcp6s", 41 | // "/system/etc/wide-dhcpv6/dhcp6s.conf", 42 | // "/system/etc/wide-dhcpv6/dhcp6sctlkey" 43 | }; 44 | 45 | private static String[] config_files = { 46 | "/system/etc/wide-dhcpv6/dhcp6c.conf", 47 | "/system/etc/wide-dhcpv6/dhcp6cDNS.conf" 48 | }; 49 | 50 | private static Map md5_sums = new HashMap(); 51 | static { 52 | md5_sums.put("/system/bin/dhcp6c", "3374072ddc7390e94f5b800e0f6475f4"); 53 | // md5_sums.put("/system/etc/wide-dhcpv6/dhcp6c.conf", "1103f18a20f607952c9911cda488c996"); 54 | md5_sums.put("/system/etc/wide-dhcpv6/dhcp6c.script", "09ab71119edeea93a9517d17501d32be"); 55 | // md5_sums.put("/system/etc/wide-dhcpv6/dhcp6cDNS.conf", "fb99396abe72d95d172bcaa30b1f3bc3"); 56 | md5_sums.put("/system/etc/wide-dhcpv6/dhcp6cctlkey", "3602680e0fd4987eb2de8a7a8ea62044"); 57 | // md5_sums.put("/system/etc/wide-dhcpv6/dhcp6sctlkey", "d3539eee2e668fc84c40b918ecfdd9ee"); 58 | md5_sums.put("/system/bin/dhcp6ctl", "f36d6f20813c2a70ad736b3e937cb1b3"); 59 | // md5_sums.put("/system/bin/dhcp6s", "fda776931320ef234911f1c8efe76637"); 60 | // md5_sums.put("/system/etc/wide-dhcpv6/dhcp6s.conf", "8901e99ab22f507bc89dffaed98aa45a"); 61 | md5_sums.put("dhcpv6_base.zip", "a8a0a946966474d238cd126202733a4a"); 62 | md5_sums.put("dhcpv6_update.zip", "0f49fa94d431e1766a367af9be23bfd3"); 63 | } 64 | 65 | private static String[] required_commands = { 66 | "cp", 67 | "rm", 68 | "chmod", 69 | "chown", 70 | "mkdir", 71 | "mount" 72 | }; 73 | 74 | public static String FullCheck() { 75 | String exists = "ok"; 76 | 77 | exists = CheckBase(); 78 | exists = CheckUpdate(); 79 | 80 | Log.d(TAG, "Check full result: " + exists); 81 | 82 | return exists; 83 | } 84 | 85 | public static String CheckBase() { 86 | String exists = "ok"; 87 | 88 | for(String file : required_files) { 89 | if(!check_md5(file)) { exists = "md5"; } 90 | } 91 | 92 | for(String file : required_files) { 93 | if(!check_file(file)) { exists = "exist"; } 94 | } 95 | 96 | Log.d(TAG, "Check base result: " + exists); 97 | 98 | return exists; 99 | } 100 | 101 | public static String CheckUpdate() { 102 | String exists = "ok"; 103 | 104 | for(String file : required_files_update) { 105 | if(!check_md5(file)) { exists = "md5"; } 106 | } 107 | 108 | for(String file : required_files_update) { 109 | if(!check_file(file)) { exists = "exist"; } 110 | } 111 | 112 | Log.d(TAG, "Check update result: " + exists); 113 | 114 | return exists; 115 | } 116 | 117 | public static boolean check_config_files(Context context) { 118 | boolean valid = true; 119 | 120 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(context); 121 | 122 | File file_c = new File(config_files[0]); 123 | File file_c_dns = new File(config_files[1]); 124 | 125 | if(file_c.exists() && file_c_dns.exists()) { 126 | if (!shared_preferences.getString(Constants.DHCP6C_CONF, "").equals(DHCPv6Integrity.calculateMD5(file_c)) || 127 | !shared_preferences.getString(Constants.DHCP6CDNS_CONF, "").equals(DHCPv6Integrity.calculateMD5(file_c_dns))) { 128 | valid = false; 129 | } 130 | }else{ 131 | valid= false; 132 | } 133 | 134 | 135 | return valid; 136 | } 137 | 138 | public static ArrayList check_commands() { 139 | ArrayList missing_commands = new ArrayList(); 140 | 141 | for(String command : required_commands) { 142 | File file = new File("/system/bin/" + command); 143 | 144 | if(!file.exists()) { 145 | missing_commands.add(command); 146 | } 147 | } 148 | 149 | return missing_commands; 150 | } 151 | 152 | public static void install_all(Context context, boolean download_files) { 153 | String tmp_dir = context.getCacheDir().toString(); 154 | 155 | if(!download_files) { 156 | Log.d(TAG, "INSTALLING: tmp_dir: " + tmp_dir); 157 | } 158 | 159 | SUCalls.mount_rw(); 160 | 161 | SUCalls.create_dir("/system/etc/wide-dhcpv6", "root", "shell", "755"); 162 | SUCalls.create_dir("/system/bin", "root", "shell", "755"); 163 | 164 | if(!download_files) { 165 | 166 | copy_resource(R.raw.dhcpv6_base, tmp_dir + "/dhcpv6_base.zip", context); 167 | 168 | Log.d(TAG, "INSTALLING: tmp_dir: dhcpv6_base.zip: " + Boolean.toString(check_file(tmp_dir + "/dhcpv6_base.zip"))); 169 | 170 | Decompress d = new Decompress(tmp_dir + "/dhcpv6_base.zip", tmp_dir + "/"); 171 | d.unzip(); 172 | 173 | Log.d(TAG, "INSTALLING: tmp_dir: dhcp_complete/system/bin/dhcp6c: " + Boolean.toString(check_file(tmp_dir + "/dhcp_complete/system/bin/dhcp6c"))); 174 | Log.d(TAG, "INSTALLING: tmp_dir: dhcp_complete/system/etc/wide-dhcpv6/dhcp6cctlkey: " + Boolean.toString(check_file(tmp_dir + "/dhcp_complete/system/etc/wide-dhcpv6/dhcp6cctlkey"))); 175 | 176 | Log.d(TAG, "INSTALLING: only checked 2 files (normal)"); 177 | 178 | for (String file : required_files) { 179 | SUCalls.copy_specific_file(tmp_dir + "/dhcp_complete" + file, file, "root", "shell", "755"); 180 | } 181 | 182 | SUCalls.delete_file(tmp_dir + "/dhcp_complete"); 183 | }else{ 184 | for (String file : required_files) { 185 | SUCalls.download_file(file); 186 | SUCalls.set_permissions(file, "755", "root", "shell"); 187 | } 188 | } 189 | install_update(context, download_files); 190 | 191 | if(!download_files) { 192 | SUCalls.delete_file(tmp_dir + "/dhcp_complete"); 193 | SUCalls.delete_file(tmp_dir + "/dhcpv6_base.zip"); 194 | SUCalls.delete_file(tmp_dir + "/dhcpv6_update.zip"); 195 | } 196 | 197 | SUCalls.mount_ro(); 198 | } 199 | 200 | public static void install_update(Context context, boolean download_files) { 201 | String tmp_dir = context.getCacheDir().toString(); 202 | 203 | if(!download_files) { 204 | Log.d(TAG, "INSTALLING: tmp_dir: " + tmp_dir); 205 | } 206 | 207 | SUCalls.mount_rw(); 208 | 209 | SUCalls.create_dir("/system/etc/wide-dhcpv6", "root", "shell", "755"); 210 | SUCalls.create_dir("/system/bin", "root", "shell", "755"); 211 | 212 | if(!download_files) { 213 | 214 | copy_resource(R.raw.dhcpv6_update, tmp_dir + "/dhcpv6_update.zip", context); 215 | 216 | Log.d(TAG, "INSTALLING: tmp_dir: dhcpv6_update.zip: " + Boolean.toString(check_file(tmp_dir + "/dhcpv6_update.zip"))); 217 | 218 | Decompress d = new Decompress(tmp_dir + "/dhcpv6_update.zip", tmp_dir + "/"); 219 | d.unzip(); 220 | 221 | Log.d(TAG, "INSTALLING: tmp_dir: dhcp_complete/system/bin/dhcp6ctl: " + Boolean.toString(check_file(tmp_dir + "/dhcp_complete/system/bin/dhcp6ctl"))); 222 | Log.d(TAG, "INSTALLING: tmp_dir: dhcp_complete/system/etc/wide-dhcpv6/dhcp6sctlkey: " + Boolean.toString(check_file(tmp_dir + "/dhcp_complete/system/etc/wide-dhcpv6/dhcp6sctlkey"))); 223 | 224 | Log.d(TAG, "INSTALLING: only checked 2 files (normal)"); 225 | 226 | for (String file : required_files_update) { 227 | SUCalls.copy_specific_file(tmp_dir + "/dhcp_complete" + file, file, "root", "shell", "755"); 228 | } 229 | 230 | SUCalls.delete_file(tmp_dir + "/dhcpv6_update.zip"); 231 | }else{ 232 | for (String file : required_files_update) { 233 | SUCalls.download_file(file); 234 | SUCalls.set_permissions(file, "755", "root", "shell"); 235 | } 236 | } 237 | 238 | SUCalls.mount_ro(); 239 | } 240 | 241 | public static void delete_client_conf() { 242 | SUCalls.remove_file("/system/etc/wide-dhcpv6/dhcp6c.conf"); 243 | SUCalls.remove_file("/system/etc/wide-dhcpv6/dhcp6cDNS.conf"); 244 | } 245 | 246 | public static String write_client_conf(String file, String content) { 247 | SUCalls.write_file(content, file); 248 | SUCalls.set_permissions(file, "755", "root", "shell"); 249 | return calculateMD5(new File(file)); 250 | } 251 | 252 | private static void copy_resource(int resource, String dest_dir, Context context) { 253 | try { 254 | InputStream in = context.getResources().openRawResource(resource); 255 | OutputStream out = new FileOutputStream(new File(dest_dir)); 256 | byte[] buffer = new byte[1024]; 257 | int len; 258 | while((len = in.read(buffer, 0, buffer.length)) != -1){ 259 | out.write(buffer, 0, len); 260 | } 261 | in.close(); 262 | out.close(); 263 | }catch (Exception e) { 264 | 265 | } 266 | } 267 | 268 | private static boolean check_md5(String file) { 269 | String md5_file = calculateMD5(new File(file)); 270 | 271 | if(md5_file == null) { 272 | return false; 273 | } 274 | 275 | if(!md5_file.equals(md5_sums.get(file))) { 276 | return false; 277 | }else{ 278 | return true; 279 | } 280 | } 281 | 282 | private static boolean check_file(String file) { 283 | File check_file = new File(file); 284 | return check_file.exists(); 285 | } 286 | 287 | public static String calculateMD5(File updateFile) { 288 | MessageDigest digest; 289 | try { 290 | digest = MessageDigest.getInstance("MD5"); 291 | } catch (NoSuchAlgorithmException e) { 292 | // Log.e(TAG, "Exception while getting digest", e); 293 | return null; 294 | } 295 | 296 | InputStream is; 297 | try { 298 | is = new FileInputStream(updateFile); 299 | } catch (FileNotFoundException e) { 300 | // Log.e(TAG, "Exception while getting FileInputStream", e); 301 | return null; 302 | } 303 | 304 | byte[] buffer = new byte[8192]; 305 | int read; 306 | try { 307 | while ((read = is.read(buffer)) > 0) { 308 | digest.update(buffer, 0, read); 309 | } 310 | byte[] md5sum = digest.digest(); 311 | BigInteger bigInt = new BigInteger(1, md5sum); 312 | String output = bigInt.toString(16); 313 | // Fill to 32 chars 314 | output = String.format("%32s", output).replace(' ', '0'); 315 | return output; 316 | } catch (IOException e) { 317 | Log.d(TAG, "MD5: Unable to process file for MD5: " + e.toString()); 318 | throw new RuntimeException("Unable to process file for MD5", e); 319 | } finally { 320 | try { 321 | is.close(); 322 | } catch (IOException e) { 323 | // Log.e(TAG, "Exception on closing MD5 input stream", e); 324 | } 325 | } 326 | } 327 | 328 | public static class Decompress { 329 | private String _zipFile; 330 | private String _location; 331 | 332 | public Decompress(String zipFile, String location) { 333 | _zipFile = zipFile; 334 | _location = location; 335 | 336 | _dirChecker(""); 337 | } 338 | 339 | public void unzip() { 340 | try { 341 | FileInputStream fin = new FileInputStream(_zipFile); 342 | ZipInputStream zin = new ZipInputStream(fin); 343 | ZipEntry ze = null; 344 | while ((ze = zin.getNextEntry()) != null) { 345 | 346 | if(ze.isDirectory()) { 347 | _dirChecker(ze.getName()); 348 | } else { 349 | FileOutputStream fout = new FileOutputStream(_location + ze.getName()); 350 | for (int c = zin.read(); c != -1; c = zin.read()) { 351 | fout.write(c); 352 | } 353 | 354 | zin.closeEntry(); 355 | fout.close(); 356 | } 357 | 358 | } 359 | zin.close(); 360 | } catch(Exception e) { 361 | // Log.e("EXCEPTION", "unzip", e); 362 | } 363 | 364 | } 365 | 366 | private void _dirChecker(String dir) { 367 | File f = new File(_location + dir); 368 | 369 | if(!f.isDirectory()) { 370 | f.mkdirs(); 371 | } 372 | } 373 | } 374 | } 375 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/DoStartup.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.app.Dialog; 6 | import android.app.ProgressDialog; 7 | import android.content.Context; 8 | import android.content.DialogInterface; 9 | import android.os.AsyncTask; 10 | import android.view.KeyEvent; 11 | 12 | import com.stericson.RootTools.RootTools; 13 | 14 | import java.util.ArrayList; 15 | 16 | import eu.chainfire.libsuperuser.Shell; 17 | 18 | /** 19 | * Created by Anastassios Martakos on 11.08.2015. 20 | */ 21 | public class DoStartup extends AsyncTask { 22 | ProgressDialog progDialog; 23 | Activity activity; 24 | MainActivity main_activity; 25 | private String result_status; 26 | 27 | public DoStartup(Activity activity_arg, MainActivity main_activity_arg) { 28 | activity = activity_arg; 29 | main_activity = main_activity_arg; 30 | progDialog = new ProgressDialog(activity_arg); 31 | } 32 | 33 | @Override 34 | protected void onPreExecute() { 35 | super.onPreExecute(); 36 | progDialog.setMessage("Requesting Root permissions ..."); 37 | progDialog.setIndeterminate(false); 38 | progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 39 | progDialog.setCancelable(false); 40 | progDialog.show(); 41 | } 42 | 43 | @Override 44 | protected String doInBackground(String... aurl) { 45 | result_status = check_permissions(); 46 | return null; 47 | } 48 | 49 | @Override 50 | protected void onPostExecute(String unused) { 51 | super.onPostExecute(unused); 52 | 53 | Dialog.OnKeyListener diaglog_key_listener = new Dialog.OnKeyListener() { 54 | @Override 55 | public boolean onKey(DialogInterface arg0, int key_code, KeyEvent event) { 56 | if(key_code == KeyEvent.KEYCODE_BACK) { 57 | activity.finish(); 58 | } 59 | 60 | return true; 61 | } 62 | }; 63 | 64 | MsgBoxes error_message = new MsgBoxes(); 65 | AlertDialog fail_root_dialog_obj = (AlertDialog) error_message.one_button(activity, activity.getString(R.string.no_root_title), activity.getString(R.string.no_root), false); 66 | AlertDialog fail_busybox_dialog_obj = (AlertDialog) error_message.one_button(activity, activity.getString(R.string.no_busybox_title), activity.getString(R.string.no_busybox), true); 67 | 68 | fail_root_dialog_obj.setOnKeyListener(diaglog_key_listener); 69 | fail_busybox_dialog_obj.setOnKeyListener(diaglog_key_listener); 70 | 71 | progDialog.dismiss(); 72 | 73 | if(result_status.equals("run")) { 74 | ArrayList missing_commands = DHCPv6Integrity.check_commands(); 75 | 76 | if(missing_commands.size() > 0) { 77 | String missing_commands_string = new String(); 78 | 79 | for(String commands : missing_commands) { 80 | missing_commands_string = missing_commands_string + commands + " "; 81 | } 82 | 83 | AlertDialog fail_commands_dialog_obj = (AlertDialog) error_message.one_button(activity, activity.getString(R.string.missing_commands_title), activity.getString(R.string.missing_commands) + missing_commands_string, true); 84 | 85 | fail_commands_dialog_obj.setOnKeyListener(diaglog_key_listener); 86 | 87 | fail_commands_dialog_obj.show(); 88 | }else{ 89 | main_activity.post_startup(true); 90 | } 91 | }else if(result_status.equals("busybox")) { 92 | fail_busybox_dialog_obj.show(); 93 | }else if(result_status.equals("root")) { 94 | fail_root_dialog_obj.show(); 95 | main_activity.post_startup(false); 96 | } 97 | 98 | } 99 | 100 | private String check_permissions() { 101 | if (Shell.SU.available()) { 102 | if (RootTools.isBusyboxAvailable()) { 103 | return "run"; 104 | }else{ 105 | return "busybox"; 106 | } 107 | }else{ 108 | return "root"; 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/DonationFragment.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.content.SharedPreferences; 4 | import android.os.Bundle; 5 | import android.preference.Preference; 6 | import android.preference.PreferenceFragment; 7 | 8 | /** 9 | * Created by Anastassios Martakos on 8/7/15. 10 | */ 11 | public class DonationFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { 12 | Preference donate_001; 13 | Preference donate_005; 14 | Preference donate_010; 15 | 16 | @Override 17 | public void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | addPreferencesFromResource(R.xml.donate); 20 | 21 | donate_001 = (Preference) findPreference("pref_button_donate_amount_1"); 22 | 23 | donate_001.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 24 | @Override 25 | public boolean onPreferenceClick(Preference preference) { 26 | ((MainActivity)getActivity()).purchase_item(Constants.DONATION_001); 27 | return true; 28 | } 29 | }); 30 | 31 | donate_005 = (Preference) findPreference("pref_button_donate_amount_5"); 32 | donate_005.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 33 | @Override 34 | public boolean onPreferenceClick(Preference preference) { 35 | ((MainActivity)getActivity()).purchase_item(Constants.DONATION_005); 36 | return true; 37 | } 38 | }); 39 | 40 | donate_010 = (Preference) findPreference("pref_button_donate_amount_10"); 41 | donate_010.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 42 | @Override 43 | public boolean onPreferenceClick(Preference preference) { 44 | ((MainActivity) getActivity()).purchase_item(Constants.DONATION_010); 45 | return true; 46 | } 47 | }); 48 | 49 | findPreference("pref_button_donate_amount_1").setTitle(findPreference("pref_button_donate_amount_1").getTitle() + " " + MainActivity.donation_001_price); 50 | findPreference("pref_button_donate_amount_5").setTitle(findPreference("pref_button_donate_amount_5").getTitle() + " " + MainActivity.donation_005_price); 51 | findPreference("pref_button_donate_amount_10").setTitle(findPreference("pref_button_donate_amount_10").getTitle() + " " + MainActivity.donation_010_price); 52 | } 53 | 54 | @Override 55 | public void onResume() { 56 | super.onResume(); 57 | } 58 | 59 | @Override 60 | public void onPause() { 61 | super.onPause(); 62 | } 63 | 64 | @Override 65 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/GenerateClientConfig.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.app.ProgressDialog; 6 | import android.content.Context; 7 | import android.content.SharedPreferences; 8 | import android.os.AsyncTask; 9 | import android.preference.PreferenceManager; 10 | 11 | import java.util.ArrayList; 12 | 13 | /** 14 | * Created by Anastassios Martakos on 8/17/15. 15 | */ 16 | public class GenerateClientConfig extends AsyncTask { 17 | private ArrayList> interfaces = new ArrayList>(); 18 | private String final_config_c = ""; 19 | private String final_config_c_dns = ""; 20 | 21 | private Activity activity; 22 | 23 | private String config_template_c = 24 | "interface {\\n" + 25 | "send ia-na ;\\n" + 26 | "request domain-name-servers;\\n" + 27 | "request domain-name;\\n" + 28 | "script \\\"/etc/wide-dhcpv6/dhcp6c.script\\\";\\n" + 29 | "};\\n\\n" + 30 | 31 | "id-assoc na {\\n" + 32 | "};\\n\\n"; 33 | 34 | private String config_template_c_dns = 35 | "interface {\\n" + 36 | "request domain-name-servers;\\n" + 37 | "request domain-name;\\n" + 38 | "information-only;\\n" + 39 | "script \\\"/etc/wide-dhcpv6/dhcp6c.script\\\";\\n" + 40 | "};\\n\\n"; 41 | 42 | ProgressDialog progDialog; 43 | 44 | public GenerateClientConfig(Activity activity) { 45 | this.activity = activity; 46 | progDialog = new ProgressDialog(activity); 47 | } 48 | 49 | @Override 50 | protected void onPreExecute() { 51 | super.onPreExecute(); 52 | progDialog.setMessage("Generating Configuration ..."); 53 | progDialog.setIndeterminate(false); 54 | progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 55 | progDialog.setCancelable(false); 56 | progDialog.show(); 57 | } 58 | @Override 59 | protected String doInBackground(String... aurl) { 60 | generate_client_config(); 61 | return null; 62 | } 63 | @Override 64 | protected void onPostExecute(String unused) { 65 | super.onPostExecute(unused); 66 | MsgBoxes msg_box = new MsgBoxes(); 67 | 68 | String full_check_result = DHCPv6Integrity.FullCheck(); 69 | 70 | if(!full_check_result.equals("ok")) { 71 | if (full_check_result.equals("md5")) { 72 | AlertDialog error = (AlertDialog) msg_box.one_button(activity, "Error", activity.getString(R.string.check_md5), false); 73 | error.show(); 74 | } else if (full_check_result.equals("exist")) { 75 | AlertDialog error = (AlertDialog) msg_box.one_button(activity, "Error", activity.getString(R.string.check_exist), false); 76 | error.show(); 77 | } else { 78 | AlertDialog error = (AlertDialog) msg_box.one_button(activity, "Error", activity.getString(R.string.check_unexpected), false); 79 | error.show(); 80 | } 81 | } 82 | 83 | progDialog.dismiss(); 84 | } 85 | 86 | private void generate_client_config() { 87 | ArrayList all_configured_interfaces_base = Misc.get_all_configured_interfaces(activity); 88 | ArrayList> all_configured_interfaces_final = new ArrayList>(); 89 | 90 | ArrayList used_ianas = new ArrayList(); 91 | 92 | for(final String conf_interface : all_configured_interfaces_base) { 93 | boolean valid_iana = false; 94 | String tmp_iana = ""; 95 | 96 | while(!valid_iana) { 97 | tmp_iana = 98 | Integer.toString(Misc.get_random_small()) + 99 | Integer.toString(Misc.get_random_small()) + 100 | Integer.toString(Misc.get_random_small()) + 101 | Integer.toString(Misc.get_random_small()) + 102 | Integer.toString(Misc.get_random_small()) + 103 | Integer.toString(Misc.get_random_small()) + 104 | Integer.toString(Misc.get_random_small()) + 105 | Integer.toString(Misc.get_random_small()) + 106 | Integer.toString(Misc.get_random_small()); 107 | 108 | boolean used = false; 109 | 110 | for(String used_iana : used_ianas) { 111 | if(used_iana.equals(tmp_iana)) { 112 | used_ianas.add(tmp_iana); 113 | used = true; 114 | } 115 | } 116 | 117 | if(!used) { 118 | valid_iana = true; 119 | } 120 | } 121 | 122 | final String iana = tmp_iana; 123 | 124 | all_configured_interfaces_final.add(new ArrayList() {{ 125 | add(conf_interface); 126 | add(iana); 127 | }}); 128 | } 129 | 130 | interfaces = all_configured_interfaces_final; 131 | 132 | generate_config(); 133 | apply_config(); 134 | } 135 | 136 | 137 | public void add_interface(ArrayList inter_face) { 138 | interfaces.add(inter_face); 139 | } 140 | 141 | public void generate_config() { 142 | for(int i = 0; i < interfaces.size(); i++) { 143 | String current_config_c = config_template_c; 144 | String current_config_c_dns = config_template_c_dns; 145 | 146 | current_config_c = current_config_c.replaceAll("", interfaces.get(i).get(0)); 147 | current_config_c = current_config_c.replaceAll("", interfaces.get(i).get(1)); 148 | current_config_c_dns = current_config_c_dns.replaceAll("", interfaces.get(i).get(0)); 149 | 150 | final_config_c += current_config_c; 151 | final_config_c_dns += current_config_c_dns; 152 | } 153 | } 154 | 155 | public void apply_config() { 156 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(activity); 157 | SharedPreferences.Editor editor = shared_preferences.edit(); 158 | 159 | if(!shared_preferences.contains(Constants.DHCP6C_CONF)) { editor.putString(Constants.DHCP6C_CONF, "null"); } 160 | if(!shared_preferences.contains(Constants.DHCP6CDNS_CONF)) { editor.putString(Constants.DHCP6CDNS_CONF, "null"); } 161 | 162 | DHCPv6Integrity.delete_client_conf(); 163 | 164 | SUCalls.mount_rw(); 165 | String md5_c = DHCPv6Integrity.write_client_conf("/system/etc/wide-dhcpv6/dhcp6c.conf", final_config_c); 166 | String md5_c_dns = DHCPv6Integrity.write_client_conf("/system/etc/wide-dhcpv6/dhcp6cDNS.conf", final_config_c_dns); 167 | SUCalls.mount_ro(); 168 | 169 | editor.putString(Constants.DHCP6C_CONF, md5_c); 170 | editor.putString(Constants.DHCP6CDNS_CONF, md5_c_dns); 171 | editor.commit(); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/GetIPv6Address.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.NotificationManager; 4 | import android.app.PendingIntent; 5 | import android.app.TaskStackBuilder; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | import android.content.SharedPreferences; 9 | import android.net.ConnectivityManager; 10 | import android.net.NetworkInfo; 11 | import android.net.wifi.WifiInfo; 12 | import android.net.wifi.WifiManager; 13 | import android.os.AsyncTask; 14 | import android.preference.PreferenceManager; 15 | import android.support.v4.app.NotificationCompat; 16 | import android.widget.Toast; 17 | 18 | import java.util.HashSet; 19 | import java.util.Set; 20 | 21 | /** 22 | * Created by Anastassios Martakos on 8/3/15. 23 | */ 24 | public class GetIPv6Address extends AsyncTask { 25 | private boolean result_status; 26 | private String inter_face; 27 | public GetIPv6Address(String inter_face_arg) { 28 | inter_face = inter_face_arg; 29 | } 30 | 31 | @Override 32 | protected void onPreExecute() { 33 | super.onPreExecute(); 34 | } 35 | @Override 36 | protected String doInBackground(String... aurl) { 37 | 38 | // as per rfc3315 the DUID should be presistent 39 | // SUCalls.remove_file("/data/misc/dhcp/dhcp6c_duid"); 40 | 41 | SUCalls.force_dhcpv6(inter_face); 42 | return null; 43 | 44 | /*if(!SUCalls.check_process("dhcp6c")) { 45 | SUCalls.start_dhpv6c_process(inter_face); 46 | return null; 47 | }else { 48 | SUCalls.send_signal_to_client_process(inter_face); 49 | return null; 50 | }*/ 51 | } 52 | @Override 53 | protected void onPostExecute(String unused) { 54 | super.onPostExecute(unused); 55 | Misc.send_ui_request_refresh_ips(); 56 | } 57 | 58 | public static boolean PreGetIPv6Address(Context context, boolean do_all) { 59 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(context); 60 | 61 | Misc.send_ui_request_refresh_ips(); 62 | 63 | if(!shared_preferences.getBoolean(Constants.PREF_ENABLE, false) || !shared_preferences.getBoolean(Constants.IS_INSTALLED, false)) { return do_all; } 64 | 65 | SharedPreferences.Editor editor = shared_preferences.edit(); 66 | 67 | if(!shared_preferences.getBoolean(Constants.IS_INSTALLED_UPDATE, false)) { 68 | if(DHCPv6Integrity.CheckUpdate().equals("ok")) { 69 | editor.putBoolean(Constants.IS_INSTALLED_UPDATE, true); 70 | editor.commit(); 71 | }else{ 72 | editor.putBoolean(Constants.IS_INSTALLED_UPDATE, false); 73 | editor.commit(); 74 | 75 | show_update_notification(context); 76 | } 77 | } 78 | 79 | ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 80 | NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); 81 | 82 | WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 83 | WifiInfo info = wifiManager.getConnectionInfo(); 84 | 85 | String ssid = info.getBSSID(); 86 | 87 | if (activeNetwork != null) { 88 | if(!shared_preferences.contains(Constants.LAST_STATE)) { 89 | editor.putInt(Constants.LAST_STATE, -200); 90 | editor.commit(); 91 | } 92 | 93 | if(!shared_preferences.contains(Constants.LAST_SSID)) { 94 | editor.putString(Constants.LAST_SSID, "randomlastssiddummy"); 95 | editor.commit(); 96 | } 97 | 98 | int last_state = shared_preferences.getInt(Constants.LAST_STATE, -200); 99 | String last_ssid = shared_preferences.getString(Constants.LAST_SSID, "randomlastssiddummy"); 100 | 101 | switch(activeNetwork.getType()) { 102 | case ConnectivityManager.TYPE_WIFI: 103 | if(last_state == ConnectivityManager.TYPE_WIFI && last_ssid.equals(ssid)) return do_all; 104 | editor.putString(Constants.LAST_SSID, ssid); 105 | editor.putInt(Constants.LAST_STATE, ConnectivityManager.TYPE_WIFI); 106 | editor.commit(); 107 | if(!shared_preferences.getBoolean(Constants.PREF_WLAN, false) && !shared_preferences.getBoolean("pref_all", false)) return do_all; 108 | 109 | do_all = prepare_dhcpv6(context, "wlan0", do_all); 110 | break; 111 | case ConnectivityManager.TYPE_MOBILE: 112 | if(last_state == ConnectivityManager.TYPE_MOBILE) return do_all; 113 | editor.putInt(Constants.LAST_STATE, ConnectivityManager.TYPE_MOBILE); 114 | editor.commit(); 115 | // if(!shared_preferences.getBoolean(Constants.PREF_MOBILE, false) && !shared_preferences.getBoolean("pref_all", false)) return do_all; 116 | 117 | // do_all = prepare_dhcpv6(context, "rmnet0", do_all); 118 | break; 119 | default: 120 | editor.putInt(Constants.LAST_STATE, -200); 121 | editor.putString(Constants.LAST_SSID, "randomlastssiddummy"); 122 | editor.commit(); 123 | if(shared_preferences.getBoolean(Constants.PREF_DEBUG, false)) { 124 | Toast.makeText(context, "NOW DISCONNECTED", Toast.LENGTH_SHORT).show(); 125 | } 126 | break; 127 | } 128 | 129 | if(do_all) { 130 | do_all = false; 131 | }else { 132 | for (String inter_face : get_custom_interfaces(context)) { 133 | do_dhcpv6_on_custom_interface(context, inter_face); 134 | } 135 | } 136 | 137 | }else{ 138 | editor.putInt(Constants.LAST_STATE, -200); 139 | editor.putString(Constants.LAST_SSID, "randomlastssiddummy"); 140 | editor.commit(); 141 | if(shared_preferences.getBoolean(Constants.PREF_DEBUG, false)) { 142 | Toast.makeText(context, "NOW DISCONNECTED", Toast.LENGTH_SHORT).show(); 143 | } 144 | } 145 | 146 | return do_all; 147 | } 148 | 149 | private static Set get_custom_interfaces(Context context) { 150 | Set custom_interfaces = new HashSet(PreferenceManager.getDefaultSharedPreferences(context).getStringSet(Constants.ADDITIONAL_INTERFACES, new HashSet())); 151 | return custom_interfaces; 152 | } 153 | 154 | private static void do_dhcpv6_on_custom_interface(Context context, String inter_face) { 155 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(context); 156 | if(shared_preferences.getBoolean(Constants.PREF_DEBUG, false)) { 157 | Toast.makeText(context, "DOING OPERATIONS ON: " + inter_face, Toast.LENGTH_SHORT).show(); 158 | } 159 | new GetIPv6Address(inter_face).execute(); 160 | } 161 | 162 | private static boolean prepare_dhcpv6(Context context, String inter_face, boolean do_all) { 163 | if(PreferenceManager.getDefaultSharedPreferences(context).getBoolean(Constants.PREF_ALL, false)) { 164 | for(String in : Misc.get_all_interfaces()) { 165 | do_dhcpv6_on_custom_interface(context, in); 166 | } 167 | do_all = true; 168 | }else{ 169 | do_dhcpv6_on_custom_interface(context, inter_face); 170 | } 171 | 172 | return do_all; 173 | } 174 | 175 | private static void show_update_notification(Context context) { 176 | NotificationCompat.Builder mBuilder = 177 | new NotificationCompat.Builder(context) 178 | .setSmallIcon(R.mipmap.app_icon) 179 | .setContentTitle(context.getString(R.string.update_notification_title)) 180 | .setContentText(context.getString(R.string.update_notification)); 181 | 182 | Intent resultIntent = new Intent(context, MainActivity.class); 183 | 184 | TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); 185 | 186 | stackBuilder.addParentStack(MainActivity.class); 187 | 188 | stackBuilder.addNextIntent(resultIntent); 189 | PendingIntent resultPendingIntent = 190 | stackBuilder.getPendingIntent( 191 | 0, 192 | PendingIntent.FLAG_UPDATE_CURRENT 193 | ); 194 | mBuilder.setContentIntent(resultPendingIntent); 195 | mBuilder.setAutoCancel(true); 196 | NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 197 | 198 | int mId = 0; 199 | 200 | mNotificationManager.notify(mId, mBuilder.build()); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/InstallDHCPv6Client.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.app.ProgressDialog; 6 | import android.content.Context; 7 | import android.content.SharedPreferences; 8 | import android.os.AsyncTask; 9 | import android.preference.PreferenceManager; 10 | import android.util.Log; 11 | 12 | /** 13 | * Created by Anastassios Martakos on 7/31/15. 14 | */ 15 | public class InstallDHCPv6Client extends AsyncTask { 16 | ProgressDialog progDialog; 17 | Activity activity; 18 | private boolean result_status; 19 | private boolean full_installation; 20 | private boolean download_files; 21 | 22 | public InstallDHCPv6Client(Activity activity_arg, boolean full_installation, boolean download_files) { 23 | activity = activity_arg; 24 | this.full_installation = full_installation; 25 | progDialog = new ProgressDialog(activity_arg); 26 | this.download_files = download_files; 27 | } 28 | 29 | @Override 30 | protected void onPreExecute() { 31 | super.onPreExecute(); 32 | progDialog.setMessage("Installing ..."); 33 | progDialog.setIndeterminate(false); 34 | progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 35 | progDialog.setCancelable(false); 36 | progDialog.show(); 37 | } 38 | @Override 39 | protected String doInBackground(String... aurl) { 40 | result_status = install_dhcpv6(); 41 | return null; 42 | } 43 | @Override 44 | protected void onPostExecute(String unused) { 45 | super.onPostExecute(unused); 46 | MsgBoxes msg_box = new MsgBoxes(); 47 | if(result_status) { 48 | String full_check_result = DHCPv6Integrity.FullCheck(); 49 | 50 | if(full_check_result.equals("ok")) { 51 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(activity); 52 | SharedPreferences.Editor editor = shared_preferences.edit(); 53 | 54 | editor.putBoolean("is_installed", true); 55 | editor.putBoolean("is_installed_update", true); 56 | editor.commit(); 57 | 58 | MainActivity.option_menu_main.findItem(R.id.action_unorinstall).setTitle(R.string.action_uninstall); 59 | MainActivity.option_menu_main.findItem(R.id.action_invoke).setEnabled(true); 60 | MainActivity.option_menu_main.findItem(R.id.action_unorinstall).setIcon(R.mipmap.ic_uninstall); 61 | 62 | new GenerateClientConfig(activity).execute(); 63 | 64 | AlertDialog success; 65 | 66 | if(full_installation) { 67 | success = (AlertDialog) msg_box.one_button(activity, "Success", activity.getString(R.string.success_install), false); 68 | }else{ 69 | success = (AlertDialog) msg_box.one_button(activity, "Success", activity.getString(R.string.success_update), false); 70 | } 71 | success.show(); 72 | }else{ 73 | Log.v("EXCEPTION", full_check_result); 74 | AlertDialog failed; 75 | if(full_check_result.equals("md5")) { 76 | if (download_files) { 77 | failed = (AlertDialog) msg_box.one_button(activity, "Failed", activity.getString(R.string.check_md5), false); 78 | failed.show(); 79 | }else{ 80 | Misc.question_download_files(activity, activity.getString(R.string.check_md5), full_installation); 81 | } 82 | }else if(full_check_result.equals("exist")) { 83 | if (download_files) { 84 | failed = (AlertDialog) msg_box.one_button(activity, "Failed", activity.getString(R.string.check_copy), false); 85 | failed.show(); 86 | }else { 87 | Misc.question_download_files(activity, activity.getString(R.string.check_copy), full_installation); 88 | } 89 | }else{ 90 | if (download_files) { 91 | failed = (AlertDialog) msg_box.one_button(activity, "Failed", activity.getString(R.string.check_unexpected), false); 92 | failed.show(); 93 | }else { 94 | Misc.question_download_files(activity, activity.getString(R.string.check_unexpected), full_installation); 95 | } 96 | } 97 | } 98 | }else{ 99 | AlertDialog failed; 100 | if (download_files) { 101 | failed = (AlertDialog) msg_box.one_button(activity, "Failed", activity.getString(R.string.check_other), false); 102 | failed.show(); 103 | }else { 104 | Misc.question_download_files(activity, activity.getString(R.string.check_other), full_installation); 105 | } 106 | } 107 | progDialog.dismiss(); 108 | } 109 | 110 | public boolean install_dhcpv6() { 111 | try { 112 | if(full_installation) { 113 | DHCPv6Integrity.install_all(activity, download_files); 114 | return true; 115 | }else{ 116 | DHCPv6Integrity.install_update(activity, download_files); 117 | return true; 118 | } 119 | }catch (Exception e) { 120 | Log.v("EXCEPTION", e.toString()); 121 | return false; 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/IpCollector.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | /** 4 | * Created by Anastassios Martakos on 8/12/15. 5 | */ 6 | public class IpCollector { 7 | private String ip; 8 | 9 | public IpCollector(String ip) { 10 | this.ip = ip; 11 | } 12 | 13 | public String getIp() { 14 | return ip; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/MainFragment.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Fragment; 4 | import android.content.BroadcastReceiver; 5 | import android.content.ClipData; 6 | import android.content.ClipboardManager; 7 | import android.content.Context; 8 | import android.content.Intent; 9 | import android.content.IntentFilter; 10 | import android.os.Bundle; 11 | import android.support.v4.content.LocalBroadcastManager; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.widget.AdapterView; 16 | import android.widget.Button; 17 | import android.widget.ListView; 18 | import android.widget.Toast; 19 | 20 | import java.util.ArrayList; 21 | 22 | /** 23 | * Created by Anastassios Martakos on 8/24/15. 24 | */ 25 | public class MainFragment extends Fragment { 26 | private BroadcastReceiver resultReceiver; 27 | 28 | @Override 29 | public void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | resultReceiver = createBroadcastReceiver(); 32 | LocalBroadcastManager.getInstance(getActivity()).registerReceiver(resultReceiver, new IntentFilter("org.daduke.realmar.dhcpv6client")); 33 | } 34 | 35 | @Override 36 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 37 | View view = inflater.inflate(R.layout.main_fragment, container, false); 38 | 39 | Button refresh_button = (Button) view.findViewById(R.id.button_refresh); 40 | refresh_button.setOnClickListener(new View.OnClickListener() { 41 | @Override 42 | public void onClick(View view) { 43 | get_ip_addresses(); 44 | } 45 | }); 46 | 47 | get_ip_addresses(); 48 | 49 | return view; 50 | } 51 | 52 | @Override 53 | public void onResume() { 54 | super.onResume(); 55 | get_ip_addresses(); 56 | } 57 | 58 | @Override 59 | public void onDestroy() { 60 | super.onDestroy(); 61 | if (resultReceiver != null) { 62 | LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(resultReceiver); 63 | } 64 | } 65 | 66 | private BroadcastReceiver createBroadcastReceiver() { 67 | return new BroadcastReceiver() { 68 | @Override 69 | public void onReceive(Context context, Intent intent) { 70 | if(intent.getStringExtra("refresh_ips").equals("refresh_ips")) { 71 | get_ip_addresses(); 72 | } 73 | } 74 | }; 75 | } 76 | 77 | public void get_ip_addresses() { 78 | ArrayList[] ips = Misc.get_ips(); 79 | 80 | View v = getView(); 81 | if(v == null) 82 | return; 83 | 84 | final ListView list_view = (ListView)v.findViewById(R.id.ip_addresses); 85 | 86 | ArrayList ip_collection = new ArrayList<>(); 87 | 88 | ip_collection.add("IPv4 Addresses"); 89 | 90 | for(Object ip : ips[0]) { 91 | ip_collection.add(new IpCollector(ip.toString())); 92 | } 93 | 94 | ip_collection.add("IPv6 Addresses"); 95 | 96 | for(Object ip : ips[1]) { 97 | ip_collection.add(new IpCollector(ip.toString())); 98 | } 99 | 100 | list_view.setAdapter(new CustomListViewAdpater(getActivity(), ip_collection)); 101 | 102 | list_view.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 103 | @Override 104 | public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { 105 | IpCollector ip_address = (IpCollector) ((ListView) getView().findViewById(R.id.ip_addresses)).getItemAtPosition(position); 106 | 107 | ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(getActivity().CLIPBOARD_SERVICE); 108 | ClipData clip = ClipData.newPlainText("ip_address", ip_address.getIp()); 109 | clipboard.setPrimaryClip(clip); 110 | 111 | Toast.makeText(getActivity(), getString(R.string.ip_to_clipboard), Toast.LENGTH_LONG).show(); 112 | return false; 113 | } 114 | }); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/Misc.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.Context; 6 | import android.content.DialogInterface; 7 | import android.content.Intent; 8 | import android.content.SharedPreferences; 9 | import android.net.ConnectivityManager; 10 | import android.net.NetworkInfo; 11 | import android.preference.PreferenceManager; 12 | import android.support.v4.content.LocalBroadcastManager; 13 | import android.support.v7.app.ActionBarActivity; 14 | 15 | import java.net.Inet4Address; 16 | import java.net.InetAddress; 17 | import java.net.NetworkInterface; 18 | import java.util.ArrayList; 19 | import java.util.Collections; 20 | import java.util.Enumeration; 21 | import java.util.HashSet; 22 | import java.util.Random; 23 | import java.util.Set; 24 | 25 | /** 26 | * Created by Anastassios Martakos on 7/31/15. 27 | */ 28 | public class Misc extends ActionBarActivity { 29 | 30 | 31 | public static ArrayList[] get_ips() { 32 | ArrayList ipv4s = new ArrayList(); 33 | ArrayList ipv6s = new ArrayList(); 34 | 35 | try { 36 | for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { 37 | NetworkInterface intf = en.nextElement(); 38 | for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { 39 | InetAddress inetAddress = enumIpAddr.nextElement(); 40 | 41 | if (!inetAddress.isLoopbackAddress()) { 42 | (inetAddress instanceof Inet4Address ? ipv4s : ipv6s).add(inetAddress.getHostAddress()); 43 | } 44 | } 45 | } 46 | } 47 | catch(Exception e) { 48 | } 49 | 50 | return new ArrayList[] {ipv4s, ipv6s}; 51 | } 52 | 53 | public static int get_random_positive_int() { 54 | Random random = new Random(); 55 | return Math.abs(random.nextInt()) % 65535; 56 | } 57 | 58 | public static int get_random_small() { 59 | Random random = new Random(); 60 | return Math.abs(random.nextInt((9 - 1) + 1) + 1); 61 | } 62 | 63 | public static ArrayList get_all_interfaces() { 64 | ArrayList interfaces = new ArrayList(); 65 | 66 | try { 67 | Enumeration nets = NetworkInterface.getNetworkInterfaces(); 68 | for (NetworkInterface netint : Collections.list(nets)) { 69 | if (netint.isUp()) interfaces.add(netint.getName()); 70 | } 71 | } 72 | catch(Exception e) { 73 | } 74 | 75 | return interfaces; 76 | } 77 | 78 | public static void send_ui_request_refresh_ips() { 79 | if(MainActivity.main_context != null) { 80 | Intent intent = new Intent("org.daduke.realmar.dhcpv6client"); 81 | intent.putExtra("refresh_ips", "refresh_ips"); 82 | LocalBroadcastManager.getInstance(MainActivity.main_context).sendBroadcast(intent); 83 | } 84 | } 85 | 86 | public static void question_installation_update(final Activity activity) { 87 | AlertDialog alertDialog = new AlertDialog.Builder(activity).create(); 88 | alertDialog.setTitle(activity.getString(R.string.update_title)); 89 | alertDialog.setMessage(activity.getString(R.string.update_text)); 90 | alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", 91 | new DialogInterface.OnClickListener() { 92 | public void onClick(DialogInterface dialog, int which) { 93 | if(SystemIntegrity.update_check()) { 94 | new InstallDHCPv6Client(activity, false, false).execute(); 95 | }else{ 96 | MsgBoxes msg_box = new MsgBoxes(); 97 | AlertDialog no_disk_space = (AlertDialog) msg_box.one_button(activity, "Failure", activity.getString(R.string.not_enough_space), false); 98 | no_disk_space.show(); 99 | } 100 | dialog.dismiss(); 101 | } 102 | }); 103 | alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "No", 104 | new DialogInterface.OnClickListener() { 105 | public void onClick(DialogInterface dialog, int which) { 106 | dialog.dismiss(); 107 | } 108 | }); 109 | alertDialog.show(); 110 | } 111 | 112 | public static void question_installation(final Activity activity) { 113 | AlertDialog alertDialog = new AlertDialog.Builder(activity).create(); 114 | alertDialog.setTitle("Install"); 115 | alertDialog.setMessage(activity.getString(R.string.install_text)); 116 | alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", 117 | new DialogInterface.OnClickListener() { 118 | public void onClick(DialogInterface dialog, int which) { 119 | if(SystemIntegrity.full_check()) { 120 | new InstallDHCPv6Client(activity, true, false).execute(); 121 | }else{ 122 | MsgBoxes msg_box = new MsgBoxes(); 123 | AlertDialog no_disk_space = (AlertDialog) msg_box.one_button(activity, "Failure", activity.getString(R.string.not_enough_space), false); 124 | no_disk_space.show(); 125 | } 126 | dialog.dismiss(); 127 | } 128 | }); 129 | alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "No", 130 | new DialogInterface.OnClickListener() { 131 | public void onClick(DialogInterface dialog, int which) { 132 | dialog.dismiss(); 133 | } 134 | }); 135 | alertDialog.show(); 136 | } 137 | 138 | public static void question_uninstallation(final Activity activity) { 139 | AlertDialog alertDialog = new AlertDialog.Builder(activity).create(); 140 | alertDialog.setTitle("Uninstall"); 141 | alertDialog.setMessage(activity.getString(R.string.uninstall_text)); 142 | alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", 143 | new DialogInterface.OnClickListener() { 144 | public void onClick(DialogInterface dialog, int which) { 145 | new UninstallDHCPv6Client(activity).execute(); 146 | dialog.dismiss(); 147 | } 148 | }); 149 | alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "No", 150 | new DialogInterface.OnClickListener() { 151 | public void onClick(DialogInterface dialog, int which) { 152 | dialog.dismiss(); 153 | } 154 | }); 155 | alertDialog.show(); 156 | } 157 | 158 | public static void question_download_files(final Activity activity, String text, final boolean full_installation) { 159 | AlertDialog alertDialog = new AlertDialog.Builder(activity).create(); 160 | alertDialog.setTitle("Retry?"); 161 | alertDialog.setMessage(text + activity.getString(R.string.download_append_text)); 162 | alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", 163 | new DialogInterface.OnClickListener() { 164 | public void onClick(DialogInterface dialog, int which) { 165 | if(is_internet_availble(activity)) { 166 | new InstallDHCPv6Client(activity, full_installation, true).execute(); 167 | }else{ 168 | MsgBoxes msg_box = new MsgBoxes(); 169 | AlertDialog no_internet = (AlertDialog) msg_box.one_button(activity, "Failure", activity.getString(R.string.failure_no_internet_connection), false); 170 | no_internet.show(); 171 | } 172 | dialog.dismiss(); 173 | } 174 | }); 175 | alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "No", 176 | new DialogInterface.OnClickListener() { 177 | public void onClick(DialogInterface dialog, int which) { 178 | dialog.dismiss(); 179 | } 180 | }); 181 | alertDialog.show(); 182 | } 183 | 184 | public static void unsupported_arch(final Activity activity, String text) { 185 | AlertDialog alertDialog = new AlertDialog.Builder(activity).create(); 186 | alertDialog.setTitle("Unsupported Architecture"); 187 | alertDialog.setMessage(text); 188 | alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Ok", 189 | new DialogInterface.OnClickListener() { 190 | public void onClick(DialogInterface dialog, int which) { 191 | dialog.dismiss(); 192 | } 193 | }); 194 | alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Do not show again", 195 | new DialogInterface.OnClickListener() { 196 | public void onClick(DialogInterface dialog, int which) { 197 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(activity); 198 | SharedPreferences.Editor editor = shared_preferences.edit(); 199 | 200 | editor.putBoolean(Constants.SHOW_ARCH_WARNING, false); 201 | 202 | editor.commit(); 203 | 204 | dialog.dismiss(); 205 | } 206 | }); 207 | alertDialog.show(); 208 | } 209 | 210 | public static ArrayList get_all_configured_interfaces(Context context) { 211 | ArrayList configured_interfaces = new ArrayList(); 212 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(context); 213 | 214 | if(shared_preferences.getBoolean("pref_all", false)) { 215 | for (String inter_face : Misc.get_all_interfaces()) { 216 | configured_interfaces.add(inter_face); 217 | } 218 | }else { 219 | if (shared_preferences.getBoolean(Constants.PREF_WLAN, false)) { 220 | configured_interfaces.add("wlan0"); 221 | } 222 | 223 | Set additional_interfaces = shared_preferences.getStringSet(Constants.ADDITIONAL_INTERFACES, new HashSet()); 224 | 225 | for (String inter_face : additional_interfaces) { 226 | configured_interfaces.add(inter_face); 227 | } 228 | } 229 | 230 | return configured_interfaces; 231 | } 232 | 233 | public static int getStatusBarHeight(Context context) { 234 | int result = 0; 235 | int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); 236 | if (resourceId > 0) { 237 | result = context.getResources().getDimensionPixelSize(resourceId); 238 | } 239 | return result; 240 | } 241 | 242 | public static boolean is_internet_availble(Context context) { 243 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 244 | NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 245 | return activeNetworkInfo != null && activeNetworkInfo.isConnected(); 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/MsgBoxes.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.app.Dialog; 6 | import android.content.Context; 7 | import android.content.DialogInterface; 8 | 9 | /** 10 | * Created by Anastassios Martakos on 7/29/15. 11 | */ 12 | public class MsgBoxes { 13 | public Dialog one_button(final Activity activity, String title, String text, final boolean exit_app) { 14 | AlertDialog alertDialog = new AlertDialog.Builder(activity).create(); 15 | alertDialog.setTitle(title); 16 | alertDialog.setMessage(text); 17 | alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Ok", 18 | new DialogInterface.OnClickListener() { 19 | public void onClick(DialogInterface dialog, int which) { 20 | dialog.dismiss(); 21 | if(exit_app) activity.finish(); 22 | } 23 | }); 24 | return alertDialog; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/NavItem.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | /** 4 | * Created by Anastassios Martakos on 8/24/15. 5 | */ 6 | public class NavItem { 7 | String mTitle; 8 | String mSubtitle; 9 | int mIcon; 10 | 11 | public NavItem(String title, String subtitle, int icon) { 12 | mTitle = title; 13 | mSubtitle = subtitle; 14 | mIcon = icon; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/PostBootComplete.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.os.AsyncTask; 6 | import android.preference.PreferenceManager; 7 | 8 | /** 9 | * Created by Anastassios Martakos on 8/18/15. 10 | */ 11 | public class PostBootComplete extends AsyncTask { 12 | private Context context; 13 | private boolean do_all; 14 | 15 | public PostBootComplete(Context context, boolean do_all) { 16 | this.context = context; 17 | this.do_all = do_all; 18 | } 19 | 20 | @Override 21 | protected void onPreExecute() { 22 | super.onPreExecute(); 23 | } 24 | 25 | @Override 26 | protected String doInBackground(String... aurl) { 27 | try { 28 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(context); 29 | SharedPreferences.Editor editor = shared_preferences.edit(); 30 | 31 | editor.putInt(Constants.LAST_STATE, -200); 32 | editor.commit(); 33 | 34 | Thread.sleep(20000); 35 | GetIPv6Address.PreGetIPv6Address(context, do_all); 36 | }catch (Exception e) { 37 | } 38 | return null; 39 | } 40 | 41 | @Override 42 | protected void onPostExecute(String unused) { 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/SUCalls.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.util.Log; 4 | 5 | // import com.stericson.RootTools.RootTools; 6 | 7 | import java.io.DataOutputStream; 8 | import java.util.Arrays; 9 | import java.util.Collections; 10 | 11 | import eu.chainfire.libsuperuser.Shell; 12 | 13 | /** 14 | * Created by Anastassios Martakos on 7/31/15. 15 | */ 16 | public class SUCalls { 17 | private static final String TAG = "SUCalls"; 18 | 19 | public static void force_dhcpv6(String ifname) { 20 | kill_client_process(); 21 | start_dhcp6c_process(ifname); 22 | } 23 | 24 | public static void start_dhcp6c_process(String ifname) { 25 | Shell.SU.run(Collections.singletonList("dhcp6c " + ifname)); 26 | } 27 | 28 | public static void download_file(String file) { 29 | Log.d(TAG, "Downloading file: " + file); 30 | Shell.SU.run(Collections.singletonList( 31 | "busybox wget -O " + file + " http://cmmn.realmar.net/dhcp/dhcp_complete" + file 32 | )); 33 | } 34 | 35 | public static void send_signal_to_client_process(String inter_face) { 36 | Log.d(TAG, "Sending signal to master process for Interface: " + inter_face); 37 | Shell.SU.run(Collections.singletonList("/system/bin/dhcp6ctl -C start interface " + inter_face)); 38 | } 39 | 40 | public static void remove_file(String file) { 41 | Log.d(TAG, "Removing file: " + file); 42 | Shell.SU.run(Collections.singletonList("rm -rf " + file)); 43 | } 44 | 45 | public static boolean check_process(String process) { 46 | Log.d(TAG, "Checking master process"); 47 | return !Shell.SU.run(Collections.singletonList("pgrep " + process)).isEmpty(); 48 | } 49 | 50 | public static void kill_client_process() { 51 | Log.d(TAG, "Killing client process"); 52 | Shell.SU.run(Collections.singletonList("kill -9 `pgrep dhcp6c`")); 53 | } 54 | 55 | public static void kill_server_process() { 56 | Log.d(TAG, "Killing server process"); 57 | Shell.SU.run(Collections.singletonList("kill -9 `pgrep dhcp6s`")); 58 | } 59 | 60 | public static void mount_rw() { 61 | Log.d(TAG, "Mounting /system RW"); 62 | // RootTools.remount("/system", "RO"); 63 | // RootTools.remount("/system", "RW"); 64 | 65 | Shell.SU.run(Collections.singletonList("mount -o rw,remount /system")); 66 | } 67 | 68 | public static void mount_ro() { 69 | Log.d(TAG, "Mounting /system RO"); 70 | // RootTools.remount("/system", "RO"); 71 | 72 | Shell.SU.run(Collections.singletonList("mount -o ro,remount /system")); 73 | } 74 | 75 | public static void create_dir(String folder, String user, String group, String permission) { 76 | Log.d(TAG, "Creating dir: " + folder + " user: " + user + " group: " + group + " permission: " + permission); 77 | Shell.SU.run(Arrays.asList( 78 | "mkdir -p " + folder, 79 | "chown " + user + ":" + group + " " + folder, 80 | "chmod " + permission + " " + folder 81 | )); 82 | } 83 | 84 | public static void delete_file(String file) { 85 | Log.d(TAG, "Delete file: " + file); 86 | Shell.SU.run(Collections.singletonList( 87 | "rm -rf " + file 88 | )); 89 | } 90 | 91 | public static void copy_specific_file(String src_file, String dest_file, String user, String group, String permission) { // is a file path with filename 92 | Log.d(TAG, "Copy file " + src_file + " --> " + dest_file + " user: " + user + " group: " + group + " permission: " + permission); 93 | Shell.SU.run(Arrays.asList( 94 | "rm -rf " + dest_file, 95 | "cp -r " + src_file + " " + dest_file, 96 | "chown " + user + ":" + group + " " + dest_file, 97 | "chmod " + permission + " " + dest_file 98 | )); 99 | } 100 | 101 | public static void set_permissions(String file, String permission, String user, String group) { 102 | Log.d(TAG, "Setting permission: " + file + " user: " + user + " group: " + group + " permission: " + permission); 103 | Shell.SU.run(Arrays.asList( 104 | "chmod " + permission + " " + file, 105 | "chown " + user + ":" + group + " " + file 106 | )); 107 | } 108 | 109 | public static void uninstall_dhcpv6_client() { 110 | Log.d(TAG, "Uninstalling DHCPv6 Client"); 111 | Shell.SU.run(Arrays.asList( 112 | "rm -rf /system/etc/wide-dhcpv6", 113 | "rm -rf /system/bin/dhcp6c", 114 | "rm -rf /system/bin/dhcp6ctl", 115 | "rm -rf /system/bin/dhcp6s" 116 | )); 117 | 118 | kill_client_process(); 119 | kill_server_process(); 120 | } 121 | 122 | public static void write_file(String content, String file_path) { 123 | Log.d(TAG, "Generating file: " + file_path + " content: " + content); 124 | Shell.SU.run(Collections.singletonList( 125 | "busybox printf \"" + content + "\" > " + file_path 126 | )); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/SettingsAdvancedAddInterfacesFragment.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.content.SharedPreferences; 4 | import android.os.Bundle; 5 | import android.preference.ListPreference; 6 | import android.preference.Preference; 7 | import android.preference.PreferenceFragment; 8 | import android.preference.PreferenceManager; 9 | import android.preference.PreferenceScreen; 10 | 11 | import java.util.ArrayList; 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | /** 16 | * Created by Anastassios Martakos on 8/24/15. 17 | */ 18 | public class SettingsAdvancedAddInterfacesFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { 19 | private Preference.OnPreferenceChangeListener preference_change_listener = new Preference.OnPreferenceChangeListener() { 20 | @Override 21 | public boolean onPreferenceChange(Preference preference, Object value) { 22 | String selected_item = value.toString(); 23 | 24 | if (preference.getKey().equals(getActivity().getString(R.string.pref_button_add_interface_key))) { 25 | if (selected_item.equals("")) return false; 26 | 27 | SharedPreferences shared_preference = PreferenceManager.getDefaultSharedPreferences(getActivity()); 28 | 29 | Set additional_interfaces = new HashSet(); 30 | 31 | if (shared_preference.contains(Constants.ADDITIONAL_INTERFACES)) { 32 | additional_interfaces = new HashSet(shared_preference.getStringSet(Constants.ADDITIONAL_INTERFACES, new HashSet())); 33 | } 34 | 35 | assert additional_interfaces != null; 36 | additional_interfaces.add(selected_item); 37 | 38 | SharedPreferences.Editor editor = shared_preference.edit(); 39 | 40 | editor.putStringSet(Constants.ADDITIONAL_INTERFACES, additional_interfaces); 41 | editor.commit(); 42 | 43 | update_add_interfaces(shared_preference); 44 | 45 | new GenerateClientConfig(getActivity()).execute(); 46 | } 47 | 48 | return false; 49 | } 50 | }; 51 | 52 | private Preference.OnPreferenceClickListener preference_click_listener = new Preference.OnPreferenceClickListener() { 53 | @Override 54 | public boolean onPreferenceClick(Preference preference) { 55 | if(preference.getKey().equals(getActivity().getString(R.string.cust_interface_button))) { 56 | String interface_name = preference.getTitle().toString(); 57 | SharedPreferences shared_preference = PreferenceManager.getDefaultSharedPreferences(getActivity()); 58 | 59 | Set all_custom_interfaces = new HashSet(shared_preference.getStringSet(Constants.ADDITIONAL_INTERFACES, new HashSet())); 60 | all_custom_interfaces.remove(interface_name); 61 | 62 | SharedPreferences.Editor editor = shared_preference.edit(); 63 | 64 | editor.putStringSet(Constants.ADDITIONAL_INTERFACES, all_custom_interfaces); 65 | editor.commit(); 66 | 67 | update_add_interfaces(shared_preference); 68 | 69 | new GenerateClientConfig(getActivity()).execute(); 70 | } 71 | return false; 72 | } 73 | }; 74 | 75 | @Override 76 | public void onCreate(Bundle savedInstanceState) { 77 | super.onCreate(savedInstanceState); 78 | 79 | addPreferencesFromResource(R.xml.preferences_advanced_add_interfaces); 80 | 81 | update_add_interfaces(getPreferenceManager().getSharedPreferences()); 82 | } 83 | 84 | @Override 85 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 86 | } 87 | 88 | @Override 89 | public void onResume() { 90 | super.onResume(); 91 | getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); 92 | update_add_interfaces(getPreferenceManager().getSharedPreferences()); 93 | } 94 | 95 | @Override 96 | public void onPause() { 97 | getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); 98 | super.onPause(); 99 | } 100 | 101 | private void update_add_interfaces(SharedPreferences shared_preferences) { 102 | Set additional_interfaces = shared_preferences.getStringSet(Constants.ADDITIONAL_INTERFACES, new HashSet()); 103 | 104 | PreferenceScreen preference_screen = (PreferenceScreen) findPreference("pref_add_interfaces"); 105 | preference_screen.removeAll(); 106 | 107 | if(additional_interfaces != null) { 108 | String cust_interface_button_key = getActivity().getString(R.string.cust_interface_button); 109 | 110 | for (String inter_face : additional_interfaces) { 111 | Preference new_interface = new Preference(getActivity()); 112 | 113 | new_interface.setTitle(inter_face); 114 | new_interface.setSummary(R.string.cust_interface); 115 | new_interface.setKey(cust_interface_button_key); 116 | 117 | new_interface.setOnPreferenceClickListener(preference_click_listener); 118 | 119 | preference_screen.addPreference(new_interface); 120 | } 121 | } 122 | 123 | ArrayList all_interfaces = SettingsFragment.filter_all_interfaces(Misc.get_all_interfaces(), additional_interfaces); 124 | 125 | ListPreference add_interface_button = new ListPreference(getActivity()); 126 | 127 | add_interface_button.setTitle(R.string.pref_button_add_interface); 128 | add_interface_button.setKey(getActivity().getString(R.string.pref_button_add_interface_key)); 129 | add_interface_button.setIcon(R.mipmap.drawable_plus); 130 | 131 | add_interface_button.setEntries(all_interfaces.toArray(new CharSequence[all_interfaces.size()])); 132 | add_interface_button.setEntryValues(all_interfaces.toArray(new CharSequence[all_interfaces.size()])); 133 | add_interface_button.setDefaultValue("1"); 134 | 135 | add_interface_button.setOnPreferenceChangeListener(preference_change_listener); 136 | 137 | preference_screen.addPreference(add_interface_button); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/SettingsAdvancedFragment.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.content.SharedPreferences; 4 | import android.os.Bundle; 5 | import android.preference.Preference; 6 | import android.preference.PreferenceFragment; 7 | 8 | /** 9 | * Created by Anastassios Martakos on 8/24/15. 10 | */ 11 | public class SettingsAdvancedFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { 12 | @Override 13 | public void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | 16 | addPreferencesFromResource(R.xml.preferences_advanced); 17 | add_click_listener("pref_all"); 18 | add_click_listener("pref_button_add_interfaces"); 19 | 20 | check_preferences(getPreferenceManager().getSharedPreferences()); 21 | } 22 | 23 | @Override 24 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 25 | check_preferences(sharedPreferences); 26 | } 27 | 28 | @Override 29 | public void onResume() { 30 | super.onResume(); 31 | getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); 32 | check_preferences(getPreferenceManager().getSharedPreferences()); 33 | } 34 | 35 | @Override 36 | public void onPause() { 37 | getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); 38 | super.onPause(); 39 | } 40 | 41 | private void add_click_listener(final String element_arg) { 42 | Preference element = (Preference) findPreference(element_arg); 43 | 44 | element.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 45 | @Override 46 | public boolean onPreferenceClick(Preference preference) { 47 | switch (element_arg) { 48 | case "pref_button_add_interfaces": 49 | ((MainActivity) getActivity()).go_settings_advanced_add(); 50 | break; 51 | case "pref_all": 52 | new GenerateClientConfig(getActivity()).execute(); 53 | break; 54 | } 55 | 56 | return true; 57 | } 58 | }); 59 | } 60 | 61 | private void check_preferences(SharedPreferences sharedPreferences) { 62 | boolean is_installed = sharedPreferences.getBoolean("is_installed", false); 63 | boolean is_installed_udpate = sharedPreferences.getBoolean("is_installed_update", false); 64 | 65 | if(!sharedPreferences.getBoolean("pref_enable", false) || !is_installed || !is_installed_udpate) { 66 | findPreference("pref_button_add_interfaces").setEnabled(false); 67 | findPreference("pref_all").setEnabled(false); 68 | }else{ 69 | findPreference("pref_button_add_interfaces").setEnabled(true); 70 | findPreference("pref_all").setEnabled(true); 71 | } 72 | 73 | if(sharedPreferences.getBoolean("pref_all", false)) { 74 | findPreference("pref_button_add_interfaces").setEnabled(false); 75 | }else{ 76 | if(sharedPreferences.getBoolean("pref_enable", false) && is_installed && is_installed_udpate) { 77 | findPreference("pref_button_add_interfaces").setEnabled(true); 78 | } 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/SettingsFragment.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.content.SharedPreferences; 4 | import android.os.Bundle; 5 | import android.preference.Preference; 6 | import android.preference.PreferenceFragment; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Set; 10 | 11 | /** 12 | * Created by Anastassios Martakos on 8/6/15. 13 | */ 14 | public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { 15 | @Override 16 | public void onStart() { 17 | super.onStart(); 18 | check_preferences(getPreferenceManager().getSharedPreferences()); 19 | } 20 | 21 | @Override 22 | public void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | 25 | addPreferencesFromResource(R.xml.preferences); 26 | add_click_listener("pref_wlan"); 27 | add_click_listener("pref_button_advanced"); 28 | 29 | check_preferences(getPreferenceManager().getSharedPreferences()); 30 | } 31 | 32 | @Override 33 | public void onResume() { 34 | super.onResume(); 35 | getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); 36 | check_preferences(getPreferenceManager().getSharedPreferences()); 37 | } 38 | 39 | @Override 40 | public void onPause() { 41 | getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); 42 | super.onPause(); 43 | } 44 | 45 | @Override 46 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 47 | check_preferences(sharedPreferences); 48 | } 49 | 50 | private void check_preferences(SharedPreferences sharedPreferences) { 51 | boolean is_installed = sharedPreferences.getBoolean("is_installed", false); 52 | boolean is_installed_udpate = sharedPreferences.getBoolean("is_installed_update", false); 53 | 54 | if(!sharedPreferences.getBoolean("pref_enable", false) || !is_installed || !is_installed_udpate) { 55 | findPreference("pref_wlan").setEnabled(false); 56 | findPreference("pref_button_advanced").setEnabled(false); 57 | 58 | findPreference("pref_enable").setTitle(R.string.pref_disabled); 59 | findPreference("pref_enable").setSummary(R.string.pref_disabled_summ); 60 | }else{ 61 | findPreference("pref_wlan").setEnabled(true); 62 | findPreference("pref_button_advanced").setEnabled(true); 63 | 64 | findPreference("pref_enable").setTitle(R.string.pref_enabled); 65 | findPreference("pref_enable").setSummary(R.string.pref_enabled_summ); 66 | } 67 | 68 | if(sharedPreferences.getBoolean("pref_all", false)) { 69 | findPreference("pref_wlan").setEnabled(false); 70 | }else{ 71 | if(sharedPreferences.getBoolean("pref_enable", false) && is_installed && is_installed_udpate) { 72 | findPreference("pref_wlan").setEnabled(true); 73 | } 74 | } 75 | 76 | if(!is_installed || !is_installed_udpate) { 77 | findPreference("pref_enable").setEnabled(false); 78 | }else{ 79 | findPreference("pref_enable").setEnabled(true); 80 | } 81 | } 82 | 83 | private void add_click_listener(final String element_arg) { 84 | Preference element = (Preference) findPreference(element_arg); 85 | 86 | element.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 87 | @Override 88 | public boolean onPreferenceClick(Preference preference) { 89 | switch (element_arg) { 90 | case "pref_wlan": 91 | new GenerateClientConfig(getActivity()).execute(); 92 | break; 93 | case "pref_button_advanced": 94 | ((MainActivity) getActivity()).go_settings_advanced(); 95 | break; 96 | } 97 | 98 | return true; 99 | } 100 | }); 101 | } 102 | 103 | public static ArrayList filter_all_interfaces(ArrayList unfiltered_interfaces, Set configured_interfaces) { 104 | ArrayList filtered_interfaces = new ArrayList(); 105 | 106 | for (String unfiltered_interface : unfiltered_interfaces) { 107 | boolean exists = false; 108 | 109 | for(String configured_interface : configured_interfaces) { 110 | if(configured_interface.equals(unfiltered_interface)) exists = true; 111 | } 112 | 113 | if(unfiltered_interface.equals("wlan0") || unfiltered_interface.equals("rmnet0")) exists = true; 114 | 115 | if(!exists) filtered_interfaces.add(unfiltered_interface); 116 | } 117 | 118 | return filtered_interfaces; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/SupportFragment.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Fragment; 4 | import android.os.Bundle; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | /** 10 | * Created by Anastassios Martakos on 7/31/15. 11 | */ 12 | 13 | public class SupportFragment extends Fragment { 14 | 15 | /*@Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.support_fragment); 19 | } 20 | 21 | @Override 22 | public boolean onCreateOptionsMenu(Menu menu) { 23 | // Inflate the menu; this adds items to the action bar if it is present. 24 | getMenuInflater().inflate(R.menu.support_activity, menu); 25 | return true; 26 | } 27 | 28 | @Override 29 | public boolean onOptionsItemSelected(MenuItem item) { 30 | // Handle action bar item clicks here. The action bar will 31 | // automatically handle clicks on the Home/Up button, so long 32 | // as you specify a parent activity in AndroidManifest.xml. 33 | 34 | //noinspection SimplifiableIfStatement 35 | 36 | return super.onOptionsItemSelected(item); 37 | }*/ 38 | 39 | @Override 40 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 41 | Bundle savedInstanceState) { 42 | // Inflate the layout for this fragment 43 | return inflater.inflate(R.layout.support_fragment, container, false); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/SystemIntegrity.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.os.StatFs; 4 | 5 | /** 6 | * Created by Anastassios Martakos on 8/31/15. 7 | */ 8 | public class SystemIntegrity { 9 | private static final String TAG = "SystemIntegrity"; 10 | 11 | private static String[] unsupported_arches = { 12 | Constants.ARCH_X86 13 | }; 14 | 15 | private static long base = 117581; 16 | private static long update = 131166; 17 | private static long config = 6000; 18 | 19 | public static boolean full_check() { 20 | return check_disk_space("/system", base + update + config); 21 | } 22 | 23 | public static boolean update_check() { 24 | return check_disk_space("/system", update + config); 25 | } 26 | 27 | public static String check_arch() { 28 | String current_arch = "ok"; 29 | String system_arch = System.getProperty("os.arch"); 30 | 31 | for(String arch : unsupported_arches) { 32 | if(system_arch.toLowerCase().contains(arch.toLowerCase())) { 33 | current_arch = arch; 34 | break; 35 | } 36 | } 37 | 38 | return current_arch; 39 | } 40 | 41 | private static boolean check_disk_space(String path, long size) { 42 | StatFs stat = new StatFs(path); 43 | long bytes_available = (long) stat.getBlockSize() * (long) stat.getAvailableBlocks(); 44 | 45 | if(bytes_available - size > 0) { 46 | return true; 47 | }else{ 48 | return false; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/UIMenu.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.Context; 6 | import android.content.SharedPreferences; 7 | import android.preference.PreferenceManager; 8 | 9 | /** 10 | * Created by Anastassios Martakos on 7/31/15. 11 | */ 12 | 13 | public class UIMenu { 14 | 15 | public UIMenu(Context context_arg) { 16 | } 17 | 18 | public static void open_status(boolean is_running, Context context) { 19 | String running = is_running ? "running" : "not running"; 20 | 21 | MsgBoxes status = new MsgBoxes(); 22 | AlertDialog status_dialog = (AlertDialog) status.one_button((MainActivity) context, "Status", "Client Service: " + running, false); 23 | status_dialog.show(); 24 | } 25 | 26 | public static void unorinstall(Activity activity) { 27 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(activity); 28 | 29 | if (shared_preferences.getBoolean("is_installed", false) && shared_preferences.getBoolean("is_installed_update", false)) { 30 | Misc.question_uninstallation(activity); 31 | }else if(shared_preferences.getBoolean("is_installed", false) && !shared_preferences.getBoolean("is_installed_update", false)) { 32 | Misc.question_installation_update(activity); 33 | }else{ 34 | Misc.question_installation(activity); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/UninstallDHCPv6Client.java: -------------------------------------------------------------------------------- 1 | package org.daduke.realmar.dhcpv6client; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.app.ProgressDialog; 6 | import android.content.Context; 7 | import android.content.SharedPreferences; 8 | import android.os.AsyncTask; 9 | import android.preference.PreferenceManager; 10 | 11 | /** 12 | * Created by Anastassios Martakos on 8/3/15. 13 | */ 14 | public class UninstallDHCPv6Client extends AsyncTask { 15 | ProgressDialog progDialog; 16 | Activity activity; 17 | private boolean result_status; 18 | 19 | public UninstallDHCPv6Client(Activity activity_arg) { 20 | activity = activity_arg; 21 | progDialog = new ProgressDialog(activity_arg); 22 | } 23 | 24 | @Override 25 | protected void onPreExecute() { 26 | super.onPreExecute(); 27 | progDialog.setMessage("Uninstalling ..."); 28 | progDialog.setIndeterminate(false); 29 | progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 30 | progDialog.setCancelable(false); 31 | progDialog.show(); 32 | } 33 | @Override 34 | protected String doInBackground(String... aurl) { 35 | result_status = uninstall_dhcpv6(); 36 | return null; 37 | } 38 | @Override 39 | protected void onPostExecute(String unused) { 40 | super.onPostExecute(unused); 41 | MsgBoxes msg_box = new MsgBoxes(); 42 | if(result_status) { 43 | SharedPreferences shared_preferences = PreferenceManager.getDefaultSharedPreferences(activity); 44 | SharedPreferences.Editor editor = shared_preferences.edit(); 45 | 46 | editor.putBoolean("is_installed", false); 47 | editor.putBoolean("is_installed_update", false); 48 | editor.commit(); 49 | 50 | MainActivity.option_menu_main.findItem(R.id.action_unorinstall).setTitle(R.string.action_install); 51 | MainActivity.option_menu_main.findItem(R.id.action_invoke).setEnabled(false); 52 | MainActivity.option_menu_main.findItem(R.id.action_unorinstall).setIcon(R.mipmap.ic_install); 53 | 54 | AlertDialog success = (AlertDialog) msg_box.one_button(activity, "Success", activity.getString(R.string.success_uninstall), false); 55 | success.show(); 56 | }else{ 57 | AlertDialog error = (AlertDialog) msg_box.one_button(activity, "Error", activity.getString(R.string.failure_uninstall) , false); 58 | error.show(); 59 | } 60 | progDialog.dismiss(); 61 | } 62 | 63 | public boolean uninstall_dhcpv6() { 64 | try { 65 | SUCalls.mount_rw(); 66 | SUCalls.uninstall_dhcpv6_client(); 67 | SUCalls.mount_ro(); 68 | 69 | return true; 70 | }catch (Exception e) { 71 | return false; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/util/IabBroadcastReceiver.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Google Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.daduke.realmar.dhcpv6client.util; 17 | 18 | import android.content.BroadcastReceiver; 19 | import android.content.Context; 20 | import android.content.Intent; 21 | 22 | /** 23 | * Receiver for the "com.android.vending.billing.PURCHASES_UPDATED" Action 24 | * from the Play Store. 25 | * 26 | *

It is possible that an in-app item may be acquired without the 27 | * application calling getBuyIntent(), for example if the item can be 28 | * redeemed from inside the Play Store using a promotional code. If this 29 | * application isn't running at the time, then when it is started a call 30 | * to getPurchases() will be sufficient notification. However, if the 31 | * application is already running in the background when the item is acquired, 32 | * a message to this BroadcastReceiver will indicate that the an item 33 | * has been acquired.

34 | */ 35 | public class IabBroadcastReceiver extends BroadcastReceiver { 36 | /** 37 | * Listener interface for received broadcast messages. 38 | */ 39 | public interface IabBroadcastListener { 40 | void receivedBroadcast(); 41 | } 42 | 43 | /** 44 | * The Intent action that this Receiver should filter for. 45 | */ 46 | public static final String ACTION = "com.android.vending.billing.PURCHASES_UPDATED"; 47 | 48 | private final IabBroadcastListener mListener; 49 | 50 | public IabBroadcastReceiver(IabBroadcastListener listener) { 51 | mListener = listener; 52 | } 53 | 54 | @Override 55 | public void onReceive(Context context, Intent intent) { 56 | if (mListener != null) { 57 | mListener.receivedBroadcast(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/util/IabException.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012 Google Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.daduke.realmar.dhcpv6client.util; 17 | 18 | /** 19 | * Exception thrown when something went wrong with in-app billing. 20 | * An IabException has an associated IabResult (an error). 21 | * To get the IAB result that caused this exception to be thrown, 22 | * call {@link #getResult()}. 23 | */ 24 | public class IabException extends Exception { 25 | IabResult mResult; 26 | 27 | public IabException(IabResult r) { 28 | this(r, null); 29 | } 30 | public IabException(int response, String message) { 31 | this(new IabResult(response, message)); 32 | } 33 | public IabException(IabResult r, Exception cause) { 34 | super(r.getMessage(), cause); 35 | mResult = r; 36 | } 37 | public IabException(int response, String message, Exception cause) { 38 | this(new IabResult(response, message), cause); 39 | } 40 | 41 | /** Returns the IAB result (error) that this exception signals. */ 42 | public IabResult getResult() { return mResult; } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/util/IabResult.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012 Google Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.daduke.realmar.dhcpv6client.util; 17 | 18 | /** 19 | * Represents the result of an in-app billing operation. 20 | * A result is composed of a response code (an integer) and possibly a 21 | * message (String). You can get those by calling 22 | * {@link #getResponse} and {@link #getMessage()}, respectively. You 23 | * can also inquire whether a result is a success or a failure by 24 | * calling {@link #isSuccess()} and {@link #isFailure()}. 25 | */ 26 | public class IabResult { 27 | int mResponse; 28 | String mMessage; 29 | 30 | public IabResult(int response, String message) { 31 | mResponse = response; 32 | if (message == null || message.trim().length() == 0) { 33 | mMessage = IabHelper.getResponseDesc(response); 34 | } 35 | else { 36 | mMessage = message + " (response: " + IabHelper.getResponseDesc(response) + ")"; 37 | } 38 | } 39 | public int getResponse() { return mResponse; } 40 | public String getMessage() { return mMessage; } 41 | public boolean isSuccess() { return mResponse == IabHelper.BILLING_RESPONSE_RESULT_OK; } 42 | public boolean isFailure() { return !isSuccess(); } 43 | public String toString() { return "IabResult: " + getMessage(); } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/util/Inventory.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012 Google Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.daduke.realmar.dhcpv6client.util; 17 | 18 | import java.util.ArrayList; 19 | import java.util.HashMap; 20 | import java.util.List; 21 | import java.util.Map; 22 | 23 | /** 24 | * Represents a block of information about in-app items. 25 | * An Inventory is returned by such methods as {@link IabHelper#queryInventory}. 26 | */ 27 | public class Inventory { 28 | Map mSkuMap = new HashMap(); 29 | Map mPurchaseMap = new HashMap(); 30 | 31 | Inventory() { } 32 | 33 | /** Returns the listing details for an in-app product. */ 34 | public SkuDetails getSkuDetails(String sku) { 35 | return mSkuMap.get(sku); 36 | } 37 | 38 | /** Returns purchase information for a given product, or null if there is no purchase. */ 39 | public Purchase getPurchase(String sku) { 40 | return mPurchaseMap.get(sku); 41 | } 42 | 43 | /** Returns whether or not there exists a purchase of the given product. */ 44 | public boolean hasPurchase(String sku) { 45 | return mPurchaseMap.containsKey(sku); 46 | } 47 | 48 | /** Return whether or not details about the given product are available. */ 49 | public boolean hasDetails(String sku) { 50 | return mSkuMap.containsKey(sku); 51 | } 52 | 53 | /** 54 | * Erase a purchase (locally) from the inventory, given its product ID. This just 55 | * modifies the Inventory object locally and has no effect on the server! This is 56 | * useful when you have an existing Inventory object which you know to be up to date, 57 | * and you have just consumed an item successfully, which means that erasing its 58 | * purchase data from the Inventory you already have is quicker than querying for 59 | * a new Inventory. 60 | */ 61 | public void erasePurchase(String sku) { 62 | if (mPurchaseMap.containsKey(sku)) mPurchaseMap.remove(sku); 63 | } 64 | 65 | /** Returns a list of all owned product IDs. */ 66 | List getAllOwnedSkus() { 67 | return new ArrayList(mPurchaseMap.keySet()); 68 | } 69 | 70 | /** Returns a list of all owned product IDs of a given type */ 71 | List getAllOwnedSkus(String itemType) { 72 | List result = new ArrayList(); 73 | for (Purchase p : mPurchaseMap.values()) { 74 | if (p.getItemType().equals(itemType)) result.add(p.getSku()); 75 | } 76 | return result; 77 | } 78 | 79 | /** Returns a list of all purchases. */ 80 | List getAllPurchases() { 81 | return new ArrayList(mPurchaseMap.values()); 82 | } 83 | 84 | void addSkuDetails(SkuDetails d) { 85 | mSkuMap.put(d.getSku(), d); 86 | } 87 | 88 | void addPurchase(Purchase p) { 89 | mPurchaseMap.put(p.getSku(), p); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/util/Purchase.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012 Google Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.daduke.realmar.dhcpv6client.util; 17 | 18 | import org.json.JSONException; 19 | import org.json.JSONObject; 20 | 21 | /** 22 | * Represents an in-app billing purchase. 23 | */ 24 | public class Purchase { 25 | String mItemType; // ITEM_TYPE_INAPP or ITEM_TYPE_SUBS 26 | String mOrderId; 27 | String mPackageName; 28 | String mSku; 29 | long mPurchaseTime; 30 | int mPurchaseState; 31 | String mDeveloperPayload; 32 | String mToken; 33 | String mOriginalJson; 34 | String mSignature; 35 | boolean mIsAutoRenewing; 36 | 37 | public Purchase(String itemType, String jsonPurchaseInfo, String signature) throws JSONException { 38 | mItemType = itemType; 39 | mOriginalJson = jsonPurchaseInfo; 40 | JSONObject o = new JSONObject(mOriginalJson); 41 | mOrderId = o.optString("orderId"); 42 | mPackageName = o.optString("packageName"); 43 | mSku = o.optString("productId"); 44 | mPurchaseTime = o.optLong("purchaseTime"); 45 | mPurchaseState = o.optInt("purchaseState"); 46 | mDeveloperPayload = o.optString("developerPayload"); 47 | mToken = o.optString("token", o.optString("purchaseToken")); 48 | mIsAutoRenewing = o.optBoolean("autoRenewing"); 49 | mSignature = signature; 50 | } 51 | 52 | public String getItemType() { return mItemType; } 53 | public String getOrderId() { return mOrderId; } 54 | public String getPackageName() { return mPackageName; } 55 | public String getSku() { return mSku; } 56 | public long getPurchaseTime() { return mPurchaseTime; } 57 | public int getPurchaseState() { return mPurchaseState; } 58 | public String getDeveloperPayload() { return mDeveloperPayload; } 59 | public String getToken() { return mToken; } 60 | public String getOriginalJson() { return mOriginalJson; } 61 | public String getSignature() { return mSignature; } 62 | public boolean isAutoRenewing() { return mIsAutoRenewing; } 63 | 64 | @Override 65 | public String toString() { return "PurchaseInfo(type:" + mItemType + "):" + mOriginalJson; } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/util/Security.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012 Google Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.daduke.realmar.dhcpv6client.util; 17 | 18 | import android.text.TextUtils; 19 | import android.util.Base64; 20 | import android.util.Log; 21 | 22 | import java.security.InvalidKeyException; 23 | import java.security.KeyFactory; 24 | import java.security.NoSuchAlgorithmException; 25 | import java.security.PublicKey; 26 | import java.security.Signature; 27 | import java.security.SignatureException; 28 | import java.security.spec.InvalidKeySpecException; 29 | import java.security.spec.X509EncodedKeySpec; 30 | 31 | /** 32 | * Security-related methods. For a secure implementation, all of this code 33 | * should be implemented on a server that communicates with the 34 | * application on the device. For the sake of simplicity and clarity of this 35 | * example, this code is included here and is executed on the device. If you 36 | * must verify the purchases on the phone, you should obfuscate this code to 37 | * make it harder for an attacker to replace the code with stubs that treat all 38 | * purchases as verified. 39 | */ 40 | public class Security { 41 | private static final String TAG = "IABUtil/Security"; 42 | 43 | private static final String KEY_FACTORY_ALGORITHM = "RSA"; 44 | private static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; 45 | 46 | /** 47 | * Verifies that the data was signed with the given signature, and returns 48 | * the verified purchase. The data is in JSON format and signed 49 | * with a private key. The data also contains the {@link PurchaseState} 50 | * and product ID of the purchase. 51 | * @param base64PublicKey the base64-encoded public key to use for verifying. 52 | * @param signedData the signed JSON string (signed, not encrypted) 53 | * @param signature the signature for the data, signed with the private key 54 | */ 55 | public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) { 56 | if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) || 57 | TextUtils.isEmpty(signature)) { 58 | Log.e(TAG, "Purchase verification failed: missing data."); 59 | return false; 60 | } 61 | 62 | PublicKey key = Security.generatePublicKey(base64PublicKey); 63 | return Security.verify(key, signedData, signature); 64 | } 65 | 66 | /** 67 | * Generates a PublicKey instance from a string containing the 68 | * Base64-encoded public key. 69 | * 70 | * @param encodedPublicKey Base64-encoded public key 71 | * @throws IllegalArgumentException if encodedPublicKey is invalid 72 | */ 73 | public static PublicKey generatePublicKey(String encodedPublicKey) { 74 | try { 75 | byte[] decodedKey = Base64.decode(encodedPublicKey, Base64.DEFAULT); 76 | KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM); 77 | return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey)); 78 | } catch (NoSuchAlgorithmException e) { 79 | throw new RuntimeException(e); 80 | } catch (InvalidKeySpecException e) { 81 | Log.e(TAG, "Invalid key specification."); 82 | throw new IllegalArgumentException(e); 83 | } 84 | } 85 | 86 | /** 87 | * Verifies that the signature from the server matches the computed 88 | * signature on the data. Returns true if the data is correctly signed. 89 | * 90 | * @param publicKey public key associated with the developer account 91 | * @param signedData signed data from server 92 | * @param signature server signature 93 | * @return true if the data and signature match 94 | */ 95 | public static boolean verify(PublicKey publicKey, String signedData, String signature) { 96 | byte[] signatureBytes; 97 | try { 98 | signatureBytes = Base64.decode(signature, Base64.DEFAULT); 99 | } catch (IllegalArgumentException e) { 100 | Log.e(TAG, "Base64 decoding failed."); 101 | return false; 102 | } 103 | try { 104 | Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM); 105 | sig.initVerify(publicKey); 106 | sig.update(signedData.getBytes()); 107 | if (!sig.verify(signatureBytes)) { 108 | Log.e(TAG, "Signature verification failed."); 109 | return false; 110 | } 111 | return true; 112 | } catch (NoSuchAlgorithmException e) { 113 | Log.e(TAG, "NoSuchAlgorithmException."); 114 | } catch (InvalidKeyException e) { 115 | Log.e(TAG, "Invalid key specification."); 116 | } catch (SignatureException e) { 117 | Log.e(TAG, "Signature exception."); 118 | } 119 | return false; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/java/org/daduke/realmar/dhcpv6client/util/SkuDetails.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012 Google Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.daduke.realmar.dhcpv6client.util; 17 | 18 | import org.json.JSONException; 19 | import org.json.JSONObject; 20 | 21 | /** 22 | * Represents an in-app product's listing details. 23 | */ 24 | public class SkuDetails { 25 | private final String mItemType; 26 | private final String mSku; 27 | private final String mType; 28 | private final String mPrice; 29 | private final long mPriceAmountMicros; 30 | private final String mPriceCurrencyCode; 31 | private final String mTitle; 32 | private final String mDescription; 33 | private final String mJson; 34 | 35 | public SkuDetails(String jsonSkuDetails) throws JSONException { 36 | this(IabHelper.ITEM_TYPE_INAPP, jsonSkuDetails); 37 | } 38 | 39 | public SkuDetails(String itemType, String jsonSkuDetails) throws JSONException { 40 | mItemType = itemType; 41 | mJson = jsonSkuDetails; 42 | JSONObject o = new JSONObject(mJson); 43 | mSku = o.optString("productId"); 44 | mType = o.optString("type"); 45 | mPrice = o.optString("price"); 46 | mPriceAmountMicros = o.optLong("price_amount_micros"); 47 | mPriceCurrencyCode = o.optString("price_currency_code"); 48 | mTitle = o.optString("title"); 49 | mDescription = o.optString("description"); 50 | } 51 | 52 | public String getSku() { return mSku; } 53 | public String getType() { return mType; } 54 | public String getPrice() { return mPrice; } 55 | public long getPriceAmountMicros() { return mPriceAmountMicros; } 56 | public String getPriceCurrencyCode() { return mPriceCurrencyCode; } 57 | public String getTitle() { return mTitle; } 58 | public String getDescription() { return mDescription; } 59 | 60 | @Override 61 | public String toString() { 62 | return "SkuDetails:" + mJson; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/res/animator/fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/animator/fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/about_fragment.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | 15 | 23 | 24 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | 14 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings_advanced.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | 14 | 18 | 19 | 20 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings_advanced_add.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | 14 | 18 | 19 | 20 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/custom_dhcpv6_fragment.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 19 | 20 | 29 | 30 | 34 | 35 | 36 | 43 | 44 | 45 | 46 | 53 | 54 | 63 | 64 | 69 | 70 | 71 | 78 | 79 | 91 | 92 |