diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 8941c9a8..bdf8bfbd 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="org.torproject.android" android:versionName="1.0.5" android:versionCode="11"> @@ -33,8 +33,7 @@ - - + diff --git a/CHANGELOG b/CHANGELOG index 17fa7137..d547b807 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ NOTE: Specific #s below correspond to Trac tickets logged and maintained at https://trac.torproject.org/projects/tor/ +1.0.5 +- Removed unused Socks client code from android.net package 1.0.4 - Added Russian, Persian, Arabic and other .po translations (see res/values-* folders) diff --git a/assets/torrc b/assets/torrc index b381fe7b..5f067b24 100644 --- a/assets/torrc +++ b/assets/torrc @@ -1,6 +1,6 @@ SocksPort 9050 -SocksListenAddress 127.0.0.1 -SafeSocks 1 +TestSocks 1 +WarnUnsafeSocks 1 Log notice stdout DataDirectory /data/data/org.torproject.android/data ControlPort 9051 diff --git a/default.properties b/default.properties index 08ad68f1..c5d5335e 100644 --- a/default.properties +++ b/default.properties @@ -10,5 +10,5 @@ # Indicates whether an apk should be generated for each density. split.density=false # Project target. -target=android-4 +target=android-8 apk-configurations= diff --git a/res/values/strings.xml b/res/values/strings.xml index 4ad29881..74876098 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -50,6 +50,13 @@ Tor Everything Proxy traffic for all apps through Tor +Port Proxy Fallback +WARNING: Circumvents common ports (80, 443, etc). *USE ONLY* if \'All\' or \'App\' mode doesn\'t work. + +Port List +List of ports to proxy. *USE ONLY* if \'All\' or \'App\' mode doesn\'t work +Enter ports to proxy + Tor binaries successfully installed! The Tor binary files were unable to be installed. Please check the log and notify tor-assistants@torproject.org diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 2c6b152c..271dbdf0 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -33,7 +33,19 @@ android:summary="Choose Apps to Route Through Tor" android:enabled="true"/> + + diff --git a/src/org/torproject/android/Orbot.java b/src/org/torproject/android/Orbot.java index d0abf649..a0d5a19f 100644 --- a/src/org/torproject/android/Orbot.java +++ b/src/org/torproject/android/Orbot.java @@ -825,7 +825,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants //unbindService(); - //stopService(new Intent(ITorService.class.getName())); + stopService(new Intent(ITorService.class.getName())); } diff --git a/src/org/torproject/android/net/ModSSLSocketFactory.java b/src/org/torproject/android/net/ModSSLSocketFactory.java deleted file mode 100644 index 7edea6c2..00000000 --- a/src/org/torproject/android/net/ModSSLSocketFactory.java +++ /dev/null @@ -1,442 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java $ - * $Revision: 659194 $ - * $Date: 2008-05-22 11:33:47 -0700 (Thu, 22 May 2008) $ - * - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package org.torproject.android.net; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.UnknownHostException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.UnrecoverableKeyException; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; - -import org.apache.http.conn.scheme.HostNameResolver; -import org.apache.http.conn.scheme.LayeredSocketFactory; -import org.apache.http.conn.ssl.AllowAllHostnameVerifier; -import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.conn.ssl.StrictHostnameVerifier; -import org.apache.http.conn.ssl.X509HostnameVerifier; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; - - - -/** - * Layered socket factory for TLS/SSL connections, based on JSSE. - *. - *

- * SSLSocketFactory can be used to validate the identity of the HTTPS - * server against a list of trusted certificates and to authenticate to - * the HTTPS server using a private key. - *

- * - *

- * SSLSocketFactory will enable server authentication when supplied with - * a {@link KeyStore truststore} file containg one or several trusted - * certificates. The client secure socket will reject the connection during - * the SSL session handshake if the target HTTPS server attempts to - * authenticate itself with a non-trusted certificate. - *

- * - *

- * Use JDK keytool utility to import a trusted certificate and generate a truststore file: - *

- *     keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
- *    
- *

- * - *

- * SSLSocketFactory will enable client authentication when supplied with - * a {@link KeyStore keystore} file containg a private key/public certificate - * pair. The client secure socket will use the private key to authenticate - * itself to the target HTTPS server during the SSL session handshake if - * requested to do so by the server. - * The target HTTPS server will in its turn verify the certificate presented - * by the client in order to establish client's authenticity - *

- * - *

- * Use the following sequence of actions to generate a keystore file - *

- *
    - *
  • - *

    - * Use JDK keytool utility to generate a new key - *

    keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore
    - * For simplicity use the same password for the key as that of the keystore - *

    - *
  • - *
  • - *

    - * Issue a certificate signing request (CSR) - *

    keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore
    - *

    - *
  • - *
  • - *

    - * Send the certificate request to the trusted Certificate Authority for signature. - * One may choose to act as her own CA and sign the certificate request using a PKI - * tool, such as OpenSSL. - *

    - *
  • - *
  • - *

    - * Import the trusted CA root certificate - *

    keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore
    - *

    - *
  • - *
  • - *

    - * Import the PKCS#7 file containg the complete certificate chain - *

    keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore
    - *

    - *
  • - *
  • - *

    - * Verify the content the resultant keystore file - *

    keytool -list -v -keystore my.keystore
    - *

    - *
  • - *
- * @author Oleg Kalnichevski - * @author Julius Davies - */ - -public class ModSSLSocketFactory implements LayeredSocketFactory { - - public static final String TLS = "TLS"; - public static final String SSL = "SSL"; - public static final String SSLV2 = "SSLv2"; - - public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER - = new AllowAllHostnameVerifier(); - - public static final X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER - = new BrowserCompatHostnameVerifier(); - - public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER - = new StrictHostnameVerifier(); - /** - * The factory using the default JVM settings for secure connections. - */ - private static ModSSLSocketFactory DEFAULT_FACTORY = null; - - /** - * Gets an singleton instance of the SSLProtocolSocketFactory. - * @return a SSLProtocolSocketFactory - */ - public static ModSSLSocketFactory getSocketFactory() { - if (DEFAULT_FACTORY == null) { - DEFAULT_FACTORY = new ModSSLSocketFactory(); - } - return DEFAULT_FACTORY; - } - - private final SSLContext sslcontext; - private final SSLSocketFactory socketfactory; - //private final HostNameResolver nameResolver; - private X509HostnameVerifier hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; - private SocksSocketFactory mSocksSocketFactory = null; - - public ModSSLSocketFactory( - String algorithm, - final KeyStore keystore, - final String keystorePassword, - final KeyStore truststore, - final SecureRandom random, - final HostNameResolver nameResolver) - throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException - { - super(); - if (algorithm == null) { - algorithm = SSL; - } - KeyManager[] keymanagers = null; - if (keystore != null) { - keymanagers = createKeyManagers(keystore, keystorePassword); - } - TrustManager[] trustmanagers = null; - if (truststore != null) { - trustmanagers = createTrustManagers(truststore); - } - this.sslcontext = SSLContext.getInstance(algorithm); - this.sslcontext.init(keymanagers, trustmanagers, random); - this.socketfactory = SSLSocketFactory.getSocketFactory(); - //this.nameResolver = nameResolver; - - - } - - public ModSSLSocketFactory( - final KeyStore keystore, - final String keystorePassword, - final KeyStore truststore) - throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException - { - this(SSL, keystore, keystorePassword, truststore, null, null); - } - - public ModSSLSocketFactory(final KeyStore keystore, final String keystorePassword) - throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException - { - this(SSL, keystore, keystorePassword, null, null, null); - } - - public ModSSLSocketFactory(final KeyStore truststore) - throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException - { - this(SSL, null, null, truststore, null, null); - } - - /** - * Constructs an HttpClient SSLSocketFactory backed by the given JSSE - * SSLSocketFactory. - * - * @hide - */ - public ModSSLSocketFactory(SSLSocketFactory socketfactory) { - super(); - this.sslcontext = null; - this.socketfactory = socketfactory; - //this.nameResolver = null; - } - - /** - * Creates the default SSL socket factory. - * This constructor is used exclusively to instantiate the factory for - * {@link #getSocketFactory getSocketFactory}. - */ - private ModSSLSocketFactory() { - super(); - this.sslcontext = null; - this.socketfactory = SSLSocketFactory.getSocketFactory(); - //this.nameResolver = null; - - this.mSocksSocketFactory = new SocksSocketFactory("127.0.0.1",9050); - } - - private static KeyManager[] createKeyManagers(final KeyStore keystore, final String password) - throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { - if (keystore == null) { - throw new IllegalArgumentException("Keystore may not be null"); - } - KeyManagerFactory kmfactory = KeyManagerFactory.getInstance( - KeyManagerFactory.getDefaultAlgorithm()); - kmfactory.init(keystore, password != null ? password.toCharArray(): null); - return kmfactory.getKeyManagers(); - } - - private static TrustManager[] createTrustManagers(final KeyStore keystore) - throws KeyStoreException, NoSuchAlgorithmException { - if (keystore == null) { - throw new IllegalArgumentException("Keystore may not be null"); - } - TrustManagerFactory tmfactory = TrustManagerFactory.getInstance( - TrustManagerFactory.getDefaultAlgorithm()); - tmfactory.init(keystore); - return tmfactory.getTrustManagers(); - } - - - // non-javadoc, see interface org.apache.http.conn.SocketFactory - public Socket createSocket() - throws IOException { - - // SSL Sockets don't work at the moment. - //throw new SSLException("SSL socket functionality broken"); - // the cast makes sure that the factory is working as expected - return (SSLSocket) this.socketfactory.createSocket(); - //return new Socket(); - //return null; - - } - - - // non-javadoc, see interface org.apache.http.conn.SocketFactory - public Socket connectSocket( - final Socket sock, - final String host, - final int port, - final InetAddress localAddress, - int localPort, - final HttpParams params - ) throws IOException { - - if (host == null) { - throw new IllegalArgumentException("Target host may not be null."); - } - if (params == null) { - throw new IllegalArgumentException("Parameters may not be null."); - } - - //Socket underlying = (Socket) - // ((sock != null) ? sock : createSocket()); - Socket underlying = null; - - /*sock; - if (underlying == null)// underlying = new Socket(); - { - underlying = mSocksSocketFactory.createSocket(); - - }*/ - - Socket sSocket = mSocksSocketFactory.connectSocket(underlying, host, port, localAddress, localPort, params); - - // SSLSocket sslsock = (SSLSocket) socketfactory.connectSocket(sSocket, host, port, localAddress, localPort, params); - SSLSocket sslsock = (SSLSocket)socketfactory.createSocket(sSocket, host, port, true); - - if ((localAddress != null) || (localPort > 0)) { - - // we need to bind explicitly - if (localPort < 0) - localPort = 0; // indicates "any" - - InetSocketAddress isa = - new InetSocketAddress(localAddress, localPort); - - sslsock.bind(isa); - } - - int connTimeout = HttpConnectionParams.getConnectionTimeout(params); - int soTimeout = HttpConnectionParams.getSoTimeout(params); - - InetSocketAddress remoteAddress; -// if (this.nameResolver != null) { -// remoteAddress = new InetSocketAddress(this.nameResolver.resolve(host), port); -// } else { - remoteAddress = new InetSocketAddress(host, port); -// } -// - - sslsock.connect(remoteAddress, connTimeout); - - // sslsock.setSoTimeout(0); - try { - hostnameVerifier.verify(host, sslsock); - // verifyHostName() didn't blowup - good! - } catch (IOException iox) { - // close the socket before re-throwing the exception - try { sslsock.close(); } catch (Exception x) { } - throw iox; - } - - return sslsock; - - } - - - /** - * Checks whether a socket connection is secure. - * This factory creates TLS/SSL socket connections - * which, by default, are considered secure. - *
- * Derived classes may override this method to perform - * runtime checks, for example based on the cypher suite. - * - * @param sock the connected socket - * - * @return true - * - * @throws IllegalArgumentException if the argument is invalid - */ - public boolean isSecure(Socket sock) - throws IllegalArgumentException { - - if (sock == null) { - throw new IllegalArgumentException("Socket may not be null."); - } - // This instanceof check is in line with createSocket() above. - if (!(sock instanceof SSLSocket)) { - throw new IllegalArgumentException - ("Socket not created by this factory."); - } - // This check is performed last since it calls the argument object. - if (sock.isClosed()) { - throw new IllegalArgumentException("Socket is closed."); - } - - return true; - - } // isSecure - - - // non-javadoc, see interface LayeredSocketFactory - public Socket createSocket( - final Socket socket, - final String host, - final int port, - final boolean autoClose - ) throws IOException, UnknownHostException { - SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket( - socket, - host, - port, - autoClose - ); - hostnameVerifier.verify(host, sslSocket); - // verifyHostName() didn't blowup - good! - return sslSocket; - } - - public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) { - if ( hostnameVerifier == null ) { - throw new IllegalArgumentException("Hostname verifier may not be null"); - } - this.hostnameVerifier = hostnameVerifier; - } - - public X509HostnameVerifier getHostnameVerifier() { - return hostnameVerifier; - } - - public class SSLException extends IOException { - private static final long serialVersionUID = 1L; - - public SSLException(String msg) { - super(msg); - } - }; - - -} \ No newline at end of file diff --git a/src/org/torproject/android/net/MyDefaultClientConnectionOperator.java b/src/org/torproject/android/net/MyDefaultClientConnectionOperator.java deleted file mode 100644 index 94200880..00000000 --- a/src/org/torproject/android/net/MyDefaultClientConnectionOperator.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.torproject.android.net; - -import java.io.IOException; -import java.net.ConnectException; -import java.net.InetAddress; -import java.net.Socket; - -import org.apache.http.HttpHost; -import org.apache.http.conn.HttpHostConnectException; -import org.apache.http.conn.OperatedClientConnection; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.scheme.SocketFactory; -import org.apache.http.impl.conn.DefaultClientConnectionOperator; -import org.apache.http.params.HttpParams; -import org.apache.http.protocol.HttpContext; - -public class MyDefaultClientConnectionOperator extends - DefaultClientConnectionOperator { - - public MyDefaultClientConnectionOperator(SchemeRegistry schemes) { - super(schemes); - } - - @Override - public void openConnection(OperatedClientConnection conn, HttpHost target, - InetAddress local, HttpContext context, HttpParams params) - throws IOException { - if (conn == null) { - throw new IllegalArgumentException - ("Connection must not be null."); - } - if (target == null) { - throw new IllegalArgumentException - ("Target host must not be null."); - } - // local address may be null - //@@@ is context allowed to be null? - if (params == null) { - throw new IllegalArgumentException - ("Parameters must not be null."); - } - if (conn.isOpen()) { - throw new IllegalArgumentException - ("Connection must not be open."); - } - - final Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); - final SocketFactory sf = schm.getSocketFactory(); - - Socket sock = sf.createSocket(); - conn.opening(sock, target); - - try { - Socket connsock = sf.connectSocket(sock, target.getHostName(), - schm.resolvePort(target.getPort()), - local, 0, params); - - if (sock != connsock) { - sock = connsock; - conn.opening(sock, target); - } - } catch (ConnectException ex) { - throw new HttpHostConnectException(target, ex); - } - prepareSocket(sock, context, params); - conn.openCompleted(sf.isSecure(sock), params); - } - -} diff --git a/src/org/torproject/android/net/MyThreadSafeClientConnManager.java b/src/org/torproject/android/net/MyThreadSafeClientConnManager.java deleted file mode 100644 index 77e9c2ca..00000000 --- a/src/org/torproject/android/net/MyThreadSafeClientConnManager.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.torproject.android.net; - -import org.apache.http.conn.ClientConnectionOperator; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; -import org.apache.http.params.HttpParams; - - -public class MyThreadSafeClientConnManager extends ThreadSafeClientConnManager { - - public MyThreadSafeClientConnManager(HttpParams params, SchemeRegistry schreg) { - super(params, schreg); - - } - - @Override - protected ClientConnectionOperator createConnectionOperator( - SchemeRegistry schreg) { - return new MyDefaultClientConnectionOperator(schreg); - } -} diff --git a/src/org/torproject/android/net/SOCKSHttpClient.java b/src/org/torproject/android/net/SOCKSHttpClient.java deleted file mode 100644 index d49d67ce..00000000 --- a/src/org/torproject/android/net/SOCKSHttpClient.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.torproject.android.net; - -import org.apache.http.HttpVersion; -import org.apache.http.conn.ClientConnectionManager; -import org.apache.http.conn.scheme.PlainSocketFactory; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.HttpParams; -import org.apache.http.params.HttpProtocolParams; - -public class SOCKSHttpClient extends DefaultHttpClient { - - private final static String DEFAULT_HOST = "127.0.0.1"; - private final static int DEFAULT_PORT = 9050; - - private static ClientConnectionManager ccm = null; - private static HttpParams params = null; - - public SOCKSHttpClient () - { - - super(initConnectionManager(), initParams()); - - - } - - private void setSystemProperties () - { -// System.getProperties().put("socks.proxySet","true"); - // System.getProperties().put("socks.proxyHost",DEFAULT_HOST); - // System.getProperties().put("socks.proxyPort", DEFAULT_PORT+""); - - } - - private static ClientConnectionManager initConnectionManager () - { - if (ccm == null) - { - SchemeRegistry supportedSchemes = new SchemeRegistry(); - - - supportedSchemes.register(new Scheme("http", - SocksSocketFactory.getSocketFactory(), 80)); - - supportedSchemes.register(new Scheme("https", - ModSSLSocketFactory.getSocketFactory(), 443)); - - ccm = new MyThreadSafeClientConnManager(initParams(), supportedSchemes); - } - - return ccm; - } - - private static HttpParams initParams () - { - if (params == null) - { - // prepare parameters - params = new BasicHttpParams(); - HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); - HttpProtocolParams.setContentCharset(params, "UTF-8"); - HttpProtocolParams.setUseExpectContinue(params, true); - } - - return params; - } -} diff --git a/src/org/torproject/android/net/SocksClient.java b/src/org/torproject/android/net/SocksClient.java deleted file mode 100644 index bf8fd49d..00000000 --- a/src/org/torproject/android/net/SocksClient.java +++ /dev/null @@ -1,146 +0,0 @@ -/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */ -/* See LICENSE for licensing information */ - -/** SOCKS aware echo client*/ - -package org.torproject.android.net; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -import net.sourceforge.jsocks.socks.InetRange; -import net.sourceforge.jsocks.socks.Proxy; -import net.sourceforge.jsocks.socks.SocksException; -import net.sourceforge.jsocks.socks.SocksSocket; - -import org.torproject.android.TorConstants; - -import android.util.Log; - - -public class SocksClient implements Runnable { - - @SuppressWarnings("unused") - private int port; - - @SuppressWarnings("unused") - private InetAddress hostIP; - - private Socket ss; - private InputStream in; - private OutputStream out; - - @SuppressWarnings("unused") -private static final int BUF_SIZE = 1024; - private static final String IP_LOCALHOST = "127.0.0.1"; - - public SocksClient(String host,int port) - throws IOException,UnknownHostException,SocksException{ - this.port = port; - - ss = new SocksSocket(host, port); - out = ss.getOutputStream(); - in = ss.getInputStream(); - Log.d(getClass().getName(),"Connected..."); - Log.d(getClass().getName(),"TO: "+host+":"+port); - Log.d(getClass().getName(),"ViaProxy: "+ss.getLocalAddress().getHostAddress() - +":"+ss.getLocalPort()); - - } - - public void close()throws IOException{ - ss.close(); - } - public void send(String s) throws IOException{ - out.write(s.getBytes()); - } - - public void run(){ - byte[] buf = new byte[1024]; - int bytes_read; - try{ - while((bytes_read = in.read(buf)) > 0){ - System.out.write(buf,0,bytes_read); - } - }catch(IOException io_ex){ - io_ex.printStackTrace(); - } - } - - public static void usage(){ - System.err.print( - "Usage: java SocksTest host port [socksHost socksPort]\n"); - } - - - public static void main(String args[]){ - int port; - String host; - int proxyPort; - String proxyHost; - - if(args.length > 1 && args.length < 5){ - try{ - - host = args[0]; - port = Integer.parseInt(args[1]); - - proxyPort =(args.length > 3)? Integer.parseInt(args[3]) - : 9050; - - host = args[0]; - proxyHost =(args.length > 2)? args[2] - : IP_LOCALHOST; - - Proxy.setDefaultProxy(proxyHost,proxyPort,"KOUKY001"); - //Proxy.setDefaultProxy(proxyHost,proxyPort); - InetRange inetRange = new InetRange(); - inetRange.add(InetAddress.getByName("localhost")); - Proxy.getDefaultProxy().setDirect(inetRange); - - - SocksClient st = new SocksClient(host,port); - Thread thread = new Thread(st); - thread.start(); - - BufferedReader in = new BufferedReader( - new InputStreamReader(System.in)); - String s; - - s = in.readLine(); - while(s != null){ - st.send(s+"\r\n"); - //try{ - //Thread.currentThread().sleep(10); - //}catch(InterruptedException i_ex){ - //} - s = in.readLine(); - } - st.close(); - System.exit(1); - - }catch(SocksException s_ex){ - System.err.println("SocksException:"+s_ex); - s_ex.printStackTrace(); - System.exit(1); - }catch(IOException io_ex){ - io_ex.printStackTrace(); - System.exit(1); - }catch(NumberFormatException num_ex){ - usage(); - num_ex.printStackTrace(); - System.exit(1); - } - - }else{ - usage(); - } - } - -}//End of class diff --git a/src/org/torproject/android/net/SocksSocketFactory.java b/src/org/torproject/android/net/SocksSocketFactory.java deleted file mode 100644 index fa2ca4f7..00000000 --- a/src/org/torproject/android/net/SocksSocketFactory.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Shadow - Anonymous web browser for Android devices - * Copyright (C) 2009 Connell Gauld - * - * Thanks to University of Cambridge, - * Alastair Beresford and Andrew Rice - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -package org.torproject.android.net; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -import net.sourceforge.jsocks.socks.Socks5Proxy; -import net.sourceforge.jsocks.socks.SocksException; -import net.sourceforge.jsocks.socks.SocksSocket; - - -import org.apache.http.conn.ConnectTimeoutException; -import org.apache.http.conn.scheme.SocketFactory; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; - -import android.util.Log; - - -/** - * Provides sockets for an HttpClient connection. - * @author cmg47 - * - */ -public class SocksSocketFactory implements SocketFactory { - - SocksSocket server = null; - private static Socks5Proxy sProxy = null; - - private final static String DEFAULT_HOST = "127.0.0.1"; - private final static int DEFAULT_PORT = 9050; - - /** - * Construct a SocksSocketFactory that uses the provided SOCKS proxy. - * @param proxyaddress the IP address of the SOCKS proxy - * @param proxyport the port of the SOCKS proxy - */ - public SocksSocketFactory(String proxyaddress, int proxyport) { - - - try { - sProxy = new Socks5Proxy(proxyaddress, proxyport); - } catch (UnknownHostException e) { - // TODO Auto-generated catch block - Log.d("TOR_SERVICE","SocksSF couldn't connect",e); - } - - sProxy.resolveAddrLocally(false); - - - } - - public Socket connectSocket(Socket sock, String host, int port, - InetAddress localAddress, int localPort, HttpParams params) throws IOException, - UnknownHostException, ConnectTimeoutException { - - Log.d("TOR_SERVICE","SocksSocketFactory: connectSocket: " + host + ":" + port); - - if (host == null) { - throw new IllegalArgumentException("Target host may not be null."); - } - if (params == null) { - throw new IllegalArgumentException("Parameters may not be null."); - } - - // int timeout = HttpConnectionParams.getConnectionTimeout(params); - - // Pipe this socket over the proxy - // sock = mSocksProxy.connectSocksProxy(sock, host, port, timeout); - - - - try { - sock = new SocksSocket(sProxy,host, port); - - - - sock.setSoTimeout(0); //indef - - - if ((localAddress != null) || (localPort > 0)) { - - // we need to bind explicitly - if (localPort < 0) - localPort = 0; // indicates "any" - - InetSocketAddress isa = - new InetSocketAddress(localAddress, localPort); - sock.bind(isa); - } - - - } catch (SocksException e) { - Log.e("TOR_SERVICE","error connecting socks to" + host + ":" + port,e); - } catch (UnknownHostException e) { - Log.e("TOR_SERVICE","error connecting socks to" + host + ":" + port,e); - } - - return sock; - - } - - - - public Socket createSocket() throws IOException { - return new Socket(); - } - - public boolean isSecure(Socket sock) throws IllegalArgumentException { - return false; - } - - public static SocketFactory getSocketFactory () - { - return new SocksSocketFactory (DEFAULT_HOST, DEFAULT_PORT); - } - -} diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java index b1ad2beb..24d80053 100644 --- a/src/org/torproject/android/service/TorService.java +++ b/src/org/torproject/android/service/TorService.java @@ -294,6 +294,8 @@ public class TorService extends Service implements TorServiceConstants, Runnable private void killTorProcess () throws Exception { + //android.os.Debug.waitForDebugger(); + StringBuilder log = new StringBuilder(); int procId = -1; @@ -301,9 +303,9 @@ public class TorService extends Service implements TorServiceConstants, Runnable { logNotice("Using control port to shutdown Tor"); + try { logNotice("sending SHUTDOWN signal to Tor process"); - conn.shutdownTor("SHUTDOWN"); @@ -313,30 +315,18 @@ public class TorService extends Service implements TorServiceConstants, Runnable conn = null; } - else - { - - logNotice("Checking for existing Tor process via path: " + torBinaryPath); - procId = TorServiceUtils.findProcessId(torBinaryPath); - - while (procId != -1) - { - - logNotice("Found Tor PID=" + procId + " - killing now..."); - - String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" }; - TorServiceUtils.doShellCommand(cmd,log, false, false); - - procId = TorServiceUtils.findProcessId(torBinaryPath); - } - - } - - logNotice("Checking for existing Privoxy process via path: " + privoxyPath); - procId = TorServiceUtils.findProcessId(privoxyPath); + while ((procId = TorServiceUtils.findProcessId(torBinaryPath)) != -1) + { + + logNotice("Found Tor PID=" + procId + " - killing now..."); + + String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" }; + TorServiceUtils.doShellCommand(cmd,log, false, false); - while (procId != -1) + } + + while ((procId = TorServiceUtils.findProcessId(privoxyPath)) != -1) { logNotice("Found Privoxy PID=" + procId + " - killing now..."); @@ -344,7 +334,6 @@ public class TorService extends Service implements TorServiceConstants, Runnable TorServiceUtils.doShellCommand(cmd,log, false, false); - procId = TorServiceUtils.findProcessId(privoxyPath); } } @@ -444,7 +433,6 @@ public class TorService extends Service implements TorServiceConstants, Runnable private boolean checkTorBinaries () throws Exception { - appHome = "/data/data/" + TOR_APP_USERNAME + "/"; //appHome = getApplicationContext().getFilesDir().getAbsolutePath(); @@ -1353,8 +1341,11 @@ public class TorService extends Service implements TorServiceConstants, Runnable boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false); boolean transProxyAll = prefs.getBoolean("pref_transparent_all", false); + boolean transProxyPortFallback = prefs.getBoolean("pref_transparent_port_fallback", false); + logNotice ("Transparent Proxying: " + enableTransparentProxy); + String portProxyList = prefs.getString("pref_port_list", ""); if (enabled) { @@ -1371,6 +1362,16 @@ public class TorService extends Service implements TorServiceConstants, Runnable logNotice ("TorTransProxy resp code: " + code); + //this is for Androids w/o owner module support as a circumvention only fallback + if (transProxyPortFallback) + { + StringTokenizer st = new StringTokenizer(portProxyList, ","); + + while (st.hasMoreTokens()) + TorTransProxy.setTransparentProxyingByPort(this, Integer.parseInt(st.nextToken())); + + } + return true; diff --git a/src/org/torproject/android/service/TorServiceConstants.java b/src/org/torproject/android/service/TorServiceConstants.java index 5dbc031d..caadf35d 100644 --- a/src/org/torproject/android/service/TorServiceConstants.java +++ b/src/org/torproject/android/service/TorServiceConstants.java @@ -6,7 +6,7 @@ public interface TorServiceConstants { public final static String TAG = "ORBOT"; - public static boolean LOG_OUTPUT_TO_DEBUG = false; + public static boolean LOG_OUTPUT_TO_DEBUG = true; public final static String TOR_APP_USERNAME = "org.torproject.android"; @@ -31,7 +31,7 @@ public interface TorServiceConstants { //various console cmds public final static String SHELL_CMD_CHMOD = "chmod"; - public final static String SHELL_CMD_KILL = "kill"; + public final static String SHELL_CMD_KILL = "kill -9"; public final static String SHELL_CMD_RM = "rm"; public final static String SHELL_CMD_PS = "ps"; public final static String SHELL_CMD_PIDOF = "pidof"; diff --git a/src/org/torproject/android/service/TorServiceUtils.java b/src/org/torproject/android/service/TorServiceUtils.java index 9d0c7c60..f61ea2be 100644 --- a/src/org/torproject/android/service/TorServiceUtils.java +++ b/src/org/torproject/android/service/TorServiceUtils.java @@ -3,6 +3,7 @@ package org.torproject.android.service; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; @@ -66,7 +67,6 @@ public class TorServiceUtils implements TorServiceConstants { try { procId = findProcessIdWithPS(command); - } catch (Exception e2) { @@ -87,23 +87,27 @@ public class TorServiceUtils implements TorServiceConstants { Process procPs = null; - procPs = r.exec(SHELL_CMD_PIDOF); + String baseName = new File(command).getName(); + //fix contributed my mikos on 2010.12.10 + procPs = r.exec(new String[] {SHELL_CMD_PIDOF, baseName}); + //procPs = r.exec(SHELL_CMD_PIDOF); BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream())); String line = null; - while ((line = reader.readLine())!=null) { - if (line.indexOf(command)!=-1) + + try { - //this line should just be the process id procId = Integer.parseInt(line.trim()); - - break; } + catch (NumberFormatException e) + { + logNotice("unable to parse process pid: " + line); + } } @@ -128,7 +132,7 @@ public class TorServiceUtils implements TorServiceConstants { while ((line = reader.readLine())!=null) { - if (line.indexOf(command)!=-1) + if (line.indexOf(' ' + command)!=-1) { StringTokenizer st = new StringTokenizer(line," "); diff --git a/src/org/torproject/android/service/TorTransProxy.java b/src/org/torproject/android/service/TorTransProxy.java index b9a44380..00610f93 100644 --- a/src/org/torproject/android/service/TorTransProxy.java +++ b/src/org/torproject/android/service/TorTransProxy.java @@ -42,7 +42,7 @@ public class TorTransProxy implements TorServiceConstants { out = out.substring(out.indexOf(" v")+2); out = out.substring(0,out.indexOf(":")); - return out; + return out.trim(); } @@ -221,6 +221,15 @@ public class TorTransProxy implements TorServiceConstants { logNotice("enabling transproxy for app: " + apps[i].getUsername() + "(" + apps[i].getUid() + ")"); + /* + * iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner anonymous -m tcp --syn -j REDIRECT --to-ports 9040 +iptables -t nat -A OUTPUT -p udp -m owner --uid-owner anonymous -m udp --dport 53 -j REDIRECT --to-ports 53 +iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP + */ + + + //iptables -t nat -A output -p tcp -m owner --uid-owner 100 -m tcp --sync -j REDIRECT --to-ports 9040 + //TCP script.append(baseDir); script.append("iptables -t nat"); @@ -243,7 +252,7 @@ public class TorTransProxy implements TorServiceConstants { script.append("iptables -t nat"); script.append(" -A OUTPUT -p udp -m owner --uid-owner "); script.append(apps[i].getUid()); - script.append(" --dport "); + script.append(" -m udp --dport "); script.append(STANDARD_DNS_PORT); if (ipTablesOld) @@ -256,15 +265,14 @@ public class TorTransProxy implements TorServiceConstants { script.append(" || exit\n"); - //EVERYTHING ELSE UDP - DROP! + //EVERYTHING ELSE - DROP! if (ipTablesOld) //for some reason this doesn't work on iptables 1.3.7 { - script.append(baseDir); - script.append("iptables"); - script.append(" -t nat -A OUTPUT -m owner --uid-owner "); + script.append("iptables -t nat"); + script.append(" -A OUTPUT -m owner --uid-owner "); script.append(apps[i].getUid()); - script.append(" -j DROP"); //drop all other packets as Tor won't handle them + script.append(" -j DROP"); script.append(" || exit\n"); } else @@ -310,5 +318,92 @@ public class TorTransProxy implements TorServiceConstants { return code; } + public static int setTransparentProxyingByPort(Context context, int port) throws Exception + { + + //android.os.Debug.waitForDebugger(); + + //redirectDNSResolvConf(); //not working yet + + String baseDir = findBaseDir(); + + String iptablesVersion = getIPTablesVersion(); + logNotice( "iptables version: " + iptablesVersion); + + boolean ipTablesOld = false; + if (iptablesVersion != null && iptablesVersion.startsWith("1.3")){ + ipTablesOld = true; + } + + StringBuilder script = new StringBuilder(); + + StringBuilder res = new StringBuilder(); + int code = -1; + + String[] cmdFlush = {script.toString()}; + code = TorServiceUtils.doShellCommand(cmdFlush, res, true, true); + //String msg = res.toString(); //get stdout from command + + script = new StringBuilder(); + + //TCP + //iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $srcPortNumber -j REDIRECT --to-port $dstPortNumbe + + script.append(baseDir); + script.append("iptables -t nat"); + script.append(" -A OUTPUT -p tcp"); + script.append(" --dport "); + script.append(port); + //script.append(" -m tcp --syn"); + + if (ipTablesOld) + script.append(" -j DNAT --to 127.0.0.1:"); + else + script.append(" -j REDIRECT --to-ports "); + + script.append(TOR_TRANSPROXY_PORT); + + script.append(" || exit\n"); + + script.append(baseDir); + script.append("iptables -t nat"); + script.append(" -A OUTPUT -p udp"); + script.append(" --dport "); + script.append(port); + + if (ipTablesOld) + script.append(" -j DNAT --to 127.0.0.1:"); + else + script.append(" -j REDIRECT --to-ports "); + + script.append(TOR_TRANSPROXY_PORT); + + script.append(" || exit\n"); + + //DNS + script.append(baseDir); + script.append("iptables -t nat"); + script.append(" -A OUTPUT -p udp "); + script.append(" -m udp --dport "); + script.append(STANDARD_DNS_PORT); + + if (ipTablesOld) + script.append(" -j DNAT --to 127.0.0.1:"); + else + script.append(" -j REDIRECT --to-ports "); + + script.append(TOR_DNS_PORT); + + script.append(" || exit\n"); + + + String[] cmdAdd = {script.toString()}; + code = TorServiceUtils.doShellCommand(cmdAdd, res, true, true); + String msg = res.toString(); + logNotice(cmdAdd[0] + ";errCode=" + code + ";resp=" + msg); + + return code; + } + }