/*
 * Copyright 2002 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
import java.net.*;
import java.io.*;

public class SocksServer extends Thread {
    // Some useful SOCKS constant

    static final int PROTO_VERS4                = 4;
    static final int PROTO_VERS         = 5;
    static final int DEFAULT_PORT               = 1080;

    static final int NO_AUTH            = 0;
    static final int GSSAPI             = 1;
    static final int USER_PASSW         = 2;
    static final int NO_METHODS         = -1;

    static final int CONNECT            = 1;
    static final int BIND                       = 2;
    static final int UDP_ASSOC          = 3;

    static final int IPV4                       = 1;
    static final int DOMAIN_NAME                = 3;
    static final int IPV6                       = 4;

    static final int REQUEST_OK         = 0;
    static final int GENERAL_FAILURE    = 1;
    static final int NOT_ALLOWED                = 2;
    static final int NET_UNREACHABLE    = 3;
    static final int HOST_UNREACHABLE   = 4;
    static final int CONN_REFUSED               = 5;
    static final int TTL_EXPIRED                = 6;
    static final int CMD_NOT_SUPPORTED  = 7;
    static final int ADDR_TYPE_NOT_SUP  = 8;

    private int port;
    private ServerSocket server;
    private boolean useV4 = false;
    private java.util.Hashtable users = new java.util.Hashtable();
    private boolean done = false;
    // Inner class to handle protocol with client
    // This is the bulk of the work (protocol handler)
    class ClientHandler extends Thread {
        private InputStream in;
        private OutputStream out;
        private Socket client;
        private Socket dest;

        // Simple tunneling class, moving bits from one stream to another

        class Tunnel extends Thread {
            private InputStream tin;
            private OutputStream tout;

            Tunnel(InputStream in, OutputStream out) {
                tin = in;
                tout = out;
            }

            public void run() {
                int b;
                while (true) {
                    try {
                        b = tin.read();
                        if (b == -1) {
                            tin.close();
                            tout.close();
                            return;
                        }
                        tout.write(b);
                    } catch (IOException e) {
                        // actually exit from the thread
                        return;
                    }
                }
            }
        }

        ClientHandler(Socket s) throws IOException {
            client = s;
            in = client.getInputStream();
            out = client.getOutputStream();
        }

        private void readBuf(InputStream is, byte[] buf) throws IOException {
            int l = buf.length;
            int count = 0;
            int i;
            do {
                i = is.read(buf, count, l - count);
                if (i == -1)
                    throw new IOException("unexpected EOF");
                count += i;
            } while (count < l);
        }


        private boolean userPassAuth() throws IOException {
            int ver = in.read();
            int ulen = in.read();
            if (ulen <= 0)
                throw new SocketException("SOCKS protocol error");
            byte[] buf = new byte[ulen];
            readBuf(in, buf);
            String uname = new String(buf);
            String password = null;
            ulen = in.read();
            if (ulen < 0)
                throw new SocketException("SOCKS protocol error");
            if (ulen > 0) {
                buf = new byte[ulen];
                readBuf(in, buf);
                password = new String(buf);
            }
            // Check username/password validity here
            System.err.println("User: '" + uname);
            System.err.println("PSWD: '" + password);
            if (users.containsKey(uname)) {
                String p1 = (String) users.get(uname);
                System.err.println("p1 = " + p1);
                if (p1.equals(password)) {
                    out.write(PROTO_VERS);
                    out.write(REQUEST_OK);
                    out.flush();
                    return true;
                }
            }
            out.write(PROTO_VERS);
            out.write(NOT_ALLOWED);
            out.flush();
            return false;
        }

        private void purge() throws IOException {
            boolean done = false;
            int i = 0;
            client.setSoTimeout(1000);
            while(!done && i != -1) {
                try {
                    i = in.read();
                } catch(IOException e) {
                    done = true;
                }
            }
        }


        // Handle the SOCKS version 4 protocl

        private void getRequestV4() throws IOException {
            int ver = in.read();
            int cmd = in.read();
            if (ver == -1 || cmd == -1) {
                // EOF
                in.close();
                out.close();
                return;
            }

            if (ver != 0 && ver != 4) {
                out.write(PROTO_VERS4);
                out.write(91); // Bad Request
                out.write(0);
                out.write(0);
                out.write(0);
                out.write(0);
                out.write(0);
                out.write(0);
                out.write(0);
                out.flush();
                purge();
                out.close();
                in.close();
                return;
            }

            if (cmd == CONNECT) {
                int port = ((in.read() & 0xff) << 8);
                port += (in.read() & 0xff);
                byte[] buf = new byte[4];
                readBuf(in, buf);
                InetAddress addr = InetAddress.getByAddress(buf);
                // We don't use the username...
                int c;
                do {
                    c = (in.read() & 0xff);
                } while (c!=0);
                boolean ok = true;
                try {
                    dest = new Socket(addr, port);
                } catch (IOException e) {
                    ok = false;
                }
                if (!ok) {
                    out.write(PROTO_VERS4);
                    out.write(91);
                    out.write(0);
                    out.write(0);
                    out.write(buf);
                    out.flush();
                    purge();
                    out.close();
                    in.close();
                    return;
                }
                out.write(PROTO_VERS4);
                out.write(90); // Success
                out.write((port >> 8) & 0xff);
                out.write(port & 0xff);
                out.write(buf);
                out.flush();
                InputStream in2 = dest.getInputStream();
                OutputStream out2 = dest.getOutputStream();

                Tunnel tunnel = new Tunnel(in2, out);
                tunnel.start();

                int b = 0;
                do {
                    try {
                        b = in.read();
                        if (b == -1) {
                            in.close();
                            out2.close();
                            return;
                        }
                        out2.write(b);
                    } catch (IOException ex) {
                    }
                } while (!client.isClosed());
            }
        }


        // Negociate the authentication scheme with the client
        private void negociate() throws IOException {
            int ver = in.read();
            int n = in.read();
            byte[] buf = null;
            if (n > 0) {
                buf = new byte[n];
                readBuf(in, buf);
            }
            int scheme = NO_AUTH;
            for (int i = 0; i < n; i++)
                if (buf[i] == USER_PASSW)
                    scheme = USER_PASSW;
            out.write(PROTO_VERS);
            out.write(scheme);
            out.flush();
            if (scheme == USER_PASSW)
                userPassAuth();
        }

        // Send error message then close the streams
        private void sendError(int code) {
            try {
                out.write(PROTO_VERS);
                out.write(code);
                out.write(0);
                out.write(IPV4);
                for (int i=0; i<6; i++)
                    out.write(0);
                out.flush();
                out.close();
            } catch (IOException ex) {
            }
        }

        // Actually connect the proxy to the destination then initiate tunneling

        private void doConnect(InetSocketAddress addr) throws IOException {
            dest = new Socket();
            try {
                dest.connect(addr, 10000);
            } catch (SocketTimeoutException ex) {
                sendError(HOST_UNREACHABLE);
                return;
            } catch (ConnectException cex) {
                sendError(CONN_REFUSED);
                return;
            }
            // Success
            InetAddress iadd = addr.getAddress();
            if (iadd instanceof Inet4Address) {
                out.write(PROTO_VERS);
                out.write(REQUEST_OK);
                out.write(0);
                out.write(IPV4);
                out.write(iadd.getAddress());
            } else if (iadd instanceof Inet6Address) {
                out.write(PROTO_VERS);
                out.write(REQUEST_OK);
                out.write(0);
                out.write(IPV6);
                out.write(iadd.getAddress());
            } else {
                sendError(GENERAL_FAILURE);
                return;
            }
            out.write((addr.getPort() >> 8) & 0xff);
            out.write((addr.getPort() >> 0) & 0xff);
            out.flush();

            InputStream in2 = dest.getInputStream();
            OutputStream out2 = dest.getOutputStream();

            Tunnel tunnel = new Tunnel(in2, out);
            tunnel.start();

            int b = 0;
            do {
                // Note that the socket might be closed from another thread (the tunnel)
                try {
                    b = in.read();
                    if (b == -1) {
                        in.close();
                        out2.close();
                        return;
                    }
                    out2.write(b);
                } catch(IOException ioe) {
                }
            } while (!client.isClosed());
        }

        private void doBind(InetSocketAddress addr) throws IOException {
            ServerSocket svr = new ServerSocket();
            svr.bind(null);
            InetSocketAddress bad = (InetSocketAddress) svr.getLocalSocketAddress();
            out.write(PROTO_VERS);
            out.write(REQUEST_OK);
            out.write(0);
            out.write(IPV4);
            out.write(bad.getAddress().getAddress());
            out.write((bad.getPort() >> 8) & 0xff);
            out.write((bad.getPort() & 0xff));
            out.flush();
            dest = svr.accept();
            bad = (InetSocketAddress) dest.getRemoteSocketAddress();
            out.write(PROTO_VERS);
            out.write(REQUEST_OK);
            out.write(0);
            out.write(IPV4);
            out.write(bad.getAddress().getAddress());
            out.write((bad.getPort() >> 8) & 0xff);
            out.write((bad.getPort() & 0xff));
            out.flush();
            InputStream in2 = dest.getInputStream();
            OutputStream out2 = dest.getOutputStream();

            Tunnel tunnel = new Tunnel(in2, out);
            tunnel.start();

            int b = 0;
            do {
                // Note that the socket might be close from another thread (the tunnel)
                try {
                    b = in.read();
                    if (b == -1) {
                        in.close();
                        out2.close();
                        return;
                    }
                    out2.write(b);
                } catch(IOException ioe) {
                }
            } while (!client.isClosed());

        }

        // Handle the SOCKS v5 requests

        private void getRequest() throws IOException {
            int ver = in.read();
            int cmd = in.read();
            if (ver == -1 || cmd == -1) {
                in.close();
                out.close();
                return;
            }
            int rsv = in.read();
            int atyp = in.read();
            String addr = null;
            int port = 0;

            switch(atyp) {
            case IPV4:
                {
                byte[] buf = new byte[4];
                readBuf(in, buf);
                int i = 0;
                StringBuffer sb = new StringBuffer();
                for (i = 0; i < 4; i++) {
                    sb.append(buf[i]&0xff);
                    if (i < 3)
                        sb.append('.');
                }
                addr = sb.toString();
                }
                break;
            case DOMAIN_NAME:
                {
                int i = in.read();
                byte[] buf = new byte[i];
                readBuf(in, buf);
                addr = new String(buf);
                }
                break;
            case IPV6:
                {
                byte[] buf = new byte[16];
                readBuf(in, buf);
                int i = 0;
                StringBuffer sb = new StringBuffer();
                for (i = 0; i<16; i++) {
                    sb.append(Integer.toHexString(buf[i]&0xff));
                    if (i < 15)
                        sb.append(':');
                }
                addr = sb.toString();
                }
                break;
            }

            port = ((in.read()&0xff) << 8);
            port += (in.read()&0xff);

            InetSocketAddress socAddr = new InetSocketAddress(addr, port);
            switch(cmd) {
            case CONNECT:
                doConnect(socAddr);
                break;
            case BIND:
                doBind(socAddr);
                break;
            case UDP_ASSOC:
                // doUDP(socAddr);
                break;
            }
        }

        public void run() {
            String line = null;
            try {
                if (useV4) {
                    getRequestV4();
                } else {
                    negociate();
                    getRequest();
                }
            } catch (IOException ex) {
                try {
                    sendError(GENERAL_FAILURE);
                } catch (Exception e) {
                }
            } finally {
                try {
                    client.close();
                } catch (IOException e2) {
                }
            }
        }

    }

    public SocksServer(int port, boolean v4) throws IOException {
        this(port);
        this.useV4 = v4;
    }

    public SocksServer(int port) throws IOException {
        this.port = port;
        server = new ServerSocket();
        server.bind(new InetSocketAddress(port));
    }

    public SocksServer() throws IOException {
        this (DEFAULT_PORT);
    }

    public void addUser(String user, String passwd) {
        users.put(user, passwd);
    }

    public synchronized void terminate() {
        done = true;
    }

    public void run() {
        ClientHandler cl = null;
        while (!done) {
            try {
                Socket s = server.accept();
                cl = new ClientHandler(s);
                cl.start();
            } catch (IOException ex) {
                if (cl != null)
                    cl.interrupt();
            }
        }
    }
}
