[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RFC: server->pserver proxy?
RFC: server->pserver proxy?
Thu, 24 Jan 2008 07:47:59 -0800
We currently use CVS to maintain some open source projects
and internal projects. We sometimes port these projects
to clients' systems/targets by ssh-ing into their systems
and using the CVS repository back on our host systems.
A few external contributors have either read or write access
to the open source repositories. Access is presently
enforced via honor code. In our current set up, we have
an outward-facing firewalled system where the open source
repository lives. Users access this system via ssh and
each user has a login on the firewall'ed system. Works
fine, though setting up a new system account for each
user is a bit of pain, when all we really want to do
is allow CVS access. If we are working on another site
and want to access our proprietary CVS, we really have
no easy way of doing that, though "CVS server pipelining"
(which I read about recently in the FAQ) might be able
to accomplish that. And ssh port forwarding might
work as well, but would require new keys and/or a
new system account to make it work.
We'd like to move all the CVS repositories onto one
internal CVS server and manage it there, using the pserver
access method. We'd also like to use the "alternate user"
capability of pserver so that all accesses within a given
tree are restricted to a particular user/group. We'd
have a different user group for the "public" (open source)
tree than the "local" (proprietary) tree simply as another
layer of access enforcement. We also plan to have two
separate pserver IP ports: one for the public tree, and
one for the local tree.
From what I've read, we can access our internal
pservers by transiting through our firewall servers
by using ssh port forwarding. Although port forwarding
works, it is a bit clunky. Also, we'd prefer not to
disturb our current external developers (who are using
ssh into the firewall machine and the :ext: server
protocol). We'd use --allow-root and xinetd to
handle those restricted accesses in the usual way.
Doing a little research, I noticed that pserver and
server share the same CVS transaction protocol, except
for the "front end" of the protocol where pserver
authenticates and :ext: server does not. It seemed
to me that it might be possible to write a "server
to pserver" protocol converter, that talks to an
:ext:server client on side and that translates those
requests to a pserver in a meaningful way.
To demonstrate how this might be done, I've sketched
out the basics as I understand them.
cvspsproxy - a cvs server proxy that connects to a pserver
cvspsproxy supports connections from CVS clients using
the :ext: server protocol. cvspsproxy will in turn connect
to a psercer, obtaining the pserver specification by
reading the various :ext:server specifications from stdin,
utilizing the server protocol. The pserver user, host,
and password will be extracted from the ~/.cvspass file.
This authentication information is then sent to the
pserver. Once authenticated cvspsproxy simply passes
data between the client and the pserver. This works
because the pserver and server protocols are identical
once the client has been authenticated.
Cvspsproxy is intended for use via an ssh connection,
but can be used in other contexts as well.
1. Read and parse initial server commands, up to the "Root"
- Root pathname \n
The Root request must be sent only once, and it must be sent before any
requests other than Valid-responses, valid-requests, UseUnchanged, Set,
Global_option, init, noop, or version
- Valid-responses request-list \n
- Valid-requests \n (server sends back list of requests it can process)
cvspsproxy will have to send a string of valid requests that
are supported, if this is sent before authentication.
- UseUnchanged \n
- Set variable=value \n
- Global_option option \n
- init root-name \n This will have to be unsupported because the
pserver has no way to veriyf access if no CVS root exists yet.
- noop Send back any pending errors, pending Notified reponses
- version Send back version string.
In order to get the valid requests response and version response
correct, cvspsproxy should be built withn the CVS build tree, using
All of the commands listed above can be sent by the client
before sending the Root request.
Once the root request is sent:
1. Look it up the .cvspass file and obtain the following
info. that will be sent to the pserver for authentication
purposes: (1) user, (2) password, (3) host, (4) port.
2. Connect to the host on the given port.
the string `BEGIN AUTH REQUEST', a linefeed,
the cvs root, a linefeed,
the username, a linefeed,
the password trivially scrambled, a linefeed,
the string `END AUTH REQUEST', and a linefeed.
4 Pserver replies with:
* I LOVE YOU - continue with server protocol, working
as a pure proxy simply passing packets back-forth
between the user client and the pserver.
* I HATE YOU - close the connection
* E text - send back this response and all following E responses
* error code text - send to cliet and close connection
The .cvspass check could be augmented by
1. a -d switch
2. a CVSROOT environment variable
3. and then the .cvspass check
Certain consistency checks may be required to ensure that
the Root specified by the server is the same root as that
sent to the pserver.
Does that sound feasible/useful? If it does, and someone
with knowledge of CVS internals has an interest to develop
this idea further, I'd be glad to help test and debug
the result (but don't have time right now write the
- RFC: server->pserver proxy?,
Gary Funck <=