Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-5230

Unable to use SSL Auth because certFile is not passed to svnkit

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed (View Workflow)
    • Priority: Major
    • Resolution: Fixed
    • Component/s: subversion-plugin
    • Labels:
      None
    • Environment:
      Running Hudson 1.334, and occurs when built from HEAD revision 25498. Running on an EC2 VM, Linux.
    • Similar Issues:

      Description

      Description of the problem:
      We're unable to use SSL authentication to check out a project from our repository. Accessing this repository from this machine using SSL auth with this same certificate is not a problem - svn checkout of a project from this repository works from the command-line.

      Steps to reproduce:
      Create a job that has an SVN URL to a repository which requires SSL certificate authentication
      2. View the error that shows up beneath the "Repository URL" field: "Unable to access [svn repository] : svn: Received fatal alert: handshake_failure"
      3. Go to the "enter credential" page
      4. Select HTTPS client certificate, browse to your certificate file (.pfx) on your local disk, and enter its password
      5. View the Error page which shows the java stack trace for the error (full stack trace pasted at the bottom of this message)
      Attempting an SSL client certificate authentcation
      Failed to authenticate: svn: SSL handshake failed: 'Received fatal alert: handshake_failure'
      javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

      Possible cause of the problem:
      In the Hudson source code, in the class SubversionSCM.java ( https://hudson.dev.java.net/svn/hudson/trunk/hudson/plugins/subversion/src/main/java/hudson/scm/SubversionSCM.java, revision 25498), we see that the private inner class SslClientCertificateCredential has only one member variable: String password. Its constructor takes two parameters, File certificate and String password, and then it only stores the password.
      After an object of type SslClientCertificateCredential is created (in method public void postCredential()), you call cred.createSVNAuthentication(kind), which goes to the following code:

      public SVNAuthentication createSVNAuthentication(String kind)

      { if(kind.equals(ISVNAuthenticationManager.SSL)) return new SVNSSLAuthentication(null,Scrambler.descramble(password),false); else return null; // unexpected authentication type }

      Here is the constructor signature for SVNSSLAuthentication:
      public SVNSSLAuthentication(File certFile, String password, boolean storageAllowed)

      As you can see, when you are calling the constructor of SVNSSLAuthentication, you are passing null as the first parameter instead of passing a File certFile. This is because you aren't storing the File certificate in the constructor for this class, so you have nothing to pass for that parameter.

      Because you aren't passing in a certFile, when the SVNSSLAuthentication tries to make its request to the SVN server, it doesn't have a certFile to give it, so it causes a handshake_failure when it gets the response from the SVN server.

      Attached is a patch file that I believe will fix this problem.

      _______________________________________________

      The java stack trace for the error incurred in step 5 of the repro steps:

      javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
      at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
      at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1657)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:932)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623)
      at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
      at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
      at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.sendData(HTTPConnection.java:226)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPRequest.dispatch(HTTPRequest.java:166)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:345)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:273)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:261)
      at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.exchangeCapabilities(DAVConnection.java:516)
      at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.open(DAVConnection.java:98)
      at org.tmatesoft.svn.core.internal.io.dav.DAVRepository.openConnection(DAVRepository.java:1001)
      at org.tmatesoft.svn.core.internal.io.dav.DAVRepository.testConnection(DAVRepository.java:97)
      at hudson.scm.SubversionSCM$DescriptorImpl.postCredential(SubversionSCM.java:1701)
      at hudson.scm.SubversionSCM$DescriptorImpl.doPostCredential(SubversionSCM.java:1601)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:185)
      at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:101)
      at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:54)
      at org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:74)
      at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:30)
      at org.kohsuke.stapler.Stapler.invoke(Stapler.java:500)
      at org.kohsuke.stapler.MetaClass$6.doDispatch(MetaClass.java:180)
      at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:30)
      at org.kohsuke.stapler.Stapler.invoke(Stapler.java:500)
      at org.kohsuke.stapler.Stapler.invoke(Stapler.java:416)
      at org.kohsuke.stapler.Stapler.service(Stapler.java:122)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:45)
      at winstone.ServletConfiguration.execute(ServletConfiguration.java:249)
      at winstone.RequestDispatcher.forward(RequestDispatcher.java:335)
      at winstone.RequestDispatcher.doFilter(RequestDispatcher.java:378)
      at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:94)
      at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:86)
      at winstone.FilterConfiguration.execute(FilterConfiguration.java:195)
      at winstone.RequestDispatcher.doFilter(RequestDispatcher.java:368)
      at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:47)
      at winstone.FilterConfiguration.execute(FilterConfiguration.java:195)
      at winstone.RequestDispatcher.doFilter(RequestDispatcher.java:368)
      at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)
      at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
      at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:166)
      at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
      at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:142)
      at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
      at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      at org.acegisecurity.ui.basicauth.BasicProcessingFilter.doFilter(BasicProcessingFilter.java:173)
      at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
      at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:66)
      at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:76)
      at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:164)
      at winstone.FilterConfiguration.execute(FilterConfiguration.java:195)
      at winstone.RequestDispatcher.doFilter(RequestDispatcher.java:368)
      at winstone.RequestDispatcher.forward(RequestDispatcher.java:333)
      at winstone.RequestHandlerThread.processRequest(RequestHandlerThread.java:244)
      at winstone.RequestHandlerThread.run(RequestHandlerThread.java:150)
      at java.lang.Thread.run(Thread.java:619)
      FAILED: svn: Received fatal alert: handshake_failure

        Attachments

          Issue Links

            Activity

            Hide
            kohsuke Kohsuke Kawaguchi added a comment -

            Unfortunately this doesn't quite cut it because Credential subtypes need to be remotable — in a distributed Hudson they can be sent from one place to another.

            We need to patch SVNKit so that it doesn't demand a File object. It should be able to do with just having an in-memory representation of the certificate.

            Show
            kohsuke Kohsuke Kawaguchi added a comment - Unfortunately this doesn't quite cut it because Credential subtypes need to be remotable — in a distributed Hudson they can be sent from one place to another. We need to patch SVNKit so that it doesn't demand a File object. It should be able to do with just having an in-memory representation of the certificate.
            Hide
            scm_issue_link SCM/JIRA link daemon added a comment -

            Code changed in hudson
            User: : kohsuke
            Path:
            trunk/hudson/plugins/subversion/pom.xml
            trunk/hudson/plugins/subversion/src/main/java/hudson/scm/SubversionSCM.java
            http://fisheye4.cenqua.com/changelog/hudson/?cs=25822
            Log:
            [FIXED JENKINS-5230] in 1.9. Retain SSL certificate in memory to resolve this problem.

            Show
            scm_issue_link SCM/JIRA link daemon added a comment - Code changed in hudson User: : kohsuke Path: trunk/hudson/plugins/subversion/pom.xml trunk/hudson/plugins/subversion/src/main/java/hudson/scm/SubversionSCM.java http://fisheye4.cenqua.com/changelog/hudson/?cs=25822 Log: [FIXED JENKINS-5230] in 1.9. Retain SSL certificate in memory to resolve this problem.

              People

              • Assignee:
                Unassigned
                Reporter:
                awixted awixted
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: