package org.argeo.cms.internal.runtime;
-import java.io.File;
-import java.io.FileFilter;
+import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.Reader;
import java.net.InetAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermission;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.StringJoiner;
import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
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.cms.util.FsUtils;
/**
* Implementation of a {@link CmsState}, initialising the required services.
private final Map<CmsDeployProperty, String> deployPropertyDefaults;
public CmsStateImpl() {
+ this.deployPropertyDefaults = Collections.unmodifiableMap(createDeployPropertiesDefaults());
+ }
+
+ protected Map<CmsDeployProperty, String> createDeployPropertiesDefaults() {
Map<CmsDeployProperty, String> deployPropertyDefaults = new HashMap<>();
deployPropertyDefaults.put(CmsDeployProperty.NODE_INIT, "../../init");
deployPropertyDefaults.put(CmsDeployProperty.LOCALE, Locale.getDefault().toString());
// certificates
- deployPropertyDefaults.put(CmsDeployProperty.SSL_KEYSTORETYPE, PkiUtils.PKCS12);
- deployPropertyDefaults.put(CmsDeployProperty.SSL_PASSWORD, PkiUtils.DEFAULT_KEYSTORE_PASSWORD);
- Path keyStorePath = getDataPath(PkiUtils.DEFAULT_KEYSTORE_PATH);
- deployPropertyDefaults.put(CmsDeployProperty.SSL_KEYSTORE, keyStorePath.toAbsolutePath().toString());
-
- Path trustStorePath = getDataPath(PkiUtils.DEFAULT_TRUSTSTORE_PATH);
- deployPropertyDefaults.put(CmsDeployProperty.SSL_TRUSTSTORETYPE, PkiUtils.PKCS12);
- deployPropertyDefaults.put(CmsDeployProperty.SSL_TRUSTSTOREPASSWORD, PkiUtils.DEFAULT_KEYSTORE_PASSWORD);
- deployPropertyDefaults.put(CmsDeployProperty.SSL_TRUSTSTORE, trustStorePath.toAbsolutePath().toString());
+ deployPropertyDefaults.put(CmsDeployProperty.SSL_KEYSTORETYPE, KernelConstants.PKCS12);
+ deployPropertyDefaults.put(CmsDeployProperty.SSL_PASSWORD, KernelConstants.DEFAULT_KEYSTORE_PASSWORD);
+ Path keyStorePath = getDataPath(KernelConstants.DEFAULT_KEYSTORE_PATH);
+ if (keyStorePath != null) {
+ deployPropertyDefaults.put(CmsDeployProperty.SSL_KEYSTORE, keyStorePath.toAbsolutePath().toString());
+ }
- this.deployPropertyDefaults = Collections.unmodifiableMap(deployPropertyDefaults);
+ Path trustStorePath = getDataPath(KernelConstants.DEFAULT_TRUSTSTORE_PATH);
+ if (trustStorePath != null) {
+ deployPropertyDefaults.put(CmsDeployProperty.SSL_TRUSTSTORE, trustStorePath.toAbsolutePath().toString());
+ }
+ deployPropertyDefaults.put(CmsDeployProperty.SSL_TRUSTSTORETYPE, KernelConstants.PKCS12);
+ deployPropertyDefaults.put(CmsDeployProperty.SSL_TRUSTSTOREPASSWORD, KernelConstants.DEFAULT_KEYSTORE_PASSWORD);
+
+ // SSH
+ Path authorizedKeysPath = getDataPath(KernelConstants.NODE_SSHD_AUTHORIZED_KEYS_PATH);
+ if (authorizedKeysPath != null) {
+ deployPropertyDefaults.put(CmsDeployProperty.SSHD_AUTHORIZEDKEYS,
+ authorizedKeysPath.toAbsolutePath().toString());
+ }
+ return deployPropertyDefaults;
}
public void start() {
// this.uuid = UUID.fromString(stateUuidStr);
this.uuid = uuidFactory.timeUUID();
// this.cleanState = stateUuid.equals(frameworkUuid);
- try {
- this.hostname = InetAddress.getLocalHost().getHostName();
- } catch (UnknownHostException e) {
- log.error("Cannot set hostname: " + e);
+
+ // hostname
+ this.hostname = getDeployProperty(CmsDeployProperty.HOST);
+ // TODO verify we have access to the IP address
+ if (hostname == null) {
+ final String LOCALHOST_IP = "::1";
+ ForkJoinTask<String> hostnameFJT = ForkJoinPool.commonPool().submit(() -> {
+ try {
+ String hostname = InetAddress.getLocalHost().getHostName();
+ return hostname;
+ } catch (UnknownHostException e) {
+ throw new IllegalStateException("Cannot get local hostname", e);
+ }
+ });
+ try {
+ this.hostname = hostnameFJT.get(5, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ this.hostname = LOCALHOST_IP;
+ log.warn("Could not get local hostname, using " + this.hostname);
+ }
}
availableSince = System.currentTimeMillis();
log.debug("## CMS starting... (" + uuid + ")\n" + sb + "\n");
}
-// initI18n();
-// initServices();
- if (!Files.exists(getDataPath(CmsConstants.NODE))) {// first init
+ Path privateBase = getDataPath(KernelConstants.DIR_PRIVATE);
+ if (privateBase != null && !Files.exists(privateBase)) {// first init
firstInit();
+ Files.createDirectories(privateBase);
}
} catch (RuntimeException | IOException e) {
- log.error("## FATAL: CMS activator failed", e);
+ log.error("## FATAL: CMS state failed", e);
}
}
private void initSecurity() {
+ // private directory permissions
+ Path privateDir = KernelUtils.getOsgiInstancePath(KernelConstants.DIR_PRIVATE);
+ if (privateDir != null) {
+ // TODO rather check whether we can read and write
+ Set<PosixFilePermission> posixPermissions = new HashSet<>();
+ posixPermissions.add(PosixFilePermission.OWNER_READ);
+ posixPermissions.add(PosixFilePermission.OWNER_WRITE);
+ posixPermissions.add(PosixFilePermission.OWNER_EXECUTE);
+ try {
+ if (!Files.exists(privateDir))
+ Files.createDirectories(privateDir);
+ Files.setPosixFilePermissions(privateDir, posixPermissions);
+ } catch (IOException e) {
+ log.error("Cannot set permissions on " + privateDir, e);
+ }
+ }
+
if (getDeployProperty(CmsDeployProperty.JAVA_LOGIN_CONFIG) == null) {
String jaasConfig = KernelConstants.JAAS_CONFIG;
URL url = getClass().getResource(jaasConfig);
private void initCertificates() {
// server certificate
Path keyStorePath = Paths.get(getDeployProperty(CmsDeployProperty.SSL_KEYSTORE));
- Path pemKeyPath = getDataPath(PkiUtils.DEFAULT_PEM_KEY_PATH);
- Path pemCertPath = getDataPath(PkiUtils.DEFAULT_PEM_CERT_PATH);
+ Path pemKeyPath = getDataPath(KernelConstants.DEFAULT_PEM_KEY_PATH);
+ Path pemCertPath = getDataPath(KernelConstants.DEFAULT_PEM_CERT_PATH);
char[] keyStorePassword = getDeployProperty(CmsDeployProperty.SSL_PASSWORD).toCharArray();
// Keystore
KeyStore keyStore = PkiUtils.getKeyStore(keyStorePath, keyStorePassword,
getDeployProperty(CmsDeployProperty.SSL_KEYSTORETYPE));
try (Reader key = Files.newBufferedReader(pemKeyPath, StandardCharsets.US_ASCII);
- Reader cert = Files.newBufferedReader(pemCertPath, StandardCharsets.US_ASCII);) {
- PkiUtils.loadPem(keyStore, key, keyStorePassword, cert);
+ BufferedInputStream cert = new BufferedInputStream(Files.newInputStream(pemCertPath));) {
+ PkiUtils.loadPrivateCertificatePem(keyStore, CmsConstants.NODE, key, keyStorePassword, cert);
Files.createDirectories(keyStorePath.getParent());
PkiUtils.saveKeyStore(keyStorePath, keyStorePassword, keyStore);
if (log.isDebugEnabled())
char[] trustStorePassword = getDeployProperty(CmsDeployProperty.SSL_TRUSTSTOREPASSWORD).toCharArray();
// IPA CA
- Path ipaCaCertPath = Paths.get(PkiUtils.IPA_PEM_CA_CERT_PATH);
+ Path ipaCaCertPath = Paths.get(KernelConstants.IPA_PEM_CA_CERT_PATH);
if (Files.exists(ipaCaCertPath)) {
KeyStore trustStore = PkiUtils.getKeyStore(trustStorePath, trustStorePassword,
getDeployProperty(CmsDeployProperty.SSL_TRUSTSTORETYPE));
- try (Reader cert = Files.newBufferedReader(ipaCaCertPath, StandardCharsets.US_ASCII);) {
- PkiUtils.loadPem(trustStore, null, trustStorePassword, cert);
+ try (BufferedInputStream cert = new BufferedInputStream(Files.newInputStream(ipaCaCertPath));) {
+ PkiUtils.loadTrustedCertificatePem(trustStore, trustStorePassword, cert);
Files.createDirectories(keyStorePath.getParent());
PkiUtils.saveKeyStore(trustStorePath, trustStorePassword, trustStore);
if (log.isDebugEnabled())
}
}
- 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);
-
+// if (!Files.exists(keyStorePath))
+// PkiUtils.createSelfSignedKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
}
public void stop() {
/*
* ACCESSORS
*/
- public String getHostname() {
- return hostname;
- }
-
@Override
public UUID getUuid() {
return uuid;
this.uuidFactory = uuidFactory;
}
+ public String getHostname() {
+ return hostname;
+ }
+
/**
* 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==null)
+ if (nodeInit == null)
continue;
if (nodeInit.startsWith("http")) {
} else {
// TODO use java.nio.file
- File initDir;
+ Path initDir;
if (nodeInit.startsWith("."))
initDir = KernelUtils.getExecutionDir(nodeInit);
else
- initDir = new File(nodeInit);
+ initDir = Paths.get(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);
- }
+ if (Files.exists(initDir)) {
+ Path dataPath = KernelUtils.getOsgiInstancePath("");
+ FsUtils.copyDirectory(initDir, dataPath);
+ log.info("CMS initialized from " + initDir);
+ }
}
}
}