Package com.subgraph.orchid.socks

Source Code of com.subgraph.orchid.socks.Socks5Request

package com.subgraph.orchid.socks;

import java.net.Socket;

import com.subgraph.orchid.TorConfig;
import com.subgraph.orchid.TorException;

public class Socks5Request extends SocksRequest {
  final static int SOCKS5_VERSION = 5;
  final static int SOCKS5_AUTH_NONE = 0;
  final static int SOCKS5_COMMAND_CONNECT = 1;
  final static int SOCKS5_COMMAND_RESOLV = 0xF0;
  final static int SOCKS5_COMMAND_RESOLV_PTR = 0xF1;
  final static int SOCKS5_ADDRESS_IPV4 = 1;
  final static int SOCKS5_ADDRESS_HOSTNAME = 3;
  final static int SOCKS5_ADDRESS_IPV6 = 4;
  final static int SOCKS5_STATUS_SUCCESS = 0;
  final static int SOCKS5_STATUS_FAILURE = 1;
  final static int SOCKS5_STATUS_CONNECTION_REFUSED = 5;
  final static int SOCKS5_STATUS_COMMAND_NOT_SUPPORTED = 7;
 
  private int command;
  private int addressType;
  private byte[] addressBytes = new byte[0];
  private byte[] portBytes = new byte[0];
 
  Socks5Request(TorConfig config, Socket socket) {
    super(config, socket);
  }
 
  public boolean isConnectRequest() {
    return command == SOCKS5_COMMAND_CONNECT;
  }
 
  public int getCommandCode() {
    return command;
  }

  private String addressBytesToHostname() {
    if(addressType != SOCKS5_ADDRESS_HOSTNAME)
      throw new TorException("SOCKS 4 request is not a hostname request");
    final StringBuilder sb = new StringBuilder();
    for(int i = 1; i < addressBytes.length; i++) {
      char c = (char) (addressBytes[i] & 0xFF);
      sb.append(c);
    }
    return sb.toString();
  }
 
  public void readRequest() throws SocksRequestException {
    if(!processAuthentication()) {
      throw new SocksRequestException("Failed to negotiate authentication");
    }
    if(readByte() != SOCKS5_VERSION)
      throw new SocksRequestException();

    command = readByte();
    readByte(); // Reserved
    addressType = readByte();
    addressBytes = readAddressBytes();
    portBytes = readPortData();
    if(addressType == SOCKS5_ADDRESS_IPV4)
      setIPv4AddressData(addressBytes);
    else if(addressType == SOCKS5_ADDRESS_HOSTNAME)
      setHostname(addressBytesToHostname());
    else
      throw new SocksRequestException();
    setPortData(portBytes);   
  }
 
  public void sendConnectionRefused() throws SocksRequestException {
    sendResponse(SOCKS5_STATUS_CONNECTION_REFUSED);
  }

  public void sendError(boolean isUnsupportedCommand) throws SocksRequestException  {
    if(isUnsupportedCommand) {
      sendResponse(SOCKS5_STATUS_COMMAND_NOT_SUPPORTED);
    } else {
      sendResponse(SOCKS5_STATUS_FAILURE);
    }
  }
 
  public void sendSuccess() throws SocksRequestException {
    sendResponse(SOCKS5_STATUS_SUCCESS);
  }
 
  private void sendResponse(int status) throws SocksRequestException {
    final int responseLength = 4 + addressBytes.length + portBytes.length;
    final byte[] response = new byte[responseLength];
    response[0] = SOCKS5_VERSION;
    response[1] = (byte) status;
    response[2] = 0;
    response[3] = (byte) addressType;
    System.arraycopy(addressBytes, 0, response, 4, addressBytes.length);
    System.arraycopy(portBytes, 0, response, 4 + addressBytes.length, portBytes.length);
    socketWrite(response);
  }
 
  private boolean processAuthentication() throws SocksRequestException {
    final int nmethods = readByte();
    boolean foundAuthNone = false;
    for(int i = 0; i < nmethods; i++) {
      final int meth = readByte();
      if(meth == SOCKS5_AUTH_NONE)
        foundAuthNone = true;
    }

    if(foundAuthNone) {
      sendAuthenticationResponse(SOCKS5_AUTH_NONE);
      return true;
    } else {
      sendAuthenticationResponse(0xFF);
      return false;
    }
  }
 
 
  private void sendAuthenticationResponse(int method) throws SocksRequestException {
    final byte[] response = new byte[2];
    response[0] = SOCKS5_VERSION;
    response[1] = (byte) method;
    socketWrite(response);
  }

  private byte[] readAddressBytes() throws SocksRequestException {
    switch(addressType) {
    case SOCKS5_ADDRESS_IPV4:
      return readIPv4AddressData();
    case SOCKS5_ADDRESS_IPV6:
      return readIPv6AddressData();
    case SOCKS5_ADDRESS_HOSTNAME:
      return readHostnameData();
    default:
      throw new SocksRequestException();
    }
  }
 
  private byte[] readHostnameData() throws SocksRequestException {
    final int length = readByte();
    final byte[] addrData = new byte[length + 1];
    addrData[0] = (byte) length;
    readAll(addrData, 1, length);
    return addrData;
  }
}
TOP

Related Classes of com.subgraph.orchid.socks.Socks5Request

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.