Skip to content

Commit

Permalink
Merge pull request #782 from jenkinsci/sec-fixes
Browse files Browse the repository at this point in the history
add post annotations and permissions checks
  • Loading branch information
res0nance committed Oct 11, 2022
2 parents 8ffb7fd + 5f88eb5 commit 7c7583d
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 97 deletions.
4 changes: 4 additions & 0 deletions src/main/java/hudson/plugins/ec2/AmazonEC2Cloud.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.model.DescribeRegionsResult;
import com.amazonaws.services.ec2.model.Region;
import org.kohsuke.stapler.verb.POST;

/**
* The original implementation of {@link EC2Cloud}.
Expand Down Expand Up @@ -163,7 +164,9 @@ public String getDisplayName() {
return "Amazon EC2";
}

@POST
public FormValidation doCheckCloudName(@QueryParameter String value) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
try {
Jenkins.checkGoodName(value);
} catch (Failure e) {
Expand All @@ -183,6 +186,7 @@ public FormValidation doCheckCloudName(@QueryParameter String value) {
return FormValidation.ok();
}

@POST
public FormValidation doCheckAltEC2Endpoint(@QueryParameter String value) {
if (Util.fixEmpty(value) != null) {
try {
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/hudson/plugins/ec2/EC2AbstractSlave.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import com.amazonaws.services.ec2.model.StopInstancesRequest;
import com.amazonaws.services.ec2.model.Tag;
import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
import org.kohsuke.stapler.verb.POST;

/**
* Agent running on EC2.
Expand Down Expand Up @@ -810,11 +811,13 @@ public boolean isInstantiable() {
return false;
}

@POST
public ListBoxModel doFillZoneItems(@QueryParameter boolean useInstanceProfileForCredentials,
@QueryParameter String credentialsId,
@QueryParameter String region,
@QueryParameter String roleArn,
@QueryParameter String roleSessionName) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
AWSCredentialsProvider credentialsProvider = EC2Cloud.createCredentialsProvider(useInstanceProfileForCredentials, credentialsId, roleArn, roleSessionName, region);
return fillZoneItems(credentialsProvider, region);
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/hudson/plugins/ec2/EC2Cloud.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;

import org.kohsuke.stapler.interceptor.RequirePOST;
import org.kohsuke.stapler.verb.POST;

/**
* Hudson's view of EC2.
Expand Down Expand Up @@ -1083,7 +1084,9 @@ public InstanceType[] getInstanceTypes() {
return InstanceType.values();
}

@POST
public FormValidation doCheckUseInstanceProfileForCredentials(@QueryParameter boolean value) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
if (value) {
try {
new InstanceProfileCredentialsProvider(false).getCredentials();
Expand All @@ -1095,6 +1098,7 @@ public FormValidation doCheckUseInstanceProfileForCredentials(@QueryParameter bo
return FormValidation.ok();
}

@POST
public ListBoxModel doFillSshKeysCredentialsIdItems(@AncestorInPath ItemGroup context, @QueryParameter String sshKeysCredentialsId) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);

Expand Down Expand Up @@ -1156,6 +1160,7 @@ public FormValidation doCheckSshKeysCredentialsId(@AncestorInPath ItemGroup cont
* @throws IOException
* @throws ServletException
*/
@POST
protected FormValidation doTestConnection(@AncestorInPath ItemGroup context, URL ec2endpoint, boolean useInstanceProfileForCredentials, String credentialsId, String sshKeysCredentialsId, String roleArn, String roleSessionName, String region)
throws IOException, ServletException {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/hudson/plugins/ec2/EC2Computer.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.kohsuke.stapler.HttpResponse;
import com.amazonaws.AmazonClientException;
import com.amazonaws.services.ec2.AmazonEC2;
import org.kohsuke.stapler.verb.POST;

/**
* @author Kohsuke Kawaguchi
Expand Down Expand Up @@ -214,6 +215,7 @@ public long getLaunchTime() throws InterruptedException {
* When the agent is deleted, terminate the instance.
*/
@Override
@POST
public HttpResponse doDoDelete() throws IOException {
checkPermission(DELETE);
EC2AbstractSlave node = getNode();
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/hudson/plugins/ec2/EC2Step.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.jenkinsci.plugins.workflow.steps.*;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.verb.POST;

import java.util.*;

Expand Down Expand Up @@ -85,8 +86,9 @@ public String getDisplayName() {
return "Cloud template provisioning";
}


@POST
public ListBoxModel doFillCloudItems() {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
ListBoxModel r = new ListBoxModel();
r.add("", "");
Jenkins.CloudList clouds = jenkins.model.Jenkins.get().clouds;
Expand All @@ -98,7 +100,9 @@ public ListBoxModel doFillCloudItems() {
return r;
}

@POST
public ListBoxModel doFillTemplateItems(@QueryParameter String cloud) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
cloud = Util.fixEmpty(cloud);
ListBoxModel r = new ListBoxModel();
for (Cloud cList : jenkins.model.Jenkins.get().clouds) {
Expand Down
34 changes: 0 additions & 34 deletions src/main/java/hudson/plugins/ec2/MacData.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,9 @@

import hudson.Extension;
import hudson.model.Descriptor;
import hudson.util.FormValidation;
import jenkins.model.Jenkins;

import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;

public class MacData extends AMITypeData {
private final String rootCommandPrefix;
Expand Down Expand Up @@ -61,33 +54,6 @@ public static class DescriptorImpl extends Descriptor<AMITypeData> {
public String getDisplayName() {
return "mac";
}

@Restricted(NoExternalUse.class)
public FormValidation doCheckRootCommandPrefix(@QueryParameter String value){
if(StringUtils.isBlank(value) || Jenkins.get().hasPermission(Jenkins.ADMINISTER)){
return FormValidation.ok();
}else{
return FormValidation.error(Messages.General_MissingPermission());
}
}

@Restricted(NoExternalUse.class)
public FormValidation doCheckSlaveCommandPrefix(@QueryParameter String value){
if(StringUtils.isBlank(value) || Jenkins.get().hasPermission(Jenkins.ADMINISTER)){
return FormValidation.ok();
}else{
return FormValidation.error(Messages.General_MissingPermission());
}
}

@Restricted(NoExternalUse.class)
public FormValidation doCheckSlaveCommandSuffix(@QueryParameter String value){
if(StringUtils.isBlank(value) || Jenkins.get().hasPermission(Jenkins.ADMINISTER)){
return FormValidation.ok();
}else{
return FormValidation.error(Messages.General_MissingPermission());
}
}
}

public String getRootCommandPrefix() {
Expand Down
51 changes: 23 additions & 28 deletions src/main/java/hudson/plugins/ec2/SlaveTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@
import org.kohsuke.stapler.interceptor.RequirePOST;

import edu.umd.cs.findbugs.annotations.CheckForNull;
import org.kohsuke.stapler.verb.POST;

import javax.servlet.ServletException;
import java.io.IOException;
import java.io.PrintStream;
Expand Down Expand Up @@ -1897,6 +1899,7 @@ public String getHelpFile(String fieldName) {
}

@Restricted(NoExternalUse.class)
@POST
public FormValidation doCheckDescription(@QueryParameter String value) {
try {
Jenkins.checkGoodName(value);
Expand All @@ -1906,34 +1909,6 @@ public FormValidation doCheckDescription(@QueryParameter String value) {
}
}

@Restricted(NoExternalUse.class)
public FormValidation doCheckRemoteAdmin(@QueryParameter String value){
if(StringUtils.isBlank(value) || Jenkins.get().hasPermission(Jenkins.ADMINISTER)){
return FormValidation.ok();
}else{
return FormValidation.error(Messages.General_MissingPermission());
}
}

@Restricted(NoExternalUse.class)
public FormValidation doCheckTmpDir(@QueryParameter String value){
if(StringUtils.isBlank(value) || Jenkins.get().hasPermission(Jenkins.ADMINISTER)){
return FormValidation.ok();
} else {
return FormValidation.error(Messages.General_MissingPermission());
}
}

@Restricted(NoExternalUse.class)
public FormValidation doCheckJvmopts(@QueryParameter String value){
if(StringUtils.isBlank(value) || Jenkins.get().hasPermission(Jenkins.ADMINISTER)){
return FormValidation.ok();
} else {
return FormValidation.error(Messages.General_MissingPermission());
}
}


/***
* Check that the AMI requested is available in the cloud and can be used.
*/
Expand Down Expand Up @@ -1971,6 +1946,7 @@ private void checkPermission(Permission p) {
}
}

@POST
public FormValidation doCheckLabelString(@QueryParameter String value, @QueryParameter Node.Mode mode) {
if (mode == Node.Mode.EXCLUSIVE && (value == null || value.trim().isEmpty())) {
return FormValidation.warning("You may want to assign labels to this node;"
Expand All @@ -1980,6 +1956,7 @@ public FormValidation doCheckLabelString(@QueryParameter String value, @QueryPar
return FormValidation.ok();
}

@POST
public FormValidation doCheckIdleTerminationMinutes(@QueryParameter String value) {
if (value == null || value.trim().isEmpty())
return FormValidation.ok();
Expand All @@ -1992,6 +1969,7 @@ public FormValidation doCheckIdleTerminationMinutes(@QueryParameter String value
return FormValidation.error("Idle Termination time must be a greater than -59 (or null)");
}

@POST
public FormValidation doCheckMaxTotalUses(@QueryParameter String value) {
try {
int val = Integer.parseInt(value);
Expand All @@ -2002,6 +1980,7 @@ public FormValidation doCheckMaxTotalUses(@QueryParameter String value) {
return FormValidation.error("Maximum Total Uses must be greater or equal to -1");
}

@POST
public FormValidation doCheckMinimumNumberOfInstances(@QueryParameter String value, @QueryParameter String instanceCapStr) {
if (value == null || value.trim().isEmpty())
return FormValidation.ok();
Expand All @@ -2026,6 +2005,7 @@ public FormValidation doCheckMinimumNumberOfInstances(@QueryParameter String val
return FormValidation.error("Minimum number of instances must be a non-negative integer (or null)");
}

@POST
public FormValidation doCheckMinimumNoInstancesActiveTimeRangeFrom(@QueryParameter String value) {
try {
MinimumNumberOfInstancesTimeRangeConfig.validateLocalTimeString(value);
Expand All @@ -2035,6 +2015,7 @@ public FormValidation doCheckMinimumNoInstancesActiveTimeRangeFrom(@QueryParamet
}
}

@POST
public FormValidation doCheckMinimumNoInstancesActiveTimeRangeTo(@QueryParameter String value) {
try {
MinimumNumberOfInstancesTimeRangeConfig.validateLocalTimeString(value);
Expand All @@ -2045,6 +2026,7 @@ public FormValidation doCheckMinimumNoInstancesActiveTimeRangeTo(@QueryParameter
}

// For some reason, all days will validate against this method so no need to repeat for each day.
@POST
public FormValidation doCheckMonday(@QueryParameter boolean monday,
@QueryParameter boolean tuesday,
@QueryParameter boolean wednesday,
Expand All @@ -2057,6 +2039,8 @@ public FormValidation doCheckMonday(@QueryParameter boolean monday,
}
return FormValidation.ok();
}

@POST
public FormValidation doCheckMinimumNumberOfSpareInstances(@QueryParameter String value, @QueryParameter String instanceCapStr) {
if (value == null || value.trim().isEmpty())
return FormValidation.ok();
Expand All @@ -2081,6 +2065,7 @@ public FormValidation doCheckMinimumNumberOfSpareInstances(@QueryParameter Strin
return FormValidation.error("Minimum number of spare instances must be a non-negative integer (or null)");
}

@POST
public FormValidation doCheckInstanceCapStr(@QueryParameter String value) {
if (value == null || value.trim().isEmpty())
return FormValidation.ok();
Expand All @@ -2096,6 +2081,7 @@ public FormValidation doCheckInstanceCapStr(@QueryParameter String value) {
/*
* Validate the Spot Block Duration to be between 0 & 6 hours as specified in the AWS API
*/
@POST
public FormValidation doCheckSpotBlockReservationDurationStr(@QueryParameter String value) {
if (value == null || value.trim().isEmpty())
return FormValidation.ok();
Expand All @@ -2108,6 +2094,7 @@ public FormValidation doCheckSpotBlockReservationDurationStr(@QueryParameter Str
return FormValidation.error("Spot Block Reservation Duration must be an integer between 0 & 6");
}

@POST
public FormValidation doCheckLaunchTimeoutStr(@QueryParameter String value) {
if (value == null || value.trim().isEmpty())
return FormValidation.ok();
Expand Down Expand Up @@ -2138,6 +2125,7 @@ public String getDefaultTenancy() {
/*
* Validate the Spot Max Bid Price to ensure that it is a floating point number >= .001
*/
@POST
public FormValidation doCheckSpotMaxBidPrice(@QueryParameter String spotMaxBidPrice) {
if (SpotConfiguration.normalizeBid(spotMaxBidPrice) != null) {
return FormValidation.ok();
Expand All @@ -2153,6 +2141,7 @@ public List<NodePropertyDescriptor> getNodePropertyDescriptors() {
return NodePropertyDescriptor.for_(NodeProperty.all(), EC2AbstractSlave.class);
}

@POST
public ListBoxModel doFillConnectionStrategyItems(@QueryParameter String connectionStrategy) {
return Stream.of(ConnectionStrategy.values())
.map(v -> {
Expand All @@ -2165,6 +2154,7 @@ public ListBoxModel doFillConnectionStrategyItems(@QueryParameter String connect
.collect(Collectors.toCollection(ListBoxModel::new));
}

@POST
public FormValidation doCheckConnectionStrategy(@QueryParameter String connectionStrategy) {
return Stream.of(ConnectionStrategy.values())
.filter(v -> v.name().equals(connectionStrategy))
Expand All @@ -2178,6 +2168,7 @@ public String getDefaultHostKeyVerificationStrategy() {
return HostKeyVerificationStrategyEnum.CHECK_NEW_HARD.name();
}

@POST
public ListBoxModel doFillHostKeyVerificationStrategyItems(@QueryParameter String hostKeyVerificationStrategy) {
return Stream.of(HostKeyVerificationStrategyEnum.values())
.map(v -> {
Expand All @@ -2190,6 +2181,7 @@ public ListBoxModel doFillHostKeyVerificationStrategyItems(@QueryParameter Strin
.collect(Collectors.toCollection(ListBoxModel::new));
}

@POST
public FormValidation doCheckHostKeyVerificationStrategy(@QueryParameter String hostKeyVerificationStrategy) {
Stream<HostKeyVerificationStrategyEnum> stream = Stream.of(HostKeyVerificationStrategyEnum.values());
Stream<HostKeyVerificationStrategyEnum> filteredStream = stream.filter(v -> v.name().equals(hostKeyVerificationStrategy));
Expand All @@ -2198,6 +2190,7 @@ public FormValidation doCheckHostKeyVerificationStrategy(@QueryParameter String
return okResult.orElse(FormValidation.error(String.format("Could not find selected host key verification (%s)", hostKeyVerificationStrategy)));
}

@POST
public ListBoxModel doFillTenancyItems(@QueryParameter String tenancy) {
return Stream.of(Tenancy.values())
.map(v -> {
Expand All @@ -2213,6 +2206,7 @@ public String getDefaultEbsEncryptRootVolume() {
return EbsEncryptRootVolume.DEFAULT.getDisplayText();
}

@POST
public ListBoxModel doFillEbsEncryptRootVolumeItems(@QueryParameter String ebsEncryptRootVolume ) {
return Stream.of(EbsEncryptRootVolume.values())
.map(v -> {
Expand All @@ -2225,6 +2219,7 @@ public ListBoxModel doFillEbsEncryptRootVolumeItems(@QueryParameter String ebsEn
.collect(Collectors.toCollection(ListBoxModel::new));
}

@POST
public FormValidation doEbsEncryptRootVolume(@QueryParameter String ebsEncryptRootVolume) {
Stream<EbsEncryptRootVolume> stream = Stream.of(EbsEncryptRootVolume.values());
Stream<EbsEncryptRootVolume> filteredStream = stream.filter(v -> v.name().equals(ebsEncryptRootVolume));
Expand Down
Loading

0 comments on commit 7c7583d

Please sign in to comment.