Ajout système de suppression en profondeur + hash file content.
This commit is contained in:
parent
f87c81aba4
commit
3ce850e04c
@ -67,7 +67,7 @@ public class App {
|
||||
protocolRep.addWriter(new SaveFileOkRule(repositoryStorage.getStoragePath()));
|
||||
protocolRep.addWriter(new SaveFileErrorRule(repositoryStorage.getStoragePath()));
|
||||
protocolRep.addWriter(new SendfileRule(repositoryStorage.getStoragePath()));
|
||||
protocolRep.addWriter(new GetFileErrorRule());
|
||||
protocolRep.addWriter(new GetFileErrorRule(repositoryStorage.getStoragePath()));
|
||||
protocolRep.addWriter(new EraseFileRule());
|
||||
protocolRep.addWriter(new RemoveFileErrorRule());
|
||||
protocolRep.addWriter(new RemoveFileOkRule());
|
||||
|
@ -47,7 +47,7 @@ public class FilelistRule extends ProtocolReader {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override//TODO ???
|
||||
protected <T extends ProtocolResult> T onError(Context context) {
|
||||
return super.onError(context);
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ public class RemoveFileRule extends ProtocolReader {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected RemoveFileRule.Result onExecuted(Context context, String... data) {
|
||||
RemoveFileRule.Result result = new RemoveFileRule.Result(context, data[FILENAME]);
|
||||
|
@ -3,10 +3,10 @@ package lightcontainer.protocol.rules.reader;
|
||||
import lightcontainer.domains.client.Context;
|
||||
import lightcontainer.interfaces.ProtocolRepository;
|
||||
import lightcontainer.protocol.ProtocolReader;
|
||||
import lightcontainer.protocol.rules.writer.GetFileErrorRule;
|
||||
import lightcontainer.protocol.rules.writer.GetFileOkRule;
|
||||
import lightcontainer.protocol.rules.writer.SaveFileErrorRule;
|
||||
import lightcontainer.utils.FileReceiver;
|
||||
import lightcontainer.utils.FileSender;
|
||||
import lightcontainer.utils.SHA;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
@ -59,11 +59,17 @@ public class RetrieveOkRule extends ProtocolReader {
|
||||
public void read(InputStream reader) {
|
||||
super.read(reader);
|
||||
System.out.println("Récupération du fichier du SBE");
|
||||
|
||||
FileReceiver fileReceiver = new FileReceiver(storagePath);
|
||||
fileReceiver.receiveFile(reader, this.filename, this.filesize);
|
||||
|
||||
// TODO fingerprint <!!!!!!>
|
||||
try {
|
||||
FileReceiver fileReceiver = new FileReceiver(storagePath);
|
||||
if (!fileReceiver.receiveFile(reader, this.filename, this.filesize)) {
|
||||
throw new IllegalStateException("Bad file reception");
|
||||
}
|
||||
if (SHA.hashFile(storagePath, this.filename).equals(this.hashedFileContent)) {
|
||||
throw new IllegalStateException("File hash content are not equals");
|
||||
}
|
||||
} catch (IllegalStateException|SHA.ShaException e) {
|
||||
this.setResultCommand(protocolRep.executeWriter(getContext(), GetFileErrorRule.NAME), ResultCmdReceiver.CLIENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +95,7 @@ public class RetrieveOkRule extends ProtocolReader {
|
||||
@Override
|
||||
protected ProtocolReader.ProtocolResult onError(Context context) {
|
||||
ProtocolResult result = new ProtocolResult(context);
|
||||
result.setResultCommand(protocolRep.executeWriter(context, SaveFileErrorRule.NAME), ResultCmdReceiver.CLIENT);
|
||||
result.setResultCommand(protocolRep.executeWriter(context, GetFileErrorRule.NAME), ResultCmdReceiver.CLIENT);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,7 @@ import lightcontainer.protocol.ProtocolReader;
|
||||
import lightcontainer.protocol.rules.writer.SaveFileErrorRule;
|
||||
import lightcontainer.protocol.rules.writer.SaveFileOkRule;
|
||||
import lightcontainer.protocol.rules.writer.SendfileRule;
|
||||
import lightcontainer.utils.AES_GCM;
|
||||
import lightcontainer.utils.FileReceiver;
|
||||
import lightcontainer.utils.SHA;
|
||||
import lightcontainer.utils.ShaHasher;
|
||||
import lightcontainer.utils.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -85,10 +82,7 @@ public class SavefileRule extends ProtocolReader {
|
||||
|
||||
this.setResultCommand(protocolRep.executeWriter(getContext(), SendfileRule.NAME, this.filename, String.valueOf(encryptedFileSize), fileHash), ResultCmdReceiver.STOREBACKEND);
|
||||
} catch (IOException | SHA.ShaException e) {
|
||||
// TODO : Supprimer le fichier
|
||||
System.out.println("HEYHEYHEYHEYHEY OHOHOH");
|
||||
this.setResultCommand(protocolRep.executeWriter(getContext(), SaveFileErrorRule.NAME), ResultCmdReceiver.CLIENT);
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
this.setResultCommand(protocolRep.executeWriter(getContext(), SaveFileErrorRule.NAME), ResultCmdReceiver.CLIENT);
|
||||
|
@ -5,10 +5,6 @@ import lightcontainer.interfaces.ProtocolRepository;
|
||||
import lightcontainer.protocol.ProtocolReader;
|
||||
import lightcontainer.protocol.rules.writer.SaveFileOkRule;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Règle permettant de de confirmer la sauvegrade d'un fichier.
|
||||
*/
|
||||
@ -27,12 +23,10 @@ public class SendOkRule extends ProtocolReader {
|
||||
this.protocolRep = protocolRep;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ProtocolResult onExecuted(Context context, String... data) {
|
||||
ProtocolReader.ProtocolResult result = new ProtocolReader.ProtocolResult(context);
|
||||
result.setResultCommand(protocolRep.executeWriter(context, SaveFileOkRule.NAME), ResultCmdReceiver.CLIENT);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package lightcontainer.protocol.rules.writer;
|
||||
|
||||
import lightcontainer.domains.client.Context;
|
||||
import lightcontainer.protocol.ProtocolWriter;
|
||||
import lightcontainer.utils.DeepFileEraser;
|
||||
|
||||
/**
|
||||
* Règle utilisé dans le cas ou une erreur survient lors
|
||||
@ -11,8 +13,22 @@ public class GetFileErrorRule extends ProtocolWriter {
|
||||
private static final String PATTERN = "^GETFILE_ERROR\r\n$";
|
||||
public static final String NAME = "GETFILE_ERROR";
|
||||
|
||||
// Variables
|
||||
private final String storagePath;
|
||||
|
||||
// Constructors
|
||||
public GetFileErrorRule() {
|
||||
public GetFileErrorRule(String storagePath) {
|
||||
super(NAME, PATTERN);
|
||||
this.storagePath = storagePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProtocolResult onExecuted(Context context, String... data) {
|
||||
// Delete the file
|
||||
try {
|
||||
DeepFileEraser.eraseFile(String.format("%s/%s", storagePath, context.getDataString("hashedFileName")));
|
||||
} catch (DeepFileEraser.DeepFileEraserException ignore) { }
|
||||
// Return new protocol result
|
||||
return new ProtocolResult(context);
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,11 @@ package lightcontainer.protocol.rules.writer;
|
||||
|
||||
import lightcontainer.domains.client.Context;
|
||||
import lightcontainer.protocol.ProtocolWriter;
|
||||
import lightcontainer.utils.DeepFileEraser;
|
||||
import lightcontainer.utils.FileSender;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class GetFileOkRule extends ProtocolWriter {
|
||||
// Constants
|
||||
@ -46,7 +45,6 @@ public class GetFileOkRule extends ProtocolWriter {
|
||||
public void write(OutputStream writer) throws IOException {
|
||||
System.out.printf("Sauvegarde du fichier : %s %d\n", this.filename, this.filesize);
|
||||
|
||||
System.out.println("Encrypted size for parsing: " + getContext().getDataInt("encryptedFileSize")+" normal: "+getContext().getDataInt("fileSize"));
|
||||
FileSender fileSender = new FileSender(storagePath);
|
||||
fileSender.sendFile(
|
||||
getContext().getDataString("hashedFileName"),
|
||||
@ -57,8 +55,8 @@ public class GetFileOkRule extends ProtocolWriter {
|
||||
);
|
||||
|
||||
try {
|
||||
Files.deleteIfExists(Path.of(String.format("%s/%s", storagePath, getContext().getDataString("hashedFileName"))));
|
||||
} catch (IOException ignore) { }
|
||||
DeepFileEraser.eraseFile(String.format("%s/%s", storagePath, getContext().getDataString("hashedFileName")));
|
||||
} catch (DeepFileEraser.DeepFileEraserException ignore) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,9 @@ package lightcontainer.protocol.rules.writer;
|
||||
|
||||
import lightcontainer.domains.client.Context;
|
||||
import lightcontainer.protocol.ProtocolWriter;
|
||||
import lightcontainer.utils.DeepFileEraser;
|
||||
import lightcontainer.utils.ShaHasher;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Règle signifiant que la sauvegarde d'un fichier a échoué
|
||||
*/
|
||||
@ -32,13 +29,9 @@ public class SaveFileErrorRule extends ProtocolWriter {
|
||||
// Suppression du fichier temporaire dans le stockage du FFE
|
||||
ShaHasher hasher = new ShaHasher(context.getLogin() + "_" + context.getDataString("fileName"));
|
||||
try {
|
||||
Files.deleteIfExists(Path.of(
|
||||
String.format("%s/%s", this.storagePath,
|
||||
hasher.fromSalt(hasher.saltToByte(context.getDataString("fileNameSalt")))
|
||||
)
|
||||
));
|
||||
} catch (IOException e) {}
|
||||
|
||||
DeepFileEraser.eraseFile(String.format("%s/%s", this.storagePath,
|
||||
hasher.fromSalt(hasher.saltToByte(context.getDataString("fileNameSalt")))));
|
||||
} catch (DeepFileEraser.DeepFileEraserException ignore) { }
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,7 @@ package lightcontainer.protocol.rules.writer;
|
||||
|
||||
import lightcontainer.domains.client.Context;
|
||||
import lightcontainer.protocol.ProtocolWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import lightcontainer.utils.DeepFileEraser;
|
||||
|
||||
/**
|
||||
* Règle signifiant que la sauvegarde d'un fichier fût un succès
|
||||
@ -32,9 +29,10 @@ public class SaveFileOkRule extends ProtocolWriter {
|
||||
|
||||
// Suppression du fichier temporaire dans le stockage du FFE
|
||||
String hashedFileName = context.getHashedFileName(context.getDataString("fileName"));
|
||||
|
||||
try {
|
||||
Files.deleteIfExists(Path.of(String.format("%s/%s", storagePath, hashedFileName)));
|
||||
} catch (IOException ignore) {}
|
||||
DeepFileEraser.eraseFile(String.format("%s/%s", storagePath, hashedFileName));
|
||||
} catch (DeepFileEraser.DeepFileEraserException ignore) { }
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
148
app/src/main/java/lightcontainer/utils/DeepFileEraser.java
Normal file
148
app/src/main/java/lightcontainer/utils/DeepFileEraser.java
Normal file
@ -0,0 +1,148 @@
|
||||
package lightcontainer.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* DeepFileEraser - Secure file remover
|
||||
*
|
||||
* @since 1.0
|
||||
* @version 1.0
|
||||
*
|
||||
* @author Jérémi Nihart <contact@endmove.eu>
|
||||
*/
|
||||
public class DeepFileEraser {
|
||||
public static final int DFE_BUFFER_DEFAULT_SIZE = 1024; // Default buffer size
|
||||
public static final int DFE_BUFFER_MINIMUM_SIZE = 250; // Minimum buffer size
|
||||
public static final int DFE_BASE_DEFAULT_FILL_VALUE = 0; // Filling value of the initialisation phase
|
||||
public static final int DFE_STEP_MIN_FILL_VALUE = 0; // Minimum filling value of a writing phase
|
||||
public static final int DFE_STEP_MAX_FILL_VALUE = 15; // Maximum filling value of a writing phase
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
System.out.println(random(1, 3));
|
||||
try {
|
||||
eraseFile("D:\\lol");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a number randomly.
|
||||
*
|
||||
* @param min Minimal value (included)
|
||||
* @param max Maximal value (included)
|
||||
*
|
||||
* @return Random generated number.
|
||||
*/
|
||||
private static int random(int min, int max) {
|
||||
return min + (int)(Math.random() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple remove operation.
|
||||
*
|
||||
* @param target File object on which to operate.
|
||||
* @param length File size.
|
||||
*
|
||||
* @throws DeepFileEraserException Exception if an error occur.
|
||||
*/
|
||||
private static void eraseBase(File target, long length) throws DeepFileEraserException {
|
||||
byte[] buffer = new byte[DFE_BUFFER_DEFAULT_SIZE];
|
||||
long wroteLength = 0;
|
||||
try (OutputStream out = new FileOutputStream(target)) {
|
||||
Arrays.fill(buffer, (byte)DFE_BASE_DEFAULT_FILL_VALUE);
|
||||
while (wroteLength < length) {
|
||||
if (wroteLength + buffer.length > length) {
|
||||
buffer = new byte[(int)(length-wroteLength)];
|
||||
Arrays.fill(buffer, (byte)DFE_BASE_DEFAULT_FILL_VALUE);
|
||||
}
|
||||
out.write(buffer);
|
||||
wroteLength += buffer.length;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new DeepFileEraserException(e, "Error while the Base erasing step.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deep remove operation.
|
||||
*
|
||||
* @param target File object on which to operate.
|
||||
* @param length File size.
|
||||
*
|
||||
* @throws DeepFileEraserException Exception if an error occur.
|
||||
*/
|
||||
private static void eraseStep(File target, long length) throws DeepFileEraserException {
|
||||
byte[] buffer = new byte[random(DFE_BUFFER_MINIMUM_SIZE, DFE_BUFFER_DEFAULT_SIZE)];
|
||||
long wroteLength = 0;
|
||||
try (OutputStream out = new FileOutputStream(target)) {
|
||||
while(wroteLength < length) {
|
||||
if (wroteLength + buffer.length > length) buffer = new byte[(int)(length-wroteLength)];
|
||||
Arrays.fill(buffer, (byte) random(DFE_STEP_MIN_FILL_VALUE, DFE_STEP_MAX_FILL_VALUE));
|
||||
out.write(buffer);
|
||||
wroteLength += buffer.length;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new DeepFileEraserException(e, "Error while the Step erasing step.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase a file deeply.
|
||||
* default deeply level = 5.
|
||||
*
|
||||
* @param filePath Path of the file.
|
||||
*
|
||||
* @throws DeepFileEraserException Exception if an error occur.
|
||||
*/
|
||||
public static void eraseFile(String filePath) throws DeepFileEraserException {
|
||||
eraseFile(filePath, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase a file deeply.
|
||||
*
|
||||
* @param filePath Path of the file.
|
||||
* @param depthLevel Erasure level (the higher the number, the longer and more secure the erasure).
|
||||
*
|
||||
* @throws DeepFileEraserException Exception if an error occur.
|
||||
*/
|
||||
public static void eraseFile(String filePath, int depthLevel) throws DeepFileEraserException {
|
||||
// Init
|
||||
File target = new File(filePath);
|
||||
if (target.exists()) {
|
||||
long targetSize = target.length();
|
||||
// Base write
|
||||
eraseBase(target, targetSize);
|
||||
// Deep write
|
||||
for (int i = 0; i < depthLevel; i++) eraseStep(target, targetSize);
|
||||
// Delete file
|
||||
target.delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal Error from DeepFileEraser encryption Class
|
||||
*/
|
||||
public static class DeepFileEraserException extends Exception {
|
||||
// Constant
|
||||
private static final long serialVersionUID = -158979547897543145L;
|
||||
|
||||
/**
|
||||
* Constructor of DeepFileEraserException,
|
||||
* which propagates the error triggering
|
||||
* a crash of the erasing file system with
|
||||
* a chosen detail message.
|
||||
*
|
||||
* @param e Previous exception throwable.
|
||||
* @param msg The detail message.
|
||||
*/
|
||||
public DeepFileEraserException(Throwable e, String msg) {
|
||||
super(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
@ -115,5 +115,4 @@ public class SHA {
|
||||
super(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user