From daa798e957404540d7165d9a8ae543d080f962d9 Mon Sep 17 00:00:00 2001
From: Felix Sidokhine <felix.sidokhine@randstad.ca>
Date: Tue, 12 May 2020 13:56:08 +0300
Subject: [PATCH] realized protection for install and api

---
 .../jams/authmodule/RegisterUserFlow.java     |  6 ++
 .../authmodule/UserAuthenticationModule.java  | 10 +--
 jams-ca/src/main/java/module-info.java        |  1 +
 .../main/java/net/jami/jams/ca/JamsCA.java    | 24 +++++---
 .../jami/jams/ca/workers/crl/CRLWorker.java   |  2 +-
 .../ca/workers/csr/CertificateWorker.java     |  6 +-
 .../workers/csr/builders/DeviceBuilder.java   |  4 +-
 .../csr/builders/SystemAccountBuilder.java    |  6 +-
 .../ca/workers/csr/builders/UserBuilder.java  |  2 +-
 .../builders/SystemAccountBuilderTest.java    | 18 ++++--
 jams-common/src/main/java/module-info.java    |  1 +
 .../authmodule/AuthenticationResult.java      |  3 -
 .../cryptoengineapi/CertificateAuthority.java |  2 +-
 .../CertificateAuthorityConfig.java           | 14 +++++
 .../jams/common/objects/roots/X509Entity.java |  1 +
 .../jams/common/server/ServerSettings.java    | 14 +++++
 jams-server/src/main/java/module-info.java    |  1 +
 .../java/net/jami/jams/server/Server.java     | 61 +++++++------------
 .../jami/jams/server/core/TomcatLauncher.java |  2 -
 .../servlets/api/auth/login/LoginServlet.java |  3 +-
 .../api/install/StartInstallServlet.java      | 61 +++++++++++++++++++
 .../server/servlets/filters/APIFilter.java    | 26 ++++----
 .../servlets/filters/InstallFilter.java       | 35 +++++++++++
 .../jams/server/startup/AuthModuleLoader.java |  2 -
 .../server/startup/CryptoEngineLoader.java    |  4 +-
 .../resources/webapp/images/add-user-img.svg  |  4 +-
 .../resources/webapp/images/exclamation.svg   |  4 +-
 .../resources/webapp/images/logo/logo-sfl.svg |  3 +-
 .../connector/service/UserProfileService.java |  1 -
 29 files changed, 225 insertions(+), 96 deletions(-)
 create mode 100644 jams-common/src/main/java/net/jami/jams/common/cryptoengineapi/CertificateAuthorityConfig.java
 create mode 100644 jams-common/src/main/java/net/jami/jams/common/server/ServerSettings.java
 create mode 100644 jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java
 create mode 100644 jams-server/src/main/java/net/jami/jams/server/servlets/filters/InstallFilter.java

diff --git a/authentication-module/src/main/java/net/jami/jams/authmodule/RegisterUserFlow.java b/authentication-module/src/main/java/net/jami/jams/authmodule/RegisterUserFlow.java
index 01468c48..af17ecf3 100644
--- a/authentication-module/src/main/java/net/jami/jams/authmodule/RegisterUserFlow.java
+++ b/authentication-module/src/main/java/net/jami/jams/authmodule/RegisterUserFlow.java
@@ -1,5 +1,7 @@
 package net.jami.jams.authmodule;
 
+import lombok.extern.slf4j.Slf4j;
+import net.jami.jams.common.objects.roots.X509Fields;
 import net.jami.jams.common.objects.user.User;
 import net.jami.jams.dht.DeviceReceiptGenerator;
 import net.jami.jams.dht.ETHAddressGenerator;
@@ -7,11 +9,14 @@ import net.jami.jams.dht.ETHAddressGenerator;
 import static net.jami.jams.authmodule.UserAuthenticationModule.certificateAuthority;
 import static net.jami.jams.authmodule.UserAuthenticationModule.datastore;
 
+@Slf4j
 public class RegisterUserFlow {
 
     //Get the CA, sign, return the Jami ID.
     public static void createUser(User user){
         //This generates the X509 Fields we need.
+        user.setX509Fields(new X509Fields());
+        user.getX509Fields().setCommonName(user.getUsername());
         user = certificateAuthority.getSignedCertificate(user);
         String[] ethKeyPair = null;
         while(ethKeyPair == null){
@@ -21,5 +26,6 @@ public class RegisterUserFlow {
         user.setEthKey(ethKeyPair[1]);
         user.setJamiId(DeviceReceiptGenerator.generateJamiId(user));
         datastore.getUserDao().storeObject(user);
+        log.info("Create the user " + user.getUsername() + " because he did not exist before!");
     }
 }
diff --git a/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java b/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java
index 7b4bf510..2a99fb96 100644
--- a/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java
+++ b/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java
@@ -1,17 +1,15 @@
 package net.jami.jams.authmodule;
 
-import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
 import net.jami.datastore.main.DataStore;
-import net.jami.jams.common.authmodule.AuthModuleKey;
 import net.jami.jams.common.authentication.AuthenticationSource;
 import net.jami.jams.common.authentication.AuthenticationSourceType;
-import net.jami.jams.common.authmodule.AuthenticationResult;
+import net.jami.jams.common.authmodule.AuthModuleKey;
 import net.jami.jams.common.authmodule.AuthenticationModule;
+import net.jami.jams.common.authmodule.AuthenticationResult;
 import net.jami.jams.common.cryptoengineapi.CertificateAuthority;
 import net.jami.jams.common.dao.StatementElement;
 import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.objects.roots.X509Fields;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.User;
 import net.jami.jams.common.utils.LibraryLoader;
@@ -21,7 +19,6 @@ import java.util.HashMap;
 
 
 @Slf4j
-@Getter
 public class UserAuthenticationModule implements AuthenticationModule {
     //This contains the DOMAIN-SOURCE.
     //In general there is at most 2 here.
@@ -83,9 +80,6 @@ public class UserAuthenticationModule implements AuthenticationModule {
                 user.setAccessLevel(AccessLevel.USER);
                 user.setRealm(key.getRealm());
                 user.setUserType(key.getType());
-                X509Fields x509Fields = new X509Fields();
-                x509Fields.setCommonName(username);
-                user.setX509Fields(x509Fields);
                 RegisterUserFlow.createUser(user);
                 res.setToken(tokenController.generateToken(user.getUsername(),res.getExpires()));
                 res.setAuthenticated(true);
diff --git a/jams-ca/src/main/java/module-info.java b/jams-ca/src/main/java/module-info.java
index 0dcb0ebe..6557f6e9 100644
--- a/jams-ca/src/main/java/module-info.java
+++ b/jams-ca/src/main/java/module-info.java
@@ -6,4 +6,5 @@ module jams.ca {
     requires lombok;
     requires org.slf4j;
     requires org.bouncycastle.provider;
+    requires jsoniter;
 }
\ No newline at end of file
diff --git a/jams-ca/src/main/java/net/jami/jams/ca/JamsCA.java b/jams-ca/src/main/java/net/jami/jams/ca/JamsCA.java
index 790ca69b..cd207c32 100644
--- a/jams-ca/src/main/java/net/jami/jams/ca/JamsCA.java
+++ b/jams-ca/src/main/java/net/jami/jams/ca/JamsCA.java
@@ -1,14 +1,17 @@
 package net.jami.jams.ca;
 
+import com.jsoniter.JsonIterator;
 import lombok.extern.slf4j.Slf4j;
+import net.jami.jams.ca.workers.crl.CRLWorker;
+import net.jami.jams.ca.workers.csr.CertificateWorker;
+import net.jami.jams.ca.workers.ocsp.OCSPWorker;
 import net.jami.jams.common.cryptoengineapi.CertificateAuthority;
+import net.jami.jams.common.cryptoengineapi.CertificateAuthorityConfig;
 import net.jami.jams.common.objects.devices.Device;
 import net.jami.jams.common.objects.requests.RevocationRequest;
 import net.jami.jams.common.objects.system.SystemAccount;
 import net.jami.jams.common.objects.user.User;
-import net.jami.jams.ca.workers.crl.CRLWorker;
-import net.jami.jams.ca.workers.csr.CertificateWorker;
-import net.jami.jams.ca.workers.ocsp.OCSPWorker;
+import net.jami.jams.common.serialization.JsoniterRegistry;
 import org.bouncycastle.cert.X509CRLHolder;
 import org.bouncycastle.cert.ocsp.OCSPReq;
 import org.bouncycastle.cert.ocsp.OCSPResp;
@@ -25,10 +28,10 @@ public class JamsCA implements CertificateAuthority {
     private static CRLWorker crlWorker;
     private static OCSPWorker ocspWorker;
     public static volatile String serverDomain;
-    public static volatile String signingAlgorithm;
+    //The default value is SHA512WITHRSA, this can be changed in the config file.
+    public static volatile String signingAlgorithm = "SHA512WITHRSA";
 
     //Various times
-    public static long caLifetime = 360_000_000;
     public static long crlLifetime = 360_000_000;
     public static long userLifetime = 360_000_000;
     public static long deviceLifetime = 360_000_000;
@@ -38,15 +41,20 @@ public class JamsCA implements CertificateAuthority {
     public static SystemAccount OCSP;
 
     static {
+        JsoniterRegistry.initCodecs();
         Security.addProvider(new BouncyCastleProvider());
     }
 
     @Override
-    public void init(String domain, String signingAlgorithm, SystemAccount ca, SystemAccount ocsp) {
-        serverDomain = domain;
+    public void init(String settings, SystemAccount ca, SystemAccount ocsp) {
+        CertificateAuthorityConfig config = JsonIterator.deserialize(settings, CertificateAuthorityConfig.class);
         CA = ca;
         OCSP = ocsp;
-        JamsCA.signingAlgorithm = signingAlgorithm;
+        serverDomain = config.getServerDomain();
+        signingAlgorithm = config.getSigningAlgorithm();
+        crlLifetime = config.getCrlLifetime();
+        userLifetime = config.getUserLifetime();
+        deviceLifetime = config.getDeviceLifetime();
         crlWorker = new CRLWorker(CA.getPrivateKey(), CA.getCertificate());
     }
 
diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java
index 4a2bfb3f..2d335986 100644
--- a/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java
+++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java
@@ -2,9 +2,9 @@ package net.jami.jams.ca.workers.crl;
 
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
-import net.jami.jams.common.objects.requests.RevocationRequest;
 import net.jami.jams.ca.JamsCA;
 import net.jami.jams.ca.workers.X509Worker;
+import net.jami.jams.common.objects.requests.RevocationRequest;
 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.asn1.x509.CRLReason;
 import org.bouncycastle.cert.X509CRLHolder;
diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/CertificateWorker.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/CertificateWorker.java
index 9d70b594..8c22d1f0 100644
--- a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/CertificateWorker.java
+++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/CertificateWorker.java
@@ -1,12 +1,12 @@
 package net.jami.jams.ca.workers.csr;
 
 import lombok.extern.slf4j.Slf4j;
-import net.jami.jams.common.objects.devices.Device;
-import net.jami.jams.common.objects.system.SystemAccount;
-import net.jami.jams.common.objects.user.User;
 import net.jami.jams.ca.workers.csr.builders.DeviceBuilder;
 import net.jami.jams.ca.workers.csr.builders.SystemAccountBuilder;
 import net.jami.jams.ca.workers.csr.builders.UserBuilder;
+import net.jami.jams.common.objects.devices.Device;
+import net.jami.jams.common.objects.system.SystemAccount;
+import net.jami.jams.common.objects.user.User;
 
 @Slf4j
 public class CertificateWorker {
diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/DeviceBuilder.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/DeviceBuilder.java
index 7b0d520f..e93f3684 100644
--- a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/DeviceBuilder.java
+++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/DeviceBuilder.java
@@ -1,11 +1,11 @@
 package net.jami.jams.ca.workers.csr.builders;
 
 import lombok.extern.slf4j.Slf4j;
-import net.jami.jams.common.objects.devices.Device;
-import net.jami.jams.common.objects.user.User;
 import net.jami.jams.ca.JamsCA;
 import net.jami.jams.ca.workers.csr.utils.CertificateSigner;
 import net.jami.jams.ca.workers.csr.utils.ExtensionLibrary;
+import net.jami.jams.common.objects.devices.Device;
+import net.jami.jams.common.objects.user.User;
 import org.bouncycastle.cert.X509v3CertificateBuilder;
 import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
 
diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilder.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilder.java
index 9ec74653..f6ab1e77 100644
--- a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilder.java
+++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilder.java
@@ -1,10 +1,10 @@
 package net.jami.jams.ca.workers.csr.builders;
 
 import lombok.extern.slf4j.Slf4j;
-import net.jami.jams.common.objects.system.SystemAccount;
 import net.jami.jams.ca.JamsCA;
 import net.jami.jams.ca.workers.csr.utils.CertificateSigner;
 import net.jami.jams.ca.workers.csr.utils.ExtensionLibrary;
+import net.jami.jams.common.objects.system.SystemAccount;
 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
 import org.bouncycastle.cert.X509v3CertificateBuilder;
@@ -29,7 +29,7 @@ public class SystemAccountBuilder {
                     new X500Name(systemAccount.getX509Fields().getDN()),
                     new BigInteger(256, new SecureRandom()),
                     new Date(System.currentTimeMillis()),
-                    new Date(System.currentTimeMillis() + JamsCA.caLifetime),
+                    new Date(System.currentTimeMillis() + systemAccount.getLifetime()),
                     new X500Name(systemAccount.getX509Fields().getDN()),
                     SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded())
             );
@@ -54,7 +54,7 @@ public class SystemAccountBuilder {
                     new JcaX509CertificateHolder(JamsCA.CA.getCertificate()).getSubject(),
                     new BigInteger(256, new SecureRandom()),
                     new Date(System.currentTimeMillis()),
-                    new Date(System.currentTimeMillis() + JamsCA.caLifetime),
+                    new Date(System.currentTimeMillis() + systemAccount.getLifetime()),
                     new X500Name("CN=" + systemAccount.getX509Fields().getDN()),
                     SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded())
             );
diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java
index f8e05493..117523f2 100644
--- a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java
+++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java
@@ -1,10 +1,10 @@
 package net.jami.jams.ca.workers.csr.builders;
 
 import lombok.extern.slf4j.Slf4j;
-import net.jami.jams.common.objects.user.User;
 import net.jami.jams.ca.JamsCA;
 import net.jami.jams.ca.workers.csr.utils.CertificateSigner;
 import net.jami.jams.ca.workers.csr.utils.ExtensionLibrary;
+import net.jami.jams.common.objects.user.User;
 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
 import org.bouncycastle.cert.X509v3CertificateBuilder;
diff --git a/jams-ca/src/test/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilderTest.java b/jams-ca/src/test/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilderTest.java
index 49be00cf..71dba13f 100644
--- a/jams-ca/src/test/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilderTest.java
+++ b/jams-ca/src/test/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilderTest.java
@@ -1,6 +1,9 @@
 package net.jami.jams.ca.workers.csr.builders;
 
+import com.jsoniter.output.JsonStream;
+import net.jami.jams.ca.JamsCA;
 import net.jami.jams.common.authentication.AuthenticationSourceType;
+import net.jami.jams.common.cryptoengineapi.CertificateAuthorityConfig;
 import net.jami.jams.common.objects.devices.Device;
 import net.jami.jams.common.objects.requests.RevocationRequest;
 import net.jami.jams.common.objects.requests.RevocationType;
@@ -9,7 +12,6 @@ import net.jami.jams.common.objects.system.SystemAccount;
 import net.jami.jams.common.objects.system.SystemAccountType;
 import net.jami.jams.common.objects.user.User;
 import net.jami.jams.common.utils.X509Utils;
-import net.jami.jams.ca.JamsCA;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -23,8 +25,6 @@ class SystemAccountBuilderTest {
 
     @BeforeAll
     static void setUp() throws Exception{
-        JamsCA.serverDomain = "https://localhost";
-        JamsCA.signingAlgorithm = "SHA512WITHRSA";
         InputStream path;
         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
         path = classLoader.getResourceAsStream("pkcs10request.txt");
@@ -38,6 +38,7 @@ class SystemAccountBuilderTest {
         caAccount.setX509Fields(new X509Fields());
         caAccount.getX509Fields().setCommonName("Test CA");
         caAccount.getX509Fields().setCountry("FR");
+        caAccount.setLifetime(10000000L);
         caAccount = SystemAccountBuilder.generateCA(caAccount);
         Assertions.assertNotNull(caAccount.getCertificate(),"CA Certificate was not generated!");
 
@@ -48,6 +49,7 @@ class SystemAccountBuilderTest {
         ocspAccount.setSystemAccountType(SystemAccountType.OCSP);
         ocspAccount.setX509Fields(new X509Fields());
         ocspAccount.getX509Fields().setCommonName("OCSP Server");
+        ocspAccount.setLifetime(10000000L);
         ocspAccount = SystemAccountBuilder.generateOCSP(ocspAccount);
         Assertions.assertNotNull(ocspAccount.getCertificate(),"OCSP Certificate was not generated!");
 
@@ -74,11 +76,19 @@ class SystemAccountBuilderTest {
         caAccount.setX509Fields(new X509Fields());
         caAccount.getX509Fields().setCommonName("Test CA");
         caAccount.getX509Fields().setCountry("FR");
+        caAccount.setLifetime(10000000L);
         caAccount = SystemAccountBuilder.generateCA(caAccount);
         Assertions.assertNotNull(caAccount.getCertificate(),"CA Certificate was not generated!");
+        CertificateAuthorityConfig config = new CertificateAuthorityConfig();
+        config.setUserLifetime(1000L);
+        config.setSigningAlgorithm("SHA512WITHRSA");
+        config.setServerDomain("http://localhost");
+        config.setCrlLifetime(1000000L);
+        config.setDeviceLifetime(1000L);
+
 
         JamsCA jamsCA = new JamsCA();
-        jamsCA.init("http://localhost","SHA512WITHRSA",caAccount,null);
+        jamsCA.init(JsonStream.serialize(config),caAccount,null);
         RevocationRequest revocationRequest = new RevocationRequest();
         revocationRequest.setIdentifier(new BigInteger("91828882"));
         revocationRequest.setRevocationType(RevocationType.USER);
diff --git a/jams-common/src/main/java/module-info.java b/jams-common/src/main/java/module-info.java
index a2577083..fcc8f2d3 100644
--- a/jams-common/src/main/java/module-info.java
+++ b/jams-common/src/main/java/module-info.java
@@ -47,6 +47,7 @@ module jams.common {
     exports net.jami.jams.common.authentication.ldap;
     exports net.jami.jams.common.jami;
     exports net.jami.jams.common.authmodule;
+    exports net.jami.jams.common.server;
     requires jdk.crypto.cryptoki;
     requires java.base;
     requires java.sql;
diff --git a/jams-common/src/main/java/net/jami/jams/common/authmodule/AuthenticationResult.java b/jams-common/src/main/java/net/jami/jams/common/authmodule/AuthenticationResult.java
index 48c4e722..77644a66 100644
--- a/jams-common/src/main/java/net/jami/jams/common/authmodule/AuthenticationResult.java
+++ b/jams-common/src/main/java/net/jami/jams/common/authmodule/AuthenticationResult.java
@@ -1,11 +1,8 @@
 package net.jami.jams.common.authmodule;
 
-import com.jsoniter.annotation.JsonIgnore;
-import lombok.AllArgsConstructor;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
-import net.jami.jams.common.authentication.AuthenticationSourceType;
 
 @Getter
 @Setter
diff --git a/jams-common/src/main/java/net/jami/jams/common/cryptoengineapi/CertificateAuthority.java b/jams-common/src/main/java/net/jami/jams/common/cryptoengineapi/CertificateAuthority.java
index 29fb239d..3deaa15e 100644
--- a/jams-common/src/main/java/net/jami/jams/common/cryptoengineapi/CertificateAuthority.java
+++ b/jams-common/src/main/java/net/jami/jams/common/cryptoengineapi/CertificateAuthority.java
@@ -12,7 +12,7 @@ import java.util.concurrent.atomic.AtomicReference;
 
 public interface CertificateAuthority {
     //Return a signed X509 certificate based on various constraints.
-    void init(String domain, String signingAlgorithm, SystemAccount ca, SystemAccount ocsp);
+    void init(String settings, SystemAccount ca, SystemAccount ocsp);
     User getSignedCertificate(User user);
     Device getSignedCertificate(User user, Device device);
     SystemAccount getSignedCertificate(SystemAccount systemAccount);
diff --git a/jams-common/src/main/java/net/jami/jams/common/cryptoengineapi/CertificateAuthorityConfig.java b/jams-common/src/main/java/net/jami/jams/common/cryptoengineapi/CertificateAuthorityConfig.java
new file mode 100644
index 00000000..67d49fa8
--- /dev/null
+++ b/jams-common/src/main/java/net/jami/jams/common/cryptoengineapi/CertificateAuthorityConfig.java
@@ -0,0 +1,14 @@
+package net.jami.jams.common.cryptoengineapi;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CertificateAuthorityConfig {
+   private String serverDomain;
+   private String signingAlgorithm;
+   private Long   crlLifetime;
+   private Long   userLifetime;
+   private Long   deviceLifetime;
+}
diff --git a/jams-common/src/main/java/net/jami/jams/common/objects/roots/X509Entity.java b/jams-common/src/main/java/net/jami/jams/common/objects/roots/X509Entity.java
index c4de1279..d56b96c1 100644
--- a/jams-common/src/main/java/net/jami/jams/common/objects/roots/X509Entity.java
+++ b/jams-common/src/main/java/net/jami/jams/common/objects/roots/X509Entity.java
@@ -15,4 +15,5 @@ public class X509Entity {
     //These can be null because they are only used if this is a request.
     private X509Fields x509Fields;
     private PKCS10CertificationRequest certificationRequest;
+    private Long lifetime;
 }
diff --git a/jams-common/src/main/java/net/jami/jams/common/server/ServerSettings.java b/jams-common/src/main/java/net/jami/jams/common/server/ServerSettings.java
new file mode 100644
index 00000000..fbfeb1bf
--- /dev/null
+++ b/jams-common/src/main/java/net/jami/jams/common/server/ServerSettings.java
@@ -0,0 +1,14 @@
+package net.jami.jams.common.server;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ServerSettings {
+
+    private String ldapConfiguration;
+    private String caConfiguration;
+    private String activeDirectoryConfiguration;
+
+}
diff --git a/jams-server/src/main/java/module-info.java b/jams-server/src/main/java/module-info.java
index 664ee049..1f4fbb56 100644
--- a/jams-server/src/main/java/module-info.java
+++ b/jams-server/src/main/java/module-info.java
@@ -14,4 +14,5 @@ module jams.server {
     exports net.jami.jams.server.servlets.filters to org.apache.tomcat.embed.core;
     exports net.jami.jams.server.servlets.api.auth.login to org.apache.tomcat.embed.core;
     exports net.jami.jams.server.servlets.api.auth.device to org.apache.tomcat.embed.core;
+    exports net.jami.jams.server.servlets.api.install to org.apache.tomcat.embed.core;
 }
\ No newline at end of file
diff --git a/jams-server/src/main/java/net/jami/jams/server/Server.java b/jams-server/src/main/java/net/jami/jams/server/Server.java
index 969a0d82..ae941021 100644
--- a/jams-server/src/main/java/net/jami/jams/server/Server.java
+++ b/jams-server/src/main/java/net/jami/jams/server/Server.java
@@ -1,25 +1,20 @@
 package net.jami.jams.server;
 
+import com.jsoniter.JsonIterator;
 import lombok.extern.slf4j.Slf4j;
 import net.jami.datastore.main.DataStore;
-import net.jami.jams.ca.JamsCA;
-import net.jami.jams.ca.workers.csr.builders.SystemAccountBuilder;
 import net.jami.jams.common.authentication.AuthenticationSource;
-import net.jami.jams.common.authentication.AuthenticationSourceType;
 import net.jami.jams.common.authmodule.AuthenticationModule;
 import net.jami.jams.common.cryptoengineapi.CertificateAuthority;
-import net.jami.jams.common.objects.roots.X509Fields;
-import net.jami.jams.common.objects.system.SystemAccount;
-import net.jami.jams.common.objects.system.SystemAccountType;
-import net.jami.jams.common.objects.user.UserProfile;
 import net.jami.jams.common.serialization.JsoniterRegistry;
+import net.jami.jams.common.server.ServerSettings;
+import net.jami.jams.common.utils.LibraryLoader;
 import net.jami.jams.server.core.TomcatLauncher;
-import net.jami.jams.common.authmodule.AuthModuleKey;
 import net.jami.jams.server.startup.AuthModuleLoader;
 import net.jami.jams.server.startup.CryptoEngineLoader;
-import net.jami.jams.common.utils.LibraryLoader;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -47,43 +42,33 @@ public class Server {
         TomcatLauncher tomcatLauncher = new TomcatLauncher();
         tomcatLauncher.startServer();
 
+        //Look for the config.json file locally.
+
         //Pre-load the libraries we should pre-load.
         LibraryLoader.loadlibs("libs",Server.class);
         //Step 1: Create the data store.
         dataStore = new DataStore("jdbc:derby:jams;create=true");
 
-        //Test block
-        //Step 2: if the server is initialized,
-        certificateAuthority = CryptoEngineLoader.loadCertificateAuthority(dataStore);
-        userAuthenticationModule = AuthModuleLoader.loadAuthenticationModule(dataStore,certificateAuthority);
+
 
         isInstalled.set(new File(System.getProperty("user.dir") + File.separator + "config.json").exists());
         log.info("Server is already installed: " + isInstalled.get());
-
-        //nasty injection to test this flow.
-        //Okay this is me cheating again heavily, just for testing purposes.
-        try {
-            JamsCA.serverDomain = "https://localhost";
-            JamsCA.signingAlgorithm = "SHA512WITHRSA";
-            SystemAccount caAccount = new SystemAccount();
-            caAccount.setSystemAccountType(SystemAccountType.CA);
-            caAccount.setX509Fields(new X509Fields());
-            caAccount.getX509Fields().setCommonName("Test CA");
-            caAccount.getX509Fields().setCountry("FR");
-            caAccount = SystemAccountBuilder.generateCA(caAccount);
-            JamsCA.CA = caAccount;
-
-
-            InputStream path;
-            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-            path = classLoader.getResourceAsStream("ldapconfig.json");
-            userAuthenticationModule.attachAuthSource(AuthenticationSourceType.LDAP,new String(path.readAllBytes()));
-            UserProfile[] userProfile = userAuthenticationModule.getAuthSources()
-                    .get(new AuthModuleKey("savoirfairelinux", AuthenticationSourceType.LDAP))
-                    .getUserProfile("Félix","FULL_TEXT_NAME");
-            System.out.println(userProfile[0]);
-        } catch (Exception e) {
-            log.error("Could not load and inject active directory connector with error: " + e.toString());
+        ServerSettings serverSettings = null;
+        if(isInstalled.get()){
+            try {
+                InputStream path = new FileInputStream(new File(System.getProperty("user.dir") + File.separator + "config.json"));
+                serverSettings = JsonIterator.deserialize(path.readAllBytes(),ServerSettings.class);
+                certificateAuthority = CryptoEngineLoader.loadCertificateAuthority(serverSettings.getCaConfiguration(),dataStore);
+                userAuthenticationModule = AuthModuleLoader.loadAuthenticationModule(dataStore,certificateAuthority);
+            }
+            catch (Exception e){
+                log.error("Could not load configuration file or initialize some components - this is critical");
+            }
+        }
+        else{
+            certificateAuthority = CryptoEngineLoader.loadCertificateAuthority(null,dataStore);
+            userAuthenticationModule = AuthModuleLoader.loadAuthenticationModule(dataStore,certificateAuthority);
+            log.info("Started server with empty modules waiting for setup...");
         }
     }
 }
diff --git a/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java b/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java
index 5d67aec1..d513fe78 100644
--- a/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java
+++ b/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java
@@ -8,8 +8,6 @@ import org.apache.catalina.startup.Tomcat;
 import org.apache.catalina.webresources.DirResourceSet;
 import org.apache.catalina.webresources.JarResourceSet;
 import org.apache.catalina.webresources.StandardRoot;
-import org.apache.tomcat.JarScanFilter;
-import org.apache.tomcat.JarScanType;
 
 import java.io.File;
 import java.net.URLDecoder;
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/login/LoginServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/login/LoginServlet.java
index 80878a01..aeb67a09 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/login/LoginServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/login/LoginServlet.java
@@ -11,7 +11,8 @@ import net.jami.jams.common.authmodule.AuthenticationResult;
 import java.io.IOException;
 import java.security.cert.X509Certificate;
 
-import static net.jami.jams.server.servlets.api.auth.login.AuthRequestProcessor.*;
+import static net.jami.jams.server.servlets.api.auth.login.AuthRequestProcessor.processUsernamePasswordAuth;
+import static net.jami.jams.server.servlets.api.auth.login.AuthRequestProcessor.processX509Auth;
 
 @WebServlet("/api/auth/login")
 //This method returns the token which is used for all the next calls to the API.
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java
new file mode 100644
index 00000000..d6739ecf
--- /dev/null
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java
@@ -0,0 +1,61 @@
+package net.jami.jams.server.servlets.api.install;
+
+import com.jsoniter.output.JsonStream;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import net.jami.jams.common.authentication.AuthenticationSourceType;
+import net.jami.jams.common.authmodule.AuthenticationResult;
+import net.jami.jams.common.dao.StatementList;
+import net.jami.jams.common.objects.user.AccessLevel;
+import net.jami.jams.common.objects.user.User;
+
+import java.io.IOException;
+
+import static net.jami.jams.server.Server.dataStore;
+import static net.jami.jams.server.servlets.api.auth.login.AuthRequestProcessor.processUsernamePasswordAuth;
+
+@WebServlet("/api/install/start")
+public class StartInstallServlet extends HttpServlet {
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        //Here we must decide which page to show - login or sign-up
+        StatementList statementList = new StatementList();
+        statementList.setStatements(null);
+        if(dataStore.getUserDao().getObjects(statementList).size() != 0) resp.setHeader("showLogin","true");
+        else resp.setHeader("showLogin","false");
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        AuthenticationResult res = null;
+        if(req.getParameter("username") != null && req.getParameter("password") != null){
+            res = processUsernamePasswordAuth(req.getParameter("username"),req.getParameter("password"));
+        }
+        resp.getOutputStream().write(JsonStream.serialize(res).getBytes());
+    }
+
+    //This is the ONLY case where we write directy to the DB
+    @Override
+    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        StatementList statementList = new StatementList();
+        statementList.setStatements(null);
+        if(dataStore.getUserDao().getObjects(statementList).size() != 0){
+            resp.sendError(500,"We have tried to create an administrative account where one already exists!");
+            return;
+        }
+        //The admin user has no X509 properties.
+        User user = new User();
+        user.setUsername(req.getParameter("username"));
+        user.setPassword(req.getParameter("password"));
+        user.setUserType(AuthenticationSourceType.LOCAL);
+        user.setRealm("LOCAL");
+        user.setAccessLevel(AccessLevel.ADMIN);
+        dataStore.getUserDao().storeObject(user);
+        AuthenticationResult res = processUsernamePasswordAuth(user.getUsername(),user.getPassword());
+        resp.getOutputStream().write(JsonStream.serialize(res).getBytes());
+    }
+}
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/APIFilter.java b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/APIFilter.java
index 9902c2c9..4ea2db49 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/APIFilter.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/APIFilter.java
@@ -5,13 +5,13 @@ import jakarta.servlet.annotation.WebFilter;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
-import net.jami.jams.server.servlets.api.auth.login.Decoders;
+import net.jami.jams.server.Server;
 
 import java.io.IOException;
 
 import static net.jami.jams.server.Server.userAuthenticationModule;
 
-@WebFilter(urlPatterns = {"/api/*"})
+@WebFilter(urlPatterns = {"/api/auth/*"})
 @Slf4j
 public class APIFilter implements Filter {
 
@@ -19,15 +19,19 @@ public class APIFilter implements Filter {
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
         HttpServletRequest request = (HttpServletRequest) servletRequest;
         HttpServletResponse response = (HttpServletResponse) servletResponse;
-        boolean authsuccess = false;
-        boolean isLogin = false;
-        if(request.getServletPath().contains("login")){
-            isLogin = true;
+        if (!Server.isInstalled.get()) {
+            response.sendError(404,"This endpoint requires setup to be complete!");
+        } else {
+            boolean authsuccess = false;
+            boolean isLogin = false;
+            if (request.getServletPath().contains("login")) {
+                isLogin = true;
+            }
+            if (request.getHeader("x-token") != null) {
+                authsuccess = userAuthenticationModule.validateAndGetUsername(request.getHeader("x-token")) != null;
+            }
+            if (authsuccess || isLogin) filterChain.doFilter(servletRequest, servletResponse);
+            else response.sendError(403,"This endpoint requires setup to be complete!");
         }
-        if(request.getHeader("x-token") != null) {
-            authsuccess = userAuthenticationModule.validateAndGetUsername(request.getHeader("x-token")) != null;
-        }
-        if(authsuccess || isLogin) filterChain.doFilter(servletRequest,servletResponse);
-        else response.setStatus(403);
     }
 }
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/InstallFilter.java b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/InstallFilter.java
new file mode 100644
index 00000000..2fcff582
--- /dev/null
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/InstallFilter.java
@@ -0,0 +1,35 @@
+package net.jami.jams.server.servlets.filters;
+
+import jakarta.servlet.*;
+import jakarta.servlet.annotation.WebFilter;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import net.jami.jams.server.Server;
+
+import java.io.IOException;
+
+import static net.jami.jams.server.Server.userAuthenticationModule;
+
+@WebFilter("/api/install/*")
+public class InstallFilter implements Filter {
+
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+        HttpServletRequest request = (HttpServletRequest) servletRequest;
+        HttpServletResponse response = (HttpServletResponse) servletResponse;
+        if(Server.isInstalled.get()){
+            response.sendError(404,"The server has already been configured, this endpoint is not available!");
+        }
+        else{
+            boolean authsuccess = false;
+            boolean isLogin = false;
+            if(request.getServletPath().contains("start")) isLogin = true;
+            if(request.getHeader("x-token") != null) {
+                authsuccess = userAuthenticationModule.validateAndGetUsername(request.getHeader("x-token")) != null;
+            }
+            if(authsuccess || isLogin) filterChain.doFilter(servletRequest,servletResponse);
+            else response.sendError(403,"You are not authorized to access this page!");
+        }
+    }
+
+}
diff --git a/jams-server/src/main/java/net/jami/jams/server/startup/AuthModuleLoader.java b/jams-server/src/main/java/net/jami/jams/server/startup/AuthModuleLoader.java
index 33b281e9..0687fe5d 100644
--- a/jams-server/src/main/java/net/jami/jams/server/startup/AuthModuleLoader.java
+++ b/jams-server/src/main/java/net/jami/jams/server/startup/AuthModuleLoader.java
@@ -6,8 +6,6 @@ import net.jami.jams.common.authmodule.AuthenticationModule;
 import net.jami.jams.common.cryptoengineapi.CertificateAuthority;
 import net.jami.jams.common.utils.LibraryLoader;
 
-import java.util.List;
-
 @Slf4j
 public class AuthModuleLoader {
 
diff --git a/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java b/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java
index a9abf7f8..9b33f427 100644
--- a/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java
+++ b/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java
@@ -13,7 +13,7 @@ import java.util.List;
 @Slf4j
 public class CryptoEngineLoader {
 
-    public static CertificateAuthority loadCertificateAuthority(DataStore dataStore){
+    public static CertificateAuthority loadCertificateAuthority(String config, DataStore dataStore){
         try {
             Class<?> cls = LibraryLoader.classLoader.loadClass("net.jami.jams.ca.JamsCA");
             CertificateAuthority certificateAuthority = (CertificateAuthority) cls.getConstructor().newInstance();
@@ -32,7 +32,7 @@ public class CryptoEngineLoader {
                 statementList.addStatement(new StatementElement("entity","=","OCSP",""));
                 SystemAccount ocspAccount = dataStore.getSystemDao().getObjects(statementList).get(0);
                 log.info("Injecting OCSP and CA acocunts...");
-                certificateAuthority.init("domain.com","SHA512WITHRSA",caAccount,ocspAccount);
+                certificateAuthority.init(config,caAccount,ocspAccount);
             }
             log.info("Loaded X509 Engine - please make sure it is initialized before using it to sign requests!");
             return certificateAuthority;
diff --git a/jams-server/src/main/resources/webapp/images/add-user-img.svg b/jams-server/src/main/resources/webapp/images/add-user-img.svg
index a9b5d777..416563fe 100644
--- a/jams-server/src/main/resources/webapp/images/add-user-img.svg
+++ b/jams-server/src/main/resources/webapp/images/add-user-img.svg
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 128 128" style="enable-background:new 0 0 128 128;" xml:space="preserve">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
+     viewBox="0 0 128 128" style="enable-background:new 0 0 128 128;" xml:space="preserve">
 <style type="text/css">
 	.st0{fill:#000747;}
 	.st1{fill:#FFFFFF;}
diff --git a/jams-server/src/main/resources/webapp/images/exclamation.svg b/jams-server/src/main/resources/webapp/images/exclamation.svg
index b8bda173..de5c7416 100644
--- a/jams-server/src/main/resources/webapp/images/exclamation.svg
+++ b/jams-server/src/main/resources/webapp/images/exclamation.svg
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 128 128" style="enable-background:new 0 0 128 128;" xml:space="preserve">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
+     viewBox="0 0 128 128" style="enable-background:new 0 0 128 128;" xml:space="preserve">
 <style type="text/css">
 	.st0{fill:#FF5722;}
 </style>
diff --git a/jams-server/src/main/resources/webapp/images/logo/logo-sfl.svg b/jams-server/src/main/resources/webapp/images/logo/logo-sfl.svg
index 2ddd52f4..f8c199ef 100644
--- a/jams-server/src/main/resources/webapp/images/logo/logo-sfl.svg
+++ b/jams-server/src/main/resources/webapp/images/logo/logo-sfl.svg
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="338.4px" height="96.48px" viewBox="-1.555 -0.742 338.4 96.48" enable-background="new -1.555 -0.742 338.4 96.48" xml:space="preserve">
+<svg version="1.1" id="Logo" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="338.4px" height="96.48px"
+     viewBox="-1.555 -0.742 338.4 96.48" enable-background="new -1.555 -0.742 338.4 96.48" xml:space="preserve">
 <g>
 	<g>
 		<g>
diff --git a/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java b/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java
index 68e7ebe8..b760025b 100644
--- a/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java
+++ b/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java
@@ -7,7 +7,6 @@ import org.ldaptive.*;
 
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.text.Normalizer;
 import java.util.HashMap;
 import java.util.Iterator;
 
-- 
GitLab