Synchronize ssvnc 1.0.26. Improvements to perl scripts desktop.cgi, connect_switch and inet6to4.

pull/1/head
runge 14 years ago
parent 97540de56c
commit 91d0e2fd3a

@ -211,6 +211,7 @@ if (exists $ENV{CONNECT_SWITCH_PIDFILE}) {
# CONNECT_SWITCH_BUFSIZE
# CONNECT_SWITCH_LOGFILE
# CONNECT_SWITCH_PIDFILE
# CONNECT_SWITCH_MAX_CONNECTIONS
#
# You can also set these on the cmdline:
# connect_switch CONNECT_SWITCH_LISTEN=X CONNECT_SWITCH_ALLOW_FILE=Y ...
@ -335,6 +336,13 @@ if (exists $ENV{CONNECT_SWITCH_VERBOSE}) {
$verbose = $ENV{CONNECT_SWITCH_VERBOSE};
}
# zero means loop forever, positive value means exit after handling that
# many connections.
#
my $cmax = 0;
if (exists $ENV{CONNECT_SWITCH_MAX_CONNECTIONS}) {
$cmax = $ENV{CONNECT_SWITCH_MAX_CONNECTIONS};
}
#===========================================================================
@ -384,6 +392,10 @@ my $conn = 0;
while (1) {
$conn++;
if ($cmax > 0 && $conn > $cmax) {
print STDERR "last connection ($cmax)\n" if $verbose;
last;
}
print STDERR "listening for connection: $conn\n" if $verbose;
my ($client, $ip) = $listen_sock->accept();
if (! $client) {

@ -1,37 +1,188 @@
#!/usr/bin/perl
#
# desktop.cgi
##########################################################################
# desktop.cgi:
#
# This is an example CGI script to provide multi-user web access to
# x11vnc desktops. The user desktop sessions run in 'Xvfb' displays
# that are created automatically.
#
# This script should/must be served by an HTTPS (i.e. SSL) webserver,
# otherwise the unix and vnc passwords would be sent over the network
# unencrypted (see below to disable if you really want to.)
#
# The Java VNC Viewer applet connections are encrypted by SSL as well.
#
# You can use this script to provide unix users desktops available on
# demand via any Java enabled web browser. One could also use this for
# a special-purpose 'single application' service running in a minimal
# window manager.
#
# One example of a special-purpose application would be a scientific
# data visualization tool running on a server where the data is housed.
# To do this set $x11vnc_extra_opts = '-env FD_PROG=/path/to/app/launcher'
# where the program launches your special purpose application. A very
# simple example: '-env FD_PROG=/usr/bin/xclock'
#
#
# Depending on where you place this script, the user accesses the service
# with the URL:
#
# https://your.webserver.net/cgi-bin/desktop.cgi
#
# Then they login with their unix username and password to get their
# own desktop session.
#
# If the user has an existing desktop it is connected to directly,
# otherwise a new session is created inside an Xvfb display and then
# connected to by VNC.
#
# It is possible to do port redirection to other machines running SSL
# enabled VNC servers (see below.) This script does not start the VNC
# servers on the other machines, although with some extra rigging you
# should be able to do that as well.
#
# You can customize the login procedure to whatever you want by modifying
# this script, or by using ideas in this script write your own PHP,
# (for example), script.
#
##########################################################################
# Overriding default settings:
#
# If you want to override any settings in this script and do not
# want to edit this script create the assignments in a file named
# 'desktop.cgi.conf' in the same directory as desktop.cgi. It will be
# sourced after the defaults are set. The format of desktop.cgi.conf
# is simply perl statements that make the assignments.
#
# For example, if you put something like this in desktop.cgi.conf:
#
# $x11vnc = '/usr/local/bin/x11vnc';
#
# that will set the path to the x11vnc binary to that location. Look at
# the settings below for the other variables that you can modify, for
# example one could set $allowed_users_file.
#
##########################################################################
# x11vnc:
#
# An example cgi script to provide multi-user web access to x11vnc
# desktops. This script should/must be served by an HTTPS webserver,
# otherwise the unix and vnc passwords are sent over the network
# unencrypted (see below to disable)
# You need to install x11vnc or otherwise have it available. It is
# REQUIRED that you use x11vnc 0.9.10 or later. It won't work with
# earlier versions. See below the $x11vnc parameter that you can set
# to the full path to x11vnc.
#
##########################################################################
# Xvfb:
#
# Note that the x11vnc -create virtual desktop service used below requires
# that you install the 'Xvfb' program.
# that you install the 'Xvfb' program. On debian this is currently done
# via 'apt-get install xvfb'.
#
# If you are having trouble getting 'x11vnc -create' to work with this
# script (it can be tricky), try it manually and/or see the x11vnc FAQ
# links below.
#
##########################################################################
# Apache httpd:
#
# You should put this script in, say, a cgi-bin directory. Enable cgi
# scripts in your apache (or other httpd) config. For example, we have
# these lines (not commented):
#
# In httpd.conf:
#
# You should put this script in, say, a cgi-bin directory.
# ScriptAlias /cgi-bin/ "/dist/apache/2.0/cgi-bin/"
#
# <Directory "/dist/apache/2.0/cgi-bin">
# AllowOverride None
# Options None
# Order allow,deny
# Allow from all
# </Directory>
#
# and in ssl.conf:
#
# <Directory "/dist/apache/2.0/cgi-bin">
# SSLOptions +StdEnvVars
# </Directory>
#
# Do not be confused by the non-standard /dist/apache/2.0 apache
# installation location that we happen to use. Yours will be different.
#
# You can test that you have CGI scripts working properly with the
# 'test-cgi' and 'printenv' scripts apache provides.
#
# Copy this file (desktop.cgi) to /dist/apache/2.0/cgi-bin and then run
# 'chmod 755 ...' on it to make it executable.
#
##########################################################################
# Applet Jar files served by apache:
#
# You will *also* need to copy the x11vnc classes/ssl/UltraViewerSSL.jar
# file to the document root: /UltraViewerSSL.jar (or change the html
# at bottom.)
# file to the httpd DocumentRoot to be accessible by: /UltraViewerSSL.jar
# in a URL (or change $applet_jar below or the html in $applet_html if
# you want to use a different location.)
#
# This location is relative to the apache DocumentRoot 'htdocs' directory.
# For our (non-standard location installation) that meant we copied the
# file to:
#
# /dist/apache/2.0/htdocs/UltraViewerSSL.jar
#
# (your DocumentRoot directory will be different.)
#
# The VncViewer.jar (tightvnc) will also work, but you need to change
# the $applet_jar below. You can get these jar files from the x11vnc
# tarball from:
#
# http://www.karlrunge.com/x11vnc/#downloading
#
# This script requires x11vnc 0.9.10 or later.
#
# Each x11vnc server created for a login will listen on its own port (see
# below for port selection schemes.) Your firewall must let in these ports.
# It is difficult and not as reliable to do all of this through a single port;
# however, see the fixed port scheme find_free_port = 'fixed:5900' below.
# Note that the usage mode for this script is a different from regular
# 'x11vnc -http ...' usage where x11vnc acts as a mini web server and
# serves its own applet jars. We don't use that mode for this script.
# Apache (httpd) serves the jars.
#
# Note there are two SSL certificates involved that the user may be
#
##########################################################################
# Notes and Information:
#
# Each x11vnc server created for a user login will listen on its own port
# (see below for port selection schemes.) Your firewall must let in *ALL*
# of these ports (e.g. a port range, see below for the syntax.)
#
# It is also possible, although not as reliable, to do all of this through
# a single port, see the fixed port scheme $find_free_port = 'fixed:5910'
# below. This single port mode must be different from apache's port
# (usually 443 for https) and must also be allowed in by your firewall.
#
# Note: The fixed port scheme is DISABLED by default.
#
# It is also possible to have this script act as a vnc redirector to SSL
# enabled VNC servers running on *other* machines inside your firewall
# (presumably the users' desktops) See the $enable_port_redirection
# setting below. The user provides 'username@host:port' instead of just
# 'username' when she logs in. This script doesn't start VNC servers
# on those other machines, the servers must be running there already.
# (If you want this script to start them you will need to add it
# yourself.) It is possible to provide a host:port allow list to limit
# which internal machines and ports can be redirected to. This is the
# $port_redirection_allowed_hosts parameter.
#
# Note: The vnc redirector scheme is DISABLED by default.
#
# Note there are *two* SSL certificates involved that the user may be
# asked to inspect: apache's SSL cert and x11vnc's SSL cert. This may
# confuse the user.
# confuse naive users. You may want to use the same cert for both.
#
# This script provides one example on how to provide the service. You can
# customize to meet your needs, e.g. switch to php, newer modules,
# different authentication, SQL database, etc. If you plan to use it
# in production, please examine all security aspects of it carefully;
# read the comments in the script for more info.
# customize it to meet your needs, e.g. switch to php, newer cgi modules,
# different authentication, SQL database for user authentication, etc,
# etc. If you plan to use it in production, please examine all security
# aspects of it carefully; read the comments in the script for more info.
#
# More information and background:
# More information and background and troubleshooting:
#
# http://www.karlrunge.com/x11vnc/faq.html#faq-xvfb
# http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-viewers
@ -39,6 +190,10 @@
# http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-portal
# http://www.karlrunge.com/x11vnc/faq.html#faq-unix-passwords
# http://www.karlrunge.com/x11vnc/faq.html#faq-userlogin
#
#
# Please also read the comments below for changing specific settings.
# You can modify them in this script or by override file 'desktop.cgi.conf'
#-------------------------------------------------------------------------
@ -64,31 +219,58 @@ use strict;
use IO::Socket::INET;
##########################################################################
# Path to the x11vnc program:
#
my $x11vnc = '/usr/bin/x11vnc';
##########################################################################
# You can set some extra x11vnc cmdline options here:
#
my $x11vnc_extra_opts = '';
##########################################################################
# Override the default x11vnc viewer connection timeout of 75 seconds:
#
my $x11vnc_timeout = '';
##########################################################################
# TCP Ports:
#
# Set find_free_port to 1 (or the other modes described below) to
# autoselect a free port to use. The default is to use a fixed port
# based on the userid.
# autoselect a free port to use. The default is to use a port based on
# the userid number (7000 + uid).
#
my $find_free_port = 0;
#
# Or specify a port range:
#
#$find_free_port = '7000-8000';
#
# Or indicate to use a kludge to try to do everything through a SINGLE
# port. To try to avoid contention on the port, simultaneous instances
# of this script attempt to 'take turns' using it.
# of this script attempt to 'take turns' using it the single port.
#
#$find_free_port = 'fixed:5900';
#$find_free_port = 'fixed:5910';
# This is the starting port for 7000 + uid and also $find_free_port = 1
# autoselection:
#
my $starting_port = 7000;
##########################################################################
# Port redirection mode:
#
# This is to allow port redirection mode: username@host:port If username
# is valid, there will be a port redirection to internal machine
# This is to enable port redirection mode: username@host:port. If
# username is valid, there will be a port redirection to internal machine
# host:port. Presumably there is already an SSL enabled and password
# protected VNC server running there. We don't start that server.
# protected VNC server running there. We don't start that VNC server.
# (You might be able to figure out a way to do this yourself.)
#
# See the next setting for an allowed hosts file. The default for port
# redirection is off.
#
@ -108,23 +290,60 @@ my $enable_port_redirection = 0;
my $port_redirection_allowed_hosts = '';
##########################################################################
# Allowed users:
#
# To limit which users can use this service, set the following to a file
# that contains the allowed user names one per line. Lines starting with
# the '#' character are skipped.
#
my $allowed_users_file = '';
##########################################################################
# Denied users:
#
# As with $allowed_users_file, but to deny certain users. Applied after
# any $allowed_users_file check and overrides the result.
#
my $denied_users_file = '';
##########################################################################
# trustUrlVncCert applet parameter:
#
# Set to 0 to have the java applet html set the parameter
# trustUrlVncCert=no, i.e. the applet will not automatically accept an
# SSL cert already accepted by an HTTPS URL. See print_applet_html()
# below for more info.
# trustUrlVncCert=no, i.e. the applet will not automatically accept
# an SSL cert already accepted by an HTTPS URL. See $applet_html and
# print_applet_html() below for more info.
#
my $trustUrlVncCert = 1;
##########################################################################
# One-time VNC password fifo:
#
# For extra security against local untrusted users a fifo is used
# to copy the one-time VNC password to the user's VNC password file
# ~user/x11vnc.pw. If that fifo transfer technique causes problems,
# you can set this value to 1 to disable the security feature:
#
my $disable_vnc_passwd_fifo_safety = 0;
##########################################################################
# Comment this out if you don't want PATH modified:
#
$ENV{PATH} = "/usr/bin:bin:$ENV{PATH}";
$ENV{PATH} = "/usr/bin:/bin:$ENV{PATH}";
##########################################################################
# For the next two settings, note that most users will be confused that
# geometry and session are ignored when they are returning to their
# existing desktop session (x11vnc FINDDISPLAY action.)
##########################################################################
# Used below if user did not specify preferred geometry and color depth:
#
my $default_geometry = '1024x768x24';
@ -139,6 +358,7 @@ my $session_types = '';
#$session_types = 'gnome kde xfce lxde wmaker enlightenment mwm twm failsafe';
##########################################################################
# Set this to 1 to enable user setting a unique tag for each one
# of his desktops and so can have multiple ones simultaneously and
# select which one he wants. For now we just hack this onto geometry
@ -148,37 +368,125 @@ my $session_types = '';
my $enable_unique_tags = 0;
my $unique_tag = '';
# You can set some extra x11vnc cmdline options here:
##########################################################################
# String of HTML for the login form:
#
my $x11vnc_extra_opts = '';
# Feel free to customize to your taste, _USERNAME_ and _GEOMETRY_ are
# expanded to that of the request.
#
my $login_str = <<"END";
<title>x11vnc web access</title>
<h3>x11vnc web access</h3>
<form action="$ENV{REQUEST_URI}" method="post">
<table border="0">
<tr><td colspan=2><h2>Login</h2></td></tr>
<tr><td>Username:</td><td>
<input type="text" name="username" maxlength="40" value="_USERNAME_">
</td></tr>
<tr><td>Password:</td><td>
<input type="password" name="password" maxlength="50">
</td></tr>
<tr><td>Geometry:</td><td>
<input type="text" name="geometry" maxlength="40" value="_GEOMETRY_">
</td></tr>
<!-- session -->
<tr><td colspan="2" align="right">
<input type="submit" name="submit" value="Login">
</td></tr>
</table>
</form>
END
# Path to x11vnc program:
##########################################################################
# String of HTML returned to web browser to launch applet:
#
my $x11vnc = '/usr/bin/x11vnc';
# Feel free to customize to your taste, _UID_, _VNC_PORT_, _WIDTH_,
# _HEIGHT_, _PASS_, _TRUST_UVC_, _APPLET_JAR_, and _APPLET_CLASS_ are
# expanded to the appropriate values before sending out to the browser.
#
my $applet_html = <<"END";
<html>
<TITLE>
x11vnc desktop (_UID_/_VNC_PORT_)
</TITLE>
<APPLET CODE=_APPLET_CLASS_ ARCHIVE=_APPLET_JAR_ WIDTH=_WIDTH_ HEIGHT=_HEIGHT_>
<param name=PORT value=_VNC_PORT_>
<param name=VNCSERVERPORT value=_VNC_PORT_>
<param name=PASSWORD value=_PASS_>
<param name=trustUrlVncCert value=_TRUST_UVC_>
<param name="Open New Window" value=yes>
<param name="Offer Relogin" value=no>
<param name="ignoreMSLogonCheck" value=yes>
<param name="delayAuthPanel" value=yes>
<!-- extra -->
</APPLET>
<br>
<a href="$ENV{REQUEST_URI}">Login page</a><br>
<a href=http://www.karlrunge.com/x11vnc>x11vnc website</a>
</html>
END
if (`uname -n` =~ /haystack/) {
# for my testing:
if (-f "/home/runge/dtcgi.test") {
eval `cat /home/runge/dtcgi.test`;
}
##########################################################################
# These java applet strings are expanded into the above $applet_html.
# Note that $applet_jar is relative to your apache DocumentRoot (htdocs)
# not the filesystem root.
#
my $applet_jar = '/UltraViewerSSL.jar';
my $applet_class = 'VncViewer.class';
# These make the applet panel smaller because we use 'Open New Window'
# anyway (set to 'W' or 'H' to use actual session geometry values):
#
my $applet_width = '400';
my $applet_height = '300';
# To customize ALL of the HTML printed out you may need to redefine
# the bye() subtroutine in your desktop.cgi.conf file.
##########################################################################
# Override any of the above settings by setting them in a file named
# 'desktop.cgi.conf'. It is sourced here.
#
# You can override any variable set above by supplying perl code
# in $0.conf that sets it to the desired value.
#
# Some examples you could put in $0.conf:
#
# $x11vnc = '/usr/local/bin/x11vnc';
# $x11vnc_extra_opts = '-env FD_PROG=/usr/bin/xclock';
# $x11vnc_extra_opts = '-ssl /usr/local/etc/dtcgi.pem';
# $find_free_port = 'fixed:5999';
# $enable_port_redirection = 1;
# $allowed_users_file = '/usr/local/etc/dtcgi.allowed';
#
if (-f "$0.conf") {
eval `cat "$0.conf"`;
}
# http header:
##########################################################################
# END OF MAIN USER SETTINGS.
# Only power users should change anything below.
##########################################################################
# Print http header reply:
#
print STDOUT "Content-Type: text/html\r\n\r\n";
# Require HTTPS so that unix and vnc passwords are not sent in clear text
# (perhaps it is too late...) Disable HTTPS at your own risk.
# (perhaps it is too late...) Disable HTTPS here at your own risk.
#
if ($ENV{HTTPS} !~ /^on$/i) {
bye("HTTPS must be used (to encrypt passwords)");
}
# Read request:
# Read URL request:
#
my $request;
if ($ENV{'REQUEST_METHOD'} eq "POST") {
@ -192,7 +500,8 @@ if ($ENV{'REQUEST_METHOD'} eq "POST") {
my %request = url_decode(split(/[&=]/, $request));
# Experiment for FD_TAG x11vnc feature for multiple desktops:
# Experiment for FD_TAG x11vnc feature for multiple desktops for a
# single user:
#
# we hide it in geometry:tag for now:
#
@ -212,30 +521,28 @@ if (!exists $request{session} || $request{session} =~ /^\s*$/) {
}
# String for the login form:
# Expand _USERNAME_ and _GEOMETRY_ in the login string HTML:
#
my $login_str = <<"END";
<title>x11vnc web access</title>
<h3>x11vnc web access</h3>
<form action="$ENV{REQUEST_URI}" method="post">
<table border="0">
<tr><td colspan=2><h2>Login</h2></td></tr>
<tr><td>Username:</td><td>
<input type="text" name="username" maxlength="40" value="$request{username}">
</td></tr>
<tr><td>Password:</td><td>
<input type="password" name="password" maxlength="50">
</td></tr>
<tr><td>Geometry:</td><td>
<input type="text" name="geometry" maxlength="40" value="$request{geometry}">
</td></tr>
<!-- session -->
<tr><td colspan="2" align="right">
<input type="submit" name="submit" value="Login">
</td></tr>
</table>
</form>
END
$login_str =~ s/_USERNAME_/$request{username}/g;
$login_str =~ s/_GEOMETRY_/$request{geometry}/g;
# Check x11vnc version for installers of this script who do not know
# how to read and follow instructions:
#
my $version = (split(' ', `$x11vnc -version`))[1];
$version =~ s/\D*$//;
my ($major, $minor, $micro) = split(/\./, $version);
if ($major !~ /^\d+$/ || $minor !~ /^\d+$/) {
bye("The x11vnc program is not installed correctly.");
}
$micro = 0 unless $micro;
my $level = $major * 100 * 100 + $minor * 100 + $micro;
my $needed = 0 * 100 * 100 + 9 * 100 + 10;
if ($level < $needed) {
bye("x11vnc version 0.9.10 or later is required. (Found version $version)");
}
# Set up user selected desktop session list, if enabled:
@ -301,6 +608,49 @@ if ($enable_port_redirection) {
}
}
# If there is an $allowed_users_file, check username against it:
#
if ($allowed_users_file ne '') {
if (! open(USERS, "<$allowed_users_file")) {
bye("Internal Error #0");
}
my $ok = 0;
while (<USERS>) {
chomp;
$_ =~ s/^\s*//;
$_ =~ s/\s*$//;
next if /^#/;
if ($username eq $_) {
$ok = 1;
}
}
close USERS;
if (! $ok) {
bye("Denied Username.<p>$login_str");
}
}
# If there is a $denied_users_file, check username against it:
#
if ($denied_users_file ne '') {
if (! open(USERS, "<$denied_users_file")) {
bye("Internal Error #0");
}
my $ok = 1;
while (<USERS>) {
chomp;
$_ =~ s/^\s*//;
$_ =~ s/\s*$//;
next if /^#/;
if ($username eq $_) {
$ok = 0;
}
}
close USERS;
if (! $ok) {
bye("Denied Username.<p>$login_str");
}
}
# Require username to be alphanumeric + '-' + '_':
# (one may want to add '.' as well)
@ -321,6 +671,7 @@ if ($? != 0 || $uid !~ /^\d+$/) {
# Use x11vnc trick to check if the unix password is valid:
# (requires x11vnc 0.9.10 or later.)
#
if (!open(X11VNC, "| $x11vnc -unixpw \%stdin > /dev/null")) {
bye("Internal Error #1");
@ -346,7 +697,7 @@ my $fixed_port = 0;
if (! $find_free_port) {
# Fixed port based on userid (we assume it is free):
#
$vnc_port = 7000 + $uid;
$vnc_port = $starting_port + $uid;
} elsif ($find_free_port =~ /^fixed:(\d+)$/) {
#
@ -391,7 +742,7 @@ for (my $i = 0; $i < 8; $i++) {
# Use x11vnc trick to switch to user and store vnc pass in the passwdfile.
# Result is $pass is placed in user's $HOME/x11vnc.pw
#
# (This is actually difficult to do without untrusted local users being
# (This is actually difficult to do without untrusted LOCAL users being
# able to see the pass as well, see copy_password_to_user() for details
# on how we try to avoid this.)
#
@ -430,6 +781,7 @@ if (!open(TMP, ">$tmpfile")) {
# and -sslonly disables VeNCrypt SSL connections.
# Some settings:
# (change these if you encounter timing problems, etc.)
#
my $timeout = 75;
my $extra = '';
@ -438,6 +790,8 @@ if ($fixed_port) {
$timeout = 45;
$extra .= " -loopbg100,1";
}
$timeout = $x11vnc_timeout if $x11vnc_timeout ne '';
if ($session_types ne '') {
# settings for session selection case:
if (exists $sessions{$session}) {
@ -474,7 +828,7 @@ if ($? == 0) {
unlink $md5;
}
# write x11vnc command to the tmp file:
# Write x11vnc command to the tmp file:
#
print TMP <<"END";
#!/bin/sh
@ -497,6 +851,7 @@ close TMP;
$ENV{UNIXPW_CMD} = "/bin/sh $tmpfile";
# For the fixed port scheme we try to cooperate via lock file:
# (disabled by default.)
#
my $rmlock = '';
#
@ -593,8 +948,8 @@ sub initialize_random {
# the end.
#
sub auto_select_port {
my $pmin = 7000; # default range.
my $pmax = 8000;
my $pmin = $starting_port; # default range 7000-8000.
my $pmax = $starting_port + 1000;
if ($find_free_port =~ /^(\d+)-(\d+)$/) {
# user supplied a range:
@ -647,7 +1002,7 @@ sub auto_select_port {
# the user command is run in its own tty.
#
# The best way would be a sudo action or a special setuid program for
# copying. So consider using that and thereby simplify this function.
# copying. So consider doing that and thereby simplify this function.
#
# Short of a special program doing this, we use a fifo so ONLY ONE
# process can read the password. If the untrusted local user reads it,
@ -685,6 +1040,12 @@ sub copy_password_to_user {
bye("Internal Error #7");
}
# disable fifo safety if requested:
#
if ($disable_vnc_passwd_fifo_safety) {
$use_fifo = '';
}
# Make the fifo:
#
if ($use_fifo) {
@ -756,7 +1117,6 @@ sub copy_password_to_user {
}
close X11VNC; # note we ignore return value.
fsleep(0.5);
#print STDERR `ls -l $fifo ~$username/x11vnc.pw`;
unlink $fifo;
# Done!
@ -854,33 +1214,32 @@ sub lock_fixed_port {
#
sub print_applet_html {
my ($W, $H, $D) = split(/x/, $geometry);
$W = 640; # make it smaller since we 'Open New Window' below anyway.
$H = 480;
# make it smaller since we 'Open New Window' below anyway.
if ($applet_width ne 'W') {
$W = $applet_width;
}
if ($applet_height ne 'H') {
$H = $applet_height;
}
my $tUVC = ($trustUrlVncCert ? 'yes' : 'no');
my $str = <<"END";
<html>
<TITLE>
x11vnc desktop ($uid/$vnc_port)
</TITLE>
<APPLET CODE=VncViewer.class ARCHIVE=/UltraViewerSSL.jar WIDTH=$W HEIGHT=$H>
<param name=PORT value=$vnc_port>
<param name=VNCSERVERPORT value=$vnc_port>
<param name=PASSWORD value=$pass>
<param name=trustUrlVncCert value=$tUVC>
<param name="Open New Window" value=yes>
<param name="Offer Relogin" value=no>
<param name="ignoreMSLogonCheck" value=yes>
<param name="delayAuthPanel" value=yes>
<!-- extra -->
</APPLET>
<br>
<a href="$ENV{REQUEST_URI}">Login page</a><br>
<a href=http://www.karlrunge.com/x11vnc>x11vnc website</a>
</html>
END
# see $applet_html set in defaults section for more info:
#
my $str = $applet_html;
$str =~ s/_UID_/$uid/g;
$str =~ s/_VNC_PORT_/$vnc_port/g;
$str =~ s/_WIDTH_/$W/g;
$str =~ s/_HEIGHT_/$H/g;
$str =~ s/_PASS_/$pass/g;
$str =~ s/_APPLET_JAR_/$applet_jar/g;
$str =~ s/_APPLET_CLASS_/$applet_class/g;
$str =~ s/_TRUST_UVC_/$tUVC/g;
if ($enable_port_redirection && $redirect_host ne '') {
$str =~ s/name=PASSWORD value=.*>/name=NOT_USED value=yes>/;
$str =~ s/name=PASSWORD value=.*>/name=NOT_USED value=yes>/i;
#$str =~ s/<!-- extra -->/<!-- extra -->\n<param name="ignoreProxy" value=yes>/;
}
@ -1025,6 +1384,9 @@ sub check_redirect_host {
# Much of this code is borrowed from 'connect_switch':
#
# (it only applies to the vnc redirector $enable_port_redirection mode
# which is off by default.)
#
sub handle_conn {
close STDIN;
close STDOUT;

@ -16,8 +16,8 @@ See these sites and related ones for more information:
http://www.tightvnc.com
http://www.realvnc.com
http://www.stunnel.org
http://stunnel.mirt.net
http://www.stunnel.org
http://www.openssl.org
http://www.chiark.greenend.org.uk/~sgtatham/putty/
http://sourceforge.net/projects/cotvnc/
@ -255,7 +255,7 @@ Unix and Mac OS X:
Unpack the archive:
% gzip -dc ssvnc-1.0.25.tar.gz | tar xvf -
% gzip -dc ssvnc-1.0.27.tar.gz | tar xvf -
Run the GUI:
@ -263,7 +263,7 @@ Unix and Mac OS X:
% ./ssvnc/MacOSX/ssvnc (for Mac OS X)
The smaller file "ssvnc_no_windows-1.0.25.tar.gz"
The smaller file "ssvnc_no_windows-1.0.27.tar.gz"
could have been used as well.
On MacOSX you could also click on the SSVNC app icon in the Finder.
@ -309,8 +309,8 @@ Unix/MacOSX Install:
For the conventional source tarball it will compile and install, e.g.:
gzip -dc ssvnc-1.0.25.src.tar.gz | tar xvf -
cd ssvnc-1.0.25
gzip -dc ssvnc-1.0.27.src.tar.gz | tar xvf -
cd ssvnc-1.0.27
make config
make all
make PREFIX=/my/install/dir install
@ -322,7 +322,7 @@ Windows:
Unzip, using WinZip or a similar utility, the zip file:
ssvnc-1.0.25.zip
ssvnc-1.0.27.zip
Run the GUI, e.g.:
@ -334,7 +334,7 @@ Windows:
select Open, and then OK to launch it.
The smaller file "ssvnc_windows_only-1.0.25.zip"
The smaller file "ssvnc_windows_only-1.0.27.zip"
could have been used as well.
You can make a Windows shortcut to this program if you want to.
@ -664,7 +664,7 @@ Untrusted Local Users:
By 'do not trust' we mean they might try to gain access to remote
machines you connect to via SSVNC. Note that an untrusted local
user can often obtain root access in a short amount of time; if a
user has acheived that, then all bets are off for ANYTHING that you
user has achieved that, then all bets are off for ANYTHING that you
do on the workstation. It is best to get rid of Untrusted Local
Users as soon as possible.
@ -680,7 +680,7 @@ Untrusted Local Users:
If the untrusted local user tries to connect to these ports, he may
succeed in varying degrees to gain access to the remote machine.
We now list some safeguards one can put in place to try to make this
more difficult to acheive.
more difficult to achieve.
It probably pays to have the VNC server require a password, even
though there has already been SSL or SSH authentication (via
@ -747,8 +747,8 @@ See also:
http://www.karlrunge.com/x11vnc/faq.html
x11vnc -h | more
http://www.stunnel.org
http://stunnel.mirt.net
http://www.stunnel.org
http://www.openssl.org
http://www.tightvnc.com
http://www.realvnc.com

@ -123,6 +123,12 @@ proc bmesg {msg} {
label $w.l -width 70 -text "$msg"
pack $w.l
update
if {$env(BMESG) > 1} {
for {set i 0} {$i < $env(BMESG)} {incr i} {
after 1000
update
}
}
}
proc do_connect_http {sock hostport which} {
@ -165,9 +171,15 @@ proc do_connect_http {sock hostport which} {
proc do_connect_socks4 {sock hostport which} {
global debug cur_proxy
set s [split $hostport ":"]
set host [lindex $s 0]
set port [lindex $s 1]
set host ""
set port ""
if [regexp {^(.*):([0-9][0-9]*)$} $hostport mvar host port] {
;
} else {
puts stderr "could not parse host:port $hostport"
destroy .
exit 1
}
set i1 ""
set i2 ""
@ -249,9 +261,15 @@ proc do_connect_socks4 {sock hostport which} {
proc do_connect_socks5 {sock hostport which} {
global debug cur_proxy
set s [split $hostport ":"]
set host [lindex $s 0]
set port [lindex $s 1]
set host ""
set port ""
if [regexp {^(.*):([0-9][0-9]*)$} $hostport mvar host port] {
;
} else {
puts stderr "could not parse host:port $hostport"
destroy .
exit 1
}
set p1 [binary format ccc 5 1 0]
puts -nonewline $sock $p1
@ -1058,7 +1076,7 @@ proc proxy_type {proxy} {
}
proc proxy_hostport {proxy} {
regsub -nocase {^[a-z][a-z]*://} $proxy "" hp
regsub -nocase {^[a-z][a-z0-9]*://} $proxy "" hp
regsub {\+.*$} $hp "" hp
if {! [regexp {:[0-9]} $hp] && [regexp {^repeater:} $proxy]} {
set hp "$hp:5900"
@ -1140,9 +1158,15 @@ if {$do_bridge} {
set proxy1_type [proxy_type $proxy1]
set proxy1_hp [proxy_hostport $proxy1]
set s [split $proxy1_hp ":"]
set proxy1_host [lindex $s 0]
set proxy1_port [lindex $s 1]
set proxy1_host ""
set proxy1_port ""
if [regexp {^(.*):([0-9][0-9]*)$} $proxy1_hp mvar proxy1_host proxy1_port] {
;
} else {
puts stderr "could not parse hp1 host:port $proxy1_hp"
destroy .
exit 1
}
set proxy2_type ""
set proxy2_host ""
@ -1151,9 +1175,16 @@ if {$do_bridge} {
if {$proxy2 != ""} {
set proxy2_type [proxy_type $proxy2]
set proxy2_hp [proxy_hostport $proxy2]
set s [split $proxy2_hp ":"]
set proxy2_host [lindex $s 0]
set proxy2_port [lindex $s 1]
set proxy2_host ""
set proxy2_port ""
if [regexp {^(.*):([0-9][0-9]*)$} $proxy2_hp mvar proxy2_host proxy2_port] {
;
} else {
puts stderr "could not parse hp2 host:port $proxy2_hp"
destroy .
exit 1
}
}
set proxy3_type ""
@ -1163,9 +1194,16 @@ if {$do_bridge} {
if {$proxy3 != ""} {
set proxy3_type [proxy_type $proxy3]
set proxy3_hp [proxy_hostport $proxy3]
set s [split $proxy3_hp ":"]
set proxy3_host [lindex $s 0]
set proxy3_port [lindex $s 1]
set proxy3_host ""
set proxy3_port ""
if [regexp {^(.*):([0-9][0-9]*)$} $proxy3_hp mvar proxy3_host proxy3_port] {
;
} else {
puts stderr "could not parse hp3 host:port $proxy3_hp"
destroy .
exit 1
}
}
bmesg "1: '$proxy1_host' '$proxy1_port' '$proxy1_type'";
@ -1173,9 +1211,15 @@ if {$do_bridge} {
bmesg "3: '$proxy3_host' '$proxy3_port' '$proxy3_type'";
if [info exists env(SSVNC_REVERSE)] {
set s [split $env(SSVNC_REVERSE) ":"]
set rhost [lindex $s 0]
set rport [lindex $s 1]
set rhost ""
set rport ""
if [regexp {^(.*):([0-9][0-9]*)$} $env(SSVNC_REVERSE) mvar rhost rport] {
;
} else {
puts stderr "could not parse SSVNC_REVERSE host:port $env(SSVNC_REVERSE)"
destroy .
exit 1
}
set rc [catch {set lsock [socket $rhost $rport]}]
if {$rc != 0} {
puts stderr "error reversing"

@ -382,7 +382,9 @@ if [ "X$reverse" != "X" ]; then
echo "*Warning*: -listen and a single proxy/gateway does not make sense."
sleep 2
fi
SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
# we now try to PPROXY_LOOP_THYSELF, set this var to disable that.
#SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
fi
fi
if [ "X$ssh_cmd" = "X" ]; then
@ -520,12 +522,6 @@ if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
fi
fi
# (possibly) tell the vncviewer to only listen on lo:
if [ "X$reverse" != "X" -a "X$direct_connect" = "X" ]; then
VNCVIEWER_LISTEN_LOCALHOST=1
export VNCVIEWER_LISTEN_LOCALHOST
fi
# rsh mode is an internal/secret thing only I use.
rsh=""
if echo "$orig" | grep '^rsh://' > /dev/null; then
@ -551,11 +547,98 @@ else
fi
# extract host and disp number:
# try to see if it is ipv6 address:
ipv6=0
if echo "$orig" | grep '\[' > /dev/null; then
# ipv6 [fe80::219:dbff:fee5:3f92%eth1]:5900
host=`echo "$orig" | sed -e 's/\].*$//' -e 's/\[//'`
disp=`echo "$orig" | sed -e 's/^.*\]://'`
ipv6=1
elif echo "$orig" | grep ':..*:' > /dev/null; then
# ipv6 fe80::219:dbff:fee5:3f92%eth1:5900
host=`echo "$orig" | sed -e 's/:[^:]*$//'`
disp=`echo "$orig" | sed -e 's/^.*://'`
ipv6=1
else
# regular host:port
host=`echo "$orig" | awk -F: '{print $1}'`
disp=`echo "$orig" | awk -F: '{print $2}'`
fi
if [ "X$reverse" != "X" -a "X$STUNNEL_LISTEN" = "X" -a "X$host" != "X" ]; then
STUNNEL_LISTEN=$host
echo "set STUNNEL_LISTEN=$STUNNEL_LISTEN"
fi
if [ "X$host" = "X" ]; then
host=$localhost
fi
if [ "X$SSVNC_IPV6" = "X0" ]; then
# disable checking for it.
ipv6=0
#elif [ "X$reverse" != "X" -a "X$ipv6" = "X1" ]; then
# ipv6=0
elif [ "X$ipv6" = "X1" ]; then
:
elif echo "$host" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null; then
:
else
# regular hostname, can't be sure...
host "$host" >/dev/null 2>&1
host "$host" >/dev/null 2>&1
hout=`host "$host" 2>/dev/null`
if echo "$hout" | grep -i 'has ipv6 address' > /dev/null; then
if echo "$hout" | grep -i 'has address' > /dev/null; then
:
else
echo "ipv6: "`echo "$hout" | grep -i 'has ipv6 address' | head -n 1`
ipv6=1
fi
fi
if [ "X$ipv6" = "X0" ]; then
dout=`dig -t any "$host" 2>/dev/null`
if echo "$dout" | grep -i "^$host" | grep '[ ]AAAA[ ]' > /dev/null; then
if echo "$dout" | grep -i "^$host" | grep '[ ]A[ ]' > /dev/null; then
:
else
echo "ipv6: "`echo "$dout" | grep -i '[ ]AAAA[ ]' | head -n 1`
ipv6=1
fi
fi
fi
if [ "X$ipv6" = "X0" ]; then
sout=`env LOOKUP="$host" \
perl -e ' eval {use Socket}; exit 0 if $@;
eval {use Socket6}; exit 0 if $@;
@res = getaddrinfo($ENV{LOOKUP}, "daytime", AF_UNSPEC, SOCK_STREAM);
$ipv4 = 0;
$ipv6 = 0;
$ip6 = "";
while (scalar(@res) >= 5) {
($family, $socktype, $proto, $saddr, $canon, @res) = @res;
$ipv4 = 1 if $family == AF_INET;
$ipv6 = 1 if $family == AF_INET6;
if ($family == AF_INET6 && $ip6 eq "") {
my ($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV);
$ip6 = $host;
}
}
if (! $ipv4 && $ipv6) {
print "AF_INET6_ONLY: $ENV{LOOKUP}: $ip6\n";
}
exit 0;
' 2>/dev/null`
if echo "$sout" | grep AF_INET6_ONLY > /dev/null; then
echo "$sout"
ipv6=1
fi
fi
fi
if [ "X$ipv6" = "X1" ]; then
echo "ipv6: addr=$host disp=$disp"
fi
if [ "X$disp" = "X" ]; then
port="" # probably -listen mode.
elif [ $disp -lt 0 ]; then
@ -573,6 +656,21 @@ else
port=$disp
fi
if [ "X$ipv6" = "X1" -a "X$direct_connect" = "X1" ]; then
if [ "X$proxy" = "X" -a "X$reverse" = "X" ]; then
proxy="ipv6://$host:$port"
echo "direct connect: set proxy=$proxy"
fi
fi
# (possibly) tell the vncviewer to only listen on lo:
if [ "X$reverse" != "X" ]; then
if [ "X$direct_connect" = "X" -o "X$proxy" != "X" -o "X$STUNNEL_LISTEN" != "X" ]; then
VNCVIEWER_LISTEN_LOCALHOST=1
export VNCVIEWER_LISTEN_LOCALHOST
fi
fi
# try to find an open listening port via netstat(1):
inuse=""
if uname | grep Linux > /dev/null; then
@ -787,6 +885,60 @@ pcode() {
use IO::Socket::INET;
my $have_inet6 = "";
eval "use IO::Socket::INET6;";
$have_inet6 = 1 if $@ eq "";
#my $have_sock6 = "";
#eval "use Socket; use Socket6;";
#$have_sock6 = 1 if $@ eq "";
if (exists $ENV{PPROXY_LOOP_THYSELF}) {
# used for reverse vnc, run a repeating outer loop.
print STDERR "PPROXY_LOOP: $ENV{PPROXY_LOOP_THYSELF}\n";
my $rm = $ENV{PPROXY_REMOVE};
my $lp = $ENV{PPROXY_LOOP_THYSELF};
delete $ENV{PPROXY_REMOVE};
delete $ENV{PPROXY_LOOP_THYSELF};
$ENV{PPROXY_LOOP_THYSELF_MASTER} = $$;
my $pid = $$;
my $dbg = 0;
my $c = 0;
use POSIX ":sys_wait_h";
while (1) {
$pid = fork();
last if ! defined $pid;
if ($pid eq "0") {
last;
}
$c++;
print STDERR "\nPPROXY_LOOP: pid=$$ child=$pid count=$c\n";
while (1) {
waitpid(-1, WNOHANG);
fsleep(0.25);
if (! kill 0, $pid) {
print STDERR "PPROXY_LOOP: child=$pid gone.\n";
last;
}
print STDERR "PPROXY_LOOP: child=$pid alive.\n" if $dbg;
if (! -f $lp) {
print STDERR "PPROXY_LOOP: flag file $lp gone, killing $pid\n";
kill TERM, $pid;
fsleep(0.1);
wait;
last;
}
print STDERR "PPROXY_LOOP: file exists $lp\n" if $dbg;
}
last if ! -f $lp;
fsleep(0.25);
}
if ($pid ne "0") {
unlink($0) if $rm;
exit 0;
}
}
if (exists $ENV{PPROXY_SLEEP} && $ENV{PPROXY_SLEEP} > 0) {
print STDERR "PPROXY_PID: $$\n";
sleep $ENV{PPROXY_SLEEP};
@ -835,7 +987,7 @@ if (exists $ENV{SSVNC_PREDIGESTED_HANDSHAKE}) {
}
my $have_gettimeofday = 0;
eval "use Time::HiRes";
eval "use Time::HiRes;";
if ($@ eq "") {
$have_gettimeofday = 1;
}
@ -862,7 +1014,11 @@ my ($mode_1st, $mode_2nd, $mode_3rd) = ("", "", "");
($first, $mode_1st) = url_parse($first);
my ($proxy_host, $proxy_port) = split(/:/, $first);
my ($proxy_host, $proxy_port) = ($first, "");
if ($proxy_host =~ /^(.*):(\d+)$/) {
$proxy_host = $1;
$proxy_port = $2;
}
my $connect = $ENV{PPROXY_DEST};
if ($second ne "") {
@ -875,13 +1031,15 @@ if ($third ne "") {
print STDERR "\n";
print STDERR "PPROXY v0.3: a tool for Web, SOCKS, and UltraVNC proxies and VeNCrypt bridging.\n";
print STDERR "PPROXY v0.4: a tool for Web, SOCKS, and UltraVNC proxies and for\n";
print STDERR "PPROXY v0.4: IPv6 and VNC VeNCrypt bridging.\n";
print STDERR "proxy_host: $proxy_host\n";
print STDERR "proxy_port: $proxy_port\n";
print STDERR "proxy_connect: $connect\n";
print STDERR "pproxy_params: $ENV{PPROXY_PROXY}\n";
print STDERR "pproxy_listen: $ENV{PPROXY_LISTEN}\n";
print STDERR "pproxy_reverse: $ENV{PPROXY_REVERSE}\n";
print STDERR "io_socket_inet6: $have_inet6\n";
print STDERR "\n";
if (1) {
print STDERR "pproxy 1st: $first\t- $mode_1st\n";
@ -897,15 +1055,29 @@ sub pdie {
}
if ($ENV{PPROXY_REVERSE} ne "") {
my ($rhost, $rport) = split(/:/, $ENV{PPROXY_REVERSE});
my ($rhost, $rport) = ($ENV{PPROXY_REVERSE}, "");
if ($rhost =~ /^(.*):(\d+)$/) {
$rhost = $1;
$rport = $2;
}
$rport = 5900 unless $rport;
my $emsg = "";
$listen_handle = IO::Socket::INET->new(
PeerAddr => $rhost,
PeerPort => $rport,
Proto => "tcp"
);
$emsg = $!;
if (! $listen_handle && $have_inet6) {
eval {$listen_handle = IO::Socket::INET6->new(
PeerAddr => $rhost,
PeerPort => $rport,
Proto => "tcp"
);};
$emsg .= " / $!";
}
if (! $listen_handle) {
pdie "pproxy: $! -- PPROXY_REVERSE\n";
pdie "pproxy: $emsg -- PPROXY_REVERSE\n";
}
print STDERR "PPROXY_REVERSE: connected to $rhost $rport\n";
@ -914,27 +1086,75 @@ if ($ENV{PPROXY_REVERSE} ne "") {
my $maxtry = 12;
my $sleep = 5;
my $p2 = "";
my $emsg = "";
for (my $i=0; $i < $maxtry; $i++) {
if ($ENV{PPROXY_LISTEN} =~ /^INADDR_ANY:(.*)/) {
my $p = $1;
my ($if, $p) = ("", $ENV{PPROXY_LISTEN});
if ($p =~ /^(.*):(\d+)$/) {
$if = $1;
$p = $2;
}
$p2 = "*:$p";
if ($if eq "") {
$if = "localhost";
}
print STDERR "pproxy interface: $if\n";
$emsg = "";
if (($if eq "INADDR_ANY6" || $if eq "::") && $have_inet6) {
eval {$listen_sock = IO::Socket::INET6->new(
Listen => 2,
ReuseAddr => 1,
Domain => AF_INET6,
LocalAddr => "::",
LocalPort => $p,
Proto => "tcp"
);};
$p2 = ":::$p";
} elsif ($if =~ /^INADDR_ANY/) {
$listen_sock = IO::Socket::INET->new(
Listen => 2,
ReuseAddr => 1,
LocalPort => $p,
Proto => "tcp"
);
} elsif (($if eq "INADDR_LOOPBACK6" || $if eq "::1") && $have_inet6) {
$p2 = "::1:$p";
eval {$listen_sock = IO::Socket::INET6->new(
Listen => 2,
ReuseAddr => 1,
Domain => AF_INET6,
LocalAddr => "::1",
LocalPort => $p,
Proto => "tcp"
);};
$p2 = "::1:$p";
} else {
$p2 = "localhost:$ENV{PPROXY_LISTEN}";
$p2 = "$if:$p";
$listen_sock = IO::Socket::INET->new(
Listen => 2,
LocalAddr => "127.0.0.1",
LocalPort => $ENV{PPROXY_LISTEN},
ReuseAddr => 1,
LocalAddr => $if,
LocalPort => $p,
Proto => "tcp"
);
$emsg = $!;
if (! $listen_sock && $have_inet6) {
print STDERR "PPROXY_LISTEN: retry with INET6\n";
eval {$listen_sock = IO::Socket::INET6->new(
Listen => 2,
ReuseAddr => 1,
Domain => AF_INET6,
LocalAddr => $if,
LocalPort => $p,
Proto => "tcp"
);};
$emsg .= " / $!";
}
}
if (! $listen_sock) {
if ($i < $maxtry - 1) {
warn "pproxy: $!\n";
warn "pproxy: $emsg $!\n";
warn "Could not listen on port $p2, retrying in $sleep seconds... (Ctrl-C to quit)\n";
sleep $sleep;
}
@ -943,7 +1163,7 @@ if ($ENV{PPROXY_REVERSE} ne "") {
}
}
if (! $listen_sock) {
pdie "pproxy: $! -- PPROXY_LISTEN\n";
pdie "pproxy: $emsg -- PPROXY_LISTEN\n";
}
print STDERR "pproxy: listening on $p2\n";
my $ip;
@ -953,6 +1173,24 @@ if ($ENV{PPROXY_REVERSE} ne "") {
if (! $listen_handle) {
pdie "pproxy: $err\n";
}
if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) {
my $sml = $ENV{SSVNC_MULTIPLE_LISTEN};
if ($sml ne "" && $sml ne "0") {
setpgrp(0, 0);
if (fork()) {
close $viewer_sock;
wait;
exit 0;
}
if (fork()) {
close $viewer_sock;
exit 0;
}
setpgrp(0, 0);
$parent = $$;
}
}
}
$sock = IO::Socket::INET->new(
@ -961,15 +1199,27 @@ $sock = IO::Socket::INET->new(
Proto => "tcp"
);
my $err = "";
if (! $sock && $have_inet6) {
$err = $!;
eval {$sock = IO::Socket::INET6->new(
PeerAddr => $proxy_host,
PeerPort => $proxy_port,
Proto => "tcp"
);};
$err .= " / $!";
}
if (! $sock) {
my $err = $!;
unlink($0) if $ENV{PPROXY_REMOVE};
pdie "pproxy: $err\n";
}
unlink($0) if $ENV{PPROXY_REMOVE};
if ($ENV{PPROXY_PROXY} =~ /^vencrypt:/ && $ENV{PPROXY_LISTEN} =~ /^INADDR_ANY:/) {
if ($ENV{PPROXY_PROXY} =~ /^vencrypt:/ && $ENV{PPROXY_VENCRYPT_REVERSE}) {
print STDERR "\nPPROXY: vencrypt+reverse: swapping listen socket with connect socket.\n";
my $tmp_swap = $sock;
$sock = $listen_handle;
@ -1116,6 +1366,10 @@ xfer_both();
exit;
sub fsleep {
select(undef, undef, undef, shift);
}
sub url_parse {
my $hostport = shift;
my $mode = "http";
@ -1128,11 +1382,14 @@ sub url_parse {
} elsif ($hostport =~ m,^https?://(\S*)$,i) {
$mode = "http";
$hostport = $1;
} elsif ($hostport =~ m,^ipv6://(\S*)$,i) {
$mode = "ipv6";
$hostport = $1;
} elsif ($hostport =~ m,^repeater://(\S*)\+(\S*)$,i) {
# ultravnc repeater proxy.
$hostport = $1;
$mode = "repeater:$2";
if ($hostport !~ /:\d+/) {
if ($hostport !~ /:\d+$/) {
$hostport .= ":5900";
}
} elsif ($hostport =~ m,^vencrypt://(\S*)$,i) {
@ -1144,7 +1401,7 @@ sub url_parse {
$mode = $2;
}
$mode = "vencrypt:$m";
if ($hostport !~ /:\d+/) {
if ($hostport !~ /:\d+$/) {
$hostport .= ":5900";
}
}
@ -1161,6 +1418,8 @@ sub setmode {
} else {
$ENV{PPROXY_SOCKS} = 1;
}
} elsif ($mode =~ /^ipv6/i) {
$ENV{PPROXY_SOCKS} = 0;
} elsif ($mode =~ /^repeater:(.*)/) {
$ENV{PPROXY_REPEATER} = $1;
$ENV{PPROXY_SOCKS} = "";
@ -1180,7 +1439,11 @@ sub connection {
if ($ENV{PPROXY_SOCKS} eq "5") {
# SOCKS5
my ($h, $p) = split(/:/, $CONNECT);
my ($h, $p) = ($CONNECT, "");
if ($h =~ /^(.*):(\d+)$/) {
$h = $1;
$p = $2;
}
$con .= pack("C", 0x05);
$con .= pack("C", 0x01);
$con .= pack("C", 0x00);
@ -1242,9 +1505,13 @@ sub connection {
exit(1);
}
} elsif ($ENV{PPROXY_SOCKS} ne "") {
} elsif ($ENV{PPROXY_SOCKS} eq "1") {
# SOCKS4 SOCKS4a
my ($h, $p) = split(/:/, $CONNECT);
my ($h, $p) = ($CONNECT, "");
if ($h =~ /^(.*):(\d+)$/) {
$h = $1;
$p = $2;
}
$con .= pack("C", 0x04);
$con .= pack("C", 0x01);
$con .= pack("n", $p);
@ -1296,6 +1563,9 @@ sub connection {
close $sock;
exit(1);
}
} elsif ($ENV{PPROXY_SOCKS} eq "0") {
# hack for ipv6 "proxy", nothing to do, assume INET6 call worked.
;
} elsif ($ENV{PPROXY_REPEATER} ne "") {
my $rep = $ENV{PPROXY_REPEATER};
print STDERR "repeater: $rep\n";
@ -1582,6 +1852,7 @@ sub do_vencrypt_viewer_bridge {
for (my $i=0; $i < $maxtry; $i++) {
$listen_sock = IO::Socket::INET->new(
Listen => 2,
ReuseAddr => 1,
LocalAddr => "127.0.0.1",
LocalPort => $listen,
Proto => "tcp"
@ -1606,6 +1877,23 @@ sub do_vencrypt_viewer_bridge {
if (! $viewer_sock) {
die "pproxy: vencrypt_viewer_bridge[$$]: $err\n";
}
if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) {
my $sml = $ENV{SSVNC_MULTIPLE_LISTEN};
if ($sml ne "" && $sml ne "0") {
setpgrp(0, 0);
if (fork()) {
close $viewer_sock;
wait;
exit 0;
}
if (fork()) {
close $viewer_sock;
exit 0;
}
setpgrp(0, 0);
$parent = $$;
}
}
print STDERR "vencrypt_viewer_bridge[$$]: viewer_sock $viewer_sock\n" if $db;
print STDERR "pproxy: vencrypt_viewer_bridge[$$]: connecting to 127.0.0.1:$connect\n";
@ -2055,13 +2343,18 @@ NHAFL_warning() {
echo "** Warning: you to manually remove a key from ~/.ssh/known_hosts.)"
echo "** Warning: "
echo "** Warning: This decreases security: a Man-In-The-Middle attack is possible."
echo "** Warning: For chained ssh connections the first ssh leg is secure but the"
echo "** Warning: 2nd ssh leg is vulnerable. For an ssh connection going through"
echo "** Warning: a HTTP or SOCKS proxy the ssh connection is vulnerable."
echo "** Warning: "
echo "** Warning: You can set the SSVNC_SSH_LOCALHOST_AUTH=1 env. var. to disable"
echo "** Warning: using the NoHostAuthenticationForLocalhost ssh option."
echo "** Warning: using the NoHostAuthenticationForLocalhost=yes ssh option."
echo "** Warning: "
echo "** Warning: A better solution is to configure (in the SSVNC GUI) the setting:"
echo "** Warning: 'Options -> Advanced -> Private SSH KnownHosts file' (or set"
echo "** Warning: SSVNC_KNOWN_HOSTS_FILE directly) to a per-connection known hosts"
echo "** Warning: file. This yields a both secure and convenient solution."
echo "** Warning: file. That file holds the 'localhost' cert for this specific"
echo "** Warning: connection. This yields a both secure and convenient solution."
echo ""
}
@ -2243,6 +2536,7 @@ if [ "X$use_ssh" = "X1" ]; then
nd=`findfree 6600`
PPROXY_LISTEN=$nd; export PPROXY_LISTEN
# XXX no reverse forever PPROXY_LOOP_THYSELF ...
$ptmp &
sleep 1
if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then
@ -2633,6 +2927,16 @@ if [ "X$crl" != "X" ]; then
fi
fi
if [ "X$showcert" = "X1" ]; then
if [ "X$ipv6" = "X1" -a "X$proxy" = "X" ]; then
proxy="ipv6://$host:$port"
fi
fi
if [ "X$direct_connect" != "X" -a "X$STUNNEL_LISTEN" != "X" ]; then
proxy=reverse_direct
fi
ptmp=""
if [ "X$proxy" != "X" ]; then
ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl"
@ -2840,10 +3144,23 @@ if [ "X$direct_connect" != "X" ]; then
if [ "X$reverse" = "X" ]; then
PPROXY_LISTEN=$use
export PPROXY_LISTEN
else
if [ "X$proxy" = "Xreverse_direct" ]; then
PPROXY_LISTEN="$STUNNEL_LISTEN:`expr 5500 + $disp`"
PPROXY_DEST="$localhost:$use"
PPROXY_PROXY="ipv6://$localhost:$use" # not always ipv6..
export PPROXY_LISTEN PPROXY_DEST PPROXY_PROXY
pps=1
else
PPROXY_REVERSE="$localhost:$use"
export PPROXY_REVERSE
export PPROXY_LISTEN
pps=3
fi
if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then
PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself.${RANDOM}.$$"`
export PPROXY_LOOP_THYSELF
pps=2
fi
if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
pps=`expr $pps + $SSVNC_EXTRA_SLEEP`
fi
@ -2904,10 +3221,13 @@ if [ "X$direct_connect" != "X" ]; then
echo ""
trap "final" 0 2 15
if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then
echo "NOTE: The ultravnc_dsm_helper only runs once. So after the first LISTEN"
echo " ends, you may have to Press Ctrl-C and restart for another connection."
echo " ends you must restart the Listening mode. You may also need to"
echo " Press Ctrl-C to stop the viewer and restart for another connection."
echo ""
SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
fi
#SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
VNCVIEWER_LISTEN_LOCALHOST=1
export VNCVIEWER_LISTEN_LOCALHOST
dport=`expr 5500 + $disp`
@ -2917,8 +3237,13 @@ if [ "X$direct_connect" != "X" ]; then
echo
echo "$ustr &"
echo
if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then
$cmd &
dsm_pid=$!
else
while [ 1 ]; do $cmd; sleep 1; done &
dsm_pid=$!
fi
sleep 2
disp=$use
if [ $disp -ge 5500 ]; then
@ -2935,6 +3260,9 @@ if [ "X$direct_connect" != "X" ]; then
echo "$VNCVIEWERCMD" "$@" -listen $disp2
echo ""
$VNCVIEWERCMD "$@" -listen $disp2
if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then
rm -f $PPROXY_LOOP_THYSELF
fi
fi
exit $?
fi
@ -2998,6 +3326,8 @@ else
hloc=""
if [ "X$use_ssh" = "X1" ]; then
hloc="$localhost:"
elif [ "X$STUNNEL_LISTEN" != "X" ]; then
hloc="$STUNNEL_LISTEN:"
fi
if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then
hloc="$localhost:"
@ -3127,7 +3457,12 @@ else
if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then
pstunnel=`echo "$proxy" | awk -F: '{print $2}'`
plisten=`echo "$proxy" | awk -F: '{print $3}'`
PPROXY_LISTEN="INADDR_ANY:$plisten"; export PPROXY_LISTEN
IF=INADDR_ANY
if [ "X$STUNNEL_LISTEN" != "X" ]; then
IF=$STUNNEL_LISTEN
fi
PPROXY_VENCRYPT_REVERSE=1; export PPROXY_VENCRYPT_REVERSE
PPROXY_LISTEN="$IF:$plisten"; export PPROXY_LISTEN
PPROXY_PROXY="vencrypt://$localhost:$pstunnel"; export PPROXY_PROXY
PPROXY_DEST="$localhost:$pstunnel"; export PPROXY_DEST
STUNNEL_ONCE=1; export STUNNEL_ONCE
@ -3140,6 +3475,11 @@ else
if [ $N2_trim -le 200 ]; then
N2_trim=`expr $N2_trim + 5500`
fi
if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then
PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself1.${RANDOM}.$$"`
export PPROXY_LOOP_THYSELF
PPROXY_LOOP_THYSELF0=$PPROXY_LOOP_THYSELF
fi
env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="-$port1,$port2" $ptmp &
sleep 1
fi
@ -3148,6 +3488,10 @@ else
PPROXY_SLEEP=1; export PPROXY_SLEEP;
fi
PPROXY_KILLPID=+1; export PPROXY_KILLPID;
if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then
PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself2.${RANDOM}.$$"`
export PPROXY_LOOP_THYSELF
fi
$ptmp &
# Important to have no extra pids generated between here and VNCVIEWERCMD
fi
@ -3157,6 +3501,13 @@ else
echo "$VNCVIEWERCMD" "$@" -listen $N2
echo ""
$VNCVIEWERCMD "$@" -listen $N2
if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then
rm -f $PPROXY_LOOP_THYSELF
fi
if [ "X$PPROXY_LOOP_THYSELF0" != "X" ]; then
rm -f $PPROXY_LOOP_THYSELF0
fi
fi
sleep 1

File diff suppressed because it is too large Load Diff

@ -389,7 +389,7 @@ if [ "X$SSVNC_BUILD_SKIP_STUNNEL" = "X" ]; then
cp configure configure.orig
sed -e "s,/var/ssl,/var/ssl /usr/sfw," configure.orig > configure
fi
env LDFLAGS="-L$start/$libs $LDFLAGS_OS" CPPFLAGS="$CPPFLAGS_OS" ./configure --disable-libwrap
env LDFLAGS="-L$start/$libs $LDFLAGS_OS" CPPFLAGS="$CPPFLAGS_OS" ./configure --disable-libwrap --enable-ipv6
make
ls -l src/stunnel
cd "$start"

@ -217,7 +217,7 @@ For example:
or set both of them at once.
To acheive the same effect, you can also
To achieve the same effect, you can also
set parameters in your ~/.ssvncrc file, for example:
font_default=helvetica -20 bold

@ -11,7 +11,7 @@
.\" License as specified in the file LICENCE.TXT that comes with the
.\" TightVNC distribution.
.\"
.TH ssvncviewer 1 "December 2009" "" "SSVNC"
.TH ssvncviewer 1 "September 2009" "" "SSVNC"
.SH NAME
ssvncviewer \- an X viewer client for VNC
.SH SYNOPSIS

@ -1,7 +1,7 @@
#!/bin/sh
rm -rf ./src/tmp/* || exit 1
vers=1.0.25
vers=1.0.27
cd .. || exit 1

@ -1,5 +1,10 @@
#!/bin/sh
if [ ! -f ./_getpatches ]; then
ls -l ./_getpatches
exit 1
fi
cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/tight-vncviewer*patch .
cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/vnc_unixsrc_vncviewer.patched.tar ../zips/

@ -14,9 +14,10 @@
# clients that need to connect to ipv6 servers.) Reversing is the default
# if this script is named 'inet4to6' (e.g. by a symlink.)
#
# Use Ctrl-C to stop this program.
# Use Ctrl-C to stop this program. You can also supply '-c n' as the
# first option to only handle that many connections.
#
# You can also set env. vars INET6TO4_LOOP=1 or INET6TO4_LOOP=BG
# Also set the env. vars INET6TO4_LOOP=1 or INET6TO4_LOOP=BG
# to have an outer loop restarting this program (BG means do that
# in the background), and INET6TO4_LOGFILE for a log file.
# Also set INET6TO4_VERBOSE to verbosity level and INET6TO4_WAITTIME
@ -42,12 +43,14 @@
# or see <http://www.gnu.org/licenses/>.
#-------------------------------------------------------------------------
my $program = "inet6to4";
# Set up logging:
#
if (exists $ENV{INET6TO4_LOGFILE}) {
close STDOUT;
if (!open(STDOUT, ">>$ENV{INET6TO4_LOGFILE}")) {
die "inet6to4: $ENV{INET6TO4_LOGFILE} $!\n";
die "$program: $ENV{INET6TO4_LOGFILE} $!\n";
}
close STDERR;
open(STDERR, ">&STDOUT");
@ -98,14 +101,14 @@ sub open_pidfile {
if (exists $ENV{INET6TO4_LOOP}) {
my $csl = $ENV{INET6TO4_LOOP};
if ($csl ne 'BG' && $csl ne '1') {
die "inet6to4: invalid INET6TO4_LOOP.\n";
die "$program: invalid INET6TO4_LOOP.\n";
}
if ($csl eq 'BG') {
# go into bg as "daemon":
setpgrp(0, 0);
my $pid = fork();
if (! defined $pid) {
die "inet6to4: $!\n";
die "$program: $!\n";
} elsif ($pid) {
wait;
exit 0;
@ -126,7 +129,7 @@ if (exists $ENV{INET6TO4_LOOP}) {
open_pidfile();
}
print STDERR "inet6to4: starting service at ", scalar(localtime), " master-pid=$$\n";
print STDERR "$program: starting service at ", scalar(localtime), " master-pid=$$\n";
while (1) {
$looppid = fork;
if (! defined $looppid) {
@ -137,7 +140,7 @@ if (exists $ENV{INET6TO4_LOOP}) {
exec $0, @ARGV;
exit 1;
}
print STDERR "inet6to4: re-starting service at ", scalar(localtime), " master-pid=$$\n";
print STDERR "$program: re-starting service at ", scalar(localtime), " master-pid=$$\n";
sleep 1;
}
exit 0;
@ -177,6 +180,12 @@ if (! @ARGV || $ARGV[0] =~ '^-+h') { # -help
exit;
}
my $cmax = 0;
if ($ARGV[0] eq '-c') { # -c
shift;
$cmax = shift;
}
if ($ARGV[0] eq '-r') { # -r
shift;
$reverse = 1;
@ -203,24 +212,30 @@ setpgrp(0, 0);
# create listening socket:
#
my %opts;
$opts{Listen} = 10;
$opts{Proto} = "tcp";
$opts{ReuseAddr} = 1;
if ($listen_port =~ /^(.*):(\d+)$/) {
$opts{LocalAddr} = $1;
$listen_port = $2;
}
$opts{LocalPort} = $listen_port;
if (!$reverse) {
$listen_sock = IO::Socket::INET6->new(
Listen => 10,
LocalPort => $listen_port,
Domain => AF_INET6,
ReuseAddr => 1,
Proto => "tcp"
);
# force ipv6 interface:
$opts{Domain} = AF_INET6;
$listen_sock = IO::Socket::INET6->new(%opts);
} else {
$listen_sock = IO::Socket::INET->new(
Listen => 10,
LocalPort => $listen_port,
ReuseAddr => 1,
Proto => "tcp"
);
$listen_sock = IO::Socket::INET->new(%opts);
if (! $listen_sock && $! =~ /invalid/i) {
warn "$program: $!, retrying with AF_UNSPEC:\n";
$opts{Domain} = AF_UNSPEC;
$listen_sock = IO::Socket::INET6->new(%opts);
}
}
if (! $listen_sock) {
die "inet6to4: $!\n";
die "$program: $!\n";
}
# for use by the xfer helper processes' interrupt handlers:
@ -236,6 +251,10 @@ my $conn = 0;
#
while (1) {
$conn++;
if ($cmax > 0 && $conn > $cmax) {
print STDERR "last connection ($cmax)\n" if $verbose;
last;
}
print STDERR "listening for connection: $conn\n" if $verbose;
my ($client, $ip) = $listen_sock->accept();
@ -259,7 +278,7 @@ while (1) {
#
my $pid = fork();
if (! defined $pid) {
die "inet6to4: $!\n";
die "$program: $!\n";
} elsif ($pid) {
wait;
# to throttle runaways
@ -286,24 +305,25 @@ sub handle_conn {
print STDERR "connecting to: $host:$port\n" if $verbose;
my $sock = '';
my %opts;
$opts{PeerAddr} = $host;
$opts{PeerPort} = $port;
$opts{Proto} = "tcp";
if (!$reverse) {
$sock = IO::Socket::INET->new(
PeerAddr => $host,
PeerPort => $port,
Proto => "tcp"
);
$sock = IO::Socket::INET->new(%opts);
} else {
$sock = IO::Socket::INET6->new(
PeerAddr => $host,
PeerPort => $port,
Domain => AF_INET6,
Proto => "tcp"
);
$opts{Domain} = AF_INET6;
$sock = IO::Socket::INET6->new(%opts);
}
if (! $sock) {
warn "$program: $!, retrying with AF_UNSPEC:\n";
$opts{Domain} = AF_UNSPEC;
$sock = IO::Socket::INET6->new(%opts);
}
if (! $sock) {
close $client;
die "inet6to4: $!\n";
die "$program: $!\n";
}
$current_fh1 = $client;
@ -359,10 +379,10 @@ sub xfer {
my $len = sysread($in, $buf, 8192);
if (! defined($len)) {
next if $! =~ /^Interrupted/;
print STDERR "inet6to4\[$lab/$conn/$$]: $!\n";
print STDERR "$program\[$lab/$conn/$$]: $!\n";
last;
} elsif ($len == 0) {
print STDERR "inet6to4\[$lab/$conn/$$]: "
print STDERR "$program\[$lab/$conn/$$]: "
. "Input is EOF.\n";
last;
}
@ -378,7 +398,7 @@ sub xfer {
while ($len) {
my $written = syswrite($out, $buf, $len, $offset);
if (! defined $written) {
print STDERR "inet6to4\[$lab/$conn/$$]: "
print STDERR "$program\[$lab/$conn/$$]: "
. "Output is EOF. $!\n";
$quit = 1;
last;

Loading…
Cancel
Save