-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Copied signing classes from Minio: https://github.com/minio/minio-java - Added Notice file for Minio - Replaced OkHttp, etc. classes with emulated equivalents - Added an initial test for a simple `aws s3 ls` based on this doc: https://min.io/docs/minio/linux/integrations/aws-cli-with-minio.html Closes #5
- Loading branch information
Showing
17 changed files
with
1,111 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This product includes software developed by Minio. (https://github.com/minio/minio-java) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
trino-s3-proxy/src/main/java/io/trino/s3/proxy/server/credentials/Credentials.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.trino.s3.proxy.server.credentials; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
public record Credentials(CredentialsEntry emulated, CredentialsEntry real) | ||
{ | ||
public Credentials | ||
{ | ||
requireNonNull(emulated, "emulated is null"); | ||
requireNonNull(real, "real is null"); | ||
} | ||
|
||
public record CredentialsEntry(String accessKey, String secretKey) | ||
{ | ||
public CredentialsEntry | ||
{ | ||
requireNonNull(accessKey, "accessKey is null"); | ||
requireNonNull(secretKey, "secretKey is null"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
trino-s3-proxy/src/main/java/io/trino/s3/proxy/server/credentials/SigningController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.trino.s3.proxy.server.credentials; | ||
|
||
import com.google.inject.Inject; | ||
import io.trino.s3.proxy.server.minio.Signer; | ||
import io.trino.s3.proxy.server.minio.emulation.MinioRequest; | ||
import io.trino.s3.proxy.server.minio.emulation.MinioUrl; | ||
import jakarta.ws.rs.core.MultivaluedMap; | ||
|
||
import java.security.InvalidKeyException; | ||
import java.security.NoSuchAlgorithmException; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
public class SigningController | ||
{ | ||
private final CredentialsController credentialsController; | ||
|
||
@Inject | ||
public SigningController(CredentialsController credentialsController) | ||
{ | ||
this.credentialsController = requireNonNull(credentialsController, "credentialsController is null"); | ||
} | ||
|
||
public String signRequest(String method, MultivaluedMap<String, String> requestHeaders, String encodedPath, String encodedQuery, String region, String accessKey) | ||
{ | ||
// TODO | ||
Credentials credentials = credentialsController.credentials(accessKey).orElseThrow(); | ||
|
||
MinioUrl minioUrl = new MinioUrl(encodedPath, encodedQuery); | ||
MinioRequest minioRequest = new MinioRequest(requestHeaders, method, minioUrl); | ||
|
||
// TODO | ||
String sha256 = minioRequest.headerValue("x-amz-content-sha256").orElseThrow(); | ||
|
||
try { | ||
return Signer.signV4S3(minioRequest, region, accessKey, credentials.emulated().secretKey(), sha256); | ||
} | ||
catch (NoSuchAlgorithmException | InvalidKeyException e) { | ||
// TODO | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
145 changes: 145 additions & 0 deletions
145
trino-s3-proxy/src/main/java/io/trino/s3/proxy/server/minio/Digest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* | ||
* MinIO Java SDK for Amazon S3 Compatible Cloud Storage, (C) 2015 MinIO, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.trino.s3.proxy.server.minio; | ||
|
||
import com.google.common.io.BaseEncoding; | ||
|
||
import java.io.BufferedInputStream; | ||
import java.io.IOException; | ||
import java.io.RandomAccessFile; | ||
import java.nio.charset.StandardCharsets; | ||
import java.security.MessageDigest; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.util.Base64; | ||
import java.util.Locale; | ||
|
||
/** | ||
* Various global static functions used. | ||
*/ | ||
public final class Digest | ||
{ | ||
// MD5 hash of zero length byte array. | ||
public static final String ZERO_MD5_HASH = "1B2M2Y8AsgTpgAmY7PhCfg=="; | ||
// SHA-256 hash of zero length byte array. | ||
public static final String ZERO_SHA256_HASH = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; | ||
|
||
private Digest() {} | ||
|
||
/** | ||
* Returns MD5 hash of byte array. | ||
*/ | ||
public static String md5Hash(byte[] data, int length) | ||
throws NoSuchAlgorithmException | ||
{ | ||
MessageDigest md5Digest = MessageDigest.getInstance("MD5"); | ||
md5Digest.update(data, 0, length); | ||
return Base64.getEncoder().encodeToString(md5Digest.digest()); | ||
} | ||
|
||
/** | ||
* Returns SHA-256 hash of byte array. | ||
*/ | ||
public static String sha256Hash(byte[] data, int length) | ||
throws NoSuchAlgorithmException | ||
{ | ||
MessageDigest sha256Digest = MessageDigest.getInstance("SHA-256"); | ||
sha256Digest.update(data, 0, length); | ||
return BaseEncoding.base16().encode(sha256Digest.digest()).toLowerCase(Locale.US); | ||
} | ||
|
||
/** | ||
* Returns SHA-256 hash of given string. | ||
*/ | ||
public static String sha256Hash(String string) | ||
throws NoSuchAlgorithmException | ||
{ | ||
byte[] data = string.getBytes(StandardCharsets.UTF_8); | ||
return sha256Hash(data, data.length); | ||
} | ||
|
||
/** | ||
* Updated MessageDigest with bytes read from file and stream. | ||
*/ | ||
private static int updateDigests( | ||
Object inputStream, int len, MessageDigest sha256Digest, MessageDigest md5Digest) | ||
throws IOException, InsufficientDataException | ||
{ | ||
RandomAccessFile file = null; | ||
BufferedInputStream stream = null; | ||
if (inputStream instanceof RandomAccessFile) { | ||
file = (RandomAccessFile) inputStream; | ||
} | ||
else if (inputStream instanceof BufferedInputStream) { | ||
stream = (BufferedInputStream) inputStream; | ||
} | ||
|
||
// hold current position of file/stream to reset back to this position. | ||
long pos = 0; | ||
if (file != null) { | ||
pos = file.getFilePointer(); | ||
} | ||
else if (stream != null) { | ||
stream.mark(len); | ||
} | ||
|
||
// 16KiB buffer for optimization | ||
byte[] buf = new byte[16384]; | ||
int bytesToRead = buf.length; | ||
int bytesRead = 0; | ||
int totalBytesRead = 0; | ||
while (totalBytesRead < len) { | ||
if ((len - totalBytesRead) < bytesToRead) { | ||
bytesToRead = len - totalBytesRead; | ||
} | ||
|
||
if (file != null) { | ||
bytesRead = file.read(buf, 0, bytesToRead); | ||
} | ||
else if (stream != null) { | ||
bytesRead = stream.read(buf, 0, bytesToRead); | ||
} | ||
|
||
if (bytesRead < 0) { | ||
// reached EOF | ||
throw new InsufficientDataException( | ||
"Insufficient data. bytes read " + totalBytesRead + " expected " + len); | ||
} | ||
|
||
if (bytesRead > 0) { | ||
if (sha256Digest != null) { | ||
sha256Digest.update(buf, 0, bytesRead); | ||
} | ||
|
||
if (md5Digest != null) { | ||
md5Digest.update(buf, 0, bytesRead); | ||
} | ||
|
||
totalBytesRead += bytesRead; | ||
} | ||
} | ||
|
||
// reset back to saved position. | ||
if (file != null) { | ||
file.seek(pos); | ||
} | ||
else if (stream != null) { | ||
stream.reset(); | ||
} | ||
|
||
return totalBytesRead; | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
trino-s3-proxy/src/main/java/io/trino/s3/proxy/server/minio/InsufficientDataException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* MinIO Java SDK for Amazon S3 Compatible Cloud Storage, (C) 2015 MinIO, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.trino.s3.proxy.server.minio; | ||
|
||
/** | ||
* Thrown to indicate that reading given InputStream gets EOFException before reading given length. | ||
*/ | ||
public class InsufficientDataException | ||
extends MinioException | ||
{ | ||
/** | ||
* Constructs a new InsufficientDataException with given error message. | ||
*/ | ||
public InsufficientDataException(String message) | ||
{ | ||
super(message); | ||
} | ||
} |
Oops, something went wrong.