| IO-Socket-Socks documentation | view source | Contained in the IO-Socket-Socks distribution. |
IO::Socket::Socks - Provides a way to create socks client or server both 4 and 5 version.
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\n";
$socks->close();
use IO::Socket::Socks;
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\n";
next;
}
my $command = $client->command();
if ($command->[0] == 1) # CONNECT
{
# Handle the CONNECT
$client->command_reply(0, 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;
}
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.
For complete examples of socks 4/5 client and server see `examples' subdirectory in the distribution.
Creates a new IO::Socket::Socks client object. new_from_socket() is the same as new(), but allows to create object from an existing socket. 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.
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 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.
Allows 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.
Return (host, port) of the remote host after connect/accept or socks server (host, port) after bind/udpassoc.
Creates a new IO::Socket::Socks server object. new_from_socket() is the same as new(), but allows to create object from an existing socket. Both takes the following config hash:
SocksVersion => 4 for socks v4, 5 for socks v5. Default is 5
Timeout => Timeout value for various operations
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 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.
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, HOST, PORT ]
After you call command() the client needs to be told what the result is. The REPLY CODE is as follows (integer value):
For socks v4 90: request granted 91: request rejected or failed 92: request rejected becasue SOCKS server cannot connect to identd on the client 93: request rejected because the client program and identd report different user-ids For socks v5 0: Success 1: General Failure 2: Connection Not Allowed 3: Network Unreachable 4: Host Unreachable 5: Connection Refused 6: TTL Expired 7: Command Not Supported 8: Address Not Supported
You can also use module constans. See below. HOST and PORT are the resulting host and port that you use for the command.
This scalar behaves like $! in that if undef is returned, this variable should contain a string reason for the error. Imported by default.
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.
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.
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.
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 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
SOCKS_WANT_READ and SOCKS_WANT_WRITE are imported by default.
The following options are not implemented and not planned:
However patches are welcome.
Original author is Ryan Eatmon
Now maintained by Oleg G <oleg@cpan.org>
This module is free software, you can redistribute it and/or modify it under the terms of LGPL.
| IO-Socket-Socks documentation | view source | Contained in the IO-Socket-Socks distribution. |