Native get uid

This commit is contained in:
M66B 2016-01-10 08:14:47 +01:00
parent d4b7b93a55
commit 064c3d4d4b
4 changed files with 104 additions and 103 deletions

View File

@ -98,7 +98,6 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/objectFiles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard-rules" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />

View File

@ -23,9 +23,9 @@
#NetGuard
-keepnames class eu.faircode.netguard.** { *; }
# logPacket(int version, String saddr, int sport, String daddr, int dport, int protocol, String flags)
# logPacket(int version, String saddr, int sport, String daddr, int dport, int protocol, String flags, int uid)
-keep class eu.faircode.netguard.SinkholeService {
void logPacket(int, java.lang.String, int, java.lang.String, int, int, java.lang.String);
void logPacket(int, java.lang.String, int, java.lang.String, int, int, java.lang.String, int);
}
#Support library

View File

@ -61,19 +61,15 @@ import android.util.Log;
import android.util.TypedValue;
import android.widget.RemoteViews;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
@ -724,7 +720,7 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
receiveThread.start();
}
private void logPacket(int version, String saddr, int sport, String daddr, int dport, int protocol, String flags) {
private void logPacket(int version, String saddr, int sport, String daddr, int dport, int protocol, String flags, int uid) {
try {
int connection;
if (last_connected)
@ -735,19 +731,6 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
else
connection = 0;
int tries = 0;
int uid = getUid(version, InetAddress.getByName(saddr), sport, protocol);
while (uid < 0 && tries < 10) {
try {
Thread.sleep(10);
} catch (InterruptedException ignored) {
}
tries++;
uid = getUid(version, InetAddress.getByName(saddr), sport, protocol);
if (uid >= 0)
Log.w(TAG, "Uid found after try=" + tries);
}
new DatabaseHelper(SinkholeService.this).insertLog(
version,
daddr,
@ -762,51 +745,6 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
}
}
public int getUid(int version, InetAddress source, int sport, int protocol) {
StringBuilder addr = new StringBuilder();
byte[] b = source.getAddress();
for (int i = b.length - 1; i >= 0; i--)
addr.append(String.format("%02X", b[i]));
String port = String.format("%04X", sport);
int uid = -1;
if (version == 4) {
uid = scanUid("0000000000000000FFFF0000" + addr.toString() + ":" + port, protocol == 6 ? "/proc/net/tcp6" : "/proc/net/udp6");
if (uid < 0)
uid = scanUid(addr.toString() + ":" + port, protocol == 6 ? "/proc/net/tcp" : "/proc/net/udp");
if (uid < 0 && protocol == 17)
uid = scanUid("00000000:" + port, "/proc/net/udp");
} else
uid = scanUid(addr.toString() + ":" + port, protocol == 6 ? "/proc/net/tcp6" : "/proc/net/udp6");
return uid;
}
private static int scanUid(String addr, String name) {
File file = new File(name);
Scanner scanner = null;
try {
scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.startsWith("sl"))
continue;
String[] field = line.split("\\s+");
if (addr.equals(field[1]))
return Integer.parseInt(field[7]);
}
} catch (FileNotFoundException ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
} finally {
if (scanner != null)
scanner.close();
}
return -1;
}
private void stopReceiving() {
if (receiveThread != null)
receiveThread.interrupt();

View File

@ -1,7 +1,6 @@
#include <jni.h>
#include <stdio.h>
#include <stddef.h>
#include <malloc.h>
#include <time.h>
#include <unistd.h>
#include <android/log.h>
#include <arpa/inet.h>
@ -15,7 +14,7 @@
void decode(JNIEnv *env, jobject instance, jbyte *, int);
void scanproc6(const char *);
int getUid(int protocol, int version, const char *psaddr, int psport);
JNIEXPORT void JNICALL
Java_eu_faircode_netguard_SinkholeService_jni_1init(JNIEnv *env, jobject instance) {
@ -26,21 +25,18 @@ JNIEXPORT void JNICALL
Java_eu_faircode_netguard_SinkholeService_jni_1decode(JNIEnv *env, jobject instance,
jbyteArray buffer_, jint length) {
jbyte *buffer = (*env)->GetByteArrayElements(env, buffer_, NULL);
decode(env, instance, buffer, length);
(*env)->ReleaseByteArrayElements(env, buffer_, buffer, 0);
}
JNIEXPORT void JNICALL
Java_eu_faircode_netguard_SinkholeService_jni_1receive(JNIEnv *env, jobject instance, jint fd) {
int len;
jbyte *buffer = malloc(MAXPKT);
jbyte buffer[MAXPKT];
while (1) {
len = read(fd, buffer, MAXPKT);
len = read(fd, buffer, sizeof(buffer));
if (len < 0) {
__android_log_print(ANDROID_LOG_WARN, TAG, "Receive error %d", len);
free(buffer);
return;
} else if (len > 0)
@ -52,16 +48,18 @@ Java_eu_faircode_netguard_SinkholeService_jni_1receive(JNIEnv *env, jobject inst
}
void decode(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
jbyte protocol = -1;
jbyte protocol;
char source[40];
char dest[40];
char flags[10];
int flen = 0;
void *payload = NULL;
jbyte *payload;
// Get protocol, addresses & payload
jbyte version = (*buffer) >> 4;
if (version == 4) {
struct iphdr *ip4hdr = buffer;
protocol = ip4hdr->protocol;
inet_ntop(AF_INET, &ip4hdr->saddr, source, sizeof(source));
inet_ntop(AF_INET, &ip4hdr->daddr, dest, sizeof(dest));
@ -69,10 +67,11 @@ void decode(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
jbyte optlen = 0;
if (ip4hdr->ihl > 5)
optlen = buffer[20];
payload = buffer + 20 * sizeof(jbyte) + optlen;
payload = buffer + (20 + optlen) * sizeof(jbyte);
}
else if (version == 6) {
struct ip6_hdr *ip6hdr = buffer;
protocol = ip6hdr->ip6_nxt;
inet_ntop(AF_INET6, &ip6hdr->ip6_src, source, sizeof(source));
inet_ntop(AF_INET6, &ip6hdr->ip6_dst, dest, sizeof(dest));
@ -81,16 +80,18 @@ void decode(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
}
else {
__android_log_print(ANDROID_LOG_WARN, TAG, "Unknown version %d", version);
*source = 0;
*dest = 0;
return;
}
// Get ports & flags
int sport = -1;
int dport = -1;
if (protocol == IPPROTO_TCP) {
struct tcphdr *tcp = payload;
sport = ntohs(tcp->source);
dport = ntohs(tcp->dest);
if (tcp->syn)
flags[flen++] = 'S';
if (tcp->ack)
@ -103,6 +104,7 @@ void decode(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
flags[flen++] = 'R';
} else if (protocol == IPPROTO_UDP) {
struct udphdr *udp = payload;
sport = ntohs(udp->source);
dport = ntohs(udp->dest);
}
@ -111,40 +113,102 @@ void decode(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
__android_log_print(ANDROID_LOG_INFO, TAG, "Packet v%d %s/%d -> %s/%d proto %d flags %s",
version, source, sport, dest, dport, protocol, flags);
//scanproc6("/proc/net/tcp6");
// Get uid
int uid = -1;
if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP) {
// Sleep 10 ms
struct timespec tim, tim2;
tim.tv_sec = 0;
tim.tv_nsec = 10000000L;
nanosleep(&tim, &tim2);
// Lookup uid
uid = getUid(protocol, version, source, sport);
if (uid < 0 && version == 4) {
int8_t addr128[16];
char source6[40];
memset(addr128, 0, 10);
addr128[10] = 0xFF;
addr128[11] = 0xFF;
inet_pton(AF_INET, source, addr128 + 12);
inet_ntop(AF_INET6, &addr128, source6, sizeof(source6));
uid = getUid(protocol, 6, source6, sport);
}
}
// Call back
jclass cls = (*env)->GetObjectClass(env, instance);
jmethodID mid = (*env)->GetMethodID(env, cls, "logPacket",
"(ILjava/lang/String;ILjava/lang/String;IILjava/lang/String;)V");
"(ILjava/lang/String;ILjava/lang/String;IILjava/lang/String;I)V");
if (mid != 0) {
jstring jsource = (*env)->NewStringUTF(env, source);
jstring jdest = (*env)->NewStringUTF(env, dest);
jstring jflags = (*env)->NewStringUTF(env, flags);
(*env)->CallVoidMethod(env, instance, mid,
version, jsource, sport, jdest, dport, protocol, jflags);
version, jsource, sport, jdest, dport, protocol, jflags, uid);
(*env)->DeleteLocalRef(env, jsource);
(*env)->DeleteLocalRef(env, jdest);
(*env)->DeleteLocalRef(env, jflags);
}
}
void scanproc6(const char *file) {
char line[500];
struct in6_addr *saddr = malloc(sizeof(struct in6_addr));
char source[40];
int sport;
int uid;
FILE *fd = fopen(file, "r");
if (fd != NULL) {
int i = 0;
while (fgets(line, 500, fd) != NULL) {
if (i++) {
sscanf(line,
"%*d: %8X%8X%8X%8X:%X %*X:%*X %*X %*lX:%*lX %*X:%*X %*X %d %*d %*ld ",
saddr, ((void *) saddr) + 4, ((void *) saddr) + 8, ((void *) saddr) + 12,
&sport, &uid);
inet_ntop(AF_INET6, saddr, source, sizeof(source));
__android_log_print(ANDROID_LOG_INFO, TAG, "proc %s/%d %d", source, sport, uid);
}
}
fclose(fd);
int getUid(int protocol, int version, const char *saddr, int sport) {
char line[250];
int fields;
int32_t addr32;
int8_t addr128[16];
char addr[40];
int port;
int uid = -1;
// Get proc file name
char *fn = NULL;
if (protocol == IPPROTO_TCP)
fn = (version == 4 ? "/proc/net/tcp" : "/proc/net/tcp6");
else if (protocol == IPPROTO_UDP)
fn = (version == 4 ? "/proc/net/udp" : "/proc/net/udp6");
else
return -1;
// Open proc file
FILE *fd = fopen(fn, "r");
if (fd == NULL) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "Error opening %s", fn);
return -1;
}
free(saddr);
// Scan proc file
int i = 0;
while (fgets(line, sizeof(line), fd) != NULL) {
if (i++) {
if (version == 4)
fields = sscanf(line,
"%*d: %X:%X %*X:%*X %*X %*lX:%*lX %*X:%*X %*X %d %*d %*ld ",
&addr32, &port, &uid);
else
fields = sscanf(line,
"%*d: %8X%8X%8X%8X:%X %*X:%*X %*X %*lX:%*lX %*X:%*X %*X %d %*d %*ld ",
addr128, addr128 + 4, addr128 + 8, addr128 + 12, &port, &uid);
if (fields < 3) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "Invalid field #%d: %s", fields, line);
break;
}
if (version == 4)
inet_ntop(AF_INET, &addr32, addr, sizeof(addr));
else
inet_ntop(AF_INET6, addr128, addr, sizeof(addr));
if (port == sport && strcmp(addr, saddr) == 0)
break;
}
}
fclose(fd);
return uid;
}