diff --git a/.classpath b/.classpath index 51769745..92080bb6 100644 --- a/.classpath +++ b/.classpath @@ -3,7 +3,11 @@ - + + + + + diff --git a/.project b/.project index 4d1444b7..057168b2 100644 --- a/.project +++ b/.project @@ -6,9 +6,13 @@ - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.genmakebuilder.launch + @@ -54,7 +58,7 @@ - 1435241696221 + 1451443416388 30 @@ -62,5 +66,14 @@ 1.0-name-matches-false-false-external + + 1451443416398 + + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-jni + + diff --git a/external/badvpn b/external/badvpn index d065d0f5..24a97f21 160000 --- a/external/badvpn +++ b/external/badvpn @@ -1 +1 @@ -Subproject commit d065d0f501a08068587c5aa2285cd28adf79c8b5 +Subproject commit 24a97f2101abaf0569b78ee430d62eb2543d3ec2 diff --git a/jni/Android.mk b/jni/Android.mk index 8b9af757..2dd3ef90 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -1 +1,131 @@ -include ./external/badvpn/Android.mk +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +LOCAL_PATH := $(call my-dir) +ROOT_PATH := $(LOCAL_PATH) +EXTERN_PATH := $(LOCAL_PATH)/../external + +######################################################## +## libancillary +######################################################## + +include $(CLEAR_VARS) + +ANCILLARY_SOURCE := fd_recv.c fd_send.c + +LOCAL_MODULE := libancillary +LOCAL_CFLAGS := -O2 -I$(LOCAL_PATH)/libancillary + +LOCAL_SRC_FILES := $(addprefix libancillary/, $(ANCILLARY_SOURCE)) + +include $(BUILD_STATIC_LIBRARY) + + +######################################################## +## tun2socks +######################################################## + +include $(CLEAR_VARS) + +LOCAL_CFLAGS := -std=gnu99 +LOCAL_CFLAGS += -DBADVPN_THREADWORK_USE_PTHREAD -DBADVPN_LINUX -DBADVPN_BREACTOR_BADVPN -D_GNU_SOURCE +LOCAL_CFLAGS += -DBADVPN_USE_SELFPIPE -DBADVPN_USE_EPOLL +LOCAL_CFLAGS += -DBADVPN_LITTLE_ENDIAN -DBADVPN_THREAD_SAFE +LOCAL_CFLAGS += -DNDEBUG -DANDROID +LOCAL_CFLAGS += -DTUN2SOCKS_JNI +LOCAL_CFLAGS += -DPSIPHON + +LOCAL_STATIC_LIBRARIES := libancillary + +LOCAL_C_INCLUDES:= \ + $(LOCAL_PATH)/libancillary \ + $(EXTERN_PATH)/badvpn/ \ + $(EXTERN_PATH)/badvpn/lwip/src/include/ipv4 \ + $(EXTERN_PATH)/badvpn/lwip/src/include/ipv6 \ + $(EXTERN_PATH)/badvpn/lwip/src/include \ + $(EXTERN_PATH)/badvpn/lwip/custom \ + +TUN2SOCKS_SOURCES := \ + base/BLog_syslog.c \ + system/BReactor_badvpn.c \ + system/BSignal.c \ + system/BConnection_unix.c \ + system/BTime.c \ + system/BUnixSignal.c \ + system/BNetwork.c \ + flow/StreamRecvInterface.c \ + flow/PacketRecvInterface.c \ + flow/PacketPassInterface.c \ + flow/StreamPassInterface.c \ + flow/SinglePacketBuffer.c \ + flow/BufferWriter.c \ + flow/PacketBuffer.c \ + flow/PacketStreamSender.c \ + flow/PacketPassConnector.c \ + flow/PacketProtoFlow.c \ + flow/PacketPassFairQueue.c \ + flow/PacketProtoEncoder.c \ + flow/PacketProtoDecoder.c \ + socksclient/BSocksClient.c \ + tuntap/BTap.c \ + lwip/src/core/timers.c \ + lwip/src/core/udp.c \ + lwip/src/core/memp.c \ + lwip/src/core/init.c \ + lwip/src/core/pbuf.c \ + lwip/src/core/tcp.c \ + lwip/src/core/tcp_out.c \ + lwip/src/core/netif.c \ + lwip/src/core/def.c \ + lwip/src/core/mem.c \ + lwip/src/core/tcp_in.c \ + lwip/src/core/stats.c \ + lwip/src/core/inet_chksum.c \ + lwip/src/core/ipv4/icmp.c \ + lwip/src/core/ipv4/igmp.c \ + lwip/src/core/ipv4/ip4_addr.c \ + lwip/src/core/ipv4/ip_frag.c \ + lwip/src/core/ipv4/ip4.c \ + lwip/src/core/ipv4/autoip.c \ + lwip/src/core/ipv6/ethip6.c \ + lwip/src/core/ipv6/inet6.c \ + lwip/src/core/ipv6/ip6_addr.c \ + lwip/src/core/ipv6/mld6.c \ + lwip/src/core/ipv6/dhcp6.c \ + lwip/src/core/ipv6/icmp6.c \ + lwip/src/core/ipv6/ip6.c \ + lwip/src/core/ipv6/ip6_frag.c \ + lwip/src/core/ipv6/nd6.c \ + lwip/custom/sys.c \ + tun2socks/tun2socks.c \ + base/DebugObject.c \ + base/BLog.c \ + base/BPending.c \ + system/BDatagram_unix.c \ + flowextra/PacketPassInactivityMonitor.c \ + tun2socks/SocksUdpGwClient.c \ + udpgw_client/UdpGwClient.c + +LOCAL_MODULE := tun2socks + +LOCAL_LDLIBS := -ldl -llog + +LOCAL_SRC_FILES := $(addprefix ../external/badvpn/, $(TUN2SOCKS_SOURCES)) + +##include $(BUILD_EXECUTABLE) +include $(BUILD_SHARED_LIBRARY) + +# Import cpufeatures +$(call import-module,android/cpufeatures) diff --git a/jni/Application.mk b/jni/Application.mk index 980a0d47..3ac89c03 100644 --- a/jni/Application.mk +++ b/jni/Application.mk @@ -1,3 +1,4 @@ -APP_OPTIM := release -APP_ABI := armeabi armeabi-v7a x86 -APP_PLATFORM := android-14 +APP_ABI := armeabi-v7a arm64-v8a mips x86 +APP_PLATFORM := android-21 +APP_STL := stlport_static +NDK_TOOLCHAIN_VERSION := 4.9 diff --git a/libs/arm64-v8a/libtun2socks.so b/libs/arm64-v8a/libtun2socks.so new file mode 100755 index 00000000..9d5b3dd9 Binary files /dev/null and b/libs/arm64-v8a/libtun2socks.so differ diff --git a/libs/armeabi-v7a/libtun2socks.so b/libs/armeabi-v7a/libtun2socks.so index 62412342..04174694 100755 Binary files a/libs/armeabi-v7a/libtun2socks.so and b/libs/armeabi-v7a/libtun2socks.so differ diff --git a/libs/armeabi/libtun2socks.so b/libs/armeabi/libtun2socks.so deleted file mode 100755 index 3892a182..00000000 Binary files a/libs/armeabi/libtun2socks.so and /dev/null differ diff --git a/libs/mips/libtun2socks.so b/libs/mips/libtun2socks.so new file mode 100755 index 00000000..ac42c4da Binary files /dev/null and b/libs/mips/libtun2socks.so differ diff --git a/libs/x86/libtun2socks.so b/libs/x86/libtun2socks.so index c0368cd6..f80e6f72 100755 Binary files a/libs/x86/libtun2socks.so and b/libs/x86/libtun2socks.so differ diff --git a/res/layout/layout_main.xml b/res/layout/layout_main.xml index 8416d3b3..104e96e4 100644 --- a/res/layout/layout_main.xml +++ b/res/layout/layout_main.xml @@ -166,7 +166,7 @@ android:layout_gravity="center_horizontal|center_vertical"/> @@ -175,7 +175,8 @@ android:layout_gravity="center_horizontal|center_vertical"/> android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/menu_verify_browser" - android:layout_margin="3dp" + android:layout_marginTop="3dp" + android:layout_marginBottom="3dp" android:ellipsize="end" android:singleLine="true" /> @@ -183,7 +184,7 @@ android:layout_gravity="center_horizontal|center_vertical"/> diff --git a/res/values/strings.xml b/res/values/strings.xml index 889603ae..ec2136a0 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -21,7 +21,7 @@ Settings Log Help - Apps + VPN Start Stop About @@ -296,7 +296,7 @@ You do not have ROOT access enabled You may need to stop and start Orbot for settings change to be enabled. - Apps + VPN kbps @@ -321,7 +321,7 @@ Activate - Apps Mode + Apps VPN Mode You can enable all apps on your device to run through the Tor network using the VPN feature of Android.\n\n*WARNING* This is a new, experimental feature and in some cases may not start automatically, or may stop. It should NOT be used for anonymity, and ONLY used for getting through firewalls and filters. diff --git a/src/org/torproject/android/OrbotApp.java b/src/org/torproject/android/OrbotApp.java index bbc25092..4ee1edbf 100644 --- a/src/org/torproject/android/OrbotApp.java +++ b/src/org/torproject/android/OrbotApp.java @@ -48,6 +48,7 @@ public class OrbotApp extends Application implements OrbotConstants fileMeekclient = new File(appBinHome, TorServiceConstants.MEEK_ASSET_KEY); fileXtables = new File(appBinHome, TorServiceConstants.IPTABLES_ASSET_KEY); fileTorRc = new File(appBinHome, TorServiceConstants.TORRC_ASSET_KEY); + } @Override diff --git a/src/org/torproject/android/service/TorResourceInstaller.java b/src/org/torproject/android/service/TorResourceInstaller.java index 3e9621b0..2f946a91 100644 --- a/src/org/torproject/android/service/TorResourceInstaller.java +++ b/src/org/torproject/android/service/TorResourceInstaller.java @@ -53,12 +53,13 @@ public class TorResourceInstaller implements TorServiceConstants { } } } - file.delete(); + + file.delete(); } } private final static String COMMAND_RM_FORCE = "rm -f "; - + private final static String MP3_EXT = ".mp3"; // /* * Extract the Tor resources from the APK file using ZIP @@ -94,13 +95,13 @@ public class TorResourceInstaller implements TorServiceConstants { if (cpuPath.equals("armeabi")) { cpuPath = "armeabi"; - is = context.getAssets().open(cpuPath + "/" + OBFSCLIENT_ASSET_KEY + ".mp3"); + is = context.getAssets().open(cpuPath + "/" + OBFSCLIENT_ASSET_KEY + MP3_EXT); outFile = new File(installFolder, OBFSCLIENT_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); setExecutable(outFile); - is = context.getAssets().open(cpuPath + "/" + MEEK_ASSET_KEY + ".mp3"); + is = context.getAssets().open(cpuPath + "/" + MEEK_ASSET_KEY + MP3_EXT); outFile = new File(installFolder, MEEK_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); @@ -108,23 +109,29 @@ public class TorResourceInstaller implements TorServiceConstants { } - is = context.getAssets().open(cpuPath + "/tor.mp3"); + is = context.getAssets().open(cpuPath + '/' + TOR_ASSET_KEY + MP3_EXT); outFile = new File(installFolder, TOR_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); setExecutable(outFile); - is = context.getAssets().open(cpuPath + "/polipo.mp3"); + is = context.getAssets().open(cpuPath + '/' + POLIPO_ASSET_KEY + MP3_EXT); outFile = new File(installFolder, POLIPO_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); setExecutable(outFile); - is = context.getAssets().open(cpuPath + "/xtables.mp3"); + is = context.getAssets().open(cpuPath + '/' + IPTABLES_ASSET_KEY + MP3_EXT); outFile = new File(installFolder, IPTABLES_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); setExecutable(outFile); + + is = context.getAssets().open(cpuPath + '/' + TUN2SOCKS_ASSET_KEY + MP3_EXT); + outFile = new File(installFolder, TUN2SOCKS_ASSET_KEY); + shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); + streamToFile(is,outFile, false, true); + setExecutable(outFile); return true; } @@ -134,7 +141,7 @@ public class TorResourceInstaller implements TorServiceConstants { if (fileTorRcCustom.exists()) { fileTorRcCustom.delete(); - Log.d("torResources","deleeting existing torrc.custom"); + Log.d("torResources","deleting existing torrc.custom"); } else fileTorRcCustom.createNewFile(); @@ -144,16 +151,6 @@ public class TorResourceInstaller implements TorServiceConstants { ps.print(extraLines); ps.close(); - /* - FileWriter fw = new FileWriter( fileTorRcCustom, false ); - PrintWriter bw = new PrintWriter( fw ); - bw.write(extraLines); - bw.close(); - */ - -// StringBufferInputStream sbis = new StringBufferInputStream(extraLines + '\n'); - // streamToFile(sbis,fileTorRcCustom,false,false); - return true; } diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java index 2ee02bdb..952c732d 100644 --- a/src/org/torproject/android/service/TorService.java +++ b/src/org/torproject/android/service/TorService.java @@ -381,13 +381,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon sendCallbackLogMessage(getString(R.string.status_disabled)); } - catch (CannotKillException e) - { - logNotice("An error occured stopping Tor: " + e.getMessage()); - sendCallbackLogMessage(getString(R.string.unable_to_reset_tor)); - showToolbarNotification(getString(R.string.unable_to_reset_tor), - ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr); - } catch (Exception e) { logNotice("An error occured stopping Tor: " + e.getMessage()); @@ -466,7 +459,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } - private void killAllDaemons() throws CannotKillException { + private void killAllDaemons() throws Exception { if (conn != null) { logNotice("Using control port to shutdown Tor"); @@ -484,39 +477,29 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon // try these separately in case one fails, then it can try the next File cannotKillFile = null; try { - killProcess(OrbotApp.fileObfsclient); + TorServiceUtils.killProcess(OrbotApp.fileObfsclient); } catch (IOException e) { e.printStackTrace(); cannotKillFile = OrbotApp.fileObfsclient; } try { - killProcess(OrbotApp.fileMeekclient); + TorServiceUtils.killProcess(OrbotApp.fileMeekclient); } catch (IOException e) { e.printStackTrace(); cannotKillFile = OrbotApp.fileMeekclient; } try { - killProcess(OrbotApp.filePolipo); + TorServiceUtils.killProcess(OrbotApp.filePolipo); } catch (IOException e) { e.printStackTrace(); cannotKillFile = OrbotApp.filePolipo; } try { - killProcess(OrbotApp.fileTor); + TorServiceUtils.killProcess(OrbotApp.fileTor); } catch (IOException e) { e.printStackTrace(); cannotKillFile = OrbotApp.fileTor; } - if (cannotKillFile != null) - throw new CannotKillException(cannotKillFile); - } - - public class CannotKillException extends IllegalStateException { - private static final long serialVersionUID = -286877277562592501L; - - public CannotKillException(File f) { - super("Cannot kill " + f.getAbsolutePath()); - } } private void requestTorRereadConfig() { @@ -528,54 +511,13 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } // if that fails, try again using native utils try { - killProcess(OrbotApp.fileTor, "-1"); // this is -HUP - } catch (CannotKillException e) { + TorServiceUtils.killProcess(OrbotApp.fileTor, "-1"); // this is -HUP + } catch (Exception e) { e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } + } } - private void killProcess(File fileProcBin) throws IOException, CannotKillException { - killProcess(fileProcBin, "-9"); // this is -KILL - } - - private void killProcess(File fileProcBin, String signal) throws IOException, CannotKillException { - int procId = -1; - int killAttempts = 0; - - while ((procId = TorServiceUtils.findProcessId(fileProcBin.getCanonicalPath())) != -1) { - killAttempts++; - logNotice("Found " + fileProcBin.getName() + " PID=" + procId + " - killing now..."); - String pidString = String.valueOf(procId); - /* - * first try as the normal app user to be safe, then if that fails, - * try root since the process might be left over from - * uninstall/reinstall with different UID. - */ - Shell shell; - if (Prefs.useRoot() && killAttempts > 2) { - shell = Shell.startRootShell(); - Log.i(TAG, "using a root shell"); - } else { - shell = Shell.startShell(); - } - shell.add(new SimpleCommand("busybox killall " + signal + " " + fileProcBin.getName())); - shell.add(new SimpleCommand("toolbox kill " + signal + " " + pidString)); - shell.add(new SimpleCommand("busybox kill " + signal + " " + pidString)); - shell.add(new SimpleCommand("kill " + signal + " " + pidString)); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // ignored - } - shell.close(); - if (killAttempts > 4) - throw new CannotKillException(fileProcBin); - } - } - - private void logNotice (String msg) + private void logNotice (String msg) { if (msg != null && msg.trim().length() > 0) { @@ -675,29 +617,40 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon fileControlPort = new File(OrbotApp.appBinHome, "control.txt"); extraLines.append(TORRC_CONTROLPORT_FILE_KEY).append(' ').append(fileControlPort.getCanonicalPath()).append('\n'); - if (Prefs.transparentTethering()) - { - extraLines.append("TransListenAddress 0.0.0.0").append('\n'); - extraLines.append("DNSListenAddress 0.0.0.0").append('\n'); - - } - extraLines.append("RunAsDaemon 1").append('\n'); extraLines.append("AvoidDiskWrites 1").append('\n'); - extraLines.append("SOCKSPort ").append("auto").append('\n'); + String socksPortPref = prefs.getString(OrbotConstants.PREF_SOCKS, + String.valueOf(TorServiceConstants.SOCKS_PROXY_PORT_DEFAULT)); + if (socksPortPref.indexOf(':')!=-1) + socksPortPref = socksPortPref.split(":")[1]; + + extraLines.append("SOCKSPort ").append(socksPortPref).append('\n'); extraLines.append("SafeSocks 0").append('\n'); extraLines.append("TestSocks 0").append('\n'); extraLines.append("WarnUnsafeSocks 1").append('\n'); extraLines.append("TransPort ").append("auto").append('\n'); - extraLines.append("DNSPort ").append("auto").append('\n'); + extraLines.append("DNSPort ").append(TorServiceConstants.TOR_DNS_PORT_DEFAULT).append("\n"); + + if (Prefs.transparentTethering()) + { + extraLines.append("TransListenAddress 0.0.0.0").append('\n'); + extraLines.append("DNSListenAddress 0.0.0.0").append('\n'); + } + extraLines.append("VirtualAddrNetwork 10.192.0.0/10").append('\n'); extraLines.append("AutomapHostsOnResolve 1").append('\n'); extraLines.append("DisableNetwork 0").append('\n'); + + if (Prefs.useDebugLogging()) + { + extraLines.append("Log debug syslog").append('\n'); + extraLines.append("Log info syslog").append('\n'); - //.extraLines.append("CircuitStreamTimeout 60").append('\n'); + //extraLines.append("Log debug stdout").append('\n'); + } processSettingsImpl(extraLines); @@ -765,62 +718,57 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon return; } - // make sure there are no stray daemons running - killAllDaemons(); - sendCallbackStatus(STATUS_STARTING); - sendCallbackLogMessage(getString(R.string.status_starting_up)); - logNotice(getString(R.string.status_starting_up)); - try { - if (!isTorUpgradeAndConfigComplete) - torUpgradeAndConfig(); - - ArrayList customEnv = new ArrayList(); + + // make sure there are no stray daemons running + killAllDaemons(); + + sendCallbackStatus(STATUS_STARTING); + sendCallbackLogMessage(getString(R.string.status_starting_up)); + logNotice(getString(R.string.status_starting_up)); + + ArrayList customEnv = new ArrayList(); + + if (Prefs.bridgesEnabled()) + if (Prefs.useVpn() && !mIsLollipop) + customEnv.add("TOR_PT_PROXY=socks5://127.0.0.1:" + OrbotVpnService.mSocksProxyPort); + + String baseDirectory = OrbotApp.fileTor.getParent(); + Shell shellUser = Shell.startShell(customEnv, baseDirectory); + + boolean success = runTorShellCmd(shellUser); + + if (success) + { + if (mPortHTTP != -1) + runPolipoShellCmd(shellUser); + + if (Prefs.useRoot() && Prefs.useTransparentProxying()) + { + Shell shellRoot = Shell.startRootShell(); + + disableTransparentProxy(shellRoot); + enableTransparentProxy(shellRoot); + + shellRoot.close(); + } + + /** + if (Prefs.useVpn()) //we need to turn on VPN here so the proxy is running + { + enableVpnProxy(); + }*/ + + + getHiddenServiceHostname (); + } + else + { + showToolbarNotification(getString(R.string.unable_to_start_tor), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr); + } + shellUser.close(); - if (Prefs.bridgesEnabled()) - if (Prefs.useVpn() && !mIsLollipop) - customEnv.add("TOR_PT_PROXY=socks5://127.0.0.1:" + OrbotVpnService.mSocksProxyPort); - - String baseDirectory = OrbotApp.fileTor.getParent(); - Shell shellUser = Shell.startShell(customEnv, baseDirectory); - - boolean success = runTorShellCmd(shellUser); - - if (success) - { - if (mPortHTTP != -1) - runPolipoShellCmd(shellUser); - - if (Prefs.useRoot() && Prefs.useTransparentProxying()) - { - Shell shellRoot = Shell.startRootShell(); - - disableTransparentProxy(shellRoot); - enableTransparentProxy(shellRoot); - - shellRoot.close(); - } - - if (Prefs.useVpn()) //we need to turn on VPN here so the proxy is running - { - enableVpnProxy(); - } - - - getHiddenServiceHostname (); - } - else - { - showToolbarNotification(getString(R.string.unable_to_start_tor), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr); - } - shellUser.close(); - - } catch (CannotKillException e) { - logException(e.getMessage(), e); - showToolbarNotification(getString(R.string.unable_to_reset_tor), - ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr); - stopTor(); } catch (Exception e) { logException("Unable to start Tor: " + e.toString(), e); showToolbarNotification( @@ -1128,15 +1076,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon String torProcId = conn.getInfo("process/pid"); - //remove this for now until we can make a clean way to share logs from internal storage - /** - if (ENABLE_DEBUG_LOG) - { - File fileLog2 = new File(getFilesDir(),"orbot-tor-log.txt"); - fileLog2.setReadable(true); - conn.setConf("Log", "debug file " + fileLog2.getCanonicalPath()); - }*/ - String confSocks = conn.getInfo("net/listeners/socks"); StringTokenizer st = new StringTokenizer(confSocks," "); @@ -1144,6 +1083,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon confSocks = confSocks.substring(0,confSocks.length()-1); mPortSOCKS = Integer.parseInt(confSocks); + /** if (!isReconnect) //if we are reconnected then we don't need to reset the ports { @@ -1211,7 +1151,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon conn.setConf(confLines); - sendCallbackLogMessage("Local DNSPort port: " + transPort); + sendCallbackLogMessage("Local DNSPort port: " + dnsPort); } catch (Exception e) @@ -1220,7 +1160,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } - } + }*/ return Integer.parseInt(torProcId); @@ -1344,7 +1284,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon intent.setAction("refresh"); startService(intent); - updateConfiguration("DNSListenAddress","10.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT,false); + //updateConfiguration("DNSPort",TOR_VPN_DNS_LISTEN_ADDRESS + ":" + TorServiceConstants.TOR_DNS_PORT_DEFAULT,false); + //updateConfiguration("DNSPort",TorServiceConstants.TOR_DNS_PORT_DEFAULT+"",false); updateConfiguration("DisableNetwork","0", false); saveConfiguration(); @@ -1570,17 +1511,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon URLConnection conn = null; - Proxy proxy = null; - - if (!Prefs.useVpn()) //if not on the VPN then we should proxy - { - proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118)); - conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy); - } - else - { - conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(); - } + Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118)); + conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy); conn.setRequestProperty("Connection","Close"); conn.setConnectTimeout(60000); @@ -1977,8 +1909,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon shell.close(); } - else if (Prefs.useVpn()) //we need to turn on VPN here so the proxy is running - refreshVpnProxy(); + // else if (Prefs.useVpn()) //we need to turn on VPN here so the proxy is running + // refreshVpnProxy(); } } @@ -2279,7 +2211,10 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon if (Prefs.useVpn()) { - extraLines.append("DNSListenAddress" + ' ' + "10.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT).append('\n'); + + //extraLines.append("DNSPort ").append(TOR_VPN_DNS_LISTEN_ADDRESS).append(":").append(TorServiceConstants.TOR_DNS_PORT_DEFAULT).append("\n"); + //extraLines.append("DNSPort ").append(TorServiceConstants.TOR_DNS_PORT_DEFAULT).append("\n"); + } return true; diff --git a/src/org/torproject/android/service/TorServiceConstants.java b/src/org/torproject/android/service/TorServiceConstants.java index 058bdc1d..6c8d546e 100644 --- a/src/org/torproject/android/service/TorServiceConstants.java +++ b/src/org/torproject/android/service/TorServiceConstants.java @@ -8,7 +8,7 @@ import android.content.Intent; public interface TorServiceConstants { public final static String TOR_APP_USERNAME = "org.torproject.android"; - public final static String ORWEB_APP_USERNAME = "info.guardianproject.browser"; + public final static String BROWSER_APP_USERNAME = "info.guardianproject.orfox"; public final static String DIRECTORY_TOR_BINARY = "bin"; public final static String DIRECTORY_TOR_DATA = "data"; @@ -33,6 +33,9 @@ public interface TorServiceConstants { public final static String GEOIP_ASSET_KEY = "geoip"; public final static String GEOIP6_ASSET_KEY = "geoip6"; + //tun2socks VPN + public final static String TUN2SOCKS_ASSET_KEY = "tun2socks"; + //various console cmds public final static String SHELL_CMD_CHMOD = "chmod"; @@ -53,12 +56,16 @@ public interface TorServiceConstants { public final static String IP_LOCALHOST = "127.0.0.1"; public final static int UPDATE_TIMEOUT = 1000; public final static int TOR_TRANSPROXY_PORT_DEFAULT = 9040; + public final static int STANDARD_DNS_PORT = 53; public final static int TOR_DNS_PORT_DEFAULT = 5400; - public final static int CONTROL_PORT_DEFAULT = 9051; + public final static String TOR_VPN_DNS_LISTEN_ADDRESS = "127.0.0.1"; + + public final static int CONTROL_PORT_DEFAULT = 9051; public final static int HTTP_PROXY_PORT_DEFAULT = 8118; // like Privoxy! public final static int SOCKS_PROXY_PORT_DEFAULT = 9050; + //path to check Tor against public final static String URL_TOR_CHECK = "https://check.torproject.org"; @@ -128,7 +135,7 @@ public interface TorServiceConstants { public static final String CMD_VPN_CLEAR = "vpnclear"; public static final String CMD_UPDATE_TRANS_PROXY = "update"; - public static final String BINARY_TOR_VERSION = "0.2.6.10"; + public static final String BINARY_TOR_VERSION = "0.2.7.5"; public static final String PREF_BINARY_TOR_VERSION_INSTALLED = "BINARY_TOR_VERSION_INSTALLED"; //obfsproxy diff --git a/src/org/torproject/android/service/TorServiceUtils.java b/src/org/torproject/android/service/TorServiceUtils.java index 609a8e2a..91d48e95 100644 --- a/src/org/torproject/android/service/TorServiceUtils.java +++ b/src/org/torproject/android/service/TorServiceUtils.java @@ -9,7 +9,11 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.StringTokenizer; +import org.sufficientlysecure.rootcommands.Shell; +import org.sufficientlysecure.rootcommands.command.SimpleCommand; +import org.torproject.android.OrbotApp; import org.torproject.android.OrbotConstants; +import org.torproject.android.Prefs; import android.annotation.SuppressLint; import android.annotation.TargetApi; @@ -122,4 +126,45 @@ public class TorServiceUtils implements TorServiceConstants { return context.getSharedPreferences(OrbotConstants.PREF_TOR_SHARED_PREFS,Context.MODE_PRIVATE); } + + public static void killProcess(File fileProcBin) throws Exception { + killProcess(fileProcBin, "-9"); // this is -KILL + } + + public static void killProcess(File fileProcBin, String signal) throws Exception { + int procId = -1; + int killAttempts = 0; + + while ((procId = TorServiceUtils.findProcessId(fileProcBin.getCanonicalPath())) != -1) { + killAttempts++; + //logNotice("Found " + fileProcBin.getName() + " PID=" + procId + " - killing now..."); + String pidString = String.valueOf(procId); + /* + * first try as the normal app user to be safe, then if that fails, + * try root since the process might be left over from + * uninstall/reinstall with different UID. + */ + Shell shell; + if (Prefs.useRoot() && killAttempts > 2) { + shell = Shell.startRootShell(); + Log.i(OrbotApp.TAG, "using a root shell"); + } else { + shell = Shell.startShell(); + } + shell.add(new SimpleCommand("busybox killall " + signal + " " + fileProcBin.getName())); + shell.add(new SimpleCommand("toolbox kill " + signal + " " + pidString)); + shell.add(new SimpleCommand("busybox kill " + signal + " " + pidString)); + shell.add(new SimpleCommand("kill " + signal + " " + pidString)); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // ignored + } + shell.close(); + if (killAttempts > 4) + throw new Exception("Cannot kill: " + fileProcBin.getAbsolutePath()); + } + } + + } diff --git a/src/org/torproject/android/vpn/OrbotVpnService.java b/src/org/torproject/android/vpn/OrbotVpnService.java index 2fe3daa7..709a3da4 100644 --- a/src/org/torproject/android/vpn/OrbotVpnService.java +++ b/src/org/torproject/android/vpn/OrbotVpnService.java @@ -20,6 +20,9 @@ import java.net.InetAddress; import java.util.ArrayList; import java.util.Locale; +import org.sufficientlysecure.rootcommands.Shell; +import org.sufficientlysecure.rootcommands.command.SimpleCommand; +import org.torproject.android.OrbotApp; import org.torproject.android.service.TorServiceConstants; import org.torproject.android.service.TorServiceUtils; import org.torproject.android.settings.AppManager; @@ -59,7 +62,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { private final static int VPN_MTU = 1500; - private final static boolean isLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + private final static boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; private boolean isRestart = false; @@ -85,7 +88,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { mHandler = new Handler(this); } - if (!isLollipop) + if (!mIsLollipop) { startSocksBypass(); } @@ -105,8 +108,8 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { { Log.d(TAG,"refresh OrbotVPNService service!"); - //if (!isLollipop) - ///startSocksBypass(); + if (!mIsLollipop) + startSocksBypass(); if (!isRestart) setupTun2Socks(); @@ -181,7 +184,8 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { private void stopVPN () { - //stopSocksBypass (); + if (mIsLollipop) + stopSocksBypass (); if (mInterface != null){ try @@ -207,9 +211,6 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { mThreadVPN = null; - // Tun2Socks.Stop(); - - } @Override @@ -223,6 +224,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { private synchronized void setupTun2Socks() { + if (mInterface != null) //stop tun2socks now to give it time to clean up { isRestart = true; @@ -244,25 +246,35 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { } final String vpnName = "OrbotVPN"; - final String virtualGateway = "10.0.0.1"; - final String virtualIP = "10.0.0.2"; + final String localhost = "127.0.0.1"; + + // final String virtualGateway = "10.0.0.1"; + final String virtualIP = "192.168.10.1"; final String virtualNetMask = "255.255.255.0"; - final String localSocks = "127.0.0.1:" + final String dummyDNS = "8.8.8.8"; //this is intercepted by the tun2socks library, but we must put in a valid DNS to start + final String defaultRoute = "0.0.0.0"; + + final String localSocks = localhost + ':' + String.valueOf(TorServiceConstants.SOCKS_PROXY_PORT_DEFAULT); - final String localDNS = "10.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT; + + final String localDNS = localhost + ':' + String.valueOf(TorServiceConstants.TOR_DNS_PORT_DEFAULT); + final boolean localDnsTransparentProxy = true; Builder builder = new Builder(); builder.setMtu(VPN_MTU); - builder.addAddress(virtualGateway,28); - builder.setSession(vpnName); - builder.addRoute("0.0.0.0",0); + builder.addAddress(virtualIP,24); + builder.setSession(vpnName); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) - { - doLollipopAppRouting(builder); - } - + //route all traffic through VPN (we might offer country specific exclude lists in the future) + builder.addRoute(defaultRoute,0); + + builder.addDnsServer(dummyDNS); + builder.addRoute(dummyDNS,32); + + + if (mIsLollipop) + doLollipopAppRouting(builder); // Create a new interface using the builder and save the parameters. ParcelFileDescriptor newInterface = builder.setSession(mSessionName) @@ -278,9 +290,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { mInterface = newInterface; - Thread.sleep(4000); - - Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , true); + Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , localDnsTransparentProxy); isRestart = false; @@ -296,6 +306,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { mThreadVPN.start(); } + @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void doLollipopAppRouting (Builder builder) throws NameNotFoundException { @@ -335,53 +346,4 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { super.onRevoke(); } - /* - private void monitorSocketsFD () - { - - final String fdPath = "/proc/self/fd/"; - - new Thread () - { - public void run () - { - while (mThreadVPN != null) - { - try { - Thread.sleep(500); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - try - { - - File fileDir = new File(fdPath); - File[] files = fileDir.listFiles(); - if (files != null) - for (File file : files) - { - String cPath = file.getCanonicalPath(); - - if (cPath.contains("socket")) - { - Log.d(TAG,"found FD for socket: " + file.getAbsolutePath()); - - protect(Integer.parseInt(file.getName())); - - } - - } - } - catch (Exception e) - { - Log.e(TAG,"error getting fd: " + fdPath,e); - } - } - } - }.start(); - - } - */ } diff --git a/src/org/torproject/android/vpn/VPNEnableActivity.java b/src/org/torproject/android/vpn/VPNEnableActivity.java index 273a1cdf..9083b45f 100644 --- a/src/org/torproject/android/vpn/VPNEnableActivity.java +++ b/src/org/torproject/android/vpn/VPNEnableActivity.java @@ -86,7 +86,7 @@ public class VPNEnableActivity extends Activity { { Log.d("VPNEnableActivity","VPN enabled, starting Tor..."); sendIntentToService(TorServiceConstants.CMD_VPN); - + /** Handler h = new Handler(); h.postDelayed(new Runnable () { @@ -96,6 +96,8 @@ public class VPNEnableActivity extends Activity { finish(); } }, 1000); + */ + } else