/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jivesoftware.smack.proxy;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.SocketFactory;

/**
 * Socket factory for Socks5 proxy
 * 
 * @author Atul Aggarwal
 */
public class Socks5ProxySocketFactory 
    extends SocketFactory
{
    private ProxyInfo proxy;
    
    public Socks5ProxySocketFactory(ProxyInfo proxy)
    {
        this.proxy = proxy;
    }

    public Socket createSocket(String host, int port) 
        throws IOException, UnknownHostException
    {
        return socks5ProxifiedSocket(host,port);
    }

    public Socket createSocket(String host ,int port, InetAddress localHost,
                                int localPort)
        throws IOException, UnknownHostException
    {
        
        return socks5ProxifiedSocket(host,port);
        
    }

    public Socket createSocket(InetAddress host, int port)
        throws IOException
    {
        
        return socks5ProxifiedSocket(host.getHostAddress(),port);
        
    }

    public Socket createSocket( InetAddress address, int port, 
                                InetAddress localAddress, int localPort) 
        throws IOException
    {
        
        return socks5ProxifiedSocket(address.getHostAddress(),port);
        
    }
    
    private Socket socks5ProxifiedSocket(String host, int port) 
        throws IOException
    {
        Socket socket = null;
        InputStream in = null;
        OutputStream out = null;
        String proxy_host = proxy.getProxyAddress();
        int proxy_port = proxy.getProxyPort();
        String user = proxy.getProxyUsername();
        String passwd = proxy.getProxyPassword();
        
        try
        {
            socket=new Socket(proxy_host, proxy_port);    
            in=socket.getInputStream();
            out=socket.getOutputStream();

            socket.setTcpNoDelay(true);

            byte[] buf=new byte[1024];
            int index=0;

/*
                   +----+----------+----------+
                   |VER | NMETHODS | METHODS  |
                   +----+----------+----------+
                   | 1  |    1     | 1 to 255 |
                   +----+----------+----------+

   The VER field is set to X'05' for this version of the protocol.  The
   NMETHODS field contains the number of method identifier octets that
   appear in the METHODS field.

   The values currently defined for METHOD are:

          o  X'00' NO AUTHENTICATION REQUIRED
          o  X'01' GSSAPI
          o  X'02' USERNAME/PASSWORD
          o  X'03' to X'7F' IANA ASSIGNED
          o  X'80' to X'FE' RESERVED FOR PRIVATE METHODS
          o  X'FF' NO ACCEPTABLE METHODS
*/

            buf[index++]=5;

            buf[index++]=2;
            buf[index++]=0;           // NO AUTHENTICATION REQUIRED
            buf[index++]=2;           // USERNAME/PASSWORD

            out.write(buf, 0, index);

/*
    The server selects from one of the methods given in METHODS, and
    sends a METHOD selection message:

                         +----+--------+
                         |VER | METHOD |
                         +----+--------+
                         | 1  |   1    |
                         +----+--------+
*/
      //in.read(buf, 0, 2);
            fill(in, buf, 2);

            boolean check=false;
            switch((buf[1])&0xff)
            {
                case 0:                // NO AUTHENTICATION REQUIRED
                    check=true;
                    break;
                case 2:                // USERNAME/PASSWORD
                    if(user==null || passwd==null)
                    {
                        break;
                    }

/*
   Once the SOCKS V5 server has started, and the client has selected the
   Username/Password Authentication protocol, the Username/Password
   subnegotiation begins.  This begins with the client producing a
   Username/Password request:

           +----+------+----------+------+----------+
           |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
           +----+------+----------+------+----------+
           | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
           +----+------+----------+------+----------+

   The VER field contains the current version of the subnegotiation,
   which is X'01'. The ULEN field contains the length of the UNAME field
   that follows. The UNAME field contains the username as known to the
   source operating system. The PLEN field contains the length of the
   PASSWD field that follows. The PASSWD field contains the password
   association with the given UNAME.
*/
                    index=0;
                    buf[index++]=1;
                    buf[index++]=(byte)(user.length());
                    System.arraycopy(user.getBytes(), 0, buf, index, 
                        user.length());
                    index+=user.length();
                    buf[index++]=(byte)(passwd.length());
                    System.arraycopy(passwd.getBytes(), 0, buf, index, 
                        passwd.length());
                    index+=passwd.length();

                    out.write(buf, 0, index);

/*
   The server verifies the supplied UNAME and PASSWD, and sends the
   following response:

                        +----+--------+
                        |VER | STATUS |
                        +----+--------+
                        | 1  |   1    |
                        +----+--------+

   A STATUS field of X'00' indicates success. If the server returns a
   `failure' (STATUS value other than X'00') status, it MUST close the
   connection.
*/
                    //in.read(buf, 0, 2);
                    fill(in, buf, 2);
                    if(buf[1]==0)
                    {
                        check=true;
                    }
                    break;
                default:
            }

            if(!check)
            {
                try
                {
                    socket.close();
                }
                catch(Exception eee)
                {
                }
                throw new ProxyException(ProxyInfo.ProxyType.SOCKS5,
                    "fail in SOCKS5 proxy");
            }

/*
      The SOCKS request is formed as follows:

        +----+-----+-------+------+----------+----------+
        |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+

      Where:

      o  VER    protocol version: X'05'
      o  CMD
         o  CONNECT X'01'
         o  BIND X'02'
         o  UDP ASSOCIATE X'03'
      o  RSV    RESERVED
         o  ATYP   address type of following address
         o  IP V4 address: X'01'
         o  DOMAINNAME: X'03'
         o  IP V6 address: X'04'
      o  DST.ADDR       desired destination address
      o  DST.PORT desired destination port in network octet
         order
*/
     
            index=0;
            buf[index++]=5;
            buf[index++]=1;       // CONNECT
            buf[index++]=0;

            byte[] hostb=host.getBytes();
            int len=hostb.length;
            buf[index++]=3;      // DOMAINNAME
            buf[index++]=(byte)(len);
            System.arraycopy(hostb, 0, buf, index, len);
            index+=len;
            buf[index++]=(byte)(port>>>8);
            buf[index++]=(byte)(port&0xff);

            out.write(buf, 0, index);

/*
   The SOCKS request information is sent by the client as soon as it has
   established a connection to the SOCKS server, and completed the
   authentication negotiations.  The server evaluates the request, and
   returns a reply formed as follows:

        +----+-----+-------+------+----------+----------+
        |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+

   Where:

   o  VER    protocol version: X'05'
   o  REP    Reply field:
      o  X'00' succeeded
      o  X'01' general SOCKS server failure
      o  X'02' connection not allowed by ruleset
      o  X'03' Network unreachable
      o  X'04' Host unreachable
      o  X'05' Connection refused
      o  X'06' TTL expired
      o  X'07' Command not supported
      o  X'08' Address type not supported
      o  X'09' to X'FF' unassigned
    o  RSV    RESERVED
    o  ATYP   address type of following address
      o  IP V4 address: X'01'
      o  DOMAINNAME: X'03'
      o  IP V6 address: X'04'
    o  BND.ADDR       server bound address
    o  BND.PORT       server bound port in network octet order
*/

      //in.read(buf, 0, 4);
            fill(in, buf, 4);

            if(buf[1]!=0)
            {
                try
                {
                    socket.close();
                }
                catch(Exception eee)
                {
                }
                throw new ProxyException(ProxyInfo.ProxyType.SOCKS5, 
                    "server returns "+buf[1]);
            }

            switch(buf[3]&0xff)
            {
                case 1:
                    //in.read(buf, 0, 6);
                    fill(in, buf, 6);
                    break;
                case 3:
                    //in.read(buf, 0, 1);
                    fill(in, buf, 1);
                    //in.read(buf, 0, buf[0]+2);
                    fill(in, buf, (buf[0]&0xff)+2);
                    break;
                case 4:
                    //in.read(buf, 0, 18);
                    fill(in, buf, 18);
                    break;
                default:
            }
            return socket;
            
        }
        catch(RuntimeException e)
        {
            throw e;
        }
        catch(Exception e)
        {
            try
            {
                if(socket!=null)
                {
                    socket.close(); 
                }
            }
            catch(Exception eee)
            {
            }
            String message="ProxySOCKS5: "+e.toString();
            if(e instanceof Throwable)
            {
                throw new ProxyException(ProxyInfo.ProxyType.SOCKS5,message, 
                    (Throwable)e);
            }
            throw new IOException(message);
        }
    }
    
    private void fill(InputStream in, byte[] buf, int len) 
      throws IOException
    {
        int s=0;
        while(s<len)
        {
            int i=in.read(buf, s, len-s);
            if(i<=0)
            {
                throw new ProxyException(ProxyInfo.ProxyType.SOCKS5, "stream " +
                    "is closed");
            }
            s+=i;
        }
    }
}
