Thanks Vijay for the detailed explanation...

I am attaching the patch for the script with minor tweaks...


Regards
Prabhu


On Friday 02 September 2011 04:13 PM, vijay wrote:

Actually, there are two issues to be noted.

1.Bug with neon (Reproducible in Ubuntu 10.10, svn 1.6.12, neon 0.29.3/GNUTLS)

2.Bug with openssl (Reproducible in Ubuntu 10.10, neon 0.29.x/openssl 0.9.8o)


Bug with neon (Reproducible in Ubuntu 10.10, neon 0.29.3/GNUTLS)
---------------------------------------------------------------------------------------

Even my svn 1.6 command line binary that comes with Ubuntu 10.10 fails with following error while accessing "https://svn.eu.apache.org";

$ svn info https://svn.eu.apache.org/repos/asf/subversion/README
svn: OPTIONS of 'https://svn.eu.apache.org/repos/asf/subversion/README': SSL handshake failed: SSL error: A TLS warning alert has been received. (https://svn.eu.apache.org)

This is due to a bug[1] reported in neon-GNUTLS combination. It is fixed in neon 0.29.5.

The version of our distro's neon is 0.29.3. If we upgrade the neon library, the issue will be fixed.

Bug with openssl (Reproducible in Ubuntu 10.10, neon 0.29.x/openssl 0.9.8o)
-------------------------------------------------------------------------------------------------

I built subversion trunk with neon 0.29.6 and openssl 0.9.8o. I got the following error message.

svn: E175002: Unable to connect to a repository at URL 'https://svn.eu.apache.org/repos/asf/subversion' svn: E175002: OPTIONS of 'https://svn.eu.apache.org/repos/asf/subversion': SSL handshake failed: SSL error code -1/1/336032856 (https://svn.eu.apache.org)

openssl 0.9.8o has TLS Extensions support but it is broken there.

TLS Extensions support was added to openssl in 2006 itself.[openssl 0.9.8o was released in 2010]

<snip-from-log>
revision 1.33
date: 2006-01-03 04:44:32 +0530; author: bodo; state: Exp; lines: +12 -0; commitid: 5gJcTq6NJelx15gr;
Support TLS extensions (specifically, HostName)

Submitted by: Peter Sylvester
----------------------------
</snip>

Why we say it is broken?
-------------------------------
The server "svn.eu.apache.org" or "svn.us.apache.org" sends an alert message during SSL handshake.

We can look at it in the following ssldump output.

<snip>
vijayaguru@maverick:~/svn-sandbox/Dependencies-Untarred/openssl-0.9.8o/ssl$ sudo ssldump -i eth2 host svn.eu.apache.org
New TCP connection #1: maverick(35789) <-> harmonia.apache.org(443)
1 1  0.4067 (0.4067)  C>S  Handshake
      ClientHello
        Version 3.1
        cipher suites
        Unknown value 0xc014
        Unknown value 0xc00a
        Unknown value 0x39
        Unknown value 0x38
        Unknown value 0x88
        Unknown value 0x87
        Unknown value 0xc00f
        Unknown value 0xc005
        Unknown value 0x35
        Unknown value 0x84
        Unknown value 0xc012
        Unknown value 0xc008
        TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
        Unknown value 0xc00d
        Unknown value 0xc003
        TLS_RSA_WITH_3DES_EDE_CBC_SHA
        Unknown value 0xc013
        Unknown value 0xc009
        Unknown value 0x33
        Unknown value 0x32
        Unknown value 0x9a
        Unknown value 0x99
        Unknown value 0x45
        Unknown value 0x44
        Unknown value 0xc00e
        Unknown value 0xc004
        Unknown value 0x2f
        Unknown value 0x96
        Unknown value 0x41
        TLS_RSA_WITH_IDEA_CBC_SHA
        Unknown value 0xc011
        Unknown value 0xc007
        Unknown value 0xc00c
        Unknown value 0xc002
        TLS_RSA_WITH_RC4_128_SHA
        TLS_RSA_WITH_RC4_128_MD5
        TLS_DHE_RSA_WITH_DES_CBC_SHA
        TLS_DHE_DSS_WITH_DES_CBC_SHA
        TLS_RSA_WITH_DES_CBC_SHA
        TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
        TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
        TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
        TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
        TLS_RSA_EXPORT_WITH_RC4_40_MD5
        Unknown value 0xff
        compression methods
                  NULL
* 1 2  0.8245 (0.4177)  S>C  Alert *
    level           warning
    value         unknown value
</snip>

What does this alert message refer to?
-------------------------------------------------
<snip>

From _http://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_record_protocol_
Alert protocol

This record should normally not be sent during normal handshaking or application exchanges. However, this message can be sent at any time during the handshake and up to the closure of the session. If this is used to signal a fatal error, the session will be closed immediately after sending this record, so this record is used to give a reason for this closure. If the alert level is flagged as a warning, the remote can decide to close the session if it decides that the session is not reliable enough for its needs (before doing so, the remote may also send its own signal).
</snip>

There are two alert level types.

1.Warning
2.fatal

openssl 1.0.0d handles warning and fatal alert types in different ways.

1. If it is fatal, terminate the session.

2.If it is warning, resume it.

You can look at it in "{openssl-src-dir}/ssl/s23_clnt.c: ssl23_get_server_hello()"

But openssl 0.9.8o terminates the session if it receives an alert message; no matter the level of alert.

Here, in this case, the level of alert is "Warning".
With openssl 0.9.8o, the connection is closed immediately. We see the following error message.

<snip>
svn: E175002: Unable to connect to a repository at URL 'https://svn.eu.apache.org/repos/asf/subversion' svn: E175002: OPTIONS of 'https://svn.eu.apache.org/repos/asf/subversion': SSL handshake failed: SSL error code -1/1/336032856 (https://svn.eu.apache.org)
</snip>

openssl 1.0.0d proceeds further and we could successfully complete our svn operation.

Upgrading openssl to 1.0.0d will fix this issue.

Thanks Daniel. It is a very good learning for us.

[1] https://bugs.launchpad.net/ubuntu/+source/subversion/+bug/294648

Thanks & Regards,
Vijayaguru

Index: tools/examples/get-location-segments.py
===================================================================
--- tools/examples/get-location-segments.py     (revision 1160112)
+++ tools/examples/get-location-segments.py     (working copy)
@@ -21,6 +21,7 @@
 #
 import sys
 import os
+import getpass
 from svn import client, ra, core
 
 def printer(segment, pool):
@@ -71,6 +72,39 @@
   return url, peg_revision, start_revision, end_revision
 
 
+def prompt_func_ssl_unknown_cert(realm, failures, cert_info, may_save, pool):
+  print "The certficate details are as follows:"
+  print "--------------------------------------"
+  print "Issuer     : " + str(cert_info.issuer_dname)
+  print "Hostname   : " + str(cert_info.hostname)
+  print "ValidFrom  : " + str(cert_info.valid_from)
+  print "ValidUpto  : " + str(cert_info.valid_until)
+  print "Fingerprint: " + str(cert_info.fingerprint)
+  print ""
+  ssl_trust = core.svn_auth_cred_ssl_server_trust_t()
+  if may_save:
+    choice = raw_input( "accept (t)temporarily   (p)permanently: ")
+  else:
+    choice = raw_input( "(r)Reject or accept (t)temporarily: ")
+  if choice[0] == "t" or choice[0] == "T":
+    ssl_trust.may_save = False
+    ssl_trust.accepted_failures = failures
+  elif choice[0] == "p" or choice[0] == "P":
+    ssl_trust.may_save = True
+    ssl_trust.accepted_failures = failures
+  else:
+    ssl_trust = None
+  return ssl_trust
+
+def prompt_func_simple_prompt(realm, username, may_save, pool):
+  username = raw_input("username: ")
+  password = getpass.getpass(prompt="password: ")
+  simple_cred = core.svn_auth_cred_simple_t()
+  simple_cred.username = username
+  simple_cred.password = password
+  simple_cred.may_save = False
+  return simple_cred
+
 def main():
   try:
     url, peg_revision, start_revision, end_revision = parse_args(sys.argv[1:])
@@ -92,6 +126,8 @@
   core.svn_config_ensure(None)
   ctx = client.ctx_t()
   providers = [
+    core.svn_auth_get_simple_prompt_provider(prompt_func_simple_prompt, 2),
+    
core.svn_auth_get_ssl_server_trust_prompt_provider(prompt_func_ssl_unknown_cert),
     client.get_simple_provider(),
     client.get_username_provider(),
     client.get_ssl_server_trust_file_provider(),

Reply via email to