GNU Info

Info Node: (cvsbook.info)The Password-Authenticating Server

(cvsbook.info)The Password-Authenticating Server


Next: Anonymous Access Prev: Starting A Repository Up: Repository Administration
Enter node , (file) or (file)node

The Password-Authenticating Server
==================================

Before running through the steps needed to set up the password server,
let's examine how such connections work in the abstract.  When a remote
CVS client uses the `:pserver:' method to connect to a repository, the
client is actually contacting a specific port number on the server
machine - specifically, port number 2401 (which is 49 squared, if you
like that sort of thing).  Port 2401 is the designated default port for
the CVS pserver, although one could arrange for a different port to be
used as long as both client and server agree on it.

The CVS server is not actually waiting for connections at that port -
the server won't get started up until a connection actually arrives.
Instead, the Unix inetd (InterNET Daemon) program is listening on that
port, and needs to know that when it receives a connection request
there, it should start up the CVS server and connect it to the incoming
client.

This is accomplished by modifying inetd's configuration files:
`/etc/services' and `/etc/inetd.conf'.  The services file maps raw port
numbers to service names and then inetd.conf tells inetd what to do for
a given service name.

First, put a line like this into /etc/services (after checking to make
sure it isn't already there):

     cvspserver	2401/tcp

Then in /etc/inetd.conf, put this:

     cvspserver stream tcp nowait root /usr/local/bin/cvs cvs \
        --allow-root=/usr/local/newrepos pserver

(In the actual file, this should be all one long line, with no
backslash.)  If your system uses tcpwrappers, you may want to use
something like this instead:

     cvspserver stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/cvs \
        --allow-root=/usr/local/newrepos pserver

Now, restart inetd so it notices the changes to its configuration files
(if you don't know how to restart the daemon, just reboot the machine -
that will work too).

That's enough to permit connections, but you'll also want to set up
special CVS passwords - separate from the users' regular login
passwords - so people can access the repository without compromising
overall system security.

The CVS password file is CVSROOT/passwd in the repository.  It was not
created by default when you ran cvs init, because CVS doesn't know for
sure that you'll be using pserver.  Even if the password file had been
created, CVS would have no way of knowing what usernames and passwords
to create.  So, you'll have to create one yourself; here's a sample
CVSRoot/passwd file:

     kfogel:rKa5jzULzmhOo
     anonymous:XR4EZcEs0szik
     melissa:tGX1fS8sun6rY:pubcvs

The format is as simple as it looks.  Each line is:

     <USERNAME>:<ENCRYPTED_PASSWORD>:<OPTIONAL_SYSTEM_USERNAME>

The extra colon followed by an optional system username tells CVS that
connections authenticated with USERNAME should run as the system account
SYSTEM_USERNAME - in other words, that CVS session would only be able
to do things in the repository that someone logged in as SYSTEM_USERNAME
could do.

If no system username is given, USERNAME must match an actual login
account name on the system, and the session will run with that user's
permissions.  In either case, the encrypted password should not be the
same as the user's actual login password.  It should be an independent
password used only for CVS pserver connections.

The password is encrypted using the same algorithm as the standard Unix
system passwords stored in /etc/passwd.  You may be wondering at this
point, how does one acquire an encrypted version of a password?  For
Unix system passwords, the passwd command takes care of the encryption
in /etc/passwd for you.  Unfortunately, there is no corresponding cvs
passwd command (it has been proposed several times, but no one's gotten
around to writing it - perhaps you'll do it?).

This is an inconvenience, but only a slight one.  If nothing else, you
can always temporarily change a regular user's system password using
passwd, cut and paste the encrypted text from /etc/passwd into
CVSROOT/passwd, and then restore the old password (note that on some
systems, the encrypted passwords are found in /etc/shadow and are
readable only by root.)

That scheme is workable but rather cumbersome.  It would be much easier
to have a command-line utility that takes a plain text password as its
argument and outputs the encrypted version.  Here is such a tool,
written in Perl:

     #!/usr/bin/perl
     
     srand (time());
     my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))";
     my $salt = sprintf ("%c%c", eval $randletter, eval $randletter);
     my $plaintext = shift;
     my $crypttext = crypt ($plaintext, $salt);
     
     print "${crypttext}\n";

I keep the preceding script in `/usr/local/bin/cryptout.pl':

     floss$ ls -l /usr/local/bin/cryptout.pl
     
     -rwxr-xr-x   1   root   root   265  Jun 14 20:41 /usr/local/bin/cryptout.pl
     floss$ cryptout.pl "some text"
     sB3A79YDX5L4s
     
     floss$

If I took the output of this example and used it to create the following
entry in CVSROOT/passwd

     jrandom:sB3A79YDX5L4s:craig

then someone could connect to the repository with the following command:

     remote$ cvs -d :pserver:jrandom@floss.red-bean.com:/usr/local/newrepos login

They could then type `some text' as their password and thereafter be
able to execute CVS commands with the same access privileges as the
system user `craig'.

If someone attempts to authenticate with a username and password that
don't appear in CVSROOT/passwd, CVS will check to see if that username
and password are present in /etc/passwd.  If they are (and if the
password matches, of course), CVS will grant access.  It behaves this
way for the administrator's convenience, so that separate CVSROOT/passwd
entries don't have to be set up for regular system users.  However, this
behavior is also a security hole, because it means that if one of those
users does connect to the CVS server, her regular login password will
have crossed over the network in cleartext, potentially vulnerable to
the eyes of password sniffers.  A bit further on, you'll learn how to
turn off this "fallback" behavior, so that CVS consults only its own
passwd file.  Whether you leave it on or off, you should probably force
any CVS users who also have login accounts to maintain different
passwords for the two functions.

Although the passwd file authenticates for the whole repository, with a
little extra work you can still use it to grant project-specific access.
Here's one method:

Suppose you want to grant some remote developers access to project
`foo', and others access to project `bar', and you don't want
developers from one project to have commit access to the other.  You can
accomplish this by creating project-specific user accounts and groups on
the system and then mapping to those accounts in the CVSROOT/passwd
file.

Here's the relevant excerpt from /etc/passwd

     cvs-foo:*:600:600:Public CVS Account for Project Foo:/usr/local/cvs:/bin/false
     cvs-bar:*:601:601:Public CVS Account for Project Bar:/usr/local/cvs:/bin/false

and from /etc/group

     cvs-foo:*:600:cvs-foo
     cvs-bar:*:601:cvs-bar

and, finally, CVSROOT/passwd:

     kcunderh:rKa5jzULzmhOo:cvs-foo
     jmankoff:tGX1fS8sun6rY:cvs-foo
     brebard:cAXVPNZN6uFH2:cvs-foo
     xwang:qp5lsf7nzRzfs:cvs-foo
     dstone:JDNNF6HeX/yLw:cvs-bar
     twp:glUHEM8KhcbO6:cvs-bar
     ffranklin:cG6/6yXbS9BHI:cvs-bar
     yyang:YoEqcCeCUq1vQ:cvs-bar

Some of the CVS usernames map onto the system user account `cvs-foo'
and some onto `cvs-bar'.  Because CVS runs under the user ID of the
system account, you just have to make sure that the relevant parts of
the repository are writeable only by the appropriate users and groups.
If you just make sure that the user accounts are locked down pretty
tight (no valid login password, `/bin/false' as the shell), then this
system is reasonably secure (but see later in this chapter about
CVSROOT permissions!).  Also, CVS does record changes and log messages
under the CVS username, not the system username, so you can still tell
who is responsible for a given change.


automatically generated by info2www version 1.2.2.9