Skip to content

Commit

Permalink
- add script-security dependency (just upload remaining)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wadeck committed Jan 11, 2018
1 parent cbafe3c commit 61cb13f
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 6 deletions.
10 changes: 8 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.javadoc.skip>true</maven.javadoc.skip>
<jenkins.version>1.580</jenkins.version>
<jenkins.version>1.580.1</jenkins.version>
<java.level>6</java.level>
<findbugs.failOnError>false</findbugs.failOnError>
</properties>
Expand All @@ -57,11 +57,17 @@
<version>1.9</version>
<scope>provided</scope><!-- this is in the core -->
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>git-server</artifactId>
<version>1.7</version>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>script-security</artifactId>
<version>1.26</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@
import org.kohsuke.stapler.interceptor.RequirePOST;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
Expand Down Expand Up @@ -267,6 +269,8 @@ private String saveScriptAndForward(String id, String name, String comment, Stri

commitFileToGitRepo(finalFileName);

ScriptHelper.putScriptInApprovalQueueIfRequired(script);

Script newScript = null;
if (!StringUtils.isEmpty(originId)) {
newScript = new Script(finalFileName, displayName, comment, true, originCatalogName, originId, new SimpleDateFormat("dd MMM yyyy HH:mm:ss a").format(new Date()), parameters);
Expand Down Expand Up @@ -395,6 +399,7 @@ public HttpResponse doUploadScript(StaplerRequest req) throws IOException, Servl
if (script == null) {
script = new Script(fileName, fileName, true, nonAdministerUsing, false);
}
//TODO add approval queue for the source code
ScriptlerConfiguration config = getConfiguration();
config.addOrReplace(script);
}
Expand Down Expand Up @@ -466,6 +471,15 @@ public void doTriggerScript(StaplerRequest req, StaplerResponse rsp, @QueryParam
// the output.
tempScript = ScriptHelper.getScriptCopy(id, false);
tempScript.setScript(scriptSrc);

ScriptHelper.putScriptInApprovalQueueIfRequired(scriptSrc);
}

boolean approved = ScriptHelper.isApproved(scriptSrc);
if(!approved){
LOGGER.log(Level.WARNING, "Script {} was not approved yet, consider asking your administrator to approve it.", id);
rsp.sendError(HttpServletResponse.SC_FORBIDDEN, "Script not approved yet, consider asking your administrator to approve it.");
return;
}

final String[] slaves = resolveSlaveNames(node);
Expand Down Expand Up @@ -525,6 +539,13 @@ public void doRun(StaplerRequest req, StaplerResponse rsp, @QueryParameter(fixEm
script = tempScript.script;
}

boolean approved = ScriptHelper.isApproved(script);
if(!approved){
LOGGER.log(Level.WARNING, "Script {0} was not approved yet, consider asking your administrator to approve it.", id);
rsp.sendError(HttpServletResponse.SC_FORBIDDEN, "Script not approved yet, consider asking your administrator to approve it.");
return;
}

Parameter[] paramArray = prepareParameters(req, tempScript);

rsp.setContentType(contentType == null ? "text/plain" : contentType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.io.FileUtils;
import org.jenkinsci.plugins.scriptler.config.Script;
import org.jenkinsci.plugins.scriptler.config.ScriptlerConfiguration;
import org.jenkinsci.plugins.scriptler.util.ScriptHelper;

/**
* @author domi
Expand Down Expand Up @@ -80,7 +82,18 @@ private void synchronizeConfig() throws IOException {
cfg.save();

}

@Override
public void postInitialize() throws Exception {
for (Script script : ScriptlerConfiguration.getConfiguration().getScripts()) {
File scriptFile = new File(ScriptlerManagement.getScriptDirectory(), script.getScriptPath());
String scriptSource = FileUtils.readFileToString(scriptFile, "UTF-8");

// we cannot do that during start since the ScriptApproval is not yet loaded
ScriptHelper.putScriptInApprovalQueueIfRequired(scriptSource);
}
}

/**
* search into the declared backup directory for backup archives
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListen
if (!script.nonAdministerUsing) {
throw new Failure(script.getName() + " [" + script.getId() + "] is not allowed to be executed in a build, check its configuration!");
}

if(!ScriptHelper.isApproved(script.script)){
LOGGER.log(Level.WARNING, "The script [{0}] is not approved yet, consider asking your administrator to approve it.", script.getName());
return false;
}

try {

// expand the parameters before passing these to the execution, this is to allow any token macro to resolve parameter values
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
*/
package org.jenkinsci.plugins.scriptler.config;

import org.kohsuke.stapler.DataBoundConstructor;

public class Script implements Comparable<Script>, NamedResource {

private String id;
Expand All @@ -51,7 +49,6 @@ public class Script implements Comparable<Script>, NamedResource {
/**
* used to create/update a new script in the UI
*/
@DataBoundConstructor
public Script(String id, String name, String comment, boolean nonAdministerUsing, Parameter[] parameters, boolean onlyMaster) {
this(id, name, comment, null, null, null, nonAdministerUsing, parameters, onlyMaster);
}
Expand Down Expand Up @@ -128,7 +125,7 @@ public Parameter[] getParameters() {

/*
* (non-Javadoc)
*
*
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(Script o) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@

import jenkins.model.Jenkins;

import jenkins.security.Roles;
import org.apache.commons.collections.map.LRUMap;
import org.jenkinsci.plugins.scriptler.Messages;
import org.jenkinsci.plugins.scriptler.config.Parameter;
import org.jenkinsci.remoting.Role;
import org.jenkinsci.remoting.RoleChecker;

/**
* Inspired by hudson.util.RemotingDiagnostics.Script, but adding parameters.
Expand Down Expand Up @@ -139,6 +142,15 @@ public Object call() throws RuntimeException {
}
}

@Override
public void checkRoles(RoleChecker roleChecker) throws SecurityException {
if(launcher != null && build != null){
roleChecker.check(this, Roles.MASTER);
}else{
roleChecker.check(this, Role.UNKNOWN);
}
}

private static final class ScriptlerExecutionException extends RuntimeException {
private static final long serialVersionUID = 1L;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
import org.jenkinsci.plugins.scriptler.config.ScriptlerConfiguration;
import org.jenkinsci.plugins.scriptler.share.ScriptInfo;
import org.jenkinsci.plugins.scriptler.share.ScriptInfo.Author;
import org.jenkinsci.plugins.scriptsecurity.scripts.ApprovalContext;
import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval;
import org.jenkinsci.plugins.scriptsecurity.scripts.UnapprovedUsageException;
import org.jenkinsci.plugins.scriptsecurity.scripts.languages.GroovyLanguage;

/**
*
Expand Down Expand Up @@ -79,6 +83,31 @@ public static Script getScript(String id, boolean withSrc) {
}
return s;
}

/**
* @since TODO
*/
public static void putScriptInApprovalQueueIfRequired(String scriptSourceCode){
// we cannot use sandbox since the script is potentially sent to slaves
// and the sandbox mode is not meant to be used with remoting
ScriptApproval.get().configuring(scriptSourceCode, GroovyLanguage.get(), ApprovalContext.create().withCurrentUser());
}

/**
* @return true iff the script was approved or created by a user with RUN_SCRIPT permission
* @since TODO
*/
public static boolean isApproved(String scriptSourceCode){
try{
ScriptApproval.get().using(scriptSourceCode, GroovyLanguage.get());
return true;
}
catch(UnapprovedUsageException e){
// in case there is some ways that are not covered
putScriptInApprovalQueueIfRequired(scriptSourceCode);
return false;
}
}

public static String runScript(String[] slaves, String scriptTxt, Parameter[] parameters) throws IOException, ServletException {
StringBuffer output = new StringBuffer();
Expand Down

0 comments on commit 61cb13f

Please sign in to comment.