- report authentication error on the UI

- reduced visibility of some classes
This commit is contained in:
Sebastian Stenzel
2016-02-18 16:39:34 +01:00
parent 5a84228678
commit b85a110a24
10 changed files with 35 additions and 22 deletions

View File

@@ -28,7 +28,6 @@ import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.codec.binary.Hex;
import org.cryptomator.crypto.engine.FileContentCryptor;
import org.cryptomator.crypto.engine.FileContentEncryptor;
import org.cryptomator.io.ByteBuffers;
@@ -165,7 +164,6 @@ class FileContentEncryptorImpl implements FileContentEncryptor {
mac.update(nonce);
mac.update(ciphertextBuf);
byte[] authenticationCode = mac.doFinal();
Hex.encodeHexString(authenticationCode);
outBuf.put(authenticationCode);
// flip and return:

View File

@@ -35,7 +35,11 @@ public class CryptoFile extends CryptoNode implements File {
@Override
public ReadableFile openReadable() {
boolean authenticate = !fileSystem().delegate().shouldSkipAuthentication(toString());
return new CryptoReadableFile(cryptor.getFileContentCryptor(), forceGetPhysicalFile().openReadable(), authenticate);
return new CryptoReadableFile(cryptor.getFileContentCryptor(), forceGetPhysicalFile().openReadable(), authenticate, this::reportAuthError);
}
private void reportAuthError() {
fileSystem().delegate().authenticationFailed(this.toString());
}
@Override

View File

@@ -8,6 +8,7 @@
*******************************************************************************/
package org.cryptomator.filesystem.crypto;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
@@ -15,6 +16,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.cryptomator.crypto.engine.AuthenticationFailedException;
import org.cryptomator.crypto.engine.FileContentCryptor;
import org.cryptomator.crypto.engine.FileContentDecryptor;
import org.cryptomator.filesystem.ReadableFile;
@@ -29,15 +31,17 @@ class CryptoReadableFile implements ReadableFile {
private final FileContentCryptor cryptor;
private final ReadableFile file;
private final boolean authenticate;
private final Runnable onAuthError;
private FileContentDecryptor decryptor;
private Future<Void> readAheadTask;
private ByteBuffer bufferedCleartext = EMPTY_BUFFER;
public CryptoReadableFile(FileContentCryptor cryptor, ReadableFile file, boolean authenticate) {
public CryptoReadableFile(FileContentCryptor cryptor, ReadableFile file, boolean authenticate, Runnable onAuthError) {
this.header = ByteBuffer.allocate(cryptor.getHeaderSize());
this.cryptor = cryptor;
this.file = file;
this.authenticate = authenticate;
this.onAuthError = onAuthError;
file.position(0);
file.read(header);
header.flip();
@@ -58,6 +62,8 @@ class CryptoReadableFile implements ReadableFile {
return bytesRead;
} catch (InterruptedException e) {
throw new UncheckedIOException(new InterruptedIOException("Task interrupted while waiting for cleartext"));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@@ -78,9 +84,14 @@ class CryptoReadableFile implements ReadableFile {
readAheadTask = executorService.submit(new CiphertextReader(file, decryptor, header.remaining() + ciphertextPos));
}
private void bufferCleartext() throws InterruptedException {
private void bufferCleartext() throws InterruptedException, IOException {
if (!bufferedCleartext.hasRemaining()) {
bufferedCleartext = decryptor.cleartext();
try {
bufferedCleartext = decryptor.cleartext();
} catch (AuthenticationFailedException e) {
onAuthError.run();
throw new IOException("Failed to decrypt file due to an authentication error.", e);
}
}
}

View File

@@ -37,8 +37,11 @@ public class CryptoReadableFileTest {
}
}).thenThrow(new UncheckedIOException(new IOException("failed.")));
Runnable noop = () -> {
};
@SuppressWarnings("resource")
ReadableFile cryptoReadableFile = new CryptoReadableFile(fileContentCryptor, underlyingFile, true);
ReadableFile cryptoReadableFile = new CryptoReadableFile(fileContentCryptor, underlyingFile, true, noop);
cryptoReadableFile.read(ByteBuffer.allocate(1));
}

View File

@@ -23,7 +23,7 @@ import com.google.common.io.ByteStreams;
*
* @see {@link https://tools.ietf.org/html/rfc7233#section-4}
*/
public class DavFileWithRange extends DavFile {
class DavFileWithRange extends DavFile {
private final Pair<String, String> requestRange;

View File

@@ -19,7 +19,7 @@ import com.google.common.io.ByteStreams;
*
* @see {@link https://tools.ietf.org/html/rfc7233#section-4.2}
*/
public class DavFileWithUnsatisfiableRange extends DavFile {
class DavFileWithUnsatisfiableRange extends DavFile {
public DavFileWithUnsatisfiableRange(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, FileLocator node) throws DavException {
super(factory, lockManager, session, node);

View File

@@ -14,7 +14,7 @@ import org.apache.jackrabbit.webdav.lock.LockInfo;
import org.apache.jackrabbit.webdav.lock.Scope;
import org.apache.jackrabbit.webdav.lock.Type;
public class ExclusiveSharedLock extends AbstractActiveLock {
class ExclusiveSharedLock extends AbstractActiveLock {
private final String token;
private final Type type;

View File

@@ -30,7 +30,7 @@ import org.apache.jackrabbit.webdav.lock.Type;
import org.cryptomator.filesystem.jackrabbit.FileSystemResourceLocator;
import org.cryptomator.filesystem.jackrabbit.FolderLocator;
public class ExclusiveSharedLockManager implements LockManager {
class ExclusiveSharedLockManager implements LockManager {
private final ConcurrentMap<FileSystemResourceLocator, Map<String, ActiveLock>> lockedResources = new ConcurrentHashMap<>();

View File

@@ -27,7 +27,6 @@ import org.apache.jackrabbit.webdav.lock.Type;
import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
import org.cryptomator.filesystem.Folder;
import org.cryptomator.filesystem.jackrabbit.FileSystemResourceLocatorFactory;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.io.EofException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -87,16 +86,14 @@ public class WebDavServlet extends AbstractWebdavServlet {
@Override
protected void doGet(WebdavRequest request, WebdavResponse response, DavResource resource) throws IOException, DavException {
if (request.getHeader(HttpHeader.RANGE.asString()) != null) {
try {
super.doGet(request, response, resource);
} catch (EofException e) {
if (LOG.isDebugEnabled()) {
LOG.trace("Unexpected end of stream during delivery of partial content (client hung up).");
}
}
} else {
try {
super.doGet(request, response, resource);
} catch (EofException e) {
// Jetty EOF (other than IO EOF) is thrown when the connection is closed by the client.
// If the client is no longer interested in further content, we don't care.
if (LOG.isDebugEnabled()) {
LOG.trace("Unexpected end of stream during GET (client hung up).");
}
}
}

View File

@@ -33,7 +33,7 @@ public class InMemoryWebDavServer {
server.setPort(8080);
server.start();
FileSystem fileSystem = inMemoryFileSystem();
FileSystem fileSystem = cryptoFileSystem();
ServletContextHandler servlet = server.addServlet(fileSystem, URI.create("http://localhost:8080/foo"));
servlet.addFilter(LoggingHttpFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
servlet.start();