GNU.WIKI: The GNU/Linux Knowledge Base

  [HOME] [PHP Manual] [HowTo] [ABS] [MAN1] [MAN2] [MAN3] [MAN4] [MAN5] [MAN6] [MAN7] [MAN8] [MAN9]

  [0-9] [Aa] [Bb] [Cc] [Dd] [Ee] [Ff] [Gg] [Hh] [Ii] [Jj] [Kk] [Ll] [Mm] [Nn] [Oo] [Pp] [Qq] [Rr] [Ss] [Tt] [Uu] [Vv] [Ww] [Xx] [Yy] [Zz]


NAME

       IO::Socket::Socks - Provides a way to create socks client or server
       both 4 and 5 version.

SYNOPSIS

   Client
         use IO::Socket::Socks;

         my $socks = new IO::Socket::Socks(ProxyAddr=>"proxy host",
                                           ProxyPort=>"proxy port",
                                           ConnectAddr=>"remote host",
                                           ConnectPort=>"remote port",
                                          );

         print $socks "foo
";

         $socks->close();

   Server
         use IO::Socket::Socks ':constants';

         my $socks_server = new IO::Socket::Socks(ProxyAddr=>"localhost",
                                                  ProxyPort=>"8000",
                                                  Listen=>1,
                                                  UserAuth=>\&auth,
                                                  RequireAuth=>1
                                                 );

         my $select = new IO::Select($socks_server);

         while(1)
         {
             if ($select->can_read())
             {
                 my $client = $socks_server->accept();

                 if (!defined($client))
                 {
                     print "ERROR: $SOCKS_ERROR
";
                     next;
                 }

                 my $command = $client->command();
                 if ($command->[0] == CMD_CONNECT)
                 {
                     # Handle the CONNECT
                     $client->command_reply(REPLY_SUCCESS, addr, port);
                 }

                 ...
                 #read from the client and send to the CONNECT address
                 ...

                 $client->close();
             }
         }

         sub auth
         {
             my $user = shift;
             my $pass = shift;

             return 1 if (($user eq "foo") && ($pass eq "bar"));
             return 0;
         }

DESCRIPTION

       IO::Socket::Socks connects to a SOCKS proxy, tells it to open a
       connection to a remote host/port when the object is created.  The
       object you receive can be used directly as a socket for sending and
       receiving data from the remote host. In addition to create socks client
       this module could be used to create socks server. See examples below.

EXAMPLES

       For complete examples of socks 4/5 client and server see `examples'
       subdirectory in the distribution.

METHODS

   Socks Client
       new( %cfg )

       new_from_socket($socket, %cfg)

       new_from_fd($socket, %cfg)

       Creates a new IO::Socket::Socks client object.  new_from_socket() is
       the same as new(), but allows one to create object from an existing
       socket (new_from_fd is new_from_socket alias).  Both takes the
       following config hash:

         SocksVersion => 4 or 5. Default is 5

         Timeout => connect/accept timeout

         Blocking => Since IO::Socket::Socks version 0.5 you can perform non-blocking connect/bind by
                     passing false value for this option. Default is true - blocking. See ready()
                     below for more details.

         SocksResolve => resolve host name to ip by proxy server or
                         not (will resolve by client). This
                         overrides value of $SOCKS4_RESOLVE or $SOCKS5_RESOLVE
                         variable. Boolean.

         SocksDebug => This will cause all of the SOCKS traffic to
                       be presented on the command line in a form
                       similar to the tables in the RFCs. This overrides value
                       of $SOCKS_DEBUG variable. Boolean.

         ProxyAddr => Hostname of the proxy

         ProxyPort => Port of the proxy

         ConnectAddr => Hostname of the remote machine

         ConnectPort => Port of the remote machine

         BindAddr => Hostname of the remote machine which will
                     connect to the proxy server after bind request

         BindPort => Port of the remote machine which will
                     connect to the proxy server after bind request

         UdpAddr => Associate UDP socket on the server with this client
                    hostname

         UdpPort => Associate UDP socket on the server with this client
                    port

         AuthType => What kind of authentication to support:
                     none       - no authentication (default)
                     userpass  - Username/Password. For socks5
                     proxy only.

         RequireAuth => Do not send ANON as a valid auth mechanism.
                        For socks5 proxy only

         Username => For socks5 if AuthType is set to userpass, then
                     you must provide a username. For socks4 proxy with
                     this option you can specify userid.

         Password => If AuthType is set to userpass, then you must
                     provide a password. For socks5 proxy only.

       The following options should be specified:

         ProxyAddr and ProxyPort
         ConnectAddr and ConnectPort or BindAddr and BindPort or UdpAddr and UdpPort

       Other options are facultative.

        ready( )

       Returns true when socket becomes ready to transfer data (socks
       handshake done), false otherwise. This is useful for non-blocking
       connect/bind. When this method returns false value you can determine
       what socks handshake need for with $SOCKS_ERROR variable. It may need
       for read, then $SOCKS_ERROR will be SOCKS_WANT_READ or need for write,
       then it will be SOCKS_WANT_WRITE.

       Example:

           use IO::Socket::Socks;
           use IO::Select;

           my $sock = IO::Socket::Socks->new(
               ProxyAddr => 'localhost', ProxyPort => 1080, ConnectAddr => 'mail.com', ConnectPort => 80, Blocking => 0
           ) or die $SOCKS_ERROR;

           my $sel = IO::Select->new($sock);
           until ($sock->ready) {
               if ($SOCKS_ERROR == SOCKS_WANT_READ) {
                   $sel->can_read();
               }
               elsif ($SOCKS_ERROR == SOCKS_WANT_WRITE) {
                   $sel->can_write();
               }
               else {
                   die $SOCKS_ERROR;
               }
           }

           # you may want to return socket to blocking state by $sock->blocking(1)
           $sock->syswrite("I am ready");

        accept( )

       Accept an incoming connection after bind request. On failed returns
       undef.  On success returns socket. No new socket created, returned
       socket is same on which this method was called. Because accept(2) is
       not invoked on the client side, socks server calls accept(2) and
       proxify all traffic via socket opened by client bind request. You can
       call accept only once on IO::Socket::Socks client socket.

        command( %cfg )

       Allows one to execute socks command on already opened socket. Thus you
       can create socks chain. For example see "EXAMPLES" section.

       %cfg is like hash in the constructor. Only options listed below makes
       sence:

         ConnectAddr
         ConnectPort
         BindAddr
         BindPort
         UdpAddr
         UdpPort
         SocksVersion
         SocksDebug
         SocksResolve
         AuthType
         RequireAuth
         Username
         Password
         AuthMethods

       Values of the other options (Timeout for example) inherited from the
       constructor.  Options like ProxyAddr and ProxyPort are not included.

        dst( )

       Return (host, port) of the remote host after connect/accept or socks
       server (host, port) after bind/udpassoc.

   Socks Server
       new( %cfg )

       new_from_socket($socket, %cfg)

       new_from_fd($socket, %cfg)

       Creates a new IO::Socket::Socks server object. new_from_socket() is the
       same as new(), but allows one to create object from an existing socket
       (new_from_fd is new_from_socket alias).  Both takes the following
       config hash:

         SocksVersion => 4 for socks v4, 5 for socks v5. Default is 5

         Timeout => Timeout value for various operations

         Blocking => Since IO::Socket::Socks version 0.6 you can perform non-blocking accept by
                     passing false value for this option. Default is true - blocking. See ready()
                     below for more details.

         SocksResolve => For socks v5: return destination address to the client
                         in form of 4 bytes if true, otherwise in form of host
                         length and host name.
                         For socks v4: allow use socks4a protocol extension if
                         true and not otherwise.
                         This overrides value of $SOCKS4_RESOLVE or $SOCKS5_RESOLVE.

         SocksDebug => This will cause all of the SOCKS traffic to
                       be presented on the command line in a form
                       similar to the tables in the RFCs. This overrides value
                       of $SOCKS_DEBUG variable. Boolean.

         ProxyAddr => Local host bind address

         ProxyPort => Local host bind port

         UserAuth => Reference to a function that returns 1 if client
                     allowed to use socks server, 0 otherwise. For
                     socks5 proxy it takes login and password as
                     arguments. For socks4 argument is userid.

         RequireAuth => Not allow anonymous access for socks5 proxy.

         Listen => Same as IO::Socket::INET listen option. Should be
                   specified as number > 0.

       The following options should be specified:

         Listen
         ProxyAddr
         ProxyPort

       Other options are facultative.

       accept( )

       Accept an incoming connection and return a new IO::Socket::Socks object
       that represents that connection.  You must call command() on this to
       find out what the incoming connection wants you to do, and then call
       command_reply() to send back the reply.

       ready( )

       After non-blocking accept you will get new client socket object, which
       may be not ready to transfer data (if socks handshake is not done yet).
       ready() will return true value when handshake will be done successfully
       and false otherwise. Note, socket returned by accept() call will be
       always in blocking mode. So if your program can't block you should set
       non-blocking mode for this socket before ready() call:
       $socket->blocking(0).  When ready() returns false value you can
       determine what socks handshake needs for with $SOCKS_ERROR variable. It
       may need for read, then $SOCKS_ERROR will be SOCKS_WANT_READ or need
       for write, then it will be SOCKS_WANT_WRITE.

       Example:

         use IO::Socket::Socks;
         use IO::Select;

         my $server = IO::Socket::Socks->new(ProxyAddr => 'localhost', ProxyPort => 1080, Blocking => 0)
             or die $@;
         my $select = IO::Select->new($server);
         $select->can_read(); # wait for client

         my $client = $server->accept()
           or die "accept(): $! ($SOCKS_ERROR)";
         $client->blocking(0); # !!!
         $select->add($client);
         $select->remove($server); # no more connections

         while (1) {
             if ($client->ready) {
                 my $command = $client->command;

                 ... # do client command

                 $client->command_reply(IO::Socket::Socks::REPLY_SUCCESS, $command->[1], $command->[2]);

                 ... # transfer traffic

                 last;
             }
             elsif ($SOCKS_ERROR == SOCKS_WANT_READ) {
                 $select->can_read();
             }
             elsif ($SOCKS_ERROR == SOCKS_WANT_WRITE) {
                 $select->can_write();
             }
             else {
                 die "Unexpected error: $SOCKS_ERROR";
             }
         }

       command( )

       After you call accept() the client has sent the command they want you
       to process.  This function should be called on the socket returned by
       accept(). It returns a reference to an array with the following format:

         [ COMMAND, ADDRESS, PORT, ADDRESS TYPE ]

       command_reply( REPLY CODE, ADDRESS, PORT )

       After you call command() the client needs to be told what the result
       is.  The REPLY CODE is one of the constants as follows (integer value):

         For socks v4
         REQUEST_GRANTED(90): request granted
         REQUEST_FAILED(91): request rejected or failed
         REQUEST_REJECTED_IDENTD(92): request rejected becasue SOCKS server cannot connect to identd on the client
         REQUEST_REJECTED_USERID(93): request rejected because the client program and identd report different user-ids

         For socks v5
         REPLY_SUCCESS(0): Success
         REPLY_GENERAL_FAILURE(1): General Failure
         REPLY_CONN_NOT_ALLOWED(2): Connection Not Allowed
         REPLY_NETWORK_UNREACHABLE(3): Network Unreachable
         REPLY_HOST_UNREACHABLE(4): Host Unreachable
         REPLY_CONN_REFUSED(5): Connection Refused
         REPLY_TTL_EXPIRED(6): TTL Expired
         REPLY_CMD_NOT_SUPPORTED(7): Command Not Supported
         REPLY_ADDR_NOT_SUPPORTED(8): Address Not Supported

       HOST and PORT are the resulting host and port that you use for the
       command.

VARIABLES

   $SOCKS_ERROR
       This scalar behaves like $! in that if undef is returned. $SOCKS_ERROR
       is IO::Socket::Socks::Error object with some overloaded operators. In
       string context this variable should contain a string reason for the
       error. In numeric context it contains error code.

   $SOCKS4_RESOLVE
       If this variable has true value resolving of host names will be done by
       proxy server, otherwise resolving will be done locally. Resolving host
       by socks proxy version 4 is extension to the protocol also known as
       socks4a. So, only socks4a proxy  supports resolving of hostnames.
       Default value of this variable is false. This variable is not
       importable.  See also `SocksResolve' parameter in the constructor.

   $SOCKS5_RESOLVE
       If this variable has true value resolving of host names will be done by
       proxy server, otherwise resolving will be done locally. Note: some
       bugous socks5 servers doesn't support resolving of host names. Default
       value is true. This variable is not importable.  See also
       `SocksResolve' parameter in the constructor.

   $SOCKS_DEBUG
       Default value is $ENV{SOCKS_DEBUG}. If this variable has true value and
       no SocksDebug option in the constructor specified, then SocksDebug will
       has true value. This variable is not importable.

CONSTANTS

       The following constants could be imported manually or using
       `:constants' tag:

         SOCKS5_VER
         SOCKS4_VER
         ADDR_IPV4
         ADDR_DOMAINNAME
         ADDR_IPV6
         CMD_CONNECT
         CMD_BIND
         CMD_UDPASSOC
         AUTHMECH_ANON
         AUTHMECH_USERPASS
         AUTHMECH_INVALID
         AUTHREPLY_SUCCESS
         AUTHREPLY_FAILURE
         ISS_UNKNOWN_ADDRESS
         ISS_BAD_VERSION
         REPLY_SUCCESS
         REPLY_GENERAL_FAILURE
         REPLY_CONN_NOT_ALLOWED
         REPLY_NETWORK_UNREACHABLE
         REPLY_HOST_UNREACHABLE
         REPLY_CONN_REFUSED
         REPLY_TTL_EXPIRED
         REPLY_CMD_NOT_SUPPORTED
         REPLY_ADDR_NOT_SUPPORTED
         REQUEST_GRANTED
         REQUEST_FAILED
         REQUEST_REJECTED_IDENTD
         REQUEST_REJECTED_USERID
         SOCKS_WANT_READ
         SOCKS_WANT_WRITE
         ESOCKSPROTO

       SOCKS_WANT_READ, SOCKS_WANT_WRITE and ESOCKSPROTO are imported by
       default.

FAQ

       How to determine is connection to socks server (client accept) failed
       or some protocol error occurred?
           You can check $! variable. If $! == ESOCKSPROTO constant, then it
           was error in the protocol. Error description could be found in
           $SOCKS_ERROR.

       How to determine which error in the protocol occurred?
           You should compare $SOCKS_ERROR with constants below:

             AUTHMECH_INVALID
             AUTHREPLY_FAILURE
             ISS_UNKNOWN_ADDRESS # address type sent by client/server not supported by I::S::S
             ISS_BAD_VERSION     # socks version sent by client/server != specified version
             REPLY_GENERAL_FAILURE
             REPLY_CONN_NOT_ALLOWED
             REPLY_NETWORK_UNREACHABLE
             REPLY_HOST_UNREACHABLE
             REPLY_CONN_REFUSED
             REPLY_TTL_EXPIRED
             REPLY_CMD_NOT_SUPPORTED
             REPLY_ADDR_NOT_SUPPORTED
             REQUEST_FAILED
             REQUEST_REJECTED_IDENTD
             REQUEST_REJECTED_USERID

BUGS

       The following options are not implemented:

       GSSAPI authentication
       UDP server side support
       IPV6 support

       Patches are welcome.

SEE ALSO

       IO::Socket::Socks::Wrapper

AUTHOR

       Original author is Ryan Eatmon

       Now maintained by Oleg G <oleg@cpan.org>

COPYRIGHT

       This module is free software, you can redistribute it and/or modify it
       under the terms of LGPL.



  All copyrights belong to their respective owners. Other content (c) 2014-2018, GNU.WIKI. Please report site errors to webmaster@gnu.wiki.
Page load time: 0.090 seconds. Last modified: November 04 2018 12:49:43.