├── .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 |
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 |
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.
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.
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;i
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;i
16 | * Warning!!
19 | * It is only provided to make implementing other authentication schemes easier.
20 | *
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!!
19 | It is only provided to make implementing other authentication schemes
20 | easier.
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
11 | To use it:
12 |
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:
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.
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.
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
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 |
--------------------------------------------------------------------------------
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 | *
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
17 | * Should not be used on machines which are not behind the firewall.
18 | *
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 | *
Should not be
17 | used on machines which are not behind the firewall.
18 |
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 |
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 |
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 | *
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 | *
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 |