Explorar o código

updates to properties based config importer

jrivard@gmail.com %!s(int64=6) %!d(string=hai) anos
pai
achega
00716874d9

+ 1 - 0
server/src/main/java/password/pwm/PwmConstants.java

@@ -74,6 +74,7 @@ public abstract class PwmConstants
     public static final String CHAI_API_VERSION = com.novell.ldapchai.ChaiConstant.CHAI_API_VERSION;
 
     public static final String DEFAULT_CONFIG_FILE_FILENAME = readPwmConstantsBundle( "defaultConfigFilename" );
+    public static final String DEFAULT_PROPERTIES_CONFIG_FILE_FILENAME = readPwmConstantsBundle( "defaultPropertiesConfigFilename" );
 
     public static final String PWM_APP_NAME = readPwmConstantsBundle( "pwm.appName" );
     public static final String PWM_VENDOR_NAME = readPwmConstantsBundle( "pwm.vendorName" );

+ 69 - 17
server/src/main/java/password/pwm/http/ContextManager.java

@@ -35,23 +35,26 @@ import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmException;
 import password.pwm.error.PwmUnrecoverableException;
+import password.pwm.util.PropertyConfigurationImporter;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.TimeDuration;
 import password.pwm.util.logging.PwmLogger;
-import password.pwm.util.secure.PwmRandom;
 
 import javax.servlet.ServletContext;
 import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpSession;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.time.Instant;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Locale;
 import java.util.Map;
-import java.util.TimerTask;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -73,17 +76,16 @@ public class ContextManager implements Serializable
 
     private final AtomicInteger restartCount = new AtomicInteger( 0 );
     private TimeDuration readApplicationLockMaxWait = TimeDuration.SECONDS_30;
-    private final String instanceGuid;
     private final Lock restartLock = new ReentrantLock();
 
     private String contextPath;
+    private File applicationPath;
 
     private static final String UNSPECIFIED_VALUE = "unspecified";
 
     public ContextManager( final ServletContext servletContext )
     {
         this.servletContext = servletContext;
-        this.instanceGuid = PwmRandom.getInstance().randomUUID().toString();
         this.contextPath = servletContext.getContextPath();
     }
 
@@ -192,6 +194,7 @@ public class ContextManager implements Serializable
 
     public void initialize( )
     {
+        final Instant startTime = Instant.now();
 
         try
         {
@@ -207,7 +210,6 @@ public class ContextManager implements Serializable
 
 
         final ParameterReader parameterReader = new ParameterReader( servletContext );
-        final File applicationPath;
         {
             final String applicationPathStr = parameterReader.readApplicationPath();
             if ( applicationPathStr == null || applicationPathStr.isEmpty() )
@@ -224,7 +226,7 @@ public class ContextManager implements Serializable
         File configurationFile = null;
         try
         {
-            configurationFile = locateConfigurationFile( applicationPath );
+            configurationFile = locateConfigurationFile( applicationPath, PwmConstants.DEFAULT_CONFIG_FILE_FILENAME );
 
             configReader = new ConfigurationReader( configurationFile );
             configReader.getStoredConfiguration().lock();
@@ -297,6 +299,13 @@ public class ContextManager implements Serializable
 
             checkConfigForSaveOnRestart( configReader, pwmApplication );
         }
+
+        if ( pwmApplication == null || pwmApplication.getApplicationMode() == PwmApplicationMode.NEW )
+        {
+            taskMaster.scheduleWithFixedDelay( new SilentPropertiesFileWatcher(), fileScanFrequencyMs, fileScanFrequencyMs, TimeUnit.MILLISECONDS );
+        }
+
+        LOGGER.trace( () -> "initialization complete (" + TimeDuration.compactFromCurrent( startTime ) + ")" );
     }
 
     private void checkConfigForSaveOnRestart(
@@ -396,7 +405,7 @@ public class ContextManager implements Serializable
         return configReader;
     }
 
-    private class ConfigFileWatcher extends TimerTask
+    private class ConfigFileWatcher implements Runnable
     {
         @Override
         public void run( )
@@ -412,6 +421,56 @@ public class ContextManager implements Serializable
         }
     }
 
+    private class SilentPropertiesFileWatcher implements Runnable
+    {
+        private final File silentPropertiesFile;
+
+        SilentPropertiesFileWatcher()
+        {
+            silentPropertiesFile = locateConfigurationFile( applicationPath, PwmConstants.DEFAULT_PROPERTIES_CONFIG_FILE_FILENAME );
+        }
+
+        @Override
+        public void run()
+        {
+            if ( pwmApplication == null || pwmApplication.getApplicationMode() == PwmApplicationMode.NEW )
+            {
+                if ( silentPropertiesFile.exists() )
+                {
+                    boolean success = false;
+                    LOGGER.info( () -> "file " + silentPropertiesFile.getAbsolutePath() + " has appeared, will import as configuration" );
+                    try
+                    {
+                        final PropertyConfigurationImporter importer = new PropertyConfigurationImporter();
+                        final StoredConfigurationImpl storedConfiguration = importer.readConfiguration( new FileInputStream( silentPropertiesFile ) );
+                        configReader.saveConfiguration( storedConfiguration, pwmApplication, null );
+                        LOGGER.info( () -> "file " + silentPropertiesFile.getAbsolutePath() + " has been successfully imported and saved as configuration file" );
+                        requestPwmApplicationRestart();
+                        success = true;
+                    }
+                    catch ( Exception e )
+                    {
+                        LOGGER.error( "error importing " + silentPropertiesFile.getAbsolutePath() + ", error: " + e.getMessage() );
+                    }
+
+                    final String appendValue = success ? ".imported" : ".error";
+                    final Path source = silentPropertiesFile.toPath();
+                    final Path dest = source.resolveSibling( "silent.properties" + appendValue );
+
+                    try
+                    {
+                        Files.move( source, dest );
+                        LOGGER.info( () -> "file " + source.toString() + " has been renamed to " + dest.toString() );
+                    }
+                    catch ( IOException e )
+                    {
+                        LOGGER.error( "error renaming file " + source.toString() + " to " + dest.toString() + ", error: " + e.getMessage() );
+                    }
+                }
+            }
+        }
+    }
+
     private class RestartFlagWatcher implements Runnable
     {
 
@@ -524,10 +583,9 @@ public class ContextManager implements Serializable
         return restartCount.get();
     }
 
-    public File locateConfigurationFile( final File applicationPath )
-            throws Exception
+    private File locateConfigurationFile( final File applicationPath, final String filename )
     {
-        return new File( applicationPath.getAbsolutePath() + File.separator + PwmConstants.DEFAULT_CONFIG_FILE_FILENAME );
+        return new File( applicationPath.getAbsolutePath() + File.separator + filename );
     }
 
     public File locateWebInfFilePath( )
@@ -546,18 +604,13 @@ public class ContextManager implements Serializable
         return null;
     }
 
-    static void outputError( final String outputText )
+    private static void outputError( final String outputText )
     {
         final String msg = PwmConstants.PWM_APP_NAME + " " + JavaHelper.toIsoDate( new Date() ) + " " + outputText;
         System.out.println( msg );
         System.out.println( msg );
     }
 
-    public String getInstanceGuid( )
-    {
-        return instanceGuid;
-    }
-
     public InputStream getResourceAsStream( final String path )
     {
         return servletContext.getResourceAsStream( path );
@@ -640,5 +693,4 @@ public class ContextManager implements Serializable
     {
         return contextPath;
     }
-
 }

+ 278 - 0
server/src/main/java/password/pwm/util/PropertyConfigurationImporter.java

@@ -0,0 +1,278 @@
+/*
+ * Password Management Servlets (PWM)
+ * http://www.pwm-project.org
+ *
+ * Copyright (c) 2006-2009 Novell, Inc.
+ * Copyright (c) 2009-2018 The PWM Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package password.pwm.util;
+
+import password.pwm.config.PwmSetting;
+import password.pwm.config.StoredValue;
+import password.pwm.config.stored.ConfigurationProperty;
+import password.pwm.config.stored.StoredConfigurationImpl;
+import password.pwm.config.value.BooleanValue;
+import password.pwm.config.value.PasswordValue;
+import password.pwm.config.value.StringArrayValue;
+import password.pwm.config.value.StringValue;
+import password.pwm.config.value.UserPermissionValue;
+import password.pwm.config.value.X509CertificateValue;
+import password.pwm.config.value.data.UserPermission;
+import password.pwm.error.PwmException;
+import password.pwm.util.java.JavaHelper;
+import password.pwm.util.java.StringUtil;
+import password.pwm.util.secure.X509Utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.X509Certificate;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+public class PropertyConfigurationImporter
+{
+    private static final String LDAP_PROFILE = "default";
+
+    private Map<String, String> inputMap;
+
+    public enum PropertyKey
+    {
+        TEMPLATE_LDAP,
+        DISPLAY_THEME,
+
+        ID_VAULT_HOST,
+        ID_VAULT_LDAPS_PORT,
+        ID_VAULT_ADMIN_LDAP,
+        ID_VAULT_PASSWORD,
+        USER_CONTAINER,
+        UA_ADMIN,
+
+        SSO_SERVER_HOST,
+        SSO_SERVER_SSL_PORT,
+        SSO_SERVICE_PWD,
+
+        CONFIGURATION_PWD,
+
+        LDAP_SERVERCERTS,
+        OAUTH_IDSERVER_SERVERCERTS,
+        AUDIT_SERVERCERTS,;
+    }
+
+    public PropertyConfigurationImporter()
+    {
+    }
+
+    private void readInputFile( final InputStream propertiesInput )
+            throws IOException
+    {
+        final Properties inputProperties = new Properties( );
+        inputProperties.load( propertiesInput );
+        final Map<String, String> inputMap = JavaHelper.propertiesToStringMap( inputProperties );
+        stripValueDelimiters( inputMap );
+        this.inputMap = inputMap;
+    }
+
+    public StoredConfigurationImpl readConfiguration( final InputStream propertiesInput )
+            throws PwmException, IOException
+    {
+        readInputFile( propertiesInput );
+
+        final StoredConfigurationImpl storedConfiguration = StoredConfigurationImpl.newStoredConfiguration( );
+        storedConfiguration.initNewRandomSecurityKey( );
+        storedConfiguration.writeConfigProperty( 
+                ConfigurationProperty.CONFIG_IS_EDITABLE, Boolean.toString( true ) );
+        storedConfiguration.writeConfigProperty( 
+                ConfigurationProperty.CONFIG_EPOCH, String.valueOf( 0 ) );
+
+        // static values
+        storedConfiguration.writeSetting( PwmSetting.TEMPLATE_LDAP, new StringValue( 
+                        inputMap.getOrDefault( PropertyKey.TEMPLATE_LDAP.name( ), "NOVL_IDM" ) ),
+                null );
+
+        if ( inputMap.containsKey( PropertyKey.DISPLAY_THEME.name( ) ) )
+        {
+            storedConfiguration.writeSetting( PwmSetting.PASSWORD_POLICY_SOURCE, new StringValue( 
+                            inputMap.get( PropertyKey.DISPLAY_THEME.name( ) ) ),
+                    null );
+        }
+
+        storedConfiguration.writeSetting( PwmSetting.DISPLAY_HOME_BUTTON, new BooleanValue( false ), null );
+        storedConfiguration.writeSetting( PwmSetting.LOGOUT_AFTER_PASSWORD_CHANGE, new BooleanValue( false ), null );
+        storedConfiguration.writeSetting( PwmSetting.PASSWORD_REQUIRE_CURRENT, new BooleanValue( false ), null );
+        storedConfiguration.writeSetting( PwmSetting.PASSWORD_POLICY_SOURCE, new StringValue( "LDAP" ), null );
+        storedConfiguration.writeSetting( PwmSetting.CERTIFICATE_VALIDATION_MODE, new StringValue( "CA_ONLY" ), null );
+        {
+            final String notes = "Configuration generated via properties import at " + JavaHelper.toIsoDate( Instant.now( ) );
+            storedConfiguration.writeSetting( PwmSetting.NOTES, new StringValue( notes ), null );
+        }
+
+        // ldap server
+        storedConfiguration.writeSetting( PwmSetting.LDAP_SERVER_URLS, LDAP_PROFILE, makeLdapServerUrlValue( ), null );
+        storedConfiguration.writeSetting( PwmSetting.LDAP_PROXY_USER_DN, LDAP_PROFILE,
+                new PasswordValue( PasswordData.forStringValue( inputMap.get( PropertyKey.ID_VAULT_ADMIN_LDAP.name( ) ) ) ), null );
+        storedConfiguration.writeSetting( PwmSetting.LDAP_PROXY_USER_PASSWORD, LDAP_PROFILE,
+                new PasswordValue( PasswordData.forStringValue( inputMap.get( PropertyKey.ID_VAULT_PASSWORD.name( ) ) ) ), null );
+        storedConfiguration.writeSetting( PwmSetting.LDAP_CONTEXTLESS_ROOT, LDAP_PROFILE,
+                new StringArrayValue( Collections.singletonList( inputMap.get( PropertyKey.USER_CONTAINER.name( ) ) ) ), null );
+
+        // oauth
+        storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_LOGIN_URL, new StringValue( makeOAuthBaseUrl( ) + "/grant" ), null );
+        storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_CODERESOLVE_URL, new StringValue( makeOAuthBaseUrl( ) + "/authcoderesolve" ), null );
+        storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_ATTRIBUTES_URL, new StringValue( makeOAuthBaseUrl( ) + "/getattributes" ), null );
+        storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_CLIENTNAME, new StringValue( "sspr" ), null );
+        storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_DN_ATTRIBUTE_NAME, new StringValue( "name" ), null );
+        storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_SECRET,
+                new PasswordValue( PasswordData.forStringValue( inputMap.get( PropertyKey.SSO_SERVICE_PWD.name( ) ) ) ), null );
+
+        //urls
+        storedConfiguration.writeSetting( PwmSetting.URL_FORWARD, makeForwardUrl( ), null );
+        storedConfiguration.writeSetting( PwmSetting.URL_LOGOUT, makeLogoutUrl( ), null );
+        storedConfiguration.writeSetting( PwmSetting.PWM_SITE_URL, makeSelfUrl( ), null );
+        storedConfiguration.writeSetting( PwmSetting.SECURITY_REDIRECT_WHITELIST, makeWhitelistUrl( ), null );
+
+        // admin settings
+        storedConfiguration.writeSetting( PwmSetting.QUERY_MATCH_PWM_ADMIN, makeAdminPermissions( ), null );
+        storedConfiguration.setPassword( inputMap.get( PropertyKey.CONFIGURATION_PWD.name( ) ) );
+
+        // certificates
+        {
+            final Optional<Collection<X509Certificate>> optionalCert = readCertificate( PropertyKey.LDAP_SERVERCERTS );
+            if ( optionalCert.isPresent( ) )
+            {
+                storedConfiguration.writeSetting( PwmSetting.LDAP_SERVER_CERTS, LDAP_PROFILE, new X509CertificateValue( optionalCert.get( ) ), null );
+            }
+        }
+        {
+            final Optional<Collection<X509Certificate>> optionalCert = readCertificate( PropertyKey.AUDIT_SERVERCERTS );
+            if ( optionalCert.isPresent( ) )
+            {
+                storedConfiguration.writeSetting( PwmSetting.AUDIT_SYSLOG_CERTIFICATES, new X509CertificateValue( optionalCert.get( ) ), null );
+            }
+        }
+        {
+            final Optional<Collection<X509Certificate>> optionalCert = readCertificate( PropertyKey.OAUTH_IDSERVER_SERVERCERTS );
+            if ( optionalCert.isPresent( ) )
+            {
+                storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_CERTIFICATE, new X509CertificateValue( optionalCert.get( ) ), null );
+            }
+        }
+
+
+        return storedConfiguration;
+    }
+
+    private String makeOAuthBaseUrl( )
+    {
+        return "https://" + inputMap.get( PropertyKey.SSO_SERVER_HOST.name( ) )
+                + ":" + inputMap.get( PropertyKey.SSO_SERVER_SSL_PORT.name( ) )
+                + "/osp/a/idm/auth/oauth2";
+    }
+
+    private StringArrayValue makeWhitelistUrl( )
+    {
+        return new StringArrayValue( Collections.singletonList( "https://" + inputMap.get( PropertyKey.SSO_SERVER_HOST.name( ) )
+                + ":" + inputMap.get( PropertyKey.SSO_SERVER_SSL_PORT.name( ) ) ) );
+    }
+
+    private StoredValue makeSelfUrl( )
+    {
+        return new StringValue( "https://" + inputMap.get( PropertyKey.SSO_SERVER_HOST.name( ) )
+                + ":" + inputMap.get( PropertyKey.SSO_SERVER_SSL_PORT.name( ) )
+                + "/sspr" );
+    }
+
+    private StoredValue makeForwardUrl( )
+    {
+        return new StringValue( "https://" + inputMap.get( PropertyKey.SSO_SERVER_HOST.name( ) )
+                + ":" + inputMap.get( PropertyKey.SSO_SERVER_SSL_PORT.name( ) )
+                + "/idmdash/#/landing" );
+    }
+
+    private StoredValue makeLogoutUrl( )
+    {
+        final String targetValue = "https://" + inputMap.get( PropertyKey.SSO_SERVER_HOST.name( ) )
+                + ":" + inputMap.get( PropertyKey.SSO_SERVER_SSL_PORT.name( ) )
+                + "/sspr";
+
+        return new StringValue( "https://" + inputMap.get( PropertyKey.SSO_SERVER_HOST.name( ) )
+                + ":" + inputMap.get( PropertyKey.SSO_SERVER_SSL_PORT.name( ) )
+                + "/osp/a/idm/auth/app/logout?target="
+                + StringUtil.urlEncode( targetValue ) );
+    }
+
+    private StoredValue makeLdapServerUrlValue( )
+    {
+        final String ldapUrl = "ldaps://" + inputMap.get( PropertyKey.ID_VAULT_HOST.name( ) )
+                + ":" + inputMap.get( PropertyKey.ID_VAULT_LDAPS_PORT.name( ) );
+        return new StringArrayValue( Collections.singletonList( ldapUrl ) );
+    }
+
+    private StoredValue makeAdminPermissions( )
+    {
+        final String filter = "( objectclass=* )";
+        final List<UserPermission> permissions = new ArrayList<>( );
+        permissions.add( new UserPermission( UserPermission.Type.ldapQuery, LDAP_PROFILE, filter,
+                inputMap.get( PropertyKey.ID_VAULT_ADMIN_LDAP.name( ) ) ) );
+        permissions.add( new UserPermission( UserPermission.Type.ldapQuery, LDAP_PROFILE, filter,
+                inputMap.get( PropertyKey.UA_ADMIN.name( ) ) ) );
+        return new UserPermissionValue( permissions );
+    }
+
+    private void stripValueDelimiters( final Map<String, String> map )
+    {
+        final Pattern pattern = Pattern.compile( "^'|'$" );
+        map.replaceAll( ( key, value ) -> pattern.matcher( value ).replaceAll( "" ) );
+    }
+
+    private Optional<Collection<X509Certificate>> readCertificate( 
+            final PropertyKey propertyKey
+    )
+            throws IOException
+    {
+        final String base64Cert = inputMap.get( propertyKey.name( ) );
+        if ( !StringUtil.isEmpty( base64Cert ) )
+        {
+            final List<X509Certificate> returnCerts = new ArrayList<>( );
+            for ( final String splitB64Cert : StringUtil.splitAndTrim( base64Cert, "," ) )
+            {
+                try
+                {
+                    final X509Certificate cert = X509Utils.certificateFromBase64( splitB64Cert );
+                    if ( cert != null )
+                    {
+                        returnCerts.add( cert );
+                    }
+
+                }
+                catch ( Exception e )
+                {
+                    throw new IOException( "error importing key " + propertyKey.name() + ", error: " + e.getMessage() );
+                }
+            }
+            return Optional.of( returnCerts );
+        }
+        return Optional.empty( );
+    }
+}

+ 2 - 2
server/src/main/java/password/pwm/util/cli/MainClass.java

@@ -55,7 +55,7 @@ import password.pwm.util.cli.commands.ExportStatsCommand;
 import password.pwm.util.cli.commands.HelpCommand;
 import password.pwm.util.cli.commands.ImportHttpsKeyStoreCommand;
 import password.pwm.util.cli.commands.ImportLocalDBCommand;
-import password.pwm.util.cli.commands.ImportIDMConfigCommand;
+import password.pwm.util.cli.commands.ImportPropertyConfigCommand;
 import password.pwm.util.cli.commands.ImportResponsesCommand;
 import password.pwm.util.cli.commands.LdapSchemaExtendCommand;
 import password.pwm.util.cli.commands.LocalDBInfoCommand;
@@ -128,7 +128,7 @@ public class MainClass
         commandList.add( new ShellCommand() );
         commandList.add( new ConfigResetHttpsCommand() );
         commandList.add( new HelpCommand() );
-        commandList.add( new ImportIDMConfigCommand() );
+        commandList.add( new ImportPropertyConfigCommand() );
         commandList.add( new ResetInstanceIDCommand() );
 
         final Map<String, CliCommand> sortedMap = new TreeMap<>();

+ 0 - 248
server/src/main/java/password/pwm/util/cli/commands/ImportIDMConfigCommand.java

@@ -1,248 +0,0 @@
-/*
- * Password Management Servlets (PWM)
- * http://www.pwm-project.org
- *
- * Copyright (c) 2006-2009 Novell, Inc.
- * Copyright (c) 2009-2018 The PWM Project
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-package password.pwm.util.cli.commands;
-
-import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
-import password.pwm.config.stored.ConfigurationProperty;
-import password.pwm.config.stored.StoredConfigurationImpl;
-import password.pwm.config.value.BooleanValue;
-import password.pwm.config.value.PasswordValue;
-import password.pwm.config.value.StringArrayValue;
-import password.pwm.config.value.StringValue;
-import password.pwm.config.value.UserPermissionValue;
-import password.pwm.config.value.data.UserPermission;
-import password.pwm.error.PwmOperationalException;
-import password.pwm.error.PwmUnrecoverableException;
-import password.pwm.util.PasswordData;
-import password.pwm.util.cli.CliParameters;
-import password.pwm.util.java.JavaHelper;
-import password.pwm.util.java.StringUtil;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.regex.Pattern;
-
-/**
- * Import IDM silent properties installer file and create new configuration.
- */
-public class ImportIDMConfigCommand extends AbstractCliCommand
-{
-    @Override
-    void doCommand( )
-            throws Exception
-    {
-        final File configFile = cliEnvironment.getConfigurationFile();
-
-        if ( configFile.exists() )
-        {
-            out( "this command can not be run with an existing configuration in place.  Exiting..." );
-            return;
-        }
-
-        final File inputFile = ( File ) cliEnvironment.getOptions().get( CliParameters.REQUIRED_EXISTING_INPUT_FILE.getName() );
-
-        try
-        {
-            final IDMImporter importer = new IDMImporter( new FileInputStream( inputFile ) );
-            final StoredConfigurationImpl storedConfiguration = importer.readConfiguration();
-
-            try ( OutputStream outputStream = new FileOutputStream( configFile ) )
-            {
-                storedConfiguration.toXml( outputStream );
-                out( "output configuration file " + configFile.getAbsolutePath() );
-            }
-
-        }
-        catch ( Exception e )
-        {
-            out( "error during import: " + e.getMessage() );
-        }
-    }
-
-    @Override
-    public CliParameters getCliParameters( )
-    {
-        final CliParameters cliParameters = new CliParameters();
-        cliParameters.commandName = "ImportIDMConfig";
-        cliParameters.description = "Import an IDM installer script and create a new configuration";
-        cliParameters.options = Collections.singletonList( CliParameters.REQUIRED_EXISTING_INPUT_FILE );
-
-        cliParameters.needsPwmApplication = true;
-        cliParameters.needsLocalDB = false;
-        cliParameters.readOnly = false;
-
-        return cliParameters;
-    }
-
-    private enum IdmProperty
-    {
-        ID_VAULT_HOST,
-        ID_VAULT_LDAPS_PORT,
-        ID_VAULT_ADMIN_LDAP,
-        ID_VAULT_PASSWORD,
-        USER_CONTAINER,
-        UA_ADMIN,
-
-        SSO_SERVER_HOST,
-        SSO_SERVER_SSL_PORT,
-        SSO_SERVICE_PWD,
-
-        CONFIGURATION_PWD,
-    }
-
-    private static class IDMImporter
-    {
-        private static final String LDAP_PROFILE = "default";
-        private final Map<String, String> inputMap;
-
-        IDMImporter( final InputStream inputStream ) throws IOException
-        {
-            final Properties inputProperties = new Properties();
-            inputProperties.load( inputStream );
-            final Map<String, String> inputMap = JavaHelper.propertiesToStringMap( inputProperties );
-            stripValueDelimiters( inputMap );
-            this.inputMap = inputMap;
-        }
-
-        StoredConfigurationImpl readConfiguration() throws PwmUnrecoverableException, PwmOperationalException
-        {
-            final StoredConfigurationImpl storedConfiguration = StoredConfigurationImpl.newStoredConfiguration();
-            storedConfiguration.initNewRandomSecurityKey();
-            storedConfiguration.writeConfigProperty(
-                    ConfigurationProperty.CONFIG_IS_EDITABLE, Boolean.toString( true ) );
-            storedConfiguration.writeConfigProperty(
-                    ConfigurationProperty.CONFIG_EPOCH, String.valueOf( 0 ) );
-
-            // static values
-            storedConfiguration.writeSetting( PwmSetting.TEMPLATE_LDAP, new StringValue( "NOVL_IDM" ), null );
-            storedConfiguration.writeSetting( PwmSetting.INTERFACE_THEME, new StringValue( "mdefault" ), null );
-            storedConfiguration.writeSetting( PwmSetting.DISPLAY_HOME_BUTTON, new BooleanValue( false ), null );
-            storedConfiguration.writeSetting( PwmSetting.LOGOUT_AFTER_PASSWORD_CHANGE, new BooleanValue( false ), null );
-            storedConfiguration.writeSetting( PwmSetting.PASSWORD_REQUIRE_CURRENT, new BooleanValue( false ), null );
-            storedConfiguration.writeSetting( PwmSetting.PASSWORD_POLICY_SOURCE, new StringValue( "LDAP" ), null );
-
-            // ldap server
-            storedConfiguration.writeSetting( PwmSetting.LDAP_SERVER_URLS, LDAP_PROFILE, makeLdapServerUrlValue(), null );
-            storedConfiguration.writeSetting( PwmSetting.LDAP_PROXY_USER_DN, LDAP_PROFILE,
-                    new PasswordValue( PasswordData.forStringValue( inputMap.get( IdmProperty.ID_VAULT_ADMIN_LDAP.name() ) ) ), null );
-            storedConfiguration.writeSetting( PwmSetting.LDAP_PROXY_USER_PASSWORD, LDAP_PROFILE,
-                    new PasswordValue( PasswordData.forStringValue( inputMap.get( IdmProperty.ID_VAULT_PASSWORD.name() ) ) ), null );
-            storedConfiguration.writeSetting( PwmSetting.LDAP_CONTEXTLESS_ROOT, LDAP_PROFILE,
-                    new StringArrayValue( Collections.singletonList( inputMap.get( IdmProperty.USER_CONTAINER.name() ) ) ), null );
-
-            // oauth
-            storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_LOGIN_URL, new StringValue( makeOAuthBaseUrl() + "/grant" ), null );
-            storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_CODERESOLVE_URL, new StringValue( makeOAuthBaseUrl() + "/authcoderesolve" ), null );
-            storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_ATTRIBUTES_URL, new StringValue( makeOAuthBaseUrl() + "/getattributes" ), null );
-            storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_CLIENTNAME, new StringValue( "sspr" ), null );
-            storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_DN_ATTRIBUTE_NAME, new StringValue( "name" ), null );
-            storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_SECRET,
-                    new PasswordValue( PasswordData.forStringValue( inputMap.get( IdmProperty.SSO_SERVICE_PWD.name() ) ) ), null );
-
-            //urls
-            storedConfiguration.writeSetting( PwmSetting.URL_FORWARD, makeForwardUrl(), null );
-            storedConfiguration.writeSetting( PwmSetting.URL_LOGOUT, makeLogoutUrl(), null );
-            storedConfiguration.writeSetting( PwmSetting.PWM_SITE_URL, makeSelfUrl(), null );
-            storedConfiguration.writeSetting( PwmSetting.SECURITY_REDIRECT_WHITELIST, makeWhitelistUrl(), null );
-
-            // admin settings
-            storedConfiguration.writeSetting( PwmSetting.QUERY_MATCH_PWM_ADMIN, makeAdminPermissions(), null );
-            storedConfiguration.setPassword( inputMap.get( IdmProperty.CONFIGURATION_PWD.name() ) );
-
-            return storedConfiguration;
-        }
-
-        String makeOAuthBaseUrl()
-        {
-            return "https://" + inputMap.get( IdmProperty.SSO_SERVER_HOST.name() )
-                    + ":" + inputMap.get( IdmProperty.SSO_SERVER_SSL_PORT.name() )
-                    + "/osp/a/idm/auth/oauth2";
-        }
-
-        StringArrayValue makeWhitelistUrl()
-        {
-            return new StringArrayValue( Collections.singletonList( "https://" + inputMap.get( IdmProperty.SSO_SERVER_HOST.name() )
-                    + ":" + inputMap.get( IdmProperty.SSO_SERVER_SSL_PORT.name() ) ) );
-        }
-
-        StoredValue makeSelfUrl()
-        {
-            return new StringValue( "https://" + inputMap.get( IdmProperty.SSO_SERVER_HOST.name() )
-                    + ":" + inputMap.get( IdmProperty.SSO_SERVER_SSL_PORT.name() )
-                    + "/sspr" );
-        }
-
-        StoredValue makeForwardUrl()
-        {
-            return new StringValue( "https://" + inputMap.get( IdmProperty.SSO_SERVER_HOST.name() )
-                    + ":" + inputMap.get( IdmProperty.SSO_SERVER_SSL_PORT.name() )
-                    + "/idmdash/#/landing" );
-        }
-
-        StoredValue makeLogoutUrl()
-        {
-            final String targetValue = "https://" + inputMap.get( IdmProperty.SSO_SERVER_HOST.name() )
-                    + ":" + inputMap.get( IdmProperty.SSO_SERVER_SSL_PORT.name() )
-                    + "/sspr";
-
-            return new StringValue( "https://" + inputMap.get( IdmProperty.SSO_SERVER_HOST.name() )
-                    + ":" + inputMap.get( IdmProperty.SSO_SERVER_SSL_PORT.name() )
-                    + "/osp/a/idm/auth/app/logout?target="
-                    + StringUtil.urlEncode( targetValue ) );
-        }
-
-        StoredValue makeLdapServerUrlValue( )
-        {
-            final String ldapUrl = "ldaps://" + inputMap.get( IdmProperty.ID_VAULT_HOST.name() )
-                    + ":" + inputMap.get( IdmProperty.ID_VAULT_LDAPS_PORT.name() );
-            return new StringArrayValue( Collections.singletonList( ldapUrl ) );
-        }
-
-        StoredValue makeAdminPermissions( )
-        {
-            final String filter = "(objectclass=*)";
-            final List<UserPermission> permissions = new ArrayList<>();
-            permissions.add( new UserPermission( UserPermission.Type.ldapQuery, LDAP_PROFILE, filter,
-                    inputMap.get( IdmProperty.ID_VAULT_ADMIN_LDAP.name() ) ) );
-            permissions.add( new UserPermission( UserPermission.Type.ldapQuery, LDAP_PROFILE, filter,
-                    inputMap.get( IdmProperty.UA_ADMIN.name() ) ) );
-            return new UserPermissionValue( permissions );
-        }
-
-        static void stripValueDelimiters( final Map<String, String> map )
-        {
-            final Pattern pattern = Pattern.compile( "^'|'$" );
-            map.replaceAll( ( key, value ) -> pattern.matcher( value ).replaceAll( "" ) );
-        }
-    }
-}

+ 87 - 0
server/src/main/java/password/pwm/util/cli/commands/ImportPropertyConfigCommand.java

@@ -0,0 +1,87 @@
+/*
+ * Password Management Servlets (PWM)
+ * http://www.pwm-project.org
+ *
+ * Copyright (c) 2006-2009 Novell, Inc.
+ * Copyright (c) 2009-2018 The PWM Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package password.pwm.util.cli.commands;
+
+import password.pwm.config.stored.StoredConfigurationImpl;
+import password.pwm.util.PropertyConfigurationImporter;
+import password.pwm.util.cli.CliParameters;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import java.util.Collections;
+
+/**
+ * Import properties configuration file and create new configuration.
+ */
+public class ImportPropertyConfigCommand extends AbstractCliCommand
+{
+    @Override
+    void doCommand( )
+            throws Exception
+    {
+        final File configFile = cliEnvironment.getConfigurationFile();
+
+        if ( configFile.exists() )
+        {
+            out( "this command can not be run with an existing configuration in place.  Exiting..." );
+            return;
+        }
+
+        final File inputFile = ( File ) cliEnvironment.getOptions().get( CliParameters.REQUIRED_EXISTING_INPUT_FILE.getName() );
+
+        try
+        {
+            final PropertyConfigurationImporter importer = new PropertyConfigurationImporter();
+            final StoredConfigurationImpl storedConfiguration = importer.readConfiguration( new FileInputStream( inputFile ) );
+
+            try ( OutputStream outputStream = new FileOutputStream( configFile ) )
+            {
+                storedConfiguration.toXml( outputStream );
+                out( "output configuration file " + configFile.getAbsolutePath() );
+            }
+        }
+        catch ( Exception e )
+        {
+            out( "error during import: " + e.getMessage() );
+        }
+    }
+
+    @Override
+    public CliParameters getCliParameters( )
+    {
+        final CliParameters cliParameters = new CliParameters();
+        cliParameters.commandName = "ImportPropertyConfig";
+        cliParameters.description = "Import an property based configuration and create a new configuration";
+        cliParameters.options = Collections.singletonList( CliParameters.REQUIRED_EXISTING_INPUT_FILE );
+
+        cliParameters.needsPwmApplication = false;
+        cliParameters.needsLocalDB = false;
+        cliParameters.readOnly = false;
+
+        return cliParameters;
+    }
+
+}

+ 1 - 0
server/src/main/resources/password/pwm/PwmConstants.properties

@@ -37,6 +37,7 @@ trial=false
 url.pwm-home=https://github.com/pwm-project/pwm
 paramName.token=token
 defaultConfigFilename=PwmConfiguration.xml
+defaultPropertiesConfigFilename=silent.properties
 enableEulaDisplay=false
 missingVersionString=[Version Missing]
 applicationPathInfoFile=applicationPath.properties