From c0d3c041b4e5908be65bafcc98bdfaf855d053a0 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Tue, 14 Jan 2020 11:41:23 +0100 Subject: [PATCH] [SECURITY-1291] --- core/src/main/java/hudson/Plugin.java | 19 ++++++++++++++++++- core/src/main/java/hudson/model/Computer.java | 18 +++++++++++++++++- .../java/hudson/slaves/SlaveComputer.java | 19 +++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/hudson/Plugin.java b/core/src/main/java/hudson/Plugin.java index 2f065102be..8542713e5f 100644 --- a/core/src/main/java/hudson/Plugin.java +++ b/core/src/main/java/hudson/Plugin.java @@ -30,6 +30,9 @@ import hudson.model.Saveable; import hudson.model.listeners.ItemListener; import hudson.model.listeners.SaveableListener; import hudson.model.Descriptor.FormException; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -80,7 +83,7 @@ import jenkins.model.GlobalConfiguration; * @author Kohsuke Kawaguchi * @since 1.42 */ -public abstract class Plugin implements Saveable { +public abstract class Plugin implements Saveable, StaplerProxy { private static final Logger LOGGER = Logger.getLogger(Plugin.class.getName()); @@ -293,6 +296,20 @@ public abstract class Plugin implements Saveable { new File(Jenkins.getInstance().getRootDir(),wrapper.getShortName()+".xml")); } + @Override + @Restricted(NoExternalUse.class) + public Object getTarget() { + if (!SKIP_PERMISSION_CHECK) { + Jenkins.get().checkPermission(Jenkins.READ); + } + return this; + } + + /** + * Escape hatch for StaplerProxy-based access control + */ + @Restricted(NoExternalUse.class) + public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(Plugin.class.getName() + ".skipPermissionCheck"); /** * Dummy instance of {@link Plugin} to be used when a plugin didn't diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java index 3a9fde57dc..dc3f6b7239 100644 --- a/core/src/main/java/hudson/model/Computer.java +++ b/core/src/main/java/hudson/model/Computer.java @@ -79,6 +79,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.QueryParameter; @@ -149,7 +150,7 @@ import static javax.servlet.http.HttpServletResponse.*; * @author Kohsuke Kawaguchi */ @ExportedBean -public /*transient*/ abstract class Computer extends Actionable implements AccessControlled, ExecutorListener, DescriptorByNameOwner { +public /*transient*/ abstract class Computer extends Actionable implements AccessControlled, ExecutorListener, DescriptorByNameOwner, StaplerProxy { private final CopyOnWriteArrayList executors = new CopyOnWriteArrayList(); // TODO: @@ -1575,6 +1576,21 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces getLogText().doProgressText(req, rsp); } + @Override + @Restricted(NoExternalUse.class) + public Object getTarget() { + if (!SKIP_PERMISSION_CHECK) { + Jenkins.get().checkPermission(Jenkins.READ); + } + return this; + } + + /** + * Escape hatch for StaplerProxy-based access control + */ + @Restricted(NoExternalUse.class) + public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(Computer.class.getName() + ".skipPermissionCheck"); + /** * Gets the current {@link Computer} that the build is running. * This method only works when called during a build, such as by diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java index 5020cff41b..a444786ee9 100644 --- a/core/src/main/java/hudson/slaves/SlaveComputer.java +++ b/core/src/main/java/hudson/slaves/SlaveComputer.java @@ -65,6 +65,7 @@ import org.acegisecurity.context.SecurityContextHolder; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.Beta; import org.kohsuke.accmod.restrictions.DoNotUse; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; @@ -793,6 +794,24 @@ public class SlaveComputer extends Computer { return new EncryptedSlaveAgentJnlpFile(this, "slave-agent.jnlp.jelly", getName(), CONNECT); } + class LowPermissionResponse { + @WebMethod(name="slave-agent.jnlp") + public HttpResponse doSlaveAgentJnlp(StaplerRequest req, StaplerResponse res) { + return SlaveComputer.this.doSlaveAgentJnlp(req, res); + } + } + + @Override + @Restricted(NoExternalUse.class) + public Object getTarget() { + if (!SKIP_PERMISSION_CHECK) { + if (!Jenkins.get().hasPermission(Jenkins.READ)) { + return new LowPermissionResponse(); + } + } + return this; + } + @Override protected void kill() { super.kill();