cvssh at a glance
cvs pserver option is a useful but insecure tool
for managing cvs repositories. Most approaches to securing cvs
ssh tunneling or avoid
cvssh program offers a third alternative,
which combines the simplicity of
ext on the client
with the flexibility of a
This all started while I was researching cvs security for my company's
cvs hosting plans. I
decided to use a secure
pserver, or password authenticating
server. I like
pserver because it lets each
repository have its own set of users, and those users don't need
to have their own shell accounts on the server.
There are actually several other ways to access cvs:
|easy to manage
pserver + ssh
|can be fairly secure
|security through ssh
||requires shell accounts
||no win32 support (??)
ext method is interesting, because it
lets you specify an external program for connecting to
the repository. By default, that program is RSH (remote
shell), but usually, people change this to
ssh (secure shell)
because it encrypts your data as it moves across the net.
pserver setup has no encryption, which is
one reason it's insecure. Most schemes to secure
involve setting up
ssh to listen on the local cvspserver port (2401)
and securely forward connections to the cvspserver port on the
real server. This is called tunnelling.
The tunnelling concept is a good one, but it can be somewhat
confusing for users to set up, and it still requires at
least one shell account to work.
I wanted something that would be simpler for my customers to
set up, so I came up with my own tunnelling scheme that
does not rely on
ssh port forwarding.
how it works
cvssh concept is pretty simple. In fact,
the initial implementation took less than 200 lines of python
code - most of it comments. Here's an step-by-step walkthrough
of the system, following the above diagram from left to right:
- The developer logs in:
cvssh user@remotesystem:/cvsroot login
cvssh prompts the developer for a password, tests it
against the server (by logging in and trying it), and either prints
an "ACCESS DENIED" message or saves the password to
- The developer sets his or her
environment variable to
- He or she then runs
cvs -d:ext:user@remotesystem:/cvsroot (command)
cvs starts "
cvssh -l user remotesystem cvs server" as a child process
cvssh reads the password from
cvs, duped into thinking it has connected
to a real
cvs server instance, sends
cvssh the command
- At this point,
cvssh has everything it needs
to connect to the
pserver. It opens an SSL connection to
remotesystem on the
- The remote machine has
stunnel listening on that port.
stunnel receives the connection, it runs
cvs pserver and connects its input and output
to the socket connection from the developer's machine.
cvssh can now talk securely to the
cvssh sends the
pserver login information
as if the developer had actually typed
pserver either accepts or rejects the credentials.
- If the credentials are rejected,
cvssh terminates with
an "ACCESS DENIED" message.
- Otherwise, the developer's
cvs instance and the
cvs pserver instance can now communicate
cvssh simply relays their messages until
the transaction is complete.
Version 0.3 is written in python and should run on any
platform that python supports.
For whatever reason, on win32,
cvs -d:ext: requires
CVS_RSH be an
*.exe file. At least, my version did... So the
distribution includes a precompiled
py2exe. (It's in the
directory, along with its required files.)
Note: This is alpha software!!!
I have been using 0.3 for my own development projects. The only problem
I've had is that it occasionally hangs on "cvs diff".... Having said
that, this code has not been extensively tested. Use with
WARNING: the previous version, 0.2, had
some bugs in the routines that handled .cvspass, and it would corrupt
this file, possibly deleting all your saved passwords. Nothing
catastrophic, but definately annoying. 0.3 fixes the problem.
The best way to help would be to try it out and see how it
works (preferably on a test repository!).
If you want to get involved, please contact me at
Better yet, join the
cvssh list at Yahoo!
Here are several things I would like to do to improve
- Add a 'logout' command...
- Check the server's RSA fingerprint the way
- Port it to C. I usually prefer to stay up in the clouds with
python, but in this case, I think small, fast, low-level C code might
be more appropriate. I'm not much of a C programmer, though, so
this is one place I could definitely use some help!
I'm sure there's plenty of other ways this could be made better.
Why not join the list and share your ideas?
It's all GPL, baby.
(GNU General Public License)
links and credits
Here's some good stuff to read:
- Pascal Molli knows all about the CVS protocol. Reading this document (as well as the CVS code itself) made the
pserver bridge possible.
- Everything else I ever needed to know about
learned from Karl Fogel
- stunnel.org is the home page
stunnel, which has plenty of other great uses!
- cvsd makes it
easier to run a
jail, addressing another major security hole in the
- "Tim Timewaster" has a great page describing the
- Robin Dunn's
for win32 made the python SSL stuff easy.
(He's also the guy behind
- Thomas Heller's
makes building an exe file a snap!
- I based the threading portion of cvssh on code from
Sam Rushing's Medusa project.
(Thanks to Jason Orendorff
and Laurent Szyster for pointing me in the right direction here.)
- My personal homepage is sabren.net.
Most of my software is over at
- The cvs hosting plans I mentioned are available from
(c) Copyright 2002 Sabren Enterprises, Inc.