1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
# socks.pl, by Roger Espel Llima <odar@pobox.com>
#
# This script makes sirc talk through SOCKS proxies with the SOCKSv4
# protocol. sirc must be version 2.2 or greater.
#
# This script must be loaded before attempting to connect to the server,
# so in a system-wide SOCKSified sirc installation, it is best to add
# the line &load("socks.pl"); to the system's sircrc.pl.
#
# Before using sirc through a SOCKS proxy, the user must set the
# environment variable SOCKS_SERVER to the address of the SOCKS proxy
# (the firewall). This can be an IP address or a hostname, assuming
# that the local host is able to resolve the it. If the proxy is
# running on a port other than 1080, it must be given in the environment
# variable SOCKS_PORT.
#
# If the local host cannot resolve names outside of the firewalled
# network, *and* if your SOCKS server implements the SOCKS4A extension
# of the SOCKS protocol (which lets the local client pass hostnames
# instead of resolved addresses to the SOCKS proxy), then set the
# environment variable SOCKS_DNS to 1, and sirc will try to use it.
#
# If the SOCKSified sirc is able to talk to your SOCKS host, and has
# sufficient permissions for the connections, you should be able to
# connect to servers and accept DCC CHATs and DCC SENDs.
#
# To be able to send out DCC CHAT and SEND requests, the SOCKS protocol
# requires that you specify the IP address of the remote host that will
# connect to you. This script provides the command
# /setrem <hostname or IP> for this; use it before the DCC command.
#
# Since the remote host will generally be the same as the one appearing
# in the remote user's WHOIS, you can use the shortcuts /sdc <nick>
# and /sds <nick> <filename> to automatically look up the remote host
# and initiate a DCC CHAT or DCC SEND.
$add_ons.="+socks.pl" if $add_ons !~ /socks/;
$socks_server=&resolve($ENV{"SOCKS_SERVER"});
$socks_dns=defined($ENV{"SOCKS_DNS"});
$socks_userid=(getpwuid($<))[0];
$socks_port=$ENV{"SOCKS_PORT"} || 1080;
sub connect {
$_[0]=&newfh;
local($fh, $host, $port)=@_;
local($adr, $otherend, $request, $answer, $xtra)=&resolve($host);
&tell("*\cbE\cb* SOCKS_SERVER not set or invalid"), return 0
unless $socks_server;
$lastport=$port;
if (!$adr) {
&tell("*\cbE\cb* Hostname `$host' not found"), return 0 if !$socks_dns;
$xtra=$host."\c@";
$adr=pack("x3 c", 1);
} else {
$xtra='';
}
$request=pack("c c n a4 a* x a*", 4, 1, $port, $adr, $socks_userid, $xtra);
$otherend=pack("S n a4 x8", &AF_INET, $socks_port, $socks_server);
&print("*\cbE\cb* Out of file descriptors"), return 0
unless socket($fh, &PF_INET, &SOCK_STREAM, 0);
$trysock=$fh;
$SIG{'QUIT'}='sigquit';
if (!connect($fh, $otherend) ||
syswrite($fh, $request, length($request)) != length($request) ||
sysread($fh, $answer, 8) != 8 ||
$answer !~ /^\000Z/) {
&print("*\cbE\cb* Can't connect to host: " . ($! ? $! : "SOCKS error"));
close $fh;
$SIG{'QUIT'}='IGNORE';
return 0;
}
$SIG{'QUIT'}='IGNORE';
$bindaddr=$socks_server;
select($fh); $|=1; select(STDOUT);
return 1;
}
sub listen {
$_[0]=&newfh;
local($fh)=@_;
&tell("*\cbE\cb* SOCKS_SERVER not set or invalid"), return 0
unless $socks_server;
&tell("*\cbE\cb* Remote host not specified"), return 0 unless $remote_host;
local($adr, $otherend, $request, $answer, $ip, $port, $xtra)=&resolve($remote_host);
if (!$adr) {
&tell("*\cbE\cb* Hostname `$remote_host' not found"), return 0
if !$socks_dns;
$xtra=$remote_host."\c@";
$adr=pack("x3 c", 1);
} else {
$xtra='';
}
&tell("*\cbE\cb* Out of file descriptors"), return 0
unless socket($fh, &PF_INET, &SOCK_STREAM, 0);
$request=pack("c c n a4 a* x a*", 4, 2, $lastport, $adr, $socks_userid, $xtra);
$otherend=pack("S n a4 x8", &AF_INET, $socks_port, $socks_server);
$trysock=$fh;
$SIG{'QUIT'}='sigquit';
if (!connect($fh, $otherend) ||
syswrite($fh, $request, length($request)) != length($request) ||
sysread($fh, $answer, 8) != 8 ||
$answer !~ /^\000Z/) {
&print("*\cbE\cb* Can't connect to host: " . ($! ? $! : "SOCKS error"));
close $fh;
$SIG{'QUIT'}='IGNORE';
return 0;
}
$SIG{'QUIT'}='IGNORE';
($port, $ip)=(unpack("c c n a4", $answer))[2,3];
$bindaddr=$ip || $socks_server;
select($fh); $|=1; select(STDOUT);
return $port;
}
sub accept {
local($answer);
$_[0]=$_[1];
&tell("*\cbE\cb* SOCKS error"), return 0
unless (sysread($_[0], $answer, 8) == 8 && $answer =~ /^\000Z/);
1;
}
sub cmd_setrem {
&getarg;
$remote_host=$newarg;
}
&addcmd("setrem");
sub cmd_sdc {
&getarg;
&tell("*\cbE\cb* I need an argument") if $newarg eq '';
&userhost($newarg, "\$remote_host=\$host; &docommand('/dcc chat $newarg');");
}
&addcmd("sdc");
sub cmd_sds {
&getarg;
&tell("*\cbE\cb* I need two arguments") if $newarg eq '' || $args eq '';
&userhost($newarg, "\$remote_host=\$host; &docommand('/dcc send $newarg $args');");
}
&addcmd("sds");
|