How to configure WinCVS with SSH1
Patrick G. Salsbury
http://reality.sculptors.com/~salsbury/
06-28-01
Intro:
This document details the procurement, process, and possible
pitfalls of implementing WinCVS version control software with Secure Shell
(SSH) cryptographic protection. It will explain how to configure the files
& directories needed, as well as how to configure SSH public-key
authentication so that you are not prompted for a password every time you
attempt to issue a CVS command.
Background:
I have been using CVS and WinCVS (http://www.cvsgui.org/) for a
couple of years, and recently made the move to SSH-encrypted CVS sessions
on my Unix/Linux boxes. In attempting to roll this out to Windows-only
users, I found that the WinCVS software exhibits a bug when used with
version 2 of the SSH protocol. This is compounded by the fact that the
formerly freely-available version of ssh1 for windows has been removed from
the ftp://www.ssh.com/ servers, when they moved to a commercialized version
of ssh2.
Mind you, the program that they have now is really nice, it just
doesn't do ssh1, and it doesn't work with WinCVS. There are also a lot of
free and commercial ssh1 terminal clients for windows, such as PuTTY, but
these are interactive clients, and CVS requires a command-line client that
can issue basic 'ssh user@hostname command' types of commands which run
non-interactively.
After asking around on the info-cvs mailing list, I found I'd run
across a FAQ that had never really been answered very well, and after
hammering my head against it for about a month, I finally succeeded in
getting all the pieces in the right place today, so I decided to document
the hell out of it. :-)
Sources:
Having said all that, there are a few things you'll need to have to
get this working. First, you'll need a version of ssh1 that does
command-line stuff. You can still find this outside the US on some
sites. (It can't be exported from the US due to the vagaries of United
States munitions law, but you can import it from elsewhere. Go figure.)
A great place to find this is Google, where you should search for
'ssh-1.2.14-win32bin.zip'. This url should do the trick:
http://www.google.com/search?q=ssh-1.2.14-win32bin.zip
Google pointed me to various sites in Germany and I confirmed that
at least this one has the code in question:
German source: http://www.tu-bs.de/rz/Compute-Server/ssh/dos/readme.htm
(They also have a fairly complete-looking instruction guide, depending on
how your German is. Mine's a bit rusty, but from what I can glean, they
seem to have covered it fairly well.)
I also found Gordon Chaffee's page at Berkeley to be of great help
in figuring out the specific directories to create. (That ssh zip file
listed above has the binaries, but no documentation.) His info is here:
http://bmrc.berkeley.edu/people/chaffee/winntutil.html#sshnt One other
useful tip from Gordon's page is that if you copy the ssh.exe binary to
sshc.exe, then it automatically runs with compression on. He said he finds
this useful when running CVS commands. I set up my system the same
way, but seemed to notice some problems with CVS randomly hanging
sometimes. You may want to experiment with the two settings. (The hang may
have been caused by long-duration operations, as described in the "Notes"
section at the bottom, where WinCVS appears to go dead, but is actually
running in the background.)
The other page that was incredibly useful in deciphering this issue
was a page on SSH also hosted at Berkeley:
http://ptolemy.eecs.berkeley.edu/~cxh/sapub/ssh.html
Unfortunately, the Berkeley folks seem to have ready access to
Windows compilers, which isn't the case for everyone, so I recommend
downloading the zip file unless you're comfortable with patching & building
your own code on Windows and have the necessary tools on hand.
You'll also need a copy of WinCVS, which can be downloaded from
http://www.cvsgui.org/ and a copy of WinZip (http://www.winzip.com/) or
some other unzipper if you don't already have one. I also recommend
installing the TCL toolkit, if you'd like to use the macro functionality of
WinCVS. You can find TCL at http://www.scriptics.com/ (Note: As of
03-15-01, I see that WinCVS 1.2 has been released. I have not yet tested
SSH functionality with that release.)
Setting up the environment:
Unzip the ssh-1.2.14-win32bin.zip program and extract it to a
directory somewhere, such as c:\Program Files\ssh1
Create a home directory for your own ssh files, such as
c:\users\yourname\.ssh or c:\winnt\profiles\yourname\.ssh
Edit your AUTOEXEC.BAT file (for Win95/98) and add the following
lines:
HOME=c:\users\yourname (or wherever you chose to create, above)
PATH=%PATH%;c:\Program Files\ssh1 (or wherever you unzipped ssh into)
If you're using Windows NT (as I am), you set your environment
variables as follows:
Right click on "My Computer" and choose "Properties"
Click on the "Environment" tab
Look in the "User Variables" section.
-If you already have a "PATH" variable, click on that. Add
";c:\Program Files\ssh1" to the end of the "Value" box (the ";" separates
it from the previous PATH entries), click "Set", then click "Apply".
-If you don't already have "PATH" in your User Variables
section, type PATH in the "Variable" box, "c:\Program Files\ssh1" in the
"Value" box, click "Set", then click "Apply".
Next, type "HOME" in the "Variable" Box, and put c:\users\yourname
(or wherever you chose) into the "Value" box. Click "Set", then "Apply",
then "OK".
If you're using Windows 2000, it's almost like the NT
configuration, except as follows:
Right click on "My Computer" and choose "Properties"
Click on the "Advanced" tab
Click on the "Environment Variables" button.
(The proceed to define your PATH and HOME variables, as above.)
Generate host keys for your machine: (Note: This isn't needed for
client-only use, and for outgoing SSH connections. It's only used for
machines that will have other CVS clients connecting to them.)
Create a c:\ssh\etc directory to store your ssh_config (if
desired. I don't have one.), ssh_host_key and ssh_host_key.pub files.
cd c:/ssh/etc
ssh-keygen -b 1024 -f ssh_host_key -N '' -C yourhostname
This creates a 1024 bit host key pair and two files, ssh_host_key
and ssh_host_key.pub, with no password, and the comment being the name of
your machine.
If you don't use the -C option, you may see this error:
gethostname: No such file or directory
Testing:
Open up a new MS-DOS window, and type "set". You should see a list
of your environment variables, including HOME and PATH. They should now
contain the values you just specified above.
At this point, provided your path is set up correctly, you should
be able to just type 'ssh' and get some help-text on the various flags and
options, looking something like this:
C:\>ssh
Usage: ssh [options] host [command]
Options:
-l user Log in using this user name.
-n Redirect input from /dev/null.
-a Disable authentication agent forwarding.
-x Disable X11 connection forwarding.
-i file Identity for RSA authentication (default: ~/.ssh/identity).
-t Tty; allocate a tty even if command is given.
-v Verbose; display verbose debugging messages.
-q Quiet; don't display any warning messages.
-f Fork into background after authentication.
-e char Set escape character; ``none'' = disable (default: ~).
-c cipher Select encryption algorithm: ``idea'' (default, secure),
``des'', ``3des'', ``tss'', ``arcfour'' (fast, suitable for bulk
transfers), ``none'' (no encryption - for debugging only).
-p port Connect to this port. Server must be on the same port.
-L listen-port:host:port Forward local port to remote address
-R listen-port:host:port Forward remote port to local address
These cause ssh to listen for connections on a port, and
forward them to the other side by connecting to host:port.
-C Enable compression.
-o 'option' Process the option as if it was read from a configuration file.
Now you should be able to log into a remote machine via SSH1 by
issuing a command like:
ssh -v -l username ssh.hostname.someplace
It will ask you for your password on the remote host, and then you
should be in.
Public Key Authentication:
SSH also can use public key authentication in order to verify your
identity without constanty prompting you for a password. There are various
opinions on the wisdom of creating a public-key that doesn't use passwords
to authenticate the user. Indeed, you should weigh the inconvenience of
typing your password whenever issuing a CVS command with the general
security of your environment and machine. Certainly, a password-less key
should not be left on a public or multi-user machine. Anyone who gets
access to your windows machine would then be able to get into your Unix
account without a password. Think carefully about this.
If you are decided that you want to create a public-key to
authenticate yourself, you may do so as follows:
cd %HOME%\.ssh
ssh-keygen -C username@yourhostname
This creates a 1024 bit key pair and two files, identity and
identity.pub, and the comment being the name of your machine. It will
prompt you asking where to store the file, defaulting to
$HOME/.ssh/identity. It will also prompt you for a passphrase. Entering one
here secures your public key, but also defeats the purpose of generating a
key so that you're not prompted for a password. If you just hit "Enter"
twice (once for the passphrase, and once for confirmation), it will finish
generating the key and name it identity.pub
If you don't use the -C option, you may see this error:
gethostname: No such file or directory
Here's a sample session where I generate keys with no passphrase
for a machine called 'myhost'. I saved the keys in C:/tmp because I didn't
want to overwrite my real keys.
C:\>cd c:\tmp
C:\tmp>ssh-keygen -C myhost
Initializing random number generator...
Generating p: ...............................................................\
.............++ (distance 1296)
Generating q: ...............++ (distance 310)
Computing the keys...
Testing the keys...
Key generation complete.
Enter file in which to save the key ($HOME/.ssh/identity): C:/tmp/identity
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:/tmp/identity.
Your public key is:
1024 37 939081187355247279097286066056836200187500166757277461262410055150341\
83550520111455230281016685131343081711417148543247737788059693359594583390430\
35273471894877976769330729268657163629521105008373282900217673001284239239960\
57552669117905824359467449026626998777803348151468268532185939449766323408972\
39207727 myhost
Your public key has been saved in C:/tmp/identity.pub
At this point, I like to make a copy of the identity.pub file with
a more descriptive name. After you start copying these around to a few
different machines, it's nice to know which ones come from where.
C:\tmp>copy identity.pub identity_myhost.pub
1 file(s) copied.
C:\tmp>dir
Volume in drive C has no label.
Volume Serial Number is 3964-BC4B
Directory of C:\tmp
07/06/00 05:05p .
07/06/00 05:05p ..
02/19/01 12:55a 518 identity
02/19/01 12:55a 322 identity.pub
02/19/01 12:55a 322 identity_myhost.pub
5 File(s) 1,162 bytes
663,879,680 bytes free
Now we get to use 'scp' to copy our public key over to our Unix/CVS
host.
C:\tmp>scp identity_myhost.pub
yourname@yourhost.somewhere:/home/yourname/.ssh/identity_myhost.pub
(Make sure that /home/yourname/.ssh/ exists!)
Password: (Enter your Unix password)
Now the key is on the Unix machine, but it still hasn't been
authorized. You do this by appending the public key to the end of a file
called /home/yourname/.ssh/authorized_keys, like so:
C:\tmp>ssh -v -l yourname yourhost.somewhere
[Lots of verbose stuff]
Password:
Unix>cd ~/.ssh
Unix>ls -l
total 10
-rw-r--r-- 1 salsbury users 681 Feb 18 12:19 authorized_keys
-rw------- 1 salsbury users 547 Feb 18 03:16 identity
-rw-r--r-- 1 salsbury users 351 Feb 18 03:16 identity.pub
-rw-r--r-- 1 salsbury users 351 Feb 18 03:17 identity_machine1.pub
-rw-r--r-- 1 salsbury users 330 Feb 18 12:17 identity_machine2.pub
-rw-r--r-- 1 salsbury users 322 Feb 18 17:20 identity_myhost.pub
-rw------- 1 salsbury users 1333 Feb 18 03:17 known_hosts
-rw-r--r-- 1 salsbury users 624 Dec 2 12:14 known_hosts2
-rw------- 1 salsbury users 512 Feb 18 03:18 random_seed
Unix>cat identity_myhost.pub >> authorized_keys
Unix>ls -l authorized_keys
-rw-r--r-- 1 salsbury users 1003 Feb 18 17:30 authorized_keys
*Important!* Make sure that your .ssh directory and the files in it
are only writable by you! If group write permissions are set on the
directory or certain files within it, ssh will refuse to use your RSA keys,
and will always prompt you for a password.
Unix>chmod -R go-w ~/.ssh
A few things to note:
The 'cat identity_myhost.pub >> authorized_keys' part will append
the new key onto the end of an existing authorized_keys file, or will
create a new one if you already have one. Not only is this fast and
convenient, but less error-prone than cutting and pasting, as you don't run
the risk of an editor trying to word-wrap. (The key is all on 1 very long
line.) This is also a safer way of adding the new key, as it won't clobber
existing keys in most Unix shells.
You can see from the above directory listing why it's a good idea
to copy identity.pub to identity_machinename.pub before moving it off of
that machine. That prevents it from clobbering the identity.pub key on the
machine you're moving it to, and makes it clear which keys come from which
machines.
The second listing of authorized_keys confirms that the file grew
by 322 bytes, or the length of identity_myhost.pub. You could also cat the
file, and you'll see the last line contains the same text as
identity_myhost.pub.
At this point, you should be all set up for public-key based
authentication with ssh and scp. Go back to your MS-DOS window and try
another SSH. This time, it should let you in with no password prompt.
C:\>ssh -v -l yourname yourhost.somewhere
[Lots of verbose stuff]
Unix>
If that works, you're now set to configure WinCVS to use SSH
authentication, and then you're off and running!
Configuring WinCVS:
Start up your WinCVS software. I've tried this with both WinCVS
v1.0.6 and v1.1b17, and they both seem to work fine.
WinCVS v1.0.6
Pull down CVSAdmin->Preferences (or click CTRL-F1)
On the "General" tab enter your CVSROOT information:
yourname@yourhost.somewhere:/path/to/cvsroot
For Authentication, choose "SSH server" (If you decided not to use the
RSA public keys and instead want to enter your password when performing CVS
operations, then CVS will appear to hang when you run a command like 'cvs
-t update', but it's really waiting for you to enter your password. Hit
'ALT-TAB' and switch to the blank MS-DOS window that has appeared in the
background, enter your Unix password, and hit "Enter". CVS should then
proceed with its action.)
On the "Ports" tab, check the box that says "Check for an alternate
rsh name" and enter '/path/to/ssh' or '/path/to/sshc' (if you made a copy
of ssh to do auto-compression, as noted above.) You could also specify the
full path, but that shouldn't be necessary if your "PATH" variable is set.
Click "OK" to accept your changes
WinCVS v1.1.b17
Pull down Admin->Preferences (or click CTRL-F1)
On the "General" tab enter your CVSROOT information:
yourname@yourhost.somewhere:/path/to/cvsroot
For Authentication, choose "SSH server"
Check the "RSA Identity" box and choose your identity (not
identity.pub!) file, if it's not already listed. (It should pick it up from
$HOME\.ssh\identity) (This step isn't needed if you decide not to use the
RSA public keys and instead want to enter your password when performing CVS
operations. In that case, CVS will appear to hang when you run a command
like 'cvs -t update', but it's really waiting for you to enter your
password. Hit 'ALT-TAB' and switch to the blank MS-DOS window that has
appeared in the background, enter your Unix password, and hit "Enter". CVS
should then proceed with its action.)
On the "Ports" tab, check the box that says "Check for an alternate
rsh name" and enter 'ssh' or 'sshc' (if you made a copy of ssh to do
auto-compression, as noted above.) You could also specify the full path,
but that shouldn't be necessary if your "PATH" variable is set.
Click "OK" to accept your changes
Now you should be all set! Any CVS commands that you issue will now
run through SSH and all of your data will be wrapped in a protective crypto
tunnel. Enjoy!
Notes:
Be patient when doing CVS operations that might take a while.
WinCVS doesn't seem to give you updates as it goes along, unlike the Unix
client, which will give you status after each file. Even when using the
'-t' (trace) option with CVS, (which provides more debugging info) doesn't
update until the very end of an operation in WinCVS, while in Unix it will
merrily chatter along while working, so that you know the system isn't
hung.
I just did a checkout of a 5.5Mb CVS module over my dialup line at
home (~31.2Kbit/sec), and it took approximately 25 minutes to download
everything. During this time, WinCVS looked dead to the world, complete
with the system not refreshing the CVS window if I moved another window
over it, ALT-TABbing to the MS-DOS window running the ssh command, and
seeing no response, etc. The only reason I knew it was still working was by
doing 'tcpdump' analysis of my PPP interface, running an 'strace' of the
process on my remote CVS server, and seeing the little blinking lights on
my modem. :-) During this time, WinCVS showed no signs of life. However,
once the operations and download were complete, it came back to life and
showered me with updated info as to all the programs it had downloaded.
This could almost certainly be improved upon in the user interface,
but for now, if you're on a slow link, be patient, and check your modem
lights/interface data if you don't believe it's still working. You'll
probably also want to turn on compression in CVS and perhaps within ssh by
running as 'sshc' (see above).
Errata:
I've noticed that the 'cvs release' function doesn't seem to want
to work over SSH, but haven't yet diagnosed why. It should still be
possible to just do an update on the directory to make sure it's
synchronized with the Repository, then remove the directory via standard
Windows tools.
On my setup, it's bombing out with this error:
cvs release . (in directory D:\cvs\misc-files\)
rsh: can't establish connection
cvs [update aborted]: end of file from server (consult above messages if any)
cvs release: unable to release `.'
*****CVS exited normally with code 0*****
I also noticed that my Linux machine was registering a bunch of
actual rshd (not sshd) attempts coming from my notebook while I was testing
this, so it could be that the WinCVS code isn't using the SSH method for
'release' operations that it is using for others. Someone familiar with the
source code will be able to confirm or deny this.
**********
Comments, suggestions, and corrections to this doc are welcome at
the above email address.
Pat