You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Michael Reinecke <mi...@achelos.de> on 2014/09/26 09:57:26 UTC

Bug in Mina2.0.7 with SOCKS5 Proxy

Hello devs,

we are using Mina 2.0.7 to access an server through an Socks5 proxy. This worked fine as long as we use a direct IP address of the endpoint, but once we use the computer name, a nullpointer exception would occur. I searched through the source code and found the cause.
If Java can not resolve the computer name, then the handler will switch to the else branch, which tries to access the host value from the request. But to construct the Socks5 Request, you HAVE to set an INetAddress and CAN NOT set the host directly.
One feature of Socks5 is the ability to resolve the hostname by the proxy which may not be resolvable by others and therefor it is not required to resolve the name on our side. So the fastest way to fix this was to add the green code in the else branch.

I am sure there are smarter ways to handle this problem, like extracting the host name in the SocksProxyRequest constructor and set it to the host variable. But as far as I do not know the complete infrastructure of MINA and the resulting consequences, I used this approach ;).

Yours,
Michael Reinecke

<...>
SocksProxyRequest  soxx = new SocksProxyRequest(
                                                                                              SocksProxyConstants.SOCKS_VERSION_5,
                                                                                              SocksProxyConstants.ESTABLISH_TCPIP_STREAM,
                                                                                              new InetSocketAddress("endpoint-name", 666),
                                                                                              "username");
<...>


package org.apache.mina.proxy.handlers.socks;
<...>
public class Socks5LogicHandler extends AbstractSocksLogicHandler {
<...>
    private IoBuffer encodeProxyRequestPacket(final SocksProxyRequest request) throws UnsupportedEncodingException {
        int len = 6;
        InetSocketAddress adr = request.getEndpointAddress();
        byte addressType = 0;
        byte[] host = null;

        if (adr != null && !adr.isUnresolved()) {
            if (adr.getAddress() instanceof Inet6Address) {
                len += 16;
                addressType = SocksProxyConstants.IPV6_ADDRESS_TYPE;
            } else if (adr.getAddress() instanceof Inet4Address) {
                len += 4;
                addressType = SocksProxyConstants.IPV4_ADDRESS_TYPE;
            }
        } else {
            host = request.getHost() != null ? request.getHost().getBytes("ASCII") : null;
            //The proxy will take care of the destination in Socks5
            if(host == null && adr != null){
                host = adr.getHostName().getBytes("ASCII");
            }
            if (host != null) {
                len += 1 + host.length;
                addressType = SocksProxyConstants.DOMAIN_NAME_ADDRESS_TYPE;
            } else {
                throw new IllegalArgumentException("SocksProxyRequest object " + "has no suitable endpoint information");
            }
        }
<...>
    }

Re: Bug in Mina2.0.7 with SOCKS5 Proxy

Posted by Jeff MAURY <je...@jeffmaury.com>.
Can you open a JIRA for this ?

Thanks
Jeff

On Fri, Sep 26, 2014 at 9:57 AM, Michael Reinecke <
michael.reinecke@achelos.de> wrote:

> Hello devs,
>
> we are using Mina 2.0.7 to access an server through an Socks5 proxy. This
> worked fine as long as we use a direct IP address of the endpoint, but once
> we use the computer name, a nullpointer exception would occur. I searched
> through the source code and found the cause.
> If Java can not resolve the computer name, then the handler will switch to
> the else branch, which tries to access the host value from the request. But
> to construct the Socks5 Request, you HAVE to set an INetAddress and CAN NOT
> set the host directly.
> One feature of Socks5 is the ability to resolve the hostname by the proxy
> which may not be resolvable by others and therefor it is not required to
> resolve the name on our side. So the fastest way to fix this was to add the
> green code in the else branch.
>
> I am sure there are smarter ways to handle this problem, like extracting
> the host name in the SocksProxyRequest constructor and set it to the host
> variable. But as far as I do not know the complete infrastructure of MINA
> and the resulting consequences, I used this approach ;).
>
> Yours,
> Michael Reinecke
>
> <...>
> SocksProxyRequest  soxx = new SocksProxyRequest(
>
>                     SocksProxyConstants.SOCKS_VERSION_5,
>
>                     SocksProxyConstants.ESTABLISH_TCPIP_STREAM,
>
>                     new InetSocketAddress("endpoint-name", 666),
>
>                     "username");
> <...>
>
>
> package org.apache.mina.proxy.handlers.socks;
> <...>
> public class Socks5LogicHandler extends AbstractSocksLogicHandler {
> <...>
>     private IoBuffer encodeProxyRequestPacket(final SocksProxyRequest
> request) throws UnsupportedEncodingException {
>         int len = 6;
>         InetSocketAddress adr = request.getEndpointAddress();
>         byte addressType = 0;
>         byte[] host = null;
>
>         if (adr != null && !adr.isUnresolved()) {
>             if (adr.getAddress() instanceof Inet6Address) {
>                 len += 16;
>                 addressType = SocksProxyConstants.IPV6_ADDRESS_TYPE;
>             } else if (adr.getAddress() instanceof Inet4Address) {
>                 len += 4;
>                 addressType = SocksProxyConstants.IPV4_ADDRESS_TYPE;
>             }
>         } else {
>             host = request.getHost() != null ?
> request.getHost().getBytes("ASCII") : null;
>             //The proxy will take care of the destination in Socks5
>             if(host == null && adr != null){
>                 host = adr.getHostName().getBytes("ASCII");
>             }
>             if (host != null) {
>                 len += 1 + host.length;
>                 addressType = SocksProxyConstants.DOMAIN_NAME_ADDRESS_TYPE;
>             } else {
>                 throw new IllegalArgumentException("SocksProxyRequest
> object " + "has no suitable endpoint information");
>             }
>         }
> <...>
>     }
>



-- 
Jeff MAURY


"Legacy code" often differs from its suggested alternative by actually
working and scaling.
 - Bjarne Stroustrup

http://www.jeffmaury.com
http://riadiscuss.jeffmaury.com
http://www.twitter.com/jeffmaury