From 5443f6e419bee6b634fa0d214ee0836ebcb0a52d Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 10 May 2016 12:01:55 +0200 Subject: [PATCH] Fixed auth problem in device simulator. Fixed equals ignore case in sha1 check. Signed-off-by: Kai Zimmermann --- .../simulator/DeviceSimulatorUpdater.java | 81 ++++++++++++++++--- .../artifact/repository/ArtifactStore.java | 3 +- 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java index 6f640ca53..4545cf759 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java @@ -41,6 +41,7 @@ import org.eclipse.hawkbit.simulator.event.ProgressUpdate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import com.google.common.eventbus.EventBus; @@ -193,7 +194,8 @@ public class DeviceSimulatorUpdater { switch (entry.getKey()) { case HTTP: case HTTPS: - status.add(downloadUrl(entry.getValue(), targetToken, artifact.getHashes().getSha1())); + status.add(downloadUrl(entry.getValue(), targetToken, artifact.getHashes().getSha1(), + artifact.getSize())); break; default: // not supported yet @@ -202,37 +204,54 @@ public class DeviceSimulatorUpdater { }); } - private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash) { - LOGGER.debug("Downloading {}", url); + private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash, + final long size) { + LOGGER.debug("Downloading {} with token {}, expected sha1 hash {} and size {}", url, + hideTokenDetails(targetToken), sha1Hash, size); long overallread = 0; try { final CloseableHttpClient httpclient = createHttpClientThatAcceptsAllServerCerts(); final HttpGet request = new HttpGet(url); - request.addHeader("TargetToken", targetToken); + request.addHeader("Authorization", "TargetToken " + targetToken); final String sha1HashResult; try (final CloseableHttpResponse response = httpclient.execute(request)) { + + if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) { + final String message = wrongStatusCode(url, response); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + + if (response.getEntity().getContentLength() != size) { + final String message = wrongContentLength(url, size, response); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + final File tempFile = File.createTempFile("uploadFile", null); final MessageDigest md = MessageDigest.getInstance("SHA-1"); try (final DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(tempFile), md)) { overallread = ByteStreams.copy(response.getEntity().getContent(), dos); - sha1HashResult = BaseEncoding.base16().lowerCase().encode(md.digest()); } finally { tempFile.delete(); } + + if (overallread != size) { + final String message = incompleteRead(url, size, overallread); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + + sha1HashResult = BaseEncoding.base16().lowerCase().encode(md.digest()); } - if (!sha1Hash.equals(sha1HashResult)) { - final String message = "Download " + url + " failed with SHA1 hash missmatch (Expected: " + sha1Hash - + " but got: " + sha1HashResult + ")"; - LOGGER.debug(message); + if (!sha1Hash.equalsIgnoreCase(sha1HashResult)) { + final String message = wrongHash(url, sha1Hash, overallread, sha1HashResult); return new UpdateStatus(ResponseStatus.ERROR, message); } } catch (IOException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { - LOGGER.error("Failed to download {}", url, e); + LOGGER.error("Failed to download {} with {}", url, e.getMessage()); return new UpdateStatus(ResponseStatus.ERROR, "Failed to download " + url + ": " + e.getMessage()); } @@ -241,6 +260,48 @@ public class DeviceSimulatorUpdater { return new UpdateStatus(ResponseStatus.SUCCESSFUL, message); } + private static String hideTokenDetails(final String targetToken) { + if (targetToken.isEmpty()) { + return ""; + } + + if (targetToken.length() <= 3) { + return "***"; + } + + return targetToken.substring(0, 3) + "***" + + targetToken.substring(targetToken.length() - 3, targetToken.length()); + } + + private static String wrongHash(final String url, final String sha1Hash, final long overallread, + final String sha1HashResult) { + final String message = "Download " + url + " failed with SHA1 hash missmatch (Expected: " + sha1Hash + + " but got: " + sha1HashResult + ") (" + overallread + " bytes)"; + LOGGER.error(message); + return message; + } + + private static String incompleteRead(final String url, final long size, final long overallread) { + final String message = "Download " + url + " is incomplete (Expected: " + size + " but got: " + overallread + + ")"; + LOGGER.error(message); + return message; + } + + private static String wrongContentLength(final String url, final long size, + final CloseableHttpResponse response) { + final String message = "Download " + url + " has wrong content length (Expected: " + size + " but got: " + + response.getEntity().getContentLength() + ")"; + LOGGER.error(message); + return message; + } + + private static String wrongStatusCode(final String url, final CloseableHttpResponse response) { + final String message = "Download " + url + " failed (" + response.getStatusLine().getStatusCode() + ")"; + LOGGER.error(message); + return message; + } + private static CloseableHttpClient createHttpClientThatAcceptsAllServerCerts() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { final SSLContextBuilder builder = new SSLContextBuilder(); diff --git a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java index 94b093cb3..d863f60cf 100644 --- a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java +++ b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java @@ -185,7 +185,8 @@ public class ArtifactStore implements ArtifactRepository { throw new ArtifactStoreException(e.getMessage(), e); } - if (hash != null && hash.getMd5() != null && !storedArtifact.getHashes().getMd5().equals(hash.getMd5())) { + if (hash != null && hash.getMd5() != null + && !storedArtifact.getHashes().getMd5().equalsIgnoreCase(hash.getMd5())) { throw new HashNotMatchException("The given md5 hash " + hash.getMd5() + " not matching the calculated md5 hash " + storedArtifact.getHashes().getMd5(), HashNotMatchException.MD5);