简体   繁体   中英

PHP socket pack data

<?php

$desthost = "imap.gmail.com";
$port     = 993;
$conflag  = STREAM_CLIENT_CONNECT;

try
{
    $socket = stream_socket_client( "tcp://host:port", $errno, $errstr, 15, $conflag );

    fwrite( $socket, pack( "C3", 0x05, 0x01, 0x00 ) );
    $server_status = fread( $socket, 2048 );
    if ( $server_status == pack( "C2", 0x05, 0x00 ) )
    {
        // Connection succeeded
    }
    else
    {
        die( "SOCKS Server does not support this version and/or authentication method of SOCKS.\r\n" );
    }

    fwrite( $socket, pack( "C5", 0x05, 0x01, 0x00, 0x03, strlen( $desthost ) ) . $desthost . pack( "n", $port ) );
    $server_buffer = fread( $socket, 10 );

    var_dump(unpack("C5", $server_buffer));


    if ( ord( $server_buffer[0] ) == 5 && ord( $server_buffer[1] ) == 0 && ord( $server_buffer[2] ) == 0 )
    {
        // Connection succeeded
    }
    else
    {
        die( "The SOCKS server failed to connect to the specificed host and port. ( " . $desthost . ":" . $port . " )\r\n" );
    }

    stream_socket_enable_crypto( $socket, TRUE, STREAM_CRYPTO_METHOD_SSLv23_CLIENT );
}
catch ( Exception $e )
{
    die( $e->getMessage() );
}

if ( $socket === FALSE )
{
    die( "bad socket" );
}

//fwrite( $socket, "GET /\n" );
echo fread( $socket, 8192 );

This code connect to proxy and connect to imap via proxy. I can't understand how this pack works ?

what does mean fwrite( $socket, pack( "C3", 0x05, 0x01, 0x00 ) ); ?

and what does mean next code ?

fwrite( $socket, pack( "C5", 0x05, 0x01, 0x00, 0x03, strlen( $desthost ) ) . $desthost . pack( "n", $port ) );

I think it's "CONNECT host:port" ? Can somebody please explain me about that ? When I try to send command "0000001 LOGIN login pass" imap returns me error bad syntax. Seems I should pack this command or something like this.

There is an overview of the SOCKS protocol at https://en.wikipedia.org/wiki/SOCKS .

This is some dirty code to quickly connect to a SOCKS proxy.

fwrite( $socket, pack( "C3", 0x05, 0x01, 0x00 ) ); means sends the bytes 5, 1, and 0.

In an initial connection request this means "SOCKS version 5 ", 1 authentication method supported, and that one authentication method is No authentication .

if ( $server_status == pack( "C2", 0x05, 0x00 ) ) is checking that the server responded with "Socks version 5 , Use No Authentication ".

fwrite( $socket, pack( "C5", 0x05, 0x01, 0x00, 0x03, strlen( $desthost ) ) . $desthost . pack( "n", $port ) ); is sending a connection request:

  • 5 (SOCKS version 5)
  • 1 (TCP connection request)
  • 0 (Reserved)
  • 3 (Use a domain name)
  • length of domain name
  • The domain name
  • port number in network byte order

if ( ord( $server_buffer[0] ) == 5 && ord( $server_buffer[1] ) == 0 && ord( $server_buffer[2] ) == 0 ) is checking the server response.

  • 5 Socks version 5
  • 0 Request granted
  • 0 Reserved byte.

There are more fields but it's ignoring them, and hoping that they fit exactly into 10 bytes, which may not be true if it returns back the domain address or an IPv6 address.

At this point, the connection to the remote server is established. It then upgrades it to TLS, and should otherwise work as expected.

For your IMAP commands after this point, make sure they end in "\\r\\n". You don't actually show your code for this, so we can't help debug it.

SOCKS5 is formally specified in RFC1928 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM