Anonymous CVS over SSH

15th August, 2008Insights

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:

cd /usr/local/bin
touch cvs-shell
chmod 755 cvs-shell

and put the following content in it:

#!/bin/sh
umask 002
exec cvs server

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:

tar -zcf cvsroot.tar.gz cvsroot
scp cvsroot.tar.gz me@rs.workingsoftware.com.au:/usr/local/share/

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

tar -zxf cvsroot.tar.gz
chown -R bentley:bentley cvsroot

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:

mkdir -p /var/lock/anoncvs
chown bentley:bentley /var/lock/anoncvs
cvs -d /usr/local/share/cvsroot co CVSROOT/config
vi CVSROOT/config

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

cvs commit -m "Added an external LockDir" CVSROOT/config
cvs release -d CVSROOT
You can now make your cvsroot readonly:
cd /usr/local/share
find cvsroot -type d | xargs chmod 500
find cvsroot -type f | xargs chmod 400

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

cvs -d :ext:bentley@rs.workingsoftware.com.au:/usr/local/share/cvsroot co RocketSled

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:

chown bentley:cvsdev /var/lock/anoncvs
chmod 770 /var/lock/anoncvs

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:

cd /usr/local/share
chown bentley:cvsdev cvsroot
chmod 4570 cvsroot
chown bentley:cvsdev cvsroot/CVSROOT
find cvsroot/CVSROOT -type d | xargs chmod 4570
find cvsroot/CVSROOT -type f | xargs chmod 460

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):

cd /usr/local/share/cvsroot
chown bentley:cvsdev RocketSled
find RocketSled -type d | xargs chmod 4570
find RocketSled -type f | xargs chmod 460

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:

cd /usr/local/share/cvsroot
chown root:cvsdev MyPrivateProject
find MyPrivateProject -type d | xargs chmod 4770
find MyPrivateProject -type f | xargs chmod 660

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:

cvs -d :ext:bentley@rs.workingsoftware.com.au:/usr/local/share/cvsroot co -r v0-4 RocketSled

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)

Read More Posts

BYOD and Cybersecurity: An In-Depth Analysis

BYOD and Cybersecurity: An In-Depth Analysis

Bring Your Own Device (BYOD) policies have become increasingly prevalent in Australian businesses, offering flexibility and cost savings. However, they also introduce complex cybersecurity challenges. In this article, we explore the cybersecurity implications of BYOD...

Using a Second Phone Number for Personal Use: Benefits and Risks

Using a Second Phone Number for Personal Use: Benefits and Risks

In today's connected world, balancing personal and professional life is more challenging than ever. One solution gaining popularity is the use of a second phone number for personal use. This approach, especially with solutions like BenkoPhone, offers several benefits...

Want to try BenkoPhone?