From 5813f21e8d94badbd0553c0d9bde5c51c4b0743d Mon Sep 17 00:00:00 2001 From: Ox Cart Date: Fri, 5 Feb 2016 11:08:54 -0600 Subject: [PATCH] Working on Nexus 4 --- .../lantern/activity/LanternMainActivity.java | 28 ------ .../getlantern/lantern/model/Analytics.java | 46 ---------- .../org/getlantern/lantern/sdk/Utils.java | 13 --- .../getlantern/lantern/vpn/LanternVpn.java | 86 ------------------- .../org/getlantern/lantern/vpn/Service.java | 44 ++++------ .../getlantern/lantern/vpn/VpnBuilder.java | 23 +---- .../getlantern/lantern-mobile/jni/Android.mk | 1 + .../lantern-mobile/jni/Application.mk | 3 + src/github.com/getlantern/lantern/lantern.go | 16 ++++ .../getlantern/protected/protected.go | 16 ++-- .../getlantern/protected/protected_test.go | 2 +- 11 files changed, 46 insertions(+), 232 deletions(-) delete mode 100644 src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/model/Analytics.java delete mode 100644 src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/LanternVpn.java create mode 100644 src/github.com/getlantern/lantern-mobile/jni/Android.mk create mode 100644 src/github.com/getlantern/lantern-mobile/jni/Application.mk diff --git a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/activity/LanternMainActivity.java b/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/activity/LanternMainActivity.java index 3f84b90064..af0d21eca4 100644 --- a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/activity/LanternMainActivity.java +++ b/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/activity/LanternMainActivity.java @@ -1,57 +1,30 @@ package org.getlantern.lantern.activity; -import android.app.Fragment; -import android.app.FragmentManager; -import android.content.ComponentName; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.os.Looper; import android.os.Message; import android.os.StrictMode; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.VpnService; -import android.net.Uri; import android.net.wifi.WifiManager; -import android.content.pm.PackageManager; -import android.content.pm.PackageInfo; -import android.app.Activity; -import android.text.Html; import android.util.Log; import android.view.View; -import android.view.View.OnClickListener; -import android.widget.AdapterView; -import android.widget.CompoundButton; -import android.widget.ListView; import android.widget.Toast; -import android.widget.ToggleButton; import android.view.MenuItem; import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup; import android.support.v7.app.AppCompatActivity; -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.getlantern.lantern.config.LanternConfig; import org.getlantern.lantern.vpn.Service; import org.getlantern.lantern.model.UI; import org.getlantern.lantern.sdk.Utils; -import org.getlantern.lantern.vpn.LanternVpn; import org.getlantern.lantern.R; @@ -113,7 +86,6 @@ protected void onCreate(Bundle savedInstanceState) { try { // configure actions to be taken whenever slider changes state LanternUI.setupLanternSwitch(); - LanternVpn.LanternUI = LanternUI; } catch (Exception e) { Log.d(TAG, "Got an exception " + e); } diff --git a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/model/Analytics.java b/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/model/Analytics.java deleted file mode 100644 index f8ec31d0b8..0000000000 --- a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/model/Analytics.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.getlantern.lantern.model; - -import android.content.Context; - -import com.google.android.gms.analytics.GoogleAnalytics; -import com.google.android.gms.analytics.HitBuilders; -import com.google.android.gms.analytics.Tracker; - -public class Analytics { - private GoogleAnalytics analytics; - private Tracker tracker; - private final String TRACKING_ID = "UA-21815217-14"; - - public Analytics(Context context) { - analytics = GoogleAnalytics.getInstance(context); - analytics.setLocalDispatchPeriod(1800); - - tracker = analytics.newTracker(TRACKING_ID); - tracker.enableAdvertisingIdCollection(true); - tracker.enableAutoActivityTracking(true); - } - - public void sendNewSessionEvent() { - tracker.send(new HitBuilders.EventBuilder() - .setCategory("Session") - .setAction("Start") - .setLabel("android") - .build()); - } - - public void trackLoginEvent(String type) { - tracker.send(new HitBuilders.EventBuilder() - .setCategory("Session") - .setAction("Login") - .setLabel(type) - .build()); - } - - public void trackPageView(String pageName) { - tracker.send(new HitBuilders.EventBuilder() - .setCategory("Session") - .setAction("PageView") - .setLabel(pageName) - .build()); - } -} diff --git a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/sdk/Utils.java b/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/sdk/Utils.java index b0a640b0c1..3af4dcaec0 100644 --- a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/sdk/Utils.java +++ b/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/sdk/Utils.java @@ -2,20 +2,7 @@ import android.content.Context; import android.content.SharedPreferences; -import android.content.res.AssetManager; -import android.content.res.Resources; import android.net.ConnectivityManager; -import android.util.Log; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.InputStream; - -import java.util.Map; -import java.util.HashMap; - -import org.yaml.snakeyaml.Yaml; public class Utils { private static final String PREFS_NAME = "LanternPrefs"; diff --git a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/LanternVpn.java b/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/LanternVpn.java deleted file mode 100644 index 1af1ae4c3a..0000000000 --- a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/LanternVpn.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.getlantern.lantern.vpn; - -import android.content.Context; -import android.util.Log; - -import java.net.InetAddress; -import java.io.FileOutputStream; -import java.nio.ByteBuffer; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.io.File; -import java.util.Map; -import java.util.HashMap; - -import org.getlantern.lantern.model.UI; - -// LanternVpn is a subclass of the SDK class Lantern -// it instantiates Lantern to run in full-device VPN mode -// along with a few customizations/extensions -public class LanternVpn extends Lantern { - - private static final String TAG = "LanternVpn"; - public static UI LanternUI; - - private Service service; - - public LanternVpn(Service service) { - super(service.getApplicationContext(), "", true); - // start Lantern in VPN mode - this.service = service; - } - - @Override - public void AfterStart(String latestVersion) { - super.AfterStart(latestVersion); - // we pass the version number to setVersionNum which - // populates the version string that appears at the bottom - // of the side menu - if (LanternUI != null) { - LanternUI.setVersionNum(latestVersion); - } - } - - - @Override - public String GetDnsServer() { - try { - return service.getDnsResolver(service); - } catch (Exception e) { - return super.GetDnsServer(); - } - } - - // Protect is used to exclude a socket specified by fileDescriptor - // from the VPN connection. Once protected, the underlying connection - // is bound to the VPN device and won't be forwarded - @Override - public void Protect(long fileDescriptor) throws Exception { - if (!this.service.protect((int) fileDescriptor)) { - throw new Exception("protect socket failed"); - } - } - - // Notice is used to signal messages from Lantern - // if fatal is true, Lantern encountered a fatal error - // and we should shutdown - @Override - public void Notice(String message, boolean fatal) { - Log.d(TAG, "Received a new message from Lantern: " + message); - if (fatal) { - Log.d(TAG, "Received fatal error.. Shutting down."); - try { - // if we receive a fatal notice from Lantern - // then we shut down the VPN interface - // and close Tun2Socks - //this.service.stop(false); - //this.service.UI.handleFatalError(); - - } catch (Exception e) { - - } - } - } - -} - diff --git a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/Service.java b/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/Service.java index 240c91af57..a1c02ffff2 100644 --- a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/Service.java +++ b/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/Service.java @@ -1,34 +1,17 @@ package org.getlantern.lantern.vpn; import android.content.Intent; -import android.os.Handler; -import android.os.Message; import android.util.Log; -import android.widget.Toast; -import android.content.Context; -import android.content.SharedPreferences; - -import org.getlantern.lantern.config.LanternConfig; -import org.getlantern.lantern.sdk.Utils; - -import java.util.Map; +import go.lantern.Lantern; public class Service extends VpnBuilder implements Runnable { private static final String TAG = "VpnService"; public static boolean IsRunning = false; - private String mSessionName = "LanternVpn"; - - private Handler mHandler; - private LanternVpn lantern; private Thread mThread = null; - public Service() { - mHandler = new Handler(); - } - @Override public void onCreate() { super.onCreate(); @@ -48,17 +31,26 @@ public int onStartCommand(Intent intent, int flags, int startId) { public synchronized void run() { try { Log.d(TAG, "Loading Lantern library"); - final Service service = this; - lantern = new LanternVpn(this); - lantern.Start(); - - Thread.sleep(1000*2); - service.configure(lantern.getSettings()); + Lantern.ProtectConnections(getDnsResolver(getApplicationContext()), new Lantern.SocketProtector.Stub() { + // Protect is used to exclude a socket specified by fileDescriptor + // from the VPN connection. Once protected, the underlying connection + // is bound to the VPN device and won't be forwarded + @Override + public void Protect(long fileDescriptor) throws Exception { + if (!protect((int) fileDescriptor)) { + throw new Exception("protect socket failed"); + } + } + }); + int startTimeoutMillis = 60000; + String analyticsTrackingID = "UA-21815217-14"; + Lantern.StartResult result = org.lantern.mobilesdk.Lantern.enable(getApplicationContext(), startTimeoutMillis, analyticsTrackingID); + configure(result.getSOCKS5Addr()); while (IsRunning) { // sleep to avoid busy looping Thread.sleep(100); - } + } } catch (InterruptedException e) { Log.e(TAG, "Exception", e); } catch (Exception e) { @@ -74,9 +66,7 @@ private synchronized void stop() { try { super.close(); Log.d(TAG, "Closing VPN interface.."); - lantern.Stop(); } catch (Exception e) { - } stopSelf(); diff --git a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/VpnBuilder.java b/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/VpnBuilder.java index b6b0138e78..57ec8912c0 100644 --- a/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/VpnBuilder.java +++ b/src/github.com/getlantern/lantern-mobile/app/src/main/java/org/getlantern/lantern/vpn/VpnBuilder.java @@ -93,20 +93,13 @@ public void createBuilder() { } @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) - public synchronized void configure(final Map settings) throws Exception { + public synchronized void configure(final String socksAddr) throws Exception { vpnThread = new Thread() { public void run() { createBuilder(); - String socksAddr = "127.0.0.1:9131"; String udpgwAddr = "127.0.0.1:7300"; - if (settings != null && - settings.get("socksaddr") != null && - settings.get("udpgwaddr") != null) { - socksAddr = (String)settings.get("socksaddr"); - udpgwAddr = (String)settings.get("udpgwaddr"); - } Tun2Socks.Start( mInterface, @@ -134,20 +127,6 @@ public void close() throws Exception { vpnThread = null; } - public void restart(final Map settings) throws Exception { - close(); - Handler mHandler = new Handler(); - mHandler.postDelayed(new Runnable () { - public void run () { - try { - configure(settings); - } catch (Exception e) { - Log.e(TAG, "Could not call configure again!" + e.getMessage()); - } - } - }, 2000); - } - public static String getDnsResolver(Context context) throws Exception { Collection dnsResolvers = getDnsResolvers(context); diff --git a/src/github.com/getlantern/lantern-mobile/jni/Android.mk b/src/github.com/getlantern/lantern-mobile/jni/Android.mk new file mode 100644 index 0000000000..8b9af7574b --- /dev/null +++ b/src/github.com/getlantern/lantern-mobile/jni/Android.mk @@ -0,0 +1 @@ +include ./external/badvpn/Android.mk diff --git a/src/github.com/getlantern/lantern-mobile/jni/Application.mk b/src/github.com/getlantern/lantern-mobile/jni/Application.mk new file mode 100644 index 0000000000..980a0d47df --- /dev/null +++ b/src/github.com/getlantern/lantern-mobile/jni/Application.mk @@ -0,0 +1,3 @@ +APP_OPTIM := release +APP_ABI := armeabi armeabi-v7a x86 +APP_PLATFORM := android-14 diff --git a/src/github.com/getlantern/lantern/lantern.go b/src/github.com/getlantern/lantern/lantern.go index 904df827c4..312fd542b5 100644 --- a/src/github.com/getlantern/lantern/lantern.go +++ b/src/github.com/getlantern/lantern/lantern.go @@ -12,6 +12,8 @@ import ( "github.com/getlantern/flashlight/config" "github.com/getlantern/flashlight/logging" "github.com/getlantern/golog" + "github.com/getlantern/protected" + "github.com/getlantern/tlsdialer" ) var ( @@ -20,6 +22,20 @@ var ( startOnce sync.Once ) +type SocketProtector interface { + Protect(fileDescriptor int) error +} + +// ProtectConnections allows connections made by Lantern to be protected from +// routing via a VPN. This is useful when running Lantern as a VPN on Android, +// because it keeps Lantern's own connections from being captured by the VPN and +// resulting in an infinite loop. +func ProtectConnections(dnsServer string, protector SocketProtector) { + protected.Configure(protector.Protect, dnsServer) + tlsdialer.OverrideResolve(protected.Resolve) + tlsdialer.OverrideDial(protected.Dial) +} + // StartResult provides information about the started Lantern type StartResult struct { HTTPAddr string diff --git a/src/github.com/getlantern/protected/protected.go b/src/github.com/getlantern/protected/protected.go index 7e768bb57b..eb75977717 100644 --- a/src/github.com/getlantern/protected/protected.go +++ b/src/github.com/getlantern/protected/protected.go @@ -24,9 +24,7 @@ const ( dnsPort = 53 ) -type SocketProtector interface { - Protect(fileDescriptor int) error -} +type Protect func(fileDescriptor int) error type ProtectedConn struct { net.Conn @@ -39,12 +37,12 @@ type ProtectedConn struct { var ( log = golog.LoggerFor("lantern-android.protected") - currentProtector SocketProtector + currentProtect Protect currentDnsServer string ) -func Configure(protector SocketProtector, dnsServer string) { - currentProtector = protector +func Configure(protect Protect, dnsServer string) { + currentProtect = protect if dnsServer != "" { currentDnsServer = dnsServer } else { @@ -76,7 +74,7 @@ func Resolve(addr string) (*net.TCPAddr, error) { // Here we protect the underlying socket from the // VPN connection by passing the file descriptor // back to Java for exclusion - err = currentProtector.Protect(socketFd) + err = currentProtect(socketFd) if err != nil { return nil, fmt.Errorf("Could not bind socket to system device: %v", err) } @@ -128,7 +126,7 @@ func Resolve(addr string) (*net.TCPAddr, error) { // - syscall API calls are used to create and bind to the // specified system device (this is primarily // used for Android VpnService routing functionality) -func Dial(network, addr string, timeout time.Duration) (*ProtectedConn, error) { +func Dial(network, addr string, timeout time.Duration) (net.Conn, error) { host, port, err := SplitHostPort(addr) if err != nil { return nil, err @@ -156,7 +154,7 @@ func Dial(network, addr string, timeout time.Duration) (*ProtectedConn, error) { defer conn.cleanup() // Actually protect the underlying socket here - err = currentProtector.Protect(conn.socketFd) + err = currentProtect(conn.socketFd) if err != nil { return nil, fmt.Errorf("Could not bind socket to system device: %v", err) } diff --git a/src/github.com/getlantern/protected/protected_test.go b/src/github.com/getlantern/protected/protected_test.go index 09aa635fe5..098a5aa66a 100644 --- a/src/github.com/getlantern/protected/protected_test.go +++ b/src/github.com/getlantern/protected/protected_test.go @@ -25,7 +25,7 @@ func (p *testprotector) Protect(fileDescriptor int) error { func TestConnect(t *testing.T) { p := &testprotector{} - Configure(p, "8.8.8.8") + Configure(p.Protect, "8.8.8.8") client := &http.Client{ Transport: &http.Transport{ Dial: func(netw, addr string) (net.Conn, error) {