tags:

views:

48

answers:

1

Hi, I've written the following code to (successfully) connect to a socks5 proxy.

I send a user/pw auth and get an OK reply (0x00), but as soon as I tell the proxy to connect to whichever ip:port, it gives me 0x01 (general error).

Socket socket5_proxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint proxyEndPoint = new IPEndPoint(IPAddress.Parse("111.111.111.111"), 1080); // proxy ip, port. fake for posting purposes.
socket5_proxy.Connect(proxyEndPoint);
byte[] init_socks_command = new byte[4];
init_socks_command[0] = 0x05;
init_socks_command[1] = 0x02;
init_socks_command[2] = 0x00;
init_socks_command[3] = 0x02;
socket5_proxy.Send(init_socks_command);
byte[] socket_response = new byte[2];
int bytes_recieved = socket5_proxy.Receive(socket_response, 2, SocketFlags.None);

if (socket_response[1] == 0x02)
{
    byte[] temp_bytes;
    string socks5_user = "foo";
    string socks5_pass = "bar";
    byte[] auth_socks_command = new byte[3 + socks5_user.Length + socks5_pass.Length];
    auth_socks_command[0] = 0x05;
    auth_socks_command[1] = Convert.ToByte(socks5_user.Length);
    temp_bytes = Encoding.Default.GetBytes(socks5_user);
    temp_bytes.CopyTo(auth_socks_command, 2);
    auth_socks_command[2 + socks5_user.Length] = Convert.ToByte(socks5_pass.Length);
    temp_bytes = Encoding.Default.GetBytes(socks5_pass);
    temp_bytes.CopyTo(auth_socks_command, 3 + socks5_user.Length);
    socket5_proxy.Send(auth_socks_command);
    socket5_proxy.Receive(socket_response, 2, SocketFlags.None);
    if (socket_response[1] != 0x00)
        return;
    byte[] connect_socks_command = new byte[10];
    connect_socks_command[0] = 0x05;
    connect_socks_command[1] = 0x01; // streaming
    connect_socks_command[2] = 0x00;
    connect_socks_command[3] = 0x01; // ipv4
    temp_bytes = IPAddress.Parse("222.222.222.222").GetAddressBytes(); // target connection. fake ip, obviously
    temp_bytes.CopyTo(connect_socks_command, 4);
    byte[] portBytes = BitConverter.GetBytes(3333);
    connect_socks_command[8] = portBytes[0];
    connect_socks_command[9] = portBytes[1];
    socket5_proxy.Send(connect_socks_command);
    socket5_proxy.Receive(socket_response);
    if (socket_response[1] != 0x00)
        MessageBox.Show("Damn it"); // I always end here, 0x01

I've used this as a reference: http://en.wikipedia.org/wiki/SOCKS#SOCKS_5

Have I completely misunderstood something here? How I see it, I can connect to the socks5 fine. I can authenticate fine. But I/the proxy can't "do" anything?

  1. Yes, I know the proxy works.
  2. Yes, the target ip is available and yes the target port is open/responsive.
  3. I get 0x01 no matter what I try to connect to.

Any help is VERY MUCH appreciated!

Thanks,

  • Chuck
A: 

You might be getting bitten by endianness. Is BitConverter.GetBytes returning you the right bytes, for instance? Did you step through it and check if your byte arrays contain what you expect them to?

That looks like little endian, and networking-related things usually use big endian. BitConverter always uses system endianness, so you'll have to reverse bytes by hand if you're running on a little endian system (which you would seem to be doing). BitConverter.IsLittleEndian will tell you whether your system is little endian or not.

Also, it'd be a good idea to cast your value to short, e.g. BigConverter.GetBytes((short)3333). That way you'll get just the two bytes you need.

Matti Virkkunen
Good point. Can't say I wasn't suspicious of "endians" since I've never worked with them before. If we say port is 3333, then it gives: 5, 13, 0, 0. I'm not sure if that is right or wrong?
Chuck
13*256 + 5 = 3333, so I suppose it is right.
Chuck
Yes, however the least significant byte is first, and network protocols generally have the most significant byte first (big endian). I can't say I checked the SOCKS5 specs though, but I'd suspect it sticks with the unwritten standard of using big endian.
Matti Virkkunen
You're absolutely right! Thank you so much, Matti! You just saved me a lot of time. Happy Easter :)
Chuck