import java.util.List;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.commands.MCommand;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
package org.argeo.cms.e4;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.IInjector;
import javax.servlet.http.HttpServletRequest;
import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsException;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
-import org.argeo.cms.CmsException;
import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsException;
import org.argeo.eclipse.ui.fs.AdvancedFsBrowser;
import org.argeo.eclipse.ui.fs.SimpleFsBrowser;
import org.eclipse.swt.SWT;
import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.security.CryptoKeyring;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.dialogs.CmsMessageDialog;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.util.transaction.WorkTransaction;
import javax.security.auth.Subject;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsException;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.workbench.IWorkbench;
import javax.jcr.observation.ObservationManager;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.CmsException;
import org.argeo.cms.security.CryptoKeyring;
import org.argeo.cms.security.Keyring;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.jcr.JcrBrowserUtils;
import org.argeo.cms.ui.jcr.NodeContentProvider;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.ui.jcr.JcrDClickListener;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import javax.jcr.Value;
import org.argeo.api.cms.ux.Cms2DSize;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.CmsUiProvider;
import org.argeo.cms.ui.util.CmsLink;
import javax.annotation.PostConstruct;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.util.LangUtils;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.e4.users.providers.CommonNameLP;
import org.argeo.cms.e4.users.providers.DomainNameLP;
import org.argeo.cms.e4.users.providers.RoleIconLP;
import org.argeo.cms.e4.users.providers.UserDragListener;
+import org.argeo.cms.swt.CmsException;
//import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
//import org.argeo.cms.ui.workbench.internal.useradmin.UiUserAdminListener;
//import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper;
import java.util.Map;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.osgi.useradmin.UserDirectory;
import org.argeo.util.directory.DirectoryConf;
import org.argeo.util.transaction.WorkTransaction;
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.auth.UserAdminUtils;
import org.argeo.cms.e4.users.providers.CommonNameLP;
import org.argeo.cms.e4.users.providers.DomainNameLP;
import org.argeo.cms.e4.users.providers.MailLP;
import org.argeo.cms.e4.users.providers.UserNameLP;
+import org.argeo.cms.swt.CmsException;
import org.argeo.eclipse.ui.ColumnDefinition;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.parts.LdifUsersTable;
import javax.inject.Inject;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.e4.users.providers.CommonNameLP;
import org.argeo.cms.e4.users.providers.DomainNameLP;
import org.argeo.cms.e4.users.providers.MailLP;
import org.argeo.cms.e4.users.providers.UserDragListener;
import org.argeo.cms.e4.users.providers.UserNameLP;
+import org.argeo.cms.swt.CmsException;
import org.argeo.eclipse.ui.ColumnDefinition;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.parts.LdifUsersTable;
import javax.inject.Inject;
-import org.argeo.cms.CmsException;
import org.argeo.cms.e4.users.UserAdminWrapper;
+import org.argeo.cms.swt.CmsException;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.util.directory.DirectoryConf;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.UserAdminUtils;
import org.argeo.cms.e4.users.UiAdminUtils;
import org.argeo.cms.e4.users.UserAdminWrapper;
+import org.argeo.cms.swt.CmsException;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.util.directory.DirectoryConf;
import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.UserAdminUtils;
+import org.argeo.cms.swt.CmsException;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.swt.SWT;
+++ /dev/null
-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";
-
-}
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 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.CmsDeployProperty;
import org.argeo.cms.websocket.javax.server.CmsWebSocketConfigurator;
import org.argeo.cms.websocket.javax.server.TestEndpoint;
import org.argeo.util.LangUtils;
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();
+ //private static final String JETTY_PROPERTY_PREFIX = "org.eclipse.equinox.http.jetty.";
+
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
config.put("customizer.class", CMS_JETTY_CUSTOMIZER_CLASS);
// TODO centralise with Jetty extender
- Object webSocketEnabled = config.get(WEBSOCKET_ENABLED);
+ Object webSocketEnabled = config.get(CmsDeployProperty.WEBSOCKET_ENABLED.getProperty());
if (webSocketEnabled != null && webSocketEnabled.toString().equals("true")) {
bc.registerService(ServerEndpointConfig.Configurator.class, new CmsWebSocketConfigurator(), null);
- config.put(WEBSOCKET_ENABLED, "true");
+ // config.put(WEBSOCKET_ENABLED, "true");
}
}
// 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);
+ Object httpPort = config.get(JettyHttpConstants.HTTP_PORT);
+ Object httpsPort = config.get(JettyHttpConstants.HTTPS_PORT);
log.info(httpPortsMsg(httpPort, httpsPort));
// Explicitly starts Jetty OSGi HTTP bundle, so that it gets triggered if OSGi
/** 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");
+ String httpPort = getFrameworkProp(CmsDeployProperty.HTTP_PORT);
+ String httpsPort = getFrameworkProp(CmsDeployProperty.HTTPS_PORT);
/// 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);
+ String httpHost = getFrameworkProp(CmsDeployProperty.HOST);
+// String httpsHost = getFrameworkProp(
+// JettyConfig.JETTY_PROPERTY_PREFIX + CmsHttpConstants.HTTPS_HOST);
+ String webSocketEnabled = getFrameworkProp(CmsDeployProperty.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);
+ props.put(JettyHttpConstants.HTTP_ENABLED, httpEnabled);
boolean httpsEnabled = httpsPort != null;
- props.put(InternalHttpConstants.HTTPS_ENABLED, httpsEnabled);
+ props.put(JettyHttpConstants.HTTPS_ENABLED, httpsEnabled);
if (httpEnabled) {
- props.put(InternalHttpConstants.HTTP_PORT, httpPort);
+ props.put(JettyHttpConstants.HTTP_PORT, httpPort);
if (httpHost != null)
- props.put(InternalHttpConstants.HTTP_HOST, httpHost);
+ props.put(JettyHttpConstants.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(JettyHttpConstants.HTTPS_PORT, httpsPort);
+ if (httpHost != null)
+ props.put(JettyHttpConstants.HTTPS_HOST, httpHost);
-// props.put(InternalHttpConstants.SSL_KEYSTORETYPE, "PKCS11");
-// props.put(InternalHttpConstants.SSL_KEYSTORE, "../../nssdb");
-// props.put(InternalHttpConstants.SSL_PASSWORD, keyStorePassword);
+ props.put(JettyHttpConstants.SSL_KEYSTORETYPE, getFrameworkProp(CmsDeployProperty.SSL_KEYSTORETYPE));
+ props.put(JettyHttpConstants.SSL_KEYSTORE, getFrameworkProp(CmsDeployProperty.SSL_KEYSTORE));
+ props.put(JettyHttpConstants.SSL_PASSWORD, getFrameworkProp(CmsDeployProperty.SSL_PASSWORD));
// client certificate authentication
- String wantClientAuth = getFrameworkProp(
- InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_WANTCLIENTAUTH);
+ String wantClientAuth = getFrameworkProp(CmsDeployProperty.SSL_WANTCLIENTAUTH);
if (wantClientAuth != null)
- props.put(InternalHttpConstants.SSL_WANTCLIENTAUTH, Boolean.parseBoolean(wantClientAuth));
- String needClientAuth = getFrameworkProp(
- InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_NEEDCLIENTAUTH);
+ props.put(JettyHttpConstants.SSL_WANTCLIENTAUTH, Boolean.parseBoolean(wantClientAuth));
+ String needClientAuth = getFrameworkProp(CmsDeployProperty.SSL_NEEDCLIENTAUTH);
if (needClientAuth != null)
- props.put(InternalHttpConstants.SSL_NEEDCLIENTAUTH, Boolean.parseBoolean(needClientAuth));
+ props.put(JettyHttpConstants.SSL_NEEDCLIENTAUTH, Boolean.parseBoolean(needClientAuth));
}
// web socket
if (webSocketEnabled != null && webSocketEnabled.equals("true"))
- props.put(InternalHttpConstants.WEBSOCKET_ENABLED, true);
+ props.put(CmsDeployProperty.WEBSOCKET_ENABLED.getProperty(), true);
props.put(CmsConstants.CN, CmsConstants.DEFAULT);
}
return props;
}
- private String getFrameworkProp(String key) {
- return cmsState.getDeployProperty(key);
+ private String getFrameworkProp(CmsDeployProperty deployProperty) {
+ return cmsState.getDeployProperty(deployProperty.getProperty());
}
public void setCmsState(CmsState cmsState) {
--- /dev/null
+package org.argeo.cms.servlet.internal.jetty;
+
+/** Compatible with Jetty. */
+interface JettyHttpConstants {
+ 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";
+}
--- /dev/null
+package org.argeo.cms.swt;
+
+/** @deprecated Use standard Java {@link RuntimeException} instead. */
+@Deprecated
+public class CmsException extends RuntimeException {
+ private static final long serialVersionUID = -5341764743356771313L;
+
+ public CmsException(String message) {
+ super(message);
+ }
+
+ public CmsException(String message, Throwable e) {
+ super(message, e);
+ }
+
+}
import static org.argeo.cms.CmsMsg.username;
import java.io.IOException;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandler;
+import java.net.http.HttpResponse.BodyHandlers;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedAction;
+import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Locale;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import org.argeo.cms.CmsMsg;
import org.argeo.cms.LocaleUtils;
import org.argeo.cms.auth.RemoteAuthCallback;
+import org.argeo.cms.auth.RemoteAuthUtils;
import org.argeo.cms.servlet.ServletHttpRequest;
import org.argeo.cms.servlet.ServletHttpResponse;
import org.argeo.cms.swt.CmsStyles;
else
loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, subject, this);
loginContext.login();
+// try {
+// openHttpClient(loginContext.getSubject(), "id-internal.work.argeo.net");
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
cmsView.authChange(loginContext);
return true;
} catch (LoginException e) {
// }
}
+ private static HttpClient openHttpClient(Subject subject, String server) {
+ try {
+ String domain = "WORK.ARGEO.ORG";
+ // disable https check
+ // jdk.internal.httpclient.disableHostnameVerification=true
+ HttpClient client = HttpClient.newBuilder().sslContext(insecureContext())
+ .authenticator(new Authenticator() {
+ public PasswordAuthentication getPasswordAuthentication() {
+ // I haven't checked getRequestingScheme() here, since for NTLM
+ // and Negotiate, the usrname and password are all the same.
+ System.err.println("Feeding username and password for " + getRequestingScheme());
+ return (new PasswordAuthentication("mbaudier@" + domain, null));
+ }
+
+ }).build();
+
+ String token = RemoteAuthUtils.getGssToken(subject, "HTTP/" + server + "@" + domain);
+
+ HttpRequest request = HttpRequest.newBuilder(URI.create("https://" + server + "/ipa/session/json")).GET()
+ .header("Authorization", "Negotiate " + token).build();
+ BodyHandler<String> bodyHandler = BodyHandlers.ofString();
+ HttpResponse<String> response = client.send(request, bodyHandler);
+ System.out.println(response.body());
+ return client;
+
+ // return client;
+// AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
+// HttpParams params = DefaultHttpParams.getDefaultParams();
+// ArrayList<String> schemes = new ArrayList<>();
+// schemes.add(SpnegoAuthScheme.NAME);
+// params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
+// params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
+// HttpClient httpClient = new HttpClient();
+// httpClient.executeMethod(new GetMethod(("https://" + server + "/ipa/session/json")));
+// return httpClient;
+ } catch (
+
+ Exception e) {
+ throw new IllegalStateException("Cannot open client to IPA server " + server, e);
+ }
+
+ }
+
+ private static SSLContext insecureContext() {
+ TrustManager[] noopTrustManager = new TrustManager[] { new X509TrustManager() {
+ public void checkClientTrusted(X509Certificate[] xcs, String string) {
+ }
+
+ public void checkServerTrusted(X509Certificate[] xcs, String string) {
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ } };
+ try {
+ SSLContext sc = SSLContext.getInstance("ssl");
+ sc.init(null, noopTrustManager, null);
+ return sc;
+ } catch (KeyManagementException | NoSuchAlgorithmException e) {
+ throw new IllegalStateException("Cannot create insecure SSL context ", e);
+ }
+ }
+
protected void logout() {
cmsView.logout();
cmsView.navigateTo("~");
import javax.security.auth.callback.LanguageCallback;
-import org.argeo.cms.CmsException;
-import org.argeo.cms.LocaleUtils;
+import org.argeo.cms.swt.CmsException;
/** Choose in a list of locales. TODO: replace with {@link LanguageCallback} */
+@Deprecated
public class LocaleChoice {
private final List<Locale> locales;
this.selectedIndex = defaultIndex;
}
- /**
- * Convenience constructor based on a comma separated list of iso codes (en,
- * en_US, fr_CA, etc.). Default selection is default locale.
- */
- public LocaleChoice(String locales, Locale defaultLocale) {
- this(LocaleUtils.asLocaleList(locales), defaultLocale);
- }
+// /**
+// * Convenience constructor based on a comma separated list of iso codes (en,
+// * en_US, fr_CA, etc.). Default selection is default locale.
+// */
+// public LocaleChoice(String locales, Locale defaultLocale) {
+// this(LocaleUtils.asLocaleList(locales), defaultLocale);
+// }
public String[] getSupportedLocalesLabels() {
String[] labels = new String[locales.size()];
public class CmsJettyCustomizer extends JettyCustomizer {
private BundleContext bc = FrameworkUtil.getBundle(CmsJettyCustomizer.class).getBundleContext();
- public final static String WEBSOCKET_ENABLED = "websocket.enabled";
+ public final static String WEBSOCKET_ENABLED = "argeo.websocket.enabled";
@Override
public Object customizeContext(Object context, Dictionary<String, ?> settings) {
+++ /dev/null
-package org.argeo.cms.internal.jcr;
-
-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;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-
-import org.argeo.api.cms.CmsDeployment;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory;
-import org.argeo.jcr.JcrException;
-import org.argeo.util.naming.LdapAttrs;
-import org.osgi.framework.BundleContext;
-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);
-//// }
-//
-// }
-
- /** Override the provided config with the framework properties */
- public static Dictionary<String, Object> getNodeRepositoryConfig(Dictionary<String, Object> provided) {
- Dictionary<String, Object> props = provided != null ? provided : 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;
- }
-
-// 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 {
- Repository repository = createRemoteRepository(new URI(uri));
- Hashtable<String, Object> properties = new Hashtable<>();
- properties.put(CmsConstants.CN, CmsConstants.NODE_INIT);
- properties.put(LdapAttrs.labeledURI.name(), uri);
- properties.put(Constants.SERVICE_RANKING, -1000);
- bundleContext.registerService(Repository.class, repository, properties);
- } catch (RepositoryException e) {
- throw new JcrException(e);
- } catch (URISyntaxException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- private static Repository createRemoteRepository(URI uri) throws RepositoryException {
- RepositoryFactory repositoryFactory = new ClientDavexRepositoryFactory();
- Map<String, String> params = new HashMap<String, String>();
- params.put(ClientDavexRepositoryFactory.JACKRABBIT_DAVEX_URI, uri.toString());
- // TODO make it configurable
- params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, CmsConstants.SYS_WORKSPACE);
- return repositoryFactory.getRepository(params);
- }
-
- private static String getFrameworkProp(String key, String def) {
- String value;
- if (bundleContext != null)
- value = bundleContext.getProperty(key);
- else
- value = System.getProperty(key);
- if (value == null)
- return def;
- return value;
- }
-
- private static String getFrameworkProp(String key) {
- return getFrameworkProp(key, null);
- }
-
-}
package org.argeo.cms.internal.jcr;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.osgi.metatype.EnumAD;
-import org.argeo.osgi.metatype.EnumOCD;
/** JCR repository configuration */
-public enum RepoConf implements EnumAD {
+public enum RepoConf {
/** Repository type */
type("h2"),
/** Default workspace */
/** The default value. */
private Object def;
- private String oid;
RepoConf(String oid, Object def) {
- this.oid = oid;
this.def = def;
}
return def;
}
- @Override
- public String getID() {
- if (oid != null)
- return oid;
- return EnumAD.super.getID();
- }
-
- public static class OCD extends EnumOCD<RepoConf> {
- public OCD(String locale) {
- super(RepoConf.class, locale);
- }
- }
-
}
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.jcr.NamespaceRegistry;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.jackrabbit.commons.cnd.CndImporter;
import org.apache.jackrabbit.core.RepositoryContext;
import org.apache.jackrabbit.core.RepositoryImpl;
-import org.argeo.api.acr.spi.ProvidedRepository;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsDeployment;
import org.argeo.api.cms.CmsLog;
import org.argeo.cms.ArgeoNames;
-import org.argeo.cms.internal.jcr.JcrInitUtils;
import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.jcr.acr.JcrContentProvider;
import org.argeo.cms.jcr.internal.servlet.CmsRemotingServlet;
import org.argeo.cms.jcr.internal.servlet.CmsWebDavServlet;
import org.argeo.cms.jcr.internal.servlet.JcrHttpUtils;
import org.argeo.jcr.JcrException;
import org.argeo.jcr.JcrUtils;
import org.argeo.util.LangUtils;
-import org.argeo.util.naming.LdapAttrs;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
// }
// init from repository
- Collection<ServiceReference<Repository>> initRepositorySr;
- try {
- initRepositorySr = bc.getServiceReferences(Repository.class,
- "(" + CmsConstants.CN + "=" + CmsConstants.NODE_INIT + ")");
- } catch (InvalidSyntaxException e1) {
- throw new IllegalArgumentException(e1);
- }
- Iterator<ServiceReference<Repository>> it = initRepositorySr.iterator();
- while (it.hasNext()) {
- ServiceReference<Repository> sr = it.next();
- Object labeledUri = sr.getProperties().get(LdapAttrs.labeledURI.name());
- Repository initRepository = bc.getService(sr);
- if (log.isDebugEnabled())
- log.debug("Found init repository " + labeledUri + ", copying it...");
- initFromRepository(deployedNodeRepository, initRepository);
- log.info("Node repository initialised from " + labeledUri);
- }
+// Collection<ServiceReference<Repository>> initRepositorySr;
+// try {
+// initRepositorySr = bc.getServiceReferences(Repository.class,
+// "(" + CmsConstants.CN + "=" + CmsConstants.NODE_INIT + ")");
+// } catch (InvalidSyntaxException e1) {
+// throw new IllegalArgumentException(e1);
+// }
+// Iterator<ServiceReference<Repository>> it = initRepositorySr.iterator();
+// while (it.hasNext()) {
+// ServiceReference<Repository> sr = it.next();
+// Object labeledUri = sr.getProperties().get(LdapAttrs.labeledURI.name());
+// Repository initRepository = bc.getService(sr);
+// if (log.isDebugEnabled())
+// log.debug("Found init repository " + labeledUri + ", copying it...");
+// initFromRepository(deployedNodeRepository, initRepository);
+// log.info("Node repository initialised from " + labeledUri);
+// }
}
/** Init from a (typically remote) repository. */
import java.nio.file.Path;
/** Centralises access to the default node deployment directories. */
+@Deprecated
public class CmsPaths {
public static Path getRepoDirPath(String cn) {
return KernelUtils.getOsgiInstancePath(KernelConstants.DIR_REPOS + '/' + cn);
import org.argeo.api.cms.CmsAuth;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.CmsException;
import org.argeo.cms.jcr.CmsJcrUtils;
import org.argeo.jcr.JcrException;
import org.argeo.jcr.JcrRepositoryWrapper;
/**
* Make sure each user has a home directory available.
*/
-class EgoRepository extends JcrRepositoryWrapper implements KernelConstants {
+class EgoRepository extends JcrRepositoryWrapper {
/** The home base path. */
// private String homeBasePath = KernelConstants.DEFAULT_HOME_BASE_PATH;
// JcrUtils.addPrivilege(adminSession, groupsBasePath, NodeConstants.ROLE_USER_ADMIN, Privilege.JCR_READ);
adminSession.save();
} catch (RepositoryException e) {
- throw new CmsException("Cannot initialize home repository", e);
+ throw new JcrException("Cannot initialize home repository", e);
} finally {
JcrUtils.logoutQuietly(adminSession);
}
try {
dn = new LdapName(username);
} catch (InvalidNameException e) {
- throw new CmsException("Invalid name " + username, e);
+ throw new IllegalArgumentException("Invalid name " + username, e);
}
String userId = dn.getRdn(dn.size() - 1).getValue().toString();
return '/' + userId;
try {
dn = new LdapName(username);
} catch (InvalidNameException e) {
- throw new CmsException("Invalid name " + username, e);
+ throw new IllegalArgumentException("Invalid name " + username, e);
}
String userId = dn.getRdn(dn.size() - 1).getValue().toString();
return userId;
Node newWorkgroup = CmsJcrUtils.getGroupHome(adminSession, cn);
if (newWorkgroup != null) {
JcrUtils.logoutQuietly(adminSession);
- throw new CmsException("Workgroup " + newWorkgroup + " already exists for " + dn);
+ throw new IllegalStateException("Workgroup " + newWorkgroup + " already exists for " + dn);
}
try {
// TODO enhance transformation of cn to a valid node name
JcrUtils.addPrivilege(adminSession, newWorkgroup.getPath(), dn.toString(), Privilege.JCR_ALL);
adminSession.save();
} catch (RepositoryException e) {
- throw new CmsException("Cannot create workgroup", e);
+ throw new JcrException("Cannot create workgroup", e);
} finally {
JcrUtils.logoutQuietly(adminSession);
}
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.CmsState;
+import org.argeo.cms.CmsDeployProperty;
import org.argeo.cms.internal.jcr.RepoConf;
import org.argeo.cms.internal.jcr.RepositoryBuilder;
import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator;
/** A {@link ManagedServiceFactory} creating or referencing JCR repositories. */
public class RepositoryContextsFactory {
private final static CmsLog log = CmsLog.getLog(RepositoryContextsFactory.class);
+ private final static String NODE_REPO_PROP_PREFIX = "argeo.node.repo.";
// private final BundleContext bc = FrameworkUtil.getBundle(RepositoryServiceFactory.class).getBundleContext();
// private Map<String, RepositoryContext> repositories = new HashMap<String, RepositoryContext>();
/** Override the provided config with the framework properties */
private Dictionary<String, Object> getNodeRepositoryConfig() {
Dictionary<String, Object> props = new Hashtable<String, Object>();
+ addDeployProperty(CmsDeployProperty.DB_URL, RepoConf.dburl, props);
+ addDeployProperty(CmsDeployProperty.DB_USER, RepoConf.dbuser, props);
+ addDeployProperty(CmsDeployProperty.DB_PASSWORD, RepoConf.dbpassword, props);
for (RepoConf repoConf : RepoConf.values()) {
- Object value = getFrameworkProp(CmsConstants.NODE_REPO_PROP_PREFIX + repoConf.name());
+ Object value = getFrameworkProp(NODE_REPO_PROP_PREFIX + repoConf.name());
if (value != null) {
props.put(repoConf.name(), value);
if (log.isDebugEnabled())
return props;
}
+ private void addDeployProperty(CmsDeployProperty deployProperty, RepoConf repoConf,
+ Dictionary<String, Object> props) {
+ String value = getFrameworkProp(deployProperty.getProperty());
+ if (value != null) {
+ props.put(repoConf.name(), value);
+ }
+
+ }
+
// @Override
// public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
protected void deployRepository(Dictionary<String, Object> properties) {
import org.argeo.api.cms.CmsAuth;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.CmsException;
import org.argeo.cms.jcr.CmsJcrUtils;
import org.argeo.jcr.JcrUtils;
import org.osgi.framework.BundleContext;
response.setHeader("Content-Type", "text/html");
writer.flush();
} catch (Exception e) {
- throw new CmsException("Cannot write canonical answer", e);
+ throw new IllegalStateException("Cannot write canonical answer", e);
} finally {
JcrUtils.logoutQuietly(session);
}
buf.append(':').append(url.getPort());
return buf;
} catch (MalformedURLException e) {
- throw new CmsException("Cannot extract server base URL from " + request.getRequestURL(), e);
+ throw new IllegalArgumentException("Cannot extract server base URL from " + request.getRequestURL(), e);
}
}
buf.append(CmsJcrUtils.getDataPath(CmsConstants.EGO_REPOSITORY, node));
return new URL(buf.toString()).toString();
} catch (MalformedURLException e) {
- throw new CmsException("Cannot build data URL for " + node, e);
+ throw new IllegalArgumentException("Cannot build data URL for " + node, e);
}
}
buf.append('/').append('!').append(node.getPath());
return new URL(buf.toString()).toString();
} catch (MalformedURLException e) {
- throw new CmsException("Cannot build data URL for " + node, e);
+ throw new IllegalArgumentException("Cannot build data URL for " + node, e);
}
// return request.getRequestURL().append('!').append(node.getPath())
// .toString();
lc.login();
return subject;
} catch (LoginException e) {
- throw new CmsException("Cannot login as anonymous", e);
+ throw new IllegalStateException("Cannot login as anonymous", e);
}
}
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.ux.CmsView;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.eclipse.jface.fieldassist.ControlDecoration;
import javax.jcr.Repository;
import javax.jcr.Session;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.eclipse.ui.ColumnDefinition;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.apache.commons.io.IOUtils;
import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.dialogs.SingleValue;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.CmsStyles;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.CmsUiProvider;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.ui.CmsUiProvider;
import org.argeo.jcr.JcrUtils;
import org.eclipse.rap.rwt.RWT;
import java.util.Map;
import org.apache.commons.io.IOUtils;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.eclipse.rap.rwt.service.ResourceLoader;
import org.osgi.framework.Bundle;
import java.util.Date;
import org.apache.commons.io.IOUtils;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.CmsStyles;
import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.rap.rwt.RWT;
import javax.jcr.Node;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.auth.CmsLoginShell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ShellAdapter;
/*
* INIT FRAMEWORK PROPERTIES
*/
- String NODE_INIT = "argeo.node.init";
- String I18N_DEFAULT_LOCALE = "argeo.i18n.defaultLocale";
- String I18N_LOCALES = "argeo.i18n.locales";
+// String NODE_INIT = "argeo.node.init";
+// String I18N_DEFAULT_LOCALE = "argeo.i18n.defaultLocale";
+// String I18N_LOCALES = "argeo.i18n.locales";
// Node Security
- String ROLES_URI = "argeo.node.roles.uri";
- String TOKENS_URI = "argeo.node.tokens.uri";
- /** URI to an LDIF file or LDAP server used as initialization or backend */
- String USERADMIN_URIS = "argeo.node.useradmin.uris";
+// String ROLES_URI = "argeo.node.roles.uri";
+// String TOKENS_URI = "argeo.node.tokens.uri";
+// /** URI to an LDIF file or LDAP server used as initialization or backend */
+// String USERADMIN_URIS = "argeo.node.useradmin.uris";
// Transaction manager
- String TRANSACTION_MANAGER = "argeo.node.transaction.manager";
- String TRANSACTION_MANAGER_SIMPLE = "simple";
- String TRANSACTION_MANAGER_BITRONIX = "bitronix";
+// String TRANSACTION_MANAGER = "argeo.node.transaction.manager";
+// String TRANSACTION_MANAGER_SIMPLE = "simple";
+// String TRANSACTION_MANAGER_BITRONIX = "bitronix";
// Node
- /** Properties configuring the node repository */
- String NODE_REPO_PROP_PREFIX = "argeo.node.repo.";
- /** Additional standalone repositories, related to data models. */
- String NODE_REPOS_PROP_PREFIX = "argeo.node.repos.";
+// /** Properties configuring the node repository */
+// String NODE_REPO_PROP_PREFIX = "argeo.node.repo.";
+// /** Additional standalone repositories, related to data models. */
+// String NODE_REPOS_PROP_PREFIX = "argeo.node.repos.";
// HTTP
- String HTTP_PORT = "org.osgi.service.http.port";
- String HTTP_PORT_SECURE = "org.osgi.service.http.port.secure";
- /**
- * The HTTP header used to convey the DN of a client verified by a reverse
- * proxy. Typically SSL_CLIENT_S_DN for Apache.
- */
- String HTTP_PROXY_SSL_DN = "argeo.http.proxy.ssl.dn";
+// String HTTP_PORT = "org.osgi.service.http.port";
+// String HTTP_PORT_SECURE = "org.osgi.service.http.port.secure";
+// /**
+// * The HTTP header used to convey the DN of a client verified by a reverse
+// * proxy. Typically SSL_CLIENT_S_DN for Apache.
+// */
+// String HTTP_PROXY_SSL_DN = "argeo.http.proxy.ssl.dn";
/*
* PIDs
package org.argeo.api.cms;
-import java.util.Dictionary;
-
/** A configured node deployment. */
public interface CmsDeployment {
package org.argeo.api.cms;
import java.nio.file.Path;
+import java.util.List;
import java.util.UUID;
/** A running node process. */
UUID getUuid();
- String getDeployProperty(String key);
-
+ String getDeployProperty(String property);
+
+ /**
+ * A list of size of the max count for this property, with null values when the
+ * property is not set, or an empty list (size 0) if this property is unknown.
+ */
+ List<String> getDeployProperties(String property);
+
Path getDataPath(String relativePath);
}
package org.argeo.cms;
/** JCR names in the http://www.argeo.org/argeo namespace */
+@Deprecated
public interface ArgeoNames {
public final static String ARGEO_NAMESPACE = "http://www.argeo.org/ns/argeo";
package org.argeo.cms;
/** JCR types in the http://www.argeo.org/argeo namespace */
+@Deprecated
public interface ArgeoTypes {
public final static String ARGEO_REMOTE_REPOSITORY = "argeo:remoteRepository";
-
+
// tabular
public final static String ARGEO_TABLE = "argeo:table";
public final static String ARGEO_COLUMN = "argeo:column";
--- /dev/null
+package org.argeo.cms;
+
+import java.util.Objects;
+
+/** A property that can be used to configure a CMS node deployment. */
+public enum CmsDeployProperty {
+ //
+ // DIRECTORY
+ //
+ DIRECTORY("argeo.directory", 64),
+ //
+ // DATABASE
+ //
+ /** URL of the database backend. */
+ DB_URL("argeo.db.url"),
+ /** DB user of the database backend. */
+ DB_USER("argeo.db.user"),
+ /** DB user password of the database backend. */
+ DB_PASSWORD("argeo.db.password"),
+ //
+ // NETWORK
+ //
+ /** Either a host or an IP address. Restricts all servers to it. */
+ HOST("argeo.host"),
+ //
+ // HTTP
+ //
+ /** Request an HTTP server on this port. */
+ HTTP_PORT("argeo.http.port"),
+ /** Request an HTTPS server on this port. */
+ HTTPS_PORT("argeo.https.port"),
+ /**
+ * The HTTP header used to convey the DN of a client verified by a reverse
+ * proxy. Typically SSL_CLIENT_S_DN for Apache.
+ */
+ HTTP_PROXY_SSL_HEADER_DN("argeo.http.proxy.ssl.header.dn"),
+ //
+ // SSL
+ //
+ /** SSL keystore for the system. */
+ SSL_KEYSTORE("argeo.ssl.keystore"),
+ /** SSL keystore password for the system. */
+ SSL_PASSWORD("argeo.ssl.password"),
+ /** SSL keystore type password for the system. */
+ SSL_KEYSTORETYPE("argeo.ssl.keystoretype"),
+ /** SSL password for the private key. */
+ SSL_KEYPASSWORD("argeo.ssl.keypassword"),
+ /** Whether a client certificate is required. */
+ SSL_NEEDCLIENTAUTH("argeo.ssl.needclientauth"),
+ /** Whether a client certificate can be used. */
+ SSL_WANTCLIENTAUTH("argeo.ssl.wantclientauth"),
+ /** SSL protocol to use. */
+ SSL_PROTOCOL("argeo.ssl.protocol"),
+ /** SSL algorithm to use. */
+ SSL_ALGORITHM("argeo.ssl.algorithm"),
+ //
+ // WEBSOCKET
+ //
+ /** Whether web socket should be enables in web server. */
+ WEBSOCKET_ENABLED("argeo.websocket.enabled"),
+ //
+ // INTERNATIONALIZATION
+ //
+ /** Locales enabled for this system, the first one is considered the default. */
+ LOCALE("argeo.locale", 256),
+ //
+ // NODE
+ //
+ /** Directories to copy to the data area during the first initialisation. */
+ NODE_INIT("argeo.node.init", 64),
+ //
+ // JAVA
+ //
+ /** Custom JAAS config. */
+ JAVA_LOGIN_CONFIG("java.security.auth.login.config", true),
+ //
+ // OSGi
+ //
+ /** OSGi writable data area. */
+ OSGI_INSTANCE_AREA("osgi.instance.area"),
+ /** OSGi writable configuration area. */
+ OSGI_CONFIGURATION_AREA("osgi.configuration.area"),
+ //
+ ;
+
+ private String property;
+ private boolean systemPropertyOnly = false;
+
+ private int maxCount = 1;
+
+ CmsDeployProperty(String property) {
+ this(property, 1, false);
+ }
+
+ CmsDeployProperty(String property, int maxCount) {
+ this(property, maxCount, false);
+ }
+
+ CmsDeployProperty(String property, boolean systemPropertyOnly) {
+ this.property = property;
+ }
+
+ CmsDeployProperty(String property, int maxCount, boolean systemPropertyOnly) {
+ this.property = property;
+ this.systemPropertyOnly = systemPropertyOnly;
+ this.maxCount = maxCount;
+ }
+
+ public String getProperty() {
+ return property;
+ }
+
+ public boolean isSystemPropertyOnly() {
+ return systemPropertyOnly;
+ }
+
+ public int getMaxCount() {
+ return maxCount;
+ }
+
+ public static CmsDeployProperty find(String property) {
+ int index = getPropertyIndex(property);
+ String propertyName = index == 0 ? property : property.substring(0, property.lastIndexOf('.'));
+ for (CmsDeployProperty deployProperty : values()) {
+ if (deployProperty.getProperty().equals(propertyName))
+ return deployProperty;
+ }
+ return null;
+ }
+
+ public static int getPropertyIndex(String property) {
+ Objects.requireNonNull(property);
+ int lastDot = property.lastIndexOf('.');
+ if (lastDot <= 0 || lastDot == (property.length() - 1)) {
+ throw new IllegalArgumentException("Property " + property + " is not qualified (must contain a dot).");
+ }
+ String lastSegment = property.substring(lastDot + 1);
+ int index;
+ try {
+ index = Integer.parseInt(lastSegment);
+ } catch (NumberFormatException e) {
+ index = 0;
+ }
+ return index;
+ }
+
+}
+++ /dev/null
-package org.argeo.cms;
-
-/** @deprecated Use standard Java {@link RuntimeException} instead. */
-@Deprecated
-public class CmsException extends RuntimeException {
- private static final long serialVersionUID = -5341764743356771313L;
-
- public CmsException(String message) {
- super(message);
- }
-
- public CmsException(String message, Throwable e) {
- super(message, e);
- }
-
-}
package org.argeo.cms;
-import java.security.AccessController;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
-import javax.security.auth.Subject;
-
import org.argeo.api.cms.CmsLog;
import org.argeo.cms.auth.CurrentUser;
static Locale getCurrentLocale() {
Locale currentLocale = null;
- if (Subject.getSubject(AccessController.getContext()) != null)
+ if (CurrentUser.isAvailable())
currentLocale = CurrentUser.locale();
else if (threadLocale.get() != null) {
currentLocale = threadLocale.get();
// return Locale.getDefault();
}
- /** Returns null if argument is null. */
- public static List<Locale> asLocaleList(Object locales) {
- if (locales == null)
- return null;
- ArrayList<Locale> availableLocales = new ArrayList<Locale>();
- String[] codes = locales.toString().split(",");
- for (int i = 0; i < codes.length; i++) {
- String code = codes[i];
- // variant not supported
- int indexUnd = code.indexOf("_");
- Locale locale;
- if (indexUnd > 0) {
- String language = code.substring(0, indexUnd);
- String country = code.substring(indexUnd + 1);
- locale = new Locale(language, country);
- } else {
- locale = new Locale(code);
- }
- availableLocales.add(locale);
- }
- return availableLocales;
- }
}
CmsContentSession contentSession = userSessions.get(cmsSession);
if (contentSession == null) {
final CmsContentSession newContentSession = new CmsContentSession(this, cmsSession.getUuid(),
- cmsSession.getSubject(), locale);
+ cmsSession.getSubject(), locale, uuidFactory);
cmsSession.addOnCloseCallback((c) -> {
newContentSession.close();
userSessions.remove(cmsSession);
throw new RuntimeException("Could not login as data admin", e1);
} finally {
}
- return new CmsContentSession(this, getCmsState().getUuid(), loginContext.getSubject(),
- Locale.getDefault());
+ return new CmsContentSession(this, getCmsState().getUuid(), loginContext.getSubject(), Locale.getDefault(),
+ uuidFactory);
}
protected CmsState getCmsState() {
package org.argeo.cms.acr;
-import java.util.Iterator;
import java.util.Locale;
-import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Consumer;
-import java.util.stream.Collectors;
import javax.security.auth.Subject;
import org.argeo.api.acr.Content;
import org.argeo.api.acr.ContentSession;
import org.argeo.api.acr.CrName;
-import org.argeo.api.acr.NamespaceUtils;
-import org.argeo.api.acr.RuntimeNamespaceContext;
import org.argeo.api.acr.spi.ContentProvider;
import org.argeo.api.acr.spi.ProvidedContent;
import org.argeo.api.acr.spi.ProvidedRepository;
import org.argeo.api.acr.spi.ProvidedSession;
+import org.argeo.api.uuid.UuidFactory;
import org.argeo.cms.acr.xml.DomContentProvider;
/** Implements {@link ProvidedSession}. */
private Subject subject;
private Locale locale;
+ private UuidFactory uuidFactory;
+
private CompletableFuture<ProvidedSession> closed = new CompletableFuture<>();
private CompletableFuture<ContentSession> edition;
private Content sessionRunDir;
- public CmsContentSession(AbstractContentRepository contentRepository, UUID uuid, Subject subject, Locale locale) {
+ public CmsContentSession(AbstractContentRepository contentRepository, UUID uuid, Subject subject, Locale locale,
+ UuidFactory uuidFactory) {
this.contentRepository = contentRepository;
this.subject = subject;
this.locale = locale;
this.uuid = uuid;
-
+ this.uuidFactory = uuidFactory;
}
public void close() {
return contentRepository;
}
+ public UuidFactory getUuidFactory() {
+ return uuidFactory;
+ }
+
/*
* MOUNT MANAGEMENT
*/
import org.argeo.api.acr.ContentSession;
import org.argeo.api.acr.spi.ProvidedRepository;
+import org.argeo.api.uuid.MacAddressUuidFactory;
+import org.argeo.api.uuid.UuidFactory;
import org.argeo.cms.acr.fs.FsContentProvider;
import org.argeo.util.naming.LdapAttrs;
private UUID uuid;
+ private UuidFactory uuidFactory = MacAddressUuidFactory.DEFAULT;
+
// the single session
private CmsContentSession contentSession;
initRootContentProvider(null);
if (contentSession != null)
throw new IllegalStateException("Repository is already started, stop it first.");
- contentSession = new CmsContentSession(this, uuid, subject, locale);
+ contentSession = new CmsContentSession(this, uuid, subject, locale, uuidFactory);
}
@Override
@Override
protected CmsContentSession newSystemSession() {
- return new CmsContentSession(this, uuid, subject, Locale.getDefault());
+ return new CmsContentSession(this, uuid, subject, Locale.getDefault(), uuidFactory);
}
public static void main(String... args) {
return CmsContextImpl.getCmsContext().getCmsSessionByUuid(cmsSessionId.getUuid());
}
+ public static boolean isAvailable() {
+ return CurrentSubject.current() != null;
+ }
+
/*
* HELPERS
*/
private static Subject currentSubject() {
- return CurrentSubject.current();
+ Subject subject = CurrentSubject.current();
+ if (subject == null)
+ throw new IllegalStateException("Cannot find related subject");
+ return subject;
}
private static Authorization getAuthorization(Subject subject) {
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.Base64;
import java.util.function.Supplier;
import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosTicket;
import org.argeo.api.cms.CmsSession;
import org.argeo.cms.internal.runtime.CmsContextImpl;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
/** Remote authentication utilities. */
public class RemoteAuthUtils {
CmsSession cmsSession = CmsContextImpl.getCmsContext().getCmsSession(subject);
return cmsSession;
}
+
+ private final static Oid KERBEROS_OID;
+ static {
+ try {
+ KERBEROS_OID = new Oid("1.3.6.1.5.5.2");
+ } catch (GSSException e) {
+ throw new IllegalStateException("Cannot create Kerberos OID", e);
+ }
+ }
+
+ public static String getGssToken(Subject subject, String serverPrinc) {
+ if (subject.getPrivateCredentials(KerberosTicket.class).isEmpty())
+ throw new IllegalArgumentException("Subject " + subject + " is not GSS authenticated.");
+ return Subject.doAs(subject, (PrivilegedAction<String>) () -> {
+ GSSContext context = null;
+ String tokenStr = null;
+
+ try {
+ // Get service's principal name
+ GSSManager manager = GSSManager.getInstance();
+ GSSName serverName = manager.createName(serverPrinc, GSSName.NT_HOSTBASED_SERVICE, KERBEROS_OID);
+
+ // Get the context for authentication
+ context = manager.createContext(serverName, KERBEROS_OID, null, GSSContext.DEFAULT_LIFETIME);
+ // context.requestMutualAuth(true); // Request mutual authentication
+ // context.requestConf(true); // Request confidentiality
+ context.requestCredDeleg(true);
+
+ byte[] token = new byte[0];
+
+ // token is ignored on the first call
+ token = context.initSecContext(token, 0, token.length);
+
+ // Send a token to the server if one was generated by
+ // initSecContext
+ if (token != null) {
+ tokenStr = Base64.getEncoder().encodeToString(token);
+ // complete=true;
+ }
+ return tokenStr;
+
+ } catch (GSSException e) {
+ throw new IllegalStateException("Cannot authenticate to " + serverPrinc, e);
+ }
+ });
+ }
}
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.CmsDeployProperty;
import org.argeo.cms.internal.auth.CmsSessionImpl;
import org.argeo.cms.internal.runtime.CmsContextImpl;
+import org.argeo.cms.internal.runtime.CmsStateImpl;
import org.osgi.service.http.HttpContext;
import org.osgi.service.useradmin.Authorization;
if (log.isDebugEnabled())
log.debug("Client certificate " + certDn + " verified by servlet container");
} // Reverse proxy verified the client certificate
- String clientDnHttpHeader = CmsContextImpl.getCmsContext().getCmsState()
- .getDeployProperty(CmsConstants.HTTP_PROXY_SSL_DN);
+ String clientDnHttpHeader = CmsStateImpl.getDeployProperty(CmsContextImpl.getCmsContext().getCmsState(),
+ CmsDeployProperty.HTTP_PROXY_SSL_HEADER_DN);
if (clientDnHttpHeader != null) {
String certDn = req.getHeader(clientDnHttpHeader);
// TODO retrieve more cf. https://httpd.apache.org/docs/current/mod/mod_ssl.html
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.DefaultHttpParams;
import org.apache.commons.httpclient.params.HttpParams;
-import org.argeo.cms.internal.runtime.KernelConstants;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
}
}
+ private final static String DEFAULT_KERBEROS_SERVICE = "HTTP";
+
private boolean complete = false;
private String realm;
} catch (URIException e1) {
throw new IllegalStateException("Cannot authenticate", e1);
}
- String serverPrinc = KernelConstants.DEFAULT_KERBEROS_SERVICE + "@" + hostname;
+ String serverPrinc = DEFAULT_KERBEROS_SERVICE + "@" + hostname;
try {
// Get service's principal name
import org.argeo.api.cms.CmsLog;
import org.argeo.cms.ArgeoLogListener;
import org.argeo.cms.ArgeoLogger;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.internal.runtime.KernelConstants;
import org.argeo.util.directory.DirectoryConf;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
/** Not meant to be used directly in standard log4j config */
public class CmsOsgiLogger implements ArgeoLogger, LogListener {
+ private final static String WHITEBOARD_PATTERN_PROP = "osgi.http.whiteboard.servlet.pattern";
+ private final static String CONTEXT_NAME_PROP = "contextName";
+
/** Internal debug for development purposes. */
private static Boolean debug = false;
logDispatcherThread = new LogDispatcherThread();
logDispatcherThread.start();
} catch (Exception e) {
- throw new CmsException("Cannot initialize log4j");
+ throw new IllegalStateException("Cannot initialize log4j");
}
}
// sb.append(" " + Constants.SERVICE_PID + ": " + servicePid);
// }
// servlets
- Object whiteBoardPattern = sr.getProperty(KernelConstants.WHITEBOARD_PATTERN_PROP);
+ Object whiteBoardPattern = sr.getProperty(WHITEBOARD_PATTERN_PROP);
if (whiteBoardPattern != null) {
if (whiteBoardPattern instanceof String) {
- sb.append(" " + KernelConstants.WHITEBOARD_PATTERN_PROP + ": " + whiteBoardPattern);
+ sb.append(" " + WHITEBOARD_PATTERN_PROP + ": " + whiteBoardPattern);
} else {
- sb.append(" " + KernelConstants.WHITEBOARD_PATTERN_PROP + ": "
- + arrayToString((String[]) whiteBoardPattern));
+ sb.append(" " + WHITEBOARD_PATTERN_PROP + ": " + arrayToString((String[]) whiteBoardPattern));
}
}
// RWT
- Object contextName = sr.getProperty(KernelConstants.CONTEXT_NAME_PROP);
+ Object contextName = sr.getProperty(CONTEXT_NAME_PROP);
if (contextName != null)
- sb.append(" " + KernelConstants.CONTEXT_NAME_PROP + ": " + contextName);
+ sb.append(" " + CONTEXT_NAME_PROP + ": " + contextName);
// user directories
Object baseDn = sr.getProperty(DirectoryConf.baseDn.name());
public synchronized void register(ArgeoLogListener listener, Integer numberOfPreviousEvents) {
String username = CurrentUser.getUsername();
if (username == null)
- throw new CmsException("Only authenticated users can register a log listener");
+ throw new IllegalStateException("Only authenticated users can register a log listener");
if (!userListeners.containsKey(username)) {
List<ArgeoLogListener> lst = Collections.synchronizedList(new ArrayList<ArgeoLogListener>());
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.internal.runtime.InitUtils;
-import org.argeo.cms.internal.runtime.KernelConstants;
-import org.argeo.cms.internal.runtime.KernelUtils;
import org.argeo.util.directory.DirectoryConf;
import org.argeo.util.directory.ldap.AttributesDictionary;
import org.argeo.util.directory.ldap.LdifParser;
private final CmsLog log = CmsLog.getLog(getClass());
// private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
- private static Path deployConfigPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEPLOY_CONFIG_PATH);
+ private static Path deployConfigPath;// = KernelUtils.getOsgiInstancePath(KernelConstants.DEPLOY_CONFIG_PATH);
private SortedMap<LdapName, Attributes> deployConfigs = new TreeMap<>();
// private final DataModels dataModels;
Files.createDirectories(deployConfigPath.getParent());
// FirstInit firstInit = new FirstInit();
- InitUtils.prepareFirstInitInstanceArea();
+ //InitUtils.prepareFirstInitInstanceArea();
if (!Files.exists(deployConfigPath))
deployConfigs = new TreeMap<>();
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsLog;
import org.argeo.cms.internal.runtime.CmsUserAdmin;
-import org.argeo.cms.internal.runtime.KernelConstants;
import org.argeo.osgi.useradmin.UserDirectory;
import org.argeo.util.directory.DirectoryConf;
import org.osgi.framework.Constants;
* Aggregates multiple {@link UserDirectory} and integrates them with system
* roles.
*/
-public class NodeUserAdmin extends CmsUserAdmin implements ManagedServiceFactory, KernelConstants {
+@Deprecated
+public class NodeUserAdmin extends CmsUserAdmin implements ManagedServiceFactory {
private final static CmsLog log = CmsLog.getLog(NodeUserAdmin.class);
// OSGi
import static java.util.Locale.ENGLISH;
import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import javax.security.auth.Subject;
-import org.argeo.api.acr.spi.ProvidedContent;
-import org.argeo.api.acr.spi.ProvidedRepository;
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsContext;
import org.argeo.api.cms.CmsDeployment;
import org.argeo.api.cms.CmsSessionId;
import org.argeo.api.cms.CmsState;
import org.argeo.api.uuid.UuidFactory;
+import org.argeo.cms.CmsDeployProperty;
import org.argeo.cms.LocaleUtils;
import org.argeo.cms.internal.auth.CmsSessionImpl;
import org.ietf.jgss.GSSCredential;
// }
public void start() {
- Object defaultLocaleValue = KernelUtils.getFrameworkProp(CmsConstants.I18N_DEFAULT_LOCALE);
- defaultLocale = defaultLocaleValue != null ? new Locale(defaultLocaleValue.toString())
- : new Locale(ENGLISH.getLanguage());
- locales = LocaleUtils.asLocaleList(KernelUtils.getFrameworkProp(CmsConstants.I18N_LOCALES));
+ List<String> codes = CmsStateImpl.getDeployProperties(cmsState, CmsDeployProperty.LOCALE);
+ locales = getLocaleList(codes);
+ if (locales.size() == 0)
+ throw new IllegalStateException("At least one locale must be set");
+ defaultLocale = locales.get(0);
+// Object defaultLocaleValue = KernelUtils.getFrameworkProp(CmsConstants.I18N_DEFAULT_LOCALE);
+// defaultLocale = defaultLocaleValue != null ? new Locale(defaultLocaleValue.toString())
+// : new Locale(ENGLISH.getLanguage());
// node repository
// new ServiceTracker<Repository, Repository>(bc, Repository.class, null) {
// @Override
throw new UnsupportedOperationException();
}
+ /** Returns null if argument is null. */
+ private static List<Locale> getLocaleList(List<String> codes) {
+ if (codes == null)
+ return null;
+ ArrayList<Locale> availableLocales = new ArrayList<Locale>();
+ for (String code : codes) {
+ if (code == null)
+ continue;
+ // variant not supported
+ int indexUnd = code.indexOf("_");
+ Locale locale;
+ if (indexUnd > 0) {
+ String language = code.substring(0, indexUnd);
+ String country = code.substring(indexUnd + 1);
+ locale = new Locale(language, country);
+ } else {
+ locale = new Locale(code);
+ }
+ availableLocales.add(locale);
+ }
+ return availableLocales;
+ }
+
public void setCmsDeployment(CmsDeployment cmsDeployment) {
this.cmsDeployment = cmsDeployment;
}
import org.argeo.api.cms.CmsDeployment;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.CmsState;
+import org.argeo.cms.CmsDeployProperty;
import org.osgi.service.http.HttpService;
/** Implementation of a CMS deployment. */
public void setCmsState(CmsState cmsState) {
this.cmsState = cmsState;
- String httpPort = this.cmsState.getDeployProperty("org.osgi.service.http.port");
- String httpsPort = this.cmsState.getDeployProperty("org.osgi.service.http.port.secure");
+ String httpPort = this.cmsState.getDeployProperty(CmsDeployProperty.HTTP_PORT.getProperty());
+ String httpsPort = this.cmsState.getDeployProperty(CmsDeployProperty.HTTPS_PORT.getProperty());
httpExpected = httpPort != null || httpsPort != null;
}
package org.argeo.cms.internal.runtime;
+import java.io.File;
+import java.io.FileFilter;
import java.io.IOException;
-import java.io.InputStream;
+import java.io.Reader;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.TreeMap;
+import java.security.KeyStore;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
import java.util.UUID;
import javax.security.auth.login.Configuration;
+import org.apache.commons.io.FileUtils;
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.CmsState;
import org.argeo.api.uuid.UuidFactory;
+import org.argeo.cms.CmsDeployProperty;
import org.argeo.cms.auth.ident.IdentClient;
-import org.argeo.util.directory.ldap.LdifParser;
/**
* Implementation of a {@link CmsState}, initialising the required services.
private UuidFactory uuidFactory;
+ private final Map<CmsDeployProperty, String> deployPropertyDefaults;
+
+ public CmsStateImpl() {
+ Map<CmsDeployProperty, String> deployPropertyDefaults = new HashMap<>();
+ deployPropertyDefaults.put(CmsDeployProperty.SSL_KEYSTORETYPE, PkiUtils.PKCS12);
+ deployPropertyDefaults.put(CmsDeployProperty.NODE_INIT, "../../init");
+ deployPropertyDefaults.put(CmsDeployProperty.LOCALE, Locale.getDefault().toString());
+ this.deployPropertyDefaults = Collections.unmodifiableMap(deployPropertyDefaults);
+ }
+
public void start() {
// Runtime.getRuntime().addShutdownHook(new CmsShutdown());
}
availableSince = System.currentTimeMillis();
- if (log.isDebugEnabled())
+ if (log.isDebugEnabled()) {
// log.debug("## CMS starting... stateUuid=" + this.stateUuid + (cleanState ? "
// (clean state) " : " "));
- log.debug("## CMS starting... (" + uuid + ")");
-
+ StringJoiner sb = new StringJoiner("\n");
+ CmsDeployProperty[] deployProperties = CmsDeployProperty.values();
+ Arrays.sort(deployProperties, (o1, o2) -> o1.name().compareTo(o2.name()));
+ for (CmsDeployProperty deployProperty : deployProperties) {
+ List<String> values = getDeployProperties(deployProperty);
+ for (int i = 0; i < values.size(); i++) {
+ String value = values.get(i);
+ if (value != null) {
+ boolean isDefault = deployPropertyDefaults.containsKey(deployProperty)
+ && value.equals(deployPropertyDefaults.get(deployProperty));
+ String line = deployProperty.getProperty() + (i == 0 ? "" : "." + i) + "=" + value
+ + (isDefault ? " (default)" : "");
+ sb.add(line);
+ }
+ }
+ }
+ log.debug("## CMS starting... (" + uuid + ")\n" + sb + "\n");
+ }
// initI18n();
// initServices();
}
private void initSecurity() {
- if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) {
+ if (getDeployProperty(CmsDeployProperty.JAVA_LOGIN_CONFIG) == null) {
String jaasConfig = KernelConstants.JAAS_CONFIG;
URL url = getClass().getResource(jaasConfig);
// System.setProperty(KernelConstants.JAAS_CONFIG_PROP,
}
// explicitly load JAAS configuration
Configuration.getConfiguration();
+
+ boolean initSsl = getDeployProperty(CmsDeployProperty.HTTPS_PORT) != null;
+ if (initSsl) {
+ initCertificates();
+ }
+ }
+
+ private void initCertificates() {
+ // server certificate
+ Path keyStorePath = getDataPath(PkiUtils.DEFAULT_KEYSTORE_PATH);
+ Path pemKeyPath = getDataPath(PkiUtils.DEFAULT_PEM_KEY_PATH);
+ Path pemCertPath = getDataPath(PkiUtils.DEFAULT_PEM_CERT_PATH);
+ String keyStorePasswordStr = doGetDeployProperty(CmsDeployProperty.SSL_PASSWORD.getProperty());
+ 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(JettyHttpConstants.SSL_KEYSTORETYPE, PkiUtils.PKCS12);
+// props.put(JettyHttpConstants.SSL_KEYSTORE, keyStorePath.toString());
+// props.put(JettyHttpConstants.SSL_PASSWORD, new String(keyStorePassword));
+
+// props.put(InternalHttpConstants.SSL_KEYSTORETYPE, "PKCS11");
+// props.put(InternalHttpConstants.SSL_KEYSTORE, "../../nssdb");
+// props.put(InternalHttpConstants.SSL_PASSWORD, keyStorePassword);
+
}
public void stop() {
private void firstInit() throws IOException {
log.info("## FIRST INIT ##");
- // FirstInit firstInit = new FirstInit();
- InitUtils.prepareFirstInitInstanceArea();
+ List<String> nodeInits = getDeployProperties(CmsDeployProperty.NODE_INIT);
+// if (nodeInits == null)
+// nodeInits = "../../init";
+ CmsStateImpl.prepareFirstInitInstanceArea(nodeInits);
}
@Override
- public String getDeployProperty(String key) {
- return KernelUtils.getFrameworkProp(key);
+ public String getDeployProperty(String property) {
+ CmsDeployProperty deployProperty = CmsDeployProperty.find(property);
+ if (deployProperty == null) {
+ // legacy
+ if (property.startsWith("argeo.node.")) {
+ return doGetDeployProperty(property);
+ }
+ if (property.equals("argeo.i18n.locales")) {
+ String value = doGetDeployProperty(property);
+ if (value != null) {
+ log.warn("Property " + property + " was ignored (value=" + value + ")");
+
+ }
+ return null;
+ }
+ throw new IllegalArgumentException("Unsupported deploy property " + property);
+ }
+ int index = CmsDeployProperty.getPropertyIndex(property);
+ return getDeployProperty(deployProperty, index);
+ }
+
+ @Override
+ public List<String> getDeployProperties(String property) {
+ CmsDeployProperty deployProperty = CmsDeployProperty.find(property);
+ if (deployProperty == null)
+ return new ArrayList<>();
+ return getDeployProperties(deployProperty);
+ }
+
+ public static List<String> getDeployProperties(CmsState cmsState, CmsDeployProperty deployProperty) {
+ return ((CmsStateImpl) cmsState).getDeployProperties(deployProperty);
+ }
+
+ public List<String> getDeployProperties(CmsDeployProperty deployProperty) {
+ List<String> res = new ArrayList<>(deployProperty.getMaxCount());
+ for (int i = 0; i < deployProperty.getMaxCount(); i++) {
+ // String propertyName = i == 0 ? deployProperty.getProperty() :
+ // deployProperty.getProperty() + "." + i;
+ String value = getDeployProperty(deployProperty, i);
+ res.add(i, value);
+ }
+ return res;
+ }
+
+ public static String getDeployProperty(CmsState cmsState, CmsDeployProperty deployProperty) {
+ return ((CmsStateImpl) cmsState).getDeployProperty(deployProperty);
+ }
+
+ public String getDeployProperty(CmsDeployProperty deployProperty) {
+ String value = getDeployProperty(deployProperty, 0);
+ return value;
+ }
+
+ public String getDeployProperty(CmsDeployProperty deployProperty, int index) {
+ String propertyName = deployProperty.getProperty() + (index == 0 ? "" : "." + index);
+ String value = doGetDeployProperty(propertyName);
+ if (value == null && index == 0) {
+ // try defaults
+ if (deployPropertyDefaults.containsKey(deployProperty)) {
+ value = deployPropertyDefaults.get(deployProperty);
+ }
+ // try legacy properties
+ String legacyProperty = switch (deployProperty) {
+ case DIRECTORY -> "argeo.node.useradmin.uris";
+ case DB_URL -> "argeo.node.dburl";
+ case DB_USER -> "argeo.node.dbuser";
+ case DB_PASSWORD -> "argeo.node.dbpassword";
+ case HTTP_PORT -> "org.osgi.service.http.port";
+ case HTTPS_PORT -> "org.osgi.service.http.port.secure";
+ case HOST -> "org.eclipse.equinox.http.jetty.http.host";
+ case LOCALE -> "argeo.i18n.defaultLocale";
+
+ default -> null;
+ };
+ if (legacyProperty != null) {
+ value = doGetDeployProperty(legacyProperty);
+ if (value != null) {
+ log.warn("Retrieved deploy property " + deployProperty.getProperty()
+ + " through deprecated property " + legacyProperty);
+ }
+ }
+ }
+ if (index == 0 && deployProperty.isSystemPropertyOnly()) {
+ String systemPropertyValue = System.getProperty(deployProperty.getProperty());
+ if (!Objects.equals(value, systemPropertyValue))
+ throw new IllegalStateException(
+ "Property " + deployProperty + " must be a ssystem property, but its value is " + value
+ + ", while the system property value is " + systemPropertyValue);
+ }
+ return value != null ? value.toString() : null;
+ }
+
+ protected String getLegacyProperty(String legacyProperty, CmsDeployProperty deployProperty) {
+ String value = doGetDeployProperty(legacyProperty);
+ if (value != null) {
+ log.warn("Retrieved deploy property " + deployProperty.getProperty() + " through deprecated property "
+ + legacyProperty + ".");
+ }
+ return value;
+ }
+
+ protected String doGetDeployProperty(String property) {
+ return KernelUtils.getFrameworkProp(property);
}
@Override
this.uuidFactory = uuidFactory;
}
+ /**
+ * Called before node initialisation, in order populate OSGi instance are with
+ * some files (typically LDIF, etc).
+ */
+ public static void prepareFirstInitInstanceArea(List<String> nodeInits) {
+
+ for (String nodeInit : nodeInits) {
+
+ if (nodeInit.startsWith("http")) {
+ // TODO reconnect it
+ // registerRemoteInit(nodeInit);
+ } else {
+
+ // TODO use java.nio.file
+ File initDir;
+ if (nodeInit.startsWith("."))
+ initDir = KernelUtils.getExecutionDir(nodeInit);
+ else
+ initDir = new File(nodeInit);
+ // TODO also uncompress archives
+ if (initDir.exists())
+ try {
+ // TODO use NIO utilities
+ FileUtils.copyDirectory(initDir, KernelUtils.getOsgiInstancePath("").toFile(),
+ new FileFilter() {
+
+ @Override
+ public boolean accept(File pathname) {
+ if (pathname.getName().equals(".svn") || pathname.getName().equals(".git"))
+ return false;
+ return true;
+ }
+ });
+ log.info("CMS initialized from " + initDir.getCanonicalPath());
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot initialize from " + initDir, e);
+ }
+ }
+ }
+ }
+
/*
* STATIC
*/
package org.argeo.cms.internal.runtime;
+import java.io.File;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import org.apache.commons.httpclient.params.DefaultHttpParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.params.HttpParams;
+import org.apache.commons.io.FileUtils;
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.CmsDeployProperty;
import org.argeo.cms.internal.http.client.HttpCredentialProvider;
import org.argeo.cms.internal.http.client.SpnegoAuthScheme;
import org.argeo.osgi.useradmin.AggregatingUserAdmin;
public void start() {
super.start();
- List<Dictionary<String, Object>> configs = InitUtils.getUserDirectoryConfigs();
+ List<Dictionary<String, Object>> configs = getUserDirectoryConfigs();
for (Dictionary<String, Object> config : configs) {
UserDirectory userDirectory = enableUserDirectory(config);
if (userDirectory.getRealm().isPresent())
super.stop();
}
+ protected List<Dictionary<String, Object>> getUserDirectoryConfigs() {
+ List<Dictionary<String, Object>> res = new ArrayList<>();
+ File nodeBaseDir = cmsState.getDataPath(KernelConstants.DIR_NODE).toFile();
+ List<String> uris = new ArrayList<>();
+
+ // node roles
+ String nodeRolesUri = null;// getFrameworkProp(CmsConstants.ROLES_URI);
+ String baseNodeRoleDn = CmsConstants.ROLES_BASEDN;
+ if (nodeRolesUri == null) {
+ nodeRolesUri = baseNodeRoleDn + ".ldif";
+ File nodeRolesFile = new File(nodeBaseDir, nodeRolesUri);
+ if (!nodeRolesFile.exists())
+ try {
+ FileUtils.copyInputStreamToFile(CmsUserAdmin.class.getResourceAsStream(baseNodeRoleDn + ".ldif"),
+ nodeRolesFile);
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot copy demo resource", e);
+ }
+ // nodeRolesUri = nodeRolesFile.toURI().toString();
+ }
+ uris.add(nodeRolesUri);
+
+ // node tokens
+ String nodeTokensUri = null;// getFrameworkProp(CmsConstants.TOKENS_URI);
+ String baseNodeTokensDn = CmsConstants.TOKENS_BASEDN;
+ if (nodeTokensUri == null) {
+ nodeTokensUri = baseNodeTokensDn + ".ldif";
+ File nodeTokensFile = new File(nodeBaseDir, nodeTokensUri);
+ if (!nodeTokensFile.exists())
+ try {
+ FileUtils.copyInputStreamToFile(CmsUserAdmin.class.getResourceAsStream(baseNodeTokensDn + ".ldif"),
+ nodeTokensFile);
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot copy demo resource", e);
+ }
+ // nodeRolesUri = nodeRolesFile.toURI().toString();
+ }
+ uris.add(nodeTokensUri);
+
+ // Business roles
+// String userAdminUris = getFrameworkProp(CmsConstants.USERADMIN_URIS);
+ List<String> userAdminUris = CmsStateImpl.getDeployProperties(cmsState, CmsDeployProperty.DIRECTORY);// getFrameworkProp(CmsConstants.USERADMIN_URIS);
+ for (String userAdminUri : userAdminUris) {
+ if (userAdminUri == null)
+ continue;
+// if (!userAdminUri.trim().equals(""))
+ uris.add(userAdminUri);
+ }
+
+ if (uris.size() == 0) {
+ // TODO put this somewhere else
+ String demoBaseDn = "dc=example,dc=com";
+ String userAdminUri = demoBaseDn + ".ldif";
+ File businessRolesFile = new File(nodeBaseDir, userAdminUri);
+ File systemRolesFile = new File(nodeBaseDir, "ou=roles,ou=node.ldif");
+ if (!businessRolesFile.exists())
+ try {
+ FileUtils.copyInputStreamToFile(CmsUserAdmin.class.getResourceAsStream(demoBaseDn + ".ldif"),
+ businessRolesFile);
+ if (!systemRolesFile.exists())
+ FileUtils.copyInputStreamToFile(
+ CmsUserAdmin.class.getResourceAsStream("example-ou=roles,ou=node.ldif"),
+ systemRolesFile);
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot copy demo resources", e);
+ }
+ // userAdminUris = businessRolesFile.toURI().toString();
+ log.warn("## DEV Using dummy base DN " + demoBaseDn);
+ // TODO downgrade security level
+ }
+
+ // Interprets URIs
+ for (String uri : uris) {
+ URI u;
+ try {
+ u = new URI(uri);
+ if (u.getPath() == null)
+ throw new IllegalArgumentException(
+ "URI " + uri + " must have a path in order to determine base DN");
+ if (u.getScheme() == null) {
+ if (uri.startsWith("/") || uri.startsWith("./") || uri.startsWith("../"))
+ u = new File(uri).getCanonicalFile().toURI();
+ else if (!uri.contains("/")) {
+ // u = KernelUtils.getOsgiInstanceUri(KernelConstants.DIR_NODE + '/' + uri);
+ u = new URI(uri);
+ } else
+ throw new IllegalArgumentException("Cannot interpret " + uri + " as an uri");
+ } else if (u.getScheme().equals(DirectoryConf.SCHEME_FILE)) {
+ u = new File(u).getCanonicalFile().toURI();
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot interpret " + uri + " as an uri", e);
+ }
+ Dictionary<String, Object> properties = DirectoryConf.uriAsProperties(u.toString());
+ res.add(properties);
+ }
+
+ return res;
+ }
+
public UserDirectory enableUserDirectory(Dictionary<String, ?> properties) {
String uri = (String) properties.get(DirectoryConf.uri.name());
Object realm = properties.get(DirectoryConf.realm.name());
}
private void loadIpaJaasConfiguration() {
- if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) {
+ if (CmsStateImpl.getDeployProperty(cmsState, CmsDeployProperty.JAVA_LOGIN_CONFIG) == null) {
String jaasConfig = KernelConstants.JAAS_CONFIG_IPA;
URL url = getClass().getClassLoader().getResource(jaasConfig);
KernelUtils.setJaasConfiguration(url);
+++ /dev/null
-package org.argeo.cms.internal.runtime;
-
-import static org.argeo.cms.internal.runtime.KernelUtils.getFrameworkProp;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-
-import org.apache.commons.io.FileUtils;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.util.directory.DirectoryConf;
-
-/**
- * Interprets framework properties in order to generate the initial deploy
- * configuration.
- */
-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 List<Dictionary<String, Object>> getUserDirectoryConfigs() {
- List<Dictionary<String, Object>> res = new ArrayList<>();
- File nodeBaseDir = KernelUtils.getOsgiInstancePath(KernelConstants.DIR_NODE).toFile();
- List<String> uris = new ArrayList<>();
-
- // node roles
- String nodeRolesUri = getFrameworkProp(CmsConstants.ROLES_URI);
- String baseNodeRoleDn = CmsConstants.ROLES_BASEDN;
- if (nodeRolesUri == null) {
- nodeRolesUri = baseNodeRoleDn + ".ldif";
- File nodeRolesFile = new File(nodeBaseDir, nodeRolesUri);
- if (!nodeRolesFile.exists())
- try {
- FileUtils.copyInputStreamToFile(InitUtils.class.getResourceAsStream(baseNodeRoleDn + ".ldif"),
- nodeRolesFile);
- } catch (IOException e) {
- throw new RuntimeException("Cannot copy demo resource", e);
- }
- // nodeRolesUri = nodeRolesFile.toURI().toString();
- }
- uris.add(nodeRolesUri);
-
- // node tokens
- String nodeTokensUri = getFrameworkProp(CmsConstants.TOKENS_URI);
- String baseNodeTokensDn = CmsConstants.TOKENS_BASEDN;
- if (nodeTokensUri == null) {
- nodeTokensUri = baseNodeTokensDn + ".ldif";
- File nodeTokensFile = new File(nodeBaseDir, nodeTokensUri);
- if (!nodeTokensFile.exists())
- try {
- FileUtils.copyInputStreamToFile(InitUtils.class.getResourceAsStream(baseNodeTokensDn + ".ldif"),
- nodeTokensFile);
- } catch (IOException e) {
- throw new RuntimeException("Cannot copy demo resource", e);
- }
- // nodeRolesUri = nodeRolesFile.toURI().toString();
- }
- uris.add(nodeTokensUri);
-
- // Business roles
- String userAdminUris = getFrameworkProp(CmsConstants.USERADMIN_URIS);
- if (userAdminUris == null) {
- String demoBaseDn = "dc=example,dc=com";
- userAdminUris = demoBaseDn + ".ldif";
- File businessRolesFile = new File(nodeBaseDir, userAdminUris);
- File systemRolesFile = new File(nodeBaseDir, "ou=roles,ou=node.ldif");
- if (!businessRolesFile.exists())
- try {
- FileUtils.copyInputStreamToFile(InitUtils.class.getResourceAsStream(demoBaseDn + ".ldif"),
- businessRolesFile);
- if (!systemRolesFile.exists())
- FileUtils.copyInputStreamToFile(
- InitUtils.class.getResourceAsStream("example-ou=roles,ou=node.ldif"), systemRolesFile);
- } catch (IOException e) {
- throw new RuntimeException("Cannot copy demo resources", e);
- }
- // userAdminUris = businessRolesFile.toURI().toString();
- log.warn("## DEV Using dummy base DN " + demoBaseDn);
- // TODO downgrade security level
- }
- for (String userAdminUri : userAdminUris.split(" "))
- if (!userAdminUri.trim().equals(""))
- uris.add(userAdminUri);
-
- // Interprets URIs
- for (String uri : uris) {
- URI u;
- try {
- u = new URI(uri);
- if (u.getPath() == null)
- throw new IllegalArgumentException(
- "URI " + uri + " must have a path in order to determine base DN");
- if (u.getScheme() == null) {
- if (uri.startsWith("/") || uri.startsWith("./") || uri.startsWith("../"))
- u = new File(uri).getCanonicalFile().toURI();
- else if (!uri.contains("/")) {
- // u = KernelUtils.getOsgiInstanceUri(KernelConstants.DIR_NODE + '/' + uri);
- u = new URI(uri);
- } else
- throw new IllegalArgumentException("Cannot interpret " + uri + " as an uri");
- } else if (u.getScheme().equals(DirectoryConf.SCHEME_FILE)) {
- u = new File(u).getCanonicalFile().toURI();
- }
- } catch (Exception e) {
- throw new RuntimeException("Cannot interpret " + uri + " as an uri", e);
- }
- Dictionary<String, Object> properties = DirectoryConf.uriAsProperties(u.toString());
- res.add(properties);
- }
-
- return res;
- }
-
- /**
- * Called before node initialisation, in order populate OSGi instance are with
- * some files (typically LDIF, etc).
- */
- public static void prepareFirstInitInstanceArea() {
- String nodeInits = getFrameworkProp(CmsConstants.NODE_INIT);
- if (nodeInits == null)
- nodeInits = "../../init";
-
- for (String nodeInit : nodeInits.split(",")) {
-
- if (nodeInit.startsWith("http")) {
- // TODO reconnect it
- // registerRemoteInit(nodeInit);
- } else {
-
- // TODO use java.nio.file
- File initDir;
- if (nodeInit.startsWith("."))
- initDir = KernelUtils.getExecutionDir(nodeInit);
- else
- initDir = new File(nodeInit);
- // TODO also uncompress archives
- if (initDir.exists())
- try {
- // TODO use NIO utilities
- FileUtils.copyDirectory(initDir, KernelUtils.getOsgiInstancePath("").toFile(),
- new FileFilter() {
-
- @Override
- public boolean accept(File pathname) {
- if (pathname.getName().equals(".svn") || pathname.getName().equals(".git"))
- return false;
- return true;
- }
- });
- log.info("CMS initialized from " + initDir.getCanonicalPath());
- } catch (IOException e) {
- throw new RuntimeException("Cannot initialize from " + initDir, e);
- }
- }
- }
- }
-
-}
package org.argeo.cms.internal.runtime;
-import org.argeo.api.cms.CmsConstants;
-
/** Internal CMS constants. */
-public interface KernelConstants {
+interface KernelConstants {
// Directories
String DIR_NODE = "node";
- String DIR_REPOS = "repos";
- String DIR_INDEXES = "indexes";
- String DIR_TRANSACTIONS = "transactions";
+// String DIR_REPOS = "repos";
+// String DIR_INDEXES = "indexes";
+// String DIR_TRANSACTIONS = "transactions";
// Files
- String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + CmsConstants.DEPLOY_BASEDN + ".ldif";
+// String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + CmsConstants.DEPLOY_BASEDN + ".ldif";
String NODE_KEY_TAB_PATH = DIR_NODE + "/krb5.keytab";
// Security
String JAAS_CONFIG_IPA = "/org/argeo/cms/internal/runtime/jaas-ipa.cfg";
// Java
- String JAAS_CONFIG_PROP = "java.security.auth.login.config";
+// String JAAS_CONFIG_PROP = "java.security.auth.login.config";
// DEFAULTS JCR PATH
- String DEFAULT_HOME_BASE_PATH = "/home";
- String DEFAULT_USERS_BASE_PATH = "/users";
- String DEFAULT_GROUPS_BASE_PATH = "/groups";
+// String DEFAULT_HOME_BASE_PATH = "/home";
+// String DEFAULT_USERS_BASE_PATH = "/users";
+// String DEFAULT_GROUPS_BASE_PATH = "/groups";
// KERBEROS
String DEFAULT_KERBEROS_SERVICE = "HTTP";
// String PATH_WORKBENCH_PUBLIC = PATH_WORKBENCH + "/public";
// String JETTY_FACTORY_PID = "org.eclipse.equinox.http.jetty.config";
- String JETTY_FACTORY_PID = "org.argeo.equinox.jetty.config";
- String WHITEBOARD_PATTERN_PROP = "osgi.http.whiteboard.servlet.pattern";
+// String JETTY_FACTORY_PID = "org.argeo.equinox.jetty.config";
// default Jetty server configured via JettyConfigurator
- String DEFAULT_JETTY_SERVER = "default";
- String CMS_JETTY_CUSTOMIZER_CLASS = "org.argeo.equinox.jetty.CmsJettyCustomizer";
+// String DEFAULT_JETTY_SERVER = "default";
+// String CMS_JETTY_CUSTOMIZER_CLASS = "org.argeo.equinox.jetty.CmsJettyCustomizer";
// avoid dependencies
- String CONTEXT_NAME_PROP = "contextName";
- String JACKRABBIT_REPOSITORY_URI = "org.apache.jackrabbit.repository.uri";
- String JACKRABBIT_REMOTE_DEFAULT_WORKSPACE = "org.apache.jackrabbit.spi2davex.WorkspaceNameDefault";
+// String JACKRABBIT_REPOSITORY_URI = "org.apache.jackrabbit.repository.uri";
+// String JACKRABBIT_REMOTE_DEFAULT_WORKSPACE = "org.apache.jackrabbit.spi2davex.WorkspaceNameDefault";
}
import org.argeo.cms.internal.osgi.CmsActivator;
/** Package utilities */
-public class KernelUtils implements KernelConstants {
+class KernelUtils implements KernelConstants {
final static String OSGI_INSTANCE_AREA = "osgi.instance.area";
final static String OSGI_CONFIGURATION_AREA = "osgi.configuration.area";
--- /dev/null
+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.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.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 {
+ 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");
+ }
+ }
+
+}
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
-import java.security.AccessController;
import java.security.Provider;
import java.security.Security;
import java.util.Arrays;
import org.apache.commons.io.IOUtils;
import org.argeo.api.cms.CmsAuth;
-import org.argeo.cms.CmsException;
+import org.argeo.util.CurrentSubject;
/** username / password based keyring. TODO internationalize */
public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
/** Triggers lazy initialization */
protected SecretKey getSecretKey(char[] password) {
- Subject subject = Subject.getSubject(AccessController.getContext());
+ Subject subject = CurrentSubject.current();
+ if (subject == null)
+ throw new IllegalStateException("Current subject cannot be null");
// we assume only one secrete key is available
Iterator<SecretKey> iterator = subject.getPrivateCredentials(SecretKey.class).iterator();
- if (!iterator.hasNext() || password!=null) {// not initialized
+ if (!iterator.hasNext() || password != null) {// not initialized
CallbackHandler callbackHandler = password == null ? new KeyringCallbackHandler()
: new PasswordProvidedCallBackHandler(password);
ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
try {
- LoginContext loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_KEYRING, subject,
- callbackHandler);
+ LoginContext loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_KEYRING, subject, callbackHandler);
loginContext.login();
// FIXME will login even if password is wrong
iterator = subject.getPrivateCredentials(SecretKey.class).iterator();
return iterator.next();
} catch (LoginException e) {
- throw new CmsException("Keyring login failed", e);
+ throw new IllegalStateException("Keyring login failed", e);
} finally {
Thread.currentThread().setContextClassLoader(currentContextClassLoader);
}
} else {
SecretKey secretKey = iterator.next();
if (iterator.hasNext())
- throw new CmsException("More than one secret key in private credentials");
+ throw new IllegalStateException("More than one secret key in private credentials");
return secretKey;
}
}
IOUtils.copy(reader, writer);
return writer.toCharArray();
} catch (IOException e) {
- throw new CmsException("Cannot decrypt to char array", e);
+ throw new IllegalStateException("Cannot decrypt to char array", e);
} finally {
// IOUtils.closeQuietly(reader);
// IOUtils.closeQuietly(in);
set(path, in);
}
} catch (IOException e) {
- throw new CmsException("Cannot encrypt to char array", e);
+ throw new IllegalStateException("Cannot encrypt to char array", e);
} finally {
// IOUtils.closeQuietly(writer);
// IOUtils.closeQuietly(out);
setup(password);
SecretKey secretKey = getSecretKey(password);
if (secretKey == null)
- throw new CmsException("Could not unlock keyring");
+ throw new IllegalStateException("Could not unlock keyring");
}
protected Provider getSecurityProvider() {
char[] password = passwordCb.getPassword();
return password;
} catch (Exception e) {
- throw new CmsException("Cannot ask for a password", e);
+ throw new IllegalStateException("Cannot ask for a password", e);
}
}
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.zip.Checksum;
-import org.argeo.cms.CmsException;
-
/** Allows to fine tune how files are read. */
public class ChecksumFactory {
private int regionSize = 10 * 1024 * 1024;
return digest;
}
}
- } catch (Exception e) {
- throw new CmsException("Cannot digest " + path, e);
+ } catch (NoSuchAlgorithmException | IOException e) {
+ throw new IllegalStateException("Cannot digest " + path, e);
}
}
cursor = cursor + regionSize;
}
return crc.getValue();
- } catch (Exception e) {
- throw new CmsException("Cannot checksum " + path, e);
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot checksum " + path, e);
} finally {
long duration = System.currentTimeMillis() - begin;
System.out.println(duration / 1000 + "s");
+++ /dev/null
-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");
- }
- }
-
-}
+++ /dev/null
-package org.argeo.osgi.metatype;
-
-import org.argeo.util.naming.SpecifiedName;
-import org.osgi.service.metatype.AttributeDefinition;
-
-public interface EnumAD extends SpecifiedName, AttributeDefinition {
- String name();
-
- default Object getDefault() {
- return null;
- }
-
- @Override
- default String getName() {
- return name();
- }
-
- @Override
- default String getID() {
- return getClass().getName() + "." + name();
- }
-
- @Override
- default String getDescription() {
- return null;
- }
-
- @Override
- default int getCardinality() {
- return 0;
- }
-
- @Override
- default int getType() {
- return STRING;
- }
-
- @Override
- default String[] getOptionValues() {
- return null;
- }
-
- @Override
- default String[] getOptionLabels() {
- return null;
- }
-
- @Override
- default String validate(String value) {
- return null;
- }
-
- @Override
- default String[] getDefaultValue() {
- Object value = getDefault();
- if (value == null)
- return null;
- return new String[] { value.toString() };
- }
-}
+++ /dev/null
-package org.argeo.osgi.metatype;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.List;
-
-import org.osgi.service.metatype.AttributeDefinition;
-import org.osgi.service.metatype.ObjectClassDefinition;
-
-public class EnumOCD<T extends Enum<T>> implements ObjectClassDefinition {
- private final Class<T> enumClass;
- private String locale;
-
- public EnumOCD(Class<T> clazz, String locale) {
- this.enumClass = clazz;
- this.locale = locale;
- }
-
- @Override
- public String getName() {
- return null;
- }
-
- public String getLocale() {
- return locale;
- }
-
- @Override
- public String getID() {
- return enumClass.getName();
- }
-
- @Override
- public String getDescription() {
- return null;
- }
-
- @Override
- public AttributeDefinition[] getAttributeDefinitions(int filter) {
- EnumSet<T> set = EnumSet.allOf(enumClass);
- List<AttributeDefinition> attrs = new ArrayList<>();
- for (T key : set)
- attrs.add((AttributeDefinition) key);
- return attrs.toArray(new AttributeDefinition[attrs.size()]);
- }
-
- @Override
- public InputStream getIcon(int size) throws IOException {
- return null;
- }
-
-}
+++ /dev/null
-/** OSGi metatype support. */
-package org.argeo.osgi.metatype;
\ No newline at end of file
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.ux.CmsTheme;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.ui.CmsUiConstants;
import org.argeo.cms.ui.CmsUiProvider;
import org.argeo.cms.ui.util.CmsUiUtils;
import javax.script.ScriptException;
import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.eclipse.rap.rwt.application.Application;
import org.eclipse.rap.rwt.application.ApplicationConfiguration;
import org.osgi.framework.BundleContext;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.ux.CmsView;
import org.argeo.api.cms.CmsAuth;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.auth.RemoteAuthCallback;
import org.argeo.cms.auth.RemoteAuthCallbackHandler;
import org.argeo.cms.servlet.ServletHttpRequest;
import org.argeo.cms.servlet.ServletHttpResponse;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.CmsStyles;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.eclipse.ui.specific.UiContext;
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.ui.CmsUiConstants;
import org.argeo.cms.ui.CmsUiProvider;
import org.argeo.cms.ui.LifeCycleUiProvider;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.ux.CmsImageManager;
import org.argeo.api.cms.ux.UxContext;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.CmsStyles;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.SimpleSwtUxContext;
import org.argeo.api.cms.ux.CmsImageManager;
import org.argeo.api.cms.ux.CmsView;
import org.argeo.api.cms.ux.UxContext;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsException;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.SimpleSwtUxContext;
import org.argeo.cms.swt.auth.CmsLoginShell;
}
}
if (CurrentUser.getUsername(getSubject()) == null)
- throw new CmsException("Cannot log in");
+ throw new IllegalStateException("Cannot log in");
// try {
// CallbackHandler callbackHandler = new DefaultLoginDialog(