Explorar el Código

Using 0 prefix instead of _ suffix to mark directories

Sebastian Stenzel hace 9 años
padre
commit
07ba4eb537

+ 1 - 1
main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/Constants.java

@@ -5,7 +5,7 @@ public final class Constants {
 	private Constants() {
 	}
 
-	static final Integer CURRENT_VAULT_VERSION = 3;
+	static final Integer CURRENT_VAULT_VERSION = 4;
 
 	public static final int PAYLOAD_SIZE = 32 * 1024;
 	public static final int NONCE_SIZE = 16;

+ 2 - 1
main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FilenameCryptorImpl.java

@@ -26,7 +26,8 @@ import org.cryptomator.siv.SivMode;
 class FilenameCryptorImpl implements FilenameCryptor {
 
 	private static final BaseNCodec BASE32 = new Base32();
-	private static final Pattern BASE32_PATTERN = Pattern.compile("([A-Z0-9]{8})*[A-Z0-9=]{8}");
+	// https://tools.ietf.org/html/rfc4648#section-6
+	private static final Pattern BASE32_PATTERN = Pattern.compile("([A-Z2-7]{8})*[A-Z2-7=]{8}");
 	private static final ThreadLocal<MessageDigest> SHA1 = new ThreadLocalSha1();
 	private static final ThreadLocal<SivMode> AES_SIV = new ThreadLocal<SivMode>() {
 		@Override

+ 5 - 5
main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/ConflictResolver.java

@@ -1,6 +1,6 @@
 package org.cryptomator.filesystem.crypto;
 
-import static org.cryptomator.filesystem.crypto.Constants.DIR_SUFFIX;
+import static org.cryptomator.filesystem.crypto.Constants.DIR_PREFIX;
 
 import java.util.Optional;
 import java.util.UUID;
@@ -32,7 +32,7 @@ final class ConflictResolver {
 	}
 
 	public File resolveIfNecessary(File file) {
-		Matcher m = encryptedNamePattern.matcher(StringUtils.removeEnd(file.name(), DIR_SUFFIX));
+		Matcher m = encryptedNamePattern.matcher(StringUtils.removeStart(file.name(), DIR_PREFIX));
 		if (m.matches()) {
 			// full match, use file as is
 			return file;
@@ -47,11 +47,11 @@ final class ConflictResolver {
 
 	private File resolveConflict(File conflictingFile, MatchResult matchResult) {
 		String ciphertext = matchResult.group();
-		boolean isDirectory = conflictingFile.name().substring(matchResult.end()).startsWith(DIR_SUFFIX);
+		boolean isDirectory = conflictingFile.name().startsWith(DIR_PREFIX);
 		Optional<String> cleartext = nameDecryptor.apply(ciphertext);
 		if (cleartext.isPresent()) {
 			Folder folder = conflictingFile.parent().get();
-			File canonicalFile = folder.file(isDirectory ? ciphertext + DIR_SUFFIX : ciphertext);
+			File canonicalFile = folder.file(isDirectory ? DIR_PREFIX + ciphertext : ciphertext);
 			if (canonicalFile.exists()) {
 				// there must not be two directories pointing to the same directory id. In this case no human interaction is needed to resolve this conflict:
 				if (isDirectory && FileContents.UTF_8.readContents(canonicalFile).equals(FileContents.UTF_8.readContents(conflictingFile))) {
@@ -66,7 +66,7 @@ final class ConflictResolver {
 					conflictId = createConflictId();
 					String alternativeCleartext = cleartext.get() + " (Conflict " + conflictId + ")";
 					String alternativeCiphertext = nameEncryptor.apply(alternativeCleartext).get();
-					alternativeFile = folder.file(isDirectory ? alternativeCiphertext + DIR_SUFFIX : alternativeCiphertext);
+					alternativeFile = folder.file(isDirectory ? DIR_PREFIX + alternativeCiphertext : alternativeCiphertext);
 				} while (alternativeFile.exists());
 				LOG.info("Detected conflict {}:\n{}\n{}", conflictId, canonicalFile, conflictingFile);
 				conflictingFile.moveTo(alternativeFile);

+ 1 - 1
main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/Constants.java

@@ -11,6 +11,6 @@ public final class Constants {
 	static final String MASTERKEY_FILENAME = "masterkey.cryptomator";
 	static final String MASTERKEY_BACKUP_FILENAME = "masterkey.cryptomator.bkup";
 
-	static final String DIR_SUFFIX = "_";
+	static final String DIR_PREFIX = "0";
 
 }

+ 9 - 9
main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFolder.java

@@ -10,7 +10,7 @@ package org.cryptomator.filesystem.crypto;
 
 import static java.lang.String.format;
 import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.cryptomator.filesystem.crypto.Constants.DIR_SUFFIX;
+import static org.cryptomator.filesystem.crypto.Constants.DIR_PREFIX;
 
 import java.io.FileNotFoundException;
 import java.io.UncheckedIOException;
@@ -54,9 +54,9 @@ class CryptoFolder extends CryptoNode implements Folder {
 	@Override
 	protected Optional<String> encryptedName() {
 		if (parent().isPresent()) {
-			return parent().get().encryptChildName(name()).map(s -> s + DIR_SUFFIX);
+			return parent().get().encryptChildName(name()).map(s -> DIR_PREFIX + s);
 		} else {
-			return Optional.of(cryptor.getFilenameCryptor().encryptFilename(name()) + DIR_SUFFIX);
+			return Optional.of(DIR_PREFIX + cryptor.getFilenameCryptor().encryptFilename(name()));
 		}
 	}
 
@@ -121,20 +121,20 @@ class CryptoFolder extends CryptoNode implements Folder {
 
 	@Override
 	public Stream<CryptoFile> files() {
-		return nonConflictingFiles().map(File::name).filter(endsWithDirSuffix().negate()).map(this::decryptChildName).filter(Optional::isPresent).map(Optional::get).map(this::file);
+		return nonConflictingFiles().map(File::name).filter(startsWithDirPrefix().negate()).map(this::decryptChildName).filter(Optional::isPresent).map(Optional::get).map(this::file);
 	}
 
 	@Override
 	public Stream<CryptoFolder> folders() {
-		return nonConflictingFiles().map(File::name).filter(endsWithDirSuffix()).map(this::removeDirSuffix).map(this::decryptChildName).filter(Optional::isPresent).map(Optional::get).map(this::folder);
+		return nonConflictingFiles().map(File::name).filter(startsWithDirPrefix()).map(this::removeDirPrefix).map(this::decryptChildName).filter(Optional::isPresent).map(Optional::get).map(this::folder);
 	}
 
-	private Predicate<String> endsWithDirSuffix() {
-		return (String encryptedFolderName) -> StringUtils.endsWith(encryptedFolderName, DIR_SUFFIX);
+	private Predicate<String> startsWithDirPrefix() {
+		return (String encryptedFolderName) -> StringUtils.startsWith(encryptedFolderName, DIR_PREFIX);
 	}
 
-	private String removeDirSuffix(String encryptedFolderName) {
-		return StringUtils.removeEnd(encryptedFolderName, DIR_SUFFIX);
+	private String removeDirPrefix(String encryptedFolderName) {
+		return StringUtils.removeStart(encryptedFolderName, DIR_PREFIX);
 	}
 
 	@Override

+ 2 - 1
main/filesystem-crypto/src/test/java/org/cryptomator/filesystem/crypto/ConflictResolverTest.java

@@ -46,7 +46,7 @@ public class ConflictResolverTest {
 		unrelatedFile = Mockito.mock(File.class);
 
 		String canonicalFileName = encode.apply("test name").get();
-		String canonicalFolderName = canonicalFileName + Constants.DIR_SUFFIX;
+		String canonicalFolderName = Constants.DIR_PREFIX + canonicalFileName;
 		String conflictingFileName = canonicalFileName + " (version 2)";
 		String conflictingFolderName = canonicalFolderName + " (version 2)";
 		String unrelatedName = "notBa$e32!";
@@ -70,6 +70,7 @@ public class ConflictResolverTest {
 		Mockito.doReturn(Optional.of(folder)).when(unrelatedFile).parent();
 
 		Mockito.when(folder.file(Mockito.startsWith(canonicalFileName.substring(0, 8)))).thenReturn(resolved);
+		Mockito.when(folder.file(Mockito.startsWith(canonicalFolderName.substring(0, 8)))).thenReturn(resolved);
 		Mockito.when(folder.file(canonicalFileName)).thenReturn(canonicalFile);
 		Mockito.when(folder.file(canonicalFolderName)).thenReturn(canonicalFolder);
 		Mockito.when(folder.file(conflictingFileName)).thenReturn(conflictingFile);