-
Notifications
You must be signed in to change notification settings - Fork 748
Expand file tree
/
Copy pathSSHCredentialsTest.java
More file actions
132 lines (115 loc) · 6.31 KB
/
SSHCredentialsTest.java
File metadata and controls
132 lines (115 loc) · 6.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package io.jenkins.plugins.casc;
import static io.jenkins.plugins.casc.misc.Util.assertNotInLog;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey;
import com.cloudbees.plugins.credentials.Credentials;
import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
import io.jenkins.plugins.casc.misc.ConfiguredWithCode;
import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule;
import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import jenkins.model.Jenkins;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.LogRecorder;
import org.jvnet.hudson.test.TestExtension;
/**
* Integration tests for the SSH Credentials Plugin.
*/
@WithJenkinsConfiguredWithCode
class SSHCredentialsTest {
private final LogRecorder logging = new LogRecorder()
.record("io.jenkins.plugins.casc.Attribute", Level.INFO)
.capture(2048);
private static final String CREDENTIALS_PASSWORD = "password-of-userid";
private static final String PRIVATE_KEY = "sp0ds9d+skkfjf";
@Test
@ConfiguredWithCode("SSHCredentialsTest.yml")
@Issue("SECURITY-1279")
void shouldNotExportOrLogCredentials(JenkinsConfiguredWithCodeRule j) throws Exception {
StandardUsernamePasswordCredentials creds = getCredentials(StandardUsernamePasswordCredentials.class);
assertEquals(CREDENTIALS_PASSWORD, creds.getPassword().getPlainText());
assertNotInLog(logging, CREDENTIALS_PASSWORD);
BasicSSHUserPrivateKey certKey = getCredentials(BasicSSHUserPrivateKey.class);
// JENKINS-50181 made getPrivateKey always append a trailing newline.
assertEquals(PRIVATE_KEY + "\n", certKey.getPrivateKey());
assertNotInLog(logging, PRIVATE_KEY);
// Verify that the password does not get exported
String exportedConfig = j.exportToString(false);
assertThat(
"There should be no password in the exported YAML",
exportedConfig,
not(containsString(CREDENTIALS_PASSWORD)));
assertThat(
"There should be no private key in the exported YAML",
exportedConfig,
not(containsString(PRIVATE_KEY)));
}
@Test
@ConfiguredWithCode("SSHCredentialsTest_Multiline_Key.yml")
@Issue("https://github.com/jenkinsci/configuration-as-code-plugin/issues/1189")
void shouldSupportMultilineCertificates(JenkinsConfiguredWithCodeRule j) {
BasicSSHUserPrivateKey certKey = getCredentials(BasicSSHUserPrivateKey.class);
assertThat(
"Private key roundtrip failed",
certKey.getPrivateKey().trim(),
equalTo(MySSHKeySecretSource.PRIVATE_SSH_KEY.trim()));
}
@Test
@ConfiguredWithCode("SSHCredentialsTest_Singleline_Key.yml")
@Issue("https://github.com/jenkinsci/configuration-as-code-plugin/issues/1189")
void shouldSupportSinglelineBase64Certificates(JenkinsConfiguredWithCodeRule j) {
BasicSSHUserPrivateKey certKey = getCredentials(BasicSSHUserPrivateKey.class);
assertThat(
"Private key roundtrip failed",
certKey.getPrivateKey().trim().replace("\r\n", "\n"),
equalTo(MySSHKeySecretSource.PRIVATE_SSH_KEY));
}
private <T extends Credentials> T getCredentials(Class<T> clazz) {
List<T> creds = CredentialsProvider.lookupCredentials(
clazz, Jenkins.getInstanceOrNull(), null, Collections.emptyList());
assertEquals(1, creds.size(), "There should be only one credential");
return creds.get(0);
}
@TestExtension
public static class MySSHKeySecretSource extends SecretSource {
private static final String PRIVATE_SSH_KEY = "-----BEGIN OPENSSH PRIVATE KEY-----\n"
+ "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\n"
+ "QyNTUxOQAAACCYdvz4LdHg0G5KFS8PlauuOwVBms6Y70FaL4JY1YVahgAAAKCjJ1l+oydZ\n"
+ "fgAAAAtzc2gtZWQyNTUxOQAAACCYdvz4LdHg0G5KFS8PlauuOwVBms6Y70FaL4JY1YVahg\n"
+ "AAAEBWrtFZGX1yOg1/esgm34TPE5Zw8EXQ1OuxcgYGIaRRVph2/Pgt0eDQbkoVLw+Vq647\n"
+ "BUGazpjvQVovgljVhVqGAAAAGW9uZW5hc2hldkBMQVBUT1AtMjVLNjVMT1MBAgME\n"
+ "-----END OPENSSH PRIVATE KEY-----";
// encoded with "base64 -w 0"
private static final String PRIVATE_SSH_KEY_BASE64 =
"LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0NCmIzQmxibk56YUMxclpYa3RkakVBQUFBQUJHNXZibVVBQUFBRWJtOXVaUUFBQUFBQUFBQUJBQUFBTXdBQUFBdHpjMmd0WlcNClF5TlRVeE9RQUFBQ0NZZHZ6NExkSGcwRzVLRlM4UGxhdXVPd1ZCbXM2WTcwRmFMNEpZMVlWYWhnQUFBS0NqSjFsK295ZFoNCmZnQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDQ1lkdno0TGRIZzBHNUtGUzhQbGF1dU93VkJtczZZNzBGYUw0SlkxWVZhaGcNCkFBQUVCV3J0RlpHWDF5T2cxL2VzZ20zNFRQRTVadzhFWFExT3V4Y2dZR0lhUlJWcGgyL1BndDBlRFFia29WTHcrVnE2NDcNCkJVR2F6cGp2UVZvdmdsalZoVnFHQUFBQUdXOXVaVzVoYzJobGRrQk1RVkJVVDFBdE1qVkxOalZNVDFNQkFnTUUNCi0tLS0tRU5EIE9QRU5TU0ggUFJJVkFURSBLRVktLS0tLQ0K";
@Override
public Optional<String> reveal(String secret) {
if (secret.equals("MY_PRIVATE_KEY")) {
return Optional.of(PRIVATE_SSH_KEY);
}
if (secret.equals("SSH_AGENT_PRIVATE_KEY_BASE64")) {
return Optional.of(PRIVATE_SSH_KEY_BASE64);
}
return Optional.empty();
}
}
@Test
@ConfiguredWithCode("SSHCredentialsTest_Recursive_Key.yml")
@Issue("https://github.com/jenkinsci/configuration-as-code-plugin/issues/2488")
void shouldSupportRecursiveBase64Certificates(JenkinsConfiguredWithCodeRule j) {
BasicSSHUserPrivateKey certKey = getCredentials(BasicSSHUserPrivateKey.class);
assertThat(
"Private key roundtrip failed",
certKey.getPrivateKeys().get(0).trim().replace("\r\n", "\n"),
equalTo(MySSHKeySecretSource.PRIVATE_SSH_KEY));
}
}