#!/usr/bin/perl #!/usr/local/bin/perl # # vncxfer: A CGI script to set up TCP redirection between a VNC Viewer # and VNC Server using the Web Server as a relay point. # # Copy this to a place on a website where CGI scripts will be run. # e.g. http://somesite.com/cgi-bin/vncxfer # # One user goes to the the above URL and chooses a session name and then # clicks "Submit". That starts up a helper program on the web server to # act as a relay. # # The other user does the same, using the SAME session name. # # The page that is returned to them tells them the port number and VNC # Host:Display to use in their viewer or VNC server. # # The VNC Server makes a reverse VNC connection to the relay point. # e.g. somesite:com:5950 # # The VNC Viewer makes a normal VNC connection to the relay point. # e.g. vncviewer somesite:com:50 # # Unfortunately most Web servers will not allow this sort of thing: # # 1) They forbid running CGI programs that run as daemons that listen # on TCP ports for incoming connections. # # 2) The firewall configuration of the webserver disallows connections # to the "session" ports, e.g. 5950, etc. # # James B - modified to work with mongoose, as vncxfer.pl # Put here a list of ports to use for transfer sessions. The Web server's # firewall configuration MUST NOT block this port(s). # my @allowed_ports = qw( 5955 5956 5957 5958 5959 5960 ); # Maximum time in seconds to wait for both the VNC Viewer # and VNC Server to connect: # my $max_wait = 300; # The form action="..." program, it may need to be "/cgi-bin/vncxfer", etc. # my $program = "vncxfer.pl"; ########################################################################## # no config needed below here. use POSIX qw(setsid); my $oldsockets = 0; if (! $oldsockets) { use IO::Socket::INET; } my $oldfh = 'LISTEN000'; if (@ARGV && $ARGV[0] =~ /^vncxfer:/) { # Started in session helper mode: helper($ARGV[0]); exit 0; } # Parse CGI request: # my $request; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $request, $ENV{'CONTENT_LENGTH'}); } elsif ($ENV{'REQUEST_METHOD'} eq "GET" ) { $request = $ENV{'QUERY_STRING'}; } else { $request = $ARGV[0]; } my %request = &url_decode(split(/[&=]/, $request)); # html for top and bottom: # my $htop = "
\n"; my $hbot = "\n"; select(STDERR); $| = 1; select(STDOUT); $| = 1; # content-type: # print STDOUT "Content-Type: text/html\r\n"; # see if session is set: # my $session = ''; if (exists $request{session}) { $session = $request{session}; } $session =~ s/\W//g; # word characters only. if ($session eq '') { # No session, show the create-a-session form: print STDOUT "\r\n"; print_form(); exit 0; } # determine hostnames and IP addresses: # my $server = $ENV{HTTP_HOST}; $server =~ s/:\d+//g; my ($nm, $aliases, $type, $len, @addrs) = gethostbyname($server); my $server_ip = join('.', unpack('C4', $addrs[0])); my $sport = $ENV{SERVER_PORT}; # find an existing session, or start one up: # my $port = find_or_start_session($session); if ($port ne '') { # print some http header lines indicating the port: # my $disp = $port - 5900; print STDOUT "VNC-Host-Display: $server:$disp\r\n"; print STDOUT "VNC-IP-Display: $server_ip:$disp\r\n"; print STDOUT "VNC-Host-Port: $server:$port\r\n"; print STDOUT "VNC-IP-Port: $server_ip:$port\r\n"; print STDOUT "\r\n"; # print connection info to the browser: # print STDOUT <
Your VNC session name is: $session
Your VNC session port is: $port
Both VNC Viewer and Server must connect within $max_wait seconds.
For the VNC Viewer, use either of these as VNC Host displays:
$server:$disp
$server_ip:$disp
E.g.:
vncviewer $server_ip:$disp
For the VNC Server, it needs to do a reverse connection to either of these:
$server:$port
$server_ip:$port
E.g.:
x11vnc -connect $server_ip:$port$hbot END } else { print STDOUT "\r\n"; # whoops: # print STDOUT <
A Free VNC Port could not be found or the helper could not be started!
$hbot
END
}
exit 0;
#######################################################################
sub url_decode {
foreach (@_) {
tr/+/ /;
s/%(..)/pack("c",hex($1))/ge;
}
@_;
}
# starting form:
#
sub print_form {
print STDOUT <
To start a VNC Transfer agent for you, enter a name for your session: