On Fri, 11 Feb 2011 01:40:11 -0600, DRC wrote:
This is good work, but I'll be 100% honest-- after digging myself into a
deep pit of GnuTLS Hell this week, the thought of introducing yet
another dependency on yet another security library makes me cringe. Is
libssh really necessary? I've never observed the port conflicts you're
talking about. The -via option always seems to "just work" for me.
The port conflict arises when you start two vncviewers with the "-via" flag back-to-back pointed to two different servers. In lockstep, both viewers will:
- look for a free TCP port on the local host within a pre-determined sequence (by binding and then closing a socket)
- start an SSH connection to the specified host, with local port forwarding specified on the chosen port
- connect the viewer's RFB connection to the local SSH port
If the SSH connection takes long enough (a few seconds, perhaps), the port found by viewer #1 in step 1 will still free when viewer #2 goes through the same process, and viewer #2 will try to start SSH with the same local port. The second SSH will fail to bind to the local port, but nobody notices that. The second viewer then connects to the first viewer's local SSH process in step 3, and voila - the second viewer is now pointing to the first server. This is especially bad if these viewers are started by different users, and the second user doesn't have the credentials to connect to the first viewer's SSH server on their own.
I use VNC in an environment where multiple users are all starting multiple VNC sessions in the morning (one for each screen / server combination). They've seen this bug a few times, but fortunately it has heretofore only resulted in cross-connects of the same user's viewers.
You should not take this in any way as an indictment against your good
work. It's just that, IMHO, TigerVNC is starting to become unwieldy as
a code base. There are too many permutations-- too many X server
versions we're trying to support, too many optional features that don't
get thoroughly tested because not everyone can build them, etc. Just
getting the code to build in a reproducible and documentable manner with
GnuTLS on three platforms was a significant project. I'm not even sure
of the utility of GnuTLS, given how poorly it performs, but given that
it's tied to our authentication system, I think we're probably stuck
with it for now.
No insult taken - this is a good discussion to have about a relatively significant implementation change.
I sympathize with the pain introduced by GnuTLS, but this SSH change is different in several respects:
- The SSH change fixes an existing capability, and doesn't introduce a new capability
- The existing SSH tunnel capability already had the same level of external dependency, albeit a runtime dependency on /usr/bin/ssh. Granted, the new implementation makes it a build-time dependency or a dynamic library dependency instead of a child process dependency. I would go so far as asserting that libssh is a more portable dependency than a hardcoded reference to "/usr/bin/ssh".
- vncviewer is hardly unwieldy - have you tried building The GIMP?
Seriously, though, the existing "-via" logic would never have worked on Windows, so libssh might actually be a step towards better portability. Windows distros can be happily configured and built without libssh support, which leaves Windows users no better or worse off than they are today.
- The performance is actually slightly better with the libssh implementation than with the external ssh process, since the SSH traffic can be read/written directly from vncviewer instead of going through another socket and another process. The actual data on the network should be identical, since it's SSH-tunneled-RFB either way. The RFB protocol data can be unencrypted, since SSH is handling the transport-level encryption.
- Only users that require/desire the SSH tunneling capability would be subject to any constraints imposed by the new implementation. This is different from the GnuTLS/VeNCrypt situation where the normal "vncviewer <server>:<screen>" case is affected.
Taming complexity in an open source project is generally the result of
necessity. A feature works well because a critical mass of users need
that feature enough to try it out. I'm not convinced yet that GnuTLS
session encryption meets that guideline. At the very least, it is
already a difficult feature to support on Windows. I've already been
down the road of built-in session encryption before-- with VirtualGL.
We used to statically link with OpenSSL, because of the same problems
we're facing with GnuTLS right now-- dynamically linking with it created
a binary that was not cross-compatible. Ultimately, I got sick of
maintaining my own build of OpenSSL on every platform and pulled the
feature out of our default builds. No one missed it. They just started
using SSh tunneling.
Point taken. I personally don't know the breadth of platforms that libssh supports - I'm focused on my Fedora and Red Hat systems. We would have to build-from-source on Red Hat, but the packages are already there on Fedora.
Windows is our most popular client platform, and we need to make sure
that it gets treated as a first-class citizen, not as an afterthought.
Every new feature must work solidly on it and be buildable by a typical
Windows developer. Unfortunately, however, libssh would make that
situation worse, not better, as it is a Unix-centric library like GnuTLS
is. And it's not as widely-available on Linux platforms as GnuTLS is,
meaning that most developers would have to build it from source.
TigerVNC is in danger of becoming so complex that only system
integrators will dare to touch the code, and that's not a good thing for
any of us. IMHO, we really need to do some deep thinking about what we
want to be as a project. I would say that, going forward, we either
need to figure out a way to reduce our permutations, or we need to
consider forking off some of the technologies into separate, independent
builds. The Windows server and Java viewer, for instance, would be good
candidates for that, as would removing libjpeg-turbo from our source
tree and using the upstream builds of that library (that would at least
mean that you don't have to have NASM to build TigerVNC.) As Cendio is
proposing to move to a unified cross-platform viewer code, I even wonder
whether we shouldn't split viewer and server into separate builds. How
much of the code will really be shared by both once the viewer is using
FLTK?
These are topics for deep discussion, and I may be labeled a heretic for
even bringing them up. I just worry that our goals are starting to
diverge. The new features are being pushed in from Fedora, which means
that they are typically hard to support on older Linux platforms or
Windows or Mac, and I feel like I'm spending more time integrating and
less time innovating. I don't want to see us become another X.org.
Anyhow, I apologize for using your post as a vehicle for venting about
the project direction. Chalk it up to a tragedy of timing. I really
appreciate your effort and contribution nonetheless.
These are good topics to discuss, and I'd be happy to participate in the discussion.
However, I'd still like to know how you and the rest of the community feel about this particular SSH change, and the implementation questions I raised. As I said, I don't think it has the same mainstream consequences as GnuTLS, and might actually be a step towards supporting the SSH tunneling capability on non-Unix platforms.
What do you think?
On 2/10/11 11:26 PM, Eric Stadtherr wrote:Hi,
I have completed the code & build changes necessary to utilize libssh
within vncviewer for "-via" SSH connections (instead of starting a
/usr/bin/ssh child process). This solves the issue of two vncviewer
processes trying to start SSH processes bound to the same local port
during startup, and has some nice fringe benefits such as eliminating a
process and a socket when in this tunneling mode. The changes were
relatively straightforward - I was even able to successfully replicate
the "process GUI events when the SSH channel read would block"
methodology with the libssh API.
In brief, the changes are as follows:
* Implement a new "SSHChanConn" connection class (derived from
CConn) that establishes the SSH connection and creates a
forwarding channel to the specified VNC server.
* Implemented new RDR stream classes to handle the SSH channel I/O
(SSHChanInStream and SSHChanOutStream). These are derived from the
FdInStream and FdOutStream classes in order to re-use the existing
event processing, buffer management and timing logic.
* Modified configure.ac and Makefile.am files to dynamically
discover the presence of the libssh library in the build
environment, and add define flags and make targets appropriately
* Reworked some of the logic in vncserver.cxx that handled the
"-via" flag, and implement a decision between CConn or SSHChanConn
depending on the presence of that flag.
The work isn't 100% complete, since I wanted to ask how you would prefer
some things be handled:
1. SSH Authentication - I use the API to discover the authentication
mechanisms supported by the SSH server, and try each in turn until
authentication is successful (key pair, password,
keyboard-interactive, none). I haven't tested the "None" or
"Password" authentication mechanisms, since I don't have access to
an SSH server that is configured for those methods. How do you
want to handle that testing? Are there other auth methods that you
would like to see supported?
2. Man page - I made the "-via" argument conditionally present based
on the presence/absence of the libssh library during the build.
First, do you agree with that approach? If so, how should the man
page be handled? Can we conditionalize the description of that
argument, or just put a caveat about "only available if built with
libssh" or something along those lines?
3. Patch submission - I have a .patch file built against the latest
Subversion trunk, but the changes are fairly extensive. Is a
.patch file still appropriate, or would you like to see things a
different way?
Thanks!
-Eric
------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Tigervnc-devel mailing list
Tigervnc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tigervnc-devel
------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Tigervnc-devel mailing list
Tigervnc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tigervnc-devel
------------------------------------------------------------------------------ The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE: Pinpoint memory and threading errors before they happen. Find and fix more than 250 security defects in the development cycle. Locate bottlenecks in serial and parallel code that limit performance. http://p.sf.net/sfu/intel-dev2devfeb_______________________________________________ Tigervnc-devel mailing list Tigervnc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-devel