Skip to content
Permalink
Browse files

[JENKINS-42393] Temporary files should not be created in the bundles …

…root directory under JENKINS_HOME (#106)

[JENKINS-42393] Temporary files should not be created in the bundles root directory under JENKINS_HOME
  • Loading branch information...
batmat committed Mar 1, 2017
1 parent f819d77 commit 8850b77432ac654620ed5dcc1b345ec97711d068
@@ -25,7 +25,7 @@
package com.cloudbees.jenkins.support.api;

import com.cloudbees.jenkins.support.SupportLogFormatter;
import hudson.util.IOUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
@@ -44,7 +44,7 @@
*/
public class FileContent extends Content {

private final File file;
protected final File file;
private final long maxSize;

public FileContent(String name, File file) {
@@ -60,10 +60,10 @@ public FileContent(String name, File file, long maxSize) {
@Override
public void writeTo(OutputStream os) throws IOException {
try {
InputStream is = getInputStream();
if (maxSize == -1) {
IOUtils.copy(file, os);
IOUtils.copy(is, os);
} else {
InputStream is = new FileInputStream(file);
try {
IOUtils.copy(new TruncatedInputStream(is, maxSize), os);
} finally {
@@ -87,6 +87,15 @@ public void writeTo(OutputStream os) throws IOException {
}
}

/**
* Instantiates the {@link InputStream} for the {@link #file}.
* @return the {@link InputStream} for the {@link #file}.
* @throws IOException if something goes wrong while creating the stream for reading #file.
*/
protected InputStream getInputStream() throws IOException {
return new FileInputStream(file);
}

@Override
public long getTime() throws IOException {
return file.lastModified();
@@ -25,21 +25,15 @@

import com.cloudbees.jenkins.support.api.Component;
import com.cloudbees.jenkins.support.api.Container;
import com.cloudbees.jenkins.support.api.TemporaryFileContent;
import com.cloudbees.jenkins.support.util.Helper;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.security.Permission;
import jenkins.model.Jenkins;
import org.xml.sax.SAXException;

import javax.xml.transform.TransformerException;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

/**
@@ -76,15 +70,7 @@ public void addContents(@NonNull Container container) {
}
for(File agentDir : agentDirs) {
File config = new File(agentDir, "config.xml");
try {
File patchedConfig = SecretHandler.findSecrets(config);
container.add(new TemporaryFileContent("nodes/slave/" + agentDir.getName() + "/config.xml", patchedConfig));
} catch (IOException | SAXException | TransformerException e) {
LogRecord record = new LogRecord(Level.WARNING, "Could not add the {0} configuration file to the support bundle because of: {1}");
record.setParameters(new Object[]{ config.getAbsolutePath(), e });
record.setThrown(e);
LOGGER.log(record);
}
container.add(new XmlRedactedSecretFileContent("nodes/slave/" + agentDir.getName() + "/config.xml", config));
}
}

@@ -2,17 +2,13 @@

import com.cloudbees.jenkins.support.api.Component;
import com.cloudbees.jenkins.support.api.Container;
import com.cloudbees.jenkins.support.api.TemporaryFileContent;
import com.cloudbees.jenkins.support.util.Helper;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.security.Permission;
import jenkins.model.Jenkins;
import org.xml.sax.SAXException;

import javax.xml.transform.TransformerException;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.logging.Level;
@@ -41,13 +37,9 @@ public void addContents(@NonNull Container container) {
Jenkins jenkins = Helper.getActiveInstance();
File configFile = new File(jenkins.getRootDir(), "config.xml");
if (configFile.exists()) {
File patchedXmlFile = null;
try {
patchedXmlFile = SecretHandler.findSecrets(configFile);
container.add(new TemporaryFileContent("jenkins-root-configuration-files/" + configFile.getName(), patchedXmlFile));
} catch (IOException | SAXException | TransformerException e) {
LOGGER.log(Level.WARNING, "could not add the {0} configuration file to the support bundle because of: {1}", new Object[]{configFile.getName(), e});
}
container.add(
new XmlRedactedSecretFileContent("jenkins-root-configuration-files/" + configFile.getName(),
configFile));
} else {
//this should never happen..
LOGGER.log(Level.WARNING, "Jenkins global config file does not exist.");
@@ -2,18 +2,14 @@

import com.cloudbees.jenkins.support.api.Component;
import com.cloudbees.jenkins.support.api.Container;
import com.cloudbees.jenkins.support.api.TemporaryFileContent;
import com.cloudbees.jenkins.support.util.Helper;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.security.Permission;
import jenkins.model.Jenkins;
import org.xml.sax.SAXException;

import javax.xml.transform.TransformerException;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.logging.Level;
@@ -50,12 +46,7 @@ public boolean accept(File dir, String name) {
if (files != null) {
for (File configFile : files) {
if (configFile.exists()) {
try {
File patchedXmlFile = SecretHandler.findSecrets(configFile);
container.add(new TemporaryFileContent("jenkins-root-configuration-files/" + configFile.getName(), patchedXmlFile));
} catch (IOException | SAXException | TransformerException e) {
LOGGER.log(Level.WARNING, "could not add the {0} configuration file to the support bundle because of: {1}", new Object[]{configFile.getName(), e});
}
container.add(new XmlRedactedSecretFileContent("jenkins-root-configuration-files/" + configFile.getName(), configFile));
}
}
} else {
@@ -1,6 +1,5 @@
package com.cloudbees.jenkins.support.configfiles;

import com.cloudbees.jenkins.support.SupportPlugin;
import com.cloudbees.plugins.credentials.SecretBytes;
import hudson.util.Secret;
import org.apache.commons.io.FileUtils;
@@ -17,8 +16,8 @@
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;

@@ -29,22 +28,23 @@
* Secret Handler for xml files to add to the support bundle.
* We want to use a placeholder instead of Secrets.
*/
public class SecretHandler {
class SecretHandler {

/**
* our placeholder
*/
protected static final String SECRET_MARKER = "#secret#";
public static final String OUTPUT_ENCODING = "UTF-8";

/**
* find the secret in the xml file and replace it with the place holder
* @param xmlFile we want to parse
* @return the patched xml files without secrets
* @return the patched xml content with redacted secrets
* @throws SAXException if some XML parsing issue occurs.
* @throws IOException if some issue occurs while reading the providing file.
* @throws TransformerException if an issue occurs while writing the result.
*/
public static File findSecrets(File xmlFile) throws SAXException, IOException, TransformerException {
public static String findSecrets(File xmlFile) throws SAXException, IOException, TransformerException {

XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
private String tagName = "";
@@ -78,13 +78,14 @@ public void characters(char[] ch, int start, int length) throws SAXException {
}
};
Source src = new SAXSource(xr, new InputSource(new StringReader(FileUtils.readFileToString(xmlFile))));
File patchedFile = File.createTempFile("patched", ".xml", SupportPlugin.getRootDirectory());
Result res = new StreamResult(new FileOutputStream(patchedFile));
final ByteArrayOutputStream result = new ByteArrayOutputStream();
Result res = new StreamResult(result);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
//omit xml declaration because of https://bugs.openjdk.java.net/browse/JDK-8035437
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, OUTPUT_ENCODING);
transformer.transform(src, res);

return patchedFile;
return result.toString("UTF-8");
}
}
@@ -0,0 +1,26 @@
package com.cloudbees.jenkins.support.configfiles;

import com.cloudbees.jenkins.support.api.FileContent;
import org.xml.sax.SAXException;

import javax.xml.transform.TransformerException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

class XmlRedactedSecretFileContent extends FileContent {

public XmlRedactedSecretFileContent(String name, File file) {
super(name, file);
}

@Override
protected InputStream getInputStream() throws IOException {
try {
return new ByteArrayInputStream(SecretHandler.findSecrets(file).getBytes(SecretHandler.OUTPUT_ENCODING));
} catch (SAXException | TransformerException e) {
throw new IOException(e);
}
}
}
@@ -87,8 +87,7 @@ public void setup() {
public void shouldPutAPlaceHolderInsteadOfSecret() throws Exception {
File file = File.createTempFile("test", ".xml");
FileUtils.writeStringToFile(file, xml);
File patchedFile = SecretHandler.findSecrets(file);
String patchedXml = FileUtils.readFileToString(patchedFile);
String patchedXml = SecretHandler.findSecrets(file);
assertEquals(expectedXml, patchedXml);
}
}

0 comments on commit 8850b77

Please sign in to comment.
You can’t perform that action at this time.