/******************************************************************************* * gMix open source project - https://svs.informatik.uni-hamburg.de/gmix/ * Copyright (C) 2014 SVS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ /** * */ package userGeneratedContent.testbedPlugIns.layerPlugIns.layer5application.httpPush_v0_001.helper; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.Arrays; import staticContent.framework.util.Util; /** * This class provides methodes for communication via SOCKS5-Protocol * @author bash * */ public class SocksHandler { /** * Extract an Array of methods for identification * +----+----------+---------+ * |VER | NMETHODS | METHODS | * +----+----------+---------+ * | 1 | 1 | 1 to 255| * +----+----------+---------+ * * @param message * @return byte Array containing AuthMethodes */ public static byte[] readAuthMethodRequest(byte[] message){ byte length = message[1]; byte[] methodArray = Arrays.copyOfRange(message, 2, length+2); return methodArray; } /** * Sends a SOCKS5 Method Reply Message to user. * * +----+--------+ * |VER | METHOD | * +----+--------+ * | 1 | 1 | * +----+--------+ * * @param method method for authentification * @return socksReply as byte array */ public static byte[] sendSocks5MethodReply(byte method) { byte[] socksAuthReply = new byte[]{5,method}; return socksAuthReply; } /** * Generate SOCKS5 request. * The message looks like: * * +----+-----+-------+------+----------+----------+ * |VER | CMD | RSV | ATYP | BND.ADDR | BND.PORT | * +----+-----+-------+------+----------+----------+ * | 1 | 1 | X'00' | 1 | Variable | 2 | * +----+-----+-------+------+----------+----------+ * * * @param message * @return type of socks request as byte */ public static byte getSocksCommand(byte[] message){ return message[1]; } /** * Reads a couple of bytes depending on the address type and returns this * address as an InetAddress-Object. * * @param message * @return InetAddress */ public static InetSocketAddress getInetAddress(byte[] message) { byte aTyp = message[1]; byte[] wrapped; byte[] byteAddress = null; int length; int port = 0; InetAddress address = null; try { switch (aTyp) { case 0x01: // IP v4 length = 4; byteAddress = Arrays.copyOfRange(message, 4, 8); address = InetAddress.getByAddress(byteAddress); wrapped = Arrays.copyOfRange(message, 8, 10); port = Util.unsignedShortToInt(wrapped); break; case 0x03: // Domain, first byte defines the length of it length = Util.unsignedByteToShort(message[4]); byteAddress = Arrays.copyOfRange(message, 5, 5 + length); String stringAddress = Util .getStringWithoutNewLines(byteAddress); address = InetAddress.getByName(stringAddress); wrapped = Arrays.copyOfRange(message, 5 + length, 6 + length); port = Util.unsignedShortToInt(wrapped); break; case 0x04: // IP v6 length = 16; byteAddress = Arrays.copyOfRange(message, 4, 20); address = InetAddress.getByAddress(byteAddress); wrapped = Arrays.copyOfRange(message, 21, 22); port = Util.unsignedShortToInt(wrapped); break; } } catch (UnknownHostException e) { e.printStackTrace(); } InetSocketAddress socketAdress = new InetSocketAddress(address, port); return socketAdress; } /** * * Generate SOCKS5 reply for the connect (0x01) command. * The message looks like: * * +----+-----+-------+------+----------+----------+ * |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | * +----+-----+-------+------+----------+----------+ * | 1 | 1 | X'00' | 1 | Variable | 2 | * +----+-----+-------+------+----------+----------+ * * X'00' SUCCEEDED * X'01' general SOCKS server failure * X'02' connection not allowed by ruleset * X'03' Network unreachable * X'04' Host unreachable * X'05' Connection refused * X'06' TTL expired * * @param replyCode SOCKS5 reply field * @param aTyp valid values: 0x01, 0x03, 0x04 * @param address BindAddress as InetSocketAddress * @return Replymessage as byte[] */ public static byte[] sendSocks5ConnectionReply(byte replyCode, byte aTyp, InetSocketAddress address){ byte[] addressAsByte = address.getAddress().getAddress(); byte[] portAsByte = Util.shortToByteArray(address.getPort()); byte[] header = {0x05, replyCode, 0x00, aTyp}; byte[] connectReply= Util.concatArrays(header, addressAsByte); connectReply = Util.concatArrays(connectReply, portAsByte); return connectReply; } }