- Hashage du mot de passe lors de la création du compte
- Localisation d'un problème empêchant de se connecter plusieurs fois (ca path est mis à NULL)
This commit is contained in:
parent
a2e86eb02d
commit
8746fa3b65
@ -13,21 +13,20 @@ import lightcontainer.repository.FileFrontEnd;
|
|||||||
import lightcontainer.repository.ProtocolRepositoryImpl;
|
import lightcontainer.repository.ProtocolRepositoryImpl;
|
||||||
import lightcontainer.repository.StoreProcessorRepository;
|
import lightcontainer.repository.StoreProcessorRepository;
|
||||||
import lightcontainer.storage.AppData;
|
import lightcontainer.storage.AppData;
|
||||||
|
import lightcontainer.storage.JsonAdapter;
|
||||||
|
import lightcontainer.storage.Repository;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
public class App {
|
public class App {
|
||||||
// Constant config server
|
|
||||||
// -- Unicast client port
|
|
||||||
private static final int UNICAST_PORT = 8000;
|
|
||||||
// -- Multicast listener ip, port
|
|
||||||
private static final String MULTICAST_IP = "226.66.66.1";
|
|
||||||
private static final int MULTICAST_PORT = 15502;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
setupVM();
|
setupVM();
|
||||||
|
Repository repositoryStorage = prepareStorage();
|
||||||
AppData appData = AppData.getInstance();
|
|
||||||
|
|
||||||
// Create all repository
|
// Create all repository
|
||||||
ClientHandlerRepository clientRep = new ClientHandlerRepository();
|
ClientHandlerRepository clientRep = new ClientHandlerRepository();
|
||||||
@ -49,8 +48,8 @@ public class App {
|
|||||||
protocolRep.addWriter(new SendfileRule());
|
protocolRep.addWriter(new SendfileRule());
|
||||||
|
|
||||||
FileFrontEnd ffe = new FileFrontEnd(clientRep, storeRep, protocolRep);
|
FileFrontEnd ffe = new FileFrontEnd(clientRep, storeRep, protocolRep);
|
||||||
new UnicastServerListener(ffe, clientRep, protocolRep, UNICAST_PORT);
|
new UnicastServerListener(ffe, clientRep, protocolRep, repositoryStorage, repositoryStorage.getUnicastPort());
|
||||||
new MulticastServerListener(ffe, storeRep, protocolRep, MULTICAST_IP, MULTICAST_PORT);
|
new MulticastServerListener(ffe, storeRep, protocolRep, repositoryStorage.getMulticastIp(), repositoryStorage.getMulticastPort());
|
||||||
|
|
||||||
// close repo et client et server.
|
// close repo et client et server.
|
||||||
|
|
||||||
@ -60,6 +59,17 @@ public class App {
|
|||||||
// storeRep.close();
|
// storeRep.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Repository prepareStorage() {
|
||||||
|
AppData appData = AppData.getInstance();
|
||||||
|
Repository repository = new Repository(
|
||||||
|
Paths.get("src", "main", "resources", "appdata.json").toAbsolutePath().toString(),
|
||||||
|
appData, new JsonAdapter()
|
||||||
|
);
|
||||||
|
|
||||||
|
repository.load();
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
|
||||||
private static void setupVM() {
|
private static void setupVM() {
|
||||||
System.setProperty("javax.net.ssl.keyStore","../ffe.labo.swilabus.com.p12");
|
System.setProperty("javax.net.ssl.keyStore","../ffe.labo.swilabus.com.p12");
|
||||||
System.setProperty("javax.net.ssl.keyStorePassword","labo2022");
|
System.setProperty("javax.net.ssl.keyStorePassword","labo2022");
|
||||||
|
@ -12,6 +12,8 @@ import lightcontainer.protocol.rules.reader.SignupRule;
|
|||||||
import lightcontainer.protocol.rules.writer.SignErrorRule;
|
import lightcontainer.protocol.rules.writer.SignErrorRule;
|
||||||
import lightcontainer.protocol.rules.writer.SignOkRule;
|
import lightcontainer.protocol.rules.writer.SignOkRule;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.net.ssl.SSLHandshakeException;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@ -64,6 +66,7 @@ public class ClientHandler implements Runnable, AutoCloseable {
|
|||||||
* @see PrintWriter
|
* @see PrintWriter
|
||||||
*/
|
*/
|
||||||
private void initClient() {
|
private void initClient() {
|
||||||
|
// Start the thread
|
||||||
try {
|
try {
|
||||||
this.reader = new BufferedReader(new InputStreamReader(
|
this.reader = new BufferedReader(new InputStreamReader(
|
||||||
this.client.getInputStream(),
|
this.client.getInputStream(),
|
||||||
@ -94,18 +97,18 @@ public class ClientHandler implements Runnable, AutoCloseable {
|
|||||||
System.out.println("Client: " + command);
|
System.out.println("Client: " + command);
|
||||||
} else {
|
} else {
|
||||||
repository.disconnect(this);
|
repository.disconnect(this);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolReader.ProtocolResult ruleResult = protocolRep.executeReader(context, command + "\r\n");
|
ProtocolReader.ProtocolResult ruleResult = protocolRep.executeReader(context, command + "\r\n");
|
||||||
if (ruleResult == null) {
|
if (ruleResult == null) {
|
||||||
repository.disconnect(this);
|
repository.disconnect(this);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkAccess(ruleResult)) {
|
if (checkAccess(ruleResult)) {
|
||||||
ruleResult.read(
|
ruleResult.read(this.client.getInputStream());
|
||||||
this.client.getInputStream()
|
|
||||||
);
|
|
||||||
ProtocolWriter.ProtocolResult writerCommand = ruleResult.getResultCommand();
|
ProtocolWriter.ProtocolResult writerCommand = ruleResult.getResultCommand();
|
||||||
|
|
||||||
if (ruleResult.getReceiver() == ProtocolReader.ResultCmdReceiver.STOREBACKEND) {
|
if (ruleResult.getReceiver() == ProtocolReader.ResultCmdReceiver.STOREBACKEND) {
|
||||||
@ -123,14 +126,23 @@ public class ClientHandler implements Runnable, AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
System.out.println(4);
|
||||||
accessDenied();
|
accessDenied();
|
||||||
}
|
}
|
||||||
} catch (IOException ignore) {
|
} catch (IOException ignore) {
|
||||||
ignore.printStackTrace();
|
ignore.printStackTrace();
|
||||||
repository.disconnect(this);
|
repository.disconnect(this);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.reader.close();
|
||||||
|
this.writer.close();
|
||||||
|
this.client.close();
|
||||||
|
System.out.printf("[CLIENT] %s s'est déconnecté\n", context.getLogin());
|
||||||
|
} catch (IOException ignored) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -178,6 +190,18 @@ public class ClientHandler implements Runnable, AutoCloseable {
|
|||||||
} catch (ClassCastException e2) { }
|
} catch (ClassCastException e2) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie s'il s'âgit d'une demande de déconnexion
|
||||||
|
* @param ruleResult
|
||||||
|
*/
|
||||||
|
private void checkSignError(ProtocolWriter.ProtocolResult ruleResult) {
|
||||||
|
if (ruleResult.getCommand().startsWith(SignErrorRule.NAME)) {
|
||||||
|
System.out.println("Pas pu connecter");
|
||||||
|
repository.disconnect(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permet au Client d'attendre la fin de la réalisation de sa tâche
|
* Permet au Client d'attendre la fin de la réalisation de sa tâche
|
||||||
*/
|
*/
|
||||||
@ -210,16 +234,12 @@ public class ClientHandler implements Runnable, AutoCloseable {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if (this.client_run) {
|
System.out.println("Call close");
|
||||||
try {
|
this.client_run = false;
|
||||||
this.client_run = false;
|
|
||||||
this.client.close();
|
|
||||||
System.out.printf("[CLIENT] %s s'est déconnecté\n", context.getLogin());
|
|
||||||
} catch (IOException ignored) { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLogin() {
|
public String getLogin() {
|
||||||
return this.context.getLogin();
|
return this.context.getLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package lightcontainer.domains.client;
|
package lightcontainer.domains.client;
|
||||||
|
|
||||||
import lightcontainer.storage.AppData;
|
import lightcontainer.storage.AppData;
|
||||||
|
import lightcontainer.storage.Repository;
|
||||||
import lightcontainer.storage.User;
|
import lightcontainer.storage.User;
|
||||||
import lightcontainer.utils.AES_GCM;
|
import lightcontainer.utils.AES_GCM;
|
||||||
|
import lightcontainer.utils.ShaHasher;
|
||||||
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -13,7 +15,8 @@ import java.util.LinkedList;
|
|||||||
*/
|
*/
|
||||||
public class Context {
|
public class Context {
|
||||||
|
|
||||||
private AppData appData;
|
private Repository repository;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Login de l'utilisateur
|
* Login de l'utilisateur
|
||||||
@ -21,8 +24,8 @@ public class Context {
|
|||||||
private String login;
|
private String login;
|
||||||
|
|
||||||
// Constructeur
|
// Constructeur
|
||||||
public Context(AppData appData) {
|
public Context(Repository repository) {
|
||||||
this.appData = appData;
|
this.repository = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -35,7 +38,12 @@ public class Context {
|
|||||||
public boolean createUser(String login, String password) {
|
public boolean createUser(String login, String password) {
|
||||||
try {
|
try {
|
||||||
String key = AES_GCM.generateSecretKey();
|
String key = AES_GCM.generateSecretKey();
|
||||||
if (this.appData.addUser(login, password, key)) {
|
|
||||||
|
ShaHasher hasher = new ShaHasher(password);
|
||||||
|
password = hasher.nextHashing();
|
||||||
|
String passwordSalt = hasher.getSalt();
|
||||||
|
|
||||||
|
if (this.repository.addUser(login, password, key, passwordSalt)) {
|
||||||
this.login = login;
|
this.login = login;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -59,9 +67,14 @@ public class Context {
|
|||||||
* @return TRUE si l'utilisateur a été authentifié
|
* @return TRUE si l'utilisateur a été authentifié
|
||||||
*/
|
*/
|
||||||
public boolean signIn(String login, String password) {
|
public boolean signIn(String login, String password) {
|
||||||
if (login.equals("aaaaa") && password.equals("aaaaa")) {
|
String passwordSalt = this.repository.getUserPasswordSalt(login);
|
||||||
this.login = login;
|
if (passwordSalt != null) {
|
||||||
return true;
|
ShaHasher hasher = new ShaHasher(password);
|
||||||
|
System.out.println(hasher.fromSalt(passwordSalt));
|
||||||
|
if (this.repository.verifyUser(login, hasher.fromSalt(passwordSalt))) {
|
||||||
|
this.login = login;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,11 @@ import lightcontainer.interfaces.ProtocolRepository;
|
|||||||
import lightcontainer.interfaces.UnicastCHR;
|
import lightcontainer.interfaces.UnicastCHR;
|
||||||
import lightcontainer.repository.FileFrontEnd;
|
import lightcontainer.repository.FileFrontEnd;
|
||||||
import lightcontainer.storage.AppData;
|
import lightcontainer.storage.AppData;
|
||||||
|
import lightcontainer.storage.Repository;
|
||||||
|
|
||||||
import javax.net.ssl.SSLServerSocket;
|
import javax.net.ssl.SSLServerSocket;
|
||||||
import javax.net.ssl.SSLServerSocketFactory;
|
import javax.net.ssl.SSLServerSocketFactory;
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
@ -21,12 +23,14 @@ public class UnicastServerListener implements Runnable {
|
|||||||
private ProtocolRepository protocolRep;
|
private ProtocolRepository protocolRep;
|
||||||
private final int server_port;
|
private final int server_port;
|
||||||
private boolean server_run;
|
private boolean server_run;
|
||||||
|
private Repository repositoryStorage;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public UnicastServerListener(FileFrontEnd ffe, UnicastCHR repository, ProtocolRepository protocolRep, int port) {
|
public UnicastServerListener(FileFrontEnd ffe, UnicastCHR repository, ProtocolRepository protocolRep, Repository repositoryStorage, int port) {
|
||||||
this.ffe = ffe;
|
this.ffe = ffe;
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.protocolRep = protocolRep;
|
this.protocolRep = protocolRep;
|
||||||
|
this.repositoryStorage = repositoryStorage;
|
||||||
this.server_port = port;
|
this.server_port = port;
|
||||||
this.server_run = false;
|
this.server_run = false;
|
||||||
repository.setServerListener(this);
|
repository.setServerListener(this);
|
||||||
@ -48,10 +52,10 @@ public class UnicastServerListener implements Runnable {
|
|||||||
this.server_run = true;
|
this.server_run = true;
|
||||||
while (this.server_run) {
|
while (this.server_run) {
|
||||||
// Accepting connection requests (blocking)
|
// Accepting connection requests (blocking)
|
||||||
Socket client = this.server.accept();
|
SSLSocket client = (SSLSocket) this.server.accept();
|
||||||
System.out.println("New Client");
|
|
||||||
// Create a new Handler client by passing these dependencies to it
|
// Create a new Handler client by passing these dependencies to it
|
||||||
ClientHandler clientHandler = new ClientHandler(this.repository, client, ffe, protocolRep, new Context(AppData.getInstance()));
|
ClientHandler clientHandler = new ClientHandler(this.repository, client, ffe, protocolRep, new Context(repositoryStorage));
|
||||||
// Add the client handler to its repository (clienthandlerrepository)
|
// Add the client handler to its repository (clienthandlerrepository)
|
||||||
this.repository.addClient(clientHandler);
|
this.repository.addClient(clientHandler);
|
||||||
// Start the thread
|
// Start the thread
|
||||||
|
@ -55,7 +55,7 @@ public class SignupRule extends ProtocolReader {
|
|||||||
result.setResultCommand(this.protocolRep.executeWriter(SignErrorRule.NAME), ResultCmdReceiver.CLIENT);
|
result.setResultCommand(this.protocolRep.executeWriter(SignErrorRule.NAME), ResultCmdReceiver.CLIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,8 +73,8 @@ public class AppData {
|
|||||||
*
|
*
|
||||||
* @return True if the user was added. False if a user with the same name already exists.
|
* @return True if the user was added. False if a user with the same name already exists.
|
||||||
*/
|
*/
|
||||||
public boolean addUser(String login, String password, String key) {
|
public boolean addUser(String login, String password, String key, String passwordSalt) {
|
||||||
User user = new User(login, password, key, new HashMap<>());
|
User user = new User(login, password, key, passwordSalt, new HashMap<>());
|
||||||
if (this.users.containsKey(user.getName())) {
|
if (this.users.containsKey(user.getName())) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -142,4 +142,13 @@ public class AppData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean verifyUser(String login, String password) {
|
||||||
|
User user = getUser(login);
|
||||||
|
return user != null && user.verifyPassword(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserPasswordSalt(String login) {
|
||||||
|
User user = getUser(login);
|
||||||
|
return user == null ? null : user.getPasswordSalt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ public class JsonAdapter implements Adapter {
|
|||||||
user.addProperty("name", current.getName());
|
user.addProperty("name", current.getName());
|
||||||
user.addProperty("password", current.getPassword());
|
user.addProperty("password", current.getPassword());
|
||||||
user.addProperty("aes_key", current.getAesKey());
|
user.addProperty("aes_key", current.getAesKey());
|
||||||
|
user.addProperty("passwordSalt", current.getPasswordSalt());
|
||||||
JsonArray files = new JsonArray();
|
JsonArray files = new JsonArray();
|
||||||
Iterator<File> fileIterator = current.fileIterator();
|
Iterator<File> fileIterator = current.fileIterator();
|
||||||
addFiles(fileIterator, files);
|
addFiles(fileIterator, files);
|
||||||
@ -90,7 +91,7 @@ public class JsonAdapter implements Adapter {
|
|||||||
AppData appData = AppData.getInstance();
|
AppData appData = AppData.getInstance();
|
||||||
appData.setAppConfig(appConfig);
|
appData.setAppConfig(appConfig);
|
||||||
for (User user : users) {
|
for (User user : users) {
|
||||||
appData.addUser(user.getName(), user.getPassword(), user.getAesKey());
|
appData.addUser(user.getName(), user.getPassword(), user.getAesKey(), "");
|
||||||
}
|
}
|
||||||
return appData;
|
return appData;
|
||||||
} catch (JsonParseException parseException) {
|
} catch (JsonParseException parseException) {
|
||||||
@ -105,10 +106,11 @@ public class JsonAdapter implements Adapter {
|
|||||||
String name = jsonUser.get("name").getAsString();
|
String name = jsonUser.get("name").getAsString();
|
||||||
String password = jsonUser.get("password").getAsString();
|
String password = jsonUser.get("password").getAsString();
|
||||||
String aeskey = jsonUser.get("aes_key").getAsString();
|
String aeskey = jsonUser.get("aes_key").getAsString();
|
||||||
|
String passwordSalt = jsonUser.get("passwordSalt").getAsString();
|
||||||
Map<String, File> userFiles = new HashMap<>();
|
Map<String, File> userFiles = new HashMap<>();
|
||||||
JsonArray jsonFiles = jsonUser.getAsJsonArray("files");
|
JsonArray jsonFiles = jsonUser.getAsJsonArray("files");
|
||||||
getFiles(userFiles, jsonFiles);
|
getFiles(userFiles, jsonFiles);
|
||||||
User user = new User(name, password, aeskey, userFiles);
|
User user = new User(name, password, aeskey, passwordSalt, userFiles);
|
||||||
users.add(user);
|
users.add(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public class Repository {
|
|||||||
*/
|
*/
|
||||||
public void save() {
|
public void save() {
|
||||||
if (filePath != null) {
|
if (filePath != null) {
|
||||||
String jsonAppData = adapter.toString();
|
String jsonAppData = adapter.toString(appData);
|
||||||
try (BufferedWriter bufferedWriter = Files.newBufferedWriter(Paths.get(filePath).toAbsolutePath(), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
try (BufferedWriter bufferedWriter = Files.newBufferedWriter(Paths.get(filePath).toAbsolutePath(), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
||||||
bufferedWriter.write(jsonAppData);
|
bufferedWriter.write(jsonAppData);
|
||||||
bufferedWriter.flush();
|
bufferedWriter.flush();
|
||||||
@ -39,8 +39,8 @@ public class Repository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addUser(String login, String password, String key) {
|
public boolean addUser(String login, String password, String key, String passwordSalt) {
|
||||||
if (appData.addUser(login, password, key)) {
|
if (appData.addUser(login, password, key, passwordSalt)) {
|
||||||
save();
|
save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -94,4 +94,24 @@ public class Repository {
|
|||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getUnicastPort() {
|
||||||
|
return appData.getAppConfig().getUnicastPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMulticastIp() {
|
||||||
|
return appData.getAppConfig().getMulticastIp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMulticastPort() {
|
||||||
|
return appData.getAppConfig().getMulticastPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean verifyUser(String login, String password) {
|
||||||
|
return appData.verifyUser(login, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserPasswordSalt(String login) {
|
||||||
|
return appData.getUserPasswordSalt(login);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,14 @@ public class User {
|
|||||||
private final String Name;
|
private final String Name;
|
||||||
private final String password;
|
private final String password;
|
||||||
private final String aesKey;
|
private final String aesKey;
|
||||||
|
private final String passwordSalt;
|
||||||
private final Map<String, File> files;
|
private final Map<String, File> files;
|
||||||
|
|
||||||
public User(String Name, String password, String aesKey, Map<String, File> files) {
|
public User(String Name, String password, String aesKey, String passwordSalt, Map<String, File> files) {
|
||||||
this.Name = Name;
|
this.Name = Name;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.aesKey = aesKey;
|
this.aesKey = aesKey;
|
||||||
|
this.passwordSalt = passwordSalt;
|
||||||
this.files = files;
|
this.files = files;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,6 +38,10 @@ public class User {
|
|||||||
return aesKey;
|
return aesKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPasswordSalt() {
|
||||||
|
return this.passwordSalt;
|
||||||
|
}
|
||||||
|
|
||||||
public Iterator<File> fileIterator() {
|
public Iterator<File> fileIterator() {
|
||||||
return files.values().iterator();
|
return files.values().iterator();
|
||||||
}
|
}
|
||||||
@ -77,4 +83,9 @@ public class User {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean verifyPassword(String password) {
|
||||||
|
return this.password.equals(password);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
78
app/src/main/java/lightcontainer/utils/ShaHasher.java
Normal file
78
app/src/main/java/lightcontainer/utils/ShaHasher.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package lightcontainer.utils;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permet de hasher du texte
|
||||||
|
*/
|
||||||
|
public class ShaHasher {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mot de passe non-hashé
|
||||||
|
*/
|
||||||
|
private final String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sallage appliqué sur le mot de passe précédement généré
|
||||||
|
*/
|
||||||
|
private byte[] salt;
|
||||||
|
|
||||||
|
public ShaHasher(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permet de demander un nouvel hashage sur le mot de passe
|
||||||
|
*
|
||||||
|
* @return Mot de passe hashé
|
||||||
|
* <p>
|
||||||
|
* Source : https://www.javaguides.net/2020/02/java-sha-384-hash-with-salt-example.html
|
||||||
|
*/
|
||||||
|
public String nextHashing() {
|
||||||
|
this.salt = generateSalt();
|
||||||
|
|
||||||
|
return fromSalt(getSalt());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String fromSalt(String passwordSalt) {
|
||||||
|
String generatedPassword = null;
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-384");
|
||||||
|
md.update(saltToByte(passwordSalt));
|
||||||
|
byte[] bytes = md.digest(password.getBytes(StandardCharsets.UTF_8));
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
|
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
|
||||||
|
}
|
||||||
|
generatedPassword = sb.toString();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return generatedPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private byte[] generateSalt() {
|
||||||
|
this.salt = new byte[16];
|
||||||
|
SecureRandom random = new SecureRandom();
|
||||||
|
|
||||||
|
random.nextBytes(salt);
|
||||||
|
return salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getSalt() {
|
||||||
|
Base64.Encoder b64Encoder = Base64.getEncoder();
|
||||||
|
return b64Encoder.encodeToString(this.salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] saltToByte(String salt) {
|
||||||
|
Base64.Decoder b64Decoder = Base64.getDecoder();
|
||||||
|
return b64Decoder.decode(salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
app/src/main/resources/appdata.json
Normal file
16
app/src/main/resources/appdata.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"unicast_port": 8000,
|
||||||
|
"multicast_ip": "226.66.66.1",
|
||||||
|
"multicast_port": 15502,
|
||||||
|
"network_interface": "My network interface",
|
||||||
|
"tls": true,
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"name": "benjamin",
|
||||||
|
"password": "08ffabe5c9577b4c809aa4eeee61c1859d4b5c44b0acfe9534a81ae48c3ba1a1d372f4a6bdaad2bb46483e0899cd765b",
|
||||||
|
"aes_key": "FaiZVQaeJF1qrbcOsM0yaUdzcmeIZ3p9R3NZwA5zPcs=",
|
||||||
|
"passwordSalt": "azA4e8Dtw+svxQWWnJ+rlA==",
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -2,9 +2,7 @@ package lightcontainer.storage;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
@ -26,7 +24,7 @@ public class JsonAdapterTests {
|
|||||||
storage.add("StorBackEnd1");
|
storage.add("StorBackEnd1");
|
||||||
File file1 = new File("File1", 15, "8d8d8d8d", storage);
|
File file1 = new File("File1", 15, "8d8d8d8d", storage);
|
||||||
appData.setAppConfig(appConfig);
|
appData.setAppConfig(appConfig);
|
||||||
appData.addUser("User1", "Password","djdjjdj");
|
appData.addUser("User1", "Password","djdjjdj", "");
|
||||||
appData.addFileFor(file1, "User1");
|
appData.addFileFor(file1, "User1");
|
||||||
JsonAdapter jsonAdapter = new JsonAdapter();
|
JsonAdapter jsonAdapter = new JsonAdapter();
|
||||||
//WHEN the adapter converts AppData to Json
|
//WHEN the adapter converts AppData to Json
|
||||||
|
@ -6,9 +6,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
@ -39,7 +37,7 @@ public class RepositoryTests {
|
|||||||
storage.add("StorBackEnd1");
|
storage.add("StorBackEnd1");
|
||||||
File file1 = new File("File1", 15, "8d8d8d8d", storage);
|
File file1 = new File("File1", 15, "8d8d8d8d", storage);
|
||||||
appData.setAppConfig(appConfig);
|
appData.setAppConfig(appConfig);
|
||||||
appData.addUser("User1", "Password", "djdjjdj");
|
appData.addUser("User1", "Password", "djdjjdj", "");
|
||||||
JsonAdapter jsonAdapter = new JsonAdapter();
|
JsonAdapter jsonAdapter = new JsonAdapter();
|
||||||
appData.addFileFor(file1, "User1");
|
appData.addFileFor(file1, "User1");
|
||||||
//WHEN Repository calls save method
|
//WHEN Repository calls save method
|
||||||
|
Loading…
Reference in New Issue
Block a user