From b74c8f4241ec8c3d972ee97d0ce9a399ddd09ce1 Mon Sep 17 00:00:00 2001 From: runge Date: Sun, 18 Apr 2010 19:37:37 -0400 Subject: Improvements to demo scripts. Alias -coe for -connect_or_exit. Fix HAVE_V4L2. Warn no Xvfb, Xdummy, or Xvnc. Xinerama screens. --- x11vnc/ChangeLog | 9 ++ x11vnc/README | 334 +++++++++++++++++++++------------------ x11vnc/appshare.c | 2 +- x11vnc/connections.c | 9 +- x11vnc/help.c | 84 ++++++---- x11vnc/inet.c | 187 ++++++++++++++++++---- x11vnc/inet.h | 2 +- x11vnc/misc/connect_switch | 62 ++++++-- x11vnc/misc/desktop.cgi | 92 ++++++++--- x11vnc/misc/ultravnc_repeater.pl | 192 +++++++++++++++++++--- x11vnc/options.c | 8 +- x11vnc/options.h | 1 + x11vnc/remote.c | 13 +- x11vnc/screen.c | 5 +- x11vnc/sslhelper.c | 10 +- x11vnc/ssltools.h | 10 ++ x11vnc/user.c | 58 ++++++- x11vnc/util.c | 1 + x11vnc/v4l.c | 5 + x11vnc/x11vnc.1 | 80 ++++++---- x11vnc/x11vnc.c | 22 ++- x11vnc/x11vnc.h | 23 ++- x11vnc/x11vnc_defs.c | 2 +- x11vnc/xinerama.c | 13 +- 24 files changed, 880 insertions(+), 344 deletions(-) (limited to 'x11vnc') diff --git a/x11vnc/ChangeLog b/x11vnc/ChangeLog index ddfe0f0..16b36b2 100644 --- a/x11vnc/ChangeLog +++ b/x11vnc/ChangeLog @@ -1,3 +1,12 @@ +2010-04-18 Karl Runge + * x11vnc/misc: improvements to demo scripts + * x11vnc: Alias -coe for -connect_or_exit. more accurate + dotted_ip() and -listen6. Improvements to ipv6 mode. + http interface for X11VNC_HTTP_LISTEN_LOCALHOST. Print + warning about missing Xvfb, Xdummy, or Xvnc in -create. + Fix __LINUX_VIDEODEV2_H / HAVE_V4L2. Always print out info + about Xinerama screens. + 2010-04-09 Karl Runge * classes/ssl: debugging and workarounds for java viewer * x11vnc/misc: sync ssvnc, improve util scripts. diff --git a/x11vnc/README b/x11vnc/README index faec507..b822bc3 100644 --- a/x11vnc/README +++ b/x11vnc/README @@ -2,7 +2,7 @@ Copyright (C) 2002-2010 Karl J. Runge All rights reserved. -x11vnc README file Date: Thu Apr 8 23:54:19 EDT 2010 +x11vnc README file Date: Sun Apr 18 17:09:43 EDT 2010 The following information is taken from these URLs: @@ -438,16 +438,22 @@ nc -localhost -display :0' could be used for normal, unencrypted connections and also for SSL encrypted ones. - The the VNC displays to enter in the VNC viewer would be, say, + The VNC displays to enter in the VNC viewer would be, say, "far-away.east:0" to reach jills-pc and "far-away.east:1" to reach freds-pc. We assume above that x11vnc is using port 5900 (and any Host-Level-firewalls on jills-pc has been configured to let that port - in.) + in.) Use the "-rfbport" option to tell which port x11vnc should listen + on. For a home system one likely does not have a hostname and would have to use the IP address, say, "24.56.78.93:0". E.g.: vncviewer 24.56.78.93:0 + You may want to choose a more obscure port on the router side, e.g. + 5944, to avoid a lot of port scans finding your VNC server. For 5944 + you would tell the viewer to use: + vncviewer 24.56.78.93:44 + The IP address would need to be communicated to the person running the VNC Viewer. The site http://www.whatismyip.com/ can help here. @@ -912,18 +918,18 @@ make always supported chained SSL certificates (simply put the intermediate certificates, in order, after the server certificate in the pem file.) - * A demo CGI script desktop.cgi shows how to create a multi-user - x11vnc web login desktop service. The script requires x11vnc - version 0.9.10. The user logs into a secure web site and gets - his/her own virtual desktop (Xvfb.) x11vnc's SSL enabled Java - Viewer Applet is launched by the web browser for secure viewing - (and so no software needs to be installed on the viewer-side.) One - can use the desktop.cgi script for ideas to create their own - fancier or customized web login desktop service (e.g. - user-creation, PHP, SQL, specialized desktop application, etc.) - More info here. There is also an optional 'port redirection' mode - that allows redirection to other SSL enabled VNC servers running - inside the firewall. + * A demo CGI script desktop.cgi shows how to create an SSL + encrypted, multi-user x11vnc web login desktop service. The script + requires x11vnc version 0.9.10. The user logs into a secure web + site and gets his/her own virtual desktop (Xvfb.) x11vnc's SSL + enabled Java Viewer Applet is launched by the web browser for + secure viewing (and so no software needs to be installed on the + viewer-side.) One can use the desktop.cgi script for ideas to + create their own fancier or customized web login desktop service + (e.g. user-creation, PHP, SQL, specialized desktop application, + etc.) More info here. There is also an optional 'port redirection' + mode that allows redirection to other SSL enabled VNC servers + running inside the firewall. * Built-in support for IPv6 (128 bit internet addresses) is now provided. See the -6 and -connect options for details. Additionally, in case there are still problems with built-in IPv6 @@ -2346,8 +2352,7 @@ typedef unsigned int in_addr_t; http://www.focv.com/ Debian: (.deb) http://packages.debian.org/x11vnc Redhat/Fedora: (.rpm) http://packages.sw.be/x11vnc RPMforge http://dag.wieers.com/rpm/packages/x11vnc/ (N.B.: unmaintained after - 0.9.3) Solaris: (pkg) http://www.sunfreeware.com/ (N.B: very old; - better to compile from source) + 0.9.3) Solaris: (pkg) http://www.sunfreeware.com/ If the above binaries don't work and building x11vnc on your OS fails (and all else fails!) you can try one of My Collection of x11vnc @@ -8869,8 +8874,8 @@ or: Q-129: Does x11vnc work with IPv6? Update: as of Apr/2010 in the 0.9.10 x11vnc development tarball, there - is now some built-in support for IPv6 (128 bit internet addresses.) - See the -6 and -connect options for details. + is now built-in support for IPv6 (128 bit internet addresses.) See the + -6 and -connect options for details. The remainder of this FAQ entry shows how to do with this with pre 0.9.10 x11vnc using IPv6 helper tools. @@ -11937,20 +11942,20 @@ r On Mac OS X? Use "ssvnc_no_windows". On Windows? Use "ssvnc_windows_only". ssvnc_windows_only-1.0.26.zip Windows Binaries Only. No source included - (6.0MB) + (6.2MB) ssvnc_no_windows-1.0.26.tar.gz Unix and Mac OS X Only. No Windows binarie -s. Source included. (9.8MB) +s. Source included. (10.1MB) ssvnc_unix_only-1.0.26.tar.gz Unix Binaries Only. No source included -. (7.0MB) +. (7.2MB) ssvnc_unix_minimal-1.0.26.tar.gz Unix Minimal. You must supply your own vn cviewer and stunnel. (0.2MB) ssvnc-1.0.26.tar.gz All Unix, Mac OS X, and Windows binaries a -nd source TGZ. (15.5MB) +nd source TGZ. (16.1MB) ssvnc-1.0.26.zip All Unix, Mac OS X, and Windows binaries a -nd source ZIP. (15.5MB) +nd source ZIP. (16.4MB) ssvnc_all-1.0.26.zip All Unix, Mac OS X, and Windows binaries a -nd source AND full archives in the zip dir. (18.3MB) +nd source AND full archives in the zip dir. (19.2MB) Here is a conventional source tarball: @@ -11973,7 +11978,7 @@ nd source AND full archives in the zip dir. (18.3MB) directory to recompile for your operating system. Here are the corresponding 1.0.27 development bundles (Please help - testing them): + test them): ssvnc_windows_only-1.0.27.zip ssvnc_no_windows-1.0.27.tar.gz @@ -12022,10 +12027,10 @@ nd source AND full archives in the zip dir. (18.3MB) SunOS.i86pc Darwin.Power.Macintosh Darwin.i386 - HP-UX.9000 X - FreeBSD.i386 X - NetBSD.i386 X - OpenBSD.i386 X + HP-UX.9000 X (removed) + FreeBSD.i386 X (removed) + NetBSD.i386 X (removed) + OpenBSD.i386 X (removed) (some of these are out of date, marked with 'X' above, because I no longer have access to machines running those OS's. Use the @@ -12071,105 +12076,105 @@ x11vnc: a VNC server for real X displays Here are all of x11vnc command line options: % x11vnc -opts (see below for -help long descriptions) -x11vnc: allow VNC connections to real X11 displays. 0.9.10 lastmod: 2010-04-08 +x11vnc: allow VNC connections to real X11 displays. 0.9.10 lastmod: 2010-04-18 x11vnc options: -display disp -auth file -N -autoport n -rfbport str -6 - -noipv6 -noipv4 -reopen - -reflect host:N -id windowid -sid windowid - -appshare -clip WxH+X+Y -flashcmap - -shiftcmap n -notruecolor -advertise_truecolor - -visual n -overlay -overlay_nocursor - -8to24 [opts] -24to32 -scale fraction - -geometry WxH -scale_cursor frac -viewonly - -shared -once -forever - -loop -timeout n -sleepin n - -inetd -tightfilexfer -ultrafilexfer - -http -http_ssl -avahi - -mdns -zeroconf -connect string - -connect_or_exit str -proxy string -vncconnect - -novncconnect -allow host1[,host2..] -localhost - -listen6 str -nolookup -input string - -grabkbd -grabptr -grabalways - -viewpasswd string -passwdfile filename -showrfbauth filename - -unixpw [list] -unixpw_nis [list] -unixpw_cmd cmd - -find -finddpy -listdpy - -findauth [disp] -create -xdummy - -xvnc -xvnc_redirect -xdummy_xvfb - -create_xsrv str -svc -svc_xdummy - -svc_xvnc -svc_xdummy_xvfb -xdmsvc - -sshxdmsvc -unixpw_system_greeter -redirect port - -display WAIT:... -vencrypt mode -anontls mode - -sslonly -dhparams file -nossl - -ssl [pem] -ssltimeout n -sslnofail - -ssldir dir -sslverify path -sslCRL path - -sslGenCA [dir] -sslGenCert type name -sslEncKey pem - -sslCertInfo pem -sslDelCert pem -sslScripts - -stunnel [pem] -stunnel3 [pem] -enc cipher:keyfile - -https [port] -httpsredir [port] -http_oneport - -ssh user@host:disp -usepw -storepasswd pass file - -nopw -accept string -afteraccept string - -gone string -users list -noshm - -flipbyteorder -onetile -solid [color] - -blackout string -xinerama -noxinerama - -xtrap -xrandr [mode] -rotate string - -padgeom WxH -o logfile -flag file - -rmflag file -rc filename -norc - -env VAR=VALUE -prog /path/to/x11vnc -h, -help - -?, -opts -V, -version -license - -dbg -q, -quiet -v, -verbose - -bg -modtweak -nomodtweak - -xkb -noxkb -capslock - -skip_lockkeys -noskip_lockkeys -skip_keycodes string - -sloppy_keys -skip_dups -noskip_dups - -add_keysyms -noadd_keysyms -clear_mods - -clear_keys -clear_all -remap string - -norepeat -repeat -nofb - -nobell -nosel -noprimary - -nosetprimary -noclipboard -nosetclipboard - -seldir string -cursor [mode] -nocursor - -cursor_drag -arrow n -noxfixes - -alphacut n -alphafrac fraction -alpharemove - -noalphablend -nocursorshape -cursorpos - -nocursorpos -xwarppointer -noxwarppointer - -buttonmap string -nodragging -ncache n - -ncache_cr -ncache_no_moveraise -ncache_no_dtchange - -ncache_no_rootpixmap -ncache_keep_anims -ncache_old_wm - -ncache_pad n -debug_ncache -wireframe [str] - -nowireframe -nowireframelocal -wirecopyrect mode - -nowirecopyrect -debug_wireframe -scrollcopyrect mode - -noscrollcopyrect -scr_area n -scr_skip list - -scr_inc list -scr_keys list -scr_term list - -scr_keyrepeat lo-hi -scr_parms string -fixscreen string - -debug_scroll -noxrecord -grab_buster - -nograb_buster -debug_grabs -debug_sel - -pointer_mode n -input_skip n -allinput - -input_eagerly -speeds rd,bw,lat -wmdt string - -debug_pointer -debug_keyboard -defer time - -wait time -extra_fbur n -wait_ui factor - -setdefer n -nowait_bog -slow_fb time - -xrefresh time -nap -nonap - -sb time -readtimeout n -ping n - -nofbpm -fbpm -nodpms - -dpms -forcedpms -clientdpms - -noserverdpms -noultraext -chatwindow - -noxdamage -xd_area A -xd_mem f - -sigpipe string -threads -nothreads - -fs f -gaps n -grow n - -fuzz n -debug_tiles -snapfb - -rawfb string -freqtab file -pipeinput cmd - -macnodim -macnosleep -macnosaver - -macnowait -macwheel n -macnoswap - -macnoresize -maciconanim n -macmenu - -macuskbd -gui [gui-opts] -remote command - -query variable -QD variable -sync - -query_retries str -remote_prefix str -noremote - -yesremote -unsafe -safer - -privremote -nocmds -allowedcmds list - -deny_all - -libvncserver options: + -no6 -noipv6 -noipv4 + -reopen -reflect host:N -id windowid + -sid windowid -appshare -clip WxH+X+Y + -flashcmap -shiftcmap n -notruecolor + -advertise_truecolor -visual n -overlay + -overlay_nocursor -8to24 [opts] -24to32 + -scale fraction -geometry WxH -scale_cursor frac + -viewonly -shared -once + -forever -loop -timeout n + -sleepin n -inetd -tightfilexfer + -ultrafilexfer -http -http_ssl + -avahi -mdns -zeroconf + -connect string -connect_or_exit str -proxy string + -vncconnect -novncconnect -allow host1[,host2..] + -localhost -listen6 str -nolookup + -input string -grabkbd -grabptr + -grabalways -viewpasswd string -passwdfile filename + -showrfbauth filename -unixpw [list] -unixpw_nis [list] + -unixpw_cmd cmd -find -finddpy + -listdpy -findauth [disp] -create + -xdummy -xvnc -xvnc_redirect + -xdummy_xvfb -create_xsrv str -svc + -svc_xdummy -svc_xvnc -svc_xdummy_xvfb + -xdmsvc -sshxdmsvc -unixpw_system_greeter + -redirect port -display WAIT:... -vencrypt mode + -anontls mode -sslonly -dhparams file + -nossl -ssl [pem] -ssltimeout n + -sslnofail -ssldir dir -sslverify path + -sslCRL path -sslGenCA [dir] -sslGenCert type name + -sslEncKey pem -sslCertInfo pem -sslDelCert pem + -sslScripts -stunnel [pem] -stunnel3 [pem] + -enc cipher:keyfile -https [port] -httpsredir [port] + -http_oneport -ssh user@host:disp -usepw + -storepasswd pass file -nopw -accept string + -afteraccept string -gone string -users list + -noshm -flipbyteorder -onetile + -solid [color] -blackout string -xinerama + -noxinerama -xtrap -xrandr [mode] + -rotate string -padgeom WxH -o logfile + -flag file -rmflag file -rc filename + -norc -env VAR=VALUE -prog /path/to/x11vnc + -h, -help -?, -opts -V, -version + -license -dbg -q, -quiet + -v, -verbose -bg -modtweak + -nomodtweak -xkb -noxkb + -capslock -skip_lockkeys -noskip_lockkeys + -skip_keycodes string -sloppy_keys -skip_dups + -noskip_dups -add_keysyms -noadd_keysyms + -clear_mods -clear_keys -clear_all + -remap string -norepeat -repeat + -nofb -nobell -nosel + -noprimary -nosetprimary -noclipboard + -nosetclipboard -seldir string -cursor [mode] + -nocursor -cursor_drag -arrow n + -noxfixes -alphacut n -alphafrac fraction + -alpharemove -noalphablend -nocursorshape + -cursorpos -nocursorpos -xwarppointer + -noxwarppointer -buttonmap string -nodragging + -ncache n -ncache_cr -ncache_no_moveraise + -ncache_no_dtchange -ncache_no_rootpixmap -ncache_keep_anims + -ncache_old_wm -ncache_pad n -debug_ncache + -wireframe [str] -nowireframe -nowireframelocal + -wirecopyrect mode -nowirecopyrect -debug_wireframe + -scrollcopyrect mode -noscrollcopyrect -scr_area n + -scr_skip list -scr_inc list -scr_keys list + -scr_term list -scr_keyrepeat lo-hi -scr_parms string + -fixscreen string -debug_scroll -noxrecord + -grab_buster -nograb_buster -debug_grabs + -debug_sel -pointer_mode n -input_skip n + -allinput -input_eagerly -speeds rd,bw,lat + -wmdt string -debug_pointer -debug_keyboard + -defer time -wait time -extra_fbur n + -wait_ui factor -setdefer n -nowait_bog + -slow_fb time -xrefresh time -nap + -nonap -sb time -readtimeout n + -ping n -nofbpm -fbpm + -nodpms -dpms -forcedpms + -clientdpms -noserverdpms -noultraext + -chatwindow -noxdamage -xd_area A + -xd_mem f -sigpipe string -threads + -nothreads -fs f -gaps n + -grow n -fuzz n -debug_tiles + -snapfb -rawfb string -freqtab file + -pipeinput cmd -macnodim -macnosleep + -macnosaver -macnowait -macwheel n + -macnoswap -macnoresize -maciconanim n + -macmenu -macuskbd -gui [gui-opts] + -remote command -query variable -QD variable + -sync -query_retries str -remote_prefix str + -noremote -yesremote -unsafe + -safer -privremote -nocmds + -allowedcmds list -deny_all + +LibVNCServer options: -rfbport port TCP port for RFB protocol -rfbwait time max time in ms to wait for RFB client -rfbauth passwd-file use authentication on RFB protocol @@ -12201,7 +12206,7 @@ libvncserver-tight-extension options: % x11vnc -help -x11vnc: allow VNC connections to real X11 displays. 0.9.10 lastmod: 2010-04-08 +x11vnc: allow VNC connections to real X11 displays. 0.9.10 lastmod: 2010-04-18 (type "x11vnc -opts" to just list the options.) @@ -12287,27 +12292,39 @@ Options: The default is to start probing at 5900. Use this to stay away from other VNC servers near 5900. --rfbport str The VNC port to listen on (a libvncserver option), e.g. +-rfbport str The VNC port to listen on (a LibVNCServer option), e.g. 5900, 5901, etc. If specified as "-rfbport PROMPT" then the x11vnc -gui is used to prompt the user to enter the port number. -6 IPv6 listening support. In addition to IPv4, the IPv6 address is listened on for incoming connections. - The same port as IPv4 is used to listen. If you have - trouble compiling for this mode, set -DX11VNC_IPV6=0 - in CPPFLAGS when configuring. + The same port as IPv4 is used. - Currently, the machine may need to have some IPv4 - support, at the least for the loopback interface, for - everything to work correctly. However for most usage - modes IPv4 support is not required. + NOTE: This x11vnc binary was compiled to have the + "-6" IPv6 listening mode ENABLED by default (CPPFLAGS + -DX11VNC_LISTEN6=1). So to disable IPv6 listening mode + you MUST supply the "-no6" option (see below.) - The -6 mode works for both normal connections and + The "-6" mode works for both normal connections and -ssl encrypted ones. Nearly everything is supported for the IPv6 case, but there are a few exceptions. See -stunnel for its IPv6 support. + Currently, for absolutely everything to work correctly + the machine may need to have some IPv4 support, at the + least for the loopback interface. However, for nearly + all usage modes no IPv4 support is required. See -nopiv4 +. + + If you have trouble compiling or running in IPv6 mode, + set -DX11VNC_IPV6=0 in CPPFLAGS when configuring to + disable IPv6 support. + +-no6 Disable IPv6 listening support (only useful if the + "-6" mode is compiled in to be the default; see the + X11VNC_LISTEN6 description above under "-6".) + -noipv6 Do not try to use IPv6 for any listening or connecting sockets. This includes both the listening service port(s) and outgoing connections from -connect, @@ -12664,7 +12681,7 @@ Options: Also, tightfilexfer is disabled in -unixpw mode. -ultrafilexfer Note: to enable UltraVNC filetransfer and to get it to - work you probably need to supply these libvncserver + work you probably need to supply these LibVNCServer options: "-rfbversion 3.6 -permitfiletransfer" "-ultrafilexfer" is an alias for this combination. @@ -12777,6 +12794,8 @@ Options: -connect_or_exit str As with -connect, except if none of the reverse connections succeed, then x11vnc shuts down immediately + An easier to type alias for this option is '-coe' + By the way, if you do not want x11vnc to listen on ANY interface use -rfbport 0 which is handy for the -connect_or_exit mode. @@ -12867,7 +12886,7 @@ Options: the comma separated list of hostnames or IP addresses. Can also be a numerical IP prefix, e.g. "192.168.100." to match a simple subnet, for more control build - libvncserver with libwrap support (See the FAQ). If the + LibVNCServer with libwrap support (See the FAQ). If the list contains a "/" it instead is a interpreted as a file containing addresses or prefixes that is re-read each time a new client connects. Lines can be @@ -12900,10 +12919,11 @@ Options: IPv6: if IPv6 is supported, this option automatically implies the IPv6 loopback address '::1' as well. --listen6 str When in IPv6 listen mode "-6", only listen on the - network interface with address "str". It currently - does not work for link scope addresses or non-numeric - hostname strings. +-listen6 str When in IPv6 listen mode "-6", listen only on the + network interface with address "str". It also works + for link scope addresses (fe80::219:dbff:fee5:3f92%eth0) + and IPv6 hostname strings (e.g. ipv6.google.com.) + Use LibVNCServer -listen option for the IPv4 interface. -nolookup Do not use gethostbyname() or gethostbyaddr() to look up host names or IP numbers. Use this if name resolution @@ -12952,7 +12972,7 @@ Options: -viewpasswd string Supply a 2nd password for view-only logins. The -passwd (full-access) password must also be supplied. --passwdfile filename Specify the libvncserver password via the first line +-passwdfile filename Specify the LibVNCServer password via the first line of the file "filename" (instead of via -passwd on the command line where others might see it via ps(1)). @@ -14629,10 +14649,10 @@ Options: the network (i.e. you just want the single VNC/HTTPS port, e.g. 5900, open for connections) then specify the option -env X11VNC_HTTP_LISTEN_LOCALHOST=1 This way - the connection to the libvncserver httpd server will + the connection to the LibVNCServer httpd server will only be available on localhost (note that in -ssl mode, HTTPS requests are redirected from SSL to the non-SSL - libvncserver HTTP server.) + LibVNCServer HTTP server.) -http_oneport For UN-encrypted connections mode (i.e. no -ssl, -stunnel, or -enc options), allow the Java VNC Viewer @@ -14666,7 +14686,7 @@ Options: Note that the -env X11VNC_HTTP_LISTEN_LOCALHOST=1 option described above under -httpsredir applies for - the libvncserver httpd server in all cases (ssl or not.) + the LibVNCServer httpd server in all cases (ssl or not.) -ssh user@host:disp Create a remote listening port on machine "host" via a SSH tunnel using the -R rport:localhost:lport @@ -14681,7 +14701,7 @@ Options: username differs from the current one. By default the remote sshd is usually configured to - only listen on localhost for rport, so the viewer may + listen only on localhost for rport, so the viewer may need to ssh -L redir to "host" as well (See SSVNC to automate this). The sshd setting GatewayPorts enables listening on all interfaces for rport; viewers can @@ -15015,7 +15035,7 @@ t where you resize often. It is best to be viewing with a vncviewer that supports the NewFBSize encoding, since it knows how to react to screen size changes. Otherwise, - libvncserver tries to do so something reasonable for + LibVNCServer tries to do so something reasonable for viewers that cannot do this (portions of the screen may be clipped, unused, etc). @@ -15459,7 +15479,7 @@ t alpha factor. (useful for light colored semi-transparent cursors). -noalphablend In XFIXES mode do not send cursor alpha channel data - to libvncserver. The default is to send it. The + to LibVNCServer. The default is to send it. The alphablend effect will only be visible in -nocursorshape mode or for clients with cursorshapeupdates turned off. (However there is a hack for 32bpp with depth 24, @@ -16105,9 +16125,9 @@ t to really throttle down the screen polls (i.e. sleep for about 1.5 secs). Use 0 to disable. Default: 60 --readtimeout n Set libvncserver rfbMaxClientWait to n seconds. On +-readtimeout n Set LibVNCServer rfbMaxClientWait to n seconds. On slow links that take a long time to paint the first - screen libvncserver may hit the timeout and drop the + screen LibVNCServer may hit the timeout and drop the connection. Default: 20 seconds. -ping n Send a 1x1 framebuffer update to all clients every n seconds (e.g. to try to keep a network connection alive) @@ -16177,7 +16197,7 @@ t skip powering off the monitor. -noultraext Disable the following UltraVNC extensions: SingleWindow - and ServerInput. The others managed by libvncserver + and ServerInput. The others managed by LibVNCServer (textchat, 1/n scaling, rfbEncodingUltra) are not. -chatwindow Place a local UltraVNC chat window on the X11 display @@ -16231,12 +16251,12 @@ t (perhaps useful on a slow machine). -sigpipe string Broken pipe (SIGPIPE) handling. "string" can be - "ignore" or "exit". For "ignore" libvncserver + "ignore" or "exit". For "ignore" LibVNCServer will handle the abrupt loss of a client and continue, for "exit" x11vnc will cleanup and exit at the 1st broken connection. - This option is not really needed since libvncserver + This option is not really needed since LibVNCServer is doing the correct thing now for quite some time. However, for convenience you can use it to ignore other signals, e.g. "-sigpipe ignore:HUP,INT,TERM" in case @@ -16246,7 +16266,7 @@ t for this option if you don't like the 'pipe'. Example: -sig ignore:INT,TERM,exit:USR1 --threads Whether or not to use the threaded libvncserver +-threads Whether or not to use the threaded LibVNCServer -nothreads algorithm [rfbRunEventLoop] if libpthread is available. In this mode new threads (one for input and one for output) are created to handle each new client. @@ -16506,7 +16526,7 @@ er view and possibly interact with the Linux text/graphics console (i.e. not X11 XFree86/Xorg) - Note: If the libvncserver LinuxVNC program is on your + Note: If the LibVNCServer LinuxVNC program is on your system you may want to use that instead of the following method because it will be faster and more accurate for the Linux text console and includes mouse support. @@ -17285,7 +17305,7 @@ n uinput_thresh:n set uinput_thresh to n. uinput_reset:n set uinput_reset to n ms. uinput_always:n set uinput_always to 1/0. - progressive:n set libvncserver -progressive slice + progressive:n set LibVNCServer -progressive slice height parameter to n. desktop:str set -desktop name to str for new clients . @@ -17667,7 +17687,7 @@ n -These options are passed to libvncserver: +These options are passed to LibVNCServer: -rfbport port TCP port for RFB protocol -rfbwait time max time in ms to wait for RFB client diff --git a/x11vnc/appshare.c b/x11vnc/appshare.c index 14d2712..fc3c29e 100644 --- a/x11vnc/appshare.c +++ b/x11vnc/appshare.c @@ -1925,7 +1925,7 @@ int appshare_main(int argc, char *argv[]) { id_opt = "-sid"; if (end) exiter("no -sid value supplied\n", 1); app_str = strdup(argv[++i]); - } else if (!strcmp(s, "-connect") || !strcmp(s, "-connect_or_exit")) { + } else if (!strcmp(s, "-connect") || !strcmp(s, "-connect_or_exit") || !strcmp(s, "-coe")) { if (end) exiter("no -connect value supplied\n", 1); connect_to = strdup(argv[++i]); } else if (!strcmp(s, "-control")) { diff --git a/x11vnc/connections.c b/x11vnc/connections.c index f465325..c664377 100644 --- a/x11vnc/connections.c +++ b/x11vnc/connections.c @@ -308,7 +308,7 @@ static rfbClientPtr *client_match(char *str) { } if (ipv6_ip(str)) { ; - } else if (! dotted_ip(str)) { + } else if (! dotted_ip(str, 0)) { char *orig = rstr; rstr = host2ip(rstr); free(orig); @@ -385,7 +385,7 @@ void set_client_input(char *str) { return; } - p = strchr(str, ':'); + p = strrchr(str, ':'); if (! p) { return; } @@ -1067,7 +1067,7 @@ int check_access(char *addr) { } if (ipv6_ip(p)) { chk = p; - } else if (! dotted_ip(p)) { + } else if (! dotted_ip(p, 1)) { r = host2ip(p); if (r == NULL || *r == '\0') { rfbLog("check_access: bad lookup \"%s\"\n", p); @@ -1837,9 +1837,8 @@ void check_ipv6_listen(long usec) { screen->httpListenSock = save; } } -#else - if (usec) {} #endif + if (usec) {} } /* diff --git a/x11vnc/help.c b/x11vnc/help.c index 55ad36a..c23112c 100644 --- a/x11vnc/help.c +++ b/x11vnc/help.c @@ -136,7 +136,7 @@ void print_help(int mode) { " The default is to start probing at 5900. Use this to\n" " stay away from other VNC servers near 5900.\n" "\n" -"-rfbport str The VNC port to listen on (a libvncserver option), e.g.\n" +"-rfbport str The VNC port to listen on (a LibVNCServer option), e.g.\n" " 5900, 5901, etc. If specified as \"-rfbport PROMPT\"\n" " then the x11vnc -gui is used to prompt the user to\n" " enter the port number.\n" @@ -144,20 +144,37 @@ void print_help(int mode) { #if X11VNC_IPV6 "-6 IPv6 listening support. In addition to IPv4, the\n" " IPv6 address is listened on for incoming connections.\n" -" The same port as IPv4 is used to listen. If you have\n" -" trouble compiling for this mode, set -DX11VNC_IPV6=0\n" -" in CPPFLAGS when configuring.\n" +" The same port as IPv4 is used.\n" "\n" -" Currently, the machine may need to have some IPv4\n" -" support, at the least for the loopback interface, for\n" -" everything to work correctly. However for most usage\n" -" modes IPv4 support is not required.\n" +#if X11VNC_LISTEN6 +" NOTE: This x11vnc binary was compiled to have the\n" +" \"-6\" IPv6 listening mode ENABLED by default (CPPFLAGS\n" +" -DX11VNC_LISTEN6=1). So to disable IPv6 listening mode\n" +" you MUST supply the \"-no6\" option (see below.)\n" +#else +" NOTE: This x11vnc binary was compiled to have\n" +" the \"-6\" IPv6 listening mode DISABLED by default\n" +" (CPPFLAGS -DX11VNC_LISTEN6=0).\n" +#endif "\n" -" The -6 mode works for both normal connections and\n" +" The \"-6\" mode works for both normal connections and\n" " -ssl encrypted ones. Nearly everything is supported\n" " for the IPv6 case, but there are a few exceptions.\n" " See -stunnel for its IPv6 support.\n" "\n" +" Currently, for absolutely everything to work correctly\n" +" the machine may need to have some IPv4 support, at the\n" +" least for the loopback interface. However, for nearly\n" +" all usage modes no IPv4 support is required. See -nopiv4.\n" +"\n" +" If you have trouble compiling or running in IPv6 mode,\n" +" set -DX11VNC_IPV6=0 in CPPFLAGS when configuring to\n" +" disable IPv6 support.\n" +"\n" +"-no6 Disable IPv6 listening support (only useful if the\n" +" \"-6\" mode is compiled in to be the default; see the\n" +" X11VNC_LISTEN6 description above under \"-6\".)\n" +"\n" "-noipv6 Do not try to use IPv6 for any listening or connecting\n" " sockets. This includes both the listening service\n" " port(s) and outgoing connections from -connect,\n" @@ -522,7 +539,7 @@ void print_help(int mode) { " Also, tightfilexfer is disabled in -unixpw mode.\n" "\n" "-ultrafilexfer Note: to enable UltraVNC filetransfer and to get it to\n" -" work you probably need to supply these libvncserver\n" +" work you probably need to supply these LibVNCServer\n" " options: \"-rfbversion 3.6 -permitfiletransfer\"\n" " \"-ultrafilexfer\" is an alias for this combination.\n" "\n" @@ -635,6 +652,8 @@ void print_help(int mode) { "-connect_or_exit str As with -connect, except if none of the reverse\n" " connections succeed, then x11vnc shuts down immediately\n" "\n" +" An easier to type alias for this option is '-coe'\n" +"\n" " By the way, if you do not want x11vnc to listen on\n" " ANY interface use -rfbport 0 which is handy for the\n" " -connect_or_exit mode.\n" @@ -725,7 +744,7 @@ void print_help(int mode) { " the comma separated list of hostnames or IP addresses.\n" " Can also be a numerical IP prefix, e.g. \"192.168.100.\"\n" " to match a simple subnet, for more control build\n" -" libvncserver with libwrap support (See the FAQ). If the\n" +" LibVNCServer with libwrap support (See the FAQ). If the\n" " list contains a \"/\" it instead is a interpreted\n" " as a file containing addresses or prefixes that is\n" " re-read each time a new client connects. Lines can be\n" @@ -759,10 +778,11 @@ void print_help(int mode) { " implies the IPv6 loopback address '::1' as well.\n" "\n" #if X11VNC_IPV6 -"-listen6 str When in IPv6 listen mode \"-6\", only listen on the\n" -" network interface with address \"str\". It currently\n" -" does not work for link scope addresses or non-numeric\n" -" hostname strings.\n" +"-listen6 str When in IPv6 listen mode \"-6\", listen only on the\n" +" network interface with address \"str\". It also works\n" +" for link scope addresses (fe80::219:dbff:fee5:3f92%%eth0)\n" +" and IPv6 hostname strings (e.g. ipv6.google.com.)\n" +" Use LibVNCServer -listen option for the IPv4 interface.\n" "\n" #endif "-nolookup Do not use gethostbyname() or gethostbyaddr() to look up\n" @@ -822,7 +842,7 @@ void print_help(int mode) { "-viewpasswd string Supply a 2nd password for view-only logins. The -passwd\n" " (full-access) password must also be supplied.\n" "\n" -"-passwdfile filename Specify the libvncserver password via the first line\n" +"-passwdfile filename Specify the LibVNCServer password via the first line\n" " of the file \"filename\" (instead of via -passwd on\n" " the command line where others might see it via ps(1)).\n" "\n" @@ -2499,10 +2519,10 @@ void print_help(int mode) { " the network (i.e. you just want the single VNC/HTTPS\n" " port, e.g. 5900, open for connections) then specify the\n" " option -env X11VNC_HTTP_LISTEN_LOCALHOST=1 This way\n" -" the connection to the libvncserver httpd server will\n" +" the connection to the LibVNCServer httpd server will\n" " only be available on localhost (note that in -ssl mode,\n" " HTTPS requests are redirected from SSL to the non-SSL\n" -" libvncserver HTTP server.)\n" +" LibVNCServer HTTP server.)\n" "\n" "-http_oneport For UN-encrypted connections mode (i.e. no -ssl,\n" " -stunnel, or -enc options), allow the Java VNC Viewer\n" @@ -2536,7 +2556,7 @@ void print_help(int mode) { "\n" " Note that the -env X11VNC_HTTP_LISTEN_LOCALHOST=1\n" " option described above under -httpsredir applies for\n" -" the libvncserver httpd server in all cases (ssl or not.)\n" +" the LibVNCServer httpd server in all cases (ssl or not.)\n" "\n" "-ssh user@host:disp Create a remote listening port on machine \"host\"\n" " via a SSH tunnel using the -R rport:localhost:lport\n" @@ -2551,7 +2571,7 @@ void print_help(int mode) { " username differs from the current one.\n" "\n" " By default the remote sshd is usually configured to\n" -" only listen on localhost for rport, so the viewer may\n" +" listen only on localhost for rport, so the viewer may\n" " need to ssh -L redir to \"host\" as well (See SSVNC to\n" " automate this). The sshd setting GatewayPorts enables\n" " listening on all interfaces for rport; viewers can\n" @@ -2884,7 +2904,7 @@ void print_help(int mode) { " where you resize often. It is best to be viewing with a\n" " vncviewer that supports the NewFBSize encoding, since it\n" " knows how to react to screen size changes. Otherwise,\n" -" libvncserver tries to do so something reasonable for\n" +" LibVNCServer tries to do so something reasonable for\n" " viewers that cannot do this (portions of the screen\n" " may be clipped, unused, etc).\n" "\n" @@ -3327,7 +3347,7 @@ void print_help(int mode) { " alpha factor. (useful for light colored semi-transparent\n" " cursors).\n" "-noalphablend In XFIXES mode do not send cursor alpha channel data\n" -" to libvncserver. The default is to send it. The\n" +" to LibVNCServer. The default is to send it. The\n" " alphablend effect will only be visible in -nocursorshape\n" " mode or for clients with cursorshapeupdates turned\n" " off. (However there is a hack for 32bpp with depth 24,\n" @@ -3975,9 +3995,9 @@ void print_help(int mode) { " to really throttle down the screen polls (i.e. sleep\n" " for about 1.5 secs). Use 0 to disable. Default: %d\n" "\n" -"-readtimeout n Set libvncserver rfbMaxClientWait to n seconds. On\n" +"-readtimeout n Set LibVNCServer rfbMaxClientWait to n seconds. On\n" " slow links that take a long time to paint the first\n" -" screen libvncserver may hit the timeout and drop the\n" +" screen LibVNCServer may hit the timeout and drop the\n" " connection. Default: %d seconds.\n" "-ping n Send a 1x1 framebuffer update to all clients every n\n" " seconds (e.g. to try to keep a network connection alive)\n" @@ -4046,7 +4066,7 @@ void print_help(int mode) { " skip powering off the monitor.\n" "\n" "-noultraext Disable the following UltraVNC extensions: SingleWindow\n" -" and ServerInput. The others managed by libvncserver\n" +" and ServerInput. The others managed by LibVNCServer\n" " (textchat, 1/n scaling, rfbEncodingUltra) are not.\n" "\n" "-chatwindow Place a local UltraVNC chat window on the X11 display\n" @@ -4100,12 +4120,12 @@ void print_help(int mode) { " (perhaps useful on a slow machine).\n" "\n" "-sigpipe string Broken pipe (SIGPIPE) handling. \"string\" can be\n" -" \"ignore\" or \"exit\". For \"ignore\" libvncserver\n" +" \"ignore\" or \"exit\". For \"ignore\" LibVNCServer\n" " will handle the abrupt loss of a client and continue,\n" " for \"exit\" x11vnc will cleanup and exit at the 1st\n" " broken connection.\n" "\n" -" This option is not really needed since libvncserver\n" +" This option is not really needed since LibVNCServer\n" " is doing the correct thing now for quite some time.\n" " However, for convenience you can use it to ignore other\n" " signals, e.g. \"-sigpipe ignore:HUP,INT,TERM\" in case\n" @@ -4115,7 +4135,7 @@ void print_help(int mode) { " for this option if you don't like the 'pipe'. Example:\n" " -sig ignore:INT,TERM,exit:USR1\n" "\n" -"-threads Whether or not to use the threaded libvncserver\n" +"-threads Whether or not to use the threaded LibVNCServer\n" "-nothreads algorithm [rfbRunEventLoop] if libpthread is available.\n" " In this mode new threads (one for input and one\n" " for output) are created to handle each new client.\n" @@ -4374,7 +4394,7 @@ void print_help(int mode) { " view and possibly interact with the Linux text/graphics\n" " console (i.e. not X11 XFree86/Xorg)\n" "\n" -" Note: If the libvncserver LinuxVNC program is on your\n" +" Note: If the LibVNCServer LinuxVNC program is on your\n" " system you may want to use that instead of the following\n" " method because it will be faster and more accurate\n" " for the Linux text console and includes mouse support.\n" @@ -5158,7 +5178,7 @@ void print_help(int mode) { " uinput_thresh:n set uinput_thresh to n.\n" " uinput_reset:n set uinput_reset to n ms.\n" " uinput_always:n set uinput_always to 1/0.\n" -" progressive:n set libvncserver -progressive slice\n" +" progressive:n set LibVNCServer -progressive slice\n" " height parameter to n.\n" " desktop:str set -desktop name to str for new clients.\n" " rfbport:n set -rfbport to n.\n" @@ -5540,7 +5560,7 @@ void print_help(int mode) { "\n" "%s\n" "\n" -"These options are passed to libvncserver:\n" +"These options are passed to LibVNCServer:\n" "\n" ; /* have both our help and rfbUsage to stdout for more(1), etc. */ @@ -5571,7 +5591,7 @@ void print_help(int mode) { } p = strtok(NULL, "\n"); } - fprintf(stderr, "\n\nlibvncserver options:\n"); + fprintf(stderr, "\n\nLibVNCServer options:\n"); rfbUsage(); fprintf(stderr, "\n"); exit(1); diff --git a/x11vnc/inet.c b/x11vnc/inet.c index 60e26f5..a70ce24 100644 --- a/x11vnc/inet.c +++ b/x11vnc/inet.c @@ -45,7 +45,7 @@ char *raw2host(char *raw, int len); char *raw2ip(char *raw); char *ip2host(char *ip); int ipv6_ip(char *host); -int dotted_ip(char *host); +int dotted_ip(char *host, int partial); int get_remote_port(int sock); int get_local_port(int sock); char *get_remote_host(int sock); @@ -143,8 +143,8 @@ int ipv6_ip(char *host_in) { host = host_in; } - if (strstr(host, "::ffff:") == host) { - return dotted_ip(host + strlen("::ffff:")); + if (strstr(host, "::ffff:") == host || strstr(host, "::FFFF:") == host) { + return dotted_ip(host + strlen("::ffff:"), 0); } a[1] = '\0'; @@ -170,15 +170,34 @@ int ipv6_ip(char *host_in) { } } -int dotted_ip(char *host) { +int dotted_ip(char *host, int partial) { + int len, dots = 0; char *p = host; + + if (!host) { + return 0; + } + + if (!isdigit((unsigned char) host[0])) { + return 0; + } + + len = strlen(host); + if (!partial && !isdigit((unsigned char) host[len-1])) { + return 0; + } + while (*p != '\0') { + if (*p == '.') dots++; if (*p == '.' || isdigit((unsigned char) (*p))) { p++; continue; } return 0; } + if (!partial && dots != 3) { + return 0; + } return 1; } @@ -253,7 +272,6 @@ char *ident_username(rfbClientPtr client) { user = cd->username; } if (!user || *user == '\0') { - char msg[128]; int n, sock, ok = 0; int block = 0; int refused = 0; @@ -310,6 +328,7 @@ char *ident_username(rfbClientPtr client) { rfbLog("ident_username: could not connect to ident: %s:%d\n", client->host, 113); } else { + char msg[128]; int ret; fd_set rfds; struct timeval tv; @@ -321,14 +340,14 @@ char *ident_username(rfbClientPtr client) { FD_ZERO(&rfds); FD_SET(sock, &rfds); - tv.tv_sec = 4; + tv.tv_sec = 3; tv.tv_usec = 0; ret = select(sock+1, &rfds, NULL, NULL, &tv); if (ret > 0) { int i; char *q, *p; - for (i=0; i<128; i++) { + for (i=0; i < sizeof(msg); i++) { msg[i] = '\0'; } usleep(250*1000); @@ -504,7 +523,7 @@ char *ipv6_getnameinfo(struct sockaddr *paddr, int addrlen) { } char *ipv6_getipaddr(struct sockaddr *paddr, int addrlen) { -#if X11VNC_IPV6 +#if X11VNC_IPV6 && defined(NI_NUMERICHOST) char name[200]; if (noipv6) { return strdup("unknown"); @@ -524,22 +543,27 @@ int listen6(int port) { if (noipv6) { return -1; } + if (port <= 0 || 65535 < port) { + /* for us, invalid port means do not listen. */ + return -1; + } fd = socket(AF_INET6, SOCK_STREAM, 0); if (fd < 0) { rfbLogPerror("listen6: socket"); + rfbLog("(Ignore the above error if this system is IPv4-only.)\n"); return -1; } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) { - rfbLogPerror("listen6: setsockopt1"); + rfbLogPerror("listen6: setsockopt SO_REUSEADDR"); close(fd); return -1; } #if defined(SOL_IPV6) && defined(IPV6_V6ONLY) if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) { - rfbLogPerror("listen6: setsockopt2"); + rfbLogPerror("listen6: setsockopt IPV6_V6ONLY"); close(fd); return -1; } @@ -551,19 +575,57 @@ int listen6(int port) { sin.sin6_addr = in6addr_any; if (listen_str6) { - if (!strcmp(listen_str6, "localhost")) { + if (!strcmp(listen_str6, "localhost") || !strcmp(listen_str6, "::1")) { sin.sin6_addr = in6addr_loopback; - } else if (ipv6_ip(listen_str6)) { - int err = inet_pton(AF_INET6, listen_str6, &(sin.sin6_addr)); - if (err <= 0) { - rfbLog("inet_pton[%d] failed -listen6 %s\n", err, listen_str6); + } else { + int err; + struct addrinfo *ai; + struct addrinfo hints; + char service[32]; + + memset(&hints, 0, sizeof(hints)); + sprintf(service, "%d", port); + + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_STREAM; +#ifdef AI_ADDRCONFIG + hints.ai_flags |= AI_ADDRCONFIG; +#endif +#ifdef AI_NUMERICHOST + if(ipv6_ip(listen_str6)) { + hints.ai_flags |= AI_NUMERICHOST; + } +#endif +#ifdef AI_NUMERICSERV + hints.ai_flags |= AI_NUMERICSERV; +#endif + err = getaddrinfo(listen_str6, service, &hints, &ai); + if (err == 0) { + struct addrinfo *ap = ai; + err = 1; + while (ap != NULL) { + char *s = ipv6_getipaddr(ap->ai_addr, ap->ai_addrlen); + if (!s) s = strdup("unknown"); + + rfbLog("listen6: checking: %s family: %d\n", s, ap->ai_family); + if (ap->ai_family == AF_INET6) { + memcpy((char *)&sin, ap->ai_addr, sizeof(sin)); + rfbLog("listen6: using: %s scope_id: %d\n", s, sin.sin6_scope_id); + err = 0; + free(s); + break; + } + free(s); + ap = ap->ai_next; + } + freeaddrinfo(ai); + } + + if (err != 0) { + rfbLog("Invalid or Unsupported -listen6 string: %s\n", listen_str6); close(fd); return -1; } - } else { - rfbLog("Unsupported -listen6 string: %s\n", listen_str6); - close(fd); - return -1; } } else if (allow_list && !strcmp(allow_list, "127.0.0.1")) { sin.sin6_addr = in6addr_loopback; @@ -625,7 +687,7 @@ int connect_tcp(char *host, int port) { } if (fd < 0 && !noipv6) { -#if X11VNC_IPV6 && defined(AI_ADDRCONFIG) +#if X11VNC_IPV6 int err; struct addrinfo *ai; struct addrinfo hints; @@ -638,13 +700,13 @@ int connect_tcp(char *host, int port) { hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_ADDRCONFIG; +#ifdef AI_ADDRCONFIG + hints.ai_flags |= AI_ADDRCONFIG; +#endif if(ipv6_ip(host)) { #ifdef AI_NUMERICHOST rfbLog("connect_tcp[ipv6]: setting AI_NUMERICHOST for %s\n", host); hints.ai_flags |= AI_NUMERICHOST; -#else - rfbLog("connect_tcp[ipv6]: no AI_NUMERICHOST for %s\n", host); #endif } #ifdef AI_NUMERICSERV @@ -662,7 +724,6 @@ int connect_tcp(char *host, int port) { if (q) { *q = '\0'; } - err = getaddrinfo(host2, service, &hints, &ai); if (err != 0) { @@ -677,14 +738,53 @@ int connect_tcp(char *host, int port) { } else { struct addrinfo *ap = ai; while (ap != NULL) { - int sock = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol); + int sock; + + if (fail4) { + struct sockaddr_in6 *s6ptr; + if (ap->ai_family != AF_INET6) { + rfbLog("connect_tcp[ipv6]: skipping AF_INET address under -noipv4\n"); + ap = ap->ai_next; + continue; + } +#ifdef IN6_IS_ADDR_V4MAPPED + s6ptr = (struct sockaddr_in6 *) ap->ai_addr; + if (IN6_IS_ADDR_V4MAPPED(&(s6ptr->sin6_addr))) { + rfbLog("connect_tcp[ipv6]: skipping V4MAPPED address under -noipv4\n"); + ap = ap->ai_next; + continue; + } +#endif + } + + sock = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol); + if (sock == -1) { rfbLogPerror("connect_tcp[ipv6]: socket"); + if (0) rfbLog("(Ignore the above error if this system is IPv4-only.)\n"); } else { + int res = -1, dmsg = 0; char *s = ipv6_getipaddr(ap->ai_addr, ap->ai_addrlen); if (!s) s = strdup("unknown"); - rfbLog("connect_tcp[ipv6]: trying sock=%d using %s\n", sock, s); - if (connect(sock, ap->ai_addr, ap->ai_addrlen) == 0) { + + rfbLog("connect_tcp[ipv6]: trying sock=%d fam=%d proto=%d using %s\n", + sock, ap->ai_family, ap->ai_protocol, s); + res = connect(sock, ap->ai_addr, ap->ai_addrlen); +#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) + if (res != 0) { + int zero = 0; + rfbLogPerror("connect_tcp[ipv6]: connect"); + dmsg = 1; + if (setsockopt(sock, SOL_IPV6, IPV6_V6ONLY, (char *)&zero, sizeof(zero)) == 0) { + rfbLog("connect_tcp[ipv6]: trying again with IPV6_V6ONLY=0\n"); + res = connect(sock, ap->ai_addr, ap->ai_addrlen); + dmsg = 0; + } else { + rfbLogPerror("connect_tcp[ipv6]: setsockopt IPV6_V6ONLY"); + } + } +#endif + if (res == 0) { rfbLog("connect_tcp[ipv6]: connect OK\n"); fd = sock; if (!ipv6_client_ip_str) { @@ -693,8 +793,8 @@ int connect_tcp(char *host, int port) { free(s); break; } else { + if (!dmsg) rfbLogPerror("connect_tcp[ipv6]: connect"); close(sock); - rfbLogPerror("connect_tcp[ipv6]: connect"); } free(s); } @@ -704,6 +804,30 @@ int connect_tcp(char *host, int port) { } #endif } + if (fd < 0 && !fail4) { + /* this is a kludge for IPv4-only machines getting v4mapped string. */ + char *q, *host2; + if (host[0] == '[') { + host2 = strdup(host+1); + } else { + host2 = strdup(host); + } + q = strrchr(host2, ']'); + if (q) { + *q = '\0'; + } + if (strstr(host2, "::ffff:") == host2 || strstr(host2, "::FFFF:") == host2) { + char *host3 = host2 + strlen("::ffff:"); + if (dotted_ip(host3, 0)) { + rfbLog("connect_tcp[ipv4]: trying fallback to IPv4 for %s\n", host2); + fd = rfbConnectToTcpAddr(host3, port); + if (fd < 0) { + rfbLogPerror("connect_tcp[ipv4]: connection failed"); + } + } + } + free(host2); + } return fd; } @@ -714,6 +838,11 @@ int listen_tcp(int port, in_addr_t iface, int try6) { fail4 = 2; } + if (port <= 0 || 65535 < port) { + /* for us, invalid port means do not listen. */ + return -1; + } + if (fail4) { if (fail4 > 1) { rfbLog("TESTING: IPV4_FAILS for listen_tcp: port=%d try6=%d\n", port, try6); @@ -742,8 +871,6 @@ int listen_tcp(int port, in_addr_t iface, int try6) { fd = listen6(port); } listen_str6 = save; -#else - if (try6) {} #endif } return fd; diff --git a/x11vnc/inet.h b/x11vnc/inet.h index ae1c830..f74251e 100644 --- a/x11vnc/inet.h +++ b/x11vnc/inet.h @@ -40,7 +40,7 @@ extern char *raw2host(char *raw, int len); extern char *raw2ip(char *raw); extern char *ip2host(char *ip); extern int ipv6_ip(char *host); -extern int dotted_ip(char *host); +extern int dotted_ip(char *host, int partial); extern int get_remote_port(int sock); extern int get_local_port(int sock); extern char *get_remote_host(int sock); diff --git a/x11vnc/misc/connect_switch b/x11vnc/misc/connect_switch index a25610d..08376c6 100755 --- a/x11vnc/misc/connect_switch +++ b/x11vnc/misc/connect_switch @@ -231,7 +231,11 @@ if (exists $ENV{CONNECT_SWITCH_LISTEN}) { # # E.g. CONNECT_SWITCH_LISTEN=192.168.0.32:443 # - ($listen_host, $listen_port) = split(/:/, $ENV{CONNECT_SWITCH_LISTEN}); + $listen_host = ''; + $listen_port = ''; + if ($ENV{CONNECT_SWITCH_LISTEN} =~ /^(.*):(\d+)$/) { + ($listen_host, $listen_port) = ($1, $2); + } } my $httpd_host = 'localhost'; @@ -241,7 +245,11 @@ if (exists $ENV{CONNECT_SWITCH_HTTPD}) { # # E.g. CONNECT_SWITCH_HTTPD=127.0.0.1:443 # - ($httpd_host, $httpd_port) = split(/:/, $ENV{CONNECT_SWITCH_HTTPD}); + $httpd_host = ''; + $httpd_port = ''; + if ($ENV{CONNECT_SWITCH_HTTPD} =~ /^(.*):(\d+)$/) { + ($httpd_host, $httpd_port) = ($1, $2); + } } my $bufsize = 8192; @@ -353,6 +361,12 @@ use IO::Socket::INET; use strict; use warnings; +# Test for INET6 support: +# +my $have_inet6 = 0; +eval "use IO::Socket::INET6;"; +$have_inet6 = 1 if $@ eq ""; + my $killpid = 1; setpgrp(0, 0); @@ -360,14 +374,13 @@ setpgrp(0, 0); if (exists $ENV{CONNECT_SWITCH_LISTEN_IPV6}) { # note we leave out LocalAddr. my $cmd = ' - use IO::Socket::INET6; - $listen_sock = IO::Socket::INET6->new( - Listen => 10, - LocalPort => $listen_port, - ReuseAddr => 1, - Domain => AF_INET6, - Proto => "tcp" - ); + $listen_sock = IO::Socket::INET6->new( + Listen => 10, + LocalPort => $listen_port, + ReuseAddr => 1, + Domain => AF_INET6, + Proto => "tcp" + ); '; eval $cmd; die "$@\n" if $@; @@ -493,8 +506,12 @@ sub handle_conn { if ($str =~ /^CONNECT\s+(\S+)\s+HTTP\/(\S+)/) { $hostport = $1; $http_vers = $2; + my $h = ''; + my $p = ''; - my ($h, $p) = split(/:/, $hostport); + if ($hostport =~ /^(.*):(\d+)$/) { + ($h, $p) = ($1, $2); + } if ($p =~ /^\d+$/) { # check allowed host list: foreach my $hp (@allow) { @@ -532,7 +549,12 @@ sub handle_conn { exit 0; } - my ($host, $port) = split(/:/, $hostport); + my $host = ''; + my $port = ''; + + if ($hostport =~ /^(.*):(\d+)$/) { + ($host, $port) = ($1, $2); + } print STDERR "connecting to: $host:$port\n" if $verbose; @@ -541,6 +563,15 @@ sub handle_conn { PeerPort => $port, Proto => "tcp" ); + print STDERR "connect to host='$host' port='$port' failed: $!\n" if !$sock; + if (! $sock && $have_inet6) { + eval {$sock = IO::Socket::INET6->new( + PeerAddr => $host, + PeerPort => $port, + Proto => "tcp" + );}; + print STDERR "connect to host='$host' port='$port' failed: $! (ipv6)\n" if !$sock; + } my $msg; # send the connect proxy reply: @@ -561,6 +592,13 @@ sub handle_conn { PeerPort => $httpd_port, Proto => "tcp" ); + if (! $sock && $have_inet6) { + eval {$sock = IO::Socket::INET6->new( + PeerAddr => $httpd_host, + PeerPort => $httpd_port, + Proto => "tcp" + );}; + } } if (! $sock) { diff --git a/x11vnc/misc/desktop.cgi b/x11vnc/misc/desktop.cgi index f656146..d99a39c 100755 --- a/x11vnc/misc/desktop.cgi +++ b/x11vnc/misc/desktop.cgi @@ -218,6 +218,11 @@ use strict; use IO::Socket::INET; +# Test for INET6 support: +# +my $have_inet6 = 0; +eval "use IO::Socket::INET6;"; +$have_inet6 = 1 if $@ eq ""; ########################################################################## # Path to the x11vnc program: @@ -261,6 +266,10 @@ my $find_free_port = 0; # my $starting_port = 7000; +# Listen on AF_INET6 if IO::Socket::INET6 is available. +# +my $listen_on_ipv6 = 0; + ########################################################################## # Port redirection mode: @@ -978,12 +987,24 @@ sub auto_select_port { # Now try to find a free one: # for (my $p = $pmin; $p <= $pmax; $p++) { - my $sock = IO::Socket::INET->new( - Listen => 1, - LocalPort => $p, - ReuseAddr => 1, - Proto => "tcp" - ); + my $sock = ''; + if ($have_inet6 && $listen_on_ipv6) { + eval {$sock = IO::Socket::INET6->new( + Listen => 1, + LocalPort => $p, + ReuseAddr => 1, + Domain => AF_INET6, + LocalAddr => "::", + Proto => "tcp" + );}; + } else { + $sock = IO::Socket::INET->new( + Listen => 1, + LocalPort => $p, + ReuseAddr => 1, + Proto => "tcp" + ); + } if ($sock) { # we will keep this open until we call x11vnc: $find_free_port = $sock; @@ -1159,12 +1180,23 @@ sub lock_fixed_port { $reason = 'locked'; } else { # unlocked, try to listen on port: - $sock = IO::Socket::INET->new( - Listen => 1, - LocalPort => $vnc_port, - ReuseAddr => 1, - Proto => "tcp" - ); + if ($have_inet6 && $listen_on_ipv6) { + eval {$sock = IO::Socket::INET6->new( + Listen => 1, + LocalPort => $vnc_port, + ReuseAddr => 1, + Domain => AF_INET6, + LocalAddr => "::", + Proto => "tcp" + );}; + } else { + $sock = IO::Socket::INET->new( + Listen => 1, + LocalPort => $vnc_port, + ReuseAddr => 1, + Proto => "tcp" + ); + } if ($sock) { # we got it, now try to lock: my $str = "$$:" . time(); @@ -1266,12 +1298,23 @@ sub port_redir { $rmlock = lock_fixed_port(90, 60); } elsif ($find_free_port eq '0') { - $find_free_port = IO::Socket::INET->new( - Listen => 1, - LocalPort => $vnc_port, - ReuseAddr => 1, - Proto => "tcp" - ); + if ($have_inet6 && $listen_on_ipv6) { + eval {$find_free_port = IO::Socket::INET6->new( + Listen => 1, + LocalPort => $vnc_port, + ReuseAddr => 1, + Domain => AF_INET6, + LocalAddr => "::", + Proto => "tcp" + );}; + } else { + $find_free_port = IO::Socket::INET->new( + Listen => 1, + LocalPort => $vnc_port, + ReuseAddr => 1, + Proto => "tcp" + ); + } } # In all cases, at this point $find_free_port is the listening # socket. @@ -1409,13 +1452,24 @@ sub handle_conn { exit 1; } - my ($host, $port) = split(/:/, $redirect_host); + my $host = ''; + my $port = ''; + if ($redirect_host =~ /^(.*):(\d+)$/) { + ($host, $port) = ($1, $2); + } my $sock = IO::Socket::INET->new( PeerAddr => $host, PeerPort => $port, Proto => "tcp" ); + if (! $sock && $have_inet6) { + eval {$sock = IO::Socket::INET6->new( + PeerAddr => $host, + PeerPort => $port, + Proto => "tcp" + );}; + } if (! $sock) { close $client; diff --git a/x11vnc/misc/ultravnc_repeater.pl b/x11vnc/misc/ultravnc_repeater.pl index a305ebe..5528bed 100755 --- a/x11vnc/misc/ultravnc_repeater.pl +++ b/x11vnc/misc/ultravnc_repeater.pl @@ -28,17 +28,19 @@ protocol: Listen on one port for vnc clients (default 5900.) Read 250 bytes from connecting vnc client or server. Accept ID: from clients and servers, connect them together once both are present. + The string "RFB 000.000\n" is sent to the client (the client must understand this means send ID:... or host:port.) Also accept : from clients and make the connection to the vnc server immediately. + Note there is no authentication or security WRT ID names or - identities; it us up to the client and server to manage that - and whether to encrypt the session, etc. + identities; it is up to the client and server to completely + manage that aspect and whether to encrypt the session, etc. usage: ultravnc_repeater.pl [-r] [client_port [server_port]] -Use -r to refuse new server/client connections with an existing +Use -r to refuse new server/client connections when there is an existing server/client ID. The default is to close the previous one. To write to a log file set the env. var ULTRAVNC_REPEATER_LOGFILE. @@ -175,11 +177,18 @@ use warnings; use IO::Socket::INET; use IO::Select; +# Test for INET6 support: +# +my $have_inet6 = 0; +eval "use IO::Socket::INET6;"; +$have_inet6 = 1 if $@ eq ""; +print "perl module IO::Socket::INET6 not available: no IPv6 support.\n" if ! $have_inet6; + my $prog = 'ultravnc_repeater.pl'; my %ID; my $refuse = 0; -my $init_timeout = 3; +my $init_timeout = 5; if (@ARGV && $ARGV[0] =~ /-h/) { print $usage; @@ -187,6 +196,7 @@ if (@ARGV && $ARGV[0] =~ /-h/) { } if (@ARGV && $ARGV[0] eq '-r') { $refuse = 1; + print "enabling refuse mode (-r).\n"; shift; } @@ -196,6 +206,7 @@ my $server_port = shift; $client_port = 5900 unless $client_port; $server_port = 5500 unless $server_port; +my $uname = `uname`; my $repeater_bufsize = 250; $repeater_bufsize = $ENV{BUFSIZE} if exists $ENV{BUFSIZE}; @@ -208,9 +219,25 @@ my $client_listen = IO::Socket::INET->new( ReuseAddr => 1, Proto => "tcp" ); -if (! $client_listen) { +my $err1 = $!; +my $err2 = ''; +$client_listen = '' if ! $client_listen; + +my $client_listen6 = ''; +if ($have_inet6) { + eval {$client_listen6 = IO::Socket::INET6->new( + Listen => 10, + LocalPort => $client_port, + ReuseAddr => 1, + Domain => AF_INET6, + LocalAddr => "::", + Proto => "tcp" + );}; + $err2 = $!; +} +if (! $client_listen && ! $client_listen6) { cleanup(); - die "$prog: error: client listen on port $client_port: $!\n"; + die "$prog: error: client listen on port $client_port: $err1 - $err2\n"; } my $server_listen = IO::Socket::INET->new( @@ -219,9 +246,25 @@ my $server_listen = IO::Socket::INET->new( ReuseAddr => 1, Proto => "tcp" ); -if (! $server_listen) { +$err1 = $!; +$err2 = ''; +$server_listen = '' if ! $server_listen; + +my $server_listen6 = ''; +if ($have_inet6) { + eval {$server_listen6 = IO::Socket::INET6->new( + Listen => 10, + LocalPort => $server_port, + ReuseAddr => 1, + Domain => AF_INET6, + LocalAddr => "::", + Proto => "tcp" + );}; + $err2 = $!; +} +if (! $server_listen && ! $server_listen6) { cleanup(); - die "$prog: error: server listen on port $server_port: $!\n"; + die "$prog: error: server listen on port $server_port: $err1 - $err2\n"; } my $select = new IO::Select(); @@ -230,8 +273,10 @@ if (! $select) { die "$prog: select $!\n"; } -$select->add($client_listen); -$select->add($server_listen); +$select->add($client_listen) if $client_listen; +$select->add($client_listen6) if $client_listen6; +$select->add($server_listen) if $server_listen; +$select->add($server_listen6) if $server_listen6; $SIG{INT} = sub {cleanup(); exit;}; $SIG{TERM} = sub {cleanup(); exit;}; @@ -240,7 +285,10 @@ my $SOCK1 = ''; my $SOCK2 = ''; my $CURR = ''; -print "watching for connections on ports $server_port/server and $client_port/client\n"; +print "watching for IPv4 connections on $client_port/client\n" if $client_listen; +print "watching for IPv4 connections on $server_port/server\n" if $server_listen; +print "watching for IPv6 connections on $client_port/client\n" if $client_listen6; +print "watching for IPv6 connections on $server_port/server\n" if $server_listen6; my $alarm_sock = ''; my $got_alarm = 0; @@ -255,9 +303,9 @@ sub alarm_handler { while (my @ready = $select->can_read()) { foreach my $fh (@ready) { - if ($fh == $client_listen) { + if ($fh == $client_listen || $fh == $client_listen6) { print "new vnc client connecting at ", scalar(localtime), "\n"; - } elsif ($fh == $server_listen) { + } elsif ($fh == $server_listen || $fh == $server_listen6) { print "new vnc server connecting at ", scalar(localtime), "\n"; } my $sock = $fh->accept(); @@ -266,7 +314,7 @@ while (my @ready = $select->can_read()) { next; } - if ($fh == $client_listen) { + if ($fh == $client_listen || $fh == $client_listen6) { my $str = "RFB 000.000\n"; my $len = length $str; my $n = syswrite($sock, $str, $len, 0); @@ -294,9 +342,9 @@ while (my @ready = $select->can_read()) { } elsif ($repeater_bufsize > 0 && $n != $size) { print "$prog: short read $n != $size $!\n"; close $sock; - } elsif ($fh == $client_listen) { + } elsif ($fh == $client_listen || $fh == $client_listen6) { do_new_client($sock, $buf); - } elsif ($fh == $server_listen) { + } elsif ($fh == $server_listen || $fh == $server_listen6) { do_new_server($sock, $buf); } } @@ -309,10 +357,12 @@ sub do_new_client { my $id = $1; if (exists $ID{$id}) { if ($ID{$id}{client}) { - print "refusing extra vnc client for ID:$id\n"; - close $sock; - return; - if ($refuse) { + my $ref = $refuse; + if ($ref && !established($ID{$id}{sock})) { + print "socket for ID:$id is no longer established, closing it.\n"; + $ref = 0; + } + if ($ref) { print "refusing extra vnc client for ID:$id\n"; close $sock; return; @@ -337,9 +387,11 @@ sub do_new_client { } } else { my $str = sprintf("%s", $buf); + $str =~ s/\s*$//g; + $str =~ s/\0*$//g; my $host = ''; my $port = ''; - if ($str =~ /^(.+):(\d+)/) { + if ($str =~ /^(.+):(\d+)$/) { $host = $1; $port = $2; } else { @@ -355,12 +407,23 @@ sub do_new_client { print "resetting port from $port to $pnew\n"; $port = $pnew; } - print "making vnc client connection directly to vnc server $host:$port\n"; + print "making vnc client connection directly to vnc server host='$host' port='$port'\n"; my $sock2 = IO::Socket::INET->new( PeerAddr => $host, PeerPort => $port, Proto => "tcp" ); + if (! $sock2 && $have_inet6) { + print "IPv4 connect error: $!, trying IPv6 ...\n"; + eval{$sock2 = IO::Socket::INET6->new( + PeerAddr => $host, + PeerPort => $port, + Proto => "tcp" + );}; + print "IPv6 connect error: $!\n" if !$sock2; + } else { + print "IPv4 connect error: $!\n" if !$sock2; + } if (!$sock2) { print "failed to connect to $host:$port\n"; close $sock; @@ -378,7 +441,12 @@ sub do_new_server { my $store = 1; if (exists $ID{$id}) { if (! $ID{$id}{client}) { - if ($refuse) { + my $ref = $refuse; + if ($ref && !established($ID{$id}{sock})) { + print "socket for ID:$id is no longer established, closing it.\n"; + $ref = 0; + } + if ($ref) { print "refusing extra vnc server for ID:$id\n"; close $sock; return; @@ -408,6 +476,78 @@ sub do_new_server { } } +sub established { + # hack for Linux to see if remote side has gone away: + my $fh = shift; + + # if we can't figure things out, we return true. + if ($uname !~ /Linux/) { + return 1; + } + + my @proc_net_tcp = (); + if (-e "/proc/net/tcp") { + push @proc_net_tcp, "/proc/net/tcp"; + } + if (-e "/proc/net/tcp6") { + push @proc_net_tcp, "/proc/net/tcp6"; + } + if (! @proc_net_tcp) { + return 1; + } + + my $n = fileno($fh); + if (!defined($n)) { + return 1; + } + + my $proc_fd = "/proc/$$/fd/$n"; + if (! -e $proc_fd) { + return 1; + } + + my $val = readlink($proc_fd); + if (! defined $val || $val !~ /socket:\[(\d+)\]/) { + return 1; + } + my $num = $1; + + my $st = ''; + + foreach my $tcp (@proc_net_tcp) { + if (! open(TCP, "<$tcp")) { + next; + } + while () { + next if /^\s*[A-z]/; + chomp; + # sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode + # 170: 0102000A:170C FE02000A:87FA 01 00000000:00000000 00:00000000 00000000 1001 0 423294766 1 f6fa4100 21 4 4 2 -1 + # 172: 0102000A:170C FE02000A:87FA 08 00000000:00000001 00:00000000 00000000 1001 0 423294766 1 f6fa4100 21 4 4 2 -1 + my @items = split(' ', $_); + my $state = $items[3]; + my $inode = $items[9]; + if (!defined $state || $state !~ /^\d+$/) { + next; + } + if (!defined $inode || $inode !~ /^\d+$/) { + next; + } + if ($inode == $num) { + $st = $state; + last; + } + } + close TCP; + last if $st ne ''; + } + + if ($st ne '' && $st != 1) { + return 0; + } + return 1; +} + sub handler { print STDERR "$prog\[$$/$CURR]: got SIGTERM.\n"; close $SOCK1 if $SOCK1; @@ -535,8 +675,10 @@ sub xfer_both { } sub cleanup { - close $client_listen if defined $client_listen; - close $server_listen if defined $server_listen; + close $client_listen if $client_listen; + close $client_listen6 if $client_listen6; + close $server_listen if $server_listen; + close $server_listen6 if $server_listen6; foreach my $id (keys %ID) { close $ID{$id}{sock}; } diff --git a/x11vnc/options.c b/x11vnc/options.c index 05f7538..0ad72f9 100644 --- a/x11vnc/options.c +++ b/x11vnc/options.c @@ -134,10 +134,12 @@ int no_external_cmds = 1; /* cannot be turned back on. */ char *allowed_external_cmds = NULL; int started_as_root = 0; int host_lookup = 1; -#ifndef X11VNC_LISTEN6 -int ipv6_listen = 0; /* -6 */ +#if X11VNC_LISTEN6 +int ipv6_listen = 1; /* -6 / -no6 */ +int got_ipv6_listen = 1; #else -int ipv6_listen = 1; +int ipv6_listen = 0; /* -6 / -no6 */ +int got_ipv6_listen = 0; #endif int ipv6_listen_fd = -1; int ipv6_http_fd = -1; diff --git a/x11vnc/options.h b/x11vnc/options.h index 566e1d7..34ec6c1 100644 --- a/x11vnc/options.h +++ b/x11vnc/options.h @@ -116,6 +116,7 @@ extern char *allowed_external_cmds; extern int started_as_root; extern int host_lookup; extern int ipv6_listen; +extern int got_ipv6_listen; extern int ipv6_listen_fd; extern int ipv6_http_fd; extern int noipv6; diff --git a/x11vnc/remote.c b/x11vnc/remote.c index 6c9ae42..2a45d8b 100644 --- a/x11vnc/remote.c +++ b/x11vnc/remote.c @@ -516,8 +516,16 @@ void http_connections(int on) { screen->httpInitDone = FALSE; if (check_httpdir()) { int fd6 = -1; + char *save = listen_str6; + screen->httpDir = http_dir; + rfb_http_init_sockets(); + + if (getenv("X11VNC_HTTP_LISTEN_LOCALHOST")) { + listen_str6 = "localhost"; + } + if (screen->httpPort != 0 && screen->httpListenSock < 0) { rfbLog("http_connections: failed to listen on http port: %d\n", screen->httpPort); if (ipv6_listen) { @@ -534,11 +542,12 @@ void http_connections(int on) { } ipv6_http_fd = fd6; if (ipv6_http_fd >= 0) { - rfbLog("http_connections: %s listening on IPv6 port=%d sock=%d\n", - screen->httpListenSock < 0 ? "Only" : "Also", + rfbLog("http_connections: Listening %s on IPv6 port %d (socket %d)\n", + screen->httpListenSock < 0 ? "only" : "also", screen->httpPort, ipv6_http_fd); } } + listen_str6 = save; } } else { rfbLog("http_connections: turning off http service.\n"); diff --git a/x11vnc/screen.c b/x11vnc/screen.c index 127267d..e3c6a6f 100644 --- a/x11vnc/screen.c +++ b/x11vnc/screen.c @@ -3631,9 +3631,10 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { fd = listen6(screen->port); if (fd < 0) { ipv6_listen = 0; + rfbLog("Not listening on IPv6 interface.\n"); } else { - rfbLog("%slistening on IPv6 port=%d sock=%d\n", - screen->listenSock < 0 ? "Only " : "Also ", + rfbLog("Listening %s on IPv6 port %d (socket %d)\n", + screen->listenSock < 0 ? "only" : "also", screen->port, fd); ipv6_listen_fd = fd; } diff --git a/x11vnc/sslhelper.c b/x11vnc/sslhelper.c index ae33520..3fc97b4 100644 --- a/x11vnc/sslhelper.c +++ b/x11vnc/sslhelper.c @@ -2749,7 +2749,7 @@ void openssl_port(int restart) { if (port < 0) { rfbLog("openssl_port: could not obtain listening port %d\n", port); - if (!got_rfbport && !ipv6_listen) { + if (!got_rfbport && !got_ipv6_listen) { rfbLog("openssl_port: if this system is IPv6-only, use the -6 option\n"); } clean_up_exit(1); @@ -2760,8 +2760,10 @@ void openssl_port(int restart) { sock = listen_tcp(port, iface, 0); if (ipv6_listen) { fd6 = listen6(port); - } else if (!got_rfbport) { - rfbLog("openssl_port: if this system is IPv6-only, use the -6 option\n"); + } else if (!got_rfbport && !got_ipv6_listen) { + if (sock < 0) { + rfbLog("openssl_port: if this system is IPv6-only, use the -6 option\n"); + } } if (sock < 0) { if (fd6 < 0) { @@ -2770,7 +2772,7 @@ void openssl_port(int restart) { clean_up_exit(1); } } else { - rfbLog("openssl_port: Info: only listening on IPv6\n"); + rfbLog("openssl_port: Info: listening on IPv6 only.\n"); } } } diff --git a/x11vnc/ssltools.h b/x11vnc/ssltools.h index c402ded..89849a5 100644 --- a/x11vnc/ssltools.h +++ b/x11vnc/ssltools.h @@ -1801,6 +1801,13 @@ char create_display[] = " echo \"$tf\"\n" "}\n" "\n" +"missing_mesg() {\n" +" echo \"\" 1>&2\n" +" echo \"The program \\\"$1\\\" could not be found in PATH and standard locations.\" 1>&2\n" +" echo \"You probably need to install a package that provides the \\\"$1\\\" program.\" 1>&2\n" +" echo \"\" 1>&2\n" +"}\n" +"\n" "server() {\n" " authfile=`auth`\n" " sess=`findsession`\n" @@ -2010,6 +2017,7 @@ char create_display[] = "\n" "try_Xvnc() {\n" " if [ \"X$have_Xvnc\" = \"X\" ]; then\n" +" missing_mesg Xvnc\n" " return\n" " fi\n" "\n" @@ -2078,6 +2086,7 @@ char create_display[] = "\n" "try_Xvfb() {\n" " if [ \"X$have_Xvfb\" = \"X\" ]; then\n" +" missing_mesg Xvfb\n" " return\n" " fi\n" "\n" @@ -2110,6 +2119,7 @@ char create_display[] = "\n" "try_Xdummy() {\n" " if [ \"X$have_Xdummy\" = \"X\" ]; then\n" +" missing_mesg Xdummy\n" " return\n" " fi\n" " if [ \"X$FD_XDUMMY_RUN_AS_ROOT\" != \"X\" -a \"X$have_root\" = \"X\" ]; then\n" diff --git a/x11vnc/user.c b/x11vnc/user.c index 8678b0f..150ad37 100644 --- a/x11vnc/user.c +++ b/x11vnc/user.c @@ -2417,6 +2417,46 @@ static void do_try_switch(char *usslpeer, char *users_list_save) { } } +static void path_lookup(char *prog) { + /* see create_display script */ + char *create_display_extra = "/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/dt/bin:/opt/kde4/bin:/opt/kde3/bin:/opt/gnome/bin:/usr/bin:/bin:/usr/sfw/bin:/usr/local/bin"; + char *path, *try, *p; + int found = 0, len = strlen(create_display_extra); + + if (getenv("PATH")) { + len += strlen(getenv("PATH")) + 1; + path = (char *) malloc((len+1) * sizeof(char)); + sprintf(path, "%s:%s", getenv("PATH"), create_display_extra); + } else { + path = (char *) malloc((len+1) * sizeof(char)); + sprintf(path, "%s", create_display_extra); + } + try = (char *) malloc((len+2+strlen(prog)) * sizeof(char)); + + p = strtok(path, ":"); + while (p) { + struct stat sbuf; + + sprintf(try, "%s/%s", p, prog); + if (stat(try, &sbuf) == 0) { + found = 1; + break; + } + p = strtok(NULL, ":"); + } + + free(path); + free(try); + + if (!found) { + fprintf(stderr, "\n"); + fprintf(stderr, "The program \"%s\" could not be found in PATH and standard locations.\n", prog); + fprintf(stderr, "You probably need to install a package that provides the \"%s\" program.\n", prog); + fprintf(stderr, "Without it FINDCREATEDISPLAY mode may not be able to create an X display.\n"); + fprintf(stderr, "\n"); + } +} + static int do_run_cmd(char *cmd, char *create_cmd, char *users_list_save, int created_disp, int db) { char tmp[] = "/tmp/x11vnc-find_display.XXXXXX"; char line1[1024], line2[16384]; @@ -2497,6 +2537,18 @@ static int do_run_cmd(char *cmd, char *create_cmd, char *users_list_save, int cr rfbLog("wait_for_client: running: %s\n", cmd); + if (create_cmd != NULL) { + if (strstr(create_cmd, "Xvfb")) { + path_lookup("Xvfb"); + } + if (strstr(create_cmd, "Xvnc")) { + path_lookup("Xvnc"); + } + if (strstr(create_cmd, "Xdummy")) { + path_lookup("Xdummy"); + } + } + if (unixpw && !unixpw_nis) { int res = 0, k, j, i; char line[18000]; @@ -2996,11 +3048,11 @@ int wait_for_client(int *argc, char** argv, int http) { if (got_rfbport && got_rfbport_val == 0) { ; } else if (ipv6_listen && ipv6_listen_fd >= 0) { - rfbLog("Info: listening only on IPv6 interface.\n"); + rfbLog("Info: listening on IPv6 interface only. (wait for client)\n"); } else { rfbLogEnable(1); - rfbLog("Error: could not obtain listening port.\n"); - if (!got_rfbport) { + rfbLog("Error: could not obtain listening port. (wait for client)\n"); + if (!got_rfbport && !got_ipv6_listen) { rfbLog("If this system is IPv6-only, use the -6 option.\n"); } clean_up_exit(1); diff --git a/x11vnc/util.c b/x11vnc/util.c index 4e7d80d..9c8c294 100644 --- a/x11vnc/util.c +++ b/x11vnc/util.c @@ -36,6 +36,7 @@ so, delete this exception statement from your version. #include "cleanup.h" #include "win_utils.h" #include "unixpw.h" +#include "connections.h" struct timeval _mysleep; diff --git a/x11vnc/v4l.c b/x11vnc/v4l.c index 2180794..84bfd08 100644 --- a/x11vnc/v4l.c +++ b/x11vnc/v4l.c @@ -46,6 +46,11 @@ so, delete this exception statement from your version. #include #define CONFIG_VIDEO_V4L1_COMPAT #include +#ifdef __LINUX_VIDEODEV2_H +# ifndef HAVE_V4L2 +# define HAVE_V4L2 1 +# endif +#endif #define V4L_OK #endif #endif diff --git a/x11vnc/x11vnc.1 b/x11vnc/x11vnc.1 index dc62645..66ce03b 100644 --- a/x11vnc/x11vnc.1 +++ b/x11vnc/x11vnc.1 @@ -2,7 +2,7 @@ .TH X11VNC "1" "April 2010" "x11vnc " "User Commands" .SH NAME x11vnc - allow VNC connections to real X11 displays - version: 0.9.10, lastmod: 2010-04-08 + version: 0.9.10, lastmod: 2010-04-18 .SH SYNOPSIS .B x11vnc [OPTION]... @@ -105,7 +105,7 @@ stay away from other VNC servers near 5900. .PP \fB-rfbport\fR \fIstr\fR .IP -The VNC port to listen on (a libvncserver option), e.g. +The VNC port to listen on (a LibVNCServer option), e.g. 5900, 5901, etc. If specified as "\fB-rfbport\fR \fIPROMPT\fR" then the x11vnc \fB-gui\fR is used to prompt the user to enter the port number. @@ -114,19 +114,32 @@ enter the port number. .IP IPv6 listening support. In addition to IPv4, the IPv6 address is listened on for incoming connections. -The same port as IPv4 is used to listen. If you have -trouble compiling for this mode, set \fB-DX11VNC_IPV6=0\fR -in CPPFLAGS when configuring. +The same port as IPv4 is used. .IP -Currently, the machine may need to have some IPv4 -support, at the least for the loopback interface, for -everything to work correctly. However for most usage -modes IPv4 support is not required. +NOTE: This x11vnc binary was compiled to have the +"-6" IPv6 listening mode ENABLED by default (CPPFLAGS +\fB-DX11VNC_LISTEN6=1).\fR So to disable IPv6 listening mode +you MUST supply the "\fB-no6\fR" option (see below.) .IP -The -6 mode works for both normal connections and +The "-6" mode works for both normal connections and \fB-ssl\fR encrypted ones. Nearly everything is supported for the IPv6 case, but there are a few exceptions. See \fB-stunnel\fR for its IPv6 support. +.IP +Currently, for absolutely everything to work correctly +the machine may need to have some IPv4 support, at the +least for the loopback interface. However, for nearly +all usage modes no IPv4 support is required. See \fB-nopiv4.\fR +.IP +If you have trouble compiling or running in IPv6 mode, +set \fB-DX11VNC_IPV6=0\fR in CPPFLAGS when configuring to +disable IPv6 support. +.PP +\fB-no6\fR +.IP +Disable IPv6 listening support (only useful if the +"-6" mode is compiled in to be the default; see the +X11VNC_LISTEN6 description above under "-6".) .PP \fB-noipv6\fR .IP @@ -562,7 +575,7 @@ Also, tightfilexfer is disabled in \fB-unixpw\fR mode. \fB-ultrafilexfer\fR .IP Note: to enable UltraVNC filetransfer and to get it to -work you probably need to supply these libvncserver +work you probably need to supply these LibVNCServer options: "\fB-rfbversion\fR \fI3.6 \fB-permitfiletransfer\fR"\fR "\fB-ultrafilexfer\fR" is an alias for this combination. .IP @@ -696,6 +709,8 @@ included inet6to4 script or the \fB-proxy\fR option. As with \fB-connect,\fR except if none of the reverse connections succeed, then x11vnc shuts down immediately .IP +An easier to type alias for this option is '-coe' +.IP By the way, if you do not want x11vnc to listen on ANY interface use \fB-rfbport\fR 0 which is handy for the \fB-connect_or_exit\fR mode. @@ -796,7 +811,7 @@ Only allow client connections from hosts matching the comma separated list of hostnames or IP addresses. Can also be a numerical IP prefix, e.g. "192.168.100." to match a simple subnet, for more control build -libvncserver with libwrap support (See the FAQ). If the +LibVNCServer with libwrap support (See the FAQ). If the list contains a "/" it instead is a interpreted as a file containing addresses or prefixes that is re-read each time a new client connects. Lines can be @@ -833,10 +848,11 @@ implies the IPv6 loopback address '::1' as well. .PP \fB-listen6\fR \fIstr\fR .IP -When in IPv6 listen mode "-6", only listen on the -network interface with address \fIstr\fR. It currently -does not work for link scope addresses or non-numeric -hostname strings. +When in IPv6 listen mode "-6", listen only on the +network interface with address \fIstr\fR. It also works +for link scope addresses (fe80::219:dbff:fee5:3f92%eth0) +and IPv6 hostname strings (e.g. ipv6.google.com.) +Use LibVNCServer \fB-listen\fR option for the IPv4 interface. .PP \fB-nolookup\fR .IP @@ -905,7 +921,7 @@ Supply a 2nd password for view-only logins. The \fB-passwd\fR .PP \fB-passwdfile\fR \fIfilename\fR .IP -Specify the libvncserver password via the first line +Specify the LibVNCServer password via the first line of the file \fIfilename\fR (instead of via \fB-passwd\fR on the command line where others might see it via .IR ps (1) @@ -2735,10 +2751,10 @@ If you do not want to expose the non-SSL HTTP port to the network (i.e. you just want the single VNC/HTTPS port, e.g. 5900, open for connections) then specify the option \fB-env\fR X11VNC_HTTP_LISTEN_LOCALHOST=1 This way -the connection to the libvncserver httpd server will +the connection to the LibVNCServer httpd server will only be available on localhost (note that in \fB-ssl\fR mode, HTTPS requests are redirected from SSL to the non-SSL -libvncserver HTTP server.) +LibVNCServer HTTP server.) .PP \fB-http_oneport\fR .IP @@ -2774,7 +2790,7 @@ port redirections. .IP Note that the \fB-env\fR X11VNC_HTTP_LISTEN_LOCALHOST=1 option described above under \fB-httpsredir\fR applies for -the libvncserver httpd server in all cases (ssl or not.) +the LibVNCServer httpd server in all cases (ssl or not.) .PP \fB-ssh\fR \fIuser@host:disp\fR .IP @@ -2791,7 +2807,7 @@ viewer. "user@" is not needed unless the remote unix username differs from the current one. .IP By default the remote sshd is usually configured to -only listen on localhost for rport, so the viewer may +listen only on localhost for rport, so the viewer may need to ssh \fB-L\fR redir to "host" as well (See SSVNC to automate this). The sshd setting GatewayPorts enables listening on all interfaces for rport; viewers can @@ -3188,7 +3204,7 @@ screen PDA or laptop, or using a XRANDR-aware Desktop where you resize often. It is best to be viewing with a vncviewer that supports the NewFBSize encoding, since it knows how to react to screen size changes. Otherwise, -libvncserver tries to do so something reasonable for +LibVNCServer tries to do so something reasonable for viewers that cannot do this (portions of the screen may be clipped, unused, etc). .IP @@ -3747,7 +3763,7 @@ cursors). \fB-noalphablend\fR .IP In XFIXES mode do not send cursor alpha channel data -to libvncserver. The default is to send it. The +to LibVNCServer. The default is to send it. The alphablend effect will only be visible in \fB-nocursorshape\fR mode or for clients with cursorshapeupdates turned off. (However there is a hack for 32bpp with depth 24, @@ -4518,9 +4534,9 @@ for about 1.5 secs). Use 0 to disable. Default: 60 .PP \fB-readtimeout\fR \fIn\fR .IP -Set libvncserver rfbMaxClientWait to n seconds. On +Set LibVNCServer rfbMaxClientWait to n seconds. On slow links that take a long time to paint the first -screen libvncserver may hit the timeout and drop the +screen LibVNCServer may hit the timeout and drop the connection. Default: 20 seconds. .PP \fB-ping\fR \fIn\fR @@ -4608,7 +4624,7 @@ skip powering off the monitor. \fB-noultraext\fR .IP Disable the following UltraVNC extensions: SingleWindow -and ServerInput. The others managed by libvncserver +and ServerInput. The others managed by LibVNCServer (textchat, 1/n scaling, rfbEncodingUltra) are not. .PP \fB-chatwindow\fR @@ -4673,12 +4689,12 @@ there are problems or decrease it to live on the edge \fB-sigpipe\fR \fIstring\fR .IP Broken pipe (SIGPIPE) handling. \fIstring\fR can be -"ignore" or "exit". For "ignore" libvncserver +"ignore" or "exit". For "ignore" LibVNCServer will handle the abrupt loss of a client and continue, for "exit" x11vnc will cleanup and exit at the 1st broken connection. .IP -This option is not really needed since libvncserver +This option is not really needed since LibVNCServer is doing the correct thing now for quite some time. However, for convenience you can use it to ignore other signals, e.g. "\fB-sigpipe\fR \fIignore:HUP,INT,TERM\fR" in case @@ -4690,7 +4706,7 @@ for this option if you don't like the 'pipe'. Example: .PP \fB-threads,\fR \fB-nothreads\fR .IP -Whether or not to use the threaded libvncserver +Whether or not to use the threaded LibVNCServer algorithm [rfbRunEventLoop] if libpthread is available. In this mode new threads (one for input and one for output) are created to handle each new client. @@ -4985,7 +5001,7 @@ LINUX CONSOLE: The following describes some ways to view and possibly interact with the Linux text/graphics console (i.e. not X11 XFree86/Xorg) .IP -Note: If the libvncserver LinuxVNC program is on your +Note: If the LibVNCServer LinuxVNC program is on your system you may want to use that instead of the following method because it will be faster and more accurate for the Linux text console and includes mouse support. @@ -6082,7 +6098,7 @@ uinput_reset:n set uinput_reset to n ms. .IP uinput_always:n set uinput_always to 1/0. .IP -progressive:n set libvncserver \fB-progressive\fR slice +progressive:n set LibVNCServer \fB-progressive\fR slice height parameter to n. .IP desktop:str set \fB-desktop\fR name to str for new clients. @@ -6546,7 +6562,7 @@ For use with \fB-remote\fR nodeny: start out denying all incoming clients until "\fB-remote\fR \fInodeny\fR" is used to let them in. .PP -These options are passed to libvncserver: +These options are passed to LibVNCServer: .PP \fB-rfbport\fR \fIport\fR .IP diff --git a/x11vnc/x11vnc.c b/x11vnc/x11vnc.c index 3d91918..96238b6 100644 --- a/x11vnc/x11vnc.c +++ b/x11vnc/x11vnc.c @@ -2364,8 +2364,8 @@ int main(int argc, char* argv[]) { overlay_cursor = 2; continue; } -#if !SKIP_8TO24 if (!strcmp(arg, "-8to24")) { +#if !SKIP_8TO24 cmap8to24 = 1; if (i < argc-1) { char *s = argv[i+1]; @@ -2374,9 +2374,9 @@ int main(int argc, char* argv[]) { i++; } } +#endif continue; } -#endif if (!strcmp(arg, "-24to32")) { xform24to32 = 1; continue; @@ -2481,10 +2481,13 @@ int main(int argc, char* argv[]) { continue; } if (!strcmp(arg, "-connect") || - !strcmp(arg, "-connect_or_exit")) { + !strcmp(arg, "-connect_or_exit") || + !strcmp(arg, "-coe")) { CHECK_ARGC if (!strcmp(arg, "-connect_or_exit")) { connect_or_exit = 1; + } else if (!strcmp(arg, "-coe")) { + connect_or_exit = 1; } if (strchr(argv[++i], '/') && !strstr(argv[i], "repeater://")) { struct stat sb; @@ -2522,20 +2525,27 @@ int main(int argc, char* argv[]) { continue; } if (!strcmp(arg, "-listen6")) { +#if X11VNC_IPV6 listen_str6 = strdup(argv[++i]); +#endif continue; } if (!strcmp(arg, "-nolookup")) { host_lookup = 0; continue; } -#if X11VNC_IPV6 if (!strcmp(arg, "-6")) { +#if X11VNC_IPV6 ipv6_listen = 1; + got_ipv6_listen = 1; +#endif continue; } if (!strcmp(arg, "-no6")) { +#if X11VNC_IPV6 ipv6_listen = 0; + got_ipv6_listen = 0; +#endif continue; } if (!strcmp(arg, "-noipv6")) { @@ -2546,7 +2556,7 @@ int main(int argc, char* argv[]) { noipv4 = 1; continue; } -#endif + if (!strcmp(arg, "-input")) { CHECK_ARGC allowed_input_str = strdup(argv[++i]); @@ -5785,7 +5795,7 @@ int main(int argc, char* argv[]) { } else { rfbLogEnable(1); rfbLog("Error: could not obtain listening port.\n"); - if (!got_rfbport) { + if (!got_rfbport && !got_ipv6_listen) { rfbLog("If this system is IPv6-only, use the -6 option.\n"); } clean_up_exit(1); diff --git a/x11vnc/x11vnc.h b/x11vnc/x11vnc.h index f77cccd..8d69543 100644 --- a/x11vnc/x11vnc.h +++ b/x11vnc/x11vnc.h @@ -316,14 +316,35 @@ extern int h_errno; #include #endif +#ifndef SOL_IPV6 +#ifdef IPPROTO_IPV6 +#define SOL_IPV6 IPPROTO_IPV6 +#endif +#endif + +#ifndef IPV6_V6ONLY +#ifdef IPV6_BINDV6ONLY +#define IPV6_V6ONLY IPV6_BINDV6ONLY +#endif +#endif + #ifndef X11VNC_IPV6 -#if defined(AF_INET6) || defined(PF_INET6) +#if defined(AF_INET6) #define X11VNC_IPV6 1 #else #define X11VNC_IPV6 0 #endif #endif +#ifndef X11VNC_LISTEN6 +#define X11VNC_LISTEN6 1 +#endif + +#if !X11VNC_IPV6 +#undef X11VNC_LISTEN6 +#define X11VNC_LISTEN6 0 +#endif + #if LIBVNCSERVER_HAVE_PWD_H #include #include diff --git a/x11vnc/x11vnc_defs.c b/x11vnc/x11vnc_defs.c index 0e5f0d7..ac6dfc9 100644 --- a/x11vnc/x11vnc_defs.c +++ b/x11vnc/x11vnc_defs.c @@ -47,7 +47,7 @@ int xtrap_base_event_type = 0; int xdamage_base_event_type = 0; /* date +'lastmod: %Y-%m-%d' */ -char lastmod[] = "0.9.10 lastmod: 2010-04-08"; +char lastmod[] = "0.9.10 lastmod: 2010-04-18"; /* X display info */ diff --git a/x11vnc/xinerama.c b/x11vnc/xinerama.c index 70445c9..001e2ca 100644 --- a/x11vnc/xinerama.c +++ b/x11vnc/xinerama.c @@ -372,9 +372,7 @@ static void initialize_xinerama (void) { /* n.b. change to XineramaGetData() someday */ xineramas = XineramaQueryScreens(dpy, &n); - if (verbose) { - rfbLog("Xinerama: number of sub-screens: %d\n", n); - } + rfbLog("Xinerama: number of sub-screens: %d\n", n); if (! use_xwarppointer && ! got_noxwarppointer && n > 1) { rfbLog("Xinerama: enabling -xwarppointer mode to try to correct\n"); @@ -384,11 +382,8 @@ static void initialize_xinerama (void) { } if (n == 1) { - if (verbose) { - rfbLog("Xinerama: no blackouts needed (only one" - " sub-screen)\n"); - rfbLog("\n"); - } + rfbLog("Xinerama: no blackouts needed (only one sub-screen)\n"); + rfbLog("\n"); XFree_wr(xineramas); X_UNLOCK; return; /* must be OK w/o change */ @@ -405,6 +400,8 @@ static void initialize_xinerama (void) { w = sc->width; h = sc->height; + rfbLog("Xinerama: sub-screen[%d] %dx%d+%d+%d\n", i, w, h, x, y); + tmp_region = sraRgnCreateRect(x, y, x + w, y + h); sraRgnSubtract(black_region, tmp_region); -- cgit v1.2.1