From c4d6fa2f20a12898b6f2e5daf74e41866b5853ae Mon Sep 17 00:00:00 2001 From: James Nord Date: Thu, 5 Oct 2023 11:38:40 +0100 Subject: [PATCH] [JEP-237] Disable usage stats in fips mode (#8483) * [JEP-237] disable UsageStats in FIPS mode UsageStatistics is so close to being FIPS-140 compliant but fails at the last hurdle. We can not encrypt with RSA but we can perform key wrap. The output does separate the key and data, by creating a new Key for encrypting the data and that key is encrypted with RSA. If only the RSA cipher was created with Cipher.WRAP_MODE (or Cipher.UNWRAP_MODE) instead of CIPHER.ENCRYPT_MODE (or CIPHER.DECRYPT_MODE) we would be fine, alas it is not and changing this would mean a change on the backend and to be able to continue to support both whilst older versions are in the wild. The goal of JEP-237 is not to fix all non compliant issues, so here we just ensure that in FIPS mode the usage statistics are disabled. Updates the UI in the global config page to adapt to usagestats being fully disabled by system property or partially disabled by the FIPS property Co-authored-by: Daniel Beck <1831569+daniel-beck@users.noreply.github.com> --- .../java/hudson/model/UsageStatistics.java | 13 ++++-- .../model/UsageStatistics/global.groovy | 14 ++++++- .../model/UsageStatistics/global.properties | 4 ++ .../help-usageStatisticsCollected.jelly | 42 ++++++++++++------- 4 files changed, 53 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/hudson/model/UsageStatistics.java b/core/src/main/java/hudson/model/UsageStatistics.java index cbc356aa3b77..9fc052cd1009 100644 --- a/core/src/main/java/hudson/model/UsageStatistics.java +++ b/core/src/main/java/hudson/model/UsageStatistics.java @@ -64,6 +64,7 @@ import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import jenkins.model.Jenkins; +import jenkins.security.FIPS140; import jenkins.util.SystemProperties; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; @@ -102,8 +103,10 @@ public UsageStatistics(String keyImage) { * Returns true if it's time for us to check for new version. */ public boolean isDue() { - // user opted out. no data collection. - if (!Jenkins.get().isUsageStatisticsCollected() || DISABLED) return false; + // user opted out (explicitly or FIPS is requested). no data collection + if (!Jenkins.get().isUsageStatisticsCollected() || DISABLED || FIPS140.useCompliantAlgorithms()) { + return false; + } long now = System.currentTimeMillis(); if (now - lastAttempt > DAY) { @@ -212,7 +215,11 @@ public Permission getRequiredGlobalConfigPagePermission() { public boolean configure(StaplerRequest req, JSONObject json) throws FormException { try { // for backward compatibility reasons, this configuration is stored in Jenkins - Jenkins.get().setNoUsageStatistics(json.has("usageStatisticsCollected") ? null : true); + if (DISABLED) { + Jenkins.get().setNoUsageStatistics(Boolean.TRUE); + } else { + Jenkins.get().setNoUsageStatistics(json.has("usageStatisticsCollected") ? null : Boolean.TRUE); + } return true; } catch (IOException e) { throw new FormException(e, "usageStatisticsCollected"); diff --git a/core/src/main/resources/hudson/model/UsageStatistics/global.groovy b/core/src/main/resources/hudson/model/UsageStatistics/global.groovy index 458880889eb1..901f0ead5448 100644 --- a/core/src/main/resources/hudson/model/UsageStatistics/global.groovy +++ b/core/src/main/resources/hudson/model/UsageStatistics/global.groovy @@ -1,7 +1,19 @@ package hudson.model.UsageStatistics +import hudson.model.UsageStatistics +import jenkins.security.FIPS140 +import hudson.Functions + def f=namespace(lib.FormTagLib) f.section(title: _("Usage Statistics")) { - f.optionalBlock(field: "usageStatisticsCollected", checked: app.usageStatisticsCollected, title: _("statsBlurb")) + if (UsageStatistics.DISABLED) { + span(class: "jenkins-not-applicable") { + raw(_("disabledBySystemProperty")) + } + } else if (FIPS140.useCompliantAlgorithms()) { + f.optionalBlock(field: "usageStatisticsCollected", checked: app.usageStatisticsCollected, title: _("statsBlurbFIPS")) + } else { + f.optionalBlock(field: "usageStatisticsCollected", checked: app.usageStatisticsCollected, title: _("statsBlurb")) + } } diff --git a/core/src/main/resources/hudson/model/UsageStatistics/global.properties b/core/src/main/resources/hudson/model/UsageStatistics/global.properties index 01971f396652..db939f2a7515 100644 --- a/core/src/main/resources/hudson/model/UsageStatistics/global.properties +++ b/core/src/main/resources/hudson/model/UsageStatistics/global.properties @@ -22,4 +22,8 @@ statsBlurb=\ Help make Jenkins better by sending anonymous usage statistics and crash reports to the Jenkins project +statsBlurbFIPS=\ + Help make Jenkins better by sending telemetry to the Jenkins project +disabledBySystemProperty=\ + The option to send anonymous usage statistics, crash reports and telemetry to the Jenkins project is disabled by a System Property. diff --git a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.jelly b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.jelly index 9312e653fee6..80237768112a 100644 --- a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.jelly +++ b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.jelly @@ -6,25 +6,35 @@ When enabled, Jenkins periodically sends information to the Jenkins project. The Jenkins project uses this information to set development priorities. -

General usage statistics

-
-

Jenkins reports the following general usage statistics:

- -

- This does not report any personally identifiable information. The only information reported by Jenkins is information inherently revealed by the HTTP protocol, such as the IP address. - - These usage statistics are aggregated, updated monthly, and published to stats.jenkins.io -

-
+ + +

General usage statistics

+
+

Jenkins reports the following general usage statistics:

+
    +
  • Your Jenkins version
  • +
  • For your controller and each agent, the OS type and number of executors
  • +
  • Installed plugins and their versions
  • +
  • Number of items (like jobs) of each item type
  • +
+

+ This does not report any personally identifiable information. + The only information reported by Jenkins is information inherently revealed by the HTTP protocol, such as the IP address. + These usage statistics are aggregated, updated monthly, and published to stats.jenkins.io +

+
+

Telemetry collection

- In addition to the general usage statistics listed above, the Jenkins project collects telemetry data from specific trials to inform future development. + + + The Jenkins project collects telemetry data from specific trials to inform future development. + + + In addition to the general usage statistics listed above, the Jenkins project collects telemetry data from specific trials to inform future development. + + Each trial has a specific purpose and a defined end date, after which collection stops, independent of the installed versions of Jenkins or plugins. Once a trial is complete, the trial results may be aggregated and shared with the developer community.