Реализация Socks5 протокола на Java сокетах и https google

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by huntercs16, 3 Nov 2015.

  1. huntercs16

    huntercs16 Member

    Joined:
    7 Oct 2013
    Messages:
    154
    Likes Received:
    15
    Reputations:
    6
    В браузере стоит 10000 порт на сокс5.
    Code:
         
       ServerSocket ss = new ServerSocket(10000);
            while (Math.abs(-4) > 1) {
                Socket s = ss.accept();
                System.err.println("Client accepted");
                new Thread(new SocketProcessor(s)).start();
            }
    
    Это сокетпроцессор
    Code:
    package server;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.UnsupportedEncodingException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.util.Arrays;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import struct.Socks5Error;
    
    public class SocketProcessor implements Runnable {
    
        private Socket s;
        private InputStream is;
        private OutputStream os;
    
        private byte[] ip;
        private byte[] port;
    
        private byte[] tmp;
    
        private int atype;
    
        SocketProcessor(Socket s) throws Throwable {
            this.s = s;
            this.is = s.getInputStream();
            this.os = s.getOutputStream();
            tmp = new byte[65536];
            port = new byte[2];
        }
    
        public void writeHTML() throws IOException {
    
            String html = "<html><title>tu tu tu tu</title><body>mana mana</body></html>";
            int l = html.length();
            //l=40;
            String aa = "HTTP/1.1 200 OK\r\n"
                    + "Vary: Accept-Encoding,Cookie\r\n"
                    + "Date: Sat, 23 Mar 2013 22:25:33 GMT\r\n"
                    + "Content-Length: " + l + "\r\n"
                    + "Connection: Keep-Alive\r\n"
                    + "Content-Type: text/html; charset=UTF-8\r\n\r\n";
    
            String s = aa + html;
            this.os.write(s.getBytes());
            //this.os.flush();
            //this.s.close();
        }
    
        public void badClient() {
            try {
                os.write(5);
                os.write(0xFF);
                s.close();
            } catch (IOException ex) {
    
            }
        }
    
        public void cmdResp() throws IOException {
            byte[] b = new byte[10];
            b[0] = 5;
            b[1] = 0;
            b[2] = 0;
            b[3] = 1;
            for (int i = 0; i < ip.length; i++) {
                b[i + 4] = ip[i];
            }
            b[8] = (byte) (this.port[0]);
            b[9] = (byte) (this.port[1]);
            os.write(b);
        }
    
        public void cmdError(byte err) throws IOException {
            byte[] b = new byte[10];
            b[0] = 5;
            b[1] = (byte) err;
            b[2] = 0;
            b[3] = (byte) this.atype;
            os.write(b);
        }
    
        public void run() {
    
            try {
                int r = is.read();
                if (r != 5) {
                    this.badClient();
                    return;
                }
    
                r = is.read();
                for (int i = 0; i < r; i++) {
                    r = is.read();
                }
    
                byte[] b = new byte[2];
    
                b[0] = 5;
                b[1] = 0;
    
                os.write(b);
    
                r = is.read();
                if (r != 5) {
                    this.badClient();
                    return;
                }
    
                r = is.read(); //CMD
    
                if (r != 1) {
                    System.out.println("CMD=" + r);
                    this.cmdError(Socks5Error.noCMD);
                    os.flush();
                    s.close();
                    return;
                }
    
                r = is.read(); //Reserved;
    
                this.atype = is.read();
    
                if (this.atype != 1) {
                    System.out.println("ATYPE=" + atype);
                    this.cmdError(Socks5Error.noProtocol);
                    os.flush();
                    s.close();
                    return;
                }
    
                b = new byte[4];
                r = is.read(b, 0, 4);
                if (r < 4) {
                    System.out.println("r=" + 4);
                }
    
                this.ip = b;
                r = is.read(this.port, 0, 2);
                if (r < 2) {
                    System.out.println("r=" + 4);
                }
                Socket s3 = null;
    
                try {
                    InetSocketAddress iaddr = new InetSocketAddress(Helper.getIpAddress(this.ip), port[0] * 256 + port[1]);
                    s3 = new Socket();
                    s3.connect(iaddr, 60000);
    
                } catch (Exception ex) {
                    System.out.println("ip=" + Helper.getIpAddress(this.ip) + " ,port=" + (port[0] * 256 + port[1]));
                }
                InputStream is3 = s3.getInputStream();
                OutputStream os3 = s3.getOutputStream();
    
                System.out.println(port[0] * 256 + port[1]);
    
                this.cmdResp();
    
                int cnt = 0;
                this.s.setSoTimeout(4000);
                s3.setSoTimeout(4000);
    
                while (true) {
                    //System.out.println("while");
                    try {
                        if (is.available() > 0) {
                            r = is.read(this.tmp);
                            if (r > 0) {
                                System.out.println("From User=" + r);
                                byte[] btmp = new byte[r];
                                for (int i = 0; i < r; i++) {
                                    btmp[i] = tmp[i];
                                }
                                String o = new String(btmp, "UTF-8");
                                System.out.println(o);
                                os3.write(tmp, 0, r);
                            }
                        }
    
                        if (is3.available() > 0) {
                            r = is3.read(tmp);
                            if (r > 0) {
                                System.out.println("From Server=" + r);
                                /*
                                 byte[] btmp = new byte[r];
                                 for (int i = 0; i < r; i++) {
                                 btmp[i] = tmp[i];
                                 }
                                 String o = new String(btmp, "UTF-8");
                                 System.out.println(o);
                                 */
    
                                os.write(tmp, 0, r);
                            }
                        }
                    } catch (Exception ex) {
                        if (is == null) {
                            return;
                        }
    
                        if (is3 == null) {
                            return;
                        }
    
                        //System.out.println("ex");
                        continue;
                        //break;
                        //return;
                    }
                }
    
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("ex2");
            }
    
        }
    }
    
    Если выводить манамана - это будет работать всегда и везде.

    Когда запрашиваю https google -валится ошибка где s3 инициализируется.

    ip=89.221.194.98 ,port=187
     
  2. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    Ну лично мне глядя на код не нравится как ты преобразуешь 2 байта в порт. В какой там последовательности идут байты? В какой тип данных надо преобразовать?

    Давно не писал под windows но там есть полезные макросы типа MAKEWORD (2 байта), MAKELONG (4 байта) и от меня MAKEBYTE (1 байт из 2х)
    Code:
    #define MAKELONG(a, b) \
    ((LONG) (((WORD) (a)) | ((DWORD) ((WORD) (b))) << 16))
    
    #define MAKEWORD(a,b) \ 
    ((WORD)(((BYTE)(a))|(((WORD)((BYTE)(b)))<<8)))
    
    #define MAKEBYTE(l,h) \
    (((l)<<4)|((h)&0xFF))
    
    В одном из проектов на Java мне надо было 2 байта из данных переделать в short (тот же word)
    Code:
    (short) ((pcmdata[33] << 8) + (pcmdata[32] & 0xff));
     
    _________________________
  3. huntercs16

    huntercs16 Member

    Joined:
    7 Oct 2013
    Messages:
    154
    Likes Received:
    15
    Reputations:
    6
    мана мана
     
  4. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    Да да, очень информативно описал проблему :) https://github.com/Garik-/mini_socks5 у меня и 5 лет назад все работало... "мана мана", учись пользоваться отладчиком.
     
    _________________________