[go: up one dir, main page]

File: socks.pl

package info (click to toggle)
sirc 2.211-9.1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, lenny, squeeze
  • size: 476 kB
  • ctags: 420
  • sloc: perl: 5,330; ansic: 1,200; sh: 855; makefile: 78
file content (143 lines) | stat: -rw-r--r-- 5,023 bytes parent folder | download | duplicates (4)
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");