Disable OSGi configuration admin and LDIF-based deploy config.
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 27 Jun 2022 15:50:11 +0000 (17:50 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 27 Jun 2022 15:50:11 +0000 (17:50 +0200)
28 files changed:
eclipse/org.argeo.cms.servlet/OSGI-INF/jettyServiceFactory.xml
eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/CmsServletContext.java
eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/InternalHttpConstants.java [new file with mode: 0644]
eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/JettyConfig.java [new file with mode: 0644]
jcr/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml
jcr/org.argeo.cms.jcr/OSGI-INF/repositoryContextsFactory.xml
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JcrInitUtils.java
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryContextsFactory.java
org.argeo.api.cms/src/org/argeo/api/cms/CmsDeployment.java
org.argeo.api.cms/src/org/argeo/api/cms/CmsState.java
org.argeo.cms/OSGI-INF/cmsDeployment.xml
org.argeo.cms/OSGI-INF/nodeUserAdmin.xml
org.argeo.cms/bnd.bnd
org.argeo.cms/src/org/argeo/cms/auth/RemoteSessionLoginModule.java
org.argeo.cms/src/org/argeo/cms/internal/http/InternalHttpConstants.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsActivator.java
org.argeo.cms/src/org/argeo/cms/internal/osgi/DeployConfig.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsStateImpl.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsUserAdmin.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/InitUtils.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/KernelConstants.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/KernelUtils.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/PkiUtils.java [deleted file]
org.argeo.cms/src/org/argeo/cms/runtime/StaticCms.java
org.argeo.cms/src/org/argeo/cms/security/PkiUtils.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java

index c007351aa0cb273c0e894114bc0dc9f5c39f5987..c2cf1c73bd3f0c2df77de05f89a4137ce58b3225 100644 (file)
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" name="Jetty Service Factory">
-   <implementation class="org.argeo.cms.servlet.internal.jetty.JettyServiceFactory"/>
-   <service>
-      <provide interface="org.osgi.service.cm.ManagedServiceFactory"/>
-   </service>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" activate="start" deactivate="stop" name="Jetty Service Factory">
+   <implementation class="org.argeo.cms.servlet.internal.jetty.JettyConfig"/>
    <property name="service.pid" type="String" value="org.argeo.equinox.jetty.config"/>
+   <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
 </scr:component>
index 1ae6286ac2a4e38eb6c37bf4269c187a1d89a419..cc2bc02d1978e46bc34e3149f0779baf2728522a 100644 (file)
@@ -76,7 +76,9 @@ public class CmsServletContext extends ServletContextHelper {
 
        protected LoginContext processUnauthorized(HttpServletRequest request, HttpServletResponse response) {
                // anonymous
+               ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
                try {
+                       Thread.currentThread().setContextClassLoader(CmsServletContext.class.getClassLoader());
                        LoginContext lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS,
                                        new RemoteAuthCallbackHandler(new ServletHttpRequest(request), new ServletHttpResponse(response)));
                        lc.login();
@@ -85,6 +87,8 @@ public class CmsServletContext extends ServletContextHelper {
                        if (log.isDebugEnabled())
                                log.error("Cannot log in as anonymous", e1);
                        return null;
+               } finally {
+                       Thread.currentThread().setContextClassLoader(currentContextClassLoader);
                }
        }
 
diff --git a/eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/InternalHttpConstants.java b/eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/InternalHttpConstants.java
new file mode 100644 (file)
index 0000000..462bf7a
--- /dev/null
@@ -0,0 +1,23 @@
+package org.argeo.cms.servlet.internal.jetty;
+
+/** Compatible with Jetty. */
+public interface InternalHttpConstants {
+       static final String HTTP_ENABLED = "http.enabled";
+       static final String HTTP_PORT = "http.port";
+       static final String HTTP_HOST = "http.host";
+       static final String HTTPS_ENABLED = "https.enabled";
+       static final String HTTPS_HOST = "https.host";
+       static final String HTTPS_PORT = "https.port";
+       static final String SSL_KEYSTORE = "ssl.keystore";
+       static final String SSL_PASSWORD = "ssl.password";
+       static final String SSL_KEYPASSWORD = "ssl.keypassword";
+       static final String SSL_NEEDCLIENTAUTH = "ssl.needclientauth";
+       static final String SSL_WANTCLIENTAUTH = "ssl.wantclientauth";
+       static final String SSL_PROTOCOL = "ssl.protocol";
+       static final String SSL_ALGORITHM = "ssl.algorithm";
+       static final String SSL_KEYSTORETYPE = "ssl.keystoretype";
+       static final String JETTY_PROPERTY_PREFIX = "org.eclipse.equinox.http.jetty.";
+       // Argeo specific
+       static final String WEBSOCKET_ENABLED = "websocket.enabled";
+
+}
diff --git a/eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/JettyConfig.java b/eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/JettyConfig.java
new file mode 100644 (file)
index 0000000..026993e
--- /dev/null
@@ -0,0 +1,231 @@
+package org.argeo.cms.servlet.internal.jetty;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.KeyStore;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.concurrent.ForkJoinPool;
+
+import javax.websocket.DeploymentException;
+import javax.websocket.server.ServerContainer;
+import javax.websocket.server.ServerEndpointConfig;
+
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsState;
+import org.argeo.cms.security.PkiUtils;
+import org.argeo.cms.websocket.javax.server.CmsWebSocketConfigurator;
+import org.argeo.cms.websocket.javax.server.TestEndpoint;
+import org.argeo.util.LangUtils;
+import org.eclipse.equinox.http.jetty.JettyConfigurator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class JettyConfig {
+       private final static CmsLog log = CmsLog.getLog(JettyConfig.class);
+
+       final static String CMS_JETTY_CUSTOMIZER_CLASS = "org.argeo.equinox.jetty.CmsJettyCustomizer";
+       // Argeo specific
+       final static String WEBSOCKET_ENABLED = "websocket.enabled";
+
+       private CmsState cmsState;
+
+       private final BundleContext bc = FrameworkUtil.getBundle(JettyConfig.class).getBundleContext();
+
+       public void start() {
+               // We need to start asynchronously so that Jetty bundle get started by lazy init
+               // due to the non-configurable behaviour of its activator
+               ForkJoinPool.commonPool().execute(() -> {
+                       Dictionary<String, ?> properties = getHttpServerConfig();
+                       startServer(properties);
+               });
+
+               ServiceTracker<ServerContainer, ServerContainer> serverSt = new ServiceTracker<ServerContainer, ServerContainer>(
+                               bc, ServerContainer.class, null) {
+
+                       @Override
+                       public ServerContainer addingService(ServiceReference<ServerContainer> reference) {
+                               ServerContainer serverContainer = super.addingService(reference);
+
+                               BundleContext bc = reference.getBundle().getBundleContext();
+                               ServiceReference<ServerEndpointConfig.Configurator> srConfigurator = bc
+                                               .getServiceReference(ServerEndpointConfig.Configurator.class);
+                               ServerEndpointConfig.Configurator endpointConfigurator = bc.getService(srConfigurator);
+                               ServerEndpointConfig config = ServerEndpointConfig.Builder
+                                               .create(TestEndpoint.class, "/ws/test/events/").configurator(endpointConfigurator).build();
+                               try {
+                                       serverContainer.addEndpoint(config);
+                               } catch (DeploymentException e) {
+                                       throw new IllegalStateException("Cannot initalise the WebSocket server runtime.", e);
+                               }
+                               return serverContainer;
+                       }
+
+               };
+               serverSt.open();
+       }
+
+       public void stop() {
+               try {
+                       JettyConfigurator.stopServer(CmsConstants.DEFAULT);
+               } catch (Exception e) {
+                       log.error("Cannot stop default Jetty server.", e);
+               }
+
+       }
+
+       public void startServer(Dictionary<String, ?> properties) {
+               // Explicitly configures Jetty so that the default server is not started by the
+               // activator of the Equinox Jetty bundle.
+               Map<String, String> config = LangUtils.dictToStringMap(properties);
+               if (!config.isEmpty()) {
+                       config.put("customizer.class", CMS_JETTY_CUSTOMIZER_CLASS);
+
+                       // TODO centralise with Jetty extender
+                       Object webSocketEnabled = config.get(WEBSOCKET_ENABLED);
+                       if (webSocketEnabled != null && webSocketEnabled.toString().equals("true")) {
+                               bc.registerService(ServerEndpointConfig.Configurator.class, new CmsWebSocketConfigurator(), null);
+                               config.put(WEBSOCKET_ENABLED, "true");
+                       }
+               }
+
+               int tryCount = 30;
+               try {
+                       tryGettyJetty: while (tryCount > 0) {
+                               try {
+                                       // FIXME deal with multiple ids
+                                       JettyConfigurator.startServer(CmsConstants.DEFAULT, new Hashtable<>(config));
+
+                                       Object httpPort = config.get(InternalHttpConstants.HTTP_PORT);
+                                       Object httpsPort = config.get(InternalHttpConstants.HTTPS_PORT);
+                                       log.info(httpPortsMsg(httpPort, httpsPort));
+
+                                       // Explicitly starts Jetty OSGi HTTP bundle, so that it gets triggered if OSGi
+                                       // configuration is not cleaned
+                                       FrameworkUtil.getBundle(JettyConfigurator.class).start();
+                                       break tryGettyJetty;
+                               } catch (IllegalStateException e) {
+                                       // e.printStackTrace();
+                                       // Jetty may not be ready
+                                       try {
+                                               Thread.sleep(1000);
+                                       } catch (Exception e1) {
+                                               // silent
+                                       }
+                                       tryCount--;
+                               }
+                       }
+               } catch (Exception e) {
+                       log.error("Cannot start default Jetty server with config " + properties, e);
+               }
+
+       }
+
+       private String httpPortsMsg(Object httpPort, Object httpsPort) {
+               return (httpPort != null ? "HTTP " + httpPort + " " : " ") + (httpsPort != null ? "HTTPS " + httpsPort : "");
+       }
+
+       /** Override the provided config with the framework properties */
+       public Dictionary<String, Object> getHttpServerConfig() {
+               String httpPort = getFrameworkProp("org.osgi.service.http.port");
+               String httpsPort = getFrameworkProp("org.osgi.service.http.port.secure");
+               /// TODO make it more generic
+               String httpHost = getFrameworkProp(
+                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.HTTP_HOST);
+               String httpsHost = getFrameworkProp(
+                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.HTTPS_HOST);
+               String webSocketEnabled = getFrameworkProp(
+                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.WEBSOCKET_ENABLED);
+
+               final Hashtable<String, Object> props = new Hashtable<String, Object>();
+               // try {
+               if (httpPort != null || httpsPort != null) {
+                       boolean httpEnabled = httpPort != null;
+                       props.put(InternalHttpConstants.HTTP_ENABLED, httpEnabled);
+                       boolean httpsEnabled = httpsPort != null;
+                       props.put(InternalHttpConstants.HTTPS_ENABLED, httpsEnabled);
+
+                       if (httpEnabled) {
+                               props.put(InternalHttpConstants.HTTP_PORT, httpPort);
+                               if (httpHost != null)
+                                       props.put(InternalHttpConstants.HTTP_HOST, httpHost);
+                       }
+
+                       if (httpsEnabled) {
+                               props.put(InternalHttpConstants.HTTPS_PORT, httpsPort);
+                               if (httpsHost != null)
+                                       props.put(InternalHttpConstants.HTTPS_HOST, httpsHost);
+
+                               // server certificate
+                               Path keyStorePath = cmsState.getDataPath(PkiUtils.DEFAULT_KEYSTORE_PATH);
+                               Path pemKeyPath = cmsState.getDataPath(PkiUtils.DEFAULT_PEM_KEY_PATH);
+                               Path pemCertPath = cmsState.getDataPath(PkiUtils.DEFAULT_PEM_CERT_PATH);
+                               String keyStorePasswordStr = getFrameworkProp(
+                                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_PASSWORD);
+                               char[] keyStorePassword;
+                               if (keyStorePasswordStr == null)
+                                       keyStorePassword = "changeit".toCharArray();
+                               else
+                                       keyStorePassword = keyStorePasswordStr.toCharArray();
+
+                               // if PEM files both exists, update the PKCS12 file
+                               if (Files.exists(pemCertPath) && Files.exists(pemKeyPath)) {
+                                       // TODO check certificate update time? monitor changes?
+                                       KeyStore keyStore = PkiUtils.getKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
+                                       try (Reader key = Files.newBufferedReader(pemKeyPath, StandardCharsets.US_ASCII);
+                                                       Reader cert = Files.newBufferedReader(pemCertPath, StandardCharsets.US_ASCII);) {
+                                               PkiUtils.loadPem(keyStore, key, keyStorePassword, cert);
+                                               PkiUtils.saveKeyStore(keyStorePath, keyStorePassword, keyStore);
+                                               if (log.isDebugEnabled())
+                                                       log.debug("PEM certificate stored in " + keyStorePath);
+                                       } catch (IOException e) {
+                                               log.error("Cannot read PEM files " + pemKeyPath + " and " + pemCertPath, e);
+                                       }
+                               }
+
+                               if (!Files.exists(keyStorePath))
+                                       PkiUtils.createSelfSignedKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
+                               props.put(InternalHttpConstants.SSL_KEYSTORETYPE, PkiUtils.PKCS12);
+                               props.put(InternalHttpConstants.SSL_KEYSTORE, keyStorePath.toString());
+                               props.put(InternalHttpConstants.SSL_PASSWORD, new String(keyStorePassword));
+
+//                             props.put(InternalHttpConstants.SSL_KEYSTORETYPE, "PKCS11");
+//                             props.put(InternalHttpConstants.SSL_KEYSTORE, "../../nssdb");
+//                             props.put(InternalHttpConstants.SSL_PASSWORD, keyStorePassword);
+
+                               // client certificate authentication
+                               String wantClientAuth = getFrameworkProp(
+                                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_WANTCLIENTAUTH);
+                               if (wantClientAuth != null)
+                                       props.put(InternalHttpConstants.SSL_WANTCLIENTAUTH, Boolean.parseBoolean(wantClientAuth));
+                               String needClientAuth = getFrameworkProp(
+                                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_NEEDCLIENTAUTH);
+                               if (needClientAuth != null)
+                                       props.put(InternalHttpConstants.SSL_NEEDCLIENTAUTH, Boolean.parseBoolean(needClientAuth));
+                       }
+
+                       // web socket
+                       if (webSocketEnabled != null && webSocketEnabled.equals("true"))
+                               props.put(InternalHttpConstants.WEBSOCKET_ENABLED, true);
+
+                       props.put(CmsConstants.CN, CmsConstants.DEFAULT);
+               }
+               return props;
+       }
+
+       private String getFrameworkProp(String key) {
+               return cmsState.getDeployProperty(key);
+       }
+
+       public void setCmsState(CmsState cmsState) {
+               this.cmsState = cmsState;
+       }
+
+}
index a94b15168f483b05ea270c817f69ac04e3ccd0e9..033ddbd2f0bab8a4934d2c0e2eca49feee1080b8 100644 (file)
@@ -1,5 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" name="JCR Deployment">
    <implementation class="org.argeo.cms.jcr.internal.CmsJcrDeployment"/>
-   <reference bind="setCmsDeployment" cardinality="1..1" interface="org.argeo.api.cms.CmsDeployment" policy="static"/>
 </scr:component>
index db2bfaa26068301604f252db71609de6218505c5..2d06acad5f02149126037248fe6ea816ad44d608 100644 (file)
@@ -2,8 +2,5 @@
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Jackrabbit Repository Contexts Factory">
    <implementation class="org.argeo.cms.jcr.internal.RepositoryContextsFactory"/>
    <property name="service.pid" type="String" value="org.argeo.api.repos"/>
-   <service>
-      <provide interface="org.osgi.service.cm.ManagedServiceFactory"/>
-   </service>
-   <reference cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
+   <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
 </scr:component>
index 0536fb6455bb06704868833151c3658bc12781fa..a1cba1a62bfa4a866a762a9367f84d41ee5d6d2e 100644 (file)
@@ -22,30 +22,31 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.FrameworkUtil;
 
 /** JCR specific init utilities. */
+@Deprecated
 public class JcrInitUtils {
        private final static CmsLog log = CmsLog.getLog(JcrInitUtils.class);
        private final static BundleContext bundleContext = FrameworkUtil.getBundle(JcrInitUtils.class).getBundleContext();
 
-       public static void addToDeployment(CmsDeployment nodeDeployment) {
-               // node repository
-//             Dictionary<String, Object> provided = null;
-               Dictionary<String, Object> provided = nodeDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID,
-                               CmsConstants.NODE);
-               Dictionary<String, Object> nodeConfig = JcrInitUtils.getNodeRepositoryConfig(provided);
-               // node repository is mandatory
-               nodeDeployment.addFactoryDeployConfig(CmsConstants.NODE_REPOS_FACTORY_PID, nodeConfig);
-
-               // additional repositories
-//             dataModels: for (DataModels.DataModel dataModel : dataModels.getNonAbstractDataModels()) {
-//                     if (NodeConstants.NODE_REPOSITORY.equals(dataModel.getName()))
-//                             continue dataModels;
-//                     Dictionary<String, Object> config = JcrInitUtils.getRepositoryConfig(dataModel.getName(),
-//                                     getProps(NodeConstants.NODE_REPOS_FACTORY_PID, dataModel.getName()));
-//                     if (config.size() != 0)
-//                             putFactoryDeployConfig(NodeConstants.NODE_REPOS_FACTORY_PID, config);
-//             }
-
-       }
+//     public static void addToDeployment(CmsDeployment nodeDeployment) {
+//             // node repository
+////           Dictionary<String, Object> provided = null;
+//             Dictionary<String, Object> provided = nodeDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID,
+//                             CmsConstants.NODE);
+//             Dictionary<String, Object> nodeConfig = JcrInitUtils.getNodeRepositoryConfig(provided);
+//             // node repository is mandatory
+//             nodeDeployment.addFactoryDeployConfig(CmsConstants.NODE_REPOS_FACTORY_PID, nodeConfig);
+//
+//             // additional repositories
+////           dataModels: for (DataModels.DataModel dataModel : dataModels.getNonAbstractDataModels()) {
+////                   if (NodeConstants.NODE_REPOSITORY.equals(dataModel.getName()))
+////                           continue dataModels;
+////                   Dictionary<String, Object> config = JcrInitUtils.getRepositoryConfig(dataModel.getName(),
+////                                   getProps(NodeConstants.NODE_REPOS_FACTORY_PID, dataModel.getName()));
+////                   if (config.size() != 0)
+////                           putFactoryDeployConfig(NodeConstants.NODE_REPOS_FACTORY_PID, config);
+////           }
+//
+//     }
 
        /** Override the provided config with the framework properties */
        public static Dictionary<String, Object> getNodeRepositoryConfig(Dictionary<String, Object> provided) {
@@ -62,24 +63,24 @@ public class JcrInitUtils {
                return props;
        }
 
-       public static Dictionary<String, Object> getRepositoryConfig(String dataModelName,
-                       Dictionary<String, Object> provided) {
-               if (dataModelName.equals(CmsConstants.NODE_REPOSITORY) || dataModelName.equals(CmsConstants.EGO_REPOSITORY))
-                       throw new IllegalArgumentException("Data model '" + dataModelName + "' is reserved.");
-               Dictionary<String, Object> props = provided != null ? provided : new Hashtable<String, Object>();
-               for (RepoConf repoConf : RepoConf.values()) {
-                       Object value = getFrameworkProp(
-                                       CmsConstants.NODE_REPOS_PROP_PREFIX + dataModelName + '.' + repoConf.name());
-                       if (value != null) {
-                               props.put(repoConf.name(), value);
-                               if (log.isDebugEnabled())
-                                       log.debug("Set " + dataModelName + " repo configuration " + repoConf.name() + " to " + value);
-                       }
-               }
-               if (props.size() != 0)
-                       props.put(CmsConstants.CN, dataModelName);
-               return props;
-       }
+//     public static Dictionary<String, Object> getRepositoryConfig(String dataModelName,
+//                     Dictionary<String, Object> provided) {
+//             if (dataModelName.equals(CmsConstants.NODE_REPOSITORY) || dataModelName.equals(CmsConstants.EGO_REPOSITORY))
+//                     throw new IllegalArgumentException("Data model '" + dataModelName + "' is reserved.");
+//             Dictionary<String, Object> props = provided != null ? provided : new Hashtable<String, Object>();
+//             for (RepoConf repoConf : RepoConf.values()) {
+//                     Object value = getFrameworkProp(
+//                                     CmsConstants.NODE_REPOS_PROP_PREFIX + dataModelName + '.' + repoConf.name());
+//                     if (value != null) {
+//                             props.put(repoConf.name(), value);
+//                             if (log.isDebugEnabled())
+//                                     log.debug("Set " + dataModelName + " repo configuration " + repoConf.name() + " to " + value);
+//                     }
+//             }
+//             if (props.size() != 0)
+//                     props.put(CmsConstants.CN, dataModelName);
+//             return props;
+//     }
 
        private static void registerRemoteInit(String uri) {
                try {
index 8fb61d70cb0d31ace223f9a5df9c296946478707..6fdd2009ba773e190a8a86cb63a330d2c2c80b65 100644 (file)
@@ -75,7 +75,7 @@ public class CmsJcrDeployment {
        // Readiness
        private boolean nodeAvailable = false;
 
-       CmsDeployment cmsDeployment;
+//     CmsDeployment cmsDeployment;
        public void start() {
                dataModels = new DataModels(bc);
 
@@ -85,7 +85,7 @@ public class CmsJcrDeployment {
 
 //             nodeDeployment = CmsJcrActivator.getService(NodeDeployment.class);
 
-               JcrInitUtils.addToDeployment(cmsDeployment);
+               //JcrInitUtils.addToDeployment(cmsDeployment);
 
 //             contentRepository.registerTypes(NamespaceRegistry.PREFIX_JCR, NamespaceRegistry.NAMESPACE_JCR, null);
 //             contentRepository.registerTypes(NamespaceRegistry.PREFIX_MIX, NamespaceRegistry.NAMESPACE_MIX, null);
@@ -113,9 +113,9 @@ public class CmsJcrDeployment {
 
        }
 
-       public void setCmsDeployment(CmsDeployment cmsDeployment) {
-               this.cmsDeployment = cmsDeployment;
-       }
+//     public void setCmsDeployment(CmsDeployment cmsDeployment) {
+//             this.cmsDeployment = cmsDeployment;
+//     }
 
        /**
         * Checks whether the deployment is available according to expectations, and
@@ -363,7 +363,8 @@ public class CmsJcrDeployment {
        }
 
        boolean isStandalone(String dataModelName) {
-               return cmsDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID, dataModelName) != null;
+               return true;
+               //return cmsDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID, dataModelName) != null;
        }
 
        private void publishLocalRepo(String dataModelName, Repository repository) {
index e05a0023e74acff795c7db5ff34e9d02e49e66bd..11e9a9e92bc0e064cf2fa9d3483251afcc7fd600 100644 (file)
@@ -5,6 +5,7 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Dictionary;
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.Map;
 
 import javax.jcr.Repository;
@@ -14,86 +15,111 @@ import javax.jcr.RepositoryFactory;
 import org.apache.jackrabbit.core.RepositoryContext;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsState;
 import org.argeo.cms.internal.jcr.RepoConf;
 import org.argeo.cms.internal.jcr.RepositoryBuilder;
 import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator;
 import org.argeo.util.LangUtils;
-import org.osgi.framework.Constants;
-import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.cm.ManagedServiceFactory;
 
 /** A {@link ManagedServiceFactory} creating or referencing JCR repositories. */
-public class RepositoryContextsFactory implements ManagedServiceFactory {
+public class RepositoryContextsFactory {
        private final static CmsLog log = CmsLog.getLog(RepositoryContextsFactory.class);
 //     private final BundleContext bc = FrameworkUtil.getBundle(RepositoryServiceFactory.class).getBundleContext();
 
-       private Map<String, RepositoryContext> repositories = new HashMap<String, RepositoryContext>();
-       private Map<String, Object> pidToCn = new HashMap<String, Object>();
+//     private Map<String, RepositoryContext> repositories = new HashMap<String, RepositoryContext>();
+//     private Map<String, Object> pidToCn = new HashMap<String, Object>();
 
-       public void init() {
+       private RepositoryContext repositoryContext;
+
+       private CmsState cmsState;
 
+       public void init() {
+               Dictionary<String, Object> config = getNodeRepositoryConfig();
+               deployRepository(config);
        }
 
        public void destroy() {
-               for (String pid : repositories.keySet()) {
-                       try {
-                               RepositoryContext repositoryContext = repositories.get(pid);
-                               // Must start in another thread otherwise shutdown is interrupted
-                               // TODO use an executor?
-                               new Thread(() -> {
-                                       repositoryContext.getRepository().shutdown();
-                                       if (log.isDebugEnabled())
-                                               log.debug("Shut down repository " + pid
-                                                               + (pidToCn.containsKey(pid) ? " (" + pidToCn.get(pid) + ")" : ""));
-                               }, "Shutdown JCR repository " + pid).start();
-                       } catch (Exception e) {
-                               log.error("Error when shutting down Jackrabbit repository " + pid, e);
-                       }
+               if (this.repositoryContext != null) {
+                       this.repositoryContext.getRepository().shutdown();
                }
+//             for (String pid : repositories.keySet()) {
+//                     try {
+//                             RepositoryContext repositoryContext = repositories.get(pid);
+//                             // Must start in another thread otherwise shutdown is interrupted
+//                             // TODO use an executor?
+//                             new Thread(() -> {
+//                                     repositoryContext.getRepository().shutdown();
+//                                     if (log.isDebugEnabled())
+//                                             log.debug("Shut down repository " + pid
+//                                                             + (pidToCn.containsKey(pid) ? " (" + pidToCn.get(pid) + ")" : ""));
+//                             }, "Shutdown JCR repository " + pid).start();
+//                     } catch (Exception e) {
+//                             log.error("Error when shutting down Jackrabbit repository " + pid, e);
+//                     }
+//             }
        }
 
-       @Override
-       public String getName() {
-               return "Jackrabbit repository service factory";
+//     @Override
+//     public String getName() {
+//             return "Jackrabbit repository service factory";
+//     }
+
+       /** Override the provided config with the framework properties */
+       private Dictionary<String, Object> getNodeRepositoryConfig() {
+               Dictionary<String, Object> props = new Hashtable<String, Object>();
+               for (RepoConf repoConf : RepoConf.values()) {
+                       Object value = getFrameworkProp(CmsConstants.NODE_REPO_PROP_PREFIX + repoConf.name());
+                       if (value != null) {
+                               props.put(repoConf.name(), value);
+                               if (log.isDebugEnabled())
+                                       log.debug("Set node repo configuration " + repoConf.name() + " to " + value);
+                       }
+               }
+               props.put(CmsConstants.CN, CmsConstants.NODE_REPOSITORY);
+               return props;
        }
 
-       @Override
-       public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
-               if (repositories.containsKey(pid))
-                       throw new IllegalArgumentException("Already a repository registered for " + pid);
+//     @Override
+//     public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
+       protected void deployRepository(Dictionary<String, Object> properties) {
+//             if (repositories.containsKey(pid))
+//                     throw new IllegalArgumentException("Already a repository registered for " + pid);
 
                if (properties == null)
                        return;
 
                Object cn = properties.get(CmsConstants.CN);
-               if (cn != null)
-                       for (String otherPid : pidToCn.keySet()) {
-                               Object o = pidToCn.get(otherPid);
-                               if (cn.equals(o)) {
-                                       RepositoryContext repositoryContext = repositories.remove(otherPid);
-                                       repositories.put(pid, repositoryContext);
-                                       if (log.isDebugEnabled())
-                                               log.debug("Ignoring update of Jackrabbit repository " + cn);
-                                       // FIXME perform a proper update (also of the OSGi service)
-                                       return;
-                               }
-                       }
+//             if (cn != null)
+//                     for (String otherPid : pidToCn.keySet()) {
+//                             Object o = pidToCn.get(otherPid);
+//                             if (cn.equals(o)) {
+//                                     RepositoryContext repositoryContext = repositories.remove(otherPid);
+//                                     repositories.put(pid, repositoryContext);
+//                                     if (log.isDebugEnabled())
+//                                             log.debug("Ignoring update of Jackrabbit repository " + cn);
+//                                     // FIXME perform a proper update (also of the OSGi service)
+//                                     return;
+//                             }
+//                     }
 
                try {
                        Object labeledUri = properties.get(RepoConf.labeledUri.name());
                        if (labeledUri == null) {
                                RepositoryBuilder repositoryBuilder = new RepositoryBuilder();
                                RepositoryContext repositoryContext = repositoryBuilder.createRepositoryContext(properties);
-                               repositories.put(pid, repositoryContext);
-                               Dictionary<String, Object> props = LangUtils.dict(Constants.SERVICE_PID, pid);
+//                             repositories.put(pid, repositoryContext);
+//                             Dictionary<String, Object> props = LangUtils.dict(Constants.SERVICE_PID, pid);
+                               Dictionary<String, Object> props = new Hashtable<>();
                                // props.put(ArgeoJcrConstants.JCR_REPOSITORY_URI,
                                // properties.get(RepoConf.labeledUri.name()));
                                if (cn != null) {
                                        props.put(CmsConstants.CN, cn);
                                        // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn);
-                                       pidToCn.put(pid, cn);
+//                                     pidToCn.put(pid, cn);
                                }
                                CmsJcrActivator.registerService(RepositoryContext.class, repositoryContext, props);
+                               this.repositoryContext = repositoryContext;
                        } else {
                                Object defaultWorkspace = properties.get(RepoConf.defaultWorkspace.name());
                                if (defaultWorkspace == null)
@@ -108,14 +134,14 @@ public class RepositoryContextsFactory implements ManagedServiceFactory {
                                Repository repository = repositoryFactory.getRepository(parameters);
                                // Repository repository = NodeUtils.getRepositoryByUri(repositoryFactory,
                                // uri.toString());
-                               Dictionary<String, Object> props = LangUtils.dict(Constants.SERVICE_PID, pid);
+//                             Dictionary<String, Object> props = LangUtils.dict(Constants.SERVICE_PID, pid);
+                               Dictionary<String, Object> props = new Hashtable<>();
                                props.put(RepoConf.labeledUri.name(),
                                                new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null)
                                                                .toString());
                                if (cn != null) {
                                        props.put(CmsConstants.CN, cn);
-                                       // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn);
-                                       pidToCn.put(pid, cn);
+//                                     pidToCn.put(pid, cn);
                                }
                                CmsJcrActivator.registerService(Repository.class, repository, props);
 
@@ -127,17 +153,25 @@ public class RepositoryContextsFactory implements ManagedServiceFactory {
                                }
                        }
                } catch (RepositoryException | URISyntaxException | IOException e) {
-                       throw new IllegalStateException("Cannot create Jackrabbit repository " + pid, e);
+                       throw new IllegalStateException("Cannot create Jackrabbit repository " + properties, e);
                }
 
        }
 
-       @Override
-       public void deleted(String pid) {
-               RepositoryContext repositoryContext = repositories.remove(pid);
-               repositoryContext.getRepository().shutdown();
-               if (log.isDebugEnabled())
-                       log.debug("Deleted repository " + pid);
+//     @Override
+//     public void deleted(String pid) {
+//             RepositoryContext repositoryContext = repositories.remove(pid);
+//             repositoryContext.getRepository().shutdown();
+//             if (log.isDebugEnabled())
+//                     log.debug("Deleted repository " + pid);
+//     }
+
+       private String getFrameworkProp(String key) {
+               return cmsState.getDeployProperty(key);
+       }
+
+       public void setCmsState(CmsState cmsState) {
+               this.cmsState = cmsState;
        }
 
 }
index 5893d2ec52553179bc5ebe4ad32d894d0d99e5e0..c69be8eeb7f50f59c4375b8009b9cdd2ca5eb544 100644 (file)
@@ -5,7 +5,7 @@ import java.util.Dictionary;
 /** A configured node deployment. */
 public interface CmsDeployment {
 
-       void addFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props);
-
-       Dictionary<String, Object> getProps(String factoryPid, String cn);
+//     void addFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props);
+//
+//     Dictionary<String, Object> getProps(String factoryPid, String cn);
 }
index 3828b080b6e029983de83f2311051243ca870ee1..3e0e8b75725f8d1982f63ec0a1da04f22050d3b5 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.api.cms;
 
+import java.nio.file.Path;
 import java.util.UUID;
 
 /** A running node process. */
@@ -9,4 +10,8 @@ public interface CmsState {
        Long getAvailableSince();
 
        UUID getUuid();
+
+       String getDeployProperty(String key);
+       
+       Path getDataPath(String relativePath);
 }
index d36a911102376e4f3f29b14409a184c46d8f4d5f..5f5ed5fcc7932434893af20a8eea125202c4b8d8 100644 (file)
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="false" name="CMS Deployment">
-   <reference bind="setDeployConfig" cardinality="1..1" interface="org.argeo.cms.internal.osgi.DeployConfig" name="DeployConfig" policy="static"/>
    <implementation class="org.argeo.cms.internal.runtime.CmsDeploymentImpl"/>
    <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
    <service>
index 268908e5740e5b586900373ea572a2b94b906026..50a9ea6eb791c1f399d6948fc66ee6edaa4cff85 100644 (file)
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="false" name="Node User Admin">
-   <implementation class="org.argeo.cms.internal.osgi.NodeUserAdmin"/>
+   <implementation class="org.argeo.cms.internal.runtime.CmsUserAdmin"/>
    <property name="service.pid" type="String" value="org.argeo.api.userAdmin"/>
-   <service>
-      <provide interface="org.osgi.service.cm.ManagedServiceFactory"/>
-   </service>
    <reference bind="setTransactionManager" cardinality="1..1" interface="org.argeo.util.transaction.WorkControl" name="WorkControl" policy="static"/>
    <reference bind="setUserTransaction" cardinality="1..1" interface="org.argeo.util.transaction.WorkTransaction" name="WorkTransaction" policy="static"/>
-   <reference cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
+ <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
+ <service>
+    <provide interface="org.osgi.service.useradmin.UserAdmin"/>
+ </service>
 </scr:component>
index 52987f3da8e9aa51e17f334d5124a8e99439c0b8..d0047dcc6a0b9e320289df44ddf5473923f87454 100644 (file)
@@ -12,7 +12,6 @@ OSGI-INF/cmsState.xml,\
 OSGI-INF/simpleTransactionManager.xml,\
 OSGI-INF/nodeUserAdmin.xml,\
 OSGI-INF/cmsUserManager.xml,\
-OSGI-INF/deployConfig.xml,\
 OSGI-INF/uuidFactory.xml,\
 OSGI-INF/acrContentRepository.xml,\
 OSGI-INF/cmsDeployment.xml,\
index b5734afd3221957b1fe80a7ef82ffc21f3090993..19875e88ae4b9a83b5cd636e595e3a3e44137a99 100644 (file)
@@ -211,7 +211,8 @@ public class RemoteSessionLoginModule implements LoginModule {
                        if (log.isDebugEnabled())
                                log.debug("Client certificate " + certDn + " verified by servlet container");
                } // Reverse proxy verified the client certificate
-               String clientDnHttpHeader = KernelUtils.getFrameworkProp(CmsConstants.HTTP_PROXY_SSL_DN);
+               String clientDnHttpHeader = CmsContextImpl.getCmsContext().getCmsState()
+                               .getDeployProperty(CmsConstants.HTTP_PROXY_SSL_DN);
                if (clientDnHttpHeader != null) {
                        String certDn = req.getHeader(clientDnHttpHeader);
                        // TODO retrieve more cf. https://httpd.apache.org/docs/current/mod/mod_ssl.html
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/http/InternalHttpConstants.java b/org.argeo.cms/src/org/argeo/cms/internal/http/InternalHttpConstants.java
deleted file mode 100644 (file)
index c888c29..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.argeo.cms.internal.http;
-
-/** Compatible with Jetty. */
-public interface InternalHttpConstants {
-       static final String HTTP_ENABLED = "http.enabled";
-       static final String HTTP_PORT = "http.port";
-       static final String HTTP_HOST = "http.host";
-       static final String HTTPS_ENABLED = "https.enabled";
-       static final String HTTPS_HOST = "https.host";
-       static final String HTTPS_PORT = "https.port";
-       static final String SSL_KEYSTORE = "ssl.keystore";
-       static final String SSL_PASSWORD = "ssl.password";
-       static final String SSL_KEYPASSWORD = "ssl.keypassword";
-       static final String SSL_NEEDCLIENTAUTH = "ssl.needclientauth";
-       static final String SSL_WANTCLIENTAUTH = "ssl.wantclientauth";
-       static final String SSL_PROTOCOL = "ssl.protocol";
-       static final String SSL_ALGORITHM = "ssl.algorithm";
-       static final String SSL_KEYSTORETYPE = "ssl.keystoretype";
-       static final String JETTY_PROPERTY_PREFIX = "org.eclipse.equinox.http.jetty.";
-       // Argeo specific
-       static final String WEBSOCKET_ENABLED = "websocket.enabled";
-
-}
index 038d7029ca9cf6b720c1b8c01ef85e95384c32aa..d4b2f4595a8b400b0cadf5c8383c80614b0a1dcb 100644 (file)
@@ -8,16 +8,13 @@ import org.argeo.cms.ArgeoLogger;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
 import org.osgi.service.condpermadmin.BundleLocationCondition;
 import org.osgi.service.condpermadmin.ConditionInfo;
 import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
 import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
 import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
-import org.osgi.service.http.HttpService;
 import org.osgi.service.log.LogReaderService;
 import org.osgi.service.permissionadmin.PermissionInfo;
-import org.osgi.util.tracker.ServiceTracker;
 
 /**
  * Activates the kernel. Gives access to kernel information for the rest of the
@@ -179,18 +176,18 @@ public class CmsActivator implements BundleActivator {
 //             userAdminSt = new ServiceTracker<>(bundleContext, UserAdmin.class, null);
 //             userAdminSt.open();
 
-               ServiceTracker<?, ?> httpSt = new ServiceTracker<HttpService, HttpService>(bc, HttpService.class, null) {
-
-                       @Override
-                       public HttpService addingService(ServiceReference<HttpService> sr) {
-                               Object httpPort = sr.getProperty("http.port");
-                               Object httpsPort = sr.getProperty("https.port");
-                               log.info(httpPortsMsg(httpPort, httpsPort));
-                               close();
-                               return super.addingService(sr);
-                       }
-               };
-               httpSt.open();
+//             ServiceTracker<?, ?> httpSt = new ServiceTracker<HttpService, HttpService>(bc, HttpService.class, null) {
+//
+//                     @Override
+//                     public HttpService addingService(ServiceReference<HttpService> sr) {
+//                             Object httpPort = sr.getProperty("http.port");
+//                             Object httpsPort = sr.getProperty("https.port");
+//                             log.info(httpPortsMsg(httpPort, httpsPort));
+//                             close();
+//                             return super.addingService(sr);
+//                     }
+//             };
+//             httpSt.open();
        }
 
        private String httpPortsMsg(Object httpPort, Object httpsPort) {
index b8fa8a73f49438bc15bbd439c185151f08157fbf..205ab35de7b0cc0f95ea1f5eb0618f2dc47568b3 100644 (file)
@@ -70,59 +70,50 @@ public class DeployConfig {
        private void setFromFrameworkProperties(boolean isFirstInit) {
 
                // user admin
-               List<Dictionary<String, Object>> userDirectoryConfigs = InitUtils.getUserDirectoryConfigs();
-               if (userDirectoryConfigs.size() != 0) {
-                       List<String> activeCns = new ArrayList<>();
-                       for (int i = 0; i < userDirectoryConfigs.size(); i++) {
-                               Dictionary<String, Object> userDirectoryConfig = userDirectoryConfigs.get(i);
-                               String baseDn = (String) userDirectoryConfig.get(DirectoryConf.baseDn.name());
-                               String cn;
-                               if (CmsConstants.ROLES_BASEDN.equals(baseDn))
-                                       cn = ROLES;
-                               else
-                                       cn = DirectoryConf.baseDnHash(userDirectoryConfig);
-                               activeCns.add(cn);
-                               userDirectoryConfig.put(CmsConstants.CN, cn);
-                               putFactoryDeployConfig(CmsConstants.NODE_USER_ADMIN_PID, userDirectoryConfig);
-                       }
-                       // disable others
-                       LdapName userAdminFactoryName = serviceFactoryDn(CmsConstants.NODE_USER_ADMIN_PID);
-                       for (LdapName name : deployConfigs.keySet()) {
-                               if (name.startsWith(userAdminFactoryName) && !name.equals(userAdminFactoryName)) {
-//                                     try {
-                                       Attributes attrs = deployConfigs.get(name);
-                                       String cn = name.getRdn(name.size() - 1).getValue().toString();
-                                       if (!activeCns.contains(cn)) {
-                                               attrs.put(DirectoryConf.disabled.name(), "true");
-                                       }
-//                                     } catch (Exception e) {
-//                                             throw new CmsException("Cannot disable user directory " + name, e);
+//             List<Dictionary<String, Object>> userDirectoryConfigs = InitUtils.getUserDirectoryConfigs();
+//             if (userDirectoryConfigs.size() != 0) {
+//                     List<String> activeCns = new ArrayList<>();
+//                     for (int i = 0; i < userDirectoryConfigs.size(); i++) {
+//                             Dictionary<String, Object> userDirectoryConfig = userDirectoryConfigs.get(i);
+//                             String baseDn = (String) userDirectoryConfig.get(DirectoryConf.baseDn.name());
+//                             String cn;
+//                             if (CmsConstants.ROLES_BASEDN.equals(baseDn))
+//                                     cn = ROLES;
+//                             else
+//                                     cn = DirectoryConf.baseDnHash(userDirectoryConfig);
+//                             activeCns.add(cn);
+//                             userDirectoryConfig.put(CmsConstants.CN, cn);
+//                             putFactoryDeployConfig(CmsConstants.NODE_USER_ADMIN_PID, userDirectoryConfig);
+//                     }
+//                     // disable others
+//                     LdapName userAdminFactoryName = serviceFactoryDn(CmsConstants.NODE_USER_ADMIN_PID);
+//                     for (LdapName name : deployConfigs.keySet()) {
+//                             if (name.startsWith(userAdminFactoryName) && !name.equals(userAdminFactoryName)) {
+////                                   try {
+//                                     Attributes attrs = deployConfigs.get(name);
+//                                     String cn = name.getRdn(name.size() - 1).getValue().toString();
+//                                     if (!activeCns.contains(cn)) {
+//                                             attrs.put(DirectoryConf.disabled.name(), "true");
 //                                     }
-                               }
-                       }
-               }
+////                                   } catch (Exception e) {
+////                                           throw new CmsException("Cannot disable user directory " + name, e);
+////                                   }
+//                             }
+//                     }
+//             }
 
                // http server
-               Dictionary<String, Object> webServerConfig = InitUtils
-                               .getHttpServerConfig(getProps(KernelConstants.JETTY_FACTORY_PID, CmsConstants.DEFAULT));
-               if (!webServerConfig.isEmpty()) {
-                       // TODO check for other customizers
-//                     webServerConfig.put("customizer.class", "org.argeo.equinox.jetty.CmsJettyCustomizer");
-                       putFactoryDeployConfig(KernelConstants.JETTY_FACTORY_PID, webServerConfig);
-               }
-//             LdapName defaultHttpServiceDn = serviceDn(KernelConstants.JETTY_FACTORY_PID, CmsConstants.DEFAULT);
-//             if (deployConfigs.containsKey(defaultHttpServiceDn)) {
-//                     // remove old default configs since we have now to start Jetty servlet bridge
-//                     // indirectly
-//                     deployConfigs.remove(defaultHttpServiceDn);
+//             Dictionary<String, Object> webServerConfig = InitUtils
+//                             .getHttpServerConfig(getProps(KernelConstants.JETTY_FACTORY_PID, CmsConstants.DEFAULT));
+//             if (!webServerConfig.isEmpty()) {
+//                     // TODO check for other customizers
+//                     putFactoryDeployConfig(KernelConstants.JETTY_FACTORY_PID, webServerConfig);
 //             }
 
                // SAVE
                save();
                //
 
-//             Dictionary<String, Object> webServerConfig = InitUtils
-//                             .getHttpServerConfig(getProps(KernelConstants.JETTY_FACTORY_PID, CmsConstants.DEFAULT));
        }
 
        public void start() {
index 44a2866f8df50613cbeede05262e66c660272428..5ba811c92941ad767e9b6ae626ddc4e6cd0dfe60 100644 (file)
@@ -19,28 +19,28 @@ public class CmsDeploymentImpl implements CmsDeployment {
        private HttpService httpService;
 
        private CmsState cmsState;
-       private DeployConfig deployConfig;
+//     private DeployConfig deployConfig;
 
        public void start() {
-               httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null;
-               if (deployConfig.hasDomain()) {
-                       loadIpaJaasConfiguration();
-               }
+//             httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null;
+//             if (deployConfig.hasDomain()) {
+//                     loadIpaJaasConfiguration();
+//             }
        }
 
-       public void addFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props) {
-               deployConfig.putFactoryDeployConfig(factoryPid, props);
-               deployConfig.save();
-               try {
-                       deployConfig.loadConfigs();
-               } catch (IOException e) {
-                       throw new IllegalStateException(e);
-               }
-       }
-
-       public Dictionary<String, Object> getProps(String factoryPid, String cn) {
-               return deployConfig.getProps(factoryPid, cn);
-       }
+//     public void addFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props) {
+//             deployConfig.putFactoryDeployConfig(factoryPid, props);
+//             deployConfig.save();
+//             try {
+//                     deployConfig.loadConfigs();
+//             } catch (IOException e) {
+//                     throw new IllegalStateException(e);
+//             }
+//     }
+//
+//     public Dictionary<String, Object> getProps(String factoryPid, String cn) {
+//             return deployConfig.getProps(factoryPid, cn);
+//     }
 
        public boolean isHttpAvailableOrNotExpected() {
                return (httpExpected ? httpService != null : true);
@@ -56,14 +56,14 @@ public class CmsDeploymentImpl implements CmsDeployment {
        }
 
        public void stop() {
-               if (deployConfig != null) {
-                       deployConfig.save();
-               }
+//             if (deployConfig != null) {
+//                     deployConfig.save();
+//             }
        }
 
-       public void setDeployConfig(DeployConfig deployConfig) {
-               this.deployConfig = deployConfig;
-       }
+//     public void setDeployConfig(DeployConfig deployConfig) {
+//             this.deployConfig = deployConfig;
+//     }
 
        public void setCmsState(CmsState cmsState) {
                this.cmsState = cmsState;
index 41e32653432cc7b4e621109c0c9d67bfc92b9dc6..ae85a2fc836e73089eeb2d069ac56f0efdfd2994 100644 (file)
@@ -3,6 +3,7 @@ package org.argeo.cms.internal.runtime;
 import java.net.InetAddress;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.nio.file.Path;
 import java.util.UUID;
 
 import javax.security.auth.login.Configuration;
@@ -81,6 +82,16 @@ public class CmsStateImpl implements CmsState {
                log.info("## ARGEO CMS STOPPED after " + (duration / 60) + "h " + (duration % 60) + "min uptime ##");
        }
 
+       @Override
+       public String getDeployProperty(String key) {
+               return KernelUtils.getFrameworkProp(key);
+       }
+
+       @Override
+       public Path getDataPath(String relativePath) {
+               return  KernelUtils.getOsgiInstancePath(relativePath);
+       }
+
        @Override
        public Long getAvailableSince() {
                return availableSince;
index 64e32b16a36a7d90e8645777b5e8727c789ec04b..18a880e31470f2738bb5af79dd3e696c3fca5190 100644 (file)
@@ -5,12 +5,14 @@ import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 
@@ -31,10 +33,11 @@ import org.apache.commons.httpclient.params.HttpParams;
 import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsState;
 import org.argeo.cms.internal.http.client.HttpCredentialProvider;
 import org.argeo.cms.internal.http.client.SpnegoAuthScheme;
-import org.argeo.osgi.useradmin.DirectoryUserAdmin;
 import org.argeo.osgi.useradmin.AggregatingUserAdmin;
+import org.argeo.osgi.useradmin.DirectoryUserAdmin;
 import org.argeo.osgi.useradmin.UserDirectory;
 import org.argeo.util.directory.DirectoryConf;
 import org.argeo.util.naming.dns.DnsBrowser;
@@ -65,14 +68,27 @@ public class CmsUserAdmin extends AggregatingUserAdmin {
        private WorkControl transactionManager;
        private WorkTransaction userTransaction;
 
+       private CmsState cmsState;
+
        public CmsUserAdmin() {
                super(CmsConstants.ROLES_BASEDN, CmsConstants.TOKENS_BASEDN);
        }
 
        public void start() {
+               super.start();
+               List<Dictionary<String, Object>> configs = InitUtils.getUserDirectoryConfigs();
+               for (Dictionary<String, Object> config : configs) {
+                       UserDirectory userDirectory = enableUserDirectory(config);
+                       if (userDirectory.getRealm().isPresent())
+                               loadIpaJaasConfiguration();
+               }
        }
 
        public void stop() {
+//             for (UserDirectory userDirectory : getUserDirectories()) {
+//                     removeUserDirectory(userDirectory);
+//             }
+               super.stop();
        }
 
        public UserDirectory enableUserDirectory(Dictionary<String, ?> properties) {
@@ -206,6 +222,15 @@ public class CmsUserAdmin extends AggregatingUserAdmin {
                }
        }
 
+       private void loadIpaJaasConfiguration() {
+               if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) {
+                       String jaasConfig = KernelConstants.JAAS_CONFIG_IPA;
+                       URL url = getClass().getClassLoader().getResource(jaasConfig);
+                       KernelUtils.setJaasConfiguration(url);
+                       log.debug("Set IPA JAAS configuration.");
+               }
+       }
+
        private String getKerberosServicePrincipal(String realm) {
                String hostname;
                try (DnsBrowser dnsBrowser = new DnsBrowser()) {
@@ -288,8 +313,8 @@ public class CmsUserAdmin extends AggregatingUserAdmin {
                this.userTransaction = userTransaction;
        }
 
-       /*
-        * STATIC
-        */
+       public void setCmsState(CmsState cmsState) {
+               this.cmsState = cmsState;
+       }
 
 }
index 986f7914d03a7d56edbaea56d6edb31fe5e295b4..f634e43b524b67a33d43837448a47f9a13f68f4b 100644 (file)
@@ -5,25 +5,14 @@ import static org.argeo.cms.internal.runtime.KernelUtils.getFrameworkProp;
 import java.io.File;
 import java.io.FileFilter;
 import java.io.IOException;
-import java.io.Reader;
-import java.net.InetAddress;
 import java.net.URI;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.KeyStore;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Dictionary;
-import java.util.Hashtable;
 import java.util.List;
 
-import javax.security.auth.x500.X500Principal;
-
 import org.apache.commons.io.FileUtils;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.internal.http.InternalHttpConstants;
 import org.argeo.util.directory.DirectoryConf;
 
 /**
@@ -34,92 +23,92 @@ public class InitUtils {
        private final static CmsLog log = CmsLog.getLog(InitUtils.class);
 
        /** Override the provided config with the framework properties */
-       public static Dictionary<String, Object> getHttpServerConfig(Dictionary<String, Object> provided) {
-               String httpPort = getFrameworkProp("org.osgi.service.http.port");
-               String httpsPort = getFrameworkProp("org.osgi.service.http.port.secure");
-               /// TODO make it more generic
-               String httpHost = getFrameworkProp(
-                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.HTTP_HOST);
-               String httpsHost = getFrameworkProp(
-                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.HTTPS_HOST);
-               String webSocketEnabled = getFrameworkProp(
-                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.WEBSOCKET_ENABLED);
-
-               final Hashtable<String, Object> props = new Hashtable<String, Object>();
-               // try {
-               if (httpPort != null || httpsPort != null) {
-                       boolean httpEnabled = httpPort != null;
-                       props.put(InternalHttpConstants.HTTP_ENABLED, httpEnabled);
-                       boolean httpsEnabled = httpsPort != null;
-                       props.put(InternalHttpConstants.HTTPS_ENABLED, httpsEnabled);
-
-                       if (httpEnabled) {
-                               props.put(InternalHttpConstants.HTTP_PORT, httpPort);
-                               if (httpHost != null)
-                                       props.put(InternalHttpConstants.HTTP_HOST, httpHost);
-                       }
-
-                       if (httpsEnabled) {
-                               props.put(InternalHttpConstants.HTTPS_PORT, httpsPort);
-                               if (httpsHost != null)
-                                       props.put(InternalHttpConstants.HTTPS_HOST, httpsHost);
-
-                               // server certificate
-                               Path keyStorePath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_KEYSTORE_PATH);
-                               Path pemKeyPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_PEM_KEY_PATH);
-                               Path pemCertPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_PEM_CERT_PATH);
-                               String keyStorePasswordStr = getFrameworkProp(
-                                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_PASSWORD);
-                               char[] keyStorePassword;
-                               if (keyStorePasswordStr == null)
-                                       keyStorePassword = "changeit".toCharArray();
-                               else
-                                       keyStorePassword = keyStorePasswordStr.toCharArray();
-
-                               // if PEM files both exists, update the PKCS12 file
-                               if (Files.exists(pemCertPath) && Files.exists(pemKeyPath)) {
-                                       // TODO check certificate update time? monitor changes?
-                                       KeyStore keyStore = PkiUtils.getKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
-                                       try (Reader key = Files.newBufferedReader(pemKeyPath, StandardCharsets.US_ASCII);
-                                                       Reader cert = Files.newBufferedReader(pemCertPath, StandardCharsets.US_ASCII);) {
-                                               PkiUtils.loadPem(keyStore, key, keyStorePassword, cert);
-                                               PkiUtils.saveKeyStore(keyStorePath, keyStorePassword, keyStore);
-                                               if (log.isDebugEnabled())
-                                                       log.debug("PEM certificate stored in " + keyStorePath);
-                                       } catch (IOException e) {
-                                               log.error("Cannot read PEM files " + pemKeyPath + " and " + pemCertPath, e);
-                                       }
-                               }
-
-                               if (!Files.exists(keyStorePath))
-                                       createSelfSignedKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
-                               props.put(InternalHttpConstants.SSL_KEYSTORETYPE, PkiUtils.PKCS12);
-                               props.put(InternalHttpConstants.SSL_KEYSTORE, keyStorePath.toString());
-                               props.put(InternalHttpConstants.SSL_PASSWORD, new String(keyStorePassword));
-
-//                             props.put(InternalHttpConstants.SSL_KEYSTORETYPE, "PKCS11");
-//                             props.put(InternalHttpConstants.SSL_KEYSTORE, "../../nssdb");
-//                             props.put(InternalHttpConstants.SSL_PASSWORD, keyStorePassword);
-
-                               // client certificate authentication
-                               String wantClientAuth = getFrameworkProp(
-                                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_WANTCLIENTAUTH);
-                               if (wantClientAuth != null)
-                                       props.put(InternalHttpConstants.SSL_WANTCLIENTAUTH, Boolean.parseBoolean(wantClientAuth));
-                               String needClientAuth = getFrameworkProp(
-                                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_NEEDCLIENTAUTH);
-                               if (needClientAuth != null)
-                                       props.put(InternalHttpConstants.SSL_NEEDCLIENTAUTH, Boolean.parseBoolean(needClientAuth));
-                       }
-
-                       // web socket
-                       if (webSocketEnabled != null && webSocketEnabled.equals("true"))
-                               props.put(InternalHttpConstants.WEBSOCKET_ENABLED, true);
-
-                       props.put(CmsConstants.CN, CmsConstants.DEFAULT);
-               }
-               return props;
-       }
+//     public static Dictionary<String, Object> getHttpServerConfig(Dictionary<String, Object> provided) {
+//             String httpPort = getFrameworkProp("org.osgi.service.http.port");
+//             String httpsPort = getFrameworkProp("org.osgi.service.http.port.secure");
+//             /// TODO make it more generic
+//             String httpHost = getFrameworkProp(
+//                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.HTTP_HOST);
+//             String httpsHost = getFrameworkProp(
+//                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.HTTPS_HOST);
+//             String webSocketEnabled = getFrameworkProp(
+//                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.WEBSOCKET_ENABLED);
+//
+//             final Hashtable<String, Object> props = new Hashtable<String, Object>();
+//             // try {
+//             if (httpPort != null || httpsPort != null) {
+//                     boolean httpEnabled = httpPort != null;
+//                     props.put(InternalHttpConstants.HTTP_ENABLED, httpEnabled);
+//                     boolean httpsEnabled = httpsPort != null;
+//                     props.put(InternalHttpConstants.HTTPS_ENABLED, httpsEnabled);
+//
+//                     if (httpEnabled) {
+//                             props.put(InternalHttpConstants.HTTP_PORT, httpPort);
+//                             if (httpHost != null)
+//                                     props.put(InternalHttpConstants.HTTP_HOST, httpHost);
+//                     }
+//
+//                     if (httpsEnabled) {
+//                             props.put(InternalHttpConstants.HTTPS_PORT, httpsPort);
+//                             if (httpsHost != null)
+//                                     props.put(InternalHttpConstants.HTTPS_HOST, httpsHost);
+//
+//                             // server certificate
+//                             Path keyStorePath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_KEYSTORE_PATH);
+//                             Path pemKeyPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_PEM_KEY_PATH);
+//                             Path pemCertPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_PEM_CERT_PATH);
+//                             String keyStorePasswordStr = getFrameworkProp(
+//                                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_PASSWORD);
+//                             char[] keyStorePassword;
+//                             if (keyStorePasswordStr == null)
+//                                     keyStorePassword = "changeit".toCharArray();
+//                             else
+//                                     keyStorePassword = keyStorePasswordStr.toCharArray();
+//
+//                             // if PEM files both exists, update the PKCS12 file
+//                             if (Files.exists(pemCertPath) && Files.exists(pemKeyPath)) {
+//                                     // TODO check certificate update time? monitor changes?
+//                                     KeyStore keyStore = PkiUtils.getKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
+//                                     try (Reader key = Files.newBufferedReader(pemKeyPath, StandardCharsets.US_ASCII);
+//                                                     Reader cert = Files.newBufferedReader(pemCertPath, StandardCharsets.US_ASCII);) {
+//                                             PkiUtils.loadPem(keyStore, key, keyStorePassword, cert);
+//                                             PkiUtils.saveKeyStore(keyStorePath, keyStorePassword, keyStore);
+//                                             if (log.isDebugEnabled())
+//                                                     log.debug("PEM certificate stored in " + keyStorePath);
+//                                     } catch (IOException e) {
+//                                             log.error("Cannot read PEM files " + pemKeyPath + " and " + pemCertPath, e);
+//                                     }
+//                             }
+//
+//                             if (!Files.exists(keyStorePath))
+//                                     createSelfSignedKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
+//                             props.put(InternalHttpConstants.SSL_KEYSTORETYPE, PkiUtils.PKCS12);
+//                             props.put(InternalHttpConstants.SSL_KEYSTORE, keyStorePath.toString());
+//                             props.put(InternalHttpConstants.SSL_PASSWORD, new String(keyStorePassword));
+//
+////                           props.put(InternalHttpConstants.SSL_KEYSTORETYPE, "PKCS11");
+////                           props.put(InternalHttpConstants.SSL_KEYSTORE, "../../nssdb");
+////                           props.put(InternalHttpConstants.SSL_PASSWORD, keyStorePassword);
+//
+//                             // client certificate authentication
+//                             String wantClientAuth = getFrameworkProp(
+//                                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_WANTCLIENTAUTH);
+//                             if (wantClientAuth != null)
+//                                     props.put(InternalHttpConstants.SSL_WANTCLIENTAUTH, Boolean.parseBoolean(wantClientAuth));
+//                             String needClientAuth = getFrameworkProp(
+//                                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_NEEDCLIENTAUTH);
+//                             if (needClientAuth != null)
+//                                     props.put(InternalHttpConstants.SSL_NEEDCLIENTAUTH, Boolean.parseBoolean(needClientAuth));
+//                     }
+//
+//                     // web socket
+//                     if (webSocketEnabled != null && webSocketEnabled.equals("true"))
+//                             props.put(InternalHttpConstants.WEBSOCKET_ENABLED, true);
+//
+//                     props.put(CmsConstants.CN, CmsConstants.DEFAULT);
+//             }
+//             return props;
+//     }
 
        public static List<Dictionary<String, Object>> getUserDirectoryConfigs() {
                List<Dictionary<String, Object>> res = new ArrayList<>();
@@ -258,33 +247,4 @@ public class InitUtils {
                }
        }
 
-       private static void createSelfSignedKeyStore(Path keyStorePath, char[] keyStorePassword, String keyStoreType) {
-               // for (Provider provider : Security.getProviders())
-               // System.out.println(provider.getName());
-//             File keyStoreFile = keyStorePath.toFile();
-               char[] keyPwd = Arrays.copyOf(keyStorePassword, keyStorePassword.length);
-               if (!Files.exists(keyStorePath)) {
-                       try {
-                               Files.createDirectories(keyStorePath.getParent());
-                               KeyStore keyStore = PkiUtils.getKeyStore(keyStorePath, keyStorePassword, keyStoreType);
-                               PkiUtils.generateSelfSignedCertificate(keyStore,
-                                               new X500Principal("CN=" + InetAddress.getLocalHost().getHostName() + ",OU=UNSECURE,O=UNSECURE"),
-                                               1024, keyPwd);
-                               PkiUtils.saveKeyStore(keyStorePath, keyStorePassword, keyStore);
-                               if (log.isDebugEnabled())
-                                       log.debug("Created self-signed unsecure keystore " + keyStorePath);
-                       } catch (Exception e) {
-                               try {
-                                       if (Files.size(keyStorePath) == 0)
-                                               Files.delete(keyStorePath);
-                               } catch (IOException e1) {
-                                       // silent
-                               }
-                               log.error("Cannot create keystore " + keyStorePath, e);
-                       }
-               } else {
-                       throw new IllegalStateException("Keystore " + keyStorePath + " already exists");
-               }
-       }
-
 }
index dfe86cfaaf7e95a8621a80bf30fb3ae6a2b88969..a02c557f2a79b8b51e021b1e38efc34c35b81d2e 100644 (file)
@@ -12,9 +12,6 @@ public interface KernelConstants {
 
        // Files
        String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + CmsConstants.DEPLOY_BASEDN + ".ldif";
-       String DEFAULT_KEYSTORE_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".p12";
-       String DEFAULT_PEM_KEY_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".key";
-       String DEFAULT_PEM_CERT_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".crt";
        String NODE_KEY_TAB_PATH = DIR_NODE + "/krb5.keytab";
 
        // Security
index 60c796af73280639bc8f03868ec5ec67ed03cbb9..5635bccfed34a9e5dff34999b84430ce267c6b7d 100644 (file)
@@ -101,7 +101,7 @@ public class KernelUtils implements KernelConstants {
                return value;
        }
 
-       public static String getFrameworkProp(String key) {
+       static String getFrameworkProp(String key) {
                return getFrameworkProp(key, null);
        }
 
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/PkiUtils.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/PkiUtils.java
deleted file mode 100644 (file)
index 474a899..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-package org.argeo.cms.internal.runtime;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.math.BigInteger;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.PrivateKey;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Date;
-
-import javax.security.auth.x500.X500Principal;
-
-import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.X509v3CertificateBuilder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.openssl.PEMParser;
-import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
-import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.InputDecryptorProvider;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
-import org.bouncycastle.pkcs.PKCSException;
-
-/**
- * Utilities around private keys and certificate, mostly wrapping BouncyCastle
- * implementations.
- */
-class PkiUtils {
-       final static String PKCS12 = "PKCS12";
-
-       private final static String SECURITY_PROVIDER;
-       static {
-               Security.addProvider(new BouncyCastleProvider());
-               SECURITY_PROVIDER = "BC";
-       }
-
-       public static X509Certificate generateSelfSignedCertificate(KeyStore keyStore, X500Principal x500Principal,
-                       int keySize, char[] keyPassword) {
-               try {
-                       KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", SECURITY_PROVIDER);
-                       kpGen.initialize(keySize, new SecureRandom());
-                       KeyPair pair = kpGen.generateKeyPair();
-                       Date notBefore = new Date(System.currentTimeMillis() - 10000);
-                       Date notAfter = new Date(System.currentTimeMillis() + 365 * 24L * 3600 * 1000);
-                       BigInteger serial = BigInteger.valueOf(System.currentTimeMillis());
-                       X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(x500Principal, serial, notBefore,
-                                       notAfter, x500Principal, pair.getPublic());
-                       ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(SECURITY_PROVIDER)
-                                       .build(pair.getPrivate());
-                       X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER)
-                                       .getCertificate(certGen.build(sigGen));
-                       cert.checkValidity(new Date());
-                       cert.verify(cert.getPublicKey());
-
-                       keyStore.setKeyEntry(x500Principal.getName(), pair.getPrivate(), keyPassword, new Certificate[] { cert });
-                       return cert;
-               } catch (GeneralSecurityException | OperatorCreationException e) {
-                       throw new RuntimeException("Cannot generate self-signed certificate", e);
-               }
-       }
-
-       public static KeyStore getKeyStore(Path keyStoreFile, char[] keyStorePassword, String keyStoreType) {
-               try {
-                       KeyStore store = KeyStore.getInstance(keyStoreType, SECURITY_PROVIDER);
-                       if (Files.exists(keyStoreFile)) {
-                               try (InputStream fis = Files.newInputStream(keyStoreFile)) {
-                                       store.load(fis, keyStorePassword);
-                               }
-                       } else {
-                               store.load(null);
-                       }
-                       return store;
-               } catch (GeneralSecurityException | IOException e) {
-                       throw new RuntimeException("Cannot load keystore " + keyStoreFile, e);
-               }
-       }
-
-       public static void saveKeyStore(Path keyStoreFile, char[] keyStorePassword, KeyStore keyStore) {
-               try {
-                       try (OutputStream fis = Files.newOutputStream(keyStoreFile)) {
-                               keyStore.store(fis, keyStorePassword);
-                       }
-               } catch (GeneralSecurityException | IOException e) {
-                       throw new RuntimeException("Cannot save keystore " + keyStoreFile, e);
-               }
-       }
-
-//     public static byte[] pemToPKCS12(final String keyFile, final String cerFile, final String password)
-//                     throws Exception {
-//             // Get the private key
-//             FileReader reader = new FileReader(keyFile);
-//
-//             PEMReader pem = new PemReader(reader, new PasswordFinder() {
-//                     @Override
-//                     public char[] getPassword() {
-//                             return password.toCharArray();
-//                     }
-//             });
-//
-//             PrivateKey key = ((KeyPair) pem.readObject()).getPrivate();
-//
-//             pem.close();
-//             reader.close();
-//
-//             // Get the certificate
-//             reader = new FileReader(cerFile);
-//             pem = new PEMReader(reader);
-//
-//             X509Certificate cert = (X509Certificate) pem.readObject();
-//
-//             pem.close();
-//             reader.close();
-//
-//             // Put them into a PKCS12 keystore and write it to a byte[]
-//             ByteArrayOutputStream bos = new ByteArrayOutputStream();
-//             KeyStore ks = KeyStore.getInstance("PKCS12");
-//             ks.load(null);
-//             ks.setKeyEntry("alias", (Key) key, password.toCharArray(), new java.security.cert.Certificate[] { cert });
-//             ks.store(bos, password.toCharArray());
-//             bos.close();
-//             return bos.toByteArray();
-//     }
-
-       public static void loadPem(KeyStore keyStore, Reader key, char[] keyPassword, Reader cert) {
-               PrivateKey privateKey = loadPemPrivateKey(key, keyPassword);
-               X509Certificate certificate = loadPemCertificate(cert);
-               try {
-                       keyStore.setKeyEntry(certificate.getSubjectX500Principal().getName(), privateKey, keyPassword,
-                                       new java.security.cert.Certificate[] { certificate });
-               } catch (KeyStoreException e) {
-                       throw new RuntimeException("Cannot store PEM certificate", e);
-               }
-       }
-
-       public static PrivateKey loadPemPrivateKey(Reader reader, char[] keyPassword) {
-               try (PEMParser pemParser = new PEMParser(reader)) {
-                       JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
-                       Object object = pemParser.readObject();
-                       PrivateKeyInfo privateKeyInfo;
-                       if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
-                               if (keyPassword == null)
-                                       throw new IllegalArgumentException("A key password is required");
-                               InputDecryptorProvider decProv = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(keyPassword);
-                               privateKeyInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decProv);
-                       } else if (object instanceof PrivateKeyInfo) {
-                               privateKeyInfo = (PrivateKeyInfo) object;
-                       } else {
-                               throw new IllegalArgumentException("Unsupported format for private key");
-                       }
-                       return converter.getPrivateKey(privateKeyInfo);
-               } catch (IOException | OperatorCreationException | PKCSException e) {
-                       throw new RuntimeException("Cannot read private key", e);
-               }
-       }
-
-       public static X509Certificate loadPemCertificate(Reader reader) {
-               try (PEMParser pemParser = new PEMParser(reader)) {
-                       X509CertificateHolder certHolder = (X509CertificateHolder) pemParser.readObject();
-                       X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER)
-                                       .getCertificate(certHolder);
-                       return cert;
-               } catch (IOException | CertificateException e) {
-                       throw new RuntimeException("Cannot read private key", e);
-               }
-       }
-
-       public static void main(String[] args) throws Exception {
-               final String ALGORITHM = "RSA";
-               final String provider = "BC";
-               SecureRandom secureRandom = new SecureRandom();
-               long begin = System.currentTimeMillis();
-               for (int i = 512; i < 1024; i = i + 2) {
-                       try {
-                               KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM, provider);
-                               keyGen.initialize(i, secureRandom);
-                               keyGen.generateKeyPair();
-                       } catch (Exception e) {
-                               System.err.println(i + " : " + e.getMessage());
-                       }
-               }
-               System.out.println((System.currentTimeMillis() - begin) + " ms");
-
-               // // String text = "a";
-               // String text =
-               // "testtesttesttesttesttesttesttesttesttesttesttesttesttesttest";
-               // try {
-               // System.out.println(text);
-               // PrivateKey privateKey;
-               // PublicKey publicKey;
-               // char[] password = "changeit".toCharArray();
-               // String alias = "CN=test";
-               // KeyStore keyStore = KeyStore.getInstance("pkcs12");
-               // File p12file = new File("test.p12");
-               // p12file.delete();
-               // if (!p12file.exists()) {
-               // keyStore.load(null);
-               // generateSelfSignedCertificate(keyStore, new X500Principal(alias),
-               // 513, password);
-               // try (OutputStream out = new FileOutputStream(p12file)) {
-               // keyStore.store(out, password);
-               // }
-               // }
-               // try (InputStream in = new FileInputStream(p12file)) {
-               // keyStore.load(in, password);
-               // privateKey = (PrivateKey) keyStore.getKey(alias, password);
-               // publicKey = keyStore.getCertificateChain(alias)[0].getPublicKey();
-               // }
-               // // KeyPair key;
-               // // final KeyPairGenerator keyGen =
-               // // KeyPairGenerator.getInstance(ALGORITHM);
-               // // keyGen.initialize(4096, new SecureRandom());
-               // // long begin = System.currentTimeMillis();
-               // // key = keyGen.generateKeyPair();
-               // // System.out.println((System.currentTimeMillis() - begin) + " ms");
-               // // keyStore.load(null);
-               // // keyStore.setKeyEntry("test", key.getPrivate(), password, null);
-               // // try(OutputStream out=new FileOutputStream(p12file)) {
-               // // keyStore.store(out, password);
-               // // }
-               // // privateKey = key.getPrivate();
-               // // publicKey = key.getPublic();
-               //
-               // Cipher encrypt = Cipher.getInstance(ALGORITHM);
-               // encrypt.init(Cipher.ENCRYPT_MODE, publicKey);
-               // byte[] encrypted = encrypt.doFinal(text.getBytes());
-               // String encryptedBase64 =
-               // Base64.getEncoder().encodeToString(encrypted);
-               // System.out.println(encryptedBase64);
-               // byte[] encryptedFromBase64 =
-               // Base64.getDecoder().decode(encryptedBase64);
-               //
-               // Cipher decrypt = Cipher.getInstance(ALGORITHM);
-               // decrypt.init(Cipher.DECRYPT_MODE, privateKey);
-               // byte[] decrypted = decrypt.doFinal(encryptedFromBase64);
-               // System.out.println(new String(decrypted));
-               // } catch (Exception e) {
-               // e.printStackTrace();
-               // }
-
-       }
-
-}
index a868e8c26ed02c9a94d9899a35c011ae19b7c1ba..916a413a917013b6ce3999376e7855493ca0b73b 100644 (file)
@@ -55,12 +55,12 @@ public class StaticCms {
                                .build(register);
 
                // Deployment Configuration
-               DeployConfig deployConfig = new DeployConfig();
-               Component<DeployConfig> deployConfigC = new Component.Builder<>(deployConfig) //
-                               .addType(DeployConfig.class) //
-                               .addActivation(deployConfig::start) //
-                               .addDeactivation(deployConfig::stop) //
-                               .build(register);
+//             DeployConfig deployConfig = new DeployConfig();
+//             Component<DeployConfig> deployConfigC = new Component.Builder<>(deployConfig) //
+//                             .addType(DeployConfig.class) //
+//                             .addActivation(deployConfig::start) //
+//                             .addDeactivation(deployConfig::stop) //
+//                             .build(register);
 
                // CMS Deployment
                CmsDeploymentImpl cmsDeployment = new CmsDeploymentImpl();
@@ -69,7 +69,7 @@ public class StaticCms {
                                .addActivation(cmsDeployment::start) //
                                .addDeactivation(cmsDeployment::stop) //
                                .addDependency(cmsStateC.getType(CmsState.class), cmsDeployment::setCmsState, null) //
-                               .addDependency(deployConfigC.getType(DeployConfig.class), cmsDeployment::setDeployConfig, null) //
+//                             .addDependency(deployConfigC.getType(DeployConfig.class), cmsDeployment::setDeployConfig, null) //
                                .build(register);
 
                // Transaction manager
@@ -85,10 +85,10 @@ public class StaticCms {
                                .addType(UserAdmin.class) //
                                .addDependency(transactionManagerC.getType(WorkControl.class), userAdmin::setTransactionManager, null) //
                                .addDependency(transactionManagerC.getType(WorkTransaction.class), userAdmin::setUserTransaction, null) //
-                               .addDependency(deployConfigC.getType(DeployConfig.class), (d) -> {
-                                       for (Dictionary<String, Object> userDirectoryConfig : d.getUserDirectoryConfigs())
-                                               userAdmin.enableUserDirectory(userDirectoryConfig);
-                               }, null) //
+//                             .addDependency(deployConfigC.getType(DeployConfig.class), (d) -> {
+//                                     for (Dictionary<String, Object> userDirectoryConfig : d.getUserDirectoryConfigs())
+//                                             userAdmin.enableUserDirectory(userDirectoryConfig);
+//                             }, null) //
                                .build(register);
 
                // User manager
diff --git a/org.argeo.cms/src/org/argeo/cms/security/PkiUtils.java b/org.argeo.cms/src/org/argeo/cms/security/PkiUtils.java
new file mode 100644 (file)
index 0000000..d6f90ac
--- /dev/null
@@ -0,0 +1,300 @@
+package org.argeo.cms.security;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Date;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.internal.runtime.KernelConstants;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.InputDecryptorProvider;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
+import org.bouncycastle.pkcs.PKCSException;
+
+/**
+ * Utilities around private keys and certificate, mostly wrapping BouncyCastle
+ * implementations.
+ */
+public class PkiUtils {
+       private final static CmsLog log = CmsLog.getLog(PkiUtils.class);
+
+       public final static String PKCS12 = "PKCS12";
+       public static final String DEFAULT_KEYSTORE_PATH = KernelConstants.DIR_NODE + '/' + CmsConstants.NODE + ".p12";
+
+       public static final String DEFAULT_PEM_KEY_PATH = KernelConstants.DIR_NODE + '/' + CmsConstants.NODE + ".key";
+
+       public static final String DEFAULT_PEM_CERT_PATH = KernelConstants.DIR_NODE + '/' + CmsConstants.NODE + ".crt";
+
+       private final static String SECURITY_PROVIDER;
+       static {
+               Security.addProvider(new BouncyCastleProvider());
+               SECURITY_PROVIDER = "BC";
+       }
+
+       public static X509Certificate generateSelfSignedCertificate(KeyStore keyStore, X500Principal x500Principal,
+                       int keySize, char[] keyPassword) {
+               try {
+                       KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", SECURITY_PROVIDER);
+                       kpGen.initialize(keySize, new SecureRandom());
+                       KeyPair pair = kpGen.generateKeyPair();
+                       Date notBefore = new Date(System.currentTimeMillis() - 10000);
+                       Date notAfter = new Date(System.currentTimeMillis() + 365 * 24L * 3600 * 1000);
+                       BigInteger serial = BigInteger.valueOf(System.currentTimeMillis());
+                       X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(x500Principal, serial, notBefore,
+                                       notAfter, x500Principal, pair.getPublic());
+                       ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(SECURITY_PROVIDER)
+                                       .build(pair.getPrivate());
+                       X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER)
+                                       .getCertificate(certGen.build(sigGen));
+                       cert.checkValidity(new Date());
+                       cert.verify(cert.getPublicKey());
+
+                       keyStore.setKeyEntry(x500Principal.getName(), pair.getPrivate(), keyPassword, new Certificate[] { cert });
+                       return cert;
+               } catch (GeneralSecurityException | OperatorCreationException e) {
+                       throw new RuntimeException("Cannot generate self-signed certificate", e);
+               }
+       }
+
+       public static KeyStore getKeyStore(Path keyStoreFile, char[] keyStorePassword, String keyStoreType) {
+               try {
+                       KeyStore store = KeyStore.getInstance(keyStoreType, SECURITY_PROVIDER);
+                       if (Files.exists(keyStoreFile)) {
+                               try (InputStream fis = Files.newInputStream(keyStoreFile)) {
+                                       store.load(fis, keyStorePassword);
+                               }
+                       } else {
+                               store.load(null);
+                       }
+                       return store;
+               } catch (GeneralSecurityException | IOException e) {
+                       throw new RuntimeException("Cannot load keystore " + keyStoreFile, e);
+               }
+       }
+
+       public static void saveKeyStore(Path keyStoreFile, char[] keyStorePassword, KeyStore keyStore) {
+               try {
+                       try (OutputStream fis = Files.newOutputStream(keyStoreFile)) {
+                               keyStore.store(fis, keyStorePassword);
+                       }
+               } catch (GeneralSecurityException | IOException e) {
+                       throw new RuntimeException("Cannot save keystore " + keyStoreFile, e);
+               }
+       }
+
+//     public static byte[] pemToPKCS12(final String keyFile, final String cerFile, final String password)
+//                     throws Exception {
+//             // Get the private key
+//             FileReader reader = new FileReader(keyFile);
+//
+//             PEMReader pem = new PemReader(reader, new PasswordFinder() {
+//                     @Override
+//                     public char[] getPassword() {
+//                             return password.toCharArray();
+//                     }
+//             });
+//
+//             PrivateKey key = ((KeyPair) pem.readObject()).getPrivate();
+//
+//             pem.close();
+//             reader.close();
+//
+//             // Get the certificate
+//             reader = new FileReader(cerFile);
+//             pem = new PEMReader(reader);
+//
+//             X509Certificate cert = (X509Certificate) pem.readObject();
+//
+//             pem.close();
+//             reader.close();
+//
+//             // Put them into a PKCS12 keystore and write it to a byte[]
+//             ByteArrayOutputStream bos = new ByteArrayOutputStream();
+//             KeyStore ks = KeyStore.getInstance("PKCS12");
+//             ks.load(null);
+//             ks.setKeyEntry("alias", (Key) key, password.toCharArray(), new java.security.cert.Certificate[] { cert });
+//             ks.store(bos, password.toCharArray());
+//             bos.close();
+//             return bos.toByteArray();
+//     }
+
+       public static void loadPem(KeyStore keyStore, Reader key, char[] keyPassword, Reader cert) {
+               PrivateKey privateKey = loadPemPrivateKey(key, keyPassword);
+               X509Certificate certificate = loadPemCertificate(cert);
+               try {
+                       keyStore.setKeyEntry(certificate.getSubjectX500Principal().getName(), privateKey, keyPassword,
+                                       new java.security.cert.Certificate[] { certificate });
+               } catch (KeyStoreException e) {
+                       throw new RuntimeException("Cannot store PEM certificate", e);
+               }
+       }
+
+       public static PrivateKey loadPemPrivateKey(Reader reader, char[] keyPassword) {
+               try (PEMParser pemParser = new PEMParser(reader)) {
+                       JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
+                       Object object = pemParser.readObject();
+                       PrivateKeyInfo privateKeyInfo;
+                       if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
+                               if (keyPassword == null)
+                                       throw new IllegalArgumentException("A key password is required");
+                               InputDecryptorProvider decProv = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(keyPassword);
+                               privateKeyInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decProv);
+                       } else if (object instanceof PrivateKeyInfo) {
+                               privateKeyInfo = (PrivateKeyInfo) object;
+                       } else {
+                               throw new IllegalArgumentException("Unsupported format for private key");
+                       }
+                       return converter.getPrivateKey(privateKeyInfo);
+               } catch (IOException | OperatorCreationException | PKCSException e) {
+                       throw new RuntimeException("Cannot read private key", e);
+               }
+       }
+
+       public static X509Certificate loadPemCertificate(Reader reader) {
+               try (PEMParser pemParser = new PEMParser(reader)) {
+                       X509CertificateHolder certHolder = (X509CertificateHolder) pemParser.readObject();
+                       X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER)
+                                       .getCertificate(certHolder);
+                       return cert;
+               } catch (IOException | CertificateException e) {
+                       throw new RuntimeException("Cannot read private key", e);
+               }
+       }
+
+       public static void main(String[] args) throws Exception {
+               final String ALGORITHM = "RSA";
+               final String provider = "BC";
+               SecureRandom secureRandom = new SecureRandom();
+               long begin = System.currentTimeMillis();
+               for (int i = 512; i < 1024; i = i + 2) {
+                       try {
+                               KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM, provider);
+                               keyGen.initialize(i, secureRandom);
+                               keyGen.generateKeyPair();
+                       } catch (Exception e) {
+                               System.err.println(i + " : " + e.getMessage());
+                       }
+               }
+               System.out.println((System.currentTimeMillis() - begin) + " ms");
+
+               // // String text = "a";
+               // String text =
+               // "testtesttesttesttesttesttesttesttesttesttesttesttesttesttest";
+               // try {
+               // System.out.println(text);
+               // PrivateKey privateKey;
+               // PublicKey publicKey;
+               // char[] password = "changeit".toCharArray();
+               // String alias = "CN=test";
+               // KeyStore keyStore = KeyStore.getInstance("pkcs12");
+               // File p12file = new File("test.p12");
+               // p12file.delete();
+               // if (!p12file.exists()) {
+               // keyStore.load(null);
+               // generateSelfSignedCertificate(keyStore, new X500Principal(alias),
+               // 513, password);
+               // try (OutputStream out = new FileOutputStream(p12file)) {
+               // keyStore.store(out, password);
+               // }
+               // }
+               // try (InputStream in = new FileInputStream(p12file)) {
+               // keyStore.load(in, password);
+               // privateKey = (PrivateKey) keyStore.getKey(alias, password);
+               // publicKey = keyStore.getCertificateChain(alias)[0].getPublicKey();
+               // }
+               // // KeyPair key;
+               // // final KeyPairGenerator keyGen =
+               // // KeyPairGenerator.getInstance(ALGORITHM);
+               // // keyGen.initialize(4096, new SecureRandom());
+               // // long begin = System.currentTimeMillis();
+               // // key = keyGen.generateKeyPair();
+               // // System.out.println((System.currentTimeMillis() - begin) + " ms");
+               // // keyStore.load(null);
+               // // keyStore.setKeyEntry("test", key.getPrivate(), password, null);
+               // // try(OutputStream out=new FileOutputStream(p12file)) {
+               // // keyStore.store(out, password);
+               // // }
+               // // privateKey = key.getPrivate();
+               // // publicKey = key.getPublic();
+               //
+               // Cipher encrypt = Cipher.getInstance(ALGORITHM);
+               // encrypt.init(Cipher.ENCRYPT_MODE, publicKey);
+               // byte[] encrypted = encrypt.doFinal(text.getBytes());
+               // String encryptedBase64 =
+               // Base64.getEncoder().encodeToString(encrypted);
+               // System.out.println(encryptedBase64);
+               // byte[] encryptedFromBase64 =
+               // Base64.getDecoder().decode(encryptedBase64);
+               //
+               // Cipher decrypt = Cipher.getInstance(ALGORITHM);
+               // decrypt.init(Cipher.DECRYPT_MODE, privateKey);
+               // byte[] decrypted = decrypt.doFinal(encryptedFromBase64);
+               // System.out.println(new String(decrypted));
+               // } catch (Exception e) {
+               // e.printStackTrace();
+               // }
+
+       }
+
+       public static void createSelfSignedKeyStore(Path keyStorePath, char[] keyStorePassword, String keyStoreType) {
+               // for (Provider provider : Security.getProviders())
+               // System.out.println(provider.getName());
+               // File keyStoreFile = keyStorePath.toFile();
+               char[] keyPwd = Arrays.copyOf(keyStorePassword, keyStorePassword.length);
+               if (!Files.exists(keyStorePath)) {
+                       try {
+                               Files.createDirectories(keyStorePath.getParent());
+                               KeyStore keyStore = getKeyStore(keyStorePath, keyStorePassword, keyStoreType);
+                               generateSelfSignedCertificate(keyStore,
+                                               new X500Principal("CN=" + InetAddress.getLocalHost().getHostName() + ",OU=UNSECURE,O=UNSECURE"),
+                                               1024, keyPwd);
+                               saveKeyStore(keyStorePath, keyStorePassword, keyStore);
+                               if (log.isDebugEnabled())
+                                       log.debug("Created self-signed unsecure keystore " + keyStorePath);
+                       } catch (Exception e) {
+                               try {
+                                       if (Files.size(keyStorePath) == 0)
+                                               Files.delete(keyStorePath);
+                               } catch (IOException e1) {
+                                       // silent
+                               }
+                               log.error("Cannot create keystore " + keyStorePath, e);
+                       }
+               } else {
+                       throw new IllegalStateException("Keystore " + keyStorePath + " already exists");
+               }
+       }
+
+}
index 3857b08d0607027cf55e0a4b72528de70135b7e7..79d2bd3cbc2f21142f1801a1df5c5fbc307c2095 100644 (file)
@@ -238,7 +238,11 @@ public class AggregatingUserAdmin implements UserAdmin {
 //             return res;
 //     }
 
-       public void destroy() {
+       public void start() {
+
+       }
+
+       public void stop() {
                for (LdapName name : businessRoles.keySet()) {
                        DirectoryUserAdmin userDirectory = businessRoles.get(name);
                        destroy(userDirectory);
@@ -254,6 +258,14 @@ public class AggregatingUserAdmin implements UserAdmin {
                userDirectory.destroy();
        }
 
+//     protected void removeUserDirectory(UserDirectory userDirectory) {
+//             LdapName baseDn = toLdapName(userDirectory.getContext());
+//             businessRoles.remove(baseDn);
+//             if (userDirectory instanceof DirectoryUserAdmin)
+//                     destroy((DirectoryUserAdmin) userDirectory);
+//     }
+
+       @Deprecated
        protected void removeUserDirectory(String basePath) {
                if (isSystemRolesBaseDn(basePath))
                        throw new IllegalArgumentException("System roles cannot be removed ");
@@ -274,6 +286,8 @@ public class AggregatingUserAdmin implements UserAdmin {
        public Set<UserDirectory> getUserDirectories() {
                TreeSet<UserDirectory> res = new TreeSet<>((o1, o2) -> o1.getContext().compareTo(o2.getContext()));
                res.addAll(businessRoles.values());
+               res.add(systemRoles);
                return res;
        }
+
 }