mirror of
https://github.com/M66B/NetGuard.git
synced 2025-02-23 06:41:05 +00:00
Submit settings
This commit is contained in:
parent
c23b03c275
commit
ab319fa2e2
6 changed files with 241 additions and 16 deletions
16
app/app.iml
16
app/app.iml
|
@ -104,14 +104,6 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/renderscript" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/renderscript" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
|
@ -120,6 +112,14 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/renderscript" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/renderscript" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/binaries" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
||||
|
|
|
@ -117,6 +117,11 @@
|
|||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".ServiceJob"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||
|
||||
<receiver
|
||||
android:name=".Receiver"
|
||||
android:label="@string/app_name">
|
||||
|
|
|
@ -546,10 +546,10 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> im
|
|||
PackageManager pm = context.getPackageManager();
|
||||
Cursor cursor = (Cursor) badapter.getItem(bposition);
|
||||
final long id = cursor.getLong(cursor.getColumnIndex("ID"));
|
||||
int version = cursor.getInt(cursor.getColumnIndex("version"));
|
||||
int protocol = cursor.getInt(cursor.getColumnIndex("protocol"));
|
||||
String daddr = cursor.getString(cursor.getColumnIndex("daddr"));
|
||||
int dport = cursor.getInt(cursor.getColumnIndex("dport"));
|
||||
final int version = cursor.getInt(cursor.getColumnIndex("version"));
|
||||
final int protocol = cursor.getInt(cursor.getColumnIndex("protocol"));
|
||||
final String daddr = cursor.getString(cursor.getColumnIndex("daddr"));
|
||||
final int dport = cursor.getInt(cursor.getColumnIndex("dport"));
|
||||
long time = cursor.getLong(cursor.getColumnIndex("time"));
|
||||
int block = cursor.getInt(cursor.getColumnIndex("block"));
|
||||
|
||||
|
@ -593,6 +593,8 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> im
|
|||
if (IAB.isPurchased(ActivityPro.SKU_FILTER, context)) {
|
||||
DatabaseHelper.getInstance(context).setAccess(id, 0);
|
||||
ServiceSinkhole.reload("allow host", context);
|
||||
if (ServiceJob.can(context))
|
||||
ServiceJob.submit(rule, version, protocol, daddr, dport, 0, context);
|
||||
} else
|
||||
context.startActivity(new Intent(context, ActivityPro.class));
|
||||
return true;
|
||||
|
@ -601,6 +603,8 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> im
|
|||
if (IAB.isPurchased(ActivityPro.SKU_FILTER, context)) {
|
||||
DatabaseHelper.getInstance(context).setAccess(id, 1);
|
||||
ServiceSinkhole.reload("block host", context);
|
||||
if (ServiceJob.can(context))
|
||||
ServiceJob.submit(rule, version, protocol, daddr, dport, 1, context);
|
||||
} else
|
||||
context.startActivity(new Intent(context, ActivityPro.class));
|
||||
return true;
|
||||
|
@ -608,6 +612,8 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> im
|
|||
case R.id.menu_reset:
|
||||
DatabaseHelper.getInstance(context).setAccess(id, -1);
|
||||
ServiceSinkhole.reload("reset host", context);
|
||||
if (ServiceJob.can(context))
|
||||
ServiceJob.submit(rule, version, protocol, daddr, dport, -1, context);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -734,6 +740,9 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> im
|
|||
NotificationManagerCompat.from(context).cancel(rule.info.applicationInfo.uid);
|
||||
ServiceSinkhole.reload("rule changed", context);
|
||||
}
|
||||
|
||||
if (ServiceJob.can(context))
|
||||
ServiceJob.submit(rule, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
196
app/src/main/java/eu/faircode/netguard/ServiceJob.java
Normal file
196
app/src/main/java/eu/faircode/netguard/ServiceJob.java
Normal file
|
@ -0,0 +1,196 @@
|
|||
package eu.faircode.netguard;
|
||||
|
||||
/*
|
||||
This file is part of NetGuard.
|
||||
|
||||
NetGuard is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
NetGuard is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with NetGuard. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2015-2016 by Marcel Bokhorst (M66B)
|
||||
*/
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.job.JobInfo;
|
||||
import android.app.job.JobParameters;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.app.job.JobService;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.PersistableBundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URL;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public class ServiceJob extends JobService {
|
||||
private static int id = 0;
|
||||
private static final String TAG = "NetGuard.Job";
|
||||
|
||||
private static final String cUrl = "https://crowd.netguard.me/";
|
||||
private static final int cTimeOutMs = 15000;
|
||||
|
||||
@Override
|
||||
public boolean onStartJob(JobParameters params) {
|
||||
Log.i(TAG, "Execute job=" + params.getJobId());
|
||||
|
||||
new AsyncTask<JobParameters, Object, Object>() {
|
||||
|
||||
@Override
|
||||
protected JobParameters doInBackground(JobParameters... params) {
|
||||
Log.i(TAG, "Start job=" + params[0].getJobId());
|
||||
|
||||
HttpsURLConnection urlConnection = null;
|
||||
try {
|
||||
String android_id = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("android_id", Util.sha256(android_id, ""));
|
||||
json.put("android_sdk", Build.VERSION.SDK_INT);
|
||||
json.put("netguard", Util.getSelfVersionCode(ServiceJob.this));
|
||||
for (String name : params[0].getExtras().keySet())
|
||||
json.put(name, params[0].getExtras().get(name));
|
||||
|
||||
urlConnection = (HttpsURLConnection) new URL(cUrl).openConnection();
|
||||
urlConnection.setConnectTimeout(cTimeOutMs);
|
||||
urlConnection.setReadTimeout(cTimeOutMs);
|
||||
urlConnection.setRequestProperty("Accept", "application/json");
|
||||
urlConnection.setRequestProperty("Content-type", "application/json");
|
||||
urlConnection.setRequestMethod("POST");
|
||||
urlConnection.setDoInput(true);
|
||||
urlConnection.setDoOutput(true);
|
||||
|
||||
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
|
||||
out.write(json.toString().getBytes()); // UTF-8
|
||||
out.flush();
|
||||
|
||||
int code = urlConnection.getResponseCode();
|
||||
if (code != HttpsURLConnection.HTTP_OK)
|
||||
throw new IOException("HTTP " + code);
|
||||
|
||||
InputStreamReader isr = new InputStreamReader(urlConnection.getInputStream());
|
||||
String response = read(isr);
|
||||
Log.i(TAG, "Response=" + response);
|
||||
|
||||
jobFinished(params[0], false);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
jobFinished(params[0], true);
|
||||
} finally {
|
||||
if (urlConnection != null)
|
||||
urlConnection.disconnect();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}.execute(params);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStopJob(JobParameters params) {
|
||||
Log.i(TAG, "Start job=" + params.getJobId());
|
||||
return true;
|
||||
}
|
||||
|
||||
private String read(InputStreamReader reader) {
|
||||
StringBuilder sb = new StringBuilder(2048);
|
||||
char[] read = new char[128];
|
||||
try {
|
||||
for (int i; (i = reader.read(read)) >= 0; sb.append(read, 0, i)) ;
|
||||
} catch (Throwable ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean can(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
return (prefs.getBoolean("submit", true) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);
|
||||
}
|
||||
|
||||
public static void submit(Rule rule, Context context) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
|
||||
PersistableBundle bundle = new PersistableBundle();
|
||||
bundle.putString("type", "rule");
|
||||
bundle.putString("package", rule.info.packageName);
|
||||
bundle.putString("label", rule.info.applicationInfo.loadLabel(pm).toString());
|
||||
|
||||
bundle.putInt("wifi_default", rule.wifi_default ? 1 : 0);
|
||||
bundle.putInt("other_default", rule.other_default ? 1 : 0);
|
||||
bundle.putInt("screen_wifi_default", rule.screen_wifi_default ? 1 : 0);
|
||||
bundle.putInt("screen_other_default", rule.screen_other_default ? 1 : 0);
|
||||
bundle.putInt("roaming_default", rule.roaming_default ? 1 : 0);
|
||||
|
||||
bundle.putInt("wifi_blocked", rule.wifi_blocked ? 1 : 0);
|
||||
bundle.putInt("other_blocked", rule.other_blocked ? 1 : 0);
|
||||
bundle.putInt("screen_wifi", rule.screen_wifi ? 1 : 0);
|
||||
bundle.putInt("screen_other", rule.screen_other ? 1 : 0);
|
||||
bundle.putInt("roaming", rule.roaming ? 1 : 0);
|
||||
|
||||
bundle.putInt("apply", rule.apply ? 1 : 0);
|
||||
bundle.putInt("notify", rule.notify ? 1 : 0);
|
||||
|
||||
submit(bundle, context);
|
||||
}
|
||||
|
||||
public static void submit(Rule rule, int version, int protocol, String daddr, int dport, int access, Context context) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
|
||||
PersistableBundle bundle = new PersistableBundle();
|
||||
bundle.putString("type", "host");
|
||||
bundle.putString("package", rule.info.packageName);
|
||||
bundle.putString("label", rule.info.applicationInfo.loadLabel(pm).toString());
|
||||
|
||||
bundle.putInt("version", version);
|
||||
bundle.putInt("protocol", protocol);
|
||||
bundle.putString("daddr", daddr);
|
||||
bundle.putInt("dport", dport);
|
||||
bundle.putInt("access", access);
|
||||
|
||||
submit(bundle, context);
|
||||
}
|
||||
|
||||
private static void submit(PersistableBundle bundle, Context context) {
|
||||
ComponentName serviceName = new ComponentName(context, ServiceJob.class);
|
||||
JobInfo job = new JobInfo.Builder(++id, serviceName)
|
||||
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
|
||||
.setRequiresDeviceIdle(!Util.isDebuggable(context))
|
||||
.setExtras(bundle)
|
||||
.setPersisted(true)
|
||||
.build();
|
||||
|
||||
JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
|
||||
scheduler.schedule(job);
|
||||
|
||||
Log.i(TAG, "Scheduled job=" + job.getId());
|
||||
}
|
||||
}
|
|
@ -1352,6 +1352,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
boolean screen = (metered ? rule.screen_other : rule.screen_wifi);
|
||||
if ((!blocked || (screen && last_interactive)) && (!metered || !(rule.roaming && roaming)))
|
||||
listAllowed.add(rule);
|
||||
else if (rule.info.applicationInfo.uid == Process.myUid())
|
||||
if (prefs.getBoolean("submit", true))
|
||||
listAllowed.add(rule);
|
||||
}
|
||||
|
||||
Log.i(TAG, "Allowed " + listAllowed.size() + " of " + listRule.size());
|
||||
|
@ -1405,6 +1408,11 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
// Called from native code
|
||||
private boolean isDomainBlocked(String name) {
|
||||
if ("crowd.netguard.me".equals(name)) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
if (prefs.getBoolean("submit", true))
|
||||
return false;
|
||||
}
|
||||
return (mapHostsBlocked.containsKey(name) && mapHostsBlocked.get(name));
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.net.ConnectivityManagerCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
|
@ -60,12 +59,9 @@ import java.io.OutputStream;
|
|||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InterfaceAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.URL;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
@ -111,6 +107,17 @@ public class Util {
|
|||
}
|
||||
}
|
||||
|
||||
public static String sha256(String text, String salt) throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
byte[] bytes = (text + salt).getBytes("UTF-8");
|
||||
digest.update(bytes, 0, bytes.length);
|
||||
bytes = digest.digest();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : bytes)
|
||||
sb.append(String.format("%02X", b));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean isConnected(Context context) {
|
||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo ni = (cm == null ? null : cm.getActiveNetworkInfo());
|
||||
|
|
Loading…
Reference in a new issue