Skip to content

Commit

Permalink
[JENKINS-73408] bom update to bom-2.426.x in order to align with core…
Browse files Browse the repository at this point in the history
… requirement (#211)

* updated bom and excluded eddsa-api
* updated test to use RealJenkinsRule with omit plugins
* moving js back to adjunct
* Using class name instead of ids
  • Loading branch information
PereBueno authored Jul 25, 2024
1 parent f31377f commit e5af1db
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 29 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@
<dependencies>
<dependency>
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-2.387.x</artifactId>
<version>2543.vfb_1a_5fb_9496d</version>
<artifactId>bom-2.426.x</artifactId>
<version>3208.vb_21177d4b_cd9</version>
<scope>import</scope>
<type>pom</type>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
<f:entry title="${%Key}" field="privateKey">
<f:secretTextarea checkMethod="post" id="${keyId}"/>
<f:secretTextarea checkMethod="post" class="sshCredentials_privateKey"/>
</f:entry>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,7 @@
<f:hetero-radio field="privateKeySource" descriptors="${descriptor.privateKeySources}"/>
</f:entry>
<f:entry title="${%Passphrase}" field="passphrase">
<f:password id="${passId}"/>
<f:password clazz="sshCredentials_passphrase"/>
</f:entry>
<script><![CDATA[
//TODO: this snippet, as well as ids in passphrase and private key fields can be removed once https://issues.jenkins.io/browse/JENKINS-65616 is completed
var passphraseElement = document.getElementById('${passId}');
var privateKeyElement = document.getElementById('${keyId}');
passphraseElement.addEventListener("change", event => {
var newEvent = new Event("change")
privateKeyElement.dispatchEvent(newEvent)
})
]]>
</script>
</j:jelly>
<st:adjunct includes="com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey.passphraseChangeEvent" />
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//TODO: this snippet, as well as ids in passphrase and private key fields can be removed once https://issues.jenkins.io/browse/JENKINS-65616 is completed
const passphraseElements = document.getElementsByClassName('sshCredentials_passphrase');

if (passphraseElements.length > 0) {
// Failsafe in case there's more than 1 element we'll only use the first one. Should not happen.
passphraseElements[0].addEventListener("change", event => {
var newEvent = new Event("change")
const privateKeyElements = document.getElementsByClassName('sshCredentials_privateKey');
if (passphraseElements.length > 0) {
privateKeyElements[0].dispatchEvent(newEvent)
}
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@
import hudson.ExtensionList;
import hudson.security.ACL;
import hudson.util.FormValidation;
import jenkins.security.FIPS140;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.FlagRule;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.RealJenkinsRule;
import org.jvnet.hudson.test.recipes.LocalData;

import java.io.IOException;
Expand All @@ -29,14 +27,16 @@

public class BasicSSHUserPrivateKeyFIPSTest {

@ClassRule
public static FlagRule<String> fipsFlag = FlagRule.systemProperty(FIPS140.class.getName() + ".COMPLIANCE", "true");

@Rule public JenkinsRule r = new JenkinsRule();
@Rule public RealJenkinsRule rule = new RealJenkinsRule().omitPlugins("eddsa-api", "trilead-api")
.javaOptions("-Djenkins.security.FIPS140.COMPLIANCE=true");

@Test
@Issue("JENKINS-73408")
public void nonCompliantKeysLaunchExceptionTest() throws IOException {
public void nonCompliantKeysLaunchExceptionTest() throws Throwable {
rule.then(BasicSSHUserPrivateKeyFIPSTest::checkNonCompliantKeysLaunchException);
}

private static void checkNonCompliantKeysLaunchException(JenkinsRule r) throws IOException{
new BasicSSHUserPrivateKey(CredentialsScope.GLOBAL, "no-key", "user",
null, null, "no key provided doesn't throw exceptions");
assertThrows(IllegalArgumentException.class, () -> new BasicSSHUserPrivateKey(CredentialsScope.GLOBAL, "nopass-openssh-ed25519", "user",
Expand All @@ -63,7 +63,11 @@ public void nonCompliantKeysLaunchExceptionTest() throws IOException {

@Test
@Issue("JENKINS-73408")
public void invalidKeyIsNotSavedInFIPSModeTest() throws IOException {
public void invalidKeyIsNotSavedInFIPSModeTest() throws Throwable {
rule.then(BasicSSHUserPrivateKeyFIPSTest::checkInvalidKeyIsNotSavedInFIPSMode);
}

private static void checkInvalidKeyIsNotSavedInFIPSMode(JenkinsRule r) throws IOException {
BasicSSHUserPrivateKey entry = new BasicSSHUserPrivateKey(CredentialsScope.GLOBAL, "rsa2048", "user", getKey("rsa2048"), "fipsvalidpassword", "RSA 1024 accepted key");
Iterator<CredentialsStore> stores = CredentialsProvider.lookupStores(r.jenkins).iterator();
assertTrue(stores.hasNext());
Expand All @@ -84,11 +88,14 @@ public void invalidKeyIsNotSavedInFIPSModeTest() throws IOException {
CredentialsMatchers.withId("rsa1024"));
assertNull(cred);
}

@Test
@LocalData
@Issue("JENKINS-73408")
public void invalidKeysAreRemovedOnStartupTest() {
public void invalidKeysAreRemovedOnStartupTest() throws Throwable {
rule.then(BasicSSHUserPrivateKeyFIPSTest::checkInvalidKeysAreRemovedOnStartup);
}

private static void checkInvalidKeysAreRemovedOnStartup(JenkinsRule r) {
SSHUserPrivateKey cred = CredentialsMatchers.firstOrNull(
CredentialsProvider.lookupCredentialsInItem(SSHUserPrivateKey.class, null, ACL.SYSTEM2),
CredentialsMatchers.withId("valid-rsa-key"));
Expand All @@ -101,15 +108,19 @@ public void invalidKeysAreRemovedOnStartupTest() {

@Test
@Issue("JENKINS-73408")
public void formValidationTest() throws IOException {
public void formValidationTest() throws Throwable {
rule.then(BasicSSHUserPrivateKeyFIPSTest::checkFormValidation);
}

private static void checkFormValidation(JenkinsRule r) throws IOException {
BasicSSHUserPrivateKey.DirectEntryPrivateKeySource.DescriptorImpl descriptor = ExtensionList.lookupSingleton(BasicSSHUserPrivateKey.DirectEntryPrivateKeySource.DescriptorImpl.class);
FormValidation result = descriptor.doCheckPrivateKey(getKey("rsa2048").getPrivateKey().getPlainText(), "fipsvalidpassword");
assertTrue(StringUtils.isBlank(result.getMessage()));
result = descriptor.doCheckPrivateKey(getKey("rsa1024").getPrivateKey().getPlainText(), "fipsvalidpassword");
assertTrue(StringUtils.isNotBlank(result.getMessage()));
}

private BasicSSHUserPrivateKey.DirectEntryPrivateKeySource getKey(String file) throws IOException {
private static BasicSSHUserPrivateKey.DirectEntryPrivateKeySource getKey(String file) throws IOException {
String keyText = FileUtils.readFileToString(Paths.get("src/test/resources/com/cloudbees/jenkins/plugins/sshcredentials/impl/BasicSSHUserPrivateKeyFIPSTest/nonCompliantKeysLaunchExceptionTest").resolve(file).toFile(), Charset.defaultCharset());
return new BasicSSHUserPrivateKey.DirectEntryPrivateKeySource(keyText);
}
Expand Down

0 comments on commit e5af1db

Please sign in to comment.