Today, my company moved all source code repository to another server and request all developers to start using svn+ssh to access all of the source code. For example svn+ssh://mkyong.com/share/svn/repo. Our company is using Hudson CI to build the source code automatically. I have to configure the Hudson to make it support svn+ssh access.

1) Try F-Secure Authentication Agent

I try to use F-Secure Authentication Agent to generate a pair of keys – public key and private key. However when i submitting private key to Hudson Subversion Authentication, i hit following Hudson error.

Error
Attempting a public key authentication with username mkyong
Failed to authenticate: svn: File 'NULL' is not valid OpenSSH DSA or RSA private key file
FAILED: svn: Authentication failed for svn+ssh://mkyong.com/share/svn/repo

No idea what wrong with it, it look like Hudson didn’t recognize private key format generated by
F-Secure Authentication Agent.

2) Try Putty

I try to use Putty to generate a pair of keys – public key and private key. However when i submit private key to Hudson Subversion Authentication, i hit another error

javax.servlet.ServletException: java.lang.NullPointerException
	org.kohsuke.stapler.Stapler.invoke(Stapler.java:449)
	org.kohsuke.stapler.MetaClass$9.doDispatch(MetaClass.java:263)
	org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:30)
	org.kohsuke.stapler.Stapler.invoke(Stapler.java:440)
	org.kohsuke.stapler.Stapler.invoke(Stapler.java:361)
	org.kohsuke.stapler.Stapler.service(Stapler.java:121)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:61)
	hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:53)
	hudson.security.HudsonFilter.doFilter(HudsonFilter.java:88)
root cause
 
java.lang.NullPointerException
	org.kohsuke.putty.PuTTYKey.toKey(PuTTYKey.java:140)
	org.kohsuke.putty.PuTTYKey.<init>(PuTTYKey.java:108)
	org.kohsuke.putty.PuTTYKey.<init>(PuTTYKey.java:69)
	hudson.scm.SubversionSCM$DescriptorImpl.doPostCredential(SubversionSCM.java:1111)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	java.lang.reflect.Method.invoke(Unknown Source)
	org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:103)
	org.kohsuke.stapler.Function.bindAndinvoke(Function.java:57)
	org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:75)
	org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:30)
	org.kohsuke.stapler.Stapler.invoke(Stapler.java:440)
	org.kohsuke.stapler.MetaClass$9.doDispatch(MetaClass.java:263)
	org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:30)
	org.kohsuke.stapler.Stapler.invoke(Stapler.java:440)
	org.kohsuke.stapler.Stapler.invoke(Stapler.java:361)
	org.kohsuke.stapler.Stapler.service(Stapler.java:121)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:61)
	hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:53)
	hudson.security.HudsonFilter.doFilter(HudsonFilter.java:88)

It’s look like Putty private key format is not suitable by Hudson as well. Hmm… i thought all private key generation methods should follow some kind of standard?

Solution

Googling Hudson …….Googling error….Googling…. whole day, i find out Hudson is using OpenSSH private key format. Is there any other tools that i can use to convert my existing private key to OpenSSH format?

Yes, PuTTYgen.exe had this function to convert putty private key to OpenSSH private key format. Great news, i import my existing Putty generated private key and click on export to OpenSSH format.

After exported to OpenSSH format, i can submit my private key to Hudson without any funny errors anymore. Great! Hudson can support svn+ssh access now.

P.S I also hit following error during configuration Hudson to support svn+ssh, i think it’s due to invalid private key format as well. After using OpenSSH format, this error has gone as well.

INFO: Failed to access subversion repository svn+ssh://mkyong.com/share/svn/repo
org.tmatesoft.svn.core.SVNCancelException: svn: No credential to try. Authentication failed
	at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.cancel(SVNErrorManager.java:36)
	at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.cancel(SVNErrorManager.java:31)
	at org.tmatesoft.svn.core.internal.wc.DefaultSVNAuthenticationManager.getFirstAuthentication(DefaultSVNAuthenticationManager.java:167)
	at org.tmatesoft.svn.core.internal.io.svn.SVNSSHConnector.open(SVNSSHConnector.java:70)
	at org.tmatesoft.svn.core.internal.io.svn.SVNConnection.open(SVNConnection.java:73)
	at org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryImpl.openConnection(SVNRepositoryImpl.java:1229)
	at org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryImpl.testConnection(SVNRepositoryImpl.java:94)
	at hudson.scm.SubversionSCM$DescriptorImpl.checkRepositoryPath(SubversionSCM.java:1308)
	at hudson.scm.SubversionSCM$DescriptorImpl$2.check(SubversionSCM.java:1249)