New MAC authentication warning, preventing CCAs, but allowing to force-decrypt unauthentic files.

This commit is contained in:
Sebastian Stenzel
2015-07-09 17:16:43 +02:00
parent 9d2d847727
commit 685e347524
27 changed files with 276 additions and 157 deletions

View File

@@ -29,7 +29,6 @@ import org.apache.jackrabbit.webdav.lock.LockManager;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
import org.cryptomator.crypto.Cryptor;
import org.cryptomator.crypto.exceptions.DecryptFailedException;
import org.cryptomator.crypto.exceptions.MacAuthenticationFailedException;
import org.cryptomator.webdav.exceptions.IORuntimeException;
import org.eclipse.jetty.http.HttpHeader;
@@ -61,12 +60,12 @@ class EncryptedFile extends AbstractEncryptedNode implements FileConstants {
} catch (OverlappingFileLockException e) {
// file header currently locked, report -1 for unknown size.
properties.add(new DefaultDavProperty<Long>(DavPropertyName.GETCONTENTLENGTH, -1l));
} catch (IOException e) {
LOG.error("Error reading filesize " + filePath.toString(), e);
throw new IORuntimeException(e);
} catch (MacAuthenticationFailedException e) {
LOG.warn("Content length couldn't be determined due to MAC authentication violation.");
// don't add content length DAV property
} catch (IOException e) {
LOG.error("Error reading filesize " + filePath.toString(), e);
throw new IORuntimeException(e);
}
}
this.contentLength = contentLength;
@@ -107,16 +106,11 @@ class EncryptedFile extends AbstractEncryptedNode implements FileConstants {
outputContext.setContentLength(contentLength);
}
if (outputContext.hasStream()) {
cryptor.decryptFile(c, outputContext.getOutputStream());
final boolean authenticate = !cryptoWarningHandler.ignoreMac(getLocator().getResourcePath());
cryptor.decryptFile(c, outputContext.getOutputStream(), authenticate);
}
} catch (EOFException e) {
LOG.warn("Unexpected end of stream (possibly client hung up).");
} catch (MacAuthenticationFailedException e) {
LOG.warn("File integrity violation for " + getLocator().getResourcePath());
cryptoWarningHandler.macAuthFailed(getLocator().getResourcePath());
throw new IOException("Error decrypting file " + filePath.toString(), e);
} catch (DecryptFailedException e) {
throw new IOException("Error decrypting file " + filePath.toString(), e);
}
}
}

View File

@@ -14,8 +14,6 @@ import org.apache.jackrabbit.webdav.DavSession;
import org.apache.jackrabbit.webdav.io.OutputContext;
import org.apache.jackrabbit.webdav.lock.LockManager;
import org.cryptomator.crypto.Cryptor;
import org.cryptomator.crypto.exceptions.DecryptFailedException;
import org.cryptomator.crypto.exceptions.MacAuthenticationFailedException;
import org.eclipse.jetty.http.HttpHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,18 +60,13 @@ class EncryptedFilePart extends EncryptedFile {
try (final FileChannel c = FileChannel.open(filePath, StandardOpenOption.READ)) {
if (outputContext.hasStream()) {
cryptor.decryptRange(c, outputContext.getOutputStream(), range.getLeft(), rangeLength);
final boolean authenticate = !cryptoWarningHandler.ignoreMac(getLocator().getResourcePath());
cryptor.decryptRange(c, outputContext.getOutputStream(), range.getLeft(), rangeLength, authenticate);
}
} catch (EOFException e) {
if (LOG.isDebugEnabled()) {
LOG.trace("Unexpected end of stream during delivery of partial content (client hung up).");
}
} catch (MacAuthenticationFailedException e) {
LOG.warn("File integrity violation for " + getLocator().getResourcePath());
cryptoWarningHandler.macAuthFailed(getLocator().getResourcePath());
throw new IOException("Error decrypting file " + filePath.toString(), e);
} catch (DecryptFailedException e) {
throw new IOException("Error decrypting file " + filePath.toString(), e);
}
}

View File

@@ -8,21 +8,29 @@
******************************************************************************/
package org.cryptomator.webdav.jackrabbit;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavLocatorFactory;
import org.apache.jackrabbit.webdav.DavResource;
import org.apache.jackrabbit.webdav.DavResourceFactory;
import org.apache.jackrabbit.webdav.DavSessionProvider;
import org.apache.jackrabbit.webdav.WebdavRequest;
import org.apache.jackrabbit.webdav.WebdavResponse;
import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
import org.cryptomator.crypto.Cryptor;
import org.cryptomator.crypto.exceptions.MacAuthenticationFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WebDavServlet extends AbstractWebdavServlet {
private static final Logger LOG = LoggerFactory.getLogger(WebDavServlet.class);
private static final long serialVersionUID = 7965170007048673022L;
public static final String CFG_FS_ROOT = "cfg.fs.root";
private DavSessionProvider davSessionProvider;
@@ -81,4 +89,15 @@ public class WebDavServlet extends AbstractWebdavServlet {
this.davResourceFactory = resourceFactory;
}
@Override
protected void doGet(WebdavRequest request, WebdavResponse response, DavResource resource) throws IOException, DavException {
try {
super.doGet(request, response, resource);
} catch (MacAuthenticationFailedException e) {
LOG.warn("File integrity violation for " + resource.getLocator().getResourcePath());
cryptoWarningHandler.macAuthFailed(resource.getLocator().getResourcePath());
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
}
}
}