├── .gitignore ├── jsocks_code1.01 ├── SocksEcho.gif ├── SocksEcho.lnk ├── socks │ ├── AuthenticationNone.java │ ├── server │ │ ├── UserValidation.java │ │ ├── UserPasswordAuthenticator.java │ │ ├── ServerAuthenticator.java │ │ ├── IdentAuthenticator.java │ │ ├── ServerAuthenticatorNone.java │ │ └── Ident.java │ ├── UDPEncapsulation.java │ ├── Authentication.java │ ├── UserPasswordAuthentication.java │ ├── SocksException.java │ ├── ProxyMessage.java │ ├── Socks4Proxy.java │ ├── Socks4Message.java │ ├── SocksServerSocket.java │ └── UDPRelayServer.java ├── test │ ├── UPSOCKS.java │ ├── TestServer.java │ ├── SocksUDPEcho.java │ ├── Echo.java │ ├── SocksTest.java │ ├── UDPEcho.java │ ├── TestClient.java │ └── TestService.java ├── socks.properties └── SOCKS.java ├── src └── main │ ├── resources │ └── jsocks │ │ └── main │ │ └── SocksEcho.gif │ └── java │ └── com │ └── runjva │ └── sourceforge │ └── jsocks │ ├── main │ ├── SocksEcho.gif │ └── SOCKS.java │ ├── server │ ├── ServerAuthenticatorNone.java │ ├── UserValidation.java │ ├── UserPasswordAuthenticator.java │ ├── ServerAuthenticator.java │ ├── ServerAuthenticatorBase.java │ ├── IdentAuthenticator.java │ └── Ident.java │ └── protocol │ ├── AuthenticationNone.java │ ├── UDPEncapsulation.java │ ├── Authentication.java │ ├── UserPasswordAuthentication.java │ ├── SocksException.java │ ├── ProxyMessage.java │ ├── Socks4Proxy.java │ ├── Socks4Message.java │ ├── UDPRelayServer.java │ └── SocksServerSocket.java ├── helpers └── com │ └── runjva │ └── sourceforge │ └── jsocks │ └── helpers │ ├── UPSOCKS.java │ ├── TestServer.java │ ├── SocksUDPEcho.java │ ├── Echo.java │ ├── SocksTest.java │ ├── UDPEcho.java │ └── TestClient.java ├── .github └── workflows │ └── maven-publish.yml ├── README.md ├── pom.xml ├── docs └── rfc1929.txt └── socks.properties /.gitignore: -------------------------------------------------------------------------------- 1 | /.settings 2 | /target 3 | /.classpath 4 | /.project 5 | /.idea 6 | -------------------------------------------------------------------------------- /jsocks_code1.01/SocksEcho.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravn/jsocks/HEAD/jsocks_code1.01/SocksEcho.gif -------------------------------------------------------------------------------- /jsocks_code1.01/SocksEcho.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravn/jsocks/HEAD/jsocks_code1.01/SocksEcho.lnk -------------------------------------------------------------------------------- /src/main/resources/jsocks/main/SocksEcho.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravn/jsocks/HEAD/src/main/resources/jsocks/main/SocksEcho.gif -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/main/SocksEcho.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravn/jsocks/HEAD/src/main/java/com/runjva/sourceforge/jsocks/main/SocksEcho.gif -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/server/ServerAuthenticatorNone.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.server; 2 | 3 | import java.io.InputStream; 4 | import java.io.OutputStream; 5 | 6 | /** 7 | * Simplest possible ServerAuthenticator implementation. Extends common base. 8 | * 9 | */ 10 | public class ServerAuthenticatorNone extends ServerAuthenticatorBase { 11 | 12 | public ServerAuthenticatorNone(InputStream in, OutputStream out) { 13 | super(in, out); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/AuthenticationNone.java: -------------------------------------------------------------------------------- 1 | package socks; 2 | 3 | /** 4 | SOCKS5 none authentication. Dummy class does almost nothing. 5 | */ 6 | public class AuthenticationNone implements Authentication{ 7 | 8 | public Object[] doSocksAuthentication(int methodId, 9 | java.net.Socket proxySocket) 10 | throws java.io.IOException{ 11 | 12 | if(methodId!=0) return null; 13 | 14 | return new Object[] { proxySocket.getInputStream(), 15 | proxySocket.getOutputStream()}; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/protocol/AuthenticationNone.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.protocol; 2 | 3 | import java.io.InputStream; 4 | import java.io.OutputStream; 5 | 6 | /** 7 | * SOCKS5 none authentication. Dummy class does almost nothing. 8 | */ 9 | public class AuthenticationNone implements Authentication { 10 | 11 | public Object[] doSocksAuthentication(final int methodId, 12 | final java.net.Socket proxySocket) throws java.io.IOException { 13 | 14 | if (methodId != 0) { 15 | return null; 16 | } 17 | 18 | InputStream in = proxySocket.getInputStream(); 19 | OutputStream out = proxySocket.getOutputStream(); 20 | return new Object[] { in, out }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/server/UserValidation.java: -------------------------------------------------------------------------------- 1 | package socks.server; 2 | 3 | /** 4 | Interface which provides for user validation, based on user name 5 | password and where it connects from. 6 | */ 7 | public interface UserValidation{ 8 | /** 9 | Implementations of this interface are expected to use some or all 10 | of the information provided plus any information they can extract 11 | from other sources to decide wether given user should be allowed 12 | access to SOCKS server, or whatever you use it for. 13 | 14 | @return true to indicate user is valid, false otherwise. 15 | @param username User whom implementation should validate. 16 | @param password Password this user provided. 17 | @param connection Socket which user used to connect to the server. 18 | */ 19 | boolean isUserValid(String username,String password, 20 | java.net.Socket connection); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/server/UserValidation.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.server; 2 | 3 | /** 4 | * Interface which provides for user validation, based on user name password and 5 | * where it connects from. 6 | */ 7 | public interface UserValidation { 8 | /** 9 | * Implementations of this interface are expected to use some or all of the 10 | * information provided plus any information they can extract from other 11 | * sources to decide wether given user should be allowed access to SOCKS 12 | * server, or whatever you use it for. 13 | * 14 | * @return true to indicate user is valid, false otherwise. 15 | * @param username 16 | * User whom implementation should validate. 17 | * @param password 18 | * Password this user provided. 19 | * @param connection 20 | * Socket which user used to connect to the server. 21 | */ 22 | boolean isUserValid(String username, String password, 23 | java.net.Socket connection); 24 | } 25 | -------------------------------------------------------------------------------- /jsocks_code1.01/test/UPSOCKS.java: -------------------------------------------------------------------------------- 1 | package test; 2 | import socks.*; 3 | import socks.server.*; 4 | import java.net.Socket; 5 | 6 | /** Test file for UserPasswordAuthentictor */ 7 | 8 | public class UPSOCKS implements UserValidation{ 9 | String user, password; 10 | 11 | UPSOCKS(String user,String password){ 12 | this.user = user; 13 | this.password = password; 14 | } 15 | 16 | public boolean isUserValid(String user,String password,Socket s){ 17 | System.err.println("User:"+user+"\tPassword:"+password); 18 | System.err.println("Socket:"+s); 19 | return (user.equals(this.user) && password.equals(this.password)); 20 | } 21 | 22 | public static void main(String args[]){ 23 | String user, password; 24 | 25 | if(args.length == 2){ 26 | user = args[0]; 27 | password = args[1]; 28 | }else{ 29 | user = "user"; 30 | password = "password"; 31 | } 32 | 33 | UPSOCKS us = new UPSOCKS(user,password); 34 | UserPasswordAuthenticator auth = new UserPasswordAuthenticator(us); 35 | ProxyServer server = new ProxyServer(auth); 36 | 37 | server.setLog(System.out); 38 | server.start(1080); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /helpers/com/runjva/sourceforge/jsocks/helpers/UPSOCKS.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.helpers; 2 | 3 | import java.net.Socket; 4 | 5 | import com.runjva.sourceforge.jsocks.protocol.ProxyServer; 6 | import com.runjva.sourceforge.jsocks.server.UserPasswordAuthenticator; 7 | import com.runjva.sourceforge.jsocks.server.UserValidation; 8 | 9 | /** Test file for UserPasswordAuthentictor */ 10 | 11 | public class UPSOCKS implements UserValidation { 12 | String user, password; 13 | 14 | UPSOCKS(String user, String password) { 15 | this.user = user; 16 | this.password = password; 17 | } 18 | 19 | public boolean isUserValid(String user, String password, Socket s) { 20 | System.err.println("User:" + user + "\tPassword:" + password); 21 | System.err.println("Socket:" + s); 22 | return (user.equals(this.user) && password.equals(this.password)); 23 | } 24 | 25 | public static void main(String args[]) { 26 | String user, password; 27 | 28 | if (args.length == 2) { 29 | user = args[0]; 30 | password = args[1]; 31 | } else { 32 | user = "user"; 33 | password = "password"; 34 | } 35 | 36 | final UPSOCKS us = new UPSOCKS(user, password); 37 | final UserPasswordAuthenticator auth = new UserPasswordAuthenticator(us); 38 | final ProxyServer server = new ProxyServer(auth); 39 | 40 | server.start(1080); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/protocol/UDPEncapsulation.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.protocol; 2 | 3 | /** 4 | * This interface provides for datagram encapsulation for SOCKSv5 protocol. 5 | *

6 | * SOCKSv5 allows for datagrams to be encapsulated for purposes of integrity 7 | * and/or authenticity. How it should be done is aggreed during the 8 | * authentication stage, and is authentication dependent. This interface is 9 | * provided to allow this encapsulation. 10 | * 11 | * @see Authentication 12 | */ 13 | public interface UDPEncapsulation { 14 | 15 | /** 16 | * This method should provide any authentication depended transformation on 17 | * datagrams being send from/to the client. 18 | * 19 | * @param data 20 | * Datagram data (including any SOCKS related bytes), to be 21 | * encapsulated/decapsulated. 22 | * @param out 23 | * Wether the data is being send out. If true method should 24 | * encapsulate/encrypt data, otherwise it should decapsulate/ 25 | * decrypt data. 26 | * @return Should return byte array containing data after transformation. It 27 | * is possible to return same array as input, if transformation only 28 | * involves bit mangling, and no additional data is being added or 29 | * removed. 30 | */ 31 | byte[] udpEncapsulate(byte[] data, boolean out); 32 | } 33 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/UDPEncapsulation.java: -------------------------------------------------------------------------------- 1 | package socks; 2 | /** 3 | This interface provides for datagram encapsulation for SOCKSv5 protocol. 4 |

5 | SOCKSv5 allows for datagrams to be encapsulated for purposes of integrity 6 | and/or authenticity. How it should be done is aggreed during the 7 | authentication stage, and is authentication dependent. This interface is 8 | provided to allow this encapsulation. 9 | @see Authentication 10 | */ 11 | public interface UDPEncapsulation{ 12 | 13 | /** 14 | This method should provide any authentication depended transformation 15 | on datagrams being send from/to the client. 16 | 17 | @param data Datagram data (including any SOCKS related bytes), to be 18 | encapsulated/decapsulated. 19 | @param out Wether the data is being send out. If true method should 20 | encapsulate/encrypt data, otherwise it should decapsulate/ 21 | decrypt data. 22 | @throw IOException if for some reason data can be transformed correctly. 23 | @return Should return byte array containing data after transformation. 24 | It is possible to return same array as input, if transformation 25 | only involves bit mangling, and no additional data is being 26 | added or removed. 27 | */ 28 | byte[] udpEncapsulate(byte[] data, boolean out) throws java.io.IOException; 29 | } 30 | -------------------------------------------------------------------------------- /.github/workflows/maven-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a package using Maven and then publish it to GitHub packages when a release is created 2 | # For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#apache-maven-with-a-settings-path 3 | 4 | name: Maven Package 5 | 6 | on: 7 | push: 8 | # release: 9 | # types: [created] 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: read 17 | packages: write 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up JDK 8 (for Java 6 output) 22 | uses: actions/setup-java@v3 23 | with: 24 | # https://github.com/actions/setup-java#supported-distributions 25 | java-version: '8' 26 | distribution: 'zulu' 27 | cache: 'maven' 28 | server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 29 | settings-path: ${{ github.workspace }} # location for the settings.xml file 30 | 31 | - name: Build with Maven 32 | run: mvn -B package --file pom.xml 33 | 34 | - name: Upload artifact for deployment job 35 | uses: actions/upload-artifact@v3 36 | with: 37 | name: runnable-jar 38 | path: '${{ github.workspace }}/target/*.jar' 39 | 40 | # - name: Publish to GitHub Packages Apache Maven 41 | # run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml 42 | # env: 43 | # GITHUB_TOKEN: ${{ github.token }} 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This project provides the revised source of the 2 | project as 3 | required by the LGPL. JSocks implement a SOCKS proxy 4 | (see ) in Java 6 and onwards. 5 | 6 | The git repository was started on a blank sheet, 7 | and then importing the sources, so all the 8 | work done is in the git history. The sf repository 9 | does not contain any versioned files, so there 10 | was no history to import. 11 | 12 | A source tree with proper packages has been 13 | set up and cleaned up by Eclipse. 14 | 15 | Logging has been migrated to slf4j and a 16 | launch configuration using slf4j-simple has 17 | been included, which also allows for creating 18 | runnable jars from inside Eclipse 3.5+ 19 | 20 | /ravn - 2009-09-07 21 | 22 | Mavenized. 23 | 24 | /ravn - 2012-11-07 25 | 26 | Updated for 2022. 27 | 28 | * Note: No code functionality changes. 29 | * Logging was reverted to java.util.logging to keep Java 1.6+ compatibility (slf4j 2.0 requires Java 8) 30 | and avoid dependencies for 31 | the runnable jar. If you need another logging framework, consider looking into the various slf4j tools 32 | () 33 | * IntelliJ and Eclipse report fewer warnings. 34 | * Creates a runnable jar. 35 | * GitHub Actions support. Exposes runnable jar as build artifact. 36 | * Original source tree converted to default Maven layout. 37 | * `mvn -q exec:java` should work. 38 | 39 | Pending: 40 | 41 | * Reformat sources according to a known style and add editor config and checkstyle config. 42 | * Handle SonarLint and IntelliJ reports. 43 | * Script running tests in `helper/` against compiled server. Preferably on Java 6. 44 | 45 | 46 | Suggestion and bug fixes welcome. 47 | 48 | /ravn - 2022-12-17 49 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/Authentication.java: -------------------------------------------------------------------------------- 1 | package socks; 2 | 3 | /** 4 | The Authentication interface provides for performing method specific 5 | authentication for SOCKS5 connections. 6 | */ 7 | public interface Authentication{ 8 | /** 9 | This method is called when SOCKS5 server have selected a particular 10 | authentication method, for whch an implementaion have been registered. 11 | 12 |

13 | This method should return an array {inputstream,outputstream 14 | [,UDPEncapsulation]}. The reason for that is that SOCKS5 protocol 15 | allows to have method specific encapsulation of data on the socket for 16 | purposes of integrity or security. And this encapsulation should be 17 | performed by those streams returned from the method. It is also possible 18 | to encapsulate datagrams. If authentication method supports such 19 | encapsulation an instance of the UDPEncapsulation interface should be 20 | returned as third element of the array, otherwise either null should be 21 | returned as third element, or array should contain only 2 elements. 22 | 23 | @param methodId Authentication method selected by the server. 24 | @param proxySocket Socket used to conect to the proxy. 25 | @return Two or three element array containing 26 | Input/Output streams which should be used on this connection. 27 | Third argument is optional and should contain an instance 28 | of UDPEncapsulation. It should be provided if the authentication 29 | method used requires any encapsulation to be done on the 30 | datagrams. 31 | */ 32 | Object[] doSocksAuthentication(int methodId,java.net.Socket proxySocket) 33 | throws java.io.IOException; 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/protocol/Authentication.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.protocol; 2 | 3 | /** 4 | * The Authentication interface provides for performing method specific 5 | * authentication for SOCKS5 connections. 6 | */ 7 | public interface Authentication { 8 | /** 9 | * This method is called when SOCKS5 server have selected a particular 10 | * authentication method, for whch an implementaion have been registered. 11 | * 12 | *

13 | * This method should return an array {inputstream,outputstream 14 | * [,UDPEncapsulation]}. The reason for that is that SOCKS5 protocol allows 15 | * to have method specific encapsulation of data on the socket for purposes 16 | * of integrity or security. And this encapsulation should be performed by 17 | * those streams returned from the method. It is also possible to 18 | * encapsulate datagrams. If authentication method supports such 19 | * encapsulation an instance of the UDPEncapsulation interface should be 20 | * returned as third element of the array, otherwise either null should be 21 | * returned as third element, or array should contain only 2 elements. 22 | * 23 | * @param methodId 24 | * Authentication method selected by the server. 25 | * @param proxySocket 26 | * Socket used to conect to the proxy. 27 | * @return Two or three element array containing Input/Output streams which 28 | * should be used on this connection. Third argument is optional and 29 | * should contain an instance of UDPEncapsulation. It should be 30 | * provided if the authentication method used requires any 31 | * encapsulation to be done on the datagrams. 32 | */ 33 | Object[] doSocksAuthentication(int methodId, java.net.Socket proxySocket) 34 | throws java.io.IOException; 35 | } 36 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.github.ravn.jsocks 5 | jsocks 6 | 0.0.2-SNAPSHOT 7 | SOCKS proxy 8 | Cloned from https://sourceforge.net/projects/jsocks/ 9 | 10 | 11 | ASCII 12 | com.runjva.sourceforge.jsocks.main.SOCKS 13 | 14 | 15 | 16 | 17 | 18 | 19 | maven-compiler-plugin 20 | 3.10.1 21 | 22 | 1.6 23 | 1.6 24 | 25 | 26 | 27 | 28 | org.apache.maven.plugins 29 | maven-pmd-plugin 30 | 3.19.0 31 | 32 | 33 | 34 | org.apache.maven.plugins 35 | maven-checkstyle-plugin 36 | 3.2.0 37 | 38 | 39 | org.apache.maven.plugins 40 | maven-jar-plugin 41 | 3.2.2 42 | 43 | 44 | 45 | ${exec.mainClass} 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /jsocks_code1.01/test/TestServer.java: -------------------------------------------------------------------------------- 1 | package test; 2 | import java.io.*; 3 | import java.net.*; 4 | 5 | /** 6 | Server to used perform tests for SOCKS library. 7 | */ 8 | public class TestServer implements Runnable{ 9 | static PrintStream log = null; 10 | 11 | int service; 12 | 13 | 14 | /** 15 | Creates a TestServer object which will listen on the port associated 16 | with given service. 17 | 18 | @param service Service to provide 19 | */ 20 | public TestServer(int service){ 21 | this.service = service; 22 | } 23 | 24 | public void run(){ 25 | try{ 26 | server(service); 27 | }catch(IOException ioe){ 28 | log("Exception:"+ioe); 29 | ioe.printStackTrace(); 30 | } 31 | } 32 | //Static functions 33 | ///////////////// 34 | 35 | 36 | /** 37 | Listens on the port associated with given service. 38 |

39 | When connection is accepted, speciefied service is performed. 40 | It is being done in separate thread. 41 | @return Never returns. 42 | */ 43 | static public void server(int service) throws IOException{ 44 | ServerSocket ss = new ServerSocket(TestService.servicePorts[service]); 45 | Socket s; 46 | 47 | s = ss.accept(); 48 | while(s!=null){ 49 | TestService st = new TestService(s,service); 50 | Thread t = new Thread(st); 51 | t.start(); 52 | s = ss.accept(); 53 | } 54 | } 55 | 56 | 57 | /** 58 | Performs logging. 59 | */ 60 | static synchronized void log(String s){ 61 | if(log != null) log.println(s); 62 | } 63 | 64 | //Main Function 65 | /////////////// 66 | public static void main(String[] args){ 67 | log = System.out; 68 | TestService.log = log; 69 | 70 | TestServer st; 71 | for( int i = 0; i< TestService.serviceNames.length;++i){ 72 | log("Starting service "+TestService.serviceNames[i]+" at port "+ 73 | TestService.servicePorts[i]+"."); 74 | st = new TestServer(i); 75 | Thread t = new Thread(st); 76 | t.start(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /helpers/com/runjva/sourceforge/jsocks/helpers/TestServer.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.helpers; 2 | 3 | import java.io.IOException; 4 | import java.io.PrintStream; 5 | import java.net.ServerSocket; 6 | import java.net.Socket; 7 | 8 | /** 9 | * Server to used perform tests for SOCKS library. 10 | */ 11 | public class TestServer implements Runnable { 12 | static PrintStream log = null; 13 | 14 | int service; 15 | 16 | /** 17 | * Creates a TestServer object which will listen on the port associated with 18 | * given service. 19 | * 20 | * @param service 21 | * Service to provide 22 | */ 23 | public TestServer(int service) { 24 | this.service = service; 25 | } 26 | 27 | public void run() { 28 | try { 29 | server(service); 30 | } catch (final IOException ioe) { 31 | log("Exception:" + ioe); 32 | ioe.printStackTrace(); 33 | } 34 | } 35 | 36 | // Static functions 37 | // /////////////// 38 | 39 | /** 40 | * Listens on the port associated with given service. 41 | *

42 | * When connection is accepted, speciefied service is performed. It is being 43 | * done in separate thread. 44 | * 45 | * @return Never returns. 46 | */ 47 | static public void server(int service) throws IOException { 48 | final ServerSocket ss = new ServerSocket( 49 | TestService.servicePorts[service]); 50 | Socket s; 51 | 52 | s = ss.accept(); 53 | while (s != null) { 54 | final TestService st = new TestService(s, service); 55 | final Thread t = new Thread(st); 56 | t.start(); 57 | s = ss.accept(); 58 | } 59 | } 60 | 61 | /** 62 | * Performs logging. 63 | */ 64 | static synchronized void log(String s) { 65 | if (log != null) { 66 | log.println(s); 67 | } 68 | } 69 | 70 | // Main Function 71 | // ///////////// 72 | public static void main(String[] args) { 73 | log = System.out; 74 | TestService.log = log; 75 | 76 | TestServer st; 77 | for (int i = 0; i < TestService.serviceNames.length; ++i) { 78 | log("Starting service " + TestService.serviceNames[i] + " at port " 79 | + TestService.servicePorts[i] + "."); 80 | st = new TestServer(i); 81 | final Thread t = new Thread(st); 82 | t.start(); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/server/UserPasswordAuthenticator.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.server; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.net.Socket; 7 | 8 | /** 9 | * This class implements SOCKS5 User/Password authentication scheme as defined 10 | * in rfc1929,the server side of it. (see docs/rfc1929.txt) 11 | */ 12 | public class UserPasswordAuthenticator extends ServerAuthenticatorBase { 13 | 14 | static final int METHOD_ID = 2; 15 | 16 | final UserValidation validator; 17 | 18 | /** 19 | * Construct a new UserPasswordAuthentication object, with given 20 | * UserVlaidation scheme. 21 | * 22 | * @param validator 23 | * UserValidation to use for validating users. 24 | */ 25 | public UserPasswordAuthenticator(UserValidation validator) { 26 | this.validator = validator; 27 | } 28 | 29 | public ServerAuthenticator startSession(Socket s) throws IOException { 30 | final InputStream in = s.getInputStream(); 31 | final OutputStream out = s.getOutputStream(); 32 | 33 | if (in.read() != 5) { 34 | return null; // Drop non version 5 messages. 35 | } 36 | 37 | if (!selectSocks5Authentication(in, out, METHOD_ID)) { 38 | return null; 39 | } 40 | if (!doUserPasswordAuthentication(s, in, out)) { 41 | return null; 42 | } 43 | 44 | return new ServerAuthenticatorNone(in, out); 45 | } 46 | 47 | // Private Methods 48 | // //////////////// 49 | 50 | private boolean doUserPasswordAuthentication(Socket s, InputStream in, 51 | OutputStream out) throws IOException { 52 | final int version = in.read(); 53 | if (version != 1) { 54 | return false; 55 | } 56 | 57 | final int ulen = in.read(); 58 | if (ulen < 0) { 59 | return false; 60 | } 61 | 62 | final byte[] user = new byte[ulen]; 63 | in.read(user); 64 | final int plen = in.read(); 65 | if (plen < 0) { 66 | return false; 67 | } 68 | final byte[] password = new byte[plen]; 69 | in.read(password); 70 | 71 | if (validator.isUserValid(new String(user), new String(password), s)) { 72 | // System.out.println("user valid"); 73 | out.write(new byte[] { 1, 0 }); 74 | } else { 75 | // System.out.println("user invalid"); 76 | out.write(new byte[] { 1, 1 }); 77 | return false; 78 | } 79 | 80 | return true; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/server/UserPasswordAuthenticator.java: -------------------------------------------------------------------------------- 1 | package socks.server; 2 | 3 | import socks.ProxyMessage; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.OutputStream; 7 | import java.net.Socket; 8 | 9 | /** 10 | This class implements SOCKS5 User/Password authentication scheme as 11 | defined in rfc1929,the server side of it. 12 | */ 13 | public class UserPasswordAuthenticator extends ServerAuthenticatorNone{ 14 | 15 | static final int METHOD_ID = 2; 16 | 17 | UserValidation validator; 18 | 19 | /** 20 | Construct a new UserPasswordAuthentication object, with given 21 | UserVlaidation scheme. 22 | 23 | @param v UserValidation to use for validating users. 24 | */ 25 | public UserPasswordAuthenticator(UserValidation validator){ 26 | this.validator = validator; 27 | } 28 | 29 | public ServerAuthenticator startSession(Socket s) throws IOException{ 30 | InputStream in = s.getInputStream(); 31 | OutputStream out = s.getOutputStream(); 32 | 33 | if(in.read() != 5) return null; //Drop non version 5 messages. 34 | 35 | if(!selectSocks5Authentication(in,out,METHOD_ID)) 36 | return null; 37 | if(!doUserPasswordAuthentication(s,in,out)) 38 | return null; 39 | 40 | return new ServerAuthenticatorNone(in,out); 41 | } 42 | 43 | 44 | //Private Methods 45 | ////////////////// 46 | 47 | private boolean doUserPasswordAuthentication(Socket s, 48 | InputStream in, 49 | OutputStream out) 50 | throws IOException{ 51 | int version = in.read(); 52 | if(version != 1) return false; 53 | int ulen = in.read(); 54 | if(ulen < 0) return false; 55 | byte[] user = new byte[ulen]; 56 | in.read(user); 57 | int plen = in.read(); 58 | if(plen < 0) return false; 59 | byte[] password = new byte[plen]; 60 | in.read(password); 61 | 62 | if(validator.isUserValid(new String(user), new String(password),s)){ 63 | //System.out.println("user valid"); 64 | out.write(new byte[]{1,0}); 65 | }else{ 66 | //System.out.println("user invalid"); 67 | out.write(new byte[]{1,1}); 68 | return false; 69 | } 70 | 71 | return true; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/UserPasswordAuthentication.java: -------------------------------------------------------------------------------- 1 | package socks; 2 | 3 | /** 4 | SOCKS5 User Password authentication scheme. 5 | */ 6 | public class UserPasswordAuthentication implements Authentication{ 7 | 8 | /**SOCKS ID for User/Password authentication method*/ 9 | public final static int METHOD_ID = 2; 10 | 11 | String userName, password; 12 | byte[] request; 13 | 14 | /** 15 | Create an instance of UserPasswordAuthentication. 16 | @param userName User Name to send to SOCKS server. 17 | @param password Password to send to SOCKS server. 18 | */ 19 | public UserPasswordAuthentication(String userName,String password){ 20 | this.userName = userName; 21 | this.password = password; 22 | formRequest(); 23 | } 24 | /** Get the user name. 25 | @return User name. 26 | */ 27 | public String getUser(){ 28 | return userName; 29 | } 30 | /** Get password 31 | @return Password 32 | */ 33 | public String getPassword(){ 34 | return password; 35 | } 36 | /** 37 | Does User/Password authentication as defined in rfc1929. 38 | @return An array containnig in, out streams, or null if authentication 39 | fails. 40 | */ 41 | public Object[] doSocksAuthentication(int methodId, 42 | java.net.Socket proxySocket) 43 | throws java.io.IOException{ 44 | 45 | if(methodId != METHOD_ID) return null; 46 | 47 | java.io.InputStream in = proxySocket.getInputStream(); 48 | java.io.OutputStream out = proxySocket.getOutputStream(); 49 | 50 | out.write(request); 51 | int version = in.read(); 52 | if(version < 0) return null; //Server closed connection 53 | int status = in.read(); 54 | if(status != 0) return null; //Server closed connection, or auth failed. 55 | 56 | return new Object[] {in,out}; 57 | } 58 | 59 | //Private methods 60 | ////////////////// 61 | 62 | /** Convert UserName password in to binary form, ready to be send to server*/ 63 | private void formRequest(){ 64 | byte[] user_bytes = userName.getBytes(); 65 | byte[] password_bytes = password.getBytes(); 66 | 67 | request = new byte[3+user_bytes.length+password_bytes.length]; 68 | request[0] = (byte) 1; 69 | request[1] = (byte) user_bytes.length; 70 | System.arraycopy(user_bytes,0,request,2,user_bytes.length); 71 | request[2+user_bytes.length] = (byte) password_bytes.length; 72 | System.arraycopy(password_bytes,0, 73 | request,3+user_bytes.length,password_bytes.length); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/protocol/UserPasswordAuthentication.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.protocol; 2 | 3 | /** 4 | * SOCKS5 User Password authentication scheme. 5 | */ 6 | public class UserPasswordAuthentication implements Authentication { 7 | 8 | /** SOCKS ID for User/Password authentication method */ 9 | public final static int METHOD_ID = 2; 10 | 11 | final String userName; 12 | final String password; 13 | byte[] request; 14 | 15 | /** 16 | * Create an instance of UserPasswordAuthentication. 17 | * 18 | * @param userName 19 | * User Name to send to SOCKS server. 20 | * @param password 21 | * Password to send to SOCKS server. 22 | */ 23 | public UserPasswordAuthentication(String userName, String password) { 24 | this.userName = userName; 25 | this.password = password; 26 | formRequest(); 27 | } 28 | 29 | /** 30 | * Get the user name. 31 | * 32 | * @return User name. 33 | */ 34 | public String getUser() { 35 | return userName; 36 | } 37 | 38 | /** 39 | * Get password 40 | * 41 | * @return Password 42 | */ 43 | public String getPassword() { 44 | return password; 45 | } 46 | 47 | /** 48 | * Does User/Password authentication as defined in rfc1929. 49 | * 50 | * @return An array containnig in, out streams, or null if authentication 51 | * fails. 52 | */ 53 | public Object[] doSocksAuthentication(int methodId, 54 | java.net.Socket proxySocket) throws java.io.IOException { 55 | 56 | if (methodId != METHOD_ID) { 57 | return null; 58 | } 59 | 60 | final java.io.InputStream in = proxySocket.getInputStream(); 61 | final java.io.OutputStream out = proxySocket.getOutputStream(); 62 | 63 | out.write(request); 64 | final int version = in.read(); 65 | if (version < 0) { 66 | return null; // Server closed connection 67 | } 68 | final int status = in.read(); 69 | if (status != 0) { 70 | return null; // Server closed connection, or auth failed. 71 | } 72 | 73 | return new Object[] { in, out }; 74 | } 75 | 76 | // Private methods 77 | // //////////////// 78 | 79 | /** Convert UserName password in to binary form, ready to be send to server */ 80 | private void formRequest() { 81 | final byte[] user_bytes = userName.getBytes(); 82 | final byte[] password_bytes = password.getBytes(); 83 | 84 | request = new byte[3 + user_bytes.length + password_bytes.length]; 85 | request[0] = (byte) 1; 86 | request[1] = (byte) user_bytes.length; 87 | System.arraycopy(user_bytes, 0, request, 2, user_bytes.length); 88 | request[2 + user_bytes.length] = (byte) password_bytes.length; 89 | System.arraycopy(password_bytes, 0, request, 3 + user_bytes.length, 90 | password_bytes.length); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/SocksException.java: -------------------------------------------------------------------------------- 1 | package socks; 2 | 3 | /** 4 | Exception thrown by various socks classes to indicate errors 5 | with protocol or unsuccessfull server responses. 6 | */ 7 | public class SocksException extends java.io.IOException{ 8 | /** 9 | Construct a SocksException with given errorcode. 10 |

11 | Tries to look up message which corresponds to this error code. 12 | @param errCode Error code for this exception. 13 | */ 14 | public SocksException(int errCode){ 15 | this.errCode = errCode; 16 | if((errCode >> 16) == 0){ 17 | //Server reply error message 18 | errString = errCode <= serverReplyMessage.length ? 19 | serverReplyMessage[errCode] : 20 | UNASSIGNED_ERROR_MESSAGE; 21 | }else{ 22 | //Local error 23 | errCode = (errCode >> 16) -1; 24 | errString = errCode <= localErrorMessage.length ? 25 | localErrorMessage[errCode] : 26 | UNASSIGNED_ERROR_MESSAGE; 27 | } 28 | } 29 | /** 30 | Constructs a SocksException with given error code and message. 31 | @param errCode Error code. 32 | @param errString Error Message. 33 | */ 34 | public SocksException(int errCode,String errString){ 35 | this.errCode = errCode; 36 | this.errString = errString; 37 | } 38 | /** 39 | Get the error code associated with this exception. 40 | @return Error code associated with this exception. 41 | */ 42 | public int getErrorCode(){ 43 | return errCode; 44 | } 45 | /** 46 | Get human readable representation of this exception. 47 | @return String represntation of this exception. 48 | */ 49 | public String toString(){ 50 | return errString; 51 | } 52 | 53 | static final String UNASSIGNED_ERROR_MESSAGE = 54 | "Unknown error message"; 55 | static final String serverReplyMessage[] = { 56 | "Succeeded", 57 | "General SOCKS server failure", 58 | "Connection not allowed by ruleset", 59 | "Network unreachable", 60 | "Host unreachable", 61 | "Connection refused", 62 | "TTL expired", 63 | "Command not supported", 64 | "Address type not supported" }; 65 | 66 | static final String localErrorMessage[] ={ 67 | "SOCKS server not specified", 68 | "Unable to contact SOCKS server", 69 | "IO error", 70 | "None of Authentication methods are supported", 71 | "Authentication failed", 72 | "General SOCKS fault" }; 73 | 74 | String errString; 75 | int errCode; 76 | 77 | }//End of SocksException class 78 | 79 | -------------------------------------------------------------------------------- /jsocks_code1.01/test/SocksUDPEcho.java: -------------------------------------------------------------------------------- 1 | import java.net.*; 2 | import java.io.*; 3 | import socks.*; 4 | 5 | /** SOCKS aware UDP echo client.
6 | Reads input line by line and sends it to given on command line 7 | host and port, using given proxy, then blocks until reply datagram 8 | recieved, not really echo, single threaded client, I just used it 9 | for testing before UDP actually worked. 10 | */ 11 | public class SocksUDPEcho{ 12 | 13 | public static void usage(){ 14 | System.err.print( 15 | "Usage: java SocksUDPEcho host port [socksHost socksPort]\n"); 16 | } 17 | 18 | static final int defaultProxyPort = 1080; //Default Port 19 | static final String defaultProxyHost = "www-proxy"; //Default proxy 20 | 21 | public static void main(String args[]){ 22 | int port; 23 | String host; 24 | int proxyPort; 25 | String proxyHost; 26 | InetAddress ip; 27 | 28 | if(args.length > 1 && args.length < 5){ 29 | try{ 30 | 31 | host = args[0]; 32 | port = Integer.parseInt(args[1]); 33 | 34 | proxyPort =(args.length > 3)? Integer.parseInt(args[3]) 35 | : defaultProxyPort; 36 | 37 | host = args[0]; 38 | ip = InetAddress.getByName(host); 39 | 40 | proxyHost =(args.length > 2)? args[2] 41 | : defaultProxyHost; 42 | 43 | Proxy.setDefaultProxy(proxyHost,proxyPort); 44 | Proxy p = Proxy.getDefaultProxy(); 45 | p.addDirect("lux"); 46 | 47 | 48 | DatagramSocket ds = new Socks5DatagramSocket(); 49 | 50 | 51 | BufferedReader in = new BufferedReader( 52 | new InputStreamReader(System.in)); 53 | String s; 54 | 55 | System.out.print("Enter line:"); 56 | s = in.readLine(); 57 | 58 | while(s != null){ 59 | byte[] data = (s+"\r\n").getBytes(); 60 | DatagramPacket dp = new DatagramPacket(data,0,data.length, 61 | ip,port); 62 | System.out.println("Sending to: "+ip+":"+port); 63 | ds.send(dp); 64 | dp = new DatagramPacket(new byte[1024],1024); 65 | 66 | System.out.println("Trying to recieve on port:"+ 67 | ds.getLocalPort()); 68 | ds.receive(dp); 69 | System.out.print("Recieved:\n"+ 70 | "From:"+dp.getAddress()+":"+dp.getPort()+ 71 | "\n\n"+ 72 | new String(dp.getData(),dp.getOffset(),dp.getLength())+"\n" 73 | ); 74 | System.out.print("Enter line:"); 75 | s = in.readLine(); 76 | 77 | } 78 | ds.close(); 79 | System.exit(1); 80 | 81 | }catch(SocksException s_ex){ 82 | System.err.println("SocksException:"+s_ex); 83 | s_ex.printStackTrace(); 84 | System.exit(1); 85 | }catch(IOException io_ex){ 86 | io_ex.printStackTrace(); 87 | System.exit(1); 88 | }catch(NumberFormatException num_ex){ 89 | usage(); 90 | num_ex.printStackTrace(); 91 | System.exit(1); 92 | } 93 | 94 | }else{ 95 | usage(); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/protocol/SocksException.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.protocol; 2 | 3 | /** 4 | * Exception thrown by various socks classes to indicate errors with protocol or 5 | * unsuccessfull server responses. 6 | */ 7 | public class SocksException extends java.io.IOException { 8 | /** 9 | * 10 | */ 11 | private static final long serialVersionUID = 1L; 12 | 13 | /** 14 | * Construct a SocksException with given errorcode. 15 | *

16 | * Tries to look up message which corresponds to this error code. 17 | * 18 | * @param errCode 19 | * Error code for this exception. 20 | */ 21 | public SocksException(int errCode) { 22 | this.errCode = errCode; 23 | lookupErrorString(errCode); 24 | } 25 | 26 | private void lookupErrorString(int errCode) { 27 | if ((errCode >> 16) == 0) { 28 | if (errCode <= serverReplyMessage.length) { 29 | errString = serverReplyMessage[errCode]; 30 | } else { 31 | errString = UNASSIGNED_ERROR_MESSAGE; 32 | } 33 | } else { 34 | // Local error 35 | errCode = (errCode >> 16) - 1; 36 | if (errCode <= localErrorMessage.length) { 37 | errString = localErrorMessage[errCode]; 38 | } else { 39 | errString = UNASSIGNED_ERROR_MESSAGE; 40 | } 41 | } 42 | } 43 | 44 | /** 45 | * Construct a SocksException with given error code, and a Throwable cause 46 | * 47 | * @param errCode error code, adds corresponding error string. 48 | * @param t 49 | * Nested exception for debugging purposes. 50 | */ 51 | public SocksException(int errCode, Throwable t) { 52 | super(t); // Java 1.6+ 53 | this.errCode = errCode; 54 | lookupErrorString(errCode); 55 | } 56 | 57 | /** 58 | * Constructs a SocksException with given error code and message. 59 | * 60 | * @param errCode 61 | * Error code. 62 | * @param errString 63 | * Error Message. 64 | */ 65 | public SocksException(int errCode, String errString) { 66 | this.errCode = errCode; 67 | this.errString = errString; 68 | } 69 | 70 | public SocksException(int errCode, String string, Throwable t) { 71 | super(string, t); // Java 1.6+ 72 | this.errCode = errCode; 73 | this.errString = string; 74 | } 75 | 76 | /** 77 | * Get the error code associated with this exception. 78 | * 79 | * @return Error code associated with this exception. 80 | */ 81 | public int getErrorCode() { 82 | return errCode; 83 | } 84 | 85 | /** 86 | * Get human readable representation of this exception. 87 | * 88 | * @return String represntation of this exception. 89 | */ 90 | public String toString() { 91 | return errString; 92 | } 93 | 94 | static final String UNASSIGNED_ERROR_MESSAGE = "Unknown error message"; 95 | 96 | static final String[] serverReplyMessage = { "Succeeded", 97 | "General SOCKS server failure", 98 | "Connection not allowed by ruleset", "Network unreachable", 99 | "Host unreachable", "Connection refused", "TTL expired", 100 | "Command not supported", "Address type not supported" }; 101 | 102 | static final String[] localErrorMessage = { "SOCKS server not specified", 103 | "Unable to contact SOCKS server", "IO error", 104 | "None of Authentication methods are supported", 105 | "Authentication failed", "General SOCKS fault" }; 106 | 107 | String errString; 108 | final int errCode; 109 | 110 | }// End of SocksException class 111 | 112 | -------------------------------------------------------------------------------- /jsocks_code1.01/test/Echo.java: -------------------------------------------------------------------------------- 1 | import java.net.*; 2 | import java.io.*; 3 | 4 | /** Plain SOCKS unaware echo client.*/ 5 | 6 | public class Echo implements Runnable{ 7 | 8 | private int port; 9 | private InetAddress peerIp; 10 | 11 | private Socket ss; 12 | private InputStream in; 13 | private OutputStream out; 14 | 15 | private static final int BUF_SIZE = 1024; 16 | 17 | 18 | public Echo(String host,int port,String peerHost,int peerPort) 19 | throws IOException,UnknownHostException{ 20 | this.peerIp = InetAddress.getByName(peerHost); 21 | this.port = port; 22 | 23 | ss = new Socket(host, port,peerIp,peerPort); 24 | out = ss.getOutputStream(); 25 | in = ss.getInputStream(); 26 | System.out.println("Connected..."); 27 | System.out.println("TO: "+host+":"+port); 28 | System.out.println("LocalAddress: "+ss.getLocalAddress().getHostAddress() 29 | +":"+ss.getLocalPort()); 30 | 31 | } 32 | public Echo(String host,int port) 33 | throws IOException,UnknownHostException{ 34 | 35 | System.out.println("Connecting..."); 36 | ss = new Socket(host, port); 37 | out = ss.getOutputStream(); 38 | in = ss.getInputStream(); 39 | System.out.println("TO: "+host+":"+port); 40 | System.out.println("LocalAddress: "+ss.getLocalAddress().getHostAddress() 41 | +":"+ss.getLocalPort()); 42 | 43 | } 44 | 45 | 46 | public void send(String s) throws IOException{ 47 | //System.out.println("Sending:"+s); 48 | out.write(s.getBytes()); 49 | } 50 | 51 | public void run(){ 52 | byte[] buf = new byte[1024]; 53 | int bytes_read; 54 | try{ 55 | while((bytes_read = in.read(buf)) > 0){ 56 | System.out.write(buf,0,bytes_read); 57 | System.out.flush(); 58 | } 59 | }catch(IOException io_ex){ 60 | io_ex.printStackTrace(); 61 | } 62 | } 63 | 64 | public static void usage(){ 65 | System.err.print( 66 | "Usage: java Echo host port [peerHost peerPort]\n"); 67 | } 68 | 69 | 70 | public static void main(String args[]){ 71 | int port; 72 | String host,peerHost; 73 | int peerPort; 74 | Echo echo = null; 75 | 76 | if(args.length > 1){ 77 | try{ 78 | 79 | host = args[0]; 80 | port = Integer.parseInt(args[1]); 81 | 82 | if(args.length ==4){ 83 | peerHost = args[2]; 84 | peerPort =Integer.parseInt(args[3]); 85 | echo = new Echo(host,port,peerHost,peerPort); 86 | }else{ 87 | echo = new Echo(host,port); 88 | } 89 | 90 | Thread thread = new Thread(echo); 91 | thread.start(); 92 | 93 | BufferedReader in = new BufferedReader( 94 | new InputStreamReader(System.in)); 95 | String s; 96 | 97 | s = in.readLine(); 98 | Thread.currentThread().setPriority(Thread.NORM_PRIORITY); 99 | while(s != null){ 100 | echo.send(s+"\r\n"); 101 | s = in.readLine(); 102 | } 103 | }catch(IOException io_ex){ 104 | io_ex.printStackTrace(); 105 | System.exit(1); 106 | }catch(NumberFormatException num_ex){ 107 | usage(); 108 | num_ex.printStackTrace(); 109 | System.exit(1); 110 | }finally{ 111 | if(echo!=null) try{echo.ss.close();}catch(Exception e){} 112 | } 113 | 114 | }else{ 115 | usage(); 116 | } 117 | } 118 | 119 | }//End of class 120 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/protocol/ProxyMessage.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.protocol; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.net.InetAddress; 7 | import java.net.UnknownHostException; 8 | 9 | /** 10 | * Abstract class which describes SOCKS4/5 response/request. 11 | */ 12 | public abstract class ProxyMessage { 13 | 14 | /** Host as an IP address */ 15 | public InetAddress ip = null; 16 | 17 | /** SOCKS version, or version of the response for SOCKS4 */ 18 | public int version; 19 | 20 | /** Port field of the request/response */ 21 | public int port; 22 | 23 | /** Request/response code as an int */ 24 | public int command; 25 | 26 | /** Host as string. */ 27 | public String host = null; 28 | 29 | /** User field for SOCKS4 request messages */ 30 | public String user = null; 31 | 32 | ProxyMessage(int command, InetAddress ip, int port) { 33 | this.command = command; 34 | this.ip = ip; 35 | this.port = port; 36 | } 37 | 38 | ProxyMessage() { 39 | } 40 | 41 | /** 42 | * Initialises Message from the stream. Reads server response from given 43 | * stream. 44 | * 45 | * @param in 46 | * Input stream to read response from. 47 | * @throws SocksException 48 | * If server response code is not SOCKS_SUCCESS(0), or if any 49 | * error with protocol occurs. 50 | * @throws IOException 51 | * If any error happens with I/O. 52 | */ 53 | public abstract void read(InputStream in) throws SocksException, 54 | IOException; 55 | 56 | /** 57 | * Initialises Message from the stream. Reads server response or client 58 | * request from given stream. 59 | * 60 | * @param in 61 | * Input stream to read response from. 62 | * @param client_mode 63 | * If true read server response, else read client request. 64 | * @throws SocksException 65 | * If server response code is not SOCKS_SUCCESS(0) and reading 66 | * in client mode, or if any error with protocol occurs. 67 | * @throws IOException 68 | * If any error happens with I/O. 69 | */ 70 | public abstract void read(InputStream in, boolean client_mode) 71 | throws SocksException, IOException; 72 | 73 | /** 74 | * Writes the message to the stream. 75 | * 76 | * @param out 77 | * Output stream to which message should be written. 78 | */ 79 | public abstract void write(OutputStream out) throws 80 | IOException; 81 | 82 | /** 83 | * Get the Address field of this message as InetAddress object. 84 | * 85 | * @return Host address or null, if one can't be determined. 86 | */ 87 | public InetAddress getInetAddress() throws UnknownHostException { 88 | return ip; 89 | } 90 | 91 | /** 92 | * Get string representaion of this message. 93 | * 94 | * @return string representation of this message. 95 | */ 96 | public String toString() { 97 | return "Proxy Message:\n" + "Version:" + version + "\n" + "Command:" 98 | + command + "\n" + "IP: " + ip + "\n" + "Port: " + port 99 | + "\n" + "User: " + user + "\n"; 100 | } 101 | 102 | // Package methods 103 | // //////////////// 104 | 105 | static String bytes2IPV4(byte[] addr, int offset) { 106 | StringBuilder hostName = new StringBuilder("" + (addr[offset] & 0xFF)); 107 | for (int i = offset + 1; i < offset + 4; i++) { 108 | hostName.append(".").append(addr[i] & 0xFF); 109 | } 110 | return hostName.toString(); 111 | } 112 | 113 | static String bytes2IPV6(byte[] addr, int offset) { 114 | // Have no idea how they look like! 115 | return null; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /jsocks_code1.01/test/SocksTest.java: -------------------------------------------------------------------------------- 1 | package test_util; 2 | import java.net.*; 3 | import java.io.*; 4 | import socks.*; 5 | 6 | /** SOCKS aware echo client*/ 7 | 8 | public class SocksTest implements Runnable{ 9 | 10 | private int port; 11 | private InetAddress hostIP; 12 | 13 | private Socket ss; 14 | private InputStream in; 15 | private OutputStream out; 16 | 17 | private static final int BUF_SIZE = 1024; 18 | static final int defaultProxyPort = 1080; //Default Port 19 | static final String defaultProxyHost = "www-proxy"; //Default proxy 20 | 21 | public SocksTest(String host,int port) 22 | throws IOException,UnknownHostException,SocksException{ 23 | this.port = port; 24 | 25 | ss = new SocksSocket(host, port); 26 | out = ss.getOutputStream(); 27 | in = ss.getInputStream(); 28 | System.out.println("Connected..."); 29 | System.out.println("TO: "+host+":"+port); 30 | System.out.println("ViaProxy: "+ss.getLocalAddress().getHostAddress() 31 | +":"+ss.getLocalPort()); 32 | 33 | } 34 | 35 | public void close()throws IOException{ 36 | ss.close(); 37 | } 38 | public void send(String s) throws IOException{ 39 | out.write(s.getBytes()); 40 | } 41 | 42 | public void run(){ 43 | byte[] buf = new byte[1024]; 44 | int bytes_read; 45 | try{ 46 | while((bytes_read = in.read(buf)) > 0){ 47 | System.out.write(buf,0,bytes_read); 48 | } 49 | }catch(IOException io_ex){ 50 | io_ex.printStackTrace(); 51 | } 52 | } 53 | 54 | public static void usage(){ 55 | System.err.print( 56 | "Usage: java SocksTest host port [socksHost socksPort]\n"); 57 | } 58 | 59 | 60 | public static void main(String args[]){ 61 | int port; 62 | String host; 63 | int proxyPort; 64 | String proxyHost; 65 | 66 | if(args.length > 1 && args.length < 5){ 67 | try{ 68 | 69 | host = args[0]; 70 | port = Integer.parseInt(args[1]); 71 | 72 | proxyPort =(args.length > 3)? Integer.parseInt(args[3]) 73 | : defaultProxyPort; 74 | 75 | host = args[0]; 76 | proxyHost =(args.length > 2)? args[2] 77 | : defaultProxyHost; 78 | 79 | Proxy.setDefaultProxy(proxyHost,proxyPort,"KOUKY001"); 80 | //Proxy.setDefaultProxy(proxyHost,proxyPort); 81 | Proxy.getDefaultProxy().setDirect(InetAddress.getByName("localhost")); 82 | 83 | 84 | SocksTest st = new SocksTest(host,port); 85 | Thread thread = new Thread(st); 86 | thread.start(); 87 | 88 | BufferedReader in = new BufferedReader( 89 | new InputStreamReader(System.in)); 90 | String s; 91 | 92 | s = in.readLine(); 93 | while(s != null){ 94 | st.send(s+"\r\n"); 95 | //try{ 96 | //Thread.currentThread().sleep(10); 97 | //}catch(InterruptedException i_ex){ 98 | //} 99 | s = in.readLine(); 100 | } 101 | st.close(); 102 | System.exit(1); 103 | 104 | }catch(SocksException s_ex){ 105 | System.err.println("SocksException:"+s_ex); 106 | s_ex.printStackTrace(); 107 | System.exit(1); 108 | }catch(IOException io_ex){ 109 | io_ex.printStackTrace(); 110 | System.exit(1); 111 | }catch(NumberFormatException num_ex){ 112 | usage(); 113 | num_ex.printStackTrace(); 114 | System.exit(1); 115 | } 116 | 117 | }else{ 118 | usage(); 119 | } 120 | } 121 | 122 | }//End of class 123 | -------------------------------------------------------------------------------- /helpers/com/runjva/sourceforge/jsocks/helpers/SocksUDPEcho.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.helpers; 2 | import java.io.BufferedReader; 3 | import java.io.IOException; 4 | import java.io.InputStreamReader; 5 | import java.net.DatagramPacket; 6 | import java.net.DatagramSocket; 7 | import java.net.InetAddress; 8 | import java.net.Proxy; 9 | 10 | import com.runjva.sourceforge.jsocks.Socks5DatagramSocket; 11 | import com.runjva.sourceforge.jsocks.SocksException; 12 | 13 | /** SOCKS aware UDP echo client.
14 | Reads input line by line and sends it to given on command line 15 | host and port, using given proxy, then blocks until reply datagram 16 | recieved, not really echo, single threaded client, I just used it 17 | for testing before UDP actually worked. 18 | */ 19 | public class SocksUDPEcho{ 20 | 21 | public static void usage(){ 22 | System.err.print( 23 | "Usage: java SocksUDPEcho host port [socksHost socksPort]\n"); 24 | } 25 | 26 | static final int defaultProxyPort = 1080; //Default Port 27 | static final String defaultProxyHost = "www-proxy"; //Default proxy 28 | 29 | public static void main(String args[]){ 30 | int port; 31 | String host; 32 | int proxyPort; 33 | String proxyHost; 34 | InetAddress ip; 35 | 36 | if(args.length > 1 && args.length < 5){ 37 | try{ 38 | 39 | host = args[0]; 40 | port = Integer.parseInt(args[1]); 41 | 42 | proxyPort =(args.length > 3)? Integer.parseInt(args[3]) 43 | : defaultProxyPort; 44 | 45 | host = args[0]; 46 | ip = InetAddress.getByName(host); 47 | 48 | proxyHost =(args.length > 2)? args[2] 49 | : defaultProxyHost; 50 | 51 | Proxy.setDefaultProxy(proxyHost,proxyPort); 52 | Proxy p = Proxy.getDefaultProxy(); 53 | p.addDirect("lux"); 54 | 55 | 56 | DatagramSocket ds = new Socks5DatagramSocket(); 57 | 58 | 59 | BufferedReader in = new BufferedReader( 60 | new InputStreamReader(System.in)); 61 | String s; 62 | 63 | System.out.print("Enter line:"); 64 | s = in.readLine(); 65 | 66 | while(s != null){ 67 | byte[] data = (s+"\r\n").getBytes(); 68 | DatagramPacket dp = new DatagramPacket(data,0,data.length, 69 | ip,port); 70 | System.out.println("Sending to: "+ip+":"+port); 71 | ds.send(dp); 72 | dp = new DatagramPacket(new byte[1024],1024); 73 | 74 | System.out.println("Trying to recieve on port:"+ 75 | ds.getLocalPort()); 76 | ds.receive(dp); 77 | System.out.print("Recieved:\n"+ 78 | "From:"+dp.getAddress()+":"+dp.getPort()+ 79 | "\n\n"+ 80 | new String(dp.getData(),dp.getOffset(),dp.getLength())+"\n" 81 | ); 82 | System.out.print("Enter line:"); 83 | s = in.readLine(); 84 | 85 | } 86 | ds.close(); 87 | System.exit(1); 88 | 89 | }catch(SocksException s_ex){ 90 | System.err.println("SocksException:"+s_ex); 91 | s_ex.printStackTrace(); 92 | System.exit(1); 93 | }catch(IOException io_ex){ 94 | io_ex.printStackTrace(); 95 | System.exit(1); 96 | }catch(NumberFormatException num_ex){ 97 | usage(); 98 | num_ex.printStackTrace(); 99 | System.exit(1); 100 | } 101 | 102 | }else{ 103 | usage(); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/ProxyMessage.java: -------------------------------------------------------------------------------- 1 | package socks; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.io.DataInputStream; 7 | import java.net.InetAddress; 8 | import java.net.UnknownHostException; 9 | 10 | /** 11 | Abstract class which describes SOCKS4/5 response/request. 12 | */ 13 | public abstract class ProxyMessage{ 14 | /** Host as an IP address */ 15 | public InetAddress ip=null; 16 | /** SOCKS version, or version of the response for SOCKS4*/ 17 | public int version; 18 | /** Port field of the request/response*/ 19 | public int port; 20 | /** Request/response code as an int*/ 21 | public int command; 22 | /** Host as string.*/ 23 | public String host=null; 24 | /** User field for SOCKS4 request messages*/ 25 | public String user=null; 26 | 27 | ProxyMessage(int command,InetAddress ip,int port){ 28 | this.command = command; 29 | this.ip = ip; 30 | this.port = port; 31 | } 32 | 33 | ProxyMessage(){ 34 | } 35 | 36 | 37 | /** 38 | Initialises Message from the stream. Reads server response from 39 | given stream. 40 | @param in Input stream to read response from. 41 | @throws SocksException If server response code is not SOCKS_SUCCESS(0), or 42 | if any error with protocol occurs. 43 | @throws IOException If any error happens with I/O. 44 | */ 45 | public abstract void read(InputStream in) 46 | throws SocksException, 47 | IOException; 48 | 49 | 50 | /** 51 | Initialises Message from the stream. Reads server response or client 52 | request from given stream. 53 | 54 | @param in Input stream to read response from. 55 | @param clinetMode If true read server response, else read client request. 56 | @throws SocksException If server response code is not SOCKS_SUCCESS(0) and 57 | reading in client mode, or if any error with protocol occurs. 58 | @throws IOException If any error happens with I/O. 59 | */ 60 | public abstract void read(InputStream in,boolean client_mode) 61 | throws SocksException, 62 | IOException; 63 | 64 | 65 | /** 66 | Writes the message to the stream. 67 | @param out Output stream to which message should be written. 68 | */ 69 | public abstract void write(OutputStream out)throws SocksException, 70 | IOException; 71 | 72 | /** 73 | Get the Address field of this message as InetAddress object. 74 | @return Host address or null, if one can't be determined. 75 | */ 76 | public InetAddress getInetAddress() throws UnknownHostException{ 77 | return ip; 78 | } 79 | 80 | 81 | /** 82 | Get string representaion of this message. 83 | @return string representation of this message. 84 | */ 85 | public String toString(){ 86 | return 87 | "Proxy Message:\n"+ 88 | "Version:"+ version+"\n"+ 89 | "Command:"+ command+"\n"+ 90 | "IP: "+ ip+"\n"+ 91 | "Port: "+ port+"\n"+ 92 | "User: "+ user+"\n" ; 93 | } 94 | 95 | //Package methods 96 | ////////////////// 97 | 98 | static final String bytes2IPV4(byte[] addr,int offset){ 99 | String hostName = ""+(addr[offset] & 0xFF); 100 | for(int i = offset+1;i 0) { 64 | System.out.write(buf, 0, bytes_read); 65 | System.out.flush(); 66 | } 67 | } catch (final IOException io_ex) { 68 | io_ex.printStackTrace(); 69 | } 70 | } 71 | 72 | public static void usage() { 73 | System.err.print("Usage: java Echo host port [peerHost peerPort]\n"); 74 | } 75 | 76 | public static void main(String args[]) { 77 | int port; 78 | String host, peerHost; 79 | int peerPort; 80 | Echo echo = null; 81 | 82 | if (args.length > 1) { 83 | try { 84 | 85 | host = args[0]; 86 | port = Integer.parseInt(args[1]); 87 | 88 | if (args.length == 4) { 89 | peerHost = args[2]; 90 | peerPort = Integer.parseInt(args[3]); 91 | echo = new Echo(host, port, peerHost, peerPort); 92 | } else { 93 | echo = new Echo(host, port); 94 | } 95 | 96 | final Thread thread = new Thread(echo); 97 | thread.start(); 98 | 99 | final BufferedReader in = new BufferedReader( 100 | new InputStreamReader(System.in)); 101 | String s; 102 | 103 | s = in.readLine(); 104 | Thread.currentThread().setPriority(Thread.NORM_PRIORITY); 105 | while (s != null) { 106 | echo.send(s + "\r\n"); 107 | s = in.readLine(); 108 | } 109 | } catch (final IOException io_ex) { 110 | io_ex.printStackTrace(); 111 | System.exit(1); 112 | } catch (final NumberFormatException num_ex) { 113 | usage(); 114 | num_ex.printStackTrace(); 115 | System.exit(1); 116 | } finally { 117 | if (echo != null) { 118 | try { 119 | echo.ss.close(); 120 | } catch (final Exception e) { 121 | } 122 | } 123 | } 124 | 125 | } else { 126 | usage(); 127 | } 128 | } 129 | 130 | }// End of class 131 | -------------------------------------------------------------------------------- /helpers/com/runjva/sourceforge/jsocks/helpers/SocksTest.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.helpers; 2 | import java.io.BufferedReader; 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | import java.io.OutputStream; 7 | import java.net.InetAddress; 8 | import java.net.Proxy; 9 | import java.net.Socket; 10 | import java.net.UnknownHostException; 11 | 12 | import com.runjva.sourceforge.jsocks.SocksException; 13 | import com.runjva.sourceforge.jsocks.SocksSocket; 14 | 15 | /** SOCKS aware echo client*/ 16 | 17 | public class SocksTest implements Runnable{ 18 | 19 | private int port; 20 | private InetAddress hostIP; 21 | 22 | private Socket ss; 23 | private InputStream in; 24 | private OutputStream out; 25 | 26 | private static final int BUF_SIZE = 1024; 27 | static final int defaultProxyPort = 1080; //Default Port 28 | static final String defaultProxyHost = "www-proxy"; //Default proxy 29 | 30 | public SocksTest(String host,int port) 31 | throws IOException,UnknownHostException,SocksException{ 32 | this.port = port; 33 | 34 | ss = new SocksSocket(host, port); 35 | out = ss.getOutputStream(); 36 | in = ss.getInputStream(); 37 | System.out.println("Connected..."); 38 | System.out.println("TO: "+host+":"+port); 39 | System.out.println("ViaProxy: "+ss.getLocalAddress().getHostAddress() 40 | +":"+ss.getLocalPort()); 41 | 42 | } 43 | 44 | public void close()throws IOException{ 45 | ss.close(); 46 | } 47 | public void send(String s) throws IOException{ 48 | out.write(s.getBytes()); 49 | } 50 | 51 | public void run(){ 52 | byte[] buf = new byte[1024]; 53 | int bytes_read; 54 | try{ 55 | while((bytes_read = in.read(buf)) > 0){ 56 | System.out.write(buf,0,bytes_read); 57 | } 58 | }catch(IOException io_ex){ 59 | io_ex.printStackTrace(); 60 | } 61 | } 62 | 63 | public static void usage(){ 64 | System.err.print( 65 | "Usage: java SocksTest host port [socksHost socksPort]\n"); 66 | } 67 | 68 | 69 | public static void main(String args[]){ 70 | int port; 71 | String host; 72 | int proxyPort; 73 | String proxyHost; 74 | 75 | if(args.length > 1 && args.length < 5){ 76 | try{ 77 | 78 | host = args[0]; 79 | port = Integer.parseInt(args[1]); 80 | 81 | proxyPort =(args.length > 3)? Integer.parseInt(args[3]) 82 | : defaultProxyPort; 83 | 84 | host = args[0]; 85 | proxyHost =(args.length > 2)? args[2] 86 | : defaultProxyHost; 87 | 88 | com.runjva.sourceforge.jsocks.Proxy.setDefaultProxy(proxyHost,proxyPort,"KOUKY001"); 89 | //Proxy.setDefaultProxy(proxyHost,proxyPort); 90 | com.runjva.sourceforge.jsocks.Proxy.getDefaultProxy().setDirect(InetAddress.getByName("localhost")); 91 | 92 | 93 | SocksTest st = new SocksTest(host,port); 94 | Thread thread = new Thread(st); 95 | thread.start(); 96 | 97 | BufferedReader in = new BufferedReader( 98 | new InputStreamReader(System.in)); 99 | String s; 100 | 101 | s = in.readLine(); 102 | while(s != null){ 103 | st.send(s+"\r\n"); 104 | //try{ 105 | //Thread.currentThread().sleep(10); 106 | //}catch(InterruptedException i_ex){ 107 | //} 108 | s = in.readLine(); 109 | } 110 | st.close(); 111 | System.exit(1); 112 | 113 | }catch(SocksException s_ex){ 114 | System.err.println("SocksException:"+s_ex); 115 | s_ex.printStackTrace(); 116 | System.exit(1); 117 | }catch(IOException io_ex){ 118 | io_ex.printStackTrace(); 119 | System.exit(1); 120 | }catch(NumberFormatException num_ex){ 121 | usage(); 122 | num_ex.printStackTrace(); 123 | System.exit(1); 124 | } 125 | 126 | }else{ 127 | usage(); 128 | } 129 | } 130 | 131 | }//End of class 132 | -------------------------------------------------------------------------------- /docs/rfc1929.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Network Working Group M. Leech 8 | Request for Comments: 1929 Bell-Northern Research Ltd 9 | Category: Standards Track March 1996 10 | 11 | 12 | Username/Password Authentication for SOCKS V5 13 | 14 | Status of this Memo 15 | 16 | This document specifies an Internet standards track protocol for the 17 | Internet community, and requests discussion and suggestions for 18 | improvements. Please refer to the current edition of the "Internet 19 | Official Protocol Standards" (STD 1) for the standardization state 20 | and status of this protocol. Distribution of this memo is unlimited. 21 | 22 | 1. Introduction 23 | 24 | The protocol specification for SOCKS Version 5 specifies a 25 | generalized framework for the use of arbitrary authentication 26 | protocols in the initial socks connection setup. This document 27 | describes one of those protocols, as it fits into the SOCKS Version 5 28 | authentication "subnegotiation". 29 | 30 | Note: 31 | 32 | Unless otherwise noted, the decimal numbers appearing in packet- 33 | format diagrams represent the length of the corresponding field, in 34 | octets. Where a given octet must take on a specific value, the 35 | syntax X'hh' is used to denote the value of the single octet in that 36 | field. When the word 'Variable' is used, it indicates that the 37 | corresponding field has a variable length defined either by an 38 | associated (one or two octet) length field, or by a data type field. 39 | 40 | 2. Initial negotiation 41 | 42 | Once the SOCKS V5 server has started, and the client has selected the 43 | Username/Password Authentication protocol, the Username/Password 44 | subnegotiation begins. This begins with the client producing a 45 | Username/Password request: 46 | 47 | +----+------+----------+------+----------+ 48 | |VER | ULEN | UNAME | PLEN | PASSWD | 49 | +----+------+----------+------+----------+ 50 | | 1 | 1 | 1 to 255 | 1 | 1 to 255 | 51 | +----+------+----------+------+----------+ 52 | 53 | 54 | 55 | 56 | 57 | 58 | Leech Standards Track [Page 1] 59 | 60 | RFC 1929 Username Authentication for SOCKS V5 March 1996 61 | 62 | 63 | The VER field contains the current version of the subnegotiation, 64 | which is X'01'. The ULEN field contains the length of the UNAME field 65 | that follows. The UNAME field contains the username as known to the 66 | source operating system. The PLEN field contains the length of the 67 | PASSWD field that follows. The PASSWD field contains the password 68 | association with the given UNAME. 69 | 70 | The server verifies the supplied UNAME and PASSWD, and sends the 71 | following response: 72 | 73 | +----+--------+ 74 | |VER | STATUS | 75 | +----+--------+ 76 | | 1 | 1 | 77 | +----+--------+ 78 | 79 | A STATUS field of X'00' indicates success. If the server returns a 80 | `failure' (STATUS value other than X'00') status, it MUST close the 81 | connection. 82 | 83 | 3. Security Considerations 84 | 85 | This document describes a subnegotiation that provides authentication 86 | services to the SOCKS protocol. Since the request carries the 87 | password in cleartext, this subnegotiation is not recommended for 88 | environments where "sniffing" is possible and practical. 89 | 90 | 4. Author's Address 91 | 92 | Marcus Leech 93 | Bell-Northern Research Ltd 94 | P.O. Box 3511, Station C 95 | Ottawa, ON 96 | CANADA K1Y 4H7 97 | 98 | Phone: +1 613 763 9145 99 | EMail: mleech@bnr.ca 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | Leech Standards Track [Page 2] 115 | 116 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/Socks4Proxy.java: -------------------------------------------------------------------------------- 1 | package socks; 2 | import java.net.*; 3 | import java.io.*; 4 | import java.util.Hashtable; 5 | import java.util.Enumeration; 6 | 7 | /** 8 | Proxy which describes SOCKS4 proxy. 9 | */ 10 | 11 | public class Socks4Proxy extends Proxy implements Cloneable{ 12 | 13 | //Data members 14 | String user; 15 | 16 | //Public Constructors 17 | //==================== 18 | 19 | /** 20 | Creates the SOCKS4 proxy 21 | @param p Proxy to use to connect to this proxy, allows proxy chaining. 22 | @param proxyHost Address of the proxy server. 23 | @param proxyPort Port of the proxy server 24 | @param user User name to use for identification purposes. 25 | @throws UnknownHostException If proxyHost can't be resolved. 26 | */ 27 | public Socks4Proxy(Proxy p,String proxyHost,int proxyPort,String user) 28 | throws UnknownHostException{ 29 | super(p,proxyHost,proxyPort); 30 | this.user = new String(user); 31 | version = 4; 32 | } 33 | 34 | /** 35 | Creates the SOCKS4 proxy 36 | @param proxyHost Address of the proxy server. 37 | @param proxyPort Port of the proxy server 38 | @param user User name to use for identification purposes. 39 | @throws UnknownHostException If proxyHost can't be resolved. 40 | */ 41 | public Socks4Proxy(String proxyHost,int proxyPort,String user) 42 | throws UnknownHostException{ 43 | this(null,proxyHost,proxyPort,user); 44 | } 45 | 46 | /** 47 | Creates the SOCKS4 proxy 48 | @param p Proxy to use to connect to this proxy, allows proxy chaining. 49 | @param proxyIP Address of the proxy server. 50 | @param proxyPort Port of the proxy server 51 | @param user User name to use for identification purposes. 52 | */ 53 | public Socks4Proxy(Proxy p,InetAddress proxyIP,int proxyPort,String user){ 54 | super(p,proxyIP,proxyPort); 55 | this.user = new String(user); 56 | version = 4; 57 | } 58 | 59 | /** 60 | Creates the SOCKS4 proxy 61 | @param proxyIP Address of the proxy server. 62 | @param proxyPort Port of the proxy server 63 | @param user User name to use for identification purposes. 64 | */ 65 | public Socks4Proxy(InetAddress proxyIP,int proxyPort,String user){ 66 | this(null,proxyIP,proxyPort,user); 67 | } 68 | 69 | //Public instance methods 70 | //======================== 71 | 72 | /** 73 | * Creates a clone of this proxy. Changes made to the clone should not 74 | * affect this object. 75 | */ 76 | public Object clone(){ 77 | Socks4Proxy newProxy = new Socks4Proxy(proxyIP,proxyPort,user); 78 | newProxy.directHosts = (InetRange)directHosts.clone(); 79 | newProxy.chainProxy = chainProxy; 80 | return newProxy; 81 | } 82 | 83 | 84 | //Public Static(Class) Methods 85 | //============================== 86 | 87 | 88 | //Protected Methods 89 | //================= 90 | 91 | protected Proxy copy(){ 92 | Socks4Proxy copy = new Socks4Proxy(proxyIP,proxyPort,user); 93 | copy.directHosts = this.directHosts; 94 | copy.chainProxy = chainProxy; 95 | return copy; 96 | } 97 | 98 | protected ProxyMessage formMessage(int cmd,InetAddress ip,int port){ 99 | switch(cmd){ 100 | case SOCKS_CMD_CONNECT: 101 | cmd = Socks4Message.REQUEST_CONNECT; 102 | break; 103 | case SOCKS_CMD_BIND: 104 | cmd = Socks4Message.REQUEST_BIND; 105 | break; 106 | default: 107 | return null; 108 | } 109 | return new Socks4Message(cmd,ip,port,user); 110 | } 111 | protected ProxyMessage formMessage(int cmd,String host,int port) 112 | throws UnknownHostException{ 113 | return formMessage(cmd,InetAddress.getByName(host),port); 114 | } 115 | protected ProxyMessage formMessage(InputStream in) 116 | throws SocksException, 117 | IOException{ 118 | return new Socks4Message(in,true); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/protocol/Socks4Proxy.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.protocol; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.net.InetAddress; 6 | import java.net.UnknownHostException; 7 | 8 | /** 9 | * Proxy which describes SOCKS4 proxy. 10 | */ 11 | 12 | public class Socks4Proxy extends SocksProxyBase implements Cloneable { 13 | 14 | // Data members 15 | String user; 16 | 17 | // Public Constructors 18 | // ==================== 19 | 20 | /** 21 | * Creates the SOCKS4 proxy 22 | * 23 | * @param p 24 | * Proxy to use to connect to this proxy, allows proxy chaining. 25 | * @param proxyHost 26 | * Address of the proxy server. 27 | * @param proxyPort 28 | * Port of the proxy server 29 | * @param user 30 | * User name to use for identification purposes. 31 | * @throws UnknownHostException 32 | * If proxyHost can't be resolved. 33 | */ 34 | public Socks4Proxy(SocksProxyBase p, String proxyHost, int proxyPort, 35 | String user) throws UnknownHostException { 36 | super(p, proxyHost, proxyPort); 37 | this.user = user; 38 | version = 4; 39 | } 40 | 41 | /** 42 | * Creates the SOCKS4 proxy 43 | * 44 | * @param proxyHost 45 | * Address of the proxy server. 46 | * @param proxyPort 47 | * Port of the proxy server 48 | * @param user 49 | * User name to use for identification purposes. 50 | * @throws UnknownHostException 51 | * If proxyHost can't be resolved. 52 | */ 53 | public Socks4Proxy(String proxyHost, int proxyPort, String user) 54 | throws UnknownHostException { 55 | this(null, proxyHost, proxyPort, user); 56 | } 57 | 58 | /** 59 | * Creates the SOCKS4 proxy 60 | * 61 | * @param p 62 | * Proxy to use to connect to this proxy, allows proxy chaining. 63 | * @param proxyIP 64 | * Address of the proxy server. 65 | * @param proxyPort 66 | * Port of the proxy server 67 | * @param user 68 | * User name to use for identification purposes. 69 | */ 70 | public Socks4Proxy(SocksProxyBase p, InetAddress proxyIP, int proxyPort, 71 | String user) { 72 | super(p, proxyIP, proxyPort); 73 | this.user = user; 74 | version = 4; 75 | } 76 | 77 | /** 78 | * Creates the SOCKS4 proxy 79 | * 80 | * @param proxyIP 81 | * Address of the proxy server. 82 | * @param proxyPort 83 | * Port of the proxy server 84 | * @param user 85 | * User name to use for identification purposes. 86 | */ 87 | public Socks4Proxy(InetAddress proxyIP, int proxyPort, String user) { 88 | this(null, proxyIP, proxyPort, user); 89 | } 90 | 91 | // Public instance methods 92 | // ======================== 93 | 94 | /** 95 | * Creates a clone of this proxy. Changes made to the clone should not 96 | * affect this object. 97 | */ 98 | public Object clone() { 99 | final Socks4Proxy newProxy = new Socks4Proxy(proxyIP, proxyPort, user); 100 | newProxy.directHosts = (InetRange) directHosts.clone(); 101 | newProxy.chainProxy = chainProxy; 102 | return newProxy; 103 | } 104 | 105 | // Public Static(Class) Methods 106 | // ============================== 107 | 108 | // Protected Methods 109 | // ================= 110 | 111 | protected SocksProxyBase copy() { 112 | final Socks4Proxy copy = new Socks4Proxy(proxyIP, proxyPort, user); 113 | copy.directHosts = this.directHosts; 114 | copy.chainProxy = chainProxy; 115 | return copy; 116 | } 117 | 118 | protected ProxyMessage formMessage(int cmd, InetAddress ip, int port) { 119 | switch (cmd) { 120 | case SOCKS_CMD_CONNECT: 121 | cmd = Socks4Message.REQUEST_CONNECT; 122 | break; 123 | case SOCKS_CMD_BIND: 124 | cmd = Socks4Message.REQUEST_BIND; 125 | break; 126 | default: 127 | return null; 128 | } 129 | return new Socks4Message(cmd, ip, port, user); 130 | } 131 | 132 | protected ProxyMessage formMessage(int cmd, String host, int port) 133 | throws UnknownHostException { 134 | 135 | return formMessage(cmd, InetAddress.getByName(host), port); 136 | } 137 | 138 | protected ProxyMessage formMessage(InputStream in) throws 139 | IOException { 140 | 141 | return new Socks4Message(in, true); 142 | } 143 | 144 | } 145 | -------------------------------------------------------------------------------- /jsocks_code1.01/test/UDPEcho.java: -------------------------------------------------------------------------------- 1 | import java.net.*; 2 | import java.io.*; 3 | /** 4 | Plain SOCKS unaware UDP echo server and client. 5 | */ 6 | public class UDPEcho implements Runnable{ 7 | 8 | private int port; 9 | private InetAddress hostIP; 10 | private DatagramSocket sock; 11 | 12 | private static final int BUF_SIZE = 1024; 13 | 14 | 15 | public UDPEcho(String host,int port) 16 | throws IOException,UnknownHostException{ 17 | this.hostIP = InetAddress.getByName(host); 18 | this.port = port; 19 | sock = new DatagramSocket(); 20 | System.out.println("UDP: "+sock.getLocalAddress()+":"+ 21 | sock.getLocalPort()); 22 | //sock.connect(hostIP,port); 23 | } 24 | 25 | public void send(String s) throws IOException{ 26 | System.out.println("Sending:"+s); 27 | DatagramPacket packet = new DatagramPacket(s.getBytes(), 28 | s.length(), 29 | hostIP, 30 | port); 31 | sock.send(packet); 32 | } 33 | 34 | public void run(){ 35 | byte[] buf = new byte[BUF_SIZE]; 36 | DatagramPacket incomingData = new DatagramPacket(buf,buf.length); 37 | try{ 38 | while(true){ 39 | sock.receive(incomingData); 40 | System.out.println("UDP From:"+ 41 | incomingData.getAddress().getHostAddress()+":"+ 42 | incomingData.getPort()); 43 | System.out.println(new String(incomingData.getData(), 44 | 0,incomingData.getLength())); 45 | System.out.flush(); 46 | incomingData.setLength(buf.length); 47 | } 48 | }catch(IOException io_ex){ 49 | io_ex.printStackTrace(); 50 | } 51 | } 52 | 53 | public static void usage(){ 54 | System.err.print( 55 | "Usage: java UDPEcho host port\n"+ 56 | "OR\n"+ 57 | "Usage: java UDPEcho port\n"); 58 | } 59 | 60 | public static void doEcho(int port)throws IOException{ 61 | byte[] buf = new byte[BUF_SIZE]; 62 | DatagramPacket packet = new DatagramPacket(buf,buf.length); 63 | DatagramSocket sock = new DatagramSocket(port); 64 | 65 | System.out.println("Starting UDP echo on"+ 66 | sock.getLocalAddress().getHostAddress()+ 67 | ":"+sock.getLocalPort()); 68 | while(true){ 69 | try{ 70 | sock.receive(packet); 71 | sock.send(packet); 72 | System.out.print( 73 | "UDP From: "+packet.getAddress().getHostAddress()+":"+ 74 | packet.getPort()+ 75 | "\n"+ 76 | new String(packet.getData(),0,packet.getLength())+ 77 | "\n" 78 | ); 79 | System.out.flush(); 80 | 81 | packet.setLength(buf.length); 82 | //packet = new DatagramPacket(buf,buf.length); 83 | }catch(IOException io_ex){ 84 | } 85 | } 86 | } 87 | 88 | public static void main(String args[]){ 89 | int port; 90 | String host; 91 | 92 | if(args.length == 1){ 93 | try{ 94 | port = Integer.parseInt(args[0]); 95 | 96 | doEcho(port); 97 | 98 | }catch(IOException io_ex){ 99 | io_ex.printStackTrace(); 100 | System.exit(1); 101 | 102 | }catch(NumberFormatException num_ex){ 103 | num_ex.printStackTrace(); 104 | System.exit(1); 105 | } 106 | }else if(args.length == 2){ 107 | try{ 108 | host = args[0]; 109 | port = Integer.parseInt(args[1]); 110 | 111 | UDPEcho ut = new UDPEcho(host,port); 112 | Thread thread = new Thread(ut); 113 | thread.start(); 114 | 115 | BufferedReader in = new BufferedReader( 116 | new InputStreamReader(System.in)); 117 | String s; 118 | System.out.print("Enter datagram:"); 119 | s = in.readLine(); 120 | while(s != null){ 121 | ut.send(s); 122 | try{ 123 | Thread.currentThread().sleep(100); 124 | }catch(InterruptedException i_ex){ 125 | } 126 | System.out.print("Enter datagram:"); 127 | s = in.readLine(); 128 | } 129 | System.exit(1); 130 | 131 | }catch(IOException io_ex){ 132 | io_ex.printStackTrace(); 133 | System.exit(1); 134 | }catch(NumberFormatException num_ex){ 135 | num_ex.printStackTrace(); 136 | System.exit(1); 137 | } 138 | 139 | }else{ 140 | usage(); 141 | } 142 | } 143 | 144 | }//End of class 145 | -------------------------------------------------------------------------------- /helpers/com/runjva/sourceforge/jsocks/helpers/UDPEcho.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.helpers; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.net.DatagramPacket; 7 | import java.net.DatagramSocket; 8 | import java.net.InetAddress; 9 | import java.net.UnknownHostException; 10 | 11 | /** 12 | * Plain SOCKS unaware UDP echo server and client. 13 | */ 14 | public class UDPEcho implements Runnable { 15 | 16 | private final int port; 17 | private final InetAddress hostIP; 18 | private final DatagramSocket sock; 19 | 20 | private static final int BUF_SIZE = 1024; 21 | 22 | public UDPEcho(String host, int port) throws IOException, 23 | UnknownHostException { 24 | this.hostIP = InetAddress.getByName(host); 25 | this.port = port; 26 | sock = new DatagramSocket(); 27 | System.out.println("UDP: " + sock.getLocalAddress() + ":" 28 | + sock.getLocalPort()); 29 | // sock.connect(hostIP,port); 30 | } 31 | 32 | public void send(String s) throws IOException { 33 | System.out.println("Sending:" + s); 34 | final DatagramPacket packet = new DatagramPacket(s.getBytes(), s 35 | .length(), hostIP, port); 36 | sock.send(packet); 37 | } 38 | 39 | public void run() { 40 | final byte[] buf = new byte[BUF_SIZE]; 41 | final DatagramPacket incomingData = new DatagramPacket(buf, buf.length); 42 | try { 43 | while (true) { 44 | sock.receive(incomingData); 45 | System.out.println("UDP From:" 46 | + incomingData.getAddress().getHostAddress() + ":" 47 | + incomingData.getPort()); 48 | System.out.println(new String(incomingData.getData(), 0, 49 | incomingData.getLength())); 50 | System.out.flush(); 51 | incomingData.setLength(buf.length); 52 | } 53 | } catch (final IOException io_ex) { 54 | io_ex.printStackTrace(); 55 | } 56 | } 57 | 58 | public static void usage() { 59 | System.err.print("Usage: java UDPEcho host port\n" + "OR\n" 60 | + "Usage: java UDPEcho port\n"); 61 | } 62 | 63 | public static void doEcho(int port) throws IOException { 64 | final byte[] buf = new byte[BUF_SIZE]; 65 | final DatagramPacket packet = new DatagramPacket(buf, buf.length); 66 | final DatagramSocket sock = new DatagramSocket(port); 67 | 68 | System.out.println("Starting UDP echo on" 69 | + sock.getLocalAddress().getHostAddress() + ":" 70 | + sock.getLocalPort()); 71 | while (true) { 72 | try { 73 | sock.receive(packet); 74 | sock.send(packet); 75 | System.out.print("UDP From: " 76 | + packet.getAddress().getHostAddress() + ":" 77 | + packet.getPort() + "\n" 78 | + new String(packet.getData(), 0, packet.getLength()) 79 | + "\n"); 80 | System.out.flush(); 81 | 82 | packet.setLength(buf.length); 83 | // packet = new DatagramPacket(buf,buf.length); 84 | } catch (final IOException io_ex) { 85 | } 86 | } 87 | } 88 | 89 | public static void main(String args[]) { 90 | int port; 91 | String host; 92 | 93 | if (args.length == 1) { 94 | try { 95 | port = Integer.parseInt(args[0]); 96 | 97 | doEcho(port); 98 | 99 | } catch (final IOException io_ex) { 100 | io_ex.printStackTrace(); 101 | System.exit(1); 102 | 103 | } catch (final NumberFormatException num_ex) { 104 | num_ex.printStackTrace(); 105 | System.exit(1); 106 | } 107 | } else if (args.length == 2) { 108 | try { 109 | host = args[0]; 110 | port = Integer.parseInt(args[1]); 111 | 112 | final UDPEcho ut = new UDPEcho(host, port); 113 | final Thread thread = new Thread(ut); 114 | thread.start(); 115 | 116 | final BufferedReader in = new BufferedReader( 117 | new InputStreamReader(System.in)); 118 | String s; 119 | System.out.print("Enter datagram:"); 120 | s = in.readLine(); 121 | while (s != null) { 122 | ut.send(s); 123 | try { 124 | Thread.currentThread(); 125 | Thread.sleep(100); 126 | } catch (final InterruptedException i_ex) { 127 | } 128 | System.out.print("Enter datagram:"); 129 | s = in.readLine(); 130 | } 131 | System.exit(1); 132 | 133 | } catch (final IOException io_ex) { 134 | io_ex.printStackTrace(); 135 | System.exit(1); 136 | } catch (final NumberFormatException num_ex) { 137 | num_ex.printStackTrace(); 138 | System.exit(1); 139 | } 140 | 141 | } else { 142 | usage(); 143 | } 144 | } 145 | 146 | }// End of class 147 | -------------------------------------------------------------------------------- /socks.properties: -------------------------------------------------------------------------------- 1 | #SOCKS server initialisation file. 2 | 3 | 4 | #Port on which the socks server should run 5 | #If not set deafults to 1080 6 | port = 1080 7 | 8 | #Timeout settings for the SOCKS server,in milliseconds. 9 | #If not defined, all default to 3 minutes(18000ms). 10 | # 11 | # iddleTimeout If no data received from/to user during this interval 12 | # connection will be aborted. 13 | # acceptTimeout If no connection is accepted during this interval, 14 | # connection will be aborted. 15 | # udpTimeout If no datagrams are received from/to user, in this interval 16 | # UDP relay server stops, and control connection is closed. 17 | # Any of these can be 0, implying infinit timeout, that is once the 18 | # connection is made, it is kept alive until one of the parties closes it. 19 | # In case of the BIND command, it implies that server will be listenning 20 | # for incoming connection until it is accepted, or until client closes 21 | # control connection. 22 | # For UDP servers it implies, that they will run as long, as client 23 | # keeps control connection open. 24 | 25 | iddleTimeout = 600000 # 10 minutes 26 | acceptTimeout = 60000 # 1 minute 27 | udpTimeout = 600000 # 10 minutes 28 | 29 | #datagramSize -- Size of the datagrams to use for udp relaying. 30 | #Defaults to 64K bytes(0xFFFF = 65535 a bit more than maximum possible size). 31 | #datagramSize = 8192 32 | 33 | #log -- Name of the file, to which logging should be done 34 | # If log is - (minus sine) do logging to standart output. 35 | #Optional field, if not defined, no logging is done. 36 | # 37 | 38 | #log = - 39 | 40 | #host -- Host on which to run, for multihomed hosts, 41 | # Default -- all(system dependent) 42 | #host = some.hostOfMine.com 43 | 44 | #range -- Semicolon(;) separated range of addresses, from which 45 | #connections should be accepted. 46 | # 47 | # Range could be one of those 48 | # 1. Stand alone host name -- some.host.com or 33.33.44.101 49 | # 2. Host range 50 | # .my.domain.net 51 | # 190.220.34. 52 | # host1:host2 53 | # 33.44.100:33.44.200 54 | # 55 | # Example: .myDomain.com;100.220.30.;myHome.host.com;\ 56 | # comp1.myWork.com:comp10.myWork.com 57 | # 58 | # This will include all computers in the domain myDomain.com, 59 | # all computers whose addresses start with 100.200.30, 60 | # host with the name myHome.host.com, 61 | # and computers comp1 through to comp2 in the domain myWork.com, 62 | # assuming their names correspond to there ip addresses. 63 | # 64 | # NOTE: Dot(.) by itself implies all hosts, be sure not to include 65 | # one of those. 66 | 67 | 68 | range = localhost;130.220. 69 | 70 | #users 71 | # Semicolon(;) separated list of users, for whom permissions should be 72 | # granted, given they connect from one of the hosts speciefied by range. 73 | # This field is optional, if not defined, ANY user will be allowed to use 74 | # SOCKS server, given he\she is connecting from one of the hosts in the 75 | # range. 76 | # NOTE: Whitespaces are not ignored (except for the first name, it's how java 77 | # parses Property files). 78 | # User names are CASESenSitive. 79 | # You have been warned. 80 | # NOTE2: Misspelling users with Users, or anything, will be understood as 81 | # if users were not defined, and hence will imply that ANYBODY, will 82 | # be granted access from the hosts in the range. 83 | # 84 | 85 | users = kirillka;cis-dude;root 86 | 87 | # Proxy configurations, that is what proxy this proxy should use, if any. 88 | # proxy should be a semicolon(;) separated list of proxy entries. 89 | # Each entry shoud be in the form: host[:port:user:password]. 90 | # If only host is supplied SOCKSv5 proxy is assumed, running on port 1080. 91 | # If user is supplied, but password not supplied, SOCKSv4 is assumed, 92 | # running oon machine 'host' on port 'port', user name will be supplied as 93 | # authentication for that proxy. 94 | # If both user and password is supplied, SOCKSv5 proxy is assumed, with 95 | # user/password authentication. 96 | # 97 | # directHosts should contain ;-separated list of inetaddress and ranges. 98 | # These machines will be addressed directly rather than through 99 | # the proxy. See range for more details, what sort of entries 100 | # permitted and understood. 101 | 102 | 103 | 104 | proxy = www-proxy:1080 105 | directHosts = 130.220.;.unisa.edu.au;localhost 106 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks.properties: -------------------------------------------------------------------------------- 1 | #SOCKS server initialisation file. 2 | 3 | 4 | #Port on which the socks server should run 5 | #If not set deafults to 1080 6 | port = 1080 7 | 8 | #Timeout settings for the SOCKS server,in milliseconds. 9 | #If not defined, all default to 3 minutes(18000ms). 10 | # 11 | # iddleTimeout If no data received from/to user during this interval 12 | # connection will be aborted. 13 | # acceptTimeout If no connection is accepted during this interval, 14 | # connection will be aborted. 15 | # udpTimeout If no datagrams are received from/to user, in this interval 16 | # UDP relay server stops, and control connection is closed. 17 | # Any of these can be 0, implying infinit timeout, that is once the 18 | # connection is made, it is kept alive until one of the parties closes it. 19 | # In case of the BIND command, it implies that server will be listenning 20 | # for incoming connection until it is accepted, or until client closes 21 | # control connection. 22 | # For UDP servers it implies, that they will run as long, as client 23 | # keeps control connection open. 24 | 25 | iddleTimeout = 600000 # 10 minutes 26 | acceptTimeout = 60000 # 1 minute 27 | udpTimeout = 600000 # 10 minutes 28 | 29 | #datagramSize -- Size of the datagrams to use for udp relaying. 30 | #Defaults to 64K bytes(0xFFFF = 65535 a bit more than maximum possible size). 31 | #datagramSize = 8192 32 | 33 | #log -- Name of the file, to which logging should be done 34 | # If log is - (minus sine) do logging to standart output. 35 | #Optional field, if not defined, no logging is done. 36 | # 37 | 38 | #log = - 39 | 40 | #host -- Host on which to run, for multihomed hosts, 41 | # Default -- all(system dependent) 42 | #host = some.hostOfMine.com 43 | 44 | #range -- Semicolon(;) separated range of addresses, from which 45 | #connections should be accepted. 46 | # 47 | # Range could be one of those 48 | # 1. Stand alone host name -- some.host.com or 33.33.44.101 49 | # 2. Host range 50 | # .my.domain.net 51 | # 190.220.34. 52 | # host1:host2 53 | # 33.44.100:33.44.200 54 | # 55 | # Example: .myDomain.com;100.220.30.;myHome.host.com;\ 56 | # comp1.myWork.com:comp10.myWork.com 57 | # 58 | # This will include all computers in the domain myDomain.com, 59 | # all computers whose addresses start with 100.200.30, 60 | # host with the name myHome.host.com, 61 | # and computers comp1 through to comp2 in the domain myWork.com, 62 | # assuming their names correspond to there ip addresses. 63 | # 64 | # NOTE: Dot(.) by itself implies all hosts, be sure not to include 65 | # one of those. 66 | 67 | 68 | range = localhost;130.220. 69 | 70 | #users 71 | # Semicolon(;) separated list of users, for whom permissions should be 72 | # granted, given they connect from one of the hosts speciefied by range. 73 | # This field is optional, if not defined, ANY user will be allowed to use 74 | # SOCKS server, given he\she is connecting from one of the hosts in the 75 | # range. 76 | # NOTE: Whitespaces are not ignored (except for the first name, it's how java 77 | # parses Property files). 78 | # User names are CASESenSitive. 79 | # You have been warned. 80 | # NOTE2: Misspelling users with Users, or anything, will be understood as 81 | # if users were not defined, and hence will imply that ANYBODY, will 82 | # be granted access from the hosts in the range. 83 | # 84 | 85 | users = kirillka;cis-dude;root 86 | 87 | # Proxy configurations, that is what proxy this proxy should use, if any. 88 | # proxy should be a semicolon(;) separated list of proxy entries. 89 | # Each entry shoud be in the form: host[:port:user:password]. 90 | # If only host is supplied SOCKSv5 proxy is assumed, running on port 1080. 91 | # If user is supplied, but password not supplied, SOCKSv4 is assumed, 92 | # running oon machine 'host' on port 'port', user name will be supplied as 93 | # authentication for that proxy. 94 | # If both user and password is supplied, SOCKSv5 proxy is assumed, with 95 | # user/password authentication. 96 | # 97 | # directHosts should contain ;-separated list of inetaddress and ranges. 98 | # These machines will be addressed directly rather than through 99 | # the proxy. See range for more details, what sort of entries 100 | # permitted and understood. 101 | 102 | 103 | 104 | proxy = www-proxy:1080 105 | directHosts = 130.220.;.unisa.edu.au;localhost 106 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/server/ServerAuthenticator.java: -------------------------------------------------------------------------------- 1 | package socks.server; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.net.Socket; 7 | import java.net.DatagramPacket; 8 | import socks.ProxyMessage; 9 | import socks.UDPEncapsulation; 10 | 11 | /** 12 | Classes implementing this interface should provide socks server with 13 | authentication and authorization of users. 14 | **/ 15 | public interface ServerAuthenticator{ 16 | 17 | /** 18 | This method is called when a new connection accepted by the server. 19 |

20 | At this point no data have been extracted from the connection. It is 21 | responsibility of this method to ensure that the next byte in the 22 | stream after this method have been called is the first byte of the 23 | socks request message. For SOCKSv4 there is no authentication data and 24 | the first byte in the stream is part of the request. With SOCKSv5 however 25 | there is an authentication data first. It is expected that implementaions 26 | will process this authentication data. 27 |

28 | If authentication was successful an instance of ServerAuthentication 29 | should be returned, it later will be used by the server to perform 30 | authorization and some other things. If authentication fails null should 31 | be returned, or an exception may be thrown. 32 | 33 | @param s Accepted Socket. 34 | @return An instance of ServerAuthenticator to be used for this connection 35 | or null 36 | */ 37 | ServerAuthenticator startSession(Socket s) throws IOException; 38 | 39 | /** 40 | This method should return input stream which should be used on the 41 | accepted socket. 42 |

43 | SOCKSv5 allows to have multiple authentication methods, and these methods 44 | might require some kind of transformations being made on the data. 45 |

46 | This method is called on the object returned from the startSession 47 | function. 48 | */ 49 | InputStream getInputStream(); 50 | /** 51 | This method should return output stream to use to write to the accepted 52 | socket. 53 |

54 | SOCKSv5 allows to have multiple authentication methods, and these methods 55 | might require some kind of transformations being made on the data. 56 |

57 | This method is called on the object returned from the startSession 58 | function. 59 | */ 60 | OutputStream getOutputStream(); 61 | 62 | /** 63 | This method should return UDPEncapsulation, which should be used 64 | on the datagrams being send in/out. 65 |

66 | If no transformation should be done on the datagrams, this method 67 | should return null. 68 |

69 | This method is called on the object returned from the startSession 70 | function. 71 | */ 72 | 73 | UDPEncapsulation getUdpEncapsulation(); 74 | 75 | /** 76 | This method is called when a request have been read. 77 |

78 | Implementation should decide wether to grant request or not. Returning 79 | true implies granting the request, false means request should be rejected. 80 |

81 | This method is called on the object returned from the startSession 82 | function. 83 | @param msg Request message. 84 | @return true to grant request, false to reject it. 85 | */ 86 | boolean checkRequest(ProxyMessage msg); 87 | 88 | /** 89 | This method is called when datagram is received by the server. 90 |

91 | Implementaions should decide wether it should be forwarded or dropped. 92 | It is expecteed that implementation will use datagram address and port 93 | information to make a decision, as well as anything else. Address and 94 | port of the datagram are always correspond to remote machine. It is 95 | either destination or source address. If out is true address is destination 96 | address, else it is a source address, address of the machine from which 97 | datagram have been received for the client. 98 |

99 | Implementaions should return true if the datagram is to be forwarded, and 100 | false if the datagram should be dropped. 101 |

102 | This method is called on the object returned from the startSession 103 | function. 104 | 105 | @param out If true the datagram is being send out(from the client), 106 | otherwise it is an incoming datagram. 107 | @return True to forward datagram false drop it silently. 108 | */ 109 | boolean checkRequest(DatagramPacket dp, boolean out); 110 | 111 | /** 112 | This method is called when session is completed. Either due to normal 113 | termination or due to any error condition. 114 |

115 | This method is called on the object returned from the startSession 116 | function. 117 | */ 118 | void endSession(); 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/protocol/Socks4Message.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.protocol; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.OutputStream; 7 | import java.net.InetAddress; 8 | import java.net.UnknownHostException; 9 | 10 | /** 11 | * SOCKS4 Reply/Request message. 12 | */ 13 | 14 | class Socks4Message extends ProxyMessage { 15 | 16 | private byte[] msgBytes; 17 | private int msgLength; 18 | 19 | /** 20 | * Server failed reply, cmd command for failed request 21 | */ 22 | public Socks4Message(final int cmd) { 23 | super(cmd, null, 0); 24 | this.user = null; 25 | 26 | msgLength = 2; 27 | msgBytes = new byte[2]; 28 | 29 | msgBytes[0] = (byte) 0; 30 | msgBytes[1] = (byte) command; 31 | } 32 | 33 | /** 34 | * Server successfull reply 35 | */ 36 | public Socks4Message(final int cmd, final InetAddress ip, final int port) { 37 | this(0, cmd, ip, port, null); 38 | } 39 | 40 | /** 41 | * Client request 42 | */ 43 | public Socks4Message(final int cmd, final InetAddress ip, final int port, 44 | final String user) { 45 | this(SOCKS_VERSION, cmd, ip, port, user); 46 | } 47 | 48 | /** 49 | * Most general constructor 50 | */ 51 | public Socks4Message(final int version, final int cmd, 52 | final InetAddress ip, final int port, final String user) { 53 | 54 | super(cmd, ip, port); 55 | this.user = user; 56 | this.version = version; 57 | 58 | msgLength = user == null ? 8 : 9 + user.length(); 59 | msgBytes = new byte[msgLength]; 60 | 61 | msgBytes[0] = (byte) version; 62 | msgBytes[1] = (byte) command; 63 | msgBytes[2] = (byte) (port >> 8); 64 | msgBytes[3] = (byte) port; 65 | 66 | byte[] addr; 67 | 68 | if (ip != null) { 69 | addr = ip.getAddress(); 70 | } else { 71 | addr = new byte[4]; 72 | addr[0] = addr[1] = addr[2] = addr[3] = 0; 73 | } 74 | System.arraycopy(addr, 0, msgBytes, 4, 4); 75 | 76 | if (user != null) { 77 | final byte[] buf = user.getBytes(); 78 | System.arraycopy(buf, 0, msgBytes, 8, buf.length); 79 | msgBytes[msgBytes.length - 1] = 0; 80 | } 81 | } 82 | 83 | /** 84 | * Initialise from the stream If clientMode is true attempts to read a 85 | * server response otherwise reads a client request see read for more detail 86 | */ 87 | public Socks4Message(final InputStream in, final boolean clientMode) 88 | throws IOException { 89 | msgBytes = null; 90 | read(in, clientMode); 91 | } 92 | 93 | public void read(final InputStream in) throws IOException { 94 | read(in, true); 95 | } 96 | 97 | public void read(final InputStream in, final boolean clientMode) 98 | throws IOException { 99 | final DataInputStream d_in = new DataInputStream(in); 100 | version = d_in.readUnsignedByte(); 101 | command = d_in.readUnsignedByte(); 102 | if (clientMode && (command != REPLY_OK)) { 103 | String errMsg; 104 | // FIXME: Range should be replaced with cases. 105 | if ((command > REPLY_OK) && (command < REPLY_BAD_IDENTD)) { 106 | errMsg = replyMessage[command - REPLY_OK]; 107 | } else { 108 | errMsg = "Unknown Reply Code"; 109 | } 110 | throw new SocksException(command, errMsg); 111 | } 112 | port = d_in.readUnsignedShort(); 113 | final byte[] addr = new byte[4]; 114 | d_in.readFully(addr); 115 | ip = bytes2IP(addr); 116 | host = ip.getHostName(); 117 | if (!clientMode) { 118 | int b = in.read(); 119 | // FIXME: Hope there are no idiots with user name bigger than this 120 | final byte[] userBytes = new byte[256]; 121 | int i = 0; 122 | for (i = 0; (i < userBytes.length) && (b > 0); ++i) { 123 | userBytes[i] = (byte) b; 124 | b = in.read(); 125 | } 126 | user = new String(userBytes, 0, i); 127 | } 128 | } 129 | 130 | public void write(final OutputStream out) throws IOException { 131 | if (msgBytes == null) { 132 | final Socks4Message msg; 133 | msg = new Socks4Message(version, command, ip, port, user); 134 | msgBytes = msg.msgBytes; 135 | msgLength = msg.msgLength; 136 | } 137 | out.write(msgBytes); 138 | } 139 | 140 | // Class methods 141 | static InetAddress bytes2IP(final byte[] addr) { 142 | final String s = bytes2IPV4(addr, 0); 143 | try { 144 | return InetAddress.getByName(s); 145 | } catch (final UnknownHostException uh_ex) { 146 | return null; 147 | } 148 | } 149 | 150 | // Constants 151 | 152 | static final String[] replyMessage = { "Request Granted", 153 | "Request Rejected or Failed", 154 | "Failed request, can't connect to Identd", 155 | "Failed request, bad user name" }; 156 | 157 | static final int SOCKS_VERSION = 4; 158 | 159 | public final static int REQUEST_CONNECT = 1; 160 | public final static int REQUEST_BIND = 2; 161 | 162 | public final static int REPLY_OK = 90; 163 | public final static int REPLY_REJECTED = 91; 164 | public final static int REPLY_NO_CONNECT = 92; 165 | public final static int REPLY_BAD_IDENTD = 93; 166 | 167 | } 168 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/Socks4Message.java: -------------------------------------------------------------------------------- 1 | package socks; 2 | import java.io.*; 3 | import java.net.*; 4 | 5 | /** 6 | SOCKS4 Reply/Request message. 7 | */ 8 | 9 | class Socks4Message extends ProxyMessage{ 10 | 11 | private byte[] msgBytes; 12 | private int msgLength; 13 | 14 | /** 15 | * Server failed reply, cmd command for failed request 16 | */ 17 | public Socks4Message(int cmd){ 18 | super(cmd,null,0); 19 | this.user = null; 20 | 21 | msgLength = 2; 22 | msgBytes = new byte[2]; 23 | 24 | msgBytes[0] = (byte) 0; 25 | msgBytes[1] = (byte) command; 26 | } 27 | 28 | /** 29 | * Server successfull reply 30 | */ 31 | public Socks4Message(int cmd,InetAddress ip,int port){ 32 | this(0,cmd,ip,port,null); 33 | } 34 | 35 | /** 36 | * Client request 37 | */ 38 | public Socks4Message(int cmd,InetAddress ip,int port,String user){ 39 | this(SOCKS_VERSION,cmd,ip,port,user); 40 | } 41 | 42 | /** 43 | * Most general constructor 44 | */ 45 | public Socks4Message(int version, int cmd, 46 | InetAddress ip,int port,String user){ 47 | super(cmd,ip,port); 48 | this.user = user; 49 | this.version = version; 50 | 51 | msgLength = user == null?8:9+user.length(); 52 | msgBytes = new byte[msgLength]; 53 | 54 | msgBytes[0] = (byte) version; 55 | msgBytes[1] = (byte) command; 56 | msgBytes[2] = (byte) (port >> 8); 57 | msgBytes[3] = (byte) port; 58 | 59 | byte[] addr; 60 | 61 | if(ip != null) 62 | addr = ip.getAddress(); 63 | else{ 64 | addr = new byte[4]; 65 | addr[0]=addr[1]=addr[2]=addr[3]=0; 66 | } 67 | System.arraycopy(addr,0,msgBytes,4,4); 68 | 69 | if(user != null){ 70 | byte[] buf = user.getBytes(); 71 | System.arraycopy(buf,0,msgBytes,8,buf.length); 72 | msgBytes[msgBytes.length -1 ] = 0; 73 | } 74 | } 75 | 76 | /** 77 | *Initialise from the stream 78 | *If clientMode is true attempts to read a server response 79 | *otherwise reads a client request 80 | *see read for more detail 81 | */ 82 | public Socks4Message(InputStream in, boolean clientMode) throws IOException{ 83 | msgBytes = null; 84 | read(in,clientMode); 85 | } 86 | 87 | public void read(InputStream in) throws IOException{ 88 | read(in,true); 89 | } 90 | 91 | public void read(InputStream in, boolean clientMode) throws IOException{ 92 | DataInputStream d_in = new DataInputStream(in); 93 | version= d_in.readUnsignedByte(); 94 | command = d_in.readUnsignedByte(); 95 | if(clientMode && command != REPLY_OK){ 96 | String errMsg; 97 | if(command >REPLY_OK && command < REPLY_BAD_IDENTD) 98 | errMsg = replyMessage[command-REPLY_OK]; 99 | else 100 | errMsg = "Unknown Reply Code"; 101 | throw new SocksException(command,errMsg); 102 | } 103 | port = d_in.readUnsignedShort(); 104 | byte[] addr = new byte[4]; 105 | d_in.readFully(addr); 106 | ip=bytes2IP(addr); 107 | host = ip.getHostName(); 108 | if(!clientMode){ 109 | int b = in.read(); 110 | //Hope there are no idiots with user name bigger than this 111 | byte[] userBytes = new byte[256]; 112 | int i = 0; 113 | for(i =0;i0;++i){ 114 | userBytes[i] = (byte) b; 115 | b = in.read(); 116 | } 117 | user = new String(userBytes,0,i); 118 | } 119 | } 120 | public void write(OutputStream out) throws IOException{ 121 | if(msgBytes == null){ 122 | Socks4Message msg = new Socks4Message(version,command,ip,port,user); 123 | msgBytes = msg.msgBytes; 124 | msgLength = msg.msgLength; 125 | } 126 | out.write(msgBytes); 127 | } 128 | 129 | //Class methods 130 | static InetAddress bytes2IP(byte[] addr){ 131 | String s = bytes2IPV4(addr,0); 132 | try{ 133 | return InetAddress.getByName(s); 134 | }catch(UnknownHostException uh_ex){ 135 | return null; 136 | } 137 | } 138 | 139 | //Constants 140 | 141 | static final String[] replyMessage ={ 142 | "Request Granted", 143 | "Request Rejected or Failed", 144 | "Failed request, can't connect to Identd", 145 | "Failed request, bad user name"}; 146 | 147 | static final int SOCKS_VERSION = 4; 148 | 149 | public final static int REQUEST_CONNECT = 1; 150 | public final static int REQUEST_BIND = 2; 151 | 152 | public final static int REPLY_OK = 90; 153 | public final static int REPLY_REJECTED = 91; 154 | public final static int REPLY_NO_CONNECT = 92; 155 | public final static int REPLY_BAD_IDENTD = 93; 156 | 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/server/ServerAuthenticator.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.server; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.net.DatagramPacket; 7 | import java.net.Socket; 8 | 9 | import com.runjva.sourceforge.jsocks.protocol.ProxyMessage; 10 | import com.runjva.sourceforge.jsocks.protocol.UDPEncapsulation; 11 | 12 | /** 13 | * Classes implementing this interface should provide socks server with 14 | * authentication and authorization of users. 15 | **/ 16 | public interface ServerAuthenticator { 17 | 18 | /** 19 | * This method is called when a new connection accepted by the server. 20 | *

21 | * At this point no data have been extracted from the connection. It is 22 | * responsibility of this method to ensure that the next byte in the stream 23 | * after this method have been called is the first byte of the socks request 24 | * message. For SOCKSv4 there is no authentication data and the first byte 25 | * in the stream is part of the request. With SOCKSv5 however there is an 26 | * authentication data first. It is expected that implementaions will 27 | * process this authentication data. 28 | *

29 | * If authentication was successful an instance of ServerAuthentication 30 | * should be returned, it later will be used by the server to perform 31 | * authorization and some other things. If authentication fails null should 32 | * be returned, or an exception may be thrown. 33 | * 34 | * @param s 35 | * Accepted Socket. 36 | * @return An instance of ServerAuthenticator to be used for this connection 37 | * or null 38 | */ 39 | ServerAuthenticator startSession(Socket s) throws IOException; 40 | 41 | /** 42 | * This method should return input stream which should be used on the 43 | * accepted socket. 44 | *

45 | * SOCKSv5 allows to have multiple authentication methods, and these methods 46 | * might require some kind of transformations being made on the data. 47 | *

48 | * This method is called on the object returned from the startSession 49 | * function. 50 | */ 51 | InputStream getInputStream(); 52 | 53 | /** 54 | * This method should return output stream to use to write to the accepted 55 | * socket. 56 | *

57 | * SOCKSv5 allows to have multiple authentication methods, and these methods 58 | * might require some kind of transformations being made on the data. 59 | *

60 | * This method is called on the object returned from the startSession 61 | * function. 62 | */ 63 | OutputStream getOutputStream(); 64 | 65 | /** 66 | * This method should return UDPEncapsulation, which should be used on the 67 | * datagrams being send in/out. 68 | *

69 | * If no transformation should be done on the datagrams, this method should 70 | * return null. 71 | *

72 | * This method is called on the object returned from the startSession 73 | * function. 74 | */ 75 | 76 | UDPEncapsulation getUdpEncapsulation(); 77 | 78 | /** 79 | * This method is called when a request have been read. 80 | *

81 | * Implementation should decide wether to grant request or not. Returning 82 | * true implies granting the request, false means request should be 83 | * rejected. 84 | *

85 | * This method is called on the object returned from the startSession 86 | * function. 87 | * 88 | * @param msg 89 | * Request message. 90 | * @return true to grant request, false to reject it. 91 | */ 92 | boolean checkRequest(ProxyMessage msg); 93 | 94 | /** 95 | * This method is called when datagram is received by the server. 96 | *

97 | * Implementaions should decide wether it should be forwarded or dropped. It 98 | * is expecteed that implementation will use datagram address and port 99 | * information to make a decision, as well as anything else. Address and 100 | * port of the datagram are always correspond to remote machine. It is 101 | * either destination or source address. If out is true address is 102 | * destination address, else it is a source address, address of the machine 103 | * from which datagram have been received for the client. 104 | *

105 | * Implementaions should return true if the datagram is to be forwarded, and 106 | * false if the datagram should be dropped. 107 | *

108 | * This method is called on the object returned from the startSession 109 | * function. 110 | * 111 | * @param out 112 | * If true the datagram is being send out(from the client), 113 | * otherwise it is an incoming datagram. 114 | * @return True to forward datagram false drop it silently. 115 | */ 116 | boolean checkRequest(DatagramPacket dp, boolean out); 117 | 118 | /** 119 | * This method is called when session is completed. Either due to normal 120 | * termination or due to any error condition. 121 | *

122 | * This method is called on the object returned from the startSession 123 | * function. 124 | */ 125 | void endSession(); 126 | } 127 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/server/IdentAuthenticator.java: -------------------------------------------------------------------------------- 1 | package socks.server; 2 | import socks.InetRange; 3 | import socks.ProxyMessage; 4 | import java.util.Hashtable; 5 | import java.util.Vector; 6 | import java.util.Enumeration; 7 | import java.net.*; 8 | import java.io.*; 9 | 10 | /** 11 | An implementation of socks.ServerAuthentication which provides 12 | simple authentication based on the host from which the connection 13 | is made and the name of the user on the remote machine, as reported 14 | by identd daemon on the remote machine. 15 |

16 | It can also be used to provide authentication based only on the contacting 17 | host address. 18 | */ 19 | 20 | public class IdentAuthenticator extends ServerAuthenticatorNone{ 21 | /** Vector of InetRanges */ 22 | Vector hosts; 23 | 24 | /** Vector of user hashes*/ 25 | Vector users; 26 | 27 | String user; 28 | 29 | 30 | /** 31 | Constructs empty IdentAuthenticator. 32 | */ 33 | public IdentAuthenticator(){ 34 | hosts = new Vector(); 35 | users = new Vector(); 36 | } 37 | /** 38 | Used to create instances returned from startSession. 39 | @param in Input stream. 40 | @param out OutputStream. 41 | @param user Username associated with this connection,could be 42 | null if name was not required. 43 | */ 44 | IdentAuthenticator(InputStream in,OutputStream out, String user){ 45 | super(in,out); 46 | this.user = user; 47 | } 48 | 49 | /** 50 | Adds range of addresses from which connection is allowed. Hashtable 51 | users should contain user names as keys and anything as values 52 | (value is not used and will be ignored). 53 | @param hostRange Range of ip addresses from which connection is allowed. 54 | @param users Hashtable of users for whom connection is allowed, or null 55 | to indicate that anybody is allowed to connect from the hosts within given 56 | range. 57 | */ 58 | public synchronized void add(InetRange hostRange,Hashtable users){ 59 | this.hosts.addElement(hostRange); 60 | this.users.addElement(users); 61 | } 62 | 63 | /** 64 | Grants permission only to those users, who connect from one of the 65 | hosts registered with add(InetRange,Hashtable) and whose names, as 66 | reported by identd daemon, are listed for the host the connection 67 | came from. 68 | */ 69 | public ServerAuthenticator startSession(Socket s) 70 | throws IOException{ 71 | 72 | int ind = getRangeIndex(s.getInetAddress()); 73 | String user = null; 74 | 75 | //System.out.println("getRangeReturned:"+ind); 76 | 77 | if(ind < 0) return null; //Host is not on the list. 78 | 79 | ServerAuthenticatorNone auth = (ServerAuthenticatorNone) 80 | super.startSession(s); 81 | 82 | //System.out.println("super.startSession() returned:"+auth); 83 | if(auth == null) return null; 84 | 85 | //do the authentication 86 | 87 | Hashtable user_names = (Hashtable) users.elementAt(ind); 88 | 89 | if(user_names != null){ //If need to do authentication 90 | Ident ident; 91 | ident = new Ident(s); 92 | //If can't obtain user name, fail 93 | if(!ident.successful) return null; 94 | //If user name is not listed for this address, fail 95 | if(!user_names.containsKey(ident.userName)) return null; 96 | user = ident.userName; 97 | } 98 | return new IdentAuthenticator(auth.in,auth.out,user); 99 | 100 | } 101 | /** 102 | For SOCKS5 requests allways returns true. For SOCKS4 requests 103 | checks wether the user name supplied in the request corresponds 104 | to the name obtained from the ident daemon. 105 | */ 106 | public boolean checkRequest(ProxyMessage msg,java.net.Socket s){ 107 | //If it's version 5 request, or if anybody is permitted, return true; 108 | if(msg.version == 5 || user == null) 109 | return true; 110 | 111 | if(msg.version != 4) return false; //Who knows? 112 | 113 | return user.equals(msg.user); 114 | } 115 | 116 | /** Get String representaion of the IdentAuthenticator.*/ 117 | public String toString(){ 118 | String s = ""; 119 | 120 | for(int i=0;inot do any 14 | * authentication. 15 | *

16 | * Warning!!
17 | * Should not be used on machines which are not behind the firewall. 18 | *

19 | * It is only provided to make implementing other authentication schemes easier. 20 | *
21 | * For Example:

 22 |    class MyAuth extends socks.server.ServerAuthenticator{
 23 |     ...
 24 |     public ServerAuthenticator startSession(java.net.Socket s){
 25 |       if(!checkHost(s.getInetAddress()) return null;
 26 |       return super.startSession(s);
 27 |     }
 28 | 
 29 |     boolean checkHost(java.net.Inetaddress addr){
 30 |       boolean allow;
 31 |       //Do it somehow
 32 |       return allow;
 33 |     }
 34 |    }
 35 | 
36 | */ 37 | public abstract class ServerAuthenticatorBase implements ServerAuthenticator { 38 | 39 | static final byte[] socks5response = { 5, 0 }; 40 | 41 | final InputStream in; 42 | final OutputStream out; 43 | 44 | /** 45 | * Creates new instance of the ServerAuthenticatorNone. 46 | */ 47 | public ServerAuthenticatorBase() { 48 | this.in = null; 49 | this.out = null; 50 | } 51 | 52 | /** 53 | * Constructs new ServerAuthenticatorNone object suitable for returning from 54 | * the startSession function. 55 | * 56 | * @param in 57 | * Input stream to return from getInputStream method. 58 | * @param out 59 | * Output stream to return from getOutputStream method. 60 | */ 61 | public ServerAuthenticatorBase(InputStream in, OutputStream out) { 62 | this.in = in; 63 | this.out = out; 64 | } 65 | 66 | /** 67 | * Grants access to everyone.Removes authentication related bytes from the 68 | * stream, when a SOCKS5 connection is being made, selects an authentication 69 | * NONE. 70 | */ 71 | public ServerAuthenticator startSession(Socket s) throws IOException { 72 | 73 | final PushbackInputStream in = new PushbackInputStream(s 74 | .getInputStream()); 75 | final OutputStream out = s.getOutputStream(); 76 | 77 | final int version = in.read(); 78 | if (version == 5) { 79 | if (!selectSocks5Authentication(in, out, 0)) { 80 | return null; 81 | } 82 | } else if (version == 4) { 83 | // Else it is the request message already, version 4 84 | in.unread(version); 85 | } else { 86 | return null; 87 | } 88 | 89 | return new ServerAuthenticatorNone(in, out); 90 | } 91 | 92 | /** 93 | * Get input stream. 94 | * 95 | * @return Input stream speciefied in the constructor. 96 | */ 97 | public InputStream getInputStream() { 98 | return in; 99 | } 100 | 101 | /** 102 | * Get output stream. 103 | * 104 | * @return Output stream speciefied in the constructor. 105 | */ 106 | public OutputStream getOutputStream() { 107 | return out; 108 | } 109 | 110 | /** 111 | * Allways returns null. 112 | * 113 | * @return null 114 | */ 115 | public UDPEncapsulation getUdpEncapsulation() { 116 | return null; 117 | } 118 | 119 | /** 120 | * Allways returns true. 121 | */ 122 | public boolean checkRequest(ProxyMessage msg) { 123 | return true; 124 | } 125 | 126 | /** 127 | * Allways returns true. 128 | */ 129 | public boolean checkRequest(java.net.DatagramPacket dp, boolean out) { 130 | return true; 131 | } 132 | 133 | /** 134 | * Does nothing. 135 | */ 136 | public void endSession() { 137 | } 138 | 139 | /** 140 | * Convinience routine for selecting SOCKSv5 authentication. 141 | *

142 | * This method reads in authentication methods that client supports, checks 143 | * wether it supports given method. If it does, the notification method is 144 | * written back to client, that this method have been chosen for 145 | * authentication. If given method was not found, authentication failure 146 | * message is send to client ([5,FF]). 147 | * 148 | * @param in 149 | * Input stream, version byte should be removed from the stream 150 | * before calling this method. 151 | * @param out 152 | * Output stream. 153 | * @param methodId 154 | * Method which should be selected. 155 | * @return true if methodId was found, false otherwise. 156 | */ 157 | static public boolean selectSocks5Authentication(InputStream in, 158 | OutputStream out, int methodId) throws IOException { 159 | 160 | final int num_methods = in.read(); 161 | if (num_methods <= 0) { 162 | return false; 163 | } 164 | final byte[] method_ids = new byte[num_methods]; 165 | final byte[] response = new byte[2]; 166 | boolean found = false; 167 | 168 | response[0] = (byte) 5; // SOCKS version 169 | response[1] = (byte) 0xFF; // Not found, we are pessimistic 170 | 171 | int bread = 0; // bytes read so far 172 | while (bread < num_methods) { 173 | bread += in.read(method_ids, bread, num_methods - bread); 174 | } 175 | 176 | for (int i = 0; i < num_methods; ++i) { 177 | if (method_ids[i] == methodId) { 178 | found = true; 179 | response[1] = (byte) methodId; 180 | break; 181 | } 182 | } 183 | 184 | out.write(response); 185 | return found; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/server/ServerAuthenticatorNone.java: -------------------------------------------------------------------------------- 1 | package socks.server; 2 | import socks.ProxyMessage; 3 | import socks.UDPEncapsulation; 4 | 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.DataInputStream; 8 | import java.io.OutputStream; 9 | import java.io.PushbackInputStream; 10 | import java.net.Socket; 11 | 12 | /** 13 | An implementation of ServerAuthenticator, which does not do 14 | any authentication. 15 |

16 | Warning!!
Should not be 17 | used on machines which are not behind the firewall. 18 |

19 | It is only provided to make implementing other authentication schemes 20 | easier.
21 | For Example:

 22 |    class MyAuth extends socks.server.ServerAuthenticator{
 23 |     ...
 24 |     public ServerAuthenticator startSession(java.net.Socket s){
 25 |       if(!checkHost(s.getInetAddress()) return null;
 26 |       return super.startSession(s);
 27 |     }
 28 | 
 29 |     boolean checkHost(java.net.Inetaddress addr){
 30 |       boolean allow;
 31 |       //Do it somehow
 32 |       return allow;
 33 |     }
 34 |    }
 35 | 
36 | */ 37 | public class ServerAuthenticatorNone implements ServerAuthenticator{ 38 | 39 | static final byte[] socks5response = {5,0}; 40 | 41 | InputStream in; 42 | OutputStream out; 43 | 44 | /** 45 | Creates new instance of the ServerAuthenticatorNone. 46 | */ 47 | public ServerAuthenticatorNone(){ 48 | this.in = null; 49 | this.out = null; 50 | } 51 | /** 52 | Constructs new ServerAuthenticatorNone object suitable for returning 53 | from the startSession function. 54 | @param in Input stream to return from getInputStream method. 55 | @param out Output stream to return from getOutputStream method. 56 | */ 57 | public ServerAuthenticatorNone(InputStream in, OutputStream out){ 58 | this.in = in; 59 | this.out = out; 60 | } 61 | /** 62 | Grants access to everyone.Removes authentication related bytes from 63 | the stream, when a SOCKS5 connection is being made, selects an 64 | authentication NONE. 65 | */ 66 | public ServerAuthenticator startSession(Socket s) 67 | throws IOException{ 68 | 69 | PushbackInputStream in = new PushbackInputStream(s.getInputStream()); 70 | OutputStream out = s.getOutputStream(); 71 | 72 | int version = in.read(); 73 | if(version == 5){ 74 | if(!selectSocks5Authentication(in,out,0)) 75 | return null; 76 | }else if(version == 4){ 77 | //Else it is the request message allready, version 4 78 | in.unread(version); 79 | }else 80 | return null; 81 | 82 | 83 | return new ServerAuthenticatorNone(in,out); 84 | } 85 | 86 | /** 87 | Get input stream. 88 | @return Input stream speciefied in the constructor. 89 | */ 90 | public InputStream getInputStream(){ 91 | return in; 92 | } 93 | /** 94 | Get output stream. 95 | @return Output stream speciefied in the constructor. 96 | */ 97 | public OutputStream getOutputStream(){ 98 | return out; 99 | } 100 | /** 101 | Allways returns null. 102 | @return null 103 | */ 104 | public UDPEncapsulation getUdpEncapsulation(){ 105 | return null; 106 | } 107 | 108 | /** 109 | Allways returns true. 110 | */ 111 | public boolean checkRequest(ProxyMessage msg){ 112 | return true; 113 | } 114 | 115 | /** 116 | Allways returns true. 117 | */ 118 | public boolean checkRequest(java.net.DatagramPacket dp, boolean out){ 119 | return true; 120 | } 121 | 122 | /** 123 | Does nothing. 124 | */ 125 | public void endSession(){ 126 | } 127 | 128 | /** 129 | Convinience routine for selecting SOCKSv5 authentication. 130 |

131 | This method reads in authentication methods that client supports, 132 | checks wether it supports given method. If it does, the notification 133 | method is written back to client, that this method have been chosen 134 | for authentication. If given method was not found, authentication 135 | failure message is send to client ([5,FF]). 136 | @param in Input stream, version byte should be removed from the stream 137 | before calling this method. 138 | @param out Output stream. 139 | @param methodId Method which should be selected. 140 | @return true if methodId was found, false otherwise. 141 | */ 142 | static public boolean selectSocks5Authentication(InputStream in, 143 | OutputStream out, 144 | int methodId) 145 | throws IOException{ 146 | 147 | int num_methods = in.read(); 148 | if (num_methods <= 0) return false; 149 | byte method_ids[] = new byte[num_methods]; 150 | byte response[] = new byte[2]; 151 | boolean found = false; 152 | 153 | response[0] = (byte) 5; //SOCKS version 154 | response[1] = (byte) 0xFF; //Not found, we are pessimistic 155 | 156 | int bread = 0; //bytes read so far 157 | while(bread < num_methods) 158 | bread += in.read(method_ids,bread,num_methods-bread); 159 | 160 | for(int i=0;i 21 | * It can also be used to provide authentication based only on the contacting 22 | * host address. 23 | */ 24 | 25 | public class IdentAuthenticator extends ServerAuthenticatorBase { 26 | /** Vector of InetRanges */ 27 | Vector hosts; 28 | 29 | /** Vector of user hashes */ 30 | Vector> users; 31 | 32 | String user; 33 | 34 | /** 35 | * Constructs empty IdentAuthenticator. 36 | */ 37 | public IdentAuthenticator() { 38 | hosts = new Vector(); 39 | users = new Vector>(); 40 | } 41 | 42 | /** 43 | * Used to create instances returned from startSession. 44 | * 45 | * @param in 46 | * Input stream. 47 | * @param out 48 | * OutputStream. 49 | * @param user 50 | * Username associated with this connection,could be null if name 51 | * was not required. 52 | */ 53 | IdentAuthenticator(InputStream in, OutputStream out, String user) { 54 | super(in, out); 55 | this.user = user; 56 | } 57 | 58 | /** 59 | * Adds range of addresses from which connection is allowed. Hashtable users 60 | * should contain user names as keys and anything as values (value is not 61 | * used and will be ignored). 62 | * 63 | * @param hostRange 64 | * Range of ip addresses from which connection is allowed. 65 | * @param users 66 | * Hashtable of users for whom connection is allowed, or null to 67 | * indicate that anybody is allowed to connect from the hosts 68 | * within given range. 69 | */ 70 | public synchronized void add(InetRange hostRange, Hashtable users) { 71 | this.hosts.addElement(hostRange); 72 | this.users.addElement(users); 73 | } 74 | 75 | /** 76 | * Grants permission only to those users, who connect from one of the hosts 77 | * registered with add(InetRange,Hashtable) and whose names, as reported by 78 | * identd daemon, are listed for the host the connection came from. 79 | */ 80 | public ServerAuthenticator startSession(Socket s) throws IOException { 81 | 82 | final int ind = getRangeIndex(s.getInetAddress()); 83 | String user = null; 84 | 85 | // System.out.println("getRangeReturned:"+ind); 86 | 87 | if (ind < 0) { 88 | return null; // Host is not on the list. 89 | } 90 | 91 | final ServerAuthenticator serverAuthenticator = super.startSession(s); 92 | final ServerAuthenticatorBase auth = (ServerAuthenticatorBase) serverAuthenticator; 93 | 94 | // System.out.println("super.startSession() returned:"+auth); 95 | if (auth == null) { 96 | return null; 97 | } 98 | 99 | // do the authentication 100 | 101 | final Hashtable user_names = users.elementAt(ind); 102 | 103 | if (user_names != null) { // If need to do authentication 104 | Ident ident; 105 | ident = new Ident(s); 106 | // If can't obtain user name, fail 107 | if (!ident.successful) { 108 | return null; 109 | } 110 | // If user name is not listed for this address, fail 111 | if (!user_names.containsKey(ident.userName)) { 112 | return null; 113 | } 114 | user = ident.userName; 115 | } 116 | return new IdentAuthenticator(auth.in, auth.out, user); 117 | 118 | } 119 | 120 | /** 121 | * For SOCKS5 requests allways returns true. For SOCKS4 requests checks 122 | * wether the user name supplied in the request corresponds to the name 123 | * obtained from the ident daemon. 124 | */ 125 | public boolean checkRequest(ProxyMessage msg, java.net.Socket s) { 126 | // If it's version 5 request, or if anybody is permitted, return true; 127 | if ((msg.version == 5) || (user == null)) { 128 | return true; 129 | } 130 | 131 | if (msg.version != 4) { 132 | return false; // Who knows? 133 | } 134 | 135 | return user.equals(msg.user); 136 | } 137 | 138 | /** Get String representaion of the IdentAuthenticator. */ 139 | public String toString() { 140 | StringBuilder s = new StringBuilder(); 141 | 142 | for (int i = 0; i < hosts.size(); ++i) { 143 | s.append(String.format("(Range:%s, Users:%s) ", hosts.elementAt(i), userNames(i))); 144 | } 145 | return s.toString(); 146 | } 147 | 148 | // Private Methods 149 | // //////////////// 150 | private int getRangeIndex(InetAddress ip) { 151 | int index = 0; 152 | final Enumeration enumx = hosts.elements(); 153 | while (enumx.hasMoreElements()) { 154 | final InetRange ir = enumx.nextElement(); 155 | if (ir.contains(ip)) { 156 | return index; 157 | } 158 | index++; 159 | } 160 | return -1; // Not found 161 | } 162 | 163 | private String userNames(int i) { 164 | if (users.elementAt(i) == null) { 165 | return "Everybody is permitted."; 166 | } 167 | 168 | final Enumeration enumx = users.elementAt(i).keys(); 169 | if (!enumx.hasMoreElements()) { 170 | return ""; 171 | } 172 | StringBuilder s = new StringBuilder(enumx.nextElement().toString()); 173 | while (enumx.hasMoreElements()) { 174 | s.append("; ").append(enumx.nextElement()); 175 | } 176 | 177 | return s.toString(); 178 | } 179 | 180 | } 181 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/server/Ident.java: -------------------------------------------------------------------------------- 1 | package socks.server; 2 | import socks.*; 3 | import java.net.*; 4 | import java.io.*; 5 | import java.util.StringTokenizer; 6 | 7 | /** 8 | Class Ident provides means to obtain user name of the owner of the socket 9 | on remote machine, providing remote machine runs identd daemon. 10 |

11 | To use it: 12 |

 13 |    Socket s = ss.accept();
 14 |    Ident id = new Ident(s);
 15 |    if(id.successful) goUseUser(id.userName);
 16 |    else handleIdentError(id.errorCode,id.errorMessage)
 17 |    
18 | */ 19 | public class Ident{ 20 | 21 | /** Error Message can be null.*/ 22 | public String errorMessage; 23 | /** Host type as returned by daemon, can be null, if error happened*/ 24 | public String hostType; 25 | /** User name as returned by the identd daemon, or null, if it failed*/ 26 | public String userName; 27 | 28 | /** If this is true then userName and hostType contain valid values. 29 | Else errorCode contain the error code, and errorMessage contains 30 | the corresponding message. 31 | */ 32 | public boolean successful; 33 | /** Error code*/ 34 | public int errorCode; 35 | /** Identd on port 113 can't be contacted*/ 36 | public static final int ERR_NO_CONNECT = 1; 37 | /** Connection timed out*/ 38 | public static final int ERR_TIMEOUT = 2; 39 | /** Identd daemon responded with ERROR, in this case errorMessage 40 | contains the string explanation, as send by the daemon. 41 | */ 42 | public static final int ERR_PROTOCOL = 3; 43 | /** 44 | When parsing server response protocol error happened. 45 | */ 46 | public static final int ERR_PROTOCOL_INCORRECT = 4; 47 | 48 | 49 | /** Maximum amount of time we should wait before dropping the 50 | connection to identd server.Setting it to 0 implies infinit 51 | timeout. 52 | */ 53 | public static final int connectionTimeout = 10000; 54 | 55 | 56 | /** 57 | Constructor tries to connect to Identd daemon on the host of the 58 | given socket, and retrieve user name of the owner of given socket 59 | connection on remote machine. After constructor returns public 60 | fields are initialised to whatever the server returned. 61 |

62 | If user name was successfully retrieved successful is set to true, 63 | and userName and hostType are set to whatever server returned. If 64 | however for some reason user name was not obtained, successful is set 65 | to false and errorCode contains the code explaining the reason of 66 | failure, and errorMessage contains human readable explanation. 67 |

68 | Constructor may block, for a while. 69 | @param s Socket whose ownership on remote end should be obtained. 70 | */ 71 | public Ident(Socket s ){ 72 | Socket sock = null; 73 | successful = false; //We are pessimistic 74 | 75 | try{ 76 | sock = new Socket(s.getInetAddress(),113); 77 | sock.setSoTimeout(connectionTimeout); 78 | byte[] request = (""+s.getPort()+" , "+ 79 | s.getLocalPort()+"\r\n").getBytes(); 80 | 81 | sock.getOutputStream().write(request); 82 | 83 | BufferedReader in = new BufferedReader( 84 | new InputStreamReader(sock.getInputStream())); 85 | 86 | parseResponse(in.readLine()); 87 | 88 | }catch(InterruptedIOException iioe){ 89 | errorCode = ERR_TIMEOUT; 90 | errorMessage = "Connection to identd timed out."; 91 | }catch(ConnectException ce){ 92 | errorCode = ERR_NO_CONNECT; 93 | errorMessage = "Connection to identd server failed."; 94 | 95 | }catch(IOException ioe){ 96 | errorCode = ERR_NO_CONNECT; 97 | errorMessage = ""+ioe; 98 | }finally{ 99 | try{ if(sock!=null) sock.close();}catch(IOException ioe){}; 100 | } 101 | } 102 | 103 | private void parseResponse(String response){ 104 | if(response == null){ 105 | errorCode = ERR_PROTOCOL_INCORRECT; 106 | errorMessage = "Identd server closed connection."; 107 | return; 108 | } 109 | 110 | StringTokenizer st = new StringTokenizer(response,":"); 111 | if(st.countTokens() < 3){ 112 | errorCode = ERR_PROTOCOL_INCORRECT; 113 | errorMessage = "Can't parse server response."; 114 | return; 115 | } 116 | 117 | st.nextToken(); //Discard first token, it's basically what we have send 118 | String command = st.nextToken().trim().toUpperCase(); 119 | 120 | if(command.equals("USERID") && st.countTokens() >= 2){ 121 | successful = true; 122 | hostType = st.nextToken().trim(); 123 | userName = st.nextToken("").substring(1);//Get all that is left 124 | }else if(command.equals("ERROR")){ 125 | errorCode = ERR_PROTOCOL; 126 | errorMessage = st.nextToken(); 127 | }else{ 128 | errorCode = ERR_PROTOCOL_INCORRECT; 129 | System.out.println("Opa!"); 130 | errorMessage = "Can't parse server response."; 131 | } 132 | 133 | 134 | } 135 | 136 | /////////////////////////////////////////////// 137 | //USED for Testing 138 | /* 139 | public static void main(String[] args) throws IOException{ 140 | 141 | Socket s = null; 142 | s = new Socket("gp101-16", 1391); 143 | 144 | Ident id = new Ident(s); 145 | if(id.successful){ 146 | System.out.println("User: "+id.userName); 147 | System.out.println("HostType: "+id.hostType); 148 | }else{ 149 | System.out.println("ErrorCode: "+id.errorCode); 150 | System.out.println("ErrorMessage: "+id.errorMessage); 151 | 152 | } 153 | 154 | if(s!= null) s.close(); 155 | } 156 | //*/ 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/server/Ident.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.server; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.InterruptedIOException; 7 | import java.net.ConnectException; 8 | import java.net.Socket; 9 | import java.util.StringTokenizer; 10 | import java.util.logging.Level; 11 | import java.util.logging.Logger; 12 | 13 | /** 14 | * Class Ident provides means to obtain user name of the owner of the socket on 15 | * remote machine, providing remote machine runs identd daemon. 16 | *

17 | * To use it:

 18 |    Socket s = ss.accept();
 19 |    Ident id = new Ident(s);
 20 |    if(id.successful) goUseUser(id.userName);
 21 |    else handleIdentError(id.errorCode,id.errorMessage)
 22 |    
23 | */ 24 | public class Ident { 25 | 26 | private static final Logger log = Logger.getLogger(Ident.class.getName()); 27 | 28 | /** Error Message can be null. */ 29 | public String errorMessage; 30 | 31 | /** Host type as returned by daemon, can be null, if error happened */ 32 | public String hostType; 33 | 34 | /** User name as returned by the identd daemon, or null, if it failed */ 35 | public String userName; 36 | 37 | /** 38 | * If this is true then userName and hostType contain valid values. Else 39 | * errorCode contain the error code, and errorMessage contains the 40 | * corresponding message. 41 | */ 42 | public boolean successful; 43 | 44 | /** Error code */ 45 | public int errorCode; 46 | 47 | /** Identd on port 113 can't be contacted */ 48 | public static final int ERR_NO_CONNECT = 1; 49 | 50 | /** Connection timed out */ 51 | public static final int ERR_TIMEOUT = 2; 52 | 53 | /** 54 | * Identd daemon responded with ERROR, in this case errorMessage contains 55 | * the string explanation, as send by the daemon. 56 | */ 57 | public static final int ERR_PROTOCOL = 3; 58 | 59 | /** 60 | * When parsing server response protocol error happened. 61 | */ 62 | public static final int ERR_PROTOCOL_INCORRECT = 4; 63 | 64 | /** 65 | * Maximum amount of time we should wait before dropping the connection to 66 | * identd server.Setting it to 0 implies infinit timeout. 67 | */ 68 | public static final int connectionTimeout = 10000; 69 | 70 | /** 71 | * Constructor tries to connect to Identd daemon on the host of the given 72 | * socket, and retrieve user name of the owner of given socket connection on 73 | * remote machine. After constructor returns public fields are initialised 74 | * to whatever the server returned. 75 | *

76 | * If user name was successfully retrieved successful is set to true, and 77 | * userName and hostType are set to whatever server returned. If however for 78 | * some reason user name was not obtained, successful is set to false and 79 | * errorCode contains the code explaining the reason of failure, and 80 | * errorMessage contains human readable explanation. 81 | *

82 | * Constructor may block, for a while. 83 | * 84 | * @param s 85 | * Socket whose ownership on remote end should be obtained. 86 | */ 87 | public Ident(Socket s) { 88 | Socket sock = null; 89 | successful = false; // We are pessimistic 90 | 91 | try { 92 | sock = new Socket(s.getInetAddress(), 113); 93 | sock.setSoTimeout(connectionTimeout); 94 | final byte[] request = (s.getPort() + " , " + s.getLocalPort() + "\r\n") 95 | .getBytes(); 96 | 97 | sock.getOutputStream().write(request); 98 | 99 | final BufferedReader in = new BufferedReader(new InputStreamReader( 100 | sock.getInputStream())); 101 | 102 | parseResponse(in.readLine()); 103 | 104 | } catch (final InterruptedIOException iioe) { 105 | errorCode = ERR_TIMEOUT; 106 | errorMessage = "Connection to identd timed out."; 107 | } catch (final ConnectException ce) { 108 | errorCode = ERR_NO_CONNECT; 109 | errorMessage = "Connection to identd server failed."; 110 | 111 | } catch (final IOException ioe) { 112 | errorCode = ERR_NO_CONNECT; 113 | errorMessage = "" + ioe; 114 | } finally { 115 | try { 116 | if (sock != null) { 117 | sock.close(); 118 | } 119 | } catch (final IOException ioe) { 120 | log.log(Level.WARNING, "Could not close socket", ioe); 121 | } 122 | } 123 | } 124 | 125 | private void parseResponse(String response) { 126 | if (response == null) { 127 | errorCode = ERR_PROTOCOL_INCORRECT; 128 | errorMessage = "Identd server closed connection."; 129 | return; 130 | } 131 | 132 | final StringTokenizer st = new StringTokenizer(response, ":"); 133 | if (st.countTokens() < 3) { 134 | errorCode = ERR_PROTOCOL_INCORRECT; 135 | errorMessage = "Can't parse server response."; 136 | return; 137 | } 138 | 139 | st.nextToken(); // Discard first token, it's basically what we have send 140 | final String command = st.nextToken().trim().toUpperCase(); 141 | 142 | if (command.equals("USERID") && (st.countTokens() >= 2)) { 143 | successful = true; 144 | hostType = st.nextToken().trim(); 145 | userName = st.nextToken("").substring(1);// Get all that is left 146 | } else if (command.equals("ERROR")) { 147 | errorCode = ERR_PROTOCOL; 148 | errorMessage = st.nextToken(); 149 | } else { 150 | errorCode = ERR_PROTOCOL_INCORRECT; 151 | System.out.println("Opa!"); 152 | errorMessage = "Can't parse server response."; 153 | } 154 | 155 | } 156 | 157 | // ///////////////////////////////////////////// 158 | // USED for Testing 159 | /* 160 | * public static void main(String[] args) throws IOException{ 161 | * 162 | * Socket s = null; s = new Socket("gp101-16", 1391); 163 | * 164 | * Ident id = new Ident(s); if(id.successful){ 165 | * System.out.println("User: "+id.userName); 166 | * System.out.println("HostType: "+id.hostType); }else{ 167 | * System.out.println("ErrorCode: "+id.errorCode); 168 | * System.out.println("ErrorMessage: "+id.errorMessage); 169 | * 170 | * } 171 | * 172 | * if(s!= null) s.close(); } // 173 | */ 174 | 175 | } 176 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/protocol/UDPRelayServer.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.protocol; 2 | 3 | import java.io.IOException; 4 | import java.io.InterruptedIOException; 5 | import java.net.DatagramPacket; 6 | import java.net.DatagramSocket; 7 | import java.net.InetAddress; 8 | import java.net.Socket; 9 | import java.net.UnknownHostException; 10 | import java.util.logging.Logger; 11 | 12 | 13 | import com.runjva.sourceforge.jsocks.server.ServerAuthenticator; 14 | 15 | /** 16 | * UDP Relay server, used by ProxyServer to perform udp forwarding. 17 | */ 18 | class UDPRelayServer implements Runnable { 19 | 20 | DatagramSocket client_sock; 21 | DatagramSocket remote_sock; 22 | 23 | Socket controlConnection; 24 | 25 | int relayPort; 26 | InetAddress relayIP; 27 | 28 | Thread pipe_thread1, pipe_thread2; 29 | Thread master_thread; 30 | 31 | final ServerAuthenticator auth; 32 | 33 | long lastReadTime; 34 | 35 | private static final Logger log = Logger.getLogger(UDPRelayServer.class.getName()); 36 | static SocksProxyBase proxy = null; 37 | static int datagramSize = 0xFFFF;// 64K, a bit more than max udp size 38 | static int iddleTimeout = 180000;// 3 minutes 39 | 40 | /** 41 | * Constructs UDP relay server to communicate with client on given ip and 42 | * port. 43 | * 44 | * @param clientIP 45 | * Address of the client from whom datagrams will be recieved and 46 | * to whom they will be forwarded. 47 | * @param clientPort 48 | * Clients port. 49 | * @param master_thread 50 | * Thread which will be interrupted, when UDP relay server 51 | * stoppes for some reason. 52 | * @param controlConnection 53 | * Socket which will be closed, before interrupting the master 54 | * thread, it is introduced due to a bug in windows JVM which 55 | * does not throw InterruptedIOException in threads which block 56 | * in I/O operation. 57 | */ 58 | public UDPRelayServer(InetAddress clientIP, int clientPort, 59 | Thread master_thread, Socket controlConnection, 60 | ServerAuthenticator auth) throws IOException { 61 | 62 | this.master_thread = master_thread; 63 | this.controlConnection = controlConnection; 64 | this.auth = auth; 65 | 66 | client_sock = new Socks5DatagramSocket(true, 67 | auth.getUdpEncapsulation(), clientIP, clientPort); 68 | 69 | relayPort = client_sock.getLocalPort(); 70 | relayIP = client_sock.getLocalAddress(); 71 | 72 | if (relayIP.getHostAddress().equals("0.0.0.0")) { 73 | relayIP = InetAddress.getLocalHost(); 74 | } 75 | 76 | if (proxy == null) { 77 | remote_sock = new DatagramSocket(); 78 | } else { 79 | remote_sock = new Socks5DatagramSocket(proxy, 0, null); 80 | } 81 | } 82 | 83 | // Public methods 84 | // /////////////// 85 | 86 | /** 87 | * Sets the timeout for UDPRelay server.
88 | * Zero timeout implies infinity.
89 | * Default timeout is 3 minutes. 90 | */ 91 | 92 | static public void setTimeout(int timeout) { 93 | iddleTimeout = timeout; 94 | } 95 | 96 | /** 97 | * Sets the size of the datagrams used in the UDPRelayServer.
98 | * Default size is 64K, a bit more than maximum possible size of the 99 | * datagram. 100 | */ 101 | static public void setDatagramSize(int size) { 102 | datagramSize = size; 103 | } 104 | 105 | /** 106 | * Port to which client should send datagram for association. 107 | */ 108 | public int getRelayPort() { 109 | return relayPort; 110 | } 111 | 112 | /** 113 | * IP address to which client should send datagrams for association. 114 | */ 115 | public InetAddress getRelayIP() { 116 | return relayIP; 117 | } 118 | 119 | /** 120 | * Starts udp relay server. Spawns two threads of execution and returns. 121 | */ 122 | public void start() throws IOException { 123 | remote_sock.setSoTimeout(iddleTimeout); 124 | client_sock.setSoTimeout(iddleTimeout); 125 | 126 | log.info("Starting UDP relay server on " + relayIP + ":" + relayPort); 127 | log.info("Remote socket "+ remote_sock.getLocalAddress() + ":" + 128 | remote_sock.getLocalPort()); 129 | 130 | pipe_thread1 = new Thread(this, "pipe1"); 131 | pipe_thread2 = new Thread(this, "pipe2"); 132 | 133 | lastReadTime = System.currentTimeMillis(); 134 | 135 | pipe_thread1.start(); 136 | pipe_thread2.start(); 137 | } 138 | 139 | /** 140 | * Stops Relay server. 141 | *

142 | * Does not close control connection, does not interrupt master_thread. 143 | */ 144 | public synchronized void stop() { 145 | master_thread = null; 146 | controlConnection = null; 147 | abort(); 148 | } 149 | 150 | // Runnable interface 151 | // ////////////////// 152 | public void run() { 153 | try { 154 | if (Thread.currentThread().getName().equals("pipe1")) { 155 | pipe(remote_sock, client_sock, false); 156 | } else { 157 | pipe(client_sock, remote_sock, true); 158 | } 159 | } catch (final IOException ioe) { 160 | } finally { 161 | abort(); 162 | log.info("UDP Pipe thread " + Thread.currentThread().getName() 163 | + " stopped."); 164 | } 165 | 166 | } 167 | 168 | // Private methods 169 | // /////////////// 170 | private synchronized void abort() { 171 | if (pipe_thread1 == null) { 172 | return; 173 | } 174 | 175 | log.info("Aborting UDP Relay Server"); 176 | 177 | remote_sock.close(); 178 | client_sock.close(); 179 | 180 | if (controlConnection != null) { 181 | try { 182 | controlConnection.close(); 183 | } catch (final IOException ioe) { 184 | } 185 | } 186 | 187 | if (master_thread != null) { 188 | master_thread.interrupt(); 189 | } 190 | 191 | pipe_thread1.interrupt(); 192 | pipe_thread2.interrupt(); 193 | 194 | pipe_thread1 = null; 195 | } 196 | 197 | private void pipe(DatagramSocket from, DatagramSocket to, boolean out) 198 | throws IOException { 199 | final byte[] data = new byte[datagramSize]; 200 | final DatagramPacket dp = new DatagramPacket(data, data.length); 201 | 202 | while (true) { 203 | try { 204 | from.receive(dp); 205 | lastReadTime = System.currentTimeMillis(); 206 | 207 | if (auth.checkRequest(dp, out)) { 208 | to.send(dp); 209 | } 210 | 211 | } catch (final UnknownHostException uhe) { 212 | log.info("Dropping datagram for unknown host"); 213 | } catch (final InterruptedIOException iioe) { 214 | // log("Interrupted: "+iioe); 215 | // If we were interrupted by other thread. 216 | if (iddleTimeout == 0) { 217 | return; 218 | } 219 | 220 | // If last datagram was received, long time ago, return. 221 | final long timeSinceRead = System.currentTimeMillis() 222 | - lastReadTime; 223 | if (timeSinceRead >= iddleTimeout - 100) { 224 | return; 225 | } 226 | } 227 | dp.setLength(data.length); 228 | } 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/SocksServerSocket.java: -------------------------------------------------------------------------------- 1 | package socks; 2 | 3 | import java.net.*; 4 | import java.io.*; 5 | 6 | /** 7 | SocksServerSocket allows to accept connections from one particular 8 | host through the SOCKS4 or SOCKS5 proxy. 9 | */ 10 | public class SocksServerSocket extends ServerSocket{ 11 | //Data members 12 | protected Proxy proxy; 13 | protected String localHost; 14 | protected InetAddress localIP; 15 | protected int localPort; 16 | 17 | boolean doing_direct = false; 18 | InetAddress remoteAddr; 19 | 20 | /** 21 | * Creates ServerSocket capable of accepting one connection 22 | * through the firewall, uses default Proxy. 23 | *@param host Host from which the connection should be recieved. 24 | *@param port Port number of the primary connection. 25 | */ 26 | public SocksServerSocket(String host,int port) 27 | throws SocksException,UnknownHostException,IOException{ 28 | this(Proxy.defaultProxy,host,port); 29 | } 30 | /** 31 | *Creates ServerSocket capable of accepting one connection 32 | *through the firewall, uses given proxy. 33 | *@param p Proxy object to use. 34 | *@param host Host from which the connection should be recieved. 35 | *@param port Port number of the primary connection. 36 | */ 37 | public SocksServerSocket(Proxy p,String host,int port) 38 | throws SocksException,UnknownHostException,IOException{ 39 | 40 | 41 | super(0); 42 | if(p == null) throw new SocksException(Proxy.SOCKS_NO_PROXY); 43 | //proxy=p; 44 | proxy = p.copy(); 45 | if(proxy.isDirect(host)){ 46 | remoteAddr = InetAddress.getByName(host); 47 | proxy = null; 48 | doDirect(); 49 | }else{ 50 | processReply(proxy.bind(host,port)); 51 | } 52 | } 53 | 54 | /** 55 | * Creates ServerSocket capable of accepting one connection 56 | * through the firewall, uses default Proxy. 57 | *@param ip Host from which the connection should be recieved. 58 | *@param port Port number of the primary connection. 59 | */ 60 | public SocksServerSocket(InetAddress ip, int port) throws SocksException, 61 | IOException{ 62 | this(Proxy.defaultProxy,ip,port); 63 | } 64 | 65 | /** 66 | *Creates ServerSocket capable of accepting one connection 67 | *through the firewall, uses given proxy. 68 | *@param p Proxy object to use. 69 | *@param ip Host from which the connection should be recieved. 70 | *@param port Port number of the primary connection. 71 | */ 72 | public SocksServerSocket(Proxy p,InetAddress ip, int port) 73 | throws SocksException,IOException{ 74 | super(0); 75 | 76 | if(p == null) throw new SocksException(Proxy.SOCKS_NO_PROXY); 77 | this.proxy = p.copy(); 78 | 79 | if(proxy.isDirect(ip)){ 80 | remoteAddr = ip; 81 | doDirect(); 82 | }else{ 83 | processReply(proxy.bind(ip,port)); 84 | } 85 | } 86 | 87 | 88 | /** 89 | * Accepts the incoming connection. 90 | */ 91 | public Socket accept() throws IOException{ 92 | Socket s; 93 | 94 | if(!doing_direct){ 95 | if(proxy == null) return null; 96 | 97 | ProxyMessage msg = proxy.accept(); 98 | s = msg.ip == null? new SocksSocket(msg.host,msg.port,proxy) 99 | : new SocksSocket(msg.ip,msg.port,proxy); 100 | //Set timeout back to 0 101 | proxy.proxySocket.setSoTimeout(0); 102 | }else{ //Direct Connection 103 | 104 | //Mimic the proxy behaviour, 105 | //only accept connections from the speciefed host. 106 | while(true){ 107 | s = super.accept(); 108 | if(s.getInetAddress().equals(remoteAddr)){ 109 | //got the connection from the right host 110 | //Close listenning socket. 111 | break; 112 | }else 113 | s.close(); //Drop all connections from other hosts 114 | } 115 | 116 | } 117 | proxy = null; 118 | //Return accepted socket 119 | return s; 120 | } 121 | 122 | /** 123 | * Closes the connection to proxy if socket have not been accepted, if 124 | * the direct connection is used, closes direct ServerSocket. If the 125 | * client socket have been allready accepted, does nothing. 126 | */ 127 | public void close() throws IOException{ 128 | super.close(); 129 | if(proxy != null) proxy.endSession(); 130 | proxy = null; 131 | } 132 | 133 | /** 134 | Get the name of the host proxy is using to listen for incoming 135 | connection. 136 |

137 | Usefull when address is returned by proxy as the hostname. 138 | @return the hostname of the address proxy is using to listen 139 | for incoming connection. 140 | */ 141 | public String getHost(){ 142 | return localHost; 143 | } 144 | 145 | /** 146 | * Get address assigned by proxy to listen for incomming 147 | * connections, or the local machine address if doing direct 148 | * connection. 149 | */ 150 | public InetAddress getInetAddress(){ 151 | if(localIP == null){ 152 | try{ 153 | localIP = InetAddress.getByName(localHost); 154 | }catch(UnknownHostException e){ 155 | return null; 156 | } 157 | } 158 | return localIP; 159 | } 160 | 161 | /** 162 | * Get port assigned by proxy to listen for incoming connections, or 163 | the port chosen by local system, if accepting directly. 164 | */ 165 | public int getLocalPort(){ 166 | return localPort; 167 | } 168 | 169 | /** 170 | Set Timeout. 171 | 172 | @param timeout Amount of time in milliseconds, accept should wait for 173 | incoming connection before failing with exception. 174 | Zero timeout implies infinity. 175 | */ 176 | public void setSoTimeout(int timeout) throws SocketException{ 177 | super.setSoTimeout(timeout); 178 | if(!doing_direct) proxy.proxySocket.setSoTimeout(timeout); 179 | } 180 | 181 | 182 | //Private Methods 183 | ////////////////// 184 | 185 | private void processReply(ProxyMessage reply)throws SocksException{ 186 | localPort = reply.port; 187 | /* 188 | * If the server have assigned same host as it was contacted on 189 | * it might return an address of all zeros 190 | */ 191 | if(reply.host.equals("0.0.0.0")){ 192 | localIP = proxy.proxyIP; 193 | localHost = localIP.getHostName(); 194 | }else{ 195 | localHost = reply.host; 196 | localIP = reply.ip; 197 | } 198 | } 199 | 200 | private void doDirect(){ 201 | doing_direct = true; 202 | localPort = super.getLocalPort(); 203 | localIP = super.getInetAddress(); 204 | localHost = localIP.getHostName(); 205 | } 206 | 207 | } 208 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/protocol/SocksServerSocket.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.protocol; 2 | 3 | import java.io.IOException; 4 | import java.net.InetAddress; 5 | import java.net.ServerSocket; 6 | import java.net.Socket; 7 | import java.net.SocketException; 8 | import java.net.UnknownHostException; 9 | 10 | /** 11 | * SocksServerSocket allows to accept connections from one particular host 12 | * through the SOCKS4 or SOCKS5 proxy. 13 | */ 14 | public class SocksServerSocket extends ServerSocket { 15 | // Data members 16 | protected SocksProxyBase proxy; 17 | protected String localHost; 18 | protected InetAddress localIP; 19 | protected int localPort; 20 | 21 | boolean doing_direct = false; 22 | InetAddress remoteAddr; 23 | 24 | /** 25 | * Creates ServerSocket capable of accepting one connection through the 26 | * firewall, uses default Proxy. 27 | * 28 | * @param host 29 | * Host from which the connection should be recieved. 30 | *@param port 31 | * Port number of the primary connection. 32 | */ 33 | public SocksServerSocket(String host, int port) throws 34 | IOException { 35 | this(SocksProxyBase.defaultProxy, host, port); 36 | } 37 | 38 | /** 39 | *Creates ServerSocket capable of accepting one connection through the 40 | * firewall, uses given proxy. 41 | * 42 | * @param p 43 | * Proxy object to use. 44 | *@param host 45 | * Host from which the connection should be recieved. 46 | *@param port 47 | * Port number of the primary connection. 48 | */ 49 | public SocksServerSocket(SocksProxyBase p, String host, int port) 50 | throws IOException { 51 | 52 | super(0); 53 | if (p == null) { 54 | throw new SocksException(SocksProxyBase.SOCKS_NO_PROXY); 55 | } 56 | // proxy=p; 57 | proxy = p.copy(); 58 | if (proxy.isDirect(host)) { 59 | remoteAddr = InetAddress.getByName(host); 60 | proxy = null; 61 | doDirect(); 62 | } else { 63 | processReply(proxy.bind(host, port)); 64 | } 65 | } 66 | 67 | /** 68 | * Creates ServerSocket capable of accepting one connection through the 69 | * firewall, uses default Proxy. 70 | * 71 | * @param ip 72 | * Host from which the connection should be recieved. 73 | *@param port 74 | * Port number of the primary connection. 75 | */ 76 | public SocksServerSocket(InetAddress ip, int port) throws 77 | IOException { 78 | this(SocksProxyBase.defaultProxy, ip, port); 79 | } 80 | 81 | /** 82 | *Creates ServerSocket capable of accepting one connection through the 83 | * firewall, uses given proxy. 84 | * 85 | * @param p 86 | * Proxy object to use. 87 | *@param ip 88 | * Host from which the connection should be recieved. 89 | *@param port 90 | * Port number of the primary connection. 91 | */ 92 | public SocksServerSocket(SocksProxyBase p, InetAddress ip, int port) 93 | throws IOException { 94 | super(0); 95 | 96 | if (p == null) { 97 | throw new SocksException(SocksProxyBase.SOCKS_NO_PROXY); 98 | } 99 | this.proxy = p.copy(); 100 | 101 | if (proxy.isDirect(ip)) { 102 | remoteAddr = ip; 103 | doDirect(); 104 | } else { 105 | processReply(proxy.bind(ip, port)); 106 | } 107 | } 108 | 109 | /** 110 | * Accepts the incoming connection. 111 | */ 112 | public Socket accept() throws IOException { 113 | Socket s; 114 | 115 | if (!doing_direct) { 116 | if (proxy == null) { 117 | return null; 118 | } 119 | 120 | final ProxyMessage msg = proxy.accept(); 121 | s = msg.ip == null ? new SocksSocket(msg.host, msg.port, proxy) 122 | : new SocksSocket(msg.ip, msg.port, proxy); 123 | // Set timeout back to 0 124 | proxy.proxySocket.setSoTimeout(0); 125 | } else { // Direct Connection 126 | 127 | // Mimic the proxy behaviour, 128 | // only accept connections from the speciefed host. 129 | while (true) { 130 | s = super.accept(); 131 | if (s.getInetAddress().equals(remoteAddr)) { 132 | // got the connection from the right host 133 | // Close listenning socket. 134 | break; 135 | } else { 136 | s.close(); // Drop all connections from other hosts 137 | } 138 | } 139 | 140 | } 141 | proxy = null; 142 | // Return accepted socket 143 | return s; 144 | } 145 | 146 | /** 147 | * Closes the connection to proxy if socket have not been accepted, if the 148 | * direct connection is used, closes direct ServerSocket. If the client 149 | * socket have been allready accepted, does nothing. 150 | */ 151 | public void close() throws IOException { 152 | super.close(); 153 | if (proxy != null) { 154 | proxy.endSession(); 155 | } 156 | proxy = null; 157 | } 158 | 159 | /** 160 | * Get the name of the host proxy is using to listen for incoming 161 | * connection. 162 | *

163 | * Usefull when address is returned by proxy as the hostname. 164 | * 165 | * @return the hostname of the address proxy is using to listen for incoming 166 | * connection. 167 | */ 168 | public String getHost() { 169 | return localHost; 170 | } 171 | 172 | /** 173 | * Get address assigned by proxy to listen for incomming connections, or the 174 | * local machine address if doing direct connection. 175 | */ 176 | public InetAddress getInetAddress() { 177 | if (localIP == null) { 178 | try { 179 | localIP = InetAddress.getByName(localHost); 180 | } catch (final UnknownHostException e) { 181 | return null; 182 | } 183 | } 184 | return localIP; 185 | } 186 | 187 | /** 188 | * Get port assigned by proxy to listen for incoming connections, or the 189 | * port chosen by local system, if accepting directly. 190 | */ 191 | public int getLocalPort() { 192 | return localPort; 193 | } 194 | 195 | /** 196 | * Set Timeout. 197 | * 198 | * @param timeout 199 | * Amount of time in milliseconds, accept should wait for 200 | * incoming connection before failing with exception. Zero 201 | * timeout implies infinity. 202 | */ 203 | public void setSoTimeout(int timeout) throws SocketException { 204 | super.setSoTimeout(timeout); 205 | if (!doing_direct) { 206 | proxy.proxySocket.setSoTimeout(timeout); 207 | } 208 | } 209 | 210 | // Private Methods 211 | // //////////////// 212 | 213 | private void processReply(ProxyMessage reply) { 214 | localPort = reply.port; 215 | /* 216 | * If the server have assigned same host as it was contacted on it might 217 | * return an address of all zeros 218 | */ 219 | if (reply.host.equals("0.0.0.0")) { 220 | localIP = proxy.proxyIP; 221 | localHost = localIP.getHostName(); 222 | } else { 223 | localHost = reply.host; 224 | localIP = reply.ip; 225 | } 226 | } 227 | 228 | private void doDirect() { 229 | doing_direct = true; 230 | localPort = super.getLocalPort(); 231 | localIP = super.getInetAddress(); 232 | localHost = localIP.getHostName(); 233 | } 234 | 235 | } 236 | -------------------------------------------------------------------------------- /jsocks_code1.01/test/TestClient.java: -------------------------------------------------------------------------------- 1 | package test; 2 | import java.io.*; 3 | import java.net.*; 4 | import socks.*; 5 | 6 | public class TestClient extends TestService{ 7 | /** Proxy which should be used*/ 8 | Proxy proxy; 9 | /** Host on which TestServer is running*/ 10 | String testHost; 11 | 12 | int timeout = 15000; 13 | int acceptTimeout = 0; 14 | 15 | BufferedReader in; 16 | Writer out; 17 | 18 | public TestClient(Proxy p,String testHost){ 19 | this.proxy = p; 20 | this.testHost = testHost; 21 | if(log == null) log = System.out; 22 | } 23 | 24 | public void start(){ 25 | connectTests(true); 26 | acceptTests(true); 27 | udpTests(true); 28 | 29 | connectTests(false); 30 | acceptTests(false); 31 | udpTests(false); 32 | } 33 | 34 | void connectTests(boolean useString){ 35 | try{ 36 | open(ECHO, useString); 37 | testEcho(); 38 | s.close(); 39 | 40 | open(DISCARD, useString); 41 | testDiscard(); 42 | s.close(); 43 | 44 | open(CHARGEN, useString); 45 | 46 | for(int i = 0; i< 3;){ 47 | try{ 48 | testChargen(); 49 | break; 50 | }catch(InterruptedIOException ioe){ 51 | log("IO interrupted:"+i); 52 | i++; 53 | } 54 | } 55 | 56 | s.close(); 57 | 58 | }catch(IOException ioe){ 59 | ioe.printStackTrace(); 60 | } 61 | 62 | } 63 | 64 | void acceptTests(boolean useString){ 65 | try{ 66 | testAccept(ECHO, useString); 67 | testEcho(); 68 | s.close(); 69 | 70 | testAccept(DISCARD, useString); 71 | testDiscard(); 72 | s.close(); 73 | 74 | testAccept(CHARGEN, useString); 75 | 76 | for(int i = 0; i< 3;){ 77 | try{ 78 | testChargen(); 79 | break; 80 | }catch(InterruptedIOException ioe){ 81 | log("IO interrupted:"+i); 82 | i++; 83 | } 84 | } 85 | s.close(); 86 | 87 | }catch(IOException ioe){ 88 | ioe.printStackTrace(); 89 | } 90 | } 91 | 92 | void udpTests(boolean useString){ 93 | log("Udp tests are not yet implemented"); 94 | } 95 | 96 | void testEcho() throws IOException{ 97 | log("Testing echo."); 98 | for(int i=0;i<5;++i){ 99 | out.write("String number "+i+"\r\n"); 100 | out.flush(); 101 | log("Echo:"+in.readLine());; 102 | } 103 | log("Echo finished"); 104 | } 105 | 106 | void testDiscard() throws IOException{ 107 | log("Testing discard"); 108 | for(int i =0; i < 5;++i){ 109 | log("Sending discard message:"+i); 110 | out.write("Discard message:"+i+"\r\n"); 111 | out.flush(); 112 | } 113 | log("Discard finished"); 114 | } 115 | 116 | void testChargen() throws IOException{ 117 | log("Testing chargen"); 118 | String s; 119 | s = in.readLine(); 120 | while(s!=null){ 121 | log("ChGen:"+s); 122 | s = in.readLine(); 123 | } 124 | log("Chargen finished."); 125 | } 126 | 127 | void testAccept(int service,boolean useString)throws IOException{ 128 | open(CONNECT,useString); 129 | 130 | log("Testing accept"); 131 | ServerSocket ss; 132 | 133 | if(useString) 134 | ss = new SocksServerSocket(proxy,testHost,servicePorts[service]); 135 | else 136 | ss = new SocksServerSocket(proxy,InetAddress.getByName(testHost), 137 | servicePorts[service]); 138 | log("Listenning on "+ss.getInetAddress()+":"+ss.getLocalPort()); 139 | ss.setSoTimeout(acceptTimeout); 140 | 141 | out.write(""+ss.getLocalPort()+" "+service+"\r\n"); 142 | out.flush(); 143 | 144 | String line = in.readLine(); 145 | if(line != null){ 146 | log("Accept failed:"+line); 147 | } 148 | 149 | s.close(); 150 | 151 | s = ss.accept(); 152 | log("Accepted:"+s); 153 | 154 | s.setSoTimeout(timeout); 155 | 156 | out = new OutputStreamWriter(s.getOutputStream()); 157 | in = new BufferedReader(new InputStreamReader(s.getInputStream())); 158 | 159 | ss.close(); 160 | } 161 | 162 | void open(int service,boolean useString) throws IOException{ 163 | 164 | if(!useString){ 165 | s = new SocksSocket(proxy,InetAddress.getByName(testHost), 166 | servicePorts[service]); 167 | }else{ 168 | s = new SocksSocket(proxy,testHost,servicePorts[service]); 169 | } 170 | 171 | s.setSoTimeout(timeout); 172 | 173 | out = new OutputStreamWriter(s.getOutputStream()); 174 | in = new BufferedReader(new InputStreamReader(s.getInputStream())); 175 | } 176 | 177 | //Main function 178 | /////////////// 179 | 180 | static void usage(){ 181 | System.err.println( 182 | "Usage: java Testclient testhost proxy [directhosts]"); 183 | } 184 | 185 | static Proxy initProxy(String ps){ 186 | java.util.StringTokenizer st = new java.util.StringTokenizer(ps,",;"); 187 | Proxy proxy = null; 188 | while(st.hasMoreElements()){ 189 | String entry = st.nextToken(); 190 | Proxy p = Proxy.parseProxy(entry); 191 | if( p == null){ 192 | log("Proxy "+entry+" invalid."); 193 | return null; 194 | } 195 | p.setChainProxy(proxy); 196 | proxy = p; 197 | } 198 | return proxy; 199 | } 200 | static void addDirectHosts(Proxy p, String directHosts){ 201 | java.util.StringTokenizer st = new java.util.StringTokenizer( 202 | directHosts,",;"); 203 | 204 | while(st.hasMoreElements()){ 205 | String entry = st.nextToken(); 206 | log("Adding direct host:"+entry); 207 | p.addDirect(entry); 208 | } 209 | } 210 | 211 | public static void main(String[] argv){ 212 | if(argv.length < 2){ 213 | usage(); 214 | return; 215 | } 216 | 217 | log = System.out; 218 | 219 | String testHost = argv[0]; 220 | String proxyHost = argv[1]; 221 | String directHosts = argv.length >2 ? argv[2] : null; 222 | 223 | Proxy p = initProxy(proxyHost); 224 | if(p == null){ 225 | log("Can't init proxy."); 226 | return; 227 | } 228 | if(directHosts!=null) addDirectHosts(p,directHosts); 229 | 230 | if(p instanceof Socks5Proxy) 231 | ((Socks5Proxy) p).resolveAddrLocally(false); 232 | 233 | TestClient tc = new TestClient(p,testHost); 234 | tc.start(); 235 | 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /jsocks_code1.01/socks/UDPRelayServer.java: -------------------------------------------------------------------------------- 1 | package socks; 2 | import socks.server.*; 3 | import java.net.*; 4 | import java.io.*; 5 | 6 | /** 7 | UDP Relay server, used by ProxyServer to perform udp forwarding. 8 | */ 9 | class UDPRelayServer implements Runnable{ 10 | 11 | 12 | DatagramSocket client_sock; 13 | DatagramSocket remote_sock; 14 | 15 | Socket controlConnection; 16 | 17 | int relayPort; 18 | InetAddress relayIP; 19 | 20 | Thread pipe_thread1,pipe_thread2; 21 | Thread master_thread; 22 | 23 | ServerAuthenticator auth; 24 | 25 | long lastReadTime; 26 | 27 | static PrintStream log = null; 28 | static Proxy proxy = null; 29 | static int datagramSize = 0xFFFF;//64K, a bit more than max udp size 30 | static int iddleTimeout = 180000;//3 minutes 31 | 32 | 33 | /** 34 | Constructs UDP relay server to communicate with client 35 | on given ip and port. 36 | @param clientIP Address of the client from whom datagrams 37 | will be recieved and to whom they will be forwarded. 38 | @param clientPort Clients port. 39 | @param master_thread Thread which will be interrupted, when 40 | UDP relay server stoppes for some reason. 41 | @param controlConnection Socket which will be closed, before 42 | interrupting the master thread, it is introduced due to a bug 43 | in windows JVM which does not throw InterruptedIOException in 44 | threads which block in I/O operation. 45 | */ 46 | public UDPRelayServer(InetAddress clientIP,int clientPort, 47 | Thread master_thread, 48 | Socket controlConnection, 49 | ServerAuthenticator auth) 50 | throws IOException{ 51 | this.master_thread = master_thread; 52 | this.controlConnection = controlConnection; 53 | this.auth = auth; 54 | 55 | client_sock = new Socks5DatagramSocket(true,auth.getUdpEncapsulation(), 56 | clientIP,clientPort); 57 | relayPort = client_sock.getLocalPort(); 58 | relayIP = client_sock.getLocalAddress(); 59 | 60 | if(relayIP.getHostAddress().equals("0.0.0.0")) 61 | relayIP = InetAddress.getLocalHost(); 62 | 63 | if(proxy == null) 64 | remote_sock = new DatagramSocket(); 65 | else 66 | remote_sock = new Socks5DatagramSocket(proxy,0,null); 67 | } 68 | 69 | 70 | //Public methods 71 | ///////////////// 72 | 73 | 74 | /** 75 | Sets the timeout for UDPRelay server.
76 | Zero timeout implies infinity.
77 | Default timeout is 3 minutes. 78 | */ 79 | 80 | static public void setTimeout(int timeout){ 81 | iddleTimeout = timeout; 82 | } 83 | 84 | 85 | /** 86 | Sets the size of the datagrams used in the UDPRelayServer.
87 | Default size is 64K, a bit more than maximum possible size of the 88 | datagram. 89 | */ 90 | static public void setDatagramSize(int size){ 91 | datagramSize = size; 92 | } 93 | 94 | /** 95 | Port to which client should send datagram for association. 96 | */ 97 | public int getRelayPort(){ 98 | return relayPort; 99 | } 100 | /** 101 | IP address to which client should send datagrams for association. 102 | */ 103 | public InetAddress getRelayIP(){ 104 | return relayIP; 105 | } 106 | 107 | /** 108 | Starts udp relay server. 109 | Spawns two threads of execution and returns. 110 | */ 111 | public void start() throws IOException{ 112 | remote_sock.setSoTimeout(iddleTimeout); 113 | client_sock.setSoTimeout(iddleTimeout); 114 | 115 | log("Starting UDP relay server on "+relayIP+":"+relayPort); 116 | log("Remote socket "+remote_sock.getLocalAddress()+":"+ 117 | remote_sock.getLocalPort()); 118 | 119 | pipe_thread1 = new Thread(this,"pipe1"); 120 | pipe_thread2 = new Thread(this,"pipe2"); 121 | 122 | lastReadTime = System.currentTimeMillis(); 123 | 124 | pipe_thread1.start(); 125 | pipe_thread2.start(); 126 | } 127 | 128 | /** 129 | Stops Relay server. 130 |

131 | Does not close control connection, does not interrupt master_thread. 132 | */ 133 | public synchronized void stop(){ 134 | master_thread = null; 135 | controlConnection = null; 136 | abort(); 137 | } 138 | 139 | //Runnable interface 140 | //////////////////// 141 | public void run(){ 142 | try{ 143 | if(Thread.currentThread().getName().equals("pipe1")) 144 | pipe(remote_sock,client_sock,false); 145 | else 146 | pipe(client_sock,remote_sock,true); 147 | }catch(IOException ioe){ 148 | }finally{ 149 | abort(); 150 | log("UDP Pipe thread "+Thread.currentThread().getName()+" stopped."); 151 | } 152 | 153 | } 154 | 155 | //Private methods 156 | ///////////////// 157 | private synchronized void abort(){ 158 | if(pipe_thread1 == null) return; 159 | 160 | log("Aborting UDP Relay Server"); 161 | 162 | remote_sock.close(); 163 | client_sock.close(); 164 | 165 | if(controlConnection != null) 166 | try{ controlConnection.close();} catch(IOException ioe){} 167 | 168 | if(master_thread!=null) master_thread.interrupt(); 169 | 170 | pipe_thread1.interrupt(); 171 | pipe_thread2.interrupt(); 172 | 173 | pipe_thread1 = null; 174 | } 175 | 176 | 177 | static private void log(String s){ 178 | if(log != null){ 179 | log.println(s); 180 | log.flush(); 181 | } 182 | } 183 | 184 | private void pipe(DatagramSocket from,DatagramSocket to,boolean out) 185 | throws IOException{ 186 | byte[] data = new byte[datagramSize]; 187 | DatagramPacket dp = new DatagramPacket(data,data.length); 188 | 189 | while(true){ 190 | try{ 191 | from.receive(dp); 192 | lastReadTime = System.currentTimeMillis(); 193 | 194 | if(auth.checkRequest(dp,out)) 195 | to.send(dp); 196 | 197 | }catch(UnknownHostException uhe){ 198 | log("Dropping datagram for unknown host"); 199 | }catch(InterruptedIOException iioe){ 200 | //log("Interrupted: "+iioe); 201 | //If we were interrupted by other thread. 202 | if(iddleTimeout == 0) return; 203 | 204 | //If last datagram was received, long time ago, return. 205 | long timeSinceRead = System.currentTimeMillis() - lastReadTime; 206 | if(timeSinceRead >= iddleTimeout -100) //-100 for adjustment 207 | return; 208 | } 209 | dp.setLength(data.length); 210 | } 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /helpers/com/runjva/sourceforge/jsocks/helpers/TestClient.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.helpers; 2 | import java.io.BufferedReader; 3 | import java.io.IOException; 4 | import java.io.InputStreamReader; 5 | import java.io.InterruptedIOException; 6 | import java.io.OutputStreamWriter; 7 | import java.io.Writer; 8 | import java.net.InetAddress; 9 | import java.net.Proxy; 10 | import java.net.ServerSocket; 11 | 12 | import com.runjva.sourceforge.jsocks.Socks5Proxy; 13 | import com.runjva.sourceforge.jsocks.SocksServerSocket; 14 | import com.runjva.sourceforge.jsocks.SocksSocket; 15 | 16 | public class TestClient extends TestService{ 17 | /** Proxy which should be used*/ 18 | Proxy proxy; 19 | /** Host on which TestServer is running*/ 20 | String testHost; 21 | 22 | int timeout = 15000; 23 | int acceptTimeout = 0; 24 | 25 | BufferedReader in; 26 | Writer out; 27 | 28 | public TestClient(Proxy p,String testHost){ 29 | this.proxy = p; 30 | this.testHost = testHost; 31 | if(log == null) log = System.out; 32 | } 33 | 34 | public void start(){ 35 | connectTests(true); 36 | acceptTests(true); 37 | udpTests(true); 38 | 39 | connectTests(false); 40 | acceptTests(false); 41 | udpTests(false); 42 | } 43 | 44 | void connectTests(boolean useString){ 45 | try{ 46 | open(ECHO, useString); 47 | testEcho(); 48 | s.close(); 49 | 50 | open(DISCARD, useString); 51 | testDiscard(); 52 | s.close(); 53 | 54 | open(CHARGEN, useString); 55 | 56 | for(int i = 0; i< 3;){ 57 | try{ 58 | testChargen(); 59 | break; 60 | }catch(InterruptedIOException ioe){ 61 | log("IO interrupted:"+i); 62 | i++; 63 | } 64 | } 65 | 66 | s.close(); 67 | 68 | }catch(IOException ioe){ 69 | ioe.printStackTrace(); 70 | } 71 | 72 | } 73 | 74 | void acceptTests(boolean useString){ 75 | try{ 76 | testAccept(ECHO, useString); 77 | testEcho(); 78 | s.close(); 79 | 80 | testAccept(DISCARD, useString); 81 | testDiscard(); 82 | s.close(); 83 | 84 | testAccept(CHARGEN, useString); 85 | 86 | for(int i = 0; i< 3;){ 87 | try{ 88 | testChargen(); 89 | break; 90 | }catch(InterruptedIOException ioe){ 91 | log("IO interrupted:"+i); 92 | i++; 93 | } 94 | } 95 | s.close(); 96 | 97 | }catch(IOException ioe){ 98 | ioe.printStackTrace(); 99 | } 100 | } 101 | 102 | void udpTests(boolean useString){ 103 | log("Udp tests are not yet implemented"); 104 | } 105 | 106 | void testEcho() throws IOException{ 107 | log("Testing echo."); 108 | for(int i=0;i<5;++i){ 109 | out.write("String number "+i+"\r\n"); 110 | out.flush(); 111 | log("Echo:"+in.readLine());; 112 | } 113 | log("Echo finished"); 114 | } 115 | 116 | void testDiscard() throws IOException{ 117 | log("Testing discard"); 118 | for(int i =0; i < 5;++i){ 119 | log("Sending discard message:"+i); 120 | out.write("Discard message:"+i+"\r\n"); 121 | out.flush(); 122 | } 123 | log("Discard finished"); 124 | } 125 | 126 | void testChargen() throws IOException{ 127 | log("Testing chargen"); 128 | String s; 129 | s = in.readLine(); 130 | while(s!=null){ 131 | log("ChGen:"+s); 132 | s = in.readLine(); 133 | } 134 | log("Chargen finished."); 135 | } 136 | 137 | void testAccept(int service,boolean useString)throws IOException{ 138 | open(CONNECT,useString); 139 | 140 | log("Testing accept"); 141 | ServerSocket ss; 142 | 143 | if(useString) 144 | ss = new SocksServerSocket(proxy,testHost,servicePorts[service]); 145 | else 146 | ss = new SocksServerSocket(proxy,InetAddress.getByName(testHost), 147 | servicePorts[service]); 148 | log("Listenning on "+ss.getInetAddress()+":"+ss.getLocalPort()); 149 | ss.setSoTimeout(acceptTimeout); 150 | 151 | out.write(""+ss.getLocalPort()+" "+service+"\r\n"); 152 | out.flush(); 153 | 154 | String line = in.readLine(); 155 | if(line != null){ 156 | log("Accept failed:"+line); 157 | } 158 | 159 | s.close(); 160 | 161 | s = ss.accept(); 162 | log("Accepted:"+s); 163 | 164 | s.setSoTimeout(timeout); 165 | 166 | out = new OutputStreamWriter(s.getOutputStream()); 167 | in = new BufferedReader(new InputStreamReader(s.getInputStream())); 168 | 169 | ss.close(); 170 | } 171 | 172 | void open(int service,boolean useString) throws IOException{ 173 | 174 | if(!useString){ 175 | s = new SocksSocket(proxy,InetAddress.getByName(testHost), 176 | servicePorts[service]); 177 | }else{ 178 | s = new SocksSocket(proxy,testHost,servicePorts[service]); 179 | } 180 | 181 | s.setSoTimeout(timeout); 182 | 183 | out = new OutputStreamWriter(s.getOutputStream()); 184 | in = new BufferedReader(new InputStreamReader(s.getInputStream())); 185 | } 186 | 187 | //Main function 188 | /////////////// 189 | 190 | static void usage(){ 191 | System.err.println( 192 | "Usage: java Testclient testhost proxy [directhosts]"); 193 | } 194 | 195 | static Proxy initProxy(String ps){ 196 | java.util.StringTokenizer st = new java.util.StringTokenizer(ps,",;"); 197 | Proxy proxy = null; 198 | while(st.hasMoreElements()){ 199 | String entry = st.nextToken(); 200 | Proxy p = Proxy.parseProxy(entry); 201 | if( p == null){ 202 | log("Proxy "+entry+" invalid."); 203 | return null; 204 | } 205 | p.setChainProxy(proxy); 206 | proxy = p; 207 | } 208 | return proxy; 209 | } 210 | static void addDirectHosts(Proxy p, String directHosts){ 211 | java.util.StringTokenizer st = new java.util.StringTokenizer( 212 | directHosts,",;"); 213 | 214 | while(st.hasMoreElements()){ 215 | String entry = st.nextToken(); 216 | log("Adding direct host:"+entry); 217 | p.addDirect(entry); 218 | } 219 | } 220 | 221 | public static void main(String[] argv){ 222 | if(argv.length < 2){ 223 | usage(); 224 | return; 225 | } 226 | 227 | log = System.out; 228 | 229 | String testHost = argv[0]; 230 | String proxyHost = argv[1]; 231 | String directHosts = argv.length >2 ? argv[2] : null; 232 | 233 | Proxy p = initProxy(proxyHost); 234 | if(p == null){ 235 | log("Can't init proxy."); 236 | return; 237 | } 238 | if(directHosts!=null) addDirectHosts(p,directHosts); 239 | 240 | if(p instanceof Socks5Proxy) 241 | ((Socks5Proxy) p).resolveAddrLocally(false); 242 | 243 | TestClient tc = new TestClient(p,testHost); 244 | tc.start(); 245 | 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /src/main/java/com/runjva/sourceforge/jsocks/main/SOCKS.java: -------------------------------------------------------------------------------- 1 | package com.runjva.sourceforge.jsocks.main; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.net.InetAddress; 7 | import java.net.UnknownHostException; 8 | import java.util.Hashtable; 9 | import java.util.Properties; 10 | import java.util.StringTokenizer; 11 | import java.util.logging.Logger; 12 | 13 | import com.runjva.sourceforge.jsocks.protocol.InetRange; 14 | import com.runjva.sourceforge.jsocks.protocol.ProxyServer; 15 | import com.runjva.sourceforge.jsocks.protocol.SocksProxyBase; 16 | import com.runjva.sourceforge.jsocks.server.IdentAuthenticator; 17 | 18 | public class SOCKS { 19 | 20 | private static final int DEFAULT_LISTENING_PORT = 1080; 21 | private static final Logger log = Logger.getLogger(SOCKS.class.getName()); 22 | 23 | static public void usage() { 24 | System.out.println("Usage: java SOCKS [inifile1 inifile2 ...]\n" 25 | + "If none inifile is given, uses socks.properties.\n"); 26 | } 27 | 28 | static public void main(String[] args) { 29 | 30 | String[] file_names; 31 | int port = DEFAULT_LISTENING_PORT; 32 | String logFile = null; 33 | String host = null; 34 | 35 | final IdentAuthenticator auth = new IdentAuthenticator(); 36 | 37 | InetAddress localIP = null; 38 | 39 | if (args.length == 0) { 40 | file_names = new String[] { "socks.properties" }; 41 | } else { 42 | file_names = args; 43 | } 44 | 45 | inform("Loading properties"); 46 | for (int i = 0; i < file_names.length; ++i) { 47 | 48 | inform("Reading file " + file_names[i]); 49 | 50 | final Properties pr = loadProperties(file_names[i]); 51 | if (pr == null) { 52 | System.err.println("Loading of properties from " 53 | + file_names[i] + " failed."); 54 | usage(); 55 | return; 56 | } 57 | if (!addAuth(auth, pr)) { 58 | System.err.println("Error in file " + file_names[i] + "."); 59 | usage(); 60 | return; 61 | } 62 | // First file should contain all global settings, 63 | // like port and host and log. 64 | if (i == 0) { 65 | final String port_s = (String) pr.get("port"); 66 | if (port_s != null) { 67 | try { 68 | port = Integer.parseInt(port_s); 69 | } catch (final NumberFormatException nfe) { 70 | System.err.println("Can't parse port: " + port_s); 71 | return; 72 | } 73 | } 74 | 75 | serverInit(pr); 76 | logFile = (String) pr.get("log"); 77 | host = (String) pr.get("host"); 78 | } 79 | 80 | // inform("Props:"+pr); 81 | } 82 | 83 | if (logFile != null) { 84 | System.err.println("log property not supported anymore."); 85 | } 86 | if (host != null) { 87 | try { 88 | localIP = InetAddress.getByName(host); 89 | } catch (final UnknownHostException uhe) { 90 | System.err.println("Can't resolve local ip: " + host); 91 | return; 92 | } 93 | } 94 | 95 | inform("Using Ident Authentication scheme: " + auth); 96 | final ProxyServer server = new ProxyServer(auth); 97 | server.start(port, 5, localIP); 98 | } 99 | 100 | static Properties loadProperties(String file_name) { 101 | 102 | final Properties pr = new Properties(); 103 | 104 | try { 105 | final InputStream fin = new FileInputStream(file_name); 106 | pr.load(fin); 107 | fin.close(); 108 | } catch (final IOException ioe) { 109 | return null; 110 | } 111 | return pr; 112 | } 113 | 114 | static boolean addAuth(IdentAuthenticator ident, Properties pr) { 115 | 116 | InetRange irange; 117 | 118 | final String range = (String) pr.get("range"); 119 | if (range == null) { 120 | return false; 121 | } 122 | irange = parseInetRange(range); 123 | 124 | final String users = (String) pr.get("users"); 125 | 126 | if (users == null) { 127 | ident.add(irange, null); 128 | return true; 129 | } 130 | 131 | final Hashtable uhash = new Hashtable(); 132 | 133 | final StringTokenizer st = new StringTokenizer(users, ";"); 134 | while (st.hasMoreTokens()) { 135 | uhash.put(st.nextToken(), ""); 136 | } 137 | 138 | ident.add(irange, uhash); 139 | return true; 140 | } 141 | 142 | /** 143 | * Does server initialisation. 144 | */ 145 | static void serverInit(Properties props) { 146 | int val; 147 | val = readInt(props, "iddleTimeout"); 148 | if (val >= 0) { 149 | ProxyServer.setIddleTimeout(val); 150 | inform("Setting iddle timeout to " + val + " ms."); 151 | } 152 | val = readInt(props, "acceptTimeout"); 153 | if (val >= 0) { 154 | ProxyServer.setAcceptTimeout(val); 155 | inform("Setting accept timeout to " + val + " ms."); 156 | } 157 | val = readInt(props, "udpTimeout"); 158 | if (val >= 0) { 159 | ProxyServer.setUDPTimeout(val); 160 | inform("Setting udp timeout to " + val + " ms."); 161 | } 162 | 163 | val = readInt(props, "datagramSize"); 164 | if (val >= 0) { 165 | ProxyServer.setDatagramSize(val); 166 | inform("Setting datagram size to " + val + " bytes."); 167 | } 168 | 169 | proxyInit(props); 170 | 171 | } 172 | 173 | /** 174 | * Initialises proxy, if any specified. 175 | */ 176 | static void proxyInit(Properties props) { 177 | String proxy_list; 178 | SocksProxyBase proxy = null; 179 | StringTokenizer st; 180 | 181 | proxy_list = (String) props.get("proxy"); 182 | if (proxy_list == null) { 183 | return; 184 | } 185 | 186 | st = new StringTokenizer(proxy_list, ";"); 187 | while (st.hasMoreTokens()) { 188 | final String proxy_entry = st.nextToken(); 189 | 190 | final SocksProxyBase p = SocksProxyBase.parseProxy(proxy_entry); 191 | 192 | if (p == null) { 193 | exit("Can't parse proxy entry:" + proxy_entry); 194 | } 195 | 196 | inform("Adding Proxy:" + p); 197 | 198 | if (proxy != null) { 199 | p.setChainProxy(proxy); 200 | } 201 | 202 | proxy = p; 203 | 204 | } 205 | if (proxy == null) { 206 | return; // Empty list 207 | } 208 | 209 | final String direct_hosts = (String) props.get("directHosts"); 210 | if (direct_hosts != null) { 211 | final InetRange ir = parseInetRange(direct_hosts); 212 | inform("Setting direct hosts:" + ir); 213 | proxy.setDirect(ir); 214 | } 215 | 216 | ProxyServer.setProxy(proxy); 217 | } 218 | 219 | /** 220 | * Inits range from the string of semicolon separated ranges. 221 | */ 222 | static InetRange parseInetRange(String source) { 223 | final InetRange irange = new InetRange(); 224 | 225 | final StringTokenizer st = new StringTokenizer(source, ";"); 226 | while (st.hasMoreTokens()) { 227 | irange.add(st.nextToken()); 228 | } 229 | 230 | return irange; 231 | } 232 | 233 | /** 234 | * Integer representaion of the property named name, or -1 if one is not 235 | * found. 236 | */ 237 | static int readInt(Properties props, String name) { 238 | int result = -1; 239 | final String val = (String) props.get(name); 240 | if (val == null) { 241 | return -1; 242 | } 243 | final StringTokenizer st = new StringTokenizer(val); 244 | if (!st.hasMoreElements()) { 245 | return -1; 246 | } 247 | try { 248 | result = Integer.parseInt(st.nextToken()); 249 | } catch (final NumberFormatException nfe) { 250 | inform("Bad value for " + name + ":" + val); 251 | } 252 | return result; 253 | } 254 | 255 | // Display functions 256 | // ///////////////// 257 | 258 | static void inform(String s) { 259 | log.info(s); 260 | } 261 | 262 | static void exit(String msg) { 263 | System.err.println("Error:" + msg); 264 | System.err.println("Aborting operation"); 265 | System.exit(0); 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /jsocks_code1.01/SOCKS.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | import java.net.*; 4 | import socks.server.*; 5 | import socks.*; 6 | import socks.Proxy; 7 | 8 | public class SOCKS{ 9 | 10 | static public void usage(){ 11 | System.out.println( 12 | "Usage: java SOCKS [inifile1 inifile2 ...]\n"+ 13 | "If none inifile is given, uses socks.properties.\n" 14 | ); 15 | } 16 | 17 | static public void main(String[] args){ 18 | 19 | String[] file_names; 20 | int port=1080; 21 | String logFile = null; 22 | String host = null; 23 | 24 | IdentAuthenticator auth = new IdentAuthenticator(); 25 | OutputStream log = null; 26 | InetAddress localIP = null; 27 | 28 | if(args.length == 0){ 29 | file_names = new String[1]; 30 | file_names[0] = "socks.properties"; 31 | }else{ 32 | file_names = args; 33 | } 34 | 35 | 36 | inform("Loading properties"); 37 | for(int i=0;i=0){ 146 | ProxyServer.setIddleTimeout(val); 147 | inform("Setting iddle timeout to "+val+" ms."); 148 | } 149 | val = readInt(props,"acceptTimeout"); 150 | if(val>=0){ 151 | ProxyServer.setAcceptTimeout(val); 152 | inform("Setting accept timeout to "+val+" ms."); 153 | } 154 | val = readInt(props,"udpTimeout"); 155 | if(val>=0){ 156 | ProxyServer.setUDPTimeout(val); 157 | inform("Setting udp timeout to "+val+" ms."); 158 | } 159 | 160 | val = readInt(props,"datagramSize"); 161 | if(val>=0){ 162 | ProxyServer.setDatagramSize(val); 163 | inform("Setting datagram size to "+val+" bytes."); 164 | } 165 | 166 | proxyInit(props); 167 | 168 | } 169 | 170 | /** 171 | Initialises proxy, if any specified. 172 | */ 173 | static void proxyInit(Properties props){ 174 | String proxy_list; 175 | Proxy proxy = null; 176 | StringTokenizer st; 177 | 178 | proxy_list = (String) props.get("proxy"); 179 | if(proxy_list == null) return; 180 | 181 | st = new StringTokenizer(proxy_list,";"); 182 | while(st.hasMoreTokens()){ 183 | String proxy_entry = st.nextToken(); 184 | 185 | Proxy p = Proxy.parseProxy(proxy_entry); 186 | 187 | if(p == null) 188 | exit("Can't parse proxy entry:"+proxy_entry); 189 | 190 | 191 | inform("Adding Proxy:"+p); 192 | 193 | if(proxy != null) 194 | p.setChainProxy(proxy); 195 | 196 | proxy = p; 197 | 198 | } 199 | if(proxy == null) return; //Empty list 200 | 201 | String direct_hosts = (String) props.get("directHosts"); 202 | if(direct_hosts!=null){ 203 | InetRange ir = parseInetRange(direct_hosts); 204 | inform("Setting direct hosts:"+ir); 205 | proxy.setDirect(ir); 206 | } 207 | 208 | 209 | ProxyServer.setProxy(proxy); 210 | } 211 | /** 212 | Inits range from the string of semicolon separated ranges. 213 | */ 214 | static InetRange parseInetRange(String source){ 215 | InetRange irange = new InetRange(); 216 | 217 | StringTokenizer st = new StringTokenizer(source,";"); 218 | while(st.hasMoreTokens()) 219 | irange.add(st.nextToken()); 220 | 221 | return irange; 222 | } 223 | 224 | /** 225 | Integer representaion of the property named name, or -1 if one 226 | is not found. 227 | */ 228 | static int readInt(Properties props,String name){ 229 | int result = -1; 230 | String val = (String) props.get(name); 231 | if(val==null) return -1; 232 | StringTokenizer st = new StringTokenizer(val); 233 | if(!st.hasMoreElements()) return -1; 234 | try{ 235 | result = Integer.parseInt(st.nextToken()); 236 | }catch(NumberFormatException nfe){ 237 | inform("Bad value for "+name+":"+val); 238 | } 239 | return result; 240 | } 241 | 242 | //Display functions 243 | /////////////////// 244 | 245 | static void inform(String s){ 246 | System.out.println(s); 247 | } 248 | 249 | static void exit(String msg){ 250 | System.err.println("Error:"+msg); 251 | System.err.println("Aborting operation"); 252 | System.exit(0); 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /jsocks_code1.01/test/TestService.java: -------------------------------------------------------------------------------- 1 | package test; 2 | import java.io.*; 3 | import java.net.*; 4 | 5 | /** 6 | Server to used perform tests for SOCKS library. 7 | */ 8 | public class TestService implements Runnable{ 9 | static final String chargenSequence = " !\"#$%&'()*+,-./0123456789:;<=>?@"+ 10 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefg"; 11 | 12 | static final String serviceNames[] = {"echo","discard","chargen","connect"}; 13 | static final int servicePorts[] = {5678,5679,5680,5681}; 14 | 15 | static final int ECHO = 0; 16 | static final int DISCARD = 1; 17 | static final int CHARGEN = 2; 18 | static final int CONNECT = 3; 19 | 20 | static final int BUF_SIZE = 1024; 21 | 22 | static final int CHARGEN_WAIT = 1000; //1 second 23 | static final int MAX_WAIT = 60000; //1 minute 24 | 25 | static PrintStream log = null; 26 | 27 | //Class constants 28 | Socket s; 29 | int service; 30 | 31 | /** 32 | Creates new TestService object, which will perform particular 33 | service on given socket. 34 | 35 | @param s Socket on which to perform service. 36 | @param service Service which to provide. 37 | */ 38 | public TestService(Socket s, int service){ 39 | this.s = s; 40 | this.service = service; 41 | } 42 | 43 | /** 44 | Default constructor. 45 | */ 46 | public TestService(){ 47 | this.s = null; 48 | this.service = -1; 49 | } 50 | 51 | public void run(){ 52 | try{ 53 | serve(s,service); 54 | }catch(IOException ioe){ 55 | log("Exception:"+ioe); 56 | ioe.printStackTrace(); 57 | } 58 | try{ s.close();}catch(IOException ioe){} 59 | } 60 | 61 | //Static functions 62 | ///////////////// 63 | 64 | /** 65 | Maps service name to the integer id, does it in simple 66 | linear search manner. 67 | @param serviceName Name of the service whose id one needs. 68 | @return Integer identifier for this servuce, or -1, if service 69 | can't be found. 70 | */ 71 | static public int getServiceId(String serviceName){ 72 | serviceName = serviceName.toLowerCase(); 73 | for(int i = 0;i < serviceNames.length;++i) 74 | if(serviceName.equals(serviceNames[i])) 75 | return i; 76 | 77 | //Couldn't find one. 78 | return -1; 79 | } 80 | 81 | /** 82 | Performs given service on given socket. 83 |

84 | Simply looks up and calls associated method. 85 | @param s Socket on which to perform service. 86 | @param service Id of the service to perform. 87 | @return true if service have been found, false otherwise. 88 | */ 89 | static public boolean serve(Socket s, int service) throws IOException{ 90 | switch(service){ 91 | case ECHO: 92 | echo(s); 93 | break; 94 | case DISCARD: 95 | discard(s); 96 | break; 97 | case CHARGEN: 98 | chargen(s,CHARGEN_WAIT,MAX_WAIT); 99 | break; 100 | case CONNECT: 101 | connect(s); 102 | break; 103 | default: 104 | log("Unknown service:"+service); 105 | return false; 106 | } 107 | return true; 108 | } 109 | /** 110 | Echos any input on the socket to the output. 111 | Echo is being done line by line. 112 | @param s Socket on which to perform service. 113 | */ 114 | static public void echo(Socket s) throws IOException{ 115 | BufferedReader in = new BufferedReader(new InputStreamReader( 116 | s.getInputStream())); 117 | OutputStream out = s.getOutputStream(); 118 | 119 | log("Starting \"echo\" on "+s); 120 | 121 | String line = in.readLine(); 122 | while(line != null){ 123 | out.write((line+"\n").getBytes()); 124 | log(line); 125 | line = in.readLine(); 126 | } 127 | 128 | log("Echo done."); 129 | } 130 | 131 | /** 132 | Reads input from the socket, and does not write anything back. 133 | logs input in line by line fashion. 134 | @param s Socket on which to perform service. 135 | */ 136 | static public void discard(Socket s) throws IOException{ 137 | BufferedReader in = new BufferedReader(new InputStreamReader( 138 | s.getInputStream())); 139 | log("Starting discard on "+s); 140 | 141 | String line = in.readLine(); 142 | while(line != null){ 143 | log(line); 144 | line = in.readLine(); 145 | } 146 | 147 | log("Discard finished."); 148 | } 149 | 150 | /** 151 | Generates characters and sends them to the socket. 152 |

153 | Unlike usual chargen (port 19), each next line of the generated 154 | output is send after increasingly larger time intervals. It starts 155 | from wait_time (ms), and each next time wait time is doubled. 156 | Eg. 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 ... well 157 | you got the idea. 158 |

159 | It starts if either connection is clsoed or the wait time grows 160 | bigger than max_wait. 161 | 162 | @param s Socket on which to perform service. 163 | @param wait_time Time in ms, from which timing sequence should begin. 164 | @param max_wait Time in ms, after reaching timeout greater than this 165 | value, chargen will stop. 166 | */ 167 | static public void chargen(Socket s,long wait_time,long max_wait) 168 | throws IOException{ 169 | byte[] buf = chargenSequence.getBytes(); 170 | int pos = 0; 171 | OutputStream out = s.getOutputStream(); 172 | InputStream in = s.getInputStream(); 173 | s.setSoTimeout(100); //0.1 ms 174 | 175 | log("Starting \"chargen\" on "+s); 176 | while(true){ 177 | log("Sending message."); 178 | out.write(buf,pos,buf.length - pos); 179 | out.write(buf,0,pos); 180 | out.write("\n".getBytes()); 181 | pos++; 182 | try{ 183 | if(wait_time > max_wait) break; 184 | 185 | log("Going to sleep for "+wait_time+" ms."); 186 | Thread.currentThread().sleep(wait_time); 187 | wait_time *= 2; 188 | if(in.read() < 0) break; //Connection closed 189 | }catch(InterruptedException ie){ 190 | }catch(InterruptedIOException ioe){ 191 | } 192 | } 193 | log("Chargen finished."); 194 | } 195 | 196 | /** 197 | Models connect back situation. 198 |

199 | Reads a line from the socket connection, line should be in the 200 | form port service_id. Connects back to the remote host to port 201 | specified in the line, if successful performs a service speciefied 202 | by id on that new connection. If accept was successful closes the 203 | control connection, else outputs error message, and then closes 204 | the connection. 205 | 206 | @param s Control connection. 207 | */ 208 | static public void connect(Socket s)throws IOException{ 209 | String line = null; 210 | Socket sock; 211 | int port; 212 | int service_id; 213 | 214 | BufferedReader in = new BufferedReader(new InputStreamReader( 215 | s.getInputStream())); 216 | OutputStream out = s.getOutputStream(); 217 | 218 | log("Starting \"connect\" on "+s); 219 | line = in.readLine(); 220 | if(line == null) return; //They closed connection 221 | 222 | java.util.StringTokenizer st = new java.util.StringTokenizer(line); 223 | if(st.countTokens() < 2){ //We need at least 'port' and "id" 224 | out.write("Expect: port serviceId.\n".getBytes()); 225 | log("Invalid arguments."); 226 | return; 227 | } 228 | try{ 229 | port = Integer.parseInt(st.nextToken()); 230 | service_id = Integer.parseInt(st.nextToken()); 231 | }catch(NumberFormatException nfe){ 232 | out.write("Expect: port serviceId.\n".getBytes()); 233 | log("Invalid arguments."); 234 | return; 235 | } 236 | try{ 237 | log("Connecting to "+s.getInetAddress()+":"+port); 238 | sock = new Socket(s.getInetAddress(),port); 239 | }catch(IOException ioe){ 240 | out.write(("Connect to "+s.getInetAddress()+ 241 | ":"+port+" failed").getBytes()); 242 | log("Connect failed."); 243 | return; 244 | } 245 | s.close(); 246 | log("About to serve "+service_id); 247 | serve(sock,service_id); 248 | } 249 | 250 | /** 251 | Pipes data from the input stream to the output. 252 | @param in Input stream. 253 | @param out Output stream. 254 | */ 255 | static public void pipe(InputStream in, OutputStream out) 256 | throws IOException{ 257 | byte[] buf = new byte[BUF_SIZE]; 258 | int bread = 0; 259 | while(bread >= 0){ 260 | bread = in.read(buf); 261 | out.write(buf,0,bread); 262 | } 263 | } 264 | 265 | /** 266 | Performs logging. 267 | */ 268 | static synchronized void log(String s){ 269 | if(log != null) log.println(s); 270 | } 271 | 272 | } 273 | --------------------------------------------------------------------------------