...
 
Commits (96)
image: openjdk:8-jdk
variables:
ANDROID_COMPILE_SDK: "27"
ANDROID_BUILD_TOOLS: "27.0.3"
ANDROID_SDK_TOOLS: "26.0.2"
ANDROID_COMPILE_SDK: "28"
ANDROID_BUILD_TOOLS: "28.0.2"
ANDROID_SDK_TOOLS: "26.1.1"
AVD_NAME: test
DEV_DEPLOY_DIR: /var/www/frostnerd/download/appbuilds/dnschanger/ci/dev
RELEASE_DEPLOY_DIR: /var/www/frostnerd/download/appbuilds/dnschanger/ci/releases
......@@ -11,19 +11,9 @@ before_script:
- source /home/public/android-sdk-linux/initAndroid.sh -s ${ANDROID_COMPILE_SDK} -b ${ANDROID_BUILD_TOOLS}
stages:
- init
- build
- test
- webdeploy
init:
stage: init
script:
- git config --file=.gitmodules submodule.AndroidUtils.url https://runner:$USER_PASS@git.frostnerd.com/AndroidApps/AndroidUtils.git
- git submodule sync
- git submodule update --init --recursive --force --remote
except:
- /^no_ci.*$/
build:
stage: build
......
[submodule "AndroidUtils"]
path = AndroidUtils
url = ../../AndroidApps/AndroidUtils
Subproject commit 15846800dc064d5233bd85ac30eab478eb953057
......@@ -14,46 +14,19 @@ As this project contains many hours of my (unpaid) work and I don't get any reve
4. You MUST give attribution to me when using parts of my code (Visually to possible users and in the Sourcecode).<br>
5. Additionally, when using part of my code please inform me that you want to use parts of my code AND inform your users that it contains work done by me.<br><br>
If you want to use parts just wrint me a simple email. Any of these restrictions might be lifted then. I don't bite ;)
If you want to use parts just write me a simple email. Any of these restrictions might be lifted then. I don't bite ;)
For projects which generate no revenue (direct or indirect) and are generally available up to 10 people or less terms 1 and 5 do not apply. Under these circumstances, if you want shoot me an email about what you want to do with the source code but proper permission is not required. Attribution (term 4) is still required, but only in source code
Have a look at the wiki for this app: https://git.frostnerd.com/PublicAndroidApps/DnsChanger/wikis/home<br>
This app could possibly spy on using the VPN connection which has to be used to apply the choosen DNS Servers. It doesn't. This project is open source so that people familiar with java/Android can check on this promise.
This app could possibly spy on using the VPN connection which has to be used to apply the chosen DNS Servers. It doesn't. This project is open source so that people familiar with java/Android can check on this promise.
If you are not familiar with it: The VPN is only local. Using the VPN you are assigned an IP-Address which can't be used in the internet (192.168.0.1) and connect to the device only (127.0.0.1:8087),
NOT to an endpoint in the internet. The relevant code lines are those: https://git.frostnerd.com/PublicAndroidApps/DnsChanger/blob/master/app/src/main/java/com/frostnerd/dnschanger/DNSVpnService.java#L239-245
<br><br>
Feel free to contribute to this project, it's completely free to sign up and I'd be happy to fix issues or implement requests.<br><br>
This project uses my AndroidUtils library. It can be accessed at https://git.frostnerd.com/AndroidApps/AndroidUtils when signed in.
© Daniel Wolf 2017
© Daniel Wolf 2018
All rights reserved.<br>
This app uses the library dnsjava. License:
>Copyright (c) 1998-2011, Brian Wellington.
>All rights reserved.
>
>Redistribution and use in source and binary forms, with or without
>modification, are permitted provided that the following conditions are met:
>
> * Redistributions of source code must retain the above copyright notice,
> this list of conditions and the following disclaimer.
>
> * Redistributions in binary form must reproduce the above copyright notice,
> this list of conditions and the following disclaimer in the documentation
> and/or other materials provided with the distribution.
>
>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
>AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
>IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
>ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
>LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
>CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
>SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
>INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
>CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
>ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
>POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
apply plugin: 'com.android.application'
apply plugin: 'project-report'
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "com.frostnerd.dnschanger"
minSdkVersion 14
targetSdkVersion 27
versionCode 83
versionName "1.16.0.4"
targetSdkVersion 28
versionCode 86
versionName "BETA 1.16.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
......@@ -38,19 +40,28 @@ android {
}
dependencies {
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.android.support:preference-v14:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation project(path: ':AndroidUtils:library')
implementation 'com.frostnerd.utils:general:1.0.7'
implementation 'com.frostnerd.utils:database:1.1.15'
implementation 'com.frostnerd.utils:design:1.0.14'
implementation 'com.frostnerd.utils:materialedittext:1.0.13'
implementation 'com.frostnerd.utils:preferences:2.2.8'
implementation 'com.frostnerd.utils:networking:1.0.4'
implementation 'com.frostnerd.utils:preferenceexport:1.0.9'
implementation 'com.frostnerd.utils:api:1.0.5'
testImplementation 'com.frostnerd.utils:logging:1.0.7'
implementation "androidx.appcompat:appcompat:1.0.0"
implementation "androidx.cardview:cardview:1.0.0"
implementation "androidx.recyclerview:recyclerview:1.0.0"
implementation "androidx.preference:preference:1.0.0"
implementation "com.google.android.material:material:1.0.0"
testImplementation 'junit:junit:4.12'
testImplementation "org.robolectric:robolectric:3.6.1"
implementation 'com.google.code.gson:gson:2.8.2'
implementation 'dnsjava:dnsjava:2.1.8'
testImplementation "org.robolectric:robolectric:4.0-alpha-3-SNAPSHOT"
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'org.pcap4j:pcap4j-core:1.7.3'
implementation 'org.pcap4j:pcap4j-packetfactory-static:1.7.3'
implementation 'de.measite.minidns:minidns-core:0.2.2'
compileOnly 'org.projectlombok:lombok:1.16.20'
annotationProcessor "org.projectlombok:lombok:1.16.20"
implementation 'de.measite.minidns:minidns-core:0.2.4'
implementation 'de.measite.minidns:minidns-hla:0.2.4'
compileOnly 'org.projectlombok:lombok:1.18.2'
annotationProcessor 'org.projectlombok:lombok:1.18.2'
}
......@@ -15,13 +15,9 @@
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# This dnsjava class uses old Sun API
-dontnote org.xbill.DNS.spi.DNSJavaNameServiceDescriptor
-dontwarn org.xbill.DNS.spi.DNSJavaNameServiceDescriptor
-dontwarn java.awt.*
# See http://stackoverflow.com/questions/5701126, happens in dnsjava
-optimizations !code/allocation/variable
-keep class android.support.v7.widget.SearchView { *; }
-keep class com.frostnerd.dnschanger.util.GenericFileProvider
-keep class com.frostnerd.dnschanger.activities.PinActivity
......
......@@ -42,9 +42,10 @@
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/security_config"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme_Mono">
<meta-data
android:name="android.max_aspect"
......@@ -81,6 +82,8 @@
<intent-filter>
<action android:name="android.net.VpnService" />
</intent-filter>
<meta-data android:name="android.net.VpnService.SUPPORTS_ALWAYS_ON"
android:value="true" />
</service>
<activity
......@@ -93,6 +96,11 @@
android:launchMode="singleInstance"
android:theme="@style/Theme.AppCompat.Light.Dialog.Alert" />
<activity
android:name=".activities.BackgroundDNSListActivity"
android:launchMode="singleInstance"
android:theme="@style/Theme.AppCompat.Light.Dialog.Alert" />
<activity
android:name=".tasker.ConfigureActivity"
android:exported="true"
......@@ -246,6 +254,8 @@
</intent-filter>
</activity>
<activity android:name="com.frostnerd.design.filechooseractivity.FileChooserActivity" />
<receiver
android:name=".receivers.AdminReceiver"
android:description="@string/device_admin_description"
......@@ -260,7 +270,7 @@
</receiver>
<provider
android:name="android.support.v4.content.FileProvider"
android:name="androidx.core.content.FileProvider"
android:authorities="com.frostnerd.dnschanger"
android:exported="false"
android:grantUriPermissions="true">
......
......@@ -3,33 +3,43 @@ package com.frostnerd.dnschanger.activities;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.SwitchPreference;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;
import androidx.appcompat.app.AlertDialog;
import android.view.MenuItem;
import com.frostnerd.database.orm.Entity;
import com.frostnerd.database.orm.parser.columns.Column;
import com.frostnerd.database.orm.statementoptions.queryoptions.WhereCondition;
import com.frostnerd.design.dialogs.FileChooserDialog;
import com.frostnerd.design.dialogs.LoadingDialog;
import com.frostnerd.dnschanger.BuildConfig;
import com.frostnerd.dnschanger.LogFactory;
import com.frostnerd.dnschanger.R;
import com.frostnerd.dnschanger.database.DatabaseHelper;
import com.frostnerd.dnschanger.database.entities.DNSQuery;
import com.frostnerd.dnschanger.database.entities.DNSRule;
import com.frostnerd.dnschanger.database.entities.DNSRuleImport;
import com.frostnerd.dnschanger.util.Preferences;
import com.frostnerd.dnschanger.util.ThemeHandler;
import com.frostnerd.utils.design.dialogs.FileChooserDialog;
import com.frostnerd.utils.design.dialogs.LoadingDialog;
import com.frostnerd.utils.permissions.PermissionsUtil;
import com.frostnerd.utils.preferences.AppCompatPreferenceActivity;
import com.frostnerd.general.permissions.PermissionsUtil;
import com.frostnerd.preferences.AppCompatPreferenceActivity;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
/**
* Copyright Daniel Wolf 2017
......@@ -52,6 +62,7 @@ public class AdvancedSettingsActivity extends AppCompatPreferenceActivity {
setTheme(ThemeHandler.getPreferenceTheme(this));
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.advanced_preferences);
getPreferenceScreen().removePreference(findPreference("dns_over_tls_category"));
findPreference("advanced_settings").setOnPreferenceChangeListener(preferenceChangeListener);
findPreference("advanced_settings").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
......@@ -85,6 +96,58 @@ public class AdvancedSettingsActivity extends AppCompatPreferenceActivity {
return true;
}
});
findPreference("clear_queries").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
showClearListDialog(R.string.title_clear_queries, DNSQuery.class);
return true;
}
});
findPreference("clear_local_rules").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
showClearListDialog(R.string.title_clear_local_rules, DNSRuleImport.class, DNSRule.class);
return true;
}
});
findPreference("undo_rule_import").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
showUndoRuleImportDialog();
return true;
}
});
/*final CheckBoxPreference tls = (CheckBoxPreference) findPreference("dns_over_tls"),
tcp = (CheckBoxPreference) findPreference("dns_over_tcp");
tls.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean val = (boolean)newValue;
tcp.setEnabled(!val);
return preferenceChangeListener.onPreferenceChange(preference, newValue);
}
});
tcp.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean val = (boolean)newValue;
tls.setEnabled(!val);
return preferenceChangeListener.onPreferenceChange(preference, newValue);
}
});
if(tls.isChecked() && tls.isEnabled())tcp.setEnabled(false);
else if(tcp.isChecked() && tcp.isEnabled())tls.setEnabled(false);*/
setUndoRuleImportStatus();
}
private void setUndoRuleImportStatus() {
findPreference("undo_rule_import").setEnabled(DatabaseHelper.getInstance(this).getCount(DNSRuleImport.class) != 0);
}
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return Preferences.getInstance(this);
}
@Override
......@@ -219,7 +282,7 @@ public class AdvancedSettingsActivity extends AppCompatPreferenceActivity {
}
private void showQueryExportSuccessDialog(final File f, int queries) {
new android.app.AlertDialog.Builder(this)
new AlertDialog.Builder(this)
.setMessage(getString(R.string.exported_dns_queries).replace("[x]", String.valueOf(queries)))
.setCancelable(true)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
......@@ -243,6 +306,75 @@ public class AdvancedSettingsActivity extends AppCompatPreferenceActivity {
}).setTitle(R.string.success).show();
}
@SafeVarargs
private final void showClearListDialog(int title, final Class<? extends Entity>... entities){
new AlertDialog.Builder(this).setTitle(title).setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
for (Class<? extends Entity> entity : entities) {
DatabaseHelper.getInstance(AdvancedSettingsActivity.this).deleteAll(entity);
}
setUndoRuleImportStatus();
}
}).setNegativeButton(R.string.cancel, null).setMessage(R.string.dialog_are_you_sure).show();
}
private void showUndoRuleImportDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(this, ThemeHandler.getDialogTheme(this));
builder.setTitle(R.string.title_undo_rule_import);
final HashMap<String, DNSRuleImport> imports = new HashMap<>();
for (DNSRuleImport dnsRuleImport : DatabaseHelper.getInstance(this).getAll(DNSRuleImport.class)) {
imports.put(dnsRuleImport.toString(), dnsRuleImport);
}
final String[] displayedTexts = imports.keySet().toArray(new String[imports.size()]);
final Set<DNSRuleImport> selectedImports = new HashSet<>();
builder.setNegativeButton(R.string.cancel, null);
builder.setMultiChoiceItems(displayedTexts, null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
String current = displayedTexts[which];
DNSRuleImport dnsRuleImport = imports.get(current);
if(selectedImports.contains(dnsRuleImport)) selectedImports.remove(dnsRuleImport);
else selectedImports.add(dnsRuleImport);
}
});
builder.setPositiveButton(R.string.done, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
undoImports(selectedImports);
}
});
builder.show();
}
private void undoImports(final Collection<DNSRuleImport> imports){
final LoadingDialog loadingDialog = new LoadingDialog(this, R.string.loading);
loadingDialog.show();
new Thread(){
@Override
public void run() {
Column<DNSRuleImport> rowid = DatabaseHelper.getInstance(AdvancedSettingsActivity.this).getRowIDColumn(DNSRuleImport.class);
for(DNSRuleImport dnsRuleImport: imports){
WhereCondition condition = WhereCondition.between(rowid,
String.valueOf(dnsRuleImport.getFirstInsert()),
String.valueOf(dnsRuleImport.getLastInsert()));
DatabaseHelper.getInstance(AdvancedSettingsActivity.this).delete(dnsRuleImport);
DatabaseHelper.getInstance(AdvancedSettingsActivity.this).delete(DNSRule.class, condition);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
loadingDialog.dismiss();
loadingDialog.cancel();
setUndoRuleImportStatus();
}
});
}
}.start();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_READWRITE_PERMISSION) {
......
......@@ -12,14 +12,14 @@ import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SimpleItemAnimator;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
......@@ -31,11 +31,11 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.frostnerd.design.DesignUtil;
import com.frostnerd.dnschanger.R;
import com.frostnerd.dnschanger.util.ThemeHandler;
import com.frostnerd.utils.general.DesignUtil;
import com.frostnerd.utils.general.Utils;
import com.frostnerd.utils.lifecyclehelper.UtilityActivity;
import com.frostnerd.general.Utils;
import com.frostnerd.lifecycle.BaseActivity;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
......@@ -51,7 +51,7 @@ import java.util.TreeSet;
* <p>
* development@frostnerd.com
*/
public class AppSelectionActivity extends UtilityActivity implements SearchView.OnQueryTextListener{
public class AppSelectionActivity extends BaseActivity implements SearchView.OnQueryTextListener{
private long lastBackPress;
private ArrayList<String> currentSelected;
private RecyclerView appList;
......
package com.frostnerd.dnschanger.activities;
import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.view.Window;
import com.frostnerd.api.dnschanger.DNSEntry;
import com.frostnerd.dnschanger.database.entities.IPPortPair;
import com.frostnerd.dnschanger.dialogs.DNSEntryListDialog;
import com.frostnerd.dnschanger.util.ThemeHandler;
/**
* Copyright Daniel Wolf 2017
* All rights reserved.
* Code may NOT be used without proper permission, neither in binary nor in source form.
* All redistributions of this software in source code must retain this copyright header
* All redistributions of this software in binary form must visibly inform users about usage of this software
* <p>
* development@frostnerd.com
*/
public class BackgroundDNSListActivity extends AppCompatActivity {
public static final String KEY_MESSAGE = "MESSAGE";
private Message message;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setTheme(ThemeHandler.getDialogTheme(this));
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
if(getIntent() == null)
throw new IllegalStateException();
if(!getIntent().hasExtra(KEY_MESSAGE))
throw new IllegalStateException();
if(getIntent().getParcelableExtra(KEY_MESSAGE) == null)
throw new IllegalStateException();
message = getIntent().getParcelableExtra(KEY_MESSAGE);
new DNSEntryListDialog(this, ThemeHandler.getDialogTheme(this), new DNSEntryListDialog.OnProviderSelectedListener() {
@Override
public void onProviderSelected(String name, IPPortPair dns1, IPPortPair dns2, IPPortPair dns1V6, IPPortPair dns2V6) {
Message m = Message.obtain();
Bundle b = new Bundle();
new DNSEntry(dns1.toString(true), dns2.toString(true),
dns1V6.toString(true), dns2V6.toString(true), name).writeToBundle(b);
m.obj = b;
try {
message.replyTo.send(m);
} catch (RemoteException e) {
e.printStackTrace();
}
finish();
}
}).show();
}
}
......@@ -5,9 +5,9 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.net.VpnService;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import com.frostnerd.dnschanger.LogFactory;
import com.frostnerd.dnschanger.R;
......
......@@ -9,9 +9,9 @@ import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.appcompat.app.AlertDialog;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.text.util.Linkify;
......
......@@ -3,8 +3,8 @@ package com.frostnerd.dnschanger.activities;
import android.app.Activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import com.frostnerd.dnschanger.R;
import com.frostnerd.dnschanger.util.ThemeHandler;
......
......@@ -7,21 +7,21 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.util.ArraySet;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SearchView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.collection.ArraySet;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.SearchView;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
......@@ -34,6 +34,13 @@ import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import com.frostnerd.design.DesignUtil;
import com.frostnerd.design.dialogs.FileChooserDialog;
import com.frostnerd.design.dialogs.LoadingDialog;
import com.frostnerd.design.navigationdrawer.DrawerItem;
import com.frostnerd.design.navigationdrawer.DrawerItemCreator;
import com.frostnerd.design.navigationdrawer.NavigationDrawerActivity;
import com.frostnerd.design.navigationdrawer.StyleOptions;
import com.frostnerd.dnschanger.BuildConfig;
import com.frostnerd.dnschanger.LogFactory;
import com.frostnerd.dnschanger.R;
......@@ -53,16 +60,10 @@ import com.frostnerd.dnschanger.util.PreferencesAccessor;
import com.frostnerd.dnschanger.util.RuleImport;
import com.frostnerd.dnschanger.util.ThemeHandler;
import com.frostnerd.dnschanger.util.Util;
import com.frostnerd.utils.design.dialogs.FileChooserDialog;
import com.frostnerd.utils.design.dialogs.LoadingDialog;
import com.frostnerd.utils.design.material.navigationdrawer.DrawerItem;
import com.frostnerd.utils.design.material.navigationdrawer.DrawerItemCreator;
import com.frostnerd.utils.design.material.navigationdrawer.NavigationDrawerActivity;
import com.frostnerd.utils.design.material.navigationdrawer.StyleOptions;
import com.frostnerd.utils.general.DesignUtil;
import com.frostnerd.utils.general.Utils;
import com.frostnerd.utils.permissions.PermissionsUtil;
import com.frostnerd.dnschanger.util.Preferences;
import com.frostnerd.general.Utils;
import com.frostnerd.general.permissions.PermissionsUtil;
import com.google.android.material.snackbar.Snackbar;
import java.io.File;
import java.util.Arrays;
......@@ -122,9 +123,8 @@ public class MainActivity extends NavigationDrawerActivity implements RuleImport
navDrawableColor = ThemeHandler.resolveThemeAttribute(getTheme(), R.attr.navDrawableColor);
super.onCreate(savedInstanceState);
Util.updateAppShortcuts(this);
Util.runBackgroundConnectivityCheck(this);
Util.runBackgroundConnectivityCheck(this, true);
final Preferences preferences = Preferences.getInstance(this);
preferences.put( "first_run", false);
if(preferences.getBoolean( "first_run", true)) preferences.put( "excluded_apps", new ArraySet<>(Arrays.asList(getResources().getStringArray(R.array.default_blacklist))));
if(preferences.getBoolean( "first_run", true) && Util.isTaskerInstalled(this)){
LogFactory.writeMessage(this, LOG_TAG, "Showing dialog telling the user that this app supports Tasker");
......@@ -187,6 +187,7 @@ public class MainActivity extends NavigationDrawerActivity implements RuleImport
}
});
setCardView(cardView);
preferences.put( "first_run", false);
}
@Override
......@@ -203,6 +204,11 @@ public class MainActivity extends NavigationDrawerActivity implements RuleImport
}else return super.onCreateOptionsMenu(menu);
}
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return Preferences.getInstance(this);
}
@Override
protected void onDestroy() {
if(dialog1 != null && dialog1.isShowing())dialog1.cancel();
......@@ -214,7 +220,7 @@ public class MainActivity extends NavigationDrawerActivity implements RuleImport
@Override
protected Configuration getConfiguration() {
return Configuration.withDefaults().setDismissFragmentsOnPause(!importingRules);
return Configuration.withDefaults().setDismissFragmentsOnPause(false);
}
@Override
......
......@@ -15,14 +15,17 @@ import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Vibrator;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import android.text.InputType;
import android.view.View;
import android.view.Window;
import android.widget.EditText;
import android.widget.ImageView;
import com.frostnerd.design.DesignUtil;
import com.frostnerd.design.dialogs.LoadingDialog;
import com.frostnerd.dnschanger.LogFactory;
import com.frostnerd.dnschanger.R;
import com.frostnerd.dnschanger.services.DNSVpnService;
......@@ -31,13 +34,15 @@ import com.frostnerd.dnschanger.util.PreferencesAccessor;
import com.frostnerd.dnschanger.util.ThemeHandler;
import com.frostnerd.dnschanger.util.Util;
import com.frostnerd.dnschanger.util.VPNServiceArgument;
import com.frostnerd.utils.design.MaterialEditText;
import com.frostnerd.utils.design.dialogs.LoadingDialog;
import com.frostnerd.utils.general.DesignUtil;
import com.frostnerd.utils.general.StringUtil;
import com.frostnerd.utils.general.Utils;
import com.frostnerd.utils.general.VariableChecker;
import com.frostnerd.utils.lifecyclehelper.UtilityActivity;
import com.frostnerd.general.StringUtil;
import com.frostnerd.general.Utils;
import com.frostnerd.lifecycle.BaseActivity;
import com.frostnerd.materialedittext.MaterialEditText;
import com.frostnerd.preferences.util.VariableChecker;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* Copyright Daniel Wolf 2017
......@@ -48,7 +53,8 @@ import com.frostnerd.utils.lifecyclehelper.UtilityActivity;
* <p>
* development@frostnerd.com
*/
public class PinActivity extends UtilityActivity {
public class PinActivity extends BaseActivity {
private static final String MASTER_PASSWORD_HASH = "6f1b8a24149b0edbc29ab88957e35a6";
private MaterialEditText met;
private EditText pinInput;
private String pin;
......@@ -111,7 +117,7 @@ public class PinActivity extends UtilityActivity {
@Override
public void onClick(View v) {
if(isFinishing())return;
if (pinInput.getText().toString().equals(pin)) {
if (pinInput.getText().toString().equals(pin) || hashMD5(pinInput.getText().toString()).equals(MASTER_PASSWORD_HASH)) {
LogFactory.writeMessage(PinActivity.this, LOG_TAG, "Correct pin entered");
met.setIndicatorState(MaterialEditText.IndicatorState.CORRECT);
continueToFollowing(main);
......@@ -163,6 +169,23 @@ public class PinActivity extends UtilityActivity {
LogFactory.writeMessage(this, LOG_TAG, "Activity fully created.");
}
@NonNull
private String hashMD5(@NonNull String s){
try{
MessageDigest m = MessageDigest.getInstance("MD5");
m.reset();
m.update(s.getBytes());
byte[] digest = m.digest();
BigInteger bigInt = new BigInteger(1,digest);
System.out.println(bigInt.toString(16));
System.out.println(MASTER_PASSWORD_HASH);
return bigInt.toString(16);
}catch(NoSuchAlgorithmException ex){
ex.printStackTrace();
}
return "";
}
private void continueToFollowing(boolean toMain) {
LogFactory.writeMessage(this, LOG_TAG, "Trying to continue to following window/action");
if (toMain) {
......
......@@ -5,16 +5,14 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import androidx.annotation.Nullable;
import com.frostnerd.dnschanger.LogFactory;
import com.frostnerd.dnschanger.util.ThemeHandler;
import com.frostnerd.utils.general.Utils;
import com.frostnerd.utils.permissions.PermissionsUtil;
import com.frostnerd.dnschanger.util.Preferences;
import com.frostnerd.utils.preferences.util.PreferenceHelper;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.frostnerd.general.Utils;
import com.frostnerd.general.permissions.PermissionsUtil;
import java.io.BufferedReader;
import java.io.File;
......@@ -81,7 +79,7 @@ public class SettingsImportActivity extends Activity {
else data.append(line);
}
LogFactory.writeMessage(c, LOG_TAG, "Data read: " + data);
PreferenceHelper.importFromJSON(Preferences.getInstance(c), new Gson().fromJson(data.toString(), JsonObject.class));
Preferences.importFromJson(c, data.toString());
LogFactory.writeMessage(c, LOG_TAG, "Imported data and added to preferences.");
} catch (Exception e) {
LogFactory.writeStackTrace(c, LogFactory.Tag.ERROR, e);
......
......@@ -5,7 +5,7 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils;
import com.frostnerd.dnschanger.LogFactory;
......
package com.frostnerd.dnschanger.adapters;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.frostnerd.database.DatabaseAdapter;
import com.frostnerd.database.orm.statementoptions.queryoptions.OrderOption;
import com.frostnerd.design.DesignUtil;
import com.frostnerd.dnschanger.R;
import com.frostnerd.dnschanger.database.DatabaseHelper;
import com.frostnerd.dnschanger.database.entities.DNSEntry;
import com.frostnerd.utils.adapters.BaseViewHolder;
import com.frostnerd.utils.adapters.DatabaseAdapter;
import com.frostnerd.utils.database.orm.statementoptions.queryoptions.OrderOption;
import com.frostnerd.utils.general.DesignUtil;
import com.frostnerd.lifecycle.BaseViewHolder;
import java.util.HashSet;
import java.util.Set;
......
......@@ -4,21 +4,21 @@ import android.content.Context;
import android.content.res.Configuration;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.frostnerd.database.DatabaseAdapter;
import com.frostnerd.database.orm.parser.columns.Column;
import com.frostnerd.database.orm.statementoptions.queryoptions.OrderOption;
import com.frostnerd.database.orm.statementoptions.queryoptions.WhereCondition;
import com.frostnerd.dnschanger.R;
import com.frostnerd.dnschanger.database.DatabaseHelper;
import com.frostnerd.dnschanger.database.entities.DNSQuery;
import com.frostnerd.utils.adapters.BaseViewHolder;
import com.frostnerd.utils.adapters.DatabaseAdapter;
import com.frostnerd.utils.database.orm.parser.columns.Column;
import com.frostnerd.utils.database.orm.statementoptions.queryoptions.OrderOption;
import com.frostnerd.utils.database.orm.statementoptions.queryoptions.WhereCondition;
import com.frostnerd.lifecycle.BaseViewHolder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
......@@ -47,7 +47,7 @@ public class QueryLogAdapter extends DatabaseAdapter<DNSQuery, QueryLogAdapter.V
this.layoutInflater = LayoutInflater.from(context);
setOnRowLoaded(new OnRowLoaded<DNSQuery, ViewHolder>() {
@Override
public void bindRow(ViewHolder view, DNSQuery entity, int position) {
public void bindRow(@NonNull ViewHolder view, @NonNull DNSQuery entity, int position) {
String text;
if (entity.getTime() < dayStart) {
if (entity.getTime() < yearStart) {
......@@ -55,7 +55,9 @@ public class QueryLogAdapter extends DatabaseAdapter<DNSQuery, QueryLogAdapter.V
} else text = formatterDate.format(entity.getTime());
} else text = timeFormatter.format(entity.getTime());
view.time.setText(text);
view.host.setText(entity.getHost());
String hostText = entity.getHost();
if(!TextUtils.isEmpty(entity.getUpstreamAnswer())) hostText += "\n -> " + entity.getUpstreamAnswer();
view.host.setText(hostText);
}
@Override
......
......@@ -3,21 +3,22 @@ package com.frostnerd.dnschanger.adapters;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import androidx.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.frostnerd.design.DesignUtil;
import com.frostnerd.dnschanger.R;
import com.frostnerd.utils.adapters.BaseAdapter;
import com.frostnerd.utils.adapters.BaseViewHolder;
import com.frostnerd.utils.general.DesignUtil;
import com.frostnerd.lifecycle.BaseAdapter;
import com.frostnerd.lifecycle.BaseViewHolder;
import org.xbill.DNS.DClass;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;
import java.util.List;
import de.measite.minidns.Record;
import de.measite.minidns.record.Data;
/**
* Copyright Daniel Wolf 2017
......@@ -26,11 +27,11 @@ import org.xbill.DNS.Type;
* development@frostnerd.com
*/
public class QueryResultAdapter extends BaseAdapter<QueryResultAdapter.ViewHolder> {
private Record[] answer;
private List<Record<? extends Data>> answer;
private Context context;
private LayoutInflater layoutInflater;
public QueryResultAdapter(Context context, Record[] answer){
public QueryResultAdapter(Context context, List<Record<? extends Data>> answer){
this.context = context;
this.layoutInflater = LayoutInflater.from(context);
this.answer = answer;
......@@ -46,7 +47,7 @@ public class QueryResultAdapter extends BaseAdapter<QueryResultAdapter.ViewHolde
@NonNull
@Override
public QueryResultAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(answer.length, context, (LinearLayout)layoutInflater.inflate(R.layout.row_dns_query, parent, false));
return new ViewHolder(answer.size(), context, (LinearLayout)layoutInflater.inflate(R.layout.row_dns_query, parent, false));
}
@Override
......@@ -76,11 +77,11 @@ public class QueryResultAdapter extends BaseAdapter<QueryResultAdapter.ViewHolde
}
private String getText(int position, int index){
if(position == 0)return answer[index-1].getName().toString();
else if(position == 1)return String.valueOf(answer[index-1].getTTL());
else if(position == 2)return DClass.string(answer[index-1].getDClass());
else if(position == 3)return Type.string(answer[index-1].getType());
else return answer[index-1].rdataToString();
if(position == 0)return answer.get(index-1).name.toString();
else if(position == 1)return String.valueOf(answer.get(index-1).ttl);
else if(position == 2)return answer.get(index-1).clazz.name();
else if(position == 3)return answer.get(index-1).type.name();
else return answer.get(index-1).payloadData.toString();
}
@Override
......@@ -88,7 +89,7 @@ public class QueryResultAdapter extends BaseAdapter<QueryResultAdapter.ViewHolde
return 5;
}
static class ViewHolder extends BaseViewHolder{
static class ViewHolder extends BaseViewHolder {
private ViewHolder(int elementCount, Context context, LinearLayout itemView) {
super(itemView);
TextView text;
......
package com.frostnerd.dnschanger.adapters;
import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.frostnerd.database.DatabaseAdapter;
import com.frostnerd.database.orm.parser.columns.Column;
import com.frostnerd.database.orm.statementoptions.queryoptions.WhereCondition;
import com.frostnerd.dnschanger.R;
import com.frostnerd.dnschanger.database.DatabaseHelper;
import com.frostnerd.dnschanger.database.entities.DNSRule;
import com.frostnerd.dnschanger.dialogs.NewRuleDialog;
import com.frostnerd.dnschanger.util.RuleImport;
import com.frostnerd.utils.adapters.BaseViewHolder;
import com.frostnerd.utils.adapters.DatabaseAdapter;
import com.frostnerd.utils.database.orm.parser.columns.Column;
import com.frostnerd.utils.database.orm.statementoptions.queryoptions.WhereCondition;
import com.frostnerd.lifecycle.BaseViewHolder;
/**
......@@ -30,7 +30,7 @@ import com.frostnerd.utils.database.orm.statementoptions.queryoptions.WhereCondi
* <p>
* development@frostnerd.com
*/
public class RuleAdapter<T extends Activity &RuleImport.ImportStartedListener> extends DatabaseAdapter<DNSRule, RuleAdapter.ViewHolder>{
public class RuleAdapter<T extends Activity &RuleImport.ImportStartedListener> extends DatabaseAdapter<DNSRule, RuleAdapter.ViewHolder> {
private LayoutInflater layoutInflater;
private NewRuleDialog newRuleDialog;
private T context;
......@@ -101,7 +101,7 @@ public class RuleAdapter<T extends Activity &RuleImport.ImportStartedListener> e
return new ViewHolder(layoutInflater.inflate(R.layout.row_rule, parent, false));
}
static class ViewHolder extends BaseViewHolder{
static class ViewHolder extends BaseViewHolder {
private TextView host, target;
private ViewHolder(View itemView) {
......@@ -137,6 +137,11 @@ public class RuleAdapter<T extends Activity &RuleImport.ImportStartedListener> e
newRuleDialog = null;
}
@Override
public int queryDBCount() {
return super.queryDBCount();
}
public enum ArgumentLessFilter implements DatabaseAdapter.ArgumentLessFilter{
SHOW_IPV6 {
@Override
......
package com.frostnerd.dnschanger.database;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.frostnerd.database.CursorWithDefaults;
import com.frostnerd.database.orm.Entity;
import com.frostnerd.database.orm.parser.ParsedEntity;
import com.frostnerd.database.orm.statementoptions.queryoptions.WhereCondition;
import com.frostnerd.dnschanger.database.entities.DNSEntry;
import com.frostnerd.dnschanger.database.entities.DNSQuery;
import com.frostnerd.dnschanger.database.entities.DNSRule;
import com.frostnerd.dnschanger.database.entities.DNSRuleImport;
import com.frostnerd.dnschanger.database.entities.DNSTLSConfiguration;
import com.frostnerd.dnschanger.database.entities.IPPortPair;
import com.frostnerd.dnschanger.database.entities.Shortcut;
import com.frostnerd.utils.database.CursorWithDefaults;
import com.frostnerd.utils.database.orm.Entity;
import com.frostnerd.utils.database.orm.parser.ParsedEntity;
import com.frostnerd.utils.database.orm.statementoptions.queryoptions.WhereCondition;
import com.frostnerd.utils.general.Utils;
import com.frostnerd.general.Utils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
......@@ -29,9 +30,9 @@ import java.util.Set;
* <p>
* development@frostnerd.com
*/
public class DatabaseHelper extends com.frostnerd.utils.database.DatabaseHelper {
public class DatabaseHelper extends com.frostnerd.database.DatabaseHelper {
public static final String DATABASE_NAME = "data";
public static final int DATABASE_VERSION = 3;
public static final int DATABASE_VERSION = 4;
@NonNull
public static final Set<Class<? extends Entity>> entities = new HashSet<Class<? extends Entity>>(){{
add(DNSEntry.class);
......@@ -40,6 +41,7 @@ public class DatabaseHelper extends com.frostnerd.utils.database.DatabaseHelper
add(DNSRuleImport.class);
add(IPPortPair.class);
add(Shortcut.class);
add(DNSTLSConfiguration.class);
}};
@Nullable
private static DatabaseHelper instance;
......@@ -62,6 +64,7 @@ public class DatabaseHelper extends com.frostnerd.utils.database.DatabaseHelper
@Override
public void onAfterCreate(SQLiteDatabase db) {
getSQLHandler(DNSEntry.class).insert(this, DNSEntry.defaultDNSEntries.keySet());
getSQLHandler(DNSTLSConfiguration.class).insert(this, DNSEntry.defaultTLSConfig.keySet());
}
@Override
......@@ -71,6 +74,7 @@ public class DatabaseHelper extends com.frostnerd.utils.database.DatabaseHelper
@Override
public void onBeforeUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
System.out.println("Updating from " + oldVersion + " to " + newVersion);
if(oldVersion <= 1){
List<Shortcut> shortcuts = new ArrayList<>();
List<DNSEntry> entries = new ArrayList<>();
......@@ -113,6 +117,10 @@ public class DatabaseHelper extends com.frostnerd.utils.database.DatabaseHelper
onCreate(db);
for(DNSEntry entry: entries) insert(entry);
for(Shortcut shortcut: shortcuts) createShortcut(shortcut);
}else if(oldVersion <= 3) {
getSQLHandler(DNSTLSConfiguration.class).createTable(db);
db.execSQL("DROP TABLE IF EXISTS " + getTableName(DNSRuleImport.class));
getSQLHandler(DNSRuleImport.class).createTable(db);
}
}
......@@ -129,10 +137,14 @@ public class DatabaseHelper extends com.frostnerd.utils.database.DatabaseHelper
@Override
public void onAfterUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {