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 01468c48bfe4ea6aa4457ad07646d293f044ba8c..af17ecf35c76108f878d2239292ba209fa1ae8d9 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 7b4bf5104a0c8748138ee2f7341cf8df80cfa301..2a99fb962ab9f851723118dcec1db10af7d6ad0f 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 0dcb0ebe7d50aa60c8a3f9f8161291fff380e30a..6557f6e971508e0ad29f36d2aeab17f367ad51ed 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 790ca69be63474fcd10c22ed36fe43512898636e..cd207c3214b3de773dfcc380d1cd5afe92345143 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 4a2bfb3f60db5ab2cb9725bafd447bebb67b2fe4..2d335986006b91f3b80bd9a07e07055f0b4bb4e7 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 9d70b594bf5e117f853a9385b03c709a08501d5d..8c22d1f04c5ca68936de0f326328af2964d79528 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 7b0d520fae621426e43797270321d50c016aaf61..e93f3684108c4f5ef1a89b3837b4d65f2257a467 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 9ec746538ede9946195356afd5476121ccd9e712..f6ab1e776df030b011a5d91b84d0432f73d4c7f0 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 f8e054933644ffe3ffa3dd764a5aa036d62f74e5..117523f26f82168c555229f02f2537d6bb78460b 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 49be00cfd58c57e867a27061442052f143c4d2dd..71dba13fc7f3b5db5f17e4a3cded040b619876c7 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 a25770836ac6a2f76373fad058495c5cb8e21cbe..fcc8f2d3ef55b6b8f793b54e9d3a428d9ee4e721 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 48c4e722f388c199910223bb682f4eccfe4826dc..77644a66ef20561b34b77f9b1900add7d1d6b6bf 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 29fb239d8b8c7546d2b7dc9921d7cdbe790e7407..3deaa15e399d6f94863b21bbf0354fa11c72ec67 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 0000000000000000000000000000000000000000..67d49fa8bf8e7776c0c9056bc904eb7838141dff --- /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 c4de1279bf1db6fc943585506d24f1c5e9e46329..d56b96c15eee14ef1b7408000de035a1114f7d12 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 0000000000000000000000000000000000000000..fbfeb1bf58f02a0979998fe6b10f0af1ad7da97e --- /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 664ee049ac5e7b5c08414aa22c02fa67a5bf4911..1f4fbb56fe5be235a3c9079eb7d00c23ae2c06a8 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 969a0d82d1238c9d44e4c1c14b51086751174391..ae941021d8767816a884f9221116b264bae0a291 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 5d67aec1a5144740cfaa82b30893c9529af52633..d513fe783e9c4e0ba55a9a69a721d0c3fdc7f456 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 80878a015ff3caa6e2f51243088779776818e1a9..aeb67a092eb21e5604ee12cec4f28388879a5e59 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 0000000000000000000000000000000000000000..d6739ecfc4cac2f44452d251c885555806161f29 --- /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 9902c2c9b540e85ff13b1610370853ae0df34b46..4ea2db49a7cc39fa7adb8d0860996bda151502d1 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 0000000000000000000000000000000000000000..2fcff582848ee261682f821b323b3c7712985037 --- /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 33b281e9118a3b89c7bef182308f53c22a59be74..0687fe5d27425c4480f1fc16498a069c84a00f3e 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 a9abf7f838952b75b78197d63d5676db75b6fbbb..9b33f42738bedd0ef66797acfc66471108a4a2dd 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 a9b5d777e01f8b71de5a7c935d244ad889f1647f..416563fed4b3a9e40b9143d14301c329fdc3b4ee 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 b8bda1735158faead1f7f67eff5bbb310e4fde14..de5c7416bfe34be31b0b70e75dd1ef9ce58e13aa 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 2ddd52f4a3e2aab86d8f5fd0fa04618ac8554fc4..f8c199ef6a2e645efd956a5cc125d816ef86b3f3 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 68e7ebe87c613646a0093eff2f55d7ccbee8f056..b760025b5235499dd447d8e1a2ef653916c2ea08 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;