Skip to content

Commit

Permalink
Large amount of generic improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Lauri Pajunen committed Feb 8, 2018
1 parent 4b0b11d commit f630438
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 30 deletions.
Expand Up @@ -17,7 +17,6 @@
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
import com.cloudbees.plugins.credentials.domains.HostnameRequirement;
import com.synopsys.protecode.sc.jenkins.interfaces.Listeners;
import com.synopsys.protecode.sc.jenkins.interfaces.Listeners.PollService;
import com.synopsys.protecode.sc.jenkins.interfaces.Listeners.ResultService;
import com.synopsys.protecode.sc.jenkins.interfaces.Listeners.ScanService;
Expand All @@ -34,6 +33,7 @@
import hudson.model.BuildListener;
import hudson.model.Descriptor;
import hudson.model.Item;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.security.ACL;
Expand All @@ -47,7 +47,6 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -109,7 +108,6 @@ public ProtecodeScPlugin(
String credentialsId,
String protecodeScGroup
) {
LOGGER.warning("BUILDING NEW PLUGIN");
this.credentialsId = credentialsId;
this.protecodeScGroup = protecodeScGroup;
this.includeSubdirectories = false;
Expand All @@ -122,6 +120,8 @@ public ProtecodeScPlugin(

private ProtecodeScService service() {
// TODO: Add check that service is ok. We might need to do a dummy call to the server for it.

// TODO: Is this needed?
getDescriptor().load();

try {
Expand All @@ -139,7 +139,7 @@ private ProtecodeScService service() {
);
}
} catch (Exception e){
listener.error("Cannot read Protecode URL, please make sure it has been set in the Jenkins"
listener.error("Cannot read Protecode SC URL, please make sure it has been set in the Jenkins"
+ " configuration page.");
}
return service;
Expand Down Expand Up @@ -175,21 +175,22 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,

public boolean doPerform(Run<?, ?> run, FilePath workspace)
throws IOException, InterruptedException
{
{
log = listener.getLogger();
log.println("/---------- Protecode SC plugin start ----------/");

// use shortened word to distinguish from possibly null service
ProtecodeScService serv = service();
if (serv == null) {
listener.error("Cannot connect to Protecode SC");
run.setResult(Result.FAILURE);
return false;
}

if (!UtilitiesGeneral.connectionOk(service.connectionOk())) {
listener.fatalError("Problem with connecting to Protecode SC, exiting");
return false;
}
// if (!UtilitiesGeneral.connectionOk(service.connectionOk())) {
// listener.fatalError("Problem with connecting to Protecode SC, exiting");
// return false;
// }

// TODO: Make a nice structured printing of build variables and other information to the
// console. Right now all printing is distributed everyhere and it causes confusion.
Expand Down Expand Up @@ -217,9 +218,12 @@ public boolean doPerform(Run<?, ?> run, FilePath workspace)
listener
);

// TODO: Order files by size, so the smaller are sent first. This will cause possible errors
// to be seen early

log.println("Sending following files to Protecode SC:");
filesToScan.forEach((ReadableFile file) ->
(log.println(file)));
(log.println(file.name())));

if (filesToScan.isEmpty()) {
// no files to scan, no failure
Expand Down Expand Up @@ -281,16 +285,24 @@ public void setError(String reason) {
if(convertToSummary) {
ReportBuilder.makeSummary(results, run, listener, REPORT_DIRECTORY, workspace);
}
log.println("/---------- Protecode SC plugin end -----------/");

boolean buildStatus = false;
if (failIfVulns) {
// TODO: Fail explicitly
// if (!verdict) {
// listener.fatalError("Vulnerabilities found.");
// }
return verdict;
if (!verdict) {
// TODO: Print vulns to console
log.println(UtilitiesGeneral.buildReportString(results));
listener.fatalError("Vulnerabilities found.");
run.setResult(Result.FAILURE);
}
buildStatus = verdict;
} else {
return true;
log.println("NO vulnerabilities found.");
buildStatus = true;
}

log.println("/---------- Protecode SC plugin end -----------/");
return buildStatus;
}

/**
Expand All @@ -307,7 +319,7 @@ private void addUploadResponse(PrintStream log, String name, UploadResponse resp
}

/**
* TODO clean up depth, move logic to other methods.
* TODO clean up depth, move logic to other methods. This is staggeringly awful.
* @param listener
*/
private boolean poll() {
Expand Down Expand Up @@ -447,13 +459,13 @@ public String getTask() {
}


@Extension @Symbol("ProtecodeSC")
@Extension @Symbol("protecodesc")
public static final class DescriptorImplementation extends BuildStepDescriptor<Builder> implements ExtensionPoint {
@Getter @Setter protected String protecodeScHost;
@Getter @Setter protected boolean dontCheckCert;

public DescriptorImplementation() {
LOGGER.warning("BUILDING NEW DESCRIPTOR, loading from super");
//LOGGER.warning("BUILDING NEW DESCRIPTOR, loading from super");
super.load();
}

Expand Down
Expand Up @@ -13,6 +13,7 @@
import com.synopsys.protecode.sc.jenkins.interfaces.Listeners.*;
import com.synopsys.protecode.sc.jenkins.types.HttpTypes;
import com.synopsys.protecode.sc.jenkins.interfaces.ProtecodeScApi;
import com.synopsys.protecode.sc.jenkins.interfaces.ProtecodeScServicesApi;
import com.synopsys.protecode.sc.jenkins.types.InternalTypes.ConnectionStatus;

import java.io.IOException;
Expand All @@ -37,9 +38,11 @@

private static final Logger LOGGER = Logger.getLogger(ProtecodeScService.class.getName());
private ProtecodeScApi backend = null;
private ProtecodeScServicesApi serviceBackend = null;

public ProtecodeScService(String credentialsId, URL host, boolean checkCertificate){
backend = ProtecodeScConnection.backend(credentialsId, host, checkCertificate);
serviceBackend = ProtecodeScConnection.serviceBackend(host, checkCertificate);
}

public void scan(String group, String fileName, RequestBody requestBody, ScanService listener) {
Expand Down Expand Up @@ -123,7 +126,7 @@ public void onFailure(Call<HttpTypes.ScanResultResponse> call, Throwable t) {
* @return ConnectionStatus object for the current connection.
*/
public ConnectionStatus connectionOk() {
Call<Void> call = backend.head();
Call<Void> call = serviceBackend.head();
try {
return new ConnectionStatus(call.execute());
} catch (IOException ex) {
Expand Down
Expand Up @@ -59,6 +59,7 @@ public long contentLength() throws IOException {
public void writeTo(@NonNull BufferedSink sink) {
InputStream inputStream = null;
Source source = null;
LOGGER.info("Reading file.");
try {
inputStream = file.read();
long writeAmount = inputStream.available();
Expand All @@ -70,8 +71,7 @@ public void writeTo(@NonNull BufferedSink sink) {
}
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error while sending file. Error message: {0}", e.getMessage());
} finally {
LOGGER.info("Closing file upload pipe to Protecode SC");
} finally {
try {
inputStream.close();
} catch (Exception e) {
Expand Down
Expand Up @@ -48,7 +48,8 @@ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

OkHttpClient.Builder builder = new OkHttpClient.Builder();
OkHttpClient.Builder builder = new OkHttpClient.Builder();

builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
Expand All @@ -58,6 +59,7 @@ public boolean verify(String hostname, SSLSession session) {
});

OkHttpClient okHttpClient = builder.build();
okHttpClient.dispatcher().setMaxRequests(Configuration.MAX_REQUESTS_TO_PROTECODE);
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
Expand Down
Expand Up @@ -10,7 +10,9 @@
****************************************************************************** */
package com.synopsys.protecode.sc.jenkins;

import com.synopsys.protecode.sc.jenkins.types.InternalTypes;
import com.synopsys.protecode.sc.jenkins.types.InternalTypes.ConnectionStatus;
import java.util.List;
import okhttp3.Headers;

class UtilitiesGeneral {
Expand Down Expand Up @@ -57,4 +59,15 @@ public static String replaceSpaceWithUnderscore(String line) {
// Currently underscore is accepted in protecode SC so it's in use.
return line.replace(" ", "_");
}

public static String buildReportString(List<InternalTypes.FileAndResult> results) {
String report = "Following files have vulnerabilities:\n";
for (InternalTypes.FileAndResult result : results)
{
if (!result.verdict()) {
report = report + result.getFilename() + "\n";
}
}
return report;
}
}
Expand Up @@ -16,11 +16,7 @@
import retrofit2.http.*;


public interface ProtecodeScApi {

@HEAD("/")
public Call<Void> head();

public interface ProtecodeScApi {
@PUT("/api/upload/{filename}")
public Call<HttpTypes.UploadResponse> scan(
@Header("Group") String groupName,
Expand Down
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2018 pajunen.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* pajunen - initial API and implementation and/or initial documentation
*/
package com.synopsys.protecode.sc.jenkins.interfaces;

import retrofit2.Call;
import retrofit2.http.HEAD;

/**
* Used for manually checking connection.
* TODO: Study whether to use interceptor perhaps.
*/
public interface ProtecodeScServicesApi {

@HEAD("/")
public Call<Void> head();

}
Expand Up @@ -15,7 +15,6 @@
import com.synopsys.protecode.sc.jenkins.types.HttpTypes.UploadResponse;
import java.io.IOException;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import lombok.Data;
import retrofit2.Response;
Expand Down Expand Up @@ -82,7 +81,13 @@ public boolean hasScanResponse() {
* @return True if component does not have an error, and has no vulns.
*/
public boolean verdict() {
return resultResponse.getResults().getSummary().getVulnCount().getExact() == 0;
try {
return resultResponse.getResults().getSummary().getVulnCount().getExact() == 0;
} catch (NullPointerException npe) {
// TODO: USE OPTIONAL. This is referenced so often that it's stupidity not just make sure
// once and for all.
return false;
}
}

public SerializableResult getSerializableResult() {
Expand Down Expand Up @@ -150,6 +155,7 @@ public String toString() {
private Optional<String> error = Optional.empty();

public ConnectionStatus(Response response) {
LOGGER.warning(response.toString());
this.response = response;
if (!response.isSuccessful()) {
try {
Expand Down

0 comments on commit f630438

Please sign in to comment.