Store access version/protocol

Refs #284
This commit is contained in:
M66B 2016-02-05 20:44:12 +01:00
parent f01138caeb
commit 4f263330d2
7 changed files with 110 additions and 44 deletions

View File

@ -38,6 +38,8 @@ import java.text.SimpleDateFormat;
public class AccessAdapter extends CursorAdapter {
private static String TAG = "NetGuard.Access";
private int colVersion;
private int colProtocol;
private int colDaddr;
private int colDPort;
private int colTime;
@ -50,6 +52,8 @@ public class AccessAdapter extends CursorAdapter {
public AccessAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
colVersion = cursor.getColumnIndex("version");
colProtocol = cursor.getColumnIndex("protocol");
colDaddr = cursor.getColumnIndex("daddr");
colDPort = cursor.getColumnIndex("dport");
colTime = cursor.getColumnIndex("time");
@ -78,8 +82,10 @@ public class AccessAdapter extends CursorAdapter {
@Override
public void bindView(final View view, final Context context, final Cursor cursor) {
// Get values
int version = cursor.getInt(colVersion);
int protocol = cursor.getInt(colProtocol);
String daddr = cursor.getString(colDaddr);
int dport = (cursor.isNull(colDPort) ? -1 : cursor.getInt(colDPort));
int dport = cursor.getInt(colDPort);
long time = cursor.getLong(colTime);
int allowed = cursor.getInt(colAllowed);
int block = cursor.getInt(colBlock);
@ -100,7 +106,9 @@ public class AccessAdapter extends CursorAdapter {
DrawableCompat.setTint(wrap, block > 0 ? colorOff : colorOn);
}
}
tvDest.setText(daddr + (dport > 0 ? ":" + dport : ""));
tvDest.setText(
Util.getProtocolName(protocol, version, true) + " " +
daddr + (dport > 0 ? ":" + dport : ""));
if (allowed < 0)
tvDest.setTextColor(colorText);

View File

@ -940,6 +940,8 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
DatabaseHelper dh = new DatabaseHelper(this);
Cursor cursor = dh.getAccess();
int colUid = cursor.getColumnIndex("uid");
int colVersion = cursor.getColumnIndex("version");
int colProtocol = cursor.getColumnIndex("protocol");
int colDAddr = cursor.getColumnIndex("daddr");
int colDPort = cursor.getColumnIndex("dport");
int colTime = cursor.getColumnIndex("time");
@ -954,6 +956,8 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
for (String pkg : pkgs) {
serializer.startTag(null, "rule");
serializer.attribute(null, "pkg", pkg);
serializer.attribute(null, "version", Integer.toString(cursor.getInt(colVersion)));
serializer.attribute(null, "protocol", Integer.toString(cursor.getInt(colProtocol)));
serializer.attribute(null, "daddr", cursor.getString(colDAddr));
serializer.attribute(null, "dport", Integer.toString(cursor.getInt(colDPort)));
serializer.attribute(null, "time", Long.toString(cursor.getLong(colTime)));
@ -972,6 +976,7 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
SinkholeService.stop("import", this);
DatabaseHelper dh = new DatabaseHelper(this);
dh.clearAccess();
try {
XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
XmlImportHandler handler = new XmlImportHandler(this, dh);
@ -1114,7 +1119,12 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
} else if (qName.equals("rule")) {
String pkg = attributes.getValue("pkg");
String version = attributes.getValue("version");
String protocol = attributes.getValue("protocol");
Packet packet = new Packet();
packet.version = (version == null ? 4 : Integer.parseInt(version));
packet.protocol = (protocol == null ? 6 /* TCP */ : Integer.parseInt(protocol));
packet.daddr = attributes.getValue("daddr");
packet.dport = Integer.parseInt(attributes.getValue("dport"));
packet.time = Long.parseLong(attributes.getValue("time"));

View File

@ -40,7 +40,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "NetGuard.Database";
private static final String DB_NAME = "Netguard";
private static final int DB_VERSION = 14;
private static final int DB_VERSION = 15;
private static boolean once = true;
private static List<LogChangedListener> logChangedListeners = new ArrayList<>();
@ -131,13 +131,15 @@ public class DatabaseHelper extends SQLiteOpenHelper {
db.execSQL("CREATE TABLE access (" +
" ID INTEGER PRIMARY KEY AUTOINCREMENT" +
", uid INTEGER NOT NULL" +
", version INTEGER NOT NULL" +
", protocol INTEGER NOT NULL" +
", daddr TEXT NOT NULL" +
", dport INTEGER NULL" +
", dport INTEGER NOT NULL" +
", time INTEGER NOT NULL" +
", allowed INTEGER NULL" +
", block INTEGER NOT NULL" +
");");
db.execSQL("CREATE UNIQUE INDEX idx_access ON access(uid, daddr, dport)");
db.execSQL("CREATE UNIQUE INDEX idx_access ON access(uid, version, protocol, daddr, dport)");
}
private void createTableDns(SQLiteDatabase db) {
@ -244,6 +246,11 @@ public class DatabaseHelper extends SQLiteOpenHelper {
createTableDns(db);
oldVersion = 14;
}
if (oldVersion < 15) {
db.execSQL("DROP TABLE access");
createTableAccess(db);
oldVersion = 15;
}
if (oldVersion == DB_VERSION) {
db.setVersion(oldVersion);
@ -310,7 +317,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
}
notifyLogChanged();
return this;
}
@ -322,7 +328,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
}
notifyLogChanged();
return this;
}
@ -370,14 +375,18 @@ public class DatabaseHelper extends SQLiteOpenHelper {
if (block >= 0)
cv.put("block", block);
rows = db.update("access", cv, "uid = ? AND daddr = ? AND dport = ?",
rows = db.update("access", cv, "uid = ? AND version = ? AND protocol = ? AND daddr = ? AND dport = ?",
new String[]{
Integer.toString(packet.uid),
Integer.toString(packet.version),
Integer.toString(packet.protocol),
dname == null ? packet.daddr : dname,
Integer.toString(packet.dport)});
if (rows == 0) {
cv.put("uid", packet.uid);
cv.put("version", packet.version);
cv.put("protocol", packet.protocol);
cv.put("daddr", dname == null ? packet.daddr : dname);
cv.put("dport", packet.dport);
if (block < 0)
@ -390,7 +399,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
}
notifyAccessChanged();
return (rows == 0);
}
@ -404,10 +412,19 @@ public class DatabaseHelper extends SQLiteOpenHelper {
if (db.update("access", cv, "ID = ?", new String[]{Long.toString(id)}) != 1)
Log.e(TAG, "Set access failed");
notifyAccessChanged();
}
notifyAccessChanged();
return this;
}
public DatabaseHelper clearAccess() {
synchronized (context.getApplicationContext()) {
SQLiteDatabase db = this.getReadableDatabase();
db.delete("access", null, null);
}
notifyAccessChanged();
return this;
}
@ -418,7 +435,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
}
notifyAccessChanged();
return this;
}
@ -433,12 +449,12 @@ public class DatabaseHelper extends SQLiteOpenHelper {
public Cursor getAccess() {
SQLiteDatabase db = this.getReadableDatabase();
return db.query("access", new String[]{"uid", "daddr", "dport", "time", "block"}, "block >= 0", null, null, null, "uid");
return db.query("access", null, "block >= 0", null, null, null, "uid");
}
public Cursor getAccessUnset(int uid) {
SQLiteDatabase db = this.getReadableDatabase();
return db.query("access", new String[]{"daddr", "dport", "time", "allowed"},
return db.query("access", null,
"uid = ? AND block < 0", new String[]{Integer.toString(uid)},
null, null, "time DESC");
}
@ -504,11 +520,11 @@ public class DatabaseHelper extends SQLiteOpenHelper {
public Cursor getDns() {
SQLiteDatabase db = this.getReadableDatabase();
String query = "SELECT access.uid, access.daddr, dns.resource, access.dport, access.block";
query += " FROM access";
query += " JOIN dns";
query += " ON dns.qname = access.daddr";
query += " WHERE access.block >= 0";
String query = "SELECT a.uid, a.version, a.protocol, a.daddr, d.resource, a.dport, a.block";
query += " FROM access AS a";
query += " JOIN dns AS d";
query += " ON d.qname = a.daddr";
query += " WHERE a.block >= 0";
return db.rawQuery(query, new String[]{});
}

View File

@ -171,17 +171,7 @@ public class LogAdapter extends CursorAdapter {
}
}
// https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers
if (protocol == 0) // HOPOPT
tvProtocol.setText("HOPO" + version);
else if (protocol == 1 || protocol == 58) // ICMPv4/v6
tvProtocol.setText("ICMP" + version);
else if (protocol == 6) // TCP
tvProtocol.setText("TCP" + version);
else if (protocol == 17) // UDP
tvProtocol.setText("UDP" + version);
else
tvProtocol.setText(protocol < 0 ? "" : "P" + Integer.toString(protocol) + "V" + version);
tvProtocol.setText(Util.getProtocolName(protocol, version, false));
tvFlags.setText(flags);

View File

@ -550,13 +550,17 @@ public class RuleAdapter extends RecyclerView.Adapter<RuleAdapter.ViewHolder> im
if (IAB.isPurchased(ActivityPro.SKU_FILTER, context)) {
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.isNull(cursor.getColumnIndex("dport")) ? -1 : cursor.getInt(cursor.getColumnIndex("dport")));
int dport = cursor.getInt(cursor.getColumnIndex("dport"));
int block = cursor.getInt(cursor.getColumnIndex("block"));
PopupMenu popup = new PopupMenu(context, context.findViewById(R.id.vwPopupAnchor));
popup.inflate(R.menu.access);
popup.getMenu().findItem(R.id.menu_host).setTitle(daddr + (dport > 0 ? ":" + dport : ""));
popup.getMenu().findItem(R.id.menu_host).setTitle(
Util.getProtocolName(protocol, version, false) + " " +
daddr + (dport > 0 ? ":" + dport : ""));
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override

View File

@ -680,8 +680,7 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
dh.insertLog(packet, dname, (last_connected ? last_metered ? 2 : 1 : 0), last_interactive);
// Application log
if (log_app && packet.uid >= 0 &&
(packet.protocol == 17 /* UDP */ || packet.protocol == 6 /* TCP */)) {
if (log_app && packet.uid >= 0) {
if (dh.updateAccess(packet, dname, -1))
if (notify && prefs.getBoolean("notify_" + packet.uid, true) &&
(system || !Util.isSystem(packet.uid, SinkholeService.this)))
@ -922,29 +921,38 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
DatabaseHelper dh = new DatabaseHelper(SinkholeService.this);
Cursor cursor = dh.getDns();
int colUid = cursor.getColumnIndex("uid");
int colVersion = cursor.getColumnIndex("version");
int colProtocol = cursor.getColumnIndex("protocol");
int colDAddr = cursor.getColumnIndex("daddr");
int colResource = cursor.getColumnIndex("resource");
int colDPort = cursor.getColumnIndex("dport");
int colBlock = cursor.getColumnIndex("block");
while (cursor.moveToNext()) {
int uid = cursor.getInt(colUid);
int version = cursor.getInt(colVersion);
int protocol = cursor.getInt(colProtocol);
String daddr = cursor.getString(colDAddr);
String dresource = cursor.getString(colResource);
int dport = cursor.isNull(colDPort) ? -1 : cursor.getInt(colDPort);
int dport = cursor.getInt(colDPort);
boolean block = (cursor.getInt(colBlock) > 0);
if (!map.containsKey(uid))
map.put(uid, new HashMap());
if (!map.get(uid).containsKey(dport))
map.get(uid).put(dport, new HashMap<InetAddress, Boolean>());
// TODO: handle version/protocol
if (protocol == 17 /* UDP */ || protocol == 6 /* TCP */) {
if (!map.containsKey(uid))
map.put(uid, new HashMap());
try {
map.get(uid).get(dport).put(InetAddress.getByName(dresource), block);
Log.i(TAG, "Set filter uid=" + uid + " " + daddr + " " + dresource + "/" + dport + "=" + block);
} catch (UnknownHostException ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
if (!map.get(uid).containsKey(dport))
map.get(uid).put(dport, new HashMap<InetAddress, Boolean>());
try {
map.get(uid).get(dport).put(InetAddress.getByName(dresource), block);
Log.i(TAG, "Set filter uid=" + uid + " " + daddr + " " + dresource + "/" + dport + "=" + block);
} catch (UnknownHostException ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
}
}
}
cursor.close();
@ -1624,6 +1632,8 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
DatabaseHelper dh = new DatabaseHelper(SinkholeService.this);
Cursor cursor = dh.getAccessUnset(uid);
int colVersion = cursor.getColumnIndex("version");
int colProtocol = cursor.getColumnIndex("protocol");
int colDAddr = cursor.getColumnIndex("daddr");
int colDPort = cursor.getColumnIndex("dport");
int colTime = cursor.getColumnIndex("time");
@ -1631,8 +1641,13 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
while (cursor.moveToNext()) {
StringBuilder sb = new StringBuilder();
sb.append(df.format(cursor.getLong(colTime))).append(' ');
sb.append(Util.getProtocolName(cursor.getInt(colProtocol), cursor.getInt(colVersion), true));
sb.append(' ');
String daddr = cursor.getString(colDAddr);
sb.append(daddr);
int dport = cursor.getInt(colDPort);
if (dport > 0)
sb.append(':').append(dport);

View File

@ -401,6 +401,29 @@ public class Util {
return Math.round(dips * context.getResources().getDisplayMetrics().density + 0.5f);
}
public static String getProtocolName(int protocol, int version, boolean brief) {
// https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers
String p = null;
switch (protocol) {
case 0:
p = "HOPO";
break;
case 1:
case 58:
p = "ICMP";
break;
case 6:
p = "TCP";
break;
case 17:
p = "UDP";
break;
}
if (p == null)
return Integer.toString(protocol) + "/" + version;
return (brief ? p.substring(0, 1) + version : p + version);
}
public interface DoubtListener {
public void onSure();
}