diff --git a/pom.xml b/pom.xml index d4839447e..9316d37fd 100644 --- a/pom.xml +++ b/pom.xml @@ -169,6 +169,9 @@ + + 1344 + org.antlr diff --git a/src/main/java/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl.java b/src/main/java/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl.java index 3b938c7c4..079249fd1 100644 --- a/src/main/java/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl.java +++ b/src/main/java/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl.java @@ -37,14 +37,10 @@ import hudson.util.FormValidation; import hudson.util.Secret; import java.io.ByteArrayInputStream; -import java.io.File; import java.io.IOException; import java.io.ObjectStreamException; import java.io.Serializable; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.InvalidPathException; -import java.nio.file.Paths; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -58,7 +54,6 @@ import java.util.logging.LogRecord; import java.util.logging.Logger; -import jenkins.model.Jenkins; import net.jcip.annotations.GuardedBy; import org.apache.commons.fileupload.FileItem; import org.apache.commons.lang.StringUtils; @@ -337,72 +332,6 @@ protected static FormValidation validateCertificateKeystore(String type, byte[] } } - /** - * Let the user reference a file on the disk. - * @deprecated This approach has security vulnerabilities and should be migrated to {@link UploadedKeyStoreSource} - */ - @Deprecated - public static class FileOnMasterKeyStoreSource extends KeyStoreSource { - - /** - * Our logger. - */ - private static final Logger LOGGER = Logger.getLogger(FileOnMasterKeyStoreSource.class.getName()); - - /** - * The path of the file on the controller. - */ - private final String keyStoreFile; - - public FileOnMasterKeyStoreSource(String keyStoreFile) { - this.keyStoreFile = keyStoreFile; - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public byte[] getKeyStoreBytes() { - try { - return Files.readAllBytes(Paths.get(keyStoreFile)); - } catch (IOException | InvalidPathException e) { - LOGGER.log(Level.WARNING, "Could not read private key file " + keyStoreFile, e); - return new byte[0]; - } - } - - /** - * {@inheritDoc} - */ - @Override - public long getKeyStoreLastModified() { - return new File(keyStoreFile).lastModified(); - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return "FileOnMasterKeyStoreSource{" + - "keyStoreFile='" + keyStoreFile + '\'' + - "}"; - } - - private Object readResolve() { - if (!Jenkins.get().hasPermission(Jenkins.RUN_SCRIPTS)) { - LOGGER.warning("SECURITY-1322: Permission failure migrating FileOnMasterKeyStoreSource to UploadedKeyStoreSource for a Certificate. An administrator may need to perform the migration."); - Jenkins.get().checkPermission(Jenkins.RUN_SCRIPTS); - } - - LOGGER.log(Level.INFO, "SECURITY-1322: Migrating FileOnMasterKeyStoreSource to UploadedKeyStoreSource. The containing item may need to be saved to complete the migration."); - SecretBytes secretBytes = SecretBytes.fromBytes(getKeyStoreBytes()); - return new UploadedKeyStoreSource(secretBytes); - } - - } - /** * Let the user reference an uploaded file. */ diff --git a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config.jelly b/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config.jelly deleted file mode 100644 index da5225be3..000000000 --- a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config.jelly +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - diff --git a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_de.properties b/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_de.properties deleted file mode 100644 index 95deddfc5..000000000 --- a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_de.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright 2013 Harald Albers -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -File=Datei diff --git a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_fr.properties b/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_fr.properties deleted file mode 100644 index 447e3dd3c..000000000 --- a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_fr.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2014, Damien Finck -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -File=Fichier diff --git a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_it.properties b/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_it.properties deleted file mode 100644 index c18289128..000000000 --- a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_it.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright 2020 Alessandro Menti -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -File=File diff --git a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_ja.properties b/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_ja.properties deleted file mode 100644 index 2cb913591..000000000 --- a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/config_ja.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright 2013 Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -File=\u30d5\u30a1\u30a4\u30eb \ No newline at end of file diff --git a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile.html b/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile.html deleted file mode 100644 index f9e84ff6b..000000000 --- a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile.html +++ /dev/null @@ -1,27 +0,0 @@ - - -
- The path to the file on the Jenkins controller. -
diff --git a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile_fr.html b/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile_fr.html deleted file mode 100644 index 7f11398b4..000000000 --- a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile_fr.html +++ /dev/null @@ -1,27 +0,0 @@ - - -
- Le chemin vers le fichier sur le nœud maître Jenkins. -
\ No newline at end of file diff --git a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile_it.html b/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile_it.html deleted file mode 100644 index 2a9e4bdda..000000000 --- a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile_it.html +++ /dev/null @@ -1,3 +0,0 @@ -
- Il percorso al file sul nodo master di Jenkins. -
diff --git a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile_ja.html b/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile_ja.html deleted file mode 100644 index 410fe8c66..000000000 --- a/src/main/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImpl/FileOnMasterKeyStoreSource/help-keyStoreFile_ja.html +++ /dev/null @@ -1,27 +0,0 @@ - - -
- Jenkinsのマスターノード上でのファイルのパスです。 -
\ No newline at end of file diff --git a/src/test/java/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImplTest.java b/src/test/java/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImplTest.java index 246228d64..2e8c02f0e 100644 --- a/src/test/java/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImplTest.java +++ b/src/test/java/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImplTest.java @@ -113,101 +113,6 @@ public void displayName() throws IOException { assertEquals(EXPECTED_DISPLAY_NAME, CredentialsNameProvider.name(new CertificateCredentialsImpl(null, "abc123", null, "password", storeSource))); } - @Test - @Issue("SECURITY-1322") - public void verifySystemMasterSourceConvertedToUploadedSource() throws Exception { - CertificateCredentialsImpl.FileOnMasterKeyStoreSource storeSource = new CertificateCredentialsImpl.FileOnMasterKeyStoreSource(p12.getAbsolutePath()); - CertificateCredentialsImpl credentials = new CertificateCredentialsImpl(null, "abc123", null, "password", storeSource); - SystemCredentialsProvider.getInstance().getCredentials().add(credentials); - SystemCredentialsProvider.getInstance().save(); - SystemCredentialsProvider provider = new SystemCredentialsProvider(); - Credentials reloadedCredentials = provider.getCredentials().get(0); - assertThat(reloadedCredentials, instanceOf(CertificateCredentials.class)); - CertificateCredentialsImpl.KeyStoreSource reloadedSource = ((CertificateCredentialsImpl) reloadedCredentials).getKeyStoreSource(); - assertThat(reloadedSource, instanceOf(CertificateCredentialsImpl.UploadedKeyStoreSource.class)); - provider.save(); - FilePath credentialsXml = r.getInstance().getRootPath().child("credentials.xml"); - String fileContents = credentialsXml.readToString(); - assertThat(fileContents, not(containsString("Master"))); - } - - @Test - @Issue("SECURITY-1322") - public void verifyGlobalMasterSourceConvertedToUploadedSource() throws Exception { - Folder folder = r.jenkins.createProject(Folder.class, "folder1"); - CertificateCredentialsImpl.FileOnMasterKeyStoreSource storeSource = new CertificateCredentialsImpl.FileOnMasterKeyStoreSource(p12.getAbsolutePath()); - CertificateCredentialsImpl credentials = new CertificateCredentialsImpl(null, "abc123", null, "password", storeSource); - CredentialsStore folderStore = getFolderStore(folder); - Domain domain = new Domain("test", "test", Collections.emptyList()); - folderStore.addDomain(domain, credentials); - folderStore.save(); - folder.doReload(); - CredentialsStore reloadedStore = getFolderStore(folder); - List reloadedCredentialsList = reloadedStore.getCredentials(domain); - assertThat(reloadedCredentialsList, hasSize(1)); - Credentials reloadedCredentials = reloadedCredentialsList.get(0); - CertificateCredentialsImpl.KeyStoreSource reloadedSource = ((CertificateCredentialsImpl) reloadedCredentials).getKeyStoreSource(); - assertThat(reloadedSource, instanceOf(CertificateCredentialsImpl.UploadedKeyStoreSource.class)); - reloadedStore.save(); - String configFileContent = folder.getConfigFile().asString(); - assertThat(configFileContent, not(containsString("Master"))); - } - - @Test - @Issue("SECURITY-1322") - @LocalData("updateFolder") - public void verifyUserWithoutRunScriptsCannotUploadMasterKeySource() throws Exception { - Folder folder = r.jenkins.createProject(Folder.class, "folder1"); - - FilePath updateFolder = r.jenkins.getRootPath().child("updateFolder.xml"); - CLICommandInvoker.Result result = new CLICommandInvoker(r, new UpdateJobCommand()) - .authorizedTo(Jenkins.READ, Job.READ, Job.CONFIGURE) - .withStdin(updateFolder.read()) - .invokeWithArgs("folder1"); - - assertThat(result.stderr(), containsString("user is missing the Overall/RunScripts permission")); - // 1 = means An error occurred, according to https://github.com/jenkinsci/jenkins/pull/1997/files#diff-4459859ade69b51edffdb58020f5d3f7R217 - assertThat(result, failedWith(1)); - - String configFileContent = folder.getConfigFile().asString(); - assertThat(configFileContent, not(containsString("Master"))); - } - - @Test - @Issue("SECURITY-1322") - @LocalData("updateFolder") - public void verifyUserWithRunScriptsCanUploadMasterKeySource() throws Exception { - Folder folder = r.jenkins.createProject(Folder.class, "folder1"); - - FilePath updateFolder = r.jenkins.getRootPath().child("updateFolder.xml"); - CLICommandInvoker.Result result = new CLICommandInvoker(r, new UpdateJobCommand()) - .authorizedTo(Jenkins.ADMINISTER) - .withStdin(updateFolder.read()) - .invokeWithArgs("folder1"); - - assertThat(result, succeeded()); - - Domain domain = new Domain("test", "test", Collections.emptyList()); - - // check the data is correctly updated in memory - CredentialsStore folderStore = getFolderStore(folder); - List credentialsList = folderStore.getCredentials(domain); - assertThat(credentialsList, hasSize(1)); - Credentials credentials = credentialsList.get(0); - CertificateCredentialsImpl.KeyStoreSource source = ((CertificateCredentialsImpl) credentials).getKeyStoreSource(); - assertThat(source, instanceOf(CertificateCredentialsImpl.UploadedKeyStoreSource.class)); - - folder.doReload(); - - // as well as after a reload - CredentialsStore reloadedFolderStore = getFolderStore(folder); - List reloadedCredentialsList = reloadedFolderStore.getCredentials(domain); - assertThat(reloadedCredentialsList, hasSize(1)); - Credentials reloadedCredentials = reloadedCredentialsList.get(0); - CertificateCredentialsImpl.KeyStoreSource reloadedSource = ((CertificateCredentialsImpl) reloadedCredentials).getKeyStoreSource(); - assertThat(reloadedSource, instanceOf(CertificateCredentialsImpl.UploadedKeyStoreSource.class)); - } - @Test @Issue("JENKINS-64542") public void doCheckUploadedKeystore_uploadedFileValid() throws Exception { diff --git a/src/test/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImplTest/updateFolder.xml b/src/test/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImplTest/updateFolder.xml deleted file mode 100644 index a8f0e5050..000000000 --- a/src/test/resources/com/cloudbees/plugins/credentials/impl/CertificateCredentialsImplTest/updateFolder.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - test - test - - - - - abc123 - - - /var/folders/1_/75tlch4x6297hbn2f2xl41hw0000gn/T/junit1296816016832319162/test.p12 - - Q+y6JDkS3krlY0cRvZ54ahQPQDOCauzcZ/W0Aw0eT5g= - - - - - - - - - - - All - false - false - - - - - - - - false - - - - \ No newline at end of file