In this post I will explain how to enable SSL for jenkins testlink plugin. When you try to access testlink via SSL from Jenkins you might come across the following error.
Archiving /home/ubuntu/.jenkins/jobs/TestSample/workspace/pom.xml to org.wso2.carbon/testng-test/1.0.0/testng-test-1.0.0.pom
channel stopped
Preparing TestLink client API.
Using TestLink URL: https://192.168.48.112/lib/api/xmlrpc/v1/xmlrpc.php
FATAL: Error verifying developer key: Failed to read server's response: java.security.cert.CertificateException: No subject alternative names present
br.eti.kinoshita.testlinkjavaapi.util.TestLinkAPIException: Error verifying developer key: Failed to read server's response: java.security.cert.CertificateException: No subject alternative names present
at br.eti.kinoshita.testlinkjavaapi.MiscService.checkDevKey(MiscService.java:63)
at br.eti.kinoshita.testlinkjavaapi.TestLinkAPI.<init>(TestLinkAPI.java:144)
at hudson.plugins.testlink.TestLinkBuilder.getTestLinkSite(TestLinkBuilder.java:320)
at hudson.plugins.testlink.TestLinkBuilder.perform(TestLinkBuilder.java:199)
at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:782)
at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.build(MavenModuleSetBuild.java:906)
at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.doRun(MavenModuleSetBuild.java:857)
at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:534)
at hudson.model.Run.execute(Run.java:1738)
at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:529)
at hudson.model.ResourceController.execute(ResourceController.java:98)
at hudson.model.Executor.run(Executor.java:410)
Caused by: org.apache.xmlrpc.XmlRpcException: Failed to read server's response: java.security.cert.CertificateException: No subject alternative names present
at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:161)
at org.apache.xmlrpc.client.XmlRpcHttpTransport.sendRequest(XmlRpcHttpTransport.java:143)
at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.sendRequest(XmlRpcSunHttpTransport.java:69)
at org.apache.xmlrpc.client.XmlRpcClientWorker.execute(XmlRpcClientWorker.java:56)
at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:167)
at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:158)
at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:147)
at br.eti.kinoshita.testlinkjavaapi.BaseService.executeXmlRpcCall(BaseService.java:90)
at br.eti.kinoshita.testlinkjavaapi.MiscService.checkDevKey(MiscService.java:60)
... 12 more
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1091)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.writeRequest(XmlRpcSunHttpTransport.java:104)
at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:151)
... 20 more
Caused by: java.security.cert.CertificateException: No subject alternative names present
at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:142)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:91)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:347)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:203)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)
... 33 more
ERROR: Error communicating with TestLink. Check your TestLink configuration.
Finished: FAILURE
Since the test-link plugin doesn't support SSL connections directly, you have to set SSL configurations from JVM level and get it to work.
In my case Jenkins is running on Tomcat and Test link is hosted in Apache2. The SSL layer is handled by Apache it self. So first we need to create a certificate with a proper hostname for Apache to access testlink. You can follow
this tutorial to create a certificate and enable SSL for Apache2.
After creating a proper certificate. Lets configure and add this to tomcat.
Download the created .crt file. You can do this via your browser as well. Go to certificate settings page and import the certificate through the browser.
Now lets create a new keystore with the certificate. Execute the following commands for this.
1. Login to the server where you have hosted jenkins.
2. Create a directory called ssl with the following command.
mkdir /home/ubuntu/jenkins/ssl
3. Now navigate to the created directory.
cd /home/ubuntu/jenkins/ssl
4. Copy the downloaded .crt to the above directory and execute the following command. This will create new trust store with the specified certificate.
keytool -importcert -keystore jssecacerts -trustcacerts -alias wso2qa -file apache.crt
Note : Make sure to give information that's relevant to your setup. e.g : file name, alias etc.
5. Now we need to tell tomcat where to look for the keystore. So execute the following command.
export CATALINA_OPTS="-Djavax.net.ssl.keyStoreType=jks -Djavax.net.ssl.keyStore=/home/ubuntu/jenkins/ssl/jssecacerts -Djavax.net.ssl.keyStorePassword=wso2qa123 -Djavax.net.ssl.trustStore=/home/ubuntu/jenkins/ssl/jssecacerts -Djavax.net.ssl.trustStorePassword=wso2qa123 -Djsse.enableSNIExtension=false"
CATALINA_OPTS is what tomcat refers when its started.
Note : Make sure you give the correct information in the above command (File paths/ password etc.). Also you can add the above line to bashrc or environments so it gets set on server startup.
Now restart tomcat. If everything is set properly you should be able to communicate with testlink via the https endpoint.
Note : Also if you get the above error even after following the above steps, make sure that you have defined the test-link endpoint with the host name provided in certificate you created.