diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageService.java b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageService.java index 78eee24a34de5..3337c07e6eece 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageService.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageService.java @@ -62,4 +62,23 @@ void moveBlob(String account, LocationMode mode, String container, String source void writeBlob(String account, LocationMode mode, String container, String blobName, InputStream inputStream, long blobSize) throws URISyntaxException, StorageException; + + static InputStream giveSocketPermissionsToStream(InputStream stream) { + return new InputStream() { + @Override + public int read() throws IOException { + return SocketAccess.doPrivilegedIOException(stream::read); + } + + @Override + public int read(byte[] b) throws IOException { + return SocketAccess.doPrivilegedIOException(() -> stream.read(b)); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + return SocketAccess.doPrivilegedIOException(() -> stream.read(b, off, len)); + } + }; + } } diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageServiceImpl.java b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageServiceImpl.java index 2b8992386eb2d..f21dbdfd269f4 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageServiceImpl.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageServiceImpl.java @@ -25,6 +25,7 @@ import com.microsoft.azure.storage.RetryExponentialRetry; import com.microsoft.azure.storage.RetryPolicy; import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.blob.BlobInputStream; import com.microsoft.azure.storage.blob.BlobListingDetails; import com.microsoft.azure.storage.blob.BlobProperties; import com.microsoft.azure.storage.blob.CloudBlobClient; @@ -249,12 +250,14 @@ public void deleteBlob(String account, LocationMode mode, String container, Stri } @Override - public InputStream getInputStream(String account, LocationMode mode, String container, String blob) - throws URISyntaxException, StorageException { + public InputStream getInputStream(String account, LocationMode mode, String container, String blob) throws URISyntaxException, + StorageException { logger.trace("reading container [{}], blob [{}]", container, blob); CloudBlobClient client = this.getSelectedClient(account, mode); CloudBlockBlob blockBlobReference = client.getContainerReference(container).getBlockBlobReference(blob); - return SocketAccess.doPrivilegedException(() -> blockBlobReference.openInputStream(null, null, generateOperationContext(account))); + BlobInputStream is = SocketAccess.doPrivilegedException(() -> + blockBlobReference.openInputStream(null, null, generateOperationContext(account))); + return AzureStorageService.giveSocketPermissionsToStream(is); } @Override diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/SocketAccess.java b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/SocketAccess.java index c4db24a97e958..da8b85430067c 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/SocketAccess.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/SocketAccess.java @@ -39,6 +39,15 @@ public final class SocketAccess { private SocketAccess() {} + public static T doPrivilegedIOException(PrivilegedExceptionAction operation) throws IOException { + SpecialPermission.check(); + try { + return AccessController.doPrivileged(operation); + } catch (PrivilegedActionException e) { + throw (IOException) e.getCause(); + } + } + public static T doPrivilegedException(PrivilegedExceptionAction operation) throws StorageException, URISyntaxException { SpecialPermission.check(); try { diff --git a/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageServiceMock.java b/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageServiceMock.java index 6dfe2db628013..68b84594d62ca 100644 --- a/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageServiceMock.java +++ b/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageServiceMock.java @@ -32,8 +32,10 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.net.SocketPermission; import java.net.URISyntaxException; import java.nio.file.NoSuchFileException; +import java.security.AccessController; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -81,7 +83,7 @@ public InputStream getInputStream(String account, LocationMode mode, String cont if (!blobExists(account, mode, container, blob)) { throw new NoSuchFileException("missing blob [" + blob + "]"); } - return new ByteArrayInputStream(blobs.get(blob).toByteArray()); + return AzureStorageService.giveSocketPermissionsToStream(new PermissionRequiringInputStream(blobs.get(blob).toByteArray())); } @Override @@ -170,4 +172,29 @@ public static boolean endsWithIgnoreCase(String str, String suffix) { String lcPrefix = suffix.toLowerCase(Locale.ROOT); return lcStr.equals(lcPrefix); } + + private static class PermissionRequiringInputStream extends ByteArrayInputStream { + + private PermissionRequiringInputStream(byte[] buf) { + super(buf); + } + + @Override + public synchronized int read() { + AccessController.checkPermission(new SocketPermission("*", "connect")); + return super.read(); + } + + @Override + public int read(byte[] b) throws IOException { + AccessController.checkPermission(new SocketPermission("*", "connect")); + return super.read(b); + } + + @Override + public synchronized int read(byte[] b, int off, int len) { + AccessController.checkPermission(new SocketPermission("*", "connect")); + return super.read(b, off, len); + } + } }