From 6389e45670b6b57a2803e5789a8344a2705f9965 Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Tue, 30 Apr 2019 10:41:07 +0900 Subject: [PATCH] Allow overriding maximum signed request time skew --- src/main/java/org/gaul/s3proxy/S3Proxy.java | 14 +++++++++++++- .../java/org/gaul/s3proxy/S3ProxyConstants.java | 6 +++--- src/main/java/org/gaul/s3proxy/S3ProxyHandler.java | 10 ++++++---- .../java/org/gaul/s3proxy/S3ProxyHandlerJetty.java | 5 +++-- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/gaul/s3proxy/S3Proxy.java b/src/main/java/org/gaul/s3proxy/S3Proxy.java index 082334b..7e19723 100644 --- a/src/main/java/org/gaul/s3proxy/S3Proxy.java +++ b/src/main/java/org/gaul/s3proxy/S3Proxy.java @@ -117,7 +117,7 @@ public final class S3Proxy { builder.credential, builder.virtualHost, builder.v4MaxNonChunkedRequestSize, builder.ignoreUnknownHeaders, builder.corsRules, - builder.servicePath); + builder.servicePath, builder.maximumTimeSkew); server.setHandler(handler); } @@ -137,6 +137,7 @@ public final class S3Proxy { private boolean ignoreUnknownHeaders; private CrossOriginResourceSharing corsRules; private int jettyMaxThreads = 200; // sourced from QueuedThreadPool() + private int maximumTimeSkew = 15 * 60; Builder() { } @@ -267,6 +268,12 @@ public final class S3Proxy { builder.jettyMaxThreads(Integer.parseInt(jettyMaxThreads)); } + String maximumTimeSkew = properties.getProperty( + S3ProxyConstants.PROPERTY_MAXIMUM_TIME_SKEW); + if (maximumTimeSkew != null) { + builder.maximumTimeSkew(Integer.parseInt(maximumTimeSkew)); + } + return builder; } @@ -330,6 +337,11 @@ public final class S3Proxy { return this; } + public Builder maximumTimeSkew(int maximumTimeSkew) { + this.maximumTimeSkew = maximumTimeSkew; + return this; + } + public Builder servicePath(String s3ProxyServicePath) { String path = Strings.nullToEmpty(s3ProxyServicePath); diff --git a/src/main/java/org/gaul/s3proxy/S3ProxyConstants.java b/src/main/java/org/gaul/s3proxy/S3ProxyConstants.java index 21c7b3a..aecf2bc 100644 --- a/src/main/java/org/gaul/s3proxy/S3ProxyConstants.java +++ b/src/main/java/org/gaul/s3proxy/S3ProxyConstants.java @@ -16,8 +16,6 @@ package org.gaul.s3proxy; -import java.util.concurrent.TimeUnit; - public final class S3ProxyConstants { public static final String PROPERTY_ENDPOINT = "s3proxy.endpoint"; @@ -81,7 +79,9 @@ public final class S3ProxyConstants { public static final String PROPERTY_READ_ONLY_BLOBSTORE = "s3proxy.read-only-blobstore"; - public static final long PROPERTY_TIMESKEW = TimeUnit.MINUTES.toSeconds(15); + /** Maximum time skew allowed in signed requests. */ + public static final String PROPERTY_MAXIMUM_TIME_SKEW = + "s3proxy.maximum-timeskew"; static final String PROPERTY_ALT_JCLOUDS_PREFIX = "alt."; diff --git a/src/main/java/org/gaul/s3proxy/S3ProxyHandler.java b/src/main/java/org/gaul/s3proxy/S3ProxyHandler.java index aeec7c4..0c4a25d 100644 --- a/src/main/java/org/gaul/s3proxy/S3ProxyHandler.java +++ b/src/main/java/org/gaul/s3proxy/S3ProxyHandler.java @@ -194,6 +194,7 @@ public class S3ProxyHandler { private final boolean ignoreUnknownHeaders; private final CrossOriginResourceSharing corsRules; private final String servicePath; + private final int maximumTimeSkew; private final XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance(); private BlobStoreLocator blobStoreLocator; @@ -215,7 +216,8 @@ public class S3ProxyHandler { AuthenticationType authenticationType, final String identity, final String credential, @Nullable String virtualHost, long v4MaxNonChunkedRequestSize, boolean ignoreUnknownHeaders, - CrossOriginResourceSharing corsRules, final String servicePath) { + CrossOriginResourceSharing corsRules, final String servicePath, + int maximumTimeSkew) { if (authenticationType != AuthenticationType.NONE) { anonymousIdentity = false; blobStoreLocator = new BlobStoreLocator() { @@ -250,6 +252,7 @@ public class S3ProxyHandler { xmlOutputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.FALSE); this.servicePath = Strings.nullToEmpty(servicePath); + this.maximumTimeSkew = maximumTimeSkew; } private static String getBlobStoreType(BlobStore blobStore) { @@ -2788,13 +2791,12 @@ public class S3ProxyHandler { } } - private static void isTimeSkewed(long date) throws S3Exception { + private void isTimeSkewed(long date) throws S3Exception { if (date < 0) { throw new S3Exception(S3ErrorCode.ACCESS_DENIED); } long now = System.currentTimeMillis() / 1000; - if (now + S3ProxyConstants.PROPERTY_TIMESKEW < date || - now - S3ProxyConstants.PROPERTY_TIMESKEW > date) { + if (now + maximumTimeSkew < date || now - maximumTimeSkew > date) { logger.debug("time skewed {} {}", date, now); throw new S3Exception(S3ErrorCode.REQUEST_TIME_TOO_SKEWED); } diff --git a/src/main/java/org/gaul/s3proxy/S3ProxyHandlerJetty.java b/src/main/java/org/gaul/s3proxy/S3ProxyHandlerJetty.java index 4722d94..8e73f0e 100644 --- a/src/main/java/org/gaul/s3proxy/S3ProxyHandlerJetty.java +++ b/src/main/java/org/gaul/s3proxy/S3ProxyHandlerJetty.java @@ -44,10 +44,11 @@ final class S3ProxyHandlerJetty extends AbstractHandler { AuthenticationType authenticationType, final String identity, final String credential, @Nullable String virtualHost, long v4MaxNonChunkedRequestSize, boolean ignoreUnknownHeaders, - CrossOriginResourceSharing corsRules, String servicePath) { + CrossOriginResourceSharing corsRules, String servicePath, + int maximumTimeSkew) { handler = new S3ProxyHandler(blobStore, authenticationType, identity, credential, virtualHost, v4MaxNonChunkedRequestSize, - ignoreUnknownHeaders, corsRules, servicePath); + ignoreUnknownHeaders, corsRules, servicePath, maximumTimeSkew); } private void sendS3Exception(HttpServletRequest request,