From d986c426942e42d07a4bd1f72e462409ca8d1bbe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:11:40 -0700 Subject: [PATCH 01/12] Update dependency org.jenkins-ci:jenkins to v1.120 (#9668) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e64596137f2e..e486f706d0c7 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci jenkins - 1.119 + 1.120 From 4a35cc13de79200c11cbe6a075ab33a98c1d462a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:48:25 -0700 Subject: [PATCH 02/12] Update jenkins/ath Docker tag to v5957 (#9669) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- ath.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ath.sh b/ath.sh index 415a9c6bd72d..6890d5908ab6 100644 --- a/ath.sh +++ b/ath.sh @@ -6,7 +6,7 @@ set -o xtrace cd "$(dirname "$0")" # https://github.com/jenkinsci/acceptance-test-harness/releases -export ATH_VERSION=5941.v95f3439136c7 +export ATH_VERSION=5957.v7c0e2f7ca_63e if [[ $# -eq 0 ]]; then export JDK=17 From e698b1801d9849b80ddd00acea12a4322909e20f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:51:30 -0700 Subject: [PATCH 03/12] Update Yarn to v4.4.1 (#9666) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/package.json | 2 +- war/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/war/package.json b/war/package.json index d3f908bb91e9..0fa3f50d288c 100644 --- a/war/package.json +++ b/war/package.json @@ -65,5 +65,5 @@ "defaults", "not IE 11" ], - "packageManager": "yarn@4.4.0" + "packageManager": "yarn@4.4.1" } diff --git a/war/pom.xml b/war/pom.xml index 27f19bf0be10..e6b4bf8251b7 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -53,8 +53,8 @@ THE SOFTWARE. 1.22.19 - 4.4.0 - 5f228cb28f2edb97d8c3b667fb7b2fdcf06c46798e25ea889dad9e0b4bc2e2c1 + 4.4.1 + 920b4530755296dc2ce8b4351f057d4a26429524fcb2789d277560d94837c27e From 1194313ef6c62fd43feaf71cd18f468c6a70ff41 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 12:36:22 -0700 Subject: [PATCH 04/12] Update dependency org.jenkins-ci:jenkins to v1.121 (#9670) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e486f706d0c7..bf5d1172fa37 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci jenkins - 1.120 + 1.121 From 62691528b2fd6702e52ab16061d25ae718cb6ab1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 13:13:35 -0700 Subject: [PATCH 05/12] Update dependency org.jenkins-ci:jenkins to v1.122 (#9671) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bf5d1172fa37..921d6a9f7009 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci jenkins - 1.121 + 1.122 From f84ab6aae198fb4c434783d91522815c2c852cf8 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Tue, 27 Aug 2024 21:22:12 -0400 Subject: [PATCH 06/12] [JENKINS-73692] Turn off logging from `BackgroundGlobalBuildDiscarder` (#9663) Turn off logging from `BackgroundGlobalBuildDiscarder` --- .../java/jenkins/model/BackgroundGlobalBuildDiscarder.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/src/main/java/jenkins/model/BackgroundGlobalBuildDiscarder.java b/core/src/main/java/jenkins/model/BackgroundGlobalBuildDiscarder.java index 943a7fd04ba6..1a42c0577a47 100644 --- a/core/src/main/java/jenkins/model/BackgroundGlobalBuildDiscarder.java +++ b/core/src/main/java/jenkins/model/BackgroundGlobalBuildDiscarder.java @@ -57,12 +57,9 @@ protected void execute(TaskListener listener) throws IOException, InterruptedExc } public static void processJob(TaskListener listener, Job job) { - listener.getLogger().println("Processing " + job.getFullName()); GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().forEach(strategy -> { String displayName = strategy.getDescriptor().getDisplayName(); - listener.getLogger().println("Offering " + job.getFullName() + " to " + displayName); if (strategy.isApplicable(job)) { - listener.getLogger().println(job.getFullName() + " accepted by " + displayName); try { strategy.apply(job); } catch (Exception ex) { From 5df30de4358ca93db17eb1d80a6b3a6f1c92ffad Mon Sep 17 00:00:00 2001 From: Vincent Latombe Date: Wed, 28 Aug 2024 03:22:38 +0200 Subject: [PATCH 07/12] Add -webSocket option by default when creating an inbound agent (#9665) * Add -webSocket option by default when creating an inbound agent * Update core/src/main/resources/hudson/slaves/JNLPLauncher/main.properties Co-authored-by: Jesse Glick --------- Co-authored-by: Jesse Glick --- core/src/main/java/hudson/slaves/JNLPLauncher.java | 4 +--- .../main/resources/hudson/slaves/JNLPLauncher/main.properties | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/hudson/slaves/JNLPLauncher.java b/core/src/main/java/hudson/slaves/JNLPLauncher.java index 4f0cbc1e6153..09d2b52a15fe 100644 --- a/core/src/main/java/hudson/slaves/JNLPLauncher.java +++ b/core/src/main/java/hudson/slaves/JNLPLauncher.java @@ -213,9 +213,7 @@ private String getRemotingOptions(String computerName) { sb.append("-name "); sb.append(computerName); sb.append(' '); - if (isWebSocket()) { - sb.append("-webSocket "); - } + sb.append("-webSocket "); if (tunnel != null) { sb.append(" -tunnel "); sb.append(tunnel); diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main.properties index dbb8ec9fed72..1eb84e1006bf 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main.properties @@ -26,7 +26,7 @@ slaveAgent.cli.run=Run from agent command line: slaveAgent.cli.run.secret=Or run from agent command line, with the secret stored in a file: powerShell.cli.curl=Note: PowerShell users must use curl.exe instead of curl because curl is a default PowerShell cmdlet alias for Invoke-WebRequest. commonOptions=\ - The most commonly used option is -webSocket. \ + If you prefer to use TCP instead of WebSockets, remove the -webSocket option. \ Run java -jar agent.jar -help for more. tcp-port-disabled=\ The TCP port is disabled so TCP agents may not be connected. \ From 7a88dc378e7431d31a2a187ccc72e236975cf9c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:28:23 -0700 Subject: [PATCH 08/12] Update dependency org.apache.ant:ant to v1.10.15 (#9675) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index ad23ed312b5e..adf65f6cf439 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -189,7 +189,7 @@ THE SOFTWARE. org.apache.ant ant - 1.10.14 + 1.10.15 org.apache.commons From a075ffb5832a2c7687470a2151e1242ef4a79c8d Mon Sep 17 00:00:00 2001 From: Kris Stern Date: Fri, 30 Aug 2024 21:25:58 +0800 Subject: [PATCH 09/12] Add doCheckDisplayNameOrNull to jenkins core (#9150) Co-authored-by: Daniel Beck <1831569+daniel-beck@users.noreply.github.com> --- core/src/main/java/hudson/model/AbstractProject.java | 5 ----- .../main/java/hudson/model/TopLevelItemDescriptor.java | 9 +++++++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index c568f8df8b31..917ff1f7b81f 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -1934,11 +1934,6 @@ public boolean isApplicable(Descriptor descriptor) { return true; } - @Restricted(DoNotUse.class) - public FormValidation doCheckDisplayNameOrNull(@AncestorInPath AbstractProject project, @QueryParameter String value) { - return Jenkins.get().doCheckDisplayName(value, project.getName()); - } - @Restricted(DoNotUse.class) public FormValidation doCheckAssignedLabelString(@AncestorInPath AbstractProject project, @QueryParameter String value) { diff --git a/core/src/main/java/hudson/model/TopLevelItemDescriptor.java b/core/src/main/java/hudson/model/TopLevelItemDescriptor.java index d2ebe3065349..d84e4a684f22 100644 --- a/core/src/main/java/hudson/model/TopLevelItemDescriptor.java +++ b/core/src/main/java/hudson/model/TopLevelItemDescriptor.java @@ -27,6 +27,7 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionList; +import hudson.util.FormValidation; import java.io.StringWriter; import java.util.logging.Level; import java.util.logging.Logger; @@ -37,7 +38,11 @@ import org.jenkins.ui.icon.Icon; import org.jenkins.ui.icon.IconSet; import org.jenkins.ui.icon.IconSpec; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.MetaClass; +import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.WebApp; @@ -286,4 +291,8 @@ public static ExtensionList all() { return Items.all(); } + @Restricted(NoExternalUse.class) + public FormValidation doCheckDisplayNameOrNull(@AncestorInPath TopLevelItem item, @QueryParameter String value) { + return Jenkins.get().doCheckDisplayName(value, item.getName()); + } } From fc73c2622ab6a72ea0b1612a22db22f36d5eca0f Mon Sep 17 00:00:00 2001 From: Markus Winter Date: Fri, 30 Aug 2024 15:26:10 +0200 Subject: [PATCH 10/12] =?UTF-8?q?[JENKINS-73669]=20don't=20change=20unrela?= =?UTF-8?q?ted=20checkboxes=20in=20rowSelectionCont=E2=80=A6=20(#9648)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/main/resources/hudson/PluginManager/updates.jelly | 4 ++-- .../main/resources/lib/layout/rowSelectionController.jelly | 6 +++++- .../main/js/components/row-selection-controller/index.js | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/core/src/main/resources/hudson/PluginManager/updates.jelly b/core/src/main/resources/hudson/PluginManager/updates.jelly index 2dd759d883cd..da79d1958cf9 100644 --- a/core/src/main/resources/hudson/PluginManager/updates.jelly +++ b/core/src/main/resources/hudson/PluginManager/updates.jelly @@ -69,7 +69,7 @@ THE SOFTWARE. - + diff --git a/war/src/main/js/components/row-selection-controller/index.js b/war/src/main/js/components/row-selection-controller/index.js index d4de91b89de4..31fa374ee2c3 100644 --- a/war/src/main/js/components/row-selection-controller/index.js +++ b/war/src/main/js/components/row-selection-controller/index.js @@ -4,7 +4,10 @@ const rowSelectionControllers = document.querySelectorAll( rowSelectionControllers.forEach((headerCheckbox) => { const table = headerCheckbox.closest(".jenkins-table"); - const tableCheckboxes = table.querySelectorAll("input[type='checkbox']"); + const checkboxClass = headerCheckbox.dataset.checkboxClass; + const tableCheckboxes = table.querySelectorAll( + `input[type='checkbox'].${checkboxClass}`, + ); const moreOptionsButton = table.querySelector( ".jenkins-table__checkbox-options", ); From 15e045f03d652a7e76dc3d68e071119c86fdba6a Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 30 Aug 2024 09:26:19 -0400 Subject: [PATCH 11/12] Friendlier handling of `DeploymentHandshakeException` from CLI in `-webSocket` mode (#9591) --- cli/src/main/java/hudson/cli/CLI.java | 24 ++++++++++++++++++- .../test/java/hudson/cli/CLIActionTest.java | 17 +++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/cli/src/main/java/hudson/cli/CLI.java b/cli/src/main/java/hudson/cli/CLI.java index 684b01f54981..910331b3ee9a 100644 --- a/cli/src/main/java/hudson/cli/CLI.java +++ b/cli/src/main/java/hudson/cli/CLI.java @@ -32,6 +32,7 @@ import jakarta.websocket.ClientEndpointConfig; import jakarta.websocket.Endpoint; import jakarta.websocket.EndpointConfig; +import jakarta.websocket.HandshakeResponse; import jakarta.websocket.Session; import java.io.DataInputStream; import java.io.File; @@ -64,6 +65,7 @@ import org.glassfish.tyrus.client.ClientManager; import org.glassfish.tyrus.client.ClientProperties; import org.glassfish.tyrus.client.SslEngineConfigurator; +import org.glassfish.tyrus.client.exception.DeploymentHandshakeException; import org.glassfish.tyrus.container.jdk.client.JdkClientContainer; /** @@ -340,13 +342,19 @@ public void onOpen(Session session, EndpointConfig config) {} } class Authenticator extends ClientEndpointConfig.Configurator { + HandshakeResponse hr; @Override public void beforeRequest(Map> headers) { if (factory.authorization != null) { headers.put("Authorization", List.of(factory.authorization)); } } + @Override + public void afterResponse(HandshakeResponse hr) { + this.hr = hr; + } } + var authenticator = new Authenticator(); ClientManager client = ClientManager.createClient(JdkClientContainer.class.getName()); // ~ ContainerProvider.getWebSocketContainer() client.getProperties().put(ClientProperties.REDIRECT_ENABLED, true); // https://tyrus-project.github.io/documentation/1.13.1/index/tyrus-proprietary-config.html#d0e1775 @@ -357,7 +365,21 @@ public void beforeRequest(Map> headers) { sslEngineConfigurator.setHostnameVerifier((s, sslSession) -> true); client.getProperties().put(ClientProperties.SSL_ENGINE_CONFIGURATOR, sslEngineConfigurator); } - Session session = client.connectToServer(new CLIEndpoint(), ClientEndpointConfig.Builder.create().configurator(new Authenticator()).build(), URI.create(url.replaceFirst("^http", "ws") + "cli/ws")); + Session session; + try { + session = client.connectToServer(new CLIEndpoint(), ClientEndpointConfig.Builder.create().configurator(authenticator).build(), URI.create(url.replaceFirst("^http", "ws") + "cli/ws")); + } catch (DeploymentHandshakeException x) { + System.err.println("CLI handshake failed with status code " + x.getHttpStatusCode()); + if (authenticator.hr != null) { + for (var entry : authenticator.hr.getHeaders().entrySet()) { + // org.glassfish.tyrus.core.Utils.parseHeaderValue improperly splits values like Date at commas, so undo that: + System.err.println(entry.getKey() + ": " + String.join(", ", entry.getValue())); + } + // UpgradeResponse.getReasonPhrase is useless since Jetty generates it from the code, + // and the body is not accessible at all. + } + return 15; // compare CLICommand.main + } PlainCLIProtocol.Output out = new PlainCLIProtocol.Output() { @Override public void send(byte[] data) throws IOException { diff --git a/test/src/test/java/hudson/cli/CLIActionTest.java b/test/src/test/java/hudson/cli/CLIActionTest.java index 57086142bfb9..dab7ec8a88ad 100644 --- a/test/src/test/java/hudson/cli/CLIActionTest.java +++ b/test/src/test/java/hudson/cli/CLIActionTest.java @@ -1,5 +1,9 @@ package hudson.cli; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import hudson.Functions; @@ -131,6 +135,19 @@ private void assertExitCode(int code, boolean useApiToken, File jar, String... a assertEquals(code, proc.join()); } + @Test public void authenticationFailed() throws Exception { + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); + j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy().grant(Jenkins.ADMINISTER).everywhere().toAuthenticated()); + var jar = tmp.newFile("jenkins-cli.jar"); + FileUtils.copyURLToFile(j.jenkins.getJnlpJars("jenkins-cli.jar").getURL(), jar); + var baos = new ByteArrayOutputStream(); + var exitStatus = new Launcher.LocalLauncher(StreamTaskListener.fromStderr()).launch().cmds( + "java", "-jar", jar.getAbsolutePath(), "-s", j.getURL().toString(), "-auth", "user:bogustoken", "who-am-i" + ).stdout(baos).start().join(); + assertThat(baos.toString(), allOf(containsString("status code 401"), containsString("Server: Jetty"))); + assertThat(exitStatus, is(15)); + } + @Issue("JENKINS-41745") @Test public void encodingAndLocale() throws Exception { From 5fe9a448059c5aafd2fa354cdabb12e05b3978e2 Mon Sep 17 00:00:00 2001 From: Allan Burdajewicz Date: Fri, 30 Aug 2024 23:26:27 +1000 Subject: [PATCH 12/12] [JENKINS-73422] Add escape hatch for Authenticated user access to Resource URL (#9644) Co-authored-by: Daniel Beck <1831569+daniel-beck@users.noreply.github.com> --- .../jenkins/security/ResourceDomainRootAction.java | 6 +++++- .../test/java/jenkins/security/ResourceDomainTest.java | 10 +++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/jenkins/security/ResourceDomainRootAction.java b/core/src/main/java/jenkins/security/ResourceDomainRootAction.java index 7955103d6be5..fc18071fade7 100644 --- a/core/src/main/java/jenkins/security/ResourceDomainRootAction.java +++ b/core/src/main/java/jenkins/security/ResourceDomainRootAction.java @@ -117,7 +117,7 @@ public Object getDynamic(String id, StaplerRequest req, StaplerResponse rsp) thr return null; } - if (!ACL.isAnonymous2(Jenkins.getAuthentication2())) { + if (!ALLOW_AUTHENTICATED_USER && !ACL.isAnonymous2(Jenkins.getAuthentication2())) { rsp.sendError(400); return null; } @@ -327,4 +327,8 @@ private static Token decode(String value) { // Not @Restricted because the entire class is @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") public static /* not final for Groovy */ int VALID_FOR_MINUTES = SystemProperties.getInteger(ResourceDomainRootAction.class.getName() + ".validForMinutes", 30); + + /* Escape hatch for a security hardening preventing one of the known ways to elevate arbitrary file read to RCE */ + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* not final for Groovy */ boolean ALLOW_AUTHENTICATED_USER = SystemProperties.getBoolean(ResourceDomainRootAction.class.getName() + ".allowAuthenticatedUser", false); } diff --git a/test/src/test/java/jenkins/security/ResourceDomainTest.java b/test/src/test/java/jenkins/security/ResourceDomainTest.java index 42f2a1dbbf78..b8f2d551b094 100644 --- a/test/src/test/java/jenkins/security/ResourceDomainTest.java +++ b/test/src/test/java/jenkins/security/ResourceDomainTest.java @@ -399,7 +399,7 @@ public HttpResponse doDynamic() throws Exception { } @Test - public void authenticatedCannotAccessResourceDomain() throws Exception { + public void authenticatedCannotAccessResourceDomainUnlessAllowedBySystemProperty() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); final MockAuthorizationStrategy authorizationStrategy = new MockAuthorizationStrategy(); authorizationStrategy.grant(Jenkins.ADMINISTER).everywhere().to("admin").grant(Jenkins.READ).everywhere().toEveryone(); @@ -416,5 +416,13 @@ public void authenticatedCannotAccessResourceDomain() throws Exception { try (JenkinsRule.WebClient wc = j.createWebClient().withBasicCredentials("admin")) { assertThat(assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(new URL(resourceUrl))).getStatusCode(), is(400)); } + + ResourceDomainRootAction.ALLOW_AUTHENTICATED_USER = true; + try (JenkinsRule.WebClient wc = j.createWebClient().withBasicApiToken("admin")) { + assertThat(wc.getPage(new URL(resourceUrl)).getWebResponse().getStatusCode(), is(200)); + } + try (JenkinsRule.WebClient wc = j.createWebClient().withBasicCredentials("admin")) { + assertThat(wc.getPage(new URL(resourceUrl)).getWebResponse().getStatusCode(), is(200)); + } } }