Anonymous CVS over SSH

15 Aug2008

Overview

I wanted to do an anonymous read only CVS repository over SSH for my RocketSled framework. I already had a FreeBSD jail setup for my CVS repository, but I didn't want to just hand out an SSH login on it, and I also didn't want to have two repositories (one readonly and one read/write).

So the goal is to have an easy/safe way for one public CVS user to be able to execute only CVS commands and have read only access to one or more projects in my repository, whilst still allowing me to hand out logins to trusted developers for read/write access to that and other projects in the same repository.

Creating a Public CVS User

For starters, I created a script called cvs-shell:

cvs_shell.txt

and put the following content in it:

cvs_shell_contents.txt

The umask above means that, later when our development team and the public user share a lock directory with the "set gid" bit set on it, they will not prevent each other from checking out files. I then added a passwordless user bentley in the group bentley and made that script bentley's shell. Now when that user logs in, the only command they have access to is the cvs server command. You can try logging in now

ssh bentley@rs.workingsoftware.com.au

It's worth noting here that there are other ways of restricting SSH to only a single command, however this involves having to download and install a private key and I figured that the above was easier. That being said I'd love to know if there's some massive security flaw with doing things that way. From what I can find around the place there doesn't seem to be any problem with it. Please add a comment if you have any advice!!

Creating the Read Only Repository

I had an existing repository, so I copied it onto my new CVS server:

copy_cvsroot.txt

then as root on rs.workingsoftware.com.au:

chown_cvsroot.txt

Before we can create a read only repository we have to create a spot for CVS to write lock files outside of the repository itself:

cvs_lock_dir_change.txt

Now uncomment the the LockDir line and change it to /var/lock/anoncvs and save the file, then check the changes in with:

cvs_lock_dir_change_commit.txt

After I did that I was able to go onto a different server and do:

anonymous_checkout_command.txt

I tested things out by making a change to the source code and then attempting to commit that change, and I was unable to. Success!

Mixing and Matching

There were two things wrong: firstly, I didn't want to give public access to every project in my repository and secondly, I wanted to allow write access to some of my developers.

This was pretty easy, just a matter of juggling the permissions a bit. First, I created a group cvsdev and added all my developer accounts to it (not the bentley account though). I then granted permission to that group on the LockDir:

lockdir_permissions.txt

I then set permissions on the cvsroot which would allow read only access to the bentley account, and read/write access to users in the cvsdev group, and did the same on the CVSROOT folder inside the repository:

cvsroot_permissions.txt

Note that above, for directories have "4" in front of them, which means that the "set gid" bit is set on those directories. This means that files that are created in those directories will inherit the group cvsdev. You should then change the umask for each of your developer accounts to 002, so that new files created in your repository are writable by all members of your development team.

Now for any project that you want to provide anonymous access to, you do the following (using RocketSled as an example):

make_public.txt

Users in the cvsdev group will be able to write to the public repository, but the bentley user account will only be able to read from it. Then for any project that you wish to exclude from public read access, but then allow read/write access to your development team:

make_private.txt

Because this is all permissions based, even if someone were to h4x0r my bentley@rs.workingsoftware.com.au account, they still wouldn't be able to read my private project files, and since I've got this running on a FreeBSD jail without sendmail or anything installed I doubt there's much fun they could really have. You never know though, I may be eating my words within days.

So that's it! You can now access my public RocketSled repository:

anonymous_checkout_command_rsv04.txt

and my development team can checkout using their accounts and commit changes to both the public and private projects.

Incidentally, I'd wait til release v0-5 of RocketSled (which should be within the next month or so) before starting to play around with it. If you want to find out more about RocketSled you can go to:

http://rocketsled.workingsoftware.com.au/ (ed: this link is now broken, refer to the RocketSled page)

We're working on it :)

Comment Archive

This post originally appeared on an older version of the Working Software website which implemented it's own comment mechanism. This new version of our website/blog uses Disqus for comments (see below) however I wanted to preserve the comments made on the previous post here:

In the scenario where I give read/write access to the devs and make the project public. After a developer commits a file he becomes the owner of the file and the readonly user can no longer see it. How did you manage do overcome this?

Anton Avramov (2009-10-10)

This entry was posted on Friday, August 15th, 2008 at 10:36 am author iain dooley, recipe, recipes, sysadmin, sysadmins, cvs, project management, server administration

blog comments powered by Disqus

Subscribe

Subscribe via RSS

Building software in the real world - the Working Software blog

We write about our experiences, ideas and interests in business, software and the business of software. We also sometimes write about our own products (in order to promote them).