Skip to content

Commit

Permalink
Merge pull request #1 from jenkinsci/devel
Browse files Browse the repository at this point in the history
Bugfixes
  • Loading branch information
mattisii committed Feb 14, 2017
2 parents 3eca206 + 5876629 commit c99ef6e
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 91 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
.classpath
.project
.settings
.idea
20 changes: 17 additions & 3 deletions src/main/java/com/synopsys/protecode/sc/jenkins/Artifact.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,25 @@

package com.synopsys.protecode.sc.jenkins;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public interface Artifact {
String getName();
public class Artifact {
File file;
public Artifact(File f) {
this.file = f;
}
public String getName() {
return file.getName();
}

InputStream getData() throws IOException;
public InputStream getData() throws IOException {
return new FileInputStream(file);
}

public long getSize() {
return file.length();
}
}
172 changes: 134 additions & 38 deletions src/main/java/com/synopsys/protecode/sc/jenkins/HttpApiConnector.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,28 @@

package com.synopsys.protecode.sc.jenkins;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.*;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;

import com.fasterxml.jackson.databind.JsonNode;
import com.synopsys.protecode.sc.jenkins.exceptions.ApiAuthenticationException;
import com.synopsys.protecode.sc.jenkins.exceptions.ApiException;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
Expand Down Expand Up @@ -115,7 +115,6 @@ private Client createClient()
}

config.connectorProvider(new HttpUrlConnectorProvider());

ObjectMapper mapper = new ObjectMapper();

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
Expand All @@ -129,8 +128,6 @@ private Client createClient()
.build()
: ClientBuilder.newBuilder().withConfig(config).build();

log.println("Uploading file to appcheck at " + protecodeScHost);

HttpAuthenticationFeature feature = HttpAuthenticationFeature
.basicBuilder().credentials(protecodeScUser, protecodeScPass)
.build();
Expand All @@ -139,6 +136,15 @@ private Client createClient()
return client;
}

private void setTrustAllCerts() throws NoSuchAlgorithmException, KeyManagementException {
if (doNotCheckCerts && useSsl) {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, this.trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allowAllHostnames);
}
}

public static String sanitizeArtifactFileName(String filename) {
// Protecode SC upload API does not allow some filename characters in
// the
Expand All @@ -155,36 +161,122 @@ public static String sanitizeArtifactFileName(String filename) {
return sanitizedFilename;
}

public String init(Map<String, String> scanMetaData)
throws KeyManagementException, NoSuchAlgorithmException,
IOException {

/**
* Initialize HTTP client
* @throws KeyManagementException
* @throws NoSuchAlgorithmException
*/
public void init() throws KeyManagementException, NoSuchAlgorithmException {
client = createClient();
WebTarget target = client.target(protecodeScHost);
setTrustAllCerts();
}

/**
* Send artifact for scanning
* @param artifact
* @param scanMetaData
* @return SHA1 for the file
* @throws IOException
* @throws NoSuchAlgorithmException
* When SHA-1 is not available
* @throws ApiException
* When connection fails
* When authentication fails
*/
public String sendFile(Artifact artifact, Map<String, String> scanMetaData) throws IOException, ApiException, NoSuchAlgorithmException {
String filename = artifact.getName();
String protecodeScFileName = sanitizeArtifactFileName(filename);
InputStream inputStream = new BufferedInputStream(artifact.getData());
Builder requestBuilder = target
log.println("Uploading file to Protecode SC at " + protecodeScHost);
InputStream fileInputStream = new BufferedInputStream(artifact.getData());

byte[] authData = (protecodeScUser+":"+protecodeScPass).getBytes(StandardCharsets.UTF_8);
String encodedAuthData = javax.xml.bind.DatatypeConverter.printBase64Binary(authData);

URL url = new URL(protecodeScHost + "api/upload/" + UrlEscapers.urlPathSegmentEscaper()
.escape(protecodeScFileName));

.path("api/upload/" + UrlEscapers.urlPathSegmentEscaper()
.escape(protecodeScFileName))
.request().header("Group-Appcheck", protecodeScGroup)
.header("Delete-Binary-Appcheck", "true");
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setFixedLengthStreamingMode(artifact.getSize());
httpCon.setDoOutput(true);
httpCon.setRequestMethod("PUT");
httpCon.setRequestProperty("Authorization", "Basic "+encodedAuthData);
httpCon.setRequestProperty("Group-Appcheck", protecodeScGroup);
httpCon.setRequestProperty("Delete-Binary-Appcheck", "true");

for (Entry<String, String> e : scanMetaData.entrySet()) {
requestBuilder = requestBuilder.header("META-" + e.getKey(),
e.getValue());
for (Map.Entry<String, String> e : scanMetaData.entrySet()) {
httpCon.setRequestProperty("META-" + e.getKey(), e.getValue());
}
Response r = requestBuilder.put(Entity.entity(inputStream, "*/*"));

ProtecodeSc response = r.readEntity(ProtecodeSc.class);
String identifier = response.getResults().getSha1sum();
DataOutputStream out = null;
try {
out = new DataOutputStream(
httpCon.getOutputStream());
} catch (ConnectException e) {
throw new ApiException(e);
}

int buffsize = 10240;
byte[] buff = new byte[buffsize];
int len = 0;
int inbuff = 0;
// Count the SHA1 locally to poll in case scan is already started
MessageDigest digest = MessageDigest.getInstance("SHA-1");
String sha1 = null;

try {
// Do the actual file sending
while ((len = fileInputStream.read(buff, 0, buffsize)) > 0) {
inbuff = len;
while ((inbuff < buffsize)) {
len = fileInputStream.read(buff, inbuff, buffsize - inbuff);
if (len == -1) {
break;
}
inbuff += len;
}
if (inbuff > 0) {
out.write(buff, 0, inbuff);
digest.update(buff, 0, inbuff);
}
}
sha1 = new HexBinaryAdapter().marshal(digest.digest()).toLowerCase();
out.flush();
out.close();
} catch (IOException e) {
throw new ApiException(e.getMessage()); // Don't mind this if running against dev-stack, behaves differently
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
// NOP
}
}

try {
if (httpCon.getResponseCode() == 401) {
throw new ApiAuthenticationException("Protecode SC upload failed, authorization error");
} else if (httpCon.getResponseCode() == 400) {
throw new ApiAuthenticationException("Protecode SC upload failed, bad request (please check your credentials and upload group)");
} else if (httpCon.getResponseCode() == 409) {
return sha1;
}
} catch (IOException e) {
log.println(e.getMessage());
throw new ApiException(e);
}

ObjectMapper mapper = new ObjectMapper();
try {
inputStream.close();
} catch (IOException ignore) {
// intentionally left blank
JsonNode resultJson = mapper.readTree(httpCon.getInputStream());
JsonNode results = resultJson.get("results");
return results.get("sha1sum").asText();
} catch (IOException e) {
log.println(e.getMessage());
} finally {
httpCon.disconnect();
}
return identifier;
return sha1;
}

public PollResult poll(String identifier) {
Expand All @@ -205,9 +297,13 @@ public PollResult poll(String identifier) {
log.println("Artifact " + artifact.getName()
+ " polling success, status "
+ response.getMeta().getCode());
return new PollResult(true, response.getResults().getSummary()
.getVulnCount().getExact() == 0, response,
artifact.getName());
if (response.getResults().getSummary().getVulnCount() != null) {
return new PollResult(true, response.getResults().getSummary()
.getVulnCount().getExact() == 0, response,
artifact.getName());
} else {
return new PollResult(true, false);
}
}
if (Status.B.equals(responseStatus)) {
return new PollResult(false, false);
Expand Down
Loading

0 comments on commit c99ef6e

Please sign in to comment.