Allow ignoring SSL cert when connecting to gerrit
Introduce a new boolean flag '--ignore-ssl-cert' (false by default),
to ignore validating SSL certificate. This is useful when connecting
to gerrit servers installed with self-signed certificate.
Feature: Issue 10097
Change-Id: I3467800c46123d42e8f7e37fb51a0eebf6e357d1
diff --git a/README.md b/README.md
index db7bd8a..eee18aa 100644
--- a/README.md
+++ b/README.md
@@ -68,6 +68,7 @@
If not specified events will be ignored
- --writeNotProcessedEventsTo location where to write a TSV file containing the events we couldn't process
with a description fo the reason why
+- -k --ignore-ssl-cert allows to proceed even for server connections otherwise considered insecure.
CSVs with 3 columns are expected in input.
diff --git a/common/src/main/scala/com/gerritforge/analytics/common/api/TrustAll.scala b/common/src/main/scala/com/gerritforge/analytics/common/api/TrustAll.scala
new file mode 100644
index 0000000..eb9394b
--- /dev/null
+++ b/common/src/main/scala/com/gerritforge/analytics/common/api/TrustAll.scala
@@ -0,0 +1,15 @@
+package com.gerritforge.analytics.common.api
+
+import java.security.cert.X509Certificate
+
+import javax.net.ssl._
+
+object TrustAll extends X509TrustManager {
+ override val getAcceptedIssuers: Array[X509Certificate] = Array.empty[X509Certificate]
+ override def checkClientTrusted(x509Certificates: Array[X509Certificate], s: String): Unit = ()
+ override def checkServerTrusted(x509Certificates: Array[X509Certificate], s: String): Unit = ()
+}
+
+object VerifiesAllHostNames extends HostnameVerifier {
+ override def verify(s: String, sslSession: SSLSession) = true
+}
\ No newline at end of file
diff --git a/common/src/main/scala/com/gerritforge/analytics/common/api/gerritApiConnectivity.scala b/common/src/main/scala/com/gerritforge/analytics/common/api/gerritApiConnectivity.scala
index b3214e2..91fa6aa 100644
--- a/common/src/main/scala/com/gerritforge/analytics/common/api/gerritApiConnectivity.scala
+++ b/common/src/main/scala/com/gerritforge/analytics/common/api/gerritApiConnectivity.scala
@@ -17,6 +17,7 @@
import java.net.URL
import com.typesafe.scalalogging.LazyLogging
+import javax.net.ssl.{HttpsURLConnection, SSLContext}
import org.apache.commons.codec.binary.Base64
import scala.io.{BufferedSource, Codec, Source}
@@ -34,9 +35,11 @@
BASIC + " " + encodeCredentials(username, password)
}
-class GerritConnectivity(maybeUsername: Option[String], maybePassword: Option[String]) extends HttpBasicAuthentication with Serializable with LazyLogging {
+class GerritConnectivity(maybeUsername: Option[String], maybePassword: Option[String], ignoreSSLCert: Boolean = false) extends HttpBasicAuthentication with Serializable with LazyLogging {
private def createBasicSecuredConnection(url: String, username: String, password: String): BufferedSource = {
try {
+ if(ignoreSSLCert) trustAllSSLCerts()
+
val unsecureURL = new URL(url)
val endPointPath = unsecureURL.getFile
val basicAuthURL = unsecureURL.toString.replace(endPointPath, s"/a$endPointPath")
@@ -53,6 +56,8 @@
}
private def createNonSecuredConnection(url: String): BufferedSource = {
+ if(ignoreSSLCert) trustAllSSLCerts()
+
logger.info(s"Connecting to API $url")
Source.fromURL(url, Codec.UTF8.name)
}
@@ -65,4 +70,12 @@
} yield (createBasicSecuredConnection(url, username, password))
).getOrElse(createNonSecuredConnection(url))
}
+
+ private def trustAllSSLCerts(): Unit = {
+ logger.warn("Trusting all SSL certificates")
+ val sslContext = SSLContext.getInstance("SSL")
+ sslContext.init(null, Array(TrustAll), new java.security.SecureRandom())
+ HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory)
+ HttpsURLConnection.setDefaultHostnameVerifier(VerifiesAllHostNames)
+ }
}
diff --git a/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/job/Main.scala b/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/job/Main.scala
index f99a4d1..de9ae01 100644
--- a/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/job/Main.scala
+++ b/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/job/Main.scala
@@ -105,6 +105,10 @@
c.copy(password = Some(input))
} text "Gerrit API Password"
+ opt[Boolean]('k', "ignore-ssl-cert") optional () action { (input, c) =>
+ c.copy(ignoreSSLCert = Some(input))
+ } text "Ignore SSL certificate validation"
+
opt[Boolean]('r', "extract-branches") optional () action { (input, c) =>
c.copy(extractBranches = Some(input))
} text "enables branches extraction for each commit"
diff --git a/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/model/GerritEndpointConfig.scala b/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/model/GerritEndpointConfig.scala
index e12ad91..b949fa9 100644
--- a/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/model/GerritEndpointConfig.scala
+++ b/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/model/GerritEndpointConfig.scala
@@ -34,9 +34,10 @@
eventsFailureOutputPath: Option[String] = None,
username: Option[String] = None,
password: Option[String] = None,
+ ignoreSSLCert: Option[Boolean] = None,
extractBranches: Option[Boolean] = None) {
- val gerritApiConnection: GerritConnectivity = new GerritConnectivity(username, password)
+ val gerritApiConnection: GerritConnectivity = new GerritConnectivity(username, password, ignoreSSLCert.getOrElse(false))
val gerritProjectsUrl: Option[String] = baseUrl.map { url =>
s"${url}/projects/" + prefix.fold("")("?p=" + _)
diff --git a/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/plugin/ProcessGitCommitsCommand.scala b/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/plugin/ProcessGitCommitsCommand.scala
index 41cce5e..bf42ee2 100644
--- a/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/plugin/ProcessGitCommitsCommand.scala
+++ b/gitcommits/src/main/scala/com/gerritforge/analytics/gitcommits/plugin/ProcessGitCommitsCommand.scala
@@ -49,6 +49,11 @@
usage = "\"emails to author alias\" input data path")
var emailAlias: String = null
+ @ArgOption(name = "--ignore-ssl-cert",
+ aliases = Array("-k"),
+ usage = "Ignore SSL certificate validation")
+ var ignoreSSLCert: Boolean = false
+
@ArgOption(name = "--extract-branches",
aliases = Array("-r"),
usage = "enables branches extraction for each commit")
@@ -63,7 +68,9 @@
beginDate,
endDate,
aggregate,
- emailAlias)
+ emailAlias,
+ ignoreSSLCert=Some(ignoreSSLCert)
+ )
implicit val spark: SparkSession = SparkSession
.builder()