public static Socks4CommandType valueOf(byte b) { switch (b) { case 0x01: return CONNECT; case 0x02: return BIND; } return new Socks4CommandType(b); }
public Socks4ServerDecoder() { super(State.START); setSingleDecode(true); }
public Socks4ClientDecoder() { super(State.START); setSingleDecode(true); }
@Override protected void channelRead0(final ChannelHandlerContext ctx, final Socks4CommandRequest commandRequest) { if (commandRequest.type().equals(Socks4CommandType.CONNECT)) { forwardConnection(ctx, new Socks4ConnectHandler(server, mockServerLogger, commandRequest.dstAddr(), commandRequest.dstPort()), commandRequest.dstAddr(), commandRequest.dstPort()); ctx.fireChannelRead(commandRequest); } else { ctx.writeAndFlush(new DefaultSocks4CommandResponse(Socks4CommandStatus.REJECTED_OR_FAILED)).addListener(ChannelFutureListener.CLOSE); } } }
@Override protected void encode(ChannelHandlerContext ctx, Socks4CommandRequest msg, ByteBuf out) throws Exception { out.writeByte(msg.version().byteValue()); out.writeByte(msg.type().byteValue()); out.writeShort(msg.dstPort()); if (NetUtil.isValidIpV4Address(msg.dstAddr())) { out.writeBytes(NetUtil.createByteArrayFromIpAddressString(msg.dstAddr())); ByteBufUtil.writeAscii(out, msg.userId()); out.writeByte(0); } else { out.writeBytes(IPv4_DOMAIN_MARKER); ByteBufUtil.writeAscii(out, msg.userId()); out.writeByte(0); ByteBufUtil.writeAscii(out, msg.dstAddr()); out.writeByte(0); } } }
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { try { switch (state()) { case START: { final int version = in.readUnsignedByte(); type = Socks4CommandType.valueOf(in.readByte()); dstPort = in.readUnsignedShort(); dstAddr = NetUtil.intToIpAddress(in.readInt()); checkpoint(State.READ_USERID); userId = readString("userid", in); checkpoint(State.READ_DOMAIN); dstAddr = readString("dstAddr", in); out.add(new DefaultSocks4CommandRequest(type, dstAddr, dstPort, userId)); checkpoint(State.SUCCESS); int readableBytes = actualReadableBytes(); if (readableBytes > 0) { out.add(in.readRetainedSlice(readableBytes)); in.skipBytes(actualReadableBytes()); break; fail(out, e);
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { try { switch (state()) { case START: { final int version = in.readUnsignedByte(); final Socks4CommandStatus status = Socks4CommandStatus.valueOf(in.readByte()); final int dstPort = in.readUnsignedShort(); final String dstAddr = NetUtil.intToIpAddress(in.readInt()); out.add(new DefaultSocks4CommandResponse(status, dstAddr, dstPort)); checkpoint(State.SUCCESS); int readableBytes = actualReadableBytes(); if (readableBytes > 0) { out.add(in.readRetainedSlice(readableBytes)); in.skipBytes(actualReadableBytes()); break; fail(out, e);
@Override protected void encode(ChannelHandlerContext ctx, Socks4CommandResponse msg, ByteBuf out) throws Exception { out.writeByte(0); out.writeByte(msg.status().byteValue()); out.writeShort(msg.dstPort()); out.writeBytes(msg.dstAddr() == null? IPv4_HOSTNAME_ZEROED : NetUtil.createByteArrayFromIpAddressString(msg.dstAddr())); } }
@Override public String toString() { StringBuilder buf = new StringBuilder(128); buf.append(StringUtil.simpleClassName(this)); DecoderResult decoderResult = decoderResult(); if (!decoderResult.isSuccess()) { buf.append("(decoderResult: "); buf.append(decoderResult); buf.append(", type: "); } else { buf.append("(type: "); } buf.append(type()); buf.append(", dstAddr: "); buf.append(dstAddr()); buf.append(", dstPort: "); buf.append(dstPort()); buf.append(", userId: "); buf.append(userId()); buf.append(')'); return buf.toString(); } }
private void fail(List<Object> out, Exception cause) { if (!(cause instanceof DecoderException)) { cause = new DecoderException(cause); } Socks4CommandResponse m = new DefaultSocks4CommandResponse(Socks4CommandStatus.REJECTED_OR_FAILED); m.setDecoderResult(DecoderResult.failure(cause)); out.add(m); checkpoint(State.FAILURE); } }
private void fail(List<Object> out, Exception cause) { if (!(cause instanceof DecoderException)) { cause = new DecoderException(cause); } Socks4CommandRequest m = new DefaultSocks4CommandRequest( type != null? type : Socks4CommandType.CONNECT, dstAddr != null? dstAddr : "", dstPort != 0? dstPort : 65535, userId != null? userId : ""); m.setDecoderResult(DecoderResult.failure(cause)); out.add(m); checkpoint(State.FAILURE); }
@Override public String toString() { StringBuilder buf = new StringBuilder(96); buf.append(StringUtil.simpleClassName(this)); DecoderResult decoderResult = decoderResult(); if (!decoderResult.isSuccess()) { buf.append("(decoderResult: "); buf.append(decoderResult); buf.append(", dstAddr: "); } else { buf.append("(dstAddr: "); } buf.append(dstAddr()); buf.append(", dstPort: "); buf.append(dstPort()); buf.append(')'); return buf.toString(); } }
protected Object failureResponse(Object request) { return new DefaultSocks4CommandResponse(Socks4CommandStatus.REJECTED_OR_FAILED); } }
public static boolean isSocks4(ByteBuf msg, int actualReadableBytes) { // first byte has to be 4 int i = msg.readerIndex(); if (SocksVersion.valueOf(msg.getByte(i++)) != SocksVersion.SOCKS4a) { return false; } // second byte has to be 1 or 2 Socks4CommandType commandType = Socks4CommandType.valueOf(msg.getByte(i++)); if (!(commandType.equals(Socks4CommandType.CONNECT) || commandType.equals(Socks4CommandType.BIND))) { return false; } if (-1 == (i = consumeFields(msg, i + 2))) { return false; } // end of available bytes reached // if not, it is probably not SOCKS4 // do this check last so that any waiting for data is already done return i == actualReadableBytes; }
@Override protected Object newInitialMessage(ChannelHandlerContext ctx) throws Exception { InetSocketAddress raddr = destinationAddress(); String rhost; if (raddr.isUnresolved()) { rhost = raddr.getHostString(); } else { rhost = raddr.getAddress().getHostAddress(); } return new DefaultSocks4CommandRequest( Socks4CommandType.CONNECT, rhost, raddr.getPort(), username != null? username : ""); }
@Override protected boolean handleResponse(ChannelHandlerContext ctx, Object response) throws Exception { final Socks4CommandResponse res = (Socks4CommandResponse) response; final Socks4CommandStatus status = res.status(); if (status == Socks4CommandStatus.SUCCESS) { return true; } throw new ProxyConnectException(exceptionMessage("status: " + status)); } }
private void enableSocks4(ChannelHandlerContext ctx, ByteBuf msg) { enableSocks(ctx, msg, new Socks4ProxyHandler(server, mockServerLogger), Socks4ServerEncoder.INSTANCE, new Socks4ServerDecoder()); }
@Override protected void addCodec(ChannelHandlerContext ctx) throws Exception { ChannelPipeline p = ctx.pipeline(); String name = ctx.name(); Socks4ClientDecoder decoder = new Socks4ClientDecoder(); p.addBefore(name, null, decoder); decoderName = p.context(decoder).name(); encoderName = decoderName + ".encoder"; p.addBefore(name, encoderName, Socks4ClientEncoder.INSTANCE); }
public static Socks4CommandStatus valueOf(byte b) { switch (b) { case 0x5a: return SUCCESS; case 0x5b: return REJECTED_OR_FAILED; case 0x5c: return IDENTD_UNREACHABLE; case 0x5d: return IDENTD_AUTH_FAILURE; } return new Socks4CommandStatus(b); }
protected Object successResponse(Object request) { return new DefaultSocks4CommandResponse(Socks4CommandStatus.SUCCESS); }