Hi everyone
I am trying to modify the svn protocol to add TLS support to it,
similar to how SMTP has STARTTLS support. I have briefly understood how
the svn protocol works. For those who don't know what the protocol is,
it is the protocol for client-server communications when using the
ra_svn layer. It is documented here:
http://svn.collab.net/repos/svn/trunk/subversion/libsvn_ra_svn/protocol
I am wondering if any SVN developers can proof-read this approach and
assist. It is a fairly simple modification. Basically the TLS support is
meant to work this way:
Support and absense of support for TLS are advertised as capabilities
by the server, upon connection. The client also MUST respond with the
capabilities in its response to the server. The capability word is
`starttls' for TLS support and `nostarttls' for no use of TLS (without
the quotes) for both the client and the server. Both the server and
client MUST respond with at least one of these capabilities, i.e., they
can't respond without at least one of these capabilities in their list
of capabilities.
If the client DOES NOT respond with the `starttls' capability, and if
only `starttls' was advertised as a capability by the server (and
`nostarttls' isn't) the client must immediately close the connection
(and report this to the user).
If the client DOES NOT respond with the `starttls' capability, and
`nostarttls' was advertised as a capability by the server, the server
immediately sends the auth-request command-response as it does in the
current version of the protocol and things continue as usual.
If the client DOES respond with the `starttls' capability, and
`starttls' was advertised as a capability by the server, the server
ignores the `url' argument and responds with the following response:
starttls: ( success ( starttls ) )
The above response is sent before TLS setup starts. The client should
then start TLS negotiation before issuing any other commands.
[The following was adapted from IETF's RFC 2487]
After the TLS handshake has been completed, both parties MUST
immediately decide whether or not to continue based on the
authentication and privacy achieved. Clients or servers may want to
continue only if a particular level of authentication and/or privacy was
achieved.
If the client decides that the level of authentication or privacy
is not high enough for it to continue, it SHOULD close the connection
immediately after the TLS negotiation is complete. If the server
decides that the level of authentication or privacy is not high
enough for it to continue, it SHOULD reply to every command from
the client with a failure command response (with a possible message
string such as "Command refused due to lack of security").
The decision of whether or not to believe the authenticity of the
other party in a TLS negotiation is a local matter. However, some
example rules for the decisions are:
- A client would probably only want to authenticate a
server whose server certificate has a domain name that is the
domain name that the client thought it was connecting to.
- A publicly-referenced server would probably want to accept
a certificate from a client signed by a known CA, and would
possibly want to put distinguishing information about the
certificate in the access logs.
- A client may want to communicate to a server using TLS
when the session's symmetric cipher algorithm is among
a list of acceptable ciphers
Upon completion of the TLS handshake, the protocol is reset to the
initial state and the server issues another greeting immediately. This
time, the server MUST NOT include the `starttls' capability, but MUST
include the `nostarttls' capability. The server MUST discard any
knowledge obtained from the client, such as its knowledge of the
client's capabilities, which was not obtained from the TLS negotiation
itself. The client MUST discard any knowledge obtained from the server,
such as the server's capabilities, which was not obtained from the TLS
negotiation itself. The client MUST send a response with its
capabilities and the URL, as a response to the server's capabilities.
This time, the client MUST NOT include the `starttls' capability, but
MUST include the `nostarttls' capability. Both the client and the server
MUST know if there is a TLS session active.
The list of capabilities returned by the server after the TLS
handshake MAY be different than the list returned before the TLS
handshake. For example, the server might not want to advertise
support for a particular SASL mechanism unless a client has sent
an appropriate client certificate during a TLS handshake.
A man-in-the-middle attack can be launched by deleting the
`starttls' capability in the response from the server. This would
cause the client not to try to start a TLS session. A client can
protect against this attack by not continuing with the insecure
connection, or in case of no enforced configuration, recording the
fact that a particular server offers TLS during one session and
generating an alarm if it does not appear in the capabilities
response for a later session.
Before the TLS handshake has begun, any protocol interactions
are performed in the clear and may be modified by an active attacker. For
this reason, clients and servers MUST discard any knowledge obtained
prior to the start of the TLS handshake upon completion of the TLS
handshake.
[End of part adapted from IETF's RFC 2487]
As can be understood from above, TLS can be setup only once early in
the protocol and it is meant to stay used once established, until the
connection is closed. `starttls' is also not implemented as a command
but is setup when the capabilities match. So if the client does not wish
to use TLS, it should not advertise that capability. The client may even
decide to respond appropriately after parsing the server's
greeting/capabilities command response.
A common approach which was adopted by many protocols for TLS support
was to have a different port number with 's' suffixed to the URI scheme.
Nowadays it is considered by many people to be a bad idea. Extending the
protocol is recommended instead. A good list of points to support this
argument can be found in section 7 of IETF's RFC 2595. Another point to
add to that list is the case of some protocols such as HTTPS and virtual
hosting which suffers from the chicken-and-egg problem and hence needs a
unique IP address per domain, as the virtual host to connect to cannot
be specified by the client to the server until the TLS is established
and operational, and the server is to return a certificate with the
host's domain name in the CN field during the TLS setup.
Mukund
Received on Sun Jul 11 17:30:56 2004