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

NullPointerException for SVN authentication using username+password and client certificate

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved (View Workflow)
    • Priority: Major
    • Resolution: Fixed
    • Component/s: subversion-plugin
    • Labels:
      None
    • Environment:
      OpenSuSE 11.2, jenkins-1.428-1.2 installed using package manager, upgrade from hudson 1.373 package
    • Similar Issues:

      Description

      The Subversion server uses both client certificate and username+password. I've configured authentication as described in JENKINS-3912. I've also tried using a fresh .subversion dir, as described in JENKINS-4037 although that bug has a different NPE than this.

      The client certificate part probably goes well, because after adding my cert and its password I get the authentication error details saying "401 Authentication Required":

      Attempting an SSL client certificate authentcation
      Passing user name null and password you entered
      Failed to authenticate: org.tmatesoft.svn.core.SVNErrorMessage: svn: OPTIONS of /svn/project/trunk: 401 Authorization

      But when adding login username and password I get:

      Attempting an SSL client certificate authentcation
      FAILED: org.tmatesoft.svn.core.SVNErrorMessage: svn: OPTIONS /svn/project/trunk failed

      org.tmatesoft.svn.core.SVNException: svn: OPTIONS /svn/project/trunk failed
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:291)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:276)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:264)
      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:1857)
      at hudson.scm.SubversionSCM$DescriptorImpl.doPostCredential(SubversionSCM.java:1802)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:616)
      at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:282)
      at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:149)
      at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:88)
      at org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:104)
      at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:53)
      at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:561)
      at org.kohsuke.stapler.Stapler.invoke(Stapler.java:646)
      at org.kohsuke.stapler.MetaClass$6.doDispatch(MetaClass.java:234)
      at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:53)
      at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:561)
      at org.kohsuke.stapler.Stapler.invoke(Stapler.java:646)
      at org.kohsuke.stapler.MetaClass$6.doDispatch(MetaClass.java:234)
      at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:53)
      at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:561)
      at org.kohsuke.stapler.Stapler.invoke(Stapler.java:646)
      at org.kohsuke.stapler.Stapler.invoke(Stapler.java:477)
      at org.kohsuke.stapler.Stapler.service(Stapler.java:159)
      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.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 hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:81)
      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:636)
      Caused by: org.tmatesoft.svn.core.SVNErrorMessage: svn: OPTIONS /svn/modules/cms-item/trunk failed
      at org.tmatesoft.svn.core.SVNErrorMessage.create(SVNErrorMessage.java:200)
      at org.tmatesoft.svn.core.SVNErrorMessage.create(SVNErrorMessage.java:146)
      at org.tmatesoft.svn.core.SVNErrorMessage.create(SVNErrorMessage.java:89)
      ... 53 more
      Caused by: org.tmatesoft.svn.core.SVNException: svn: Unknown error
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPSSLKeyManager.acknowledgeAndClearAuthentication(HTTPSSLKeyManager.java:295)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection._request(HTTPConnection.java:387)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:285)
      ... 52 more
      Caused by: org.tmatesoft.svn.core.SVNErrorMessage: svn: Unknown error
      at org.tmatesoft.svn.core.SVNErrorMessage.create(SVNErrorMessage.java:101)
      ... 55 more
      Caused by: java.lang.NullPointerException
      at org.apache.commons.io.FileUtils.openInputStream(FileUtils.java:129)
      at org.apache.commons.io.FileUtils.readFileToByteArray(FileUtils.java:1135)
      at hudson.scm.SubversionSCM$DescriptorImpl$SslClientCertificateCredential.<init>(SubversionSCM.java:1556)
      at hudson.scm.UserProvidedCredential$AuthenticationManagerImpl.getFirstAuthentication(UserProvidedCredential.java:204)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPSSLKeyManager.initialize(HTTPSSLKeyManager.java:319)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPSSLKeyManager.initializeNoException(HTTPSSLKeyManager.java:301)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPSSLKeyManager.chooseClientAlias(HTTPSSLKeyManager.java:196)
      at sun.security.ssl.AbstractWrapper.chooseClientAlias(SSLContextImpl.java:282)
      at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:629)
      at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:228)
      at sun.security.ssl.Handshaker.processLoop(Handshaker.java:610)
      at sun.security.ssl.Handshaker.process_record(Handshaker.java:546)
      at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:913)
      at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1158)
      at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:652)
      at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:78)
      at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
      at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
      at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.sendData(HTTPConnection.java:229)
      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:364)
      ... 53 more

      In 1.373 I managed to get working authentication by caching credentials on the command line using svnkit-cli:

      sudo -u hudson ./jsvn --config-dir /var/lib/hudson/.subversion/ info https://our-sever/svn/

      However this produced the same NPE as above with latest Jenkins. I also tried using the patched Svnkit-1.3.4 from the Jenkins Subversion plugin distribution, but with that one the jsvn command fails to authenticate.

        Attachments

          Activity

          Hide
          solsson Staffan Olsson added a comment -

          I found a hint in JENKINS-8181 that lead to a workaround: First set up the client cert and password in ~/.subversion/servers. Then use SvnKit from command line to cache your credentials, with a username identical to the jenkins user. On our OpenSUSE the command is: ./jsvn info https://my.server/svn/proj/ --config-dir=/var/lib/jenkins/.subversion --username=jenkins. Make sure to chmod the dir writable for the running user before that.

          Show
          solsson Staffan Olsson added a comment - I found a hint in JENKINS-8181 that lead to a workaround: First set up the client cert and password in ~/.subversion/servers. Then use SvnKit from command line to cache your credentials, with a username identical to the jenkins user. On our OpenSUSE the command is: ./jsvn info https://my.server/svn/proj/ --config-dir=/var/lib/jenkins/.subversion --username=jenkins. Make sure to chmod the dir writable for the running user before that.
          Hide
          solsson Staffan Olsson added a comment -

          Another insight today when the client certificate expired: Hudson (1.373, subversion plugin 1.17) actually uses the cert file that was uploaded in the UI even if the passphrase and authentication was cached using command line. Simply replacing the cert file at the path cached under /var/lib/hudson/.subversion/ did not make the Svn plugin use that cert. I had to upload the new cert in the UI and then run the caching workaround command again.

          Haven't seen how our Jenkins installation behaves yet.

          Show
          solsson Staffan Olsson added a comment - Another insight today when the client certificate expired: Hudson (1.373, subversion plugin 1.17) actually uses the cert file that was uploaded in the UI even if the passphrase and authentication was cached using command line. Simply replacing the cert file at the path cached under /var/lib/hudson/.subversion/ did not make the Svn plugin use that cert. I had to upload the new cert in the UI and then run the caching workaround command again. Haven't seen how our Jenkins installation behaves yet.
          Hide
          jogy Johann Gyger added a comment -

          I haven't been able to make this work with Jenkins 1.455. I tried different variations of the described workaround. I still get the exception and it would be nice if the radio buttons could be changed so that multiple "authentication" options are selectable (certificate and username/password).

          Show
          jogy Johann Gyger added a comment - I haven't been able to make this work with Jenkins 1.455. I tried different variations of the described workaround. I still get the exception and it would be nice if the radio buttons could be changed so that multiple "authentication" options are selectable (certificate and username/password).
          Hide
          solsson Staffan Olsson added a comment -

          Managed to do this again in Jenkins 1.490 with svn plugin 1.43. This time the error in the UI was "handshake error".

          The jenkins subversion plugin now runs a version of svnkit 1.7.4, again patched. Clearly client cert AND credentials is not part of the testing.

          The workaround again because I think my earlier posts are a bit unclear:

          • Remove (backup) jenkins' existing .subversion dir. For me it is /var/lib/jenkins/.subversion
          • Try authentication in the UI, jenkins will cache your server cert in a fresh .subversion
          • Upload client cert in the UI, with password – error
          • In jenkins .subversion/servers file configure ssl-client-cert-file and ssl-client-cert-password as for any other svn client
          • As a user with write access to jenkins .subversion (I used root), run a standalone svnkit. I used version 1.7.6.
          • Commmand: ./jsvn info https://my.server/svn/proj/ --config-dir=/var/lib/jenkins/.subversion --username=your-svn-user

          This command immediately produced a prompt that let me confirm that I want to store the client cert pass phrase in plaintext. I didn't even have to type the pass phrase, so it must have gotten it either from the upload or from the config file. After that I was prompted for svn password and confirmation to store in plaintext. After that my jenkins build run.

          Show
          solsson Staffan Olsson added a comment - Managed to do this again in Jenkins 1.490 with svn plugin 1.43. This time the error in the UI was "handshake error". The jenkins subversion plugin now runs a version of svnkit 1.7.4, again patched. Clearly client cert AND credentials is not part of the testing. The workaround again because I think my earlier posts are a bit unclear: Remove (backup) jenkins' existing .subversion dir. For me it is /var/lib/jenkins/.subversion Try authentication in the UI, jenkins will cache your server cert in a fresh .subversion Upload client cert in the UI, with password – error In jenkins .subversion/servers file configure ssl-client-cert-file and ssl-client-cert-password as for any other svn client As a user with write access to jenkins .subversion (I used root), run a standalone svnkit. I used version 1.7.6. Commmand: ./jsvn info https://my.server/svn/proj/ --config-dir=/var/lib/jenkins/.subversion --username=your-svn-user This command immediately produced a prompt that let me confirm that I want to store the client cert pass phrase in plaintext. I didn't even have to type the pass phrase, so it must have gotten it either from the upload or from the config file. After that I was prompted for svn password and confirmation to store in plaintext. After that my jenkins build run.
          Hide
          stephenconnolly Stephen Connolly added a comment -

          Is this related to JENKINS-19175

          Show
          stephenconnolly Stephen Connolly added a comment - Is this related to JENKINS-19175
          Hide
          solsson Staffan Olsson added a comment -

          Looks like it. I will test after next plugin release.

          Show
          solsson Staffan Olsson added a comment - Looks like it. I will test after next plugin release.
          Hide
          stephenconnolly Stephen Connolly added a comment -

          Should be fixed in 2.0+

          The UI validation of the credentials may warn issues. The credentials to select from the drop down should be the first realm that is required to authenticate against. Then in the Additional credentials section provide the second realm credentials and checkout + polling should work correctly

          Show
          stephenconnolly Stephen Connolly added a comment - Should be fixed in 2.0+ The UI validation of the credentials may warn issues. The credentials to select from the drop down should be the first realm that is required to authenticate against. Then in the Additional credentials section provide the second realm credentials and checkout + polling should work correctly

            People

            • Assignee:
              Unassigned
              Reporter:
              solsson Staffan Olsson
            • Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: