You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pa...@apache.org on 2013/04/11 18:23:24 UTC

svn commit: r1466945 [1/2] - in /directory/studio/trunk/plugins: connection.core/src/main/java/org/apache/directory/studio/connection/core/ connection.ui/ connection.ui/src/main/java/org/apache/directory/studio/connection/ui/ connection.ui/src/main/jav...

Author: pamarcelot
Date: Thu Apr 11 16:23:23 2013
New Revision: 1466945

URL: http://svn.apache.org/r1466945
Log:
Fix for DIRSTUDIO-901 (Add the ability to store connection passwords in a password-protected keystore)

Added:
    directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/PasswordsKeyStoreManager.java
    directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/PasswordsKeyStoreManagerUtils.java
    directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/ResetPasswordDialog.java
    directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/SetupPasswordDialog.java
    directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/preferences/PasswordsKeystorePreferencePage.java
Modified:
    directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCoreConstants.java
    directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCorePlugin.java
    directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCorePreferencesInitializer.java
    directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionManager.java
    directory/studio/trunk/plugins/connection.ui/plugin.properties
    directory/studio/trunk/plugins/connection.ui/plugin.xml
    directory/studio/trunk/plugins/connection.ui/plugin_fr.properties
    directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/UIAuthHandler.java
    directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/PasswordDialog.java
    directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/properties/ConnectionPropertyPage.java
    directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/widgets/AuthenticationParameterPage.java
    directory/studio/trunk/plugins/ldapservers.apacheds.v153/pom.xml
    directory/studio/trunk/plugins/ldapservers.apacheds.v153/src/main/java/org/apache/directory/studio/ldapservers/apacheds/v153/CreateConnectionAction.java
    directory/studio/trunk/plugins/ldapservers.apacheds.v154/pom.xml
    directory/studio/trunk/plugins/ldapservers.apacheds.v154/src/main/java/org/apache/directory/studio/ldapservers/apacheds/v154/CreateConnectionAction.java
    directory/studio/trunk/plugins/ldapservers.apacheds.v155/pom.xml
    directory/studio/trunk/plugins/ldapservers.apacheds.v155/src/main/java/org/apache/directory/studio/ldapservers/apacheds/v155/CreateConnectionAction.java
    directory/studio/trunk/plugins/ldapservers.apacheds.v156/pom.xml
    directory/studio/trunk/plugins/ldapservers.apacheds.v156/src/main/java/org/apache/directory/studio/ldapservers/apacheds/v156/CreateConnectionAction.java
    directory/studio/trunk/plugins/ldapservers.apacheds.v157/pom.xml
    directory/studio/trunk/plugins/ldapservers.apacheds.v157/src/main/java/org/apache/directory/studio/ldapservers/apacheds/v157/CreateConnectionAction.java
    directory/studio/trunk/plugins/ldapservers.apacheds.v200/pom.xml
    directory/studio/trunk/plugins/ldapservers.apacheds.v200/src/main/java/org/apache/directory/studio/ldapservers/apacheds/v200/CreateConnectionAction.java

Modified: directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCoreConstants.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCoreConstants.java?rev=1466945&r1=1466944&r2=1466945&view=diff
==============================================================================
--- directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCoreConstants.java (original)
+++ directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCoreConstants.java Thu Apr 11 16:23:23 2013
@@ -92,10 +92,18 @@ public final class ConnectionCoreConstan
     /** The constant used to identify the default network provider setting */
     public static final String PREFERENCE_DEFAULT_NETWORK_PROVIDER = "defaultNetworkProvider"; //$NON-NLS-1$
 
-    /** The constant used to identify the default network provider setting */
+    /** The constant used to identify the 'JNDI' value for the default network provider setting */
     public static final int PREFERENCE_NETWORK_PROVIDER_JNDI = 0;
 
-    /** The constant used to identify the default network provider setting */
+    /** The constant used to identify the 'Apache Directory LDAP API' value for the default provider setting */
     public static final int PREFERENCE_NETWORK_PROVIDER_APACHE_DIRECTORY_LDAP_API = 1;
 
+    /** The constant used to identify if connections passwords should be stored in a keystore */
+    public static final String PREFERENCE_CONNECTIONS_PASSWORDS_KEYSTORE = "connectionsPasswordsKeystore"; //$NON-NLS-1$
+
+    /** The constant used to identify the 'off' value for the connections passwords keystore setting */
+    public static final int PREFERENCE_CONNECTIONS_PASSWORDS_KEYSTORE_OFF = 0;
+
+    /** The constant used to identify the 'on' value for the connections passwords keystore setting */
+    public static final int PREFERENCE_CONNECTIONS_PASSWORDS_KEYSTORE_ON = 1;
 }

Modified: directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCorePlugin.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCorePlugin.java?rev=1466945&r1=1466944&r2=1466945&view=diff
==============================================================================
--- directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCorePlugin.java (original)
+++ directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCorePlugin.java Thu Apr 11 16:23:23 2013
@@ -64,6 +64,9 @@ public class ConnectionCorePlugin extend
     /** The connection folder manager */
     private ConnectionFolderManager connectionFolderManager;
 
+    /** The passwords keystore manager */
+    private PasswordsKeyStoreManager passwordsKeyStoreManager;
+
     /** The permanent trust store */
     private StudioKeyStoreManager permanentTrustStoreManager;
 
@@ -123,6 +126,11 @@ public class ConnectionCorePlugin extend
             connectionFolderManager = new ConnectionFolderManager();
         }
 
+        if ( passwordsKeyStoreManager == null )
+        {
+            passwordsKeyStoreManager = new PasswordsKeyStoreManager();
+        }
+
         if ( permanentTrustStoreManager == null )
         {
             permanentTrustStoreManager = StudioKeyStoreManager.createFileKeyStoreManager( PERMANENT_TRUST_STORE,
@@ -222,6 +230,17 @@ public class ConnectionCorePlugin extend
 
 
     /**
+     * Gets the password keystore manager.
+     *
+     * @return the password keystore manager
+     */
+    public PasswordsKeyStoreManager getPasswordsKeyStoreManager()
+    {
+        return passwordsKeyStoreManager;
+    }
+
+
+    /**
      * Gets the permanent trust store manager.
      *
      * @return the permanent trust store manager

Modified: directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCorePreferencesInitializer.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCorePreferencesInitializer.java?rev=1466945&r1=1466944&r2=1466945&view=diff
==============================================================================
--- directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCorePreferencesInitializer.java (original)
+++ directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionCorePreferencesInitializer.java Thu Apr 11 16:23:23 2013
@@ -59,6 +59,9 @@ public class ConnectionCorePreferencesIn
         preferences.setDefault( ConnectionCoreConstants.PREFERENCE_SEARCHRESULTENTRYLOGS_ENABLE, false );
         preferences.setDefault( ConnectionCoreConstants.PREFERENCE_SEARCHLOGS_FILE_COUNT, 10 );
         preferences.setDefault( ConnectionCoreConstants.PREFERENCE_SEARCHLOGS_FILE_SIZE, 100 );
-    }
 
+        // Connections Passwords Keystore
+        preferences.setDefault( ConnectionCoreConstants.PREFERENCE_CONNECTIONS_PASSWORDS_KEYSTORE,
+            ConnectionCoreConstants.PREFERENCE_CONNECTIONS_PASSWORDS_KEYSTORE_OFF );
+    }
 }

Modified: directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionManager.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionManager.java?rev=1466945&r1=1466944&r2=1466945&view=diff
==============================================================================
--- directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionManager.java (original)
+++ directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ConnectionManager.java Thu Apr 11 16:23:23 2013
@@ -359,7 +359,7 @@ public class ConnectionManager implement
     /**
      * Saves the Connections
      */
-    private synchronized void saveConnections()
+    public synchronized void saveConnections()
     {
         Set<ConnectionParameter> connectionParameters = new HashSet<ConnectionParameter>();
         for ( Connection connection : connectionList )

Added: directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/PasswordsKeyStoreManager.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/PasswordsKeyStoreManager.java?rev=1466945&view=auto
==============================================================================
--- directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/PasswordsKeyStoreManager.java (added)
+++ directory/studio/trunk/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/PasswordsKeyStoreManager.java Thu Apr 11 16:23:23 2013
@@ -0,0 +1,504 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.studio.connection.core;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStore.SecretKeyEntry;
+import java.security.KeyStoreException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+import org.apache.commons.io.FileUtils;
+
+
+/**
+ * A wrapper around {@link KeyStore} for storing passwords.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class PasswordsKeyStoreManager
+{
+    /** The default filename */
+    private static final String KEYSTORE_DEFAULT_FILENAME = "passwords.jks";
+
+    /** The keystore file name */
+    private String filename = KEYSTORE_DEFAULT_FILENAME;
+
+    /** The master password */
+    private String masterPassword;
+
+    /** The keystore */
+    private KeyStore keystore;
+
+
+    /**
+     * Creates a new instance of PasswordsKeyStoreManager.
+     */
+    public PasswordsKeyStoreManager()
+    {
+    }
+
+
+    /**
+     * Creates a new instance of PasswordsKeyStoreManager.
+     *
+     * @param filename the filename
+     */
+    public PasswordsKeyStoreManager( String filename )
+    {
+        this.filename = filename;
+    }
+
+
+    /**
+     * Indicates if the keystore is loaded.
+     *
+     * @return <code>true</code> if the keystore is loaded,
+     *         <code>false</code> if not.
+     */
+    public boolean isLoaded()
+    {
+        return keystore != null;
+    }
+
+
+    public void load( String masterPassword ) throws KeyStoreException
+    {
+        this.masterPassword = masterPassword;
+
+        try
+        {
+            keystore = KeyStore.getInstance( "JCEKS" ); //$NON-NLS-1$
+
+            // Getting the keystore file
+            File keystoreFile = getKeyStoreFile();
+
+            // Checking if the keystore file is available on disk
+            if ( keystoreFile.exists() && keystoreFile.isFile() && keystoreFile.canRead() )
+            {
+                keystore.load( new FileInputStream( keystoreFile ), masterPassword.toCharArray() );
+            }
+            else
+            {
+                keystore.load( null, null );
+            }
+        }
+        // Catch for the following exceptions that may be raised while
+        // handling the keystore:
+        // - java.security.KeyStoreException
+        // - java.security.NoSuchAlgorithmException
+        // - java.security.cert.CertificateException
+        catch ( GeneralSecurityException e )
+        {
+            this.masterPassword = null;
+            this.keystore = null;
+
+            throw new KeyStoreException( e );
+        }
+        // Catch for the following exceptions that may be raised while
+        // handling the file:
+        // - java.io.IOException
+        // - java.io.FileNotFoundException
+        catch ( IOException e )
+        {
+            this.masterPassword = null;
+            this.keystore = null;
+
+            throw new KeyStoreException( e );
+        }
+    }
+
+
+    /**
+     * Saves the keystore on disk.
+     */
+    public void save() throws KeyStoreException
+    {
+        if ( isLoaded() && ( masterPassword != null ) )
+        {
+            try
+            {
+                keystore.store( new FileOutputStream( getKeyStoreFile() ), masterPassword.toCharArray() );
+            }
+            // Catch for the following exceptions that may be raised while
+            // handling the keystore:
+            // - java.security.KeyStoreException
+            // - java.security.NoSuchAlgorithmException
+            // - java.security.cert.CertificateException
+            catch ( GeneralSecurityException e )
+            {
+                throw new KeyStoreException( e );
+            }
+            // Catch for the following exceptions that may be raised while
+            // handling the file:
+            // - java.io.IOException
+            // - java.io.FileNotFoundException
+            catch ( IOException e )
+            {
+                throw new KeyStoreException( e );
+            }
+        }
+    }
+
+
+    /**
+     * Checks the master password.
+     *
+     * @param masterPassword the master password
+     * @return <code>true</code> if the master password is correct,
+     *         <code>false</code> if not.
+     * @throws KeyStoreException if an error occurs
+     */
+    public boolean checkMasterPassword( String masterPassword ) throws KeyStoreException
+    {
+        // If the keystore is already loaded, we compare the master password directly
+        if ( isLoaded() )
+        {
+            return ( ( this.masterPassword != null ) && ( this.masterPassword.equals( masterPassword ) ) );
+        }
+        // The keystore is not loaded yet 
+        else
+        {
+            try
+            {
+                // Loading the keystore
+                load( masterPassword );
+
+                // Returning the check value
+                return isLoaded();
+            }
+            catch ( KeyStoreException e )
+            {
+                throw e;
+            }
+        }
+    }
+
+
+    /**
+     * Sets the master password.
+     *
+     * @param masterPassword the master password
+     */
+    public void setMasterPassword( String masterPassword )
+    {
+        // Creating a map to store previously stored passwords
+        Map<String, String> passwordsMap = new HashMap<String, String>();
+
+        if ( isLoaded() )
+        {
+            // Getting the connection IDs
+            String[] connectionIds = getConnectionIds();
+
+            // Storing the password of each connection in the map
+            for ( String connectionId : connectionIds )
+            {
+                // Getting the connection password
+                String connectionPassword = getConnectionPassword( connectionId );
+
+                // Checking if we got a password
+                if ( connectionPassword != null )
+                {
+                    // Storing the password of the connection in the map
+                    passwordsMap.put( connectionId, connectionPassword );
+                }
+
+                // Removing the password from the keystore
+                storeConnectionPassword( connectionId, null, false );
+            }
+        }
+
+        // Assigning the new master password
+        this.masterPassword = masterPassword;
+
+        // Storing the previous passwords back in the keystore
+        if ( passwordsMap.size() > 0 )
+        {
+            Set<String> connectionIds = passwordsMap.keySet();
+
+            // Storing the password of each connection in the keystore
+            if ( connectionIds != null )
+            {
+                for ( String connectionId : connectionIds )
+                {
+                    String connectionPassword = passwordsMap.get( connectionId );
+
+                    if ( connectionPassword != null )
+                    {
+                        // Storing the password of the connection in the keystore
+                        storeConnectionPassword( connectionId, connectionPassword, false );
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Gets the keystore file.
+     *
+     * @return the keystore file
+     */
+    public File getKeyStoreFile()
+    {
+        return ConnectionCorePlugin.getDefault().getStateLocation().append( filename ).toFile();
+    }
+
+
+    /**
+     * Deletes the keystore.
+     */
+    public void deleteKeystoreFile()
+    {
+        // Getting the keystore file
+        File keystoreFile = getKeyStoreFile();
+
+        // Checking if the keystore file is available on disk
+        if ( keystoreFile.exists() && keystoreFile.isFile() && keystoreFile.canRead() && keystoreFile.canWrite() )
+        {
+            keystoreFile.delete();
+        }
+    }
+
+
+    /**
+     * Gets the connections IDs contained in the keystore.
+     *
+     * @return the connection IDs contained in the keystore
+     */
+    public String[] getConnectionIds()
+    {
+        if ( keystore != null )
+        {
+            try
+            {
+                return Collections.list( keystore.aliases() ).toArray( new String[0] );
+            }
+            catch ( KeyStoreException e )
+            {
+                // Silent
+            }
+        }
+
+        return new String[0];
+    }
+
+
+    /**
+     * Stores a connection password.
+     *
+     * @param connection the connection
+     * @param password the password
+     */
+    public void storeConnectionPassword( Connection connection, String password )
+    {
+        if ( connection != null )
+        {
+            storeConnectionPassword( connection.getId(), password );
+        }
+    }
+
+
+    /**
+     * Stores a connection password.
+     *
+     * @param connection the connection
+     * @param password the password
+     * @param saveKeystore if the keystore needs to be saved
+     */
+    public void storeConnectionPassword( Connection connection, String password, boolean saveKeystore )
+    {
+        if ( connection != null )
+        {
+            storeConnectionPassword( connection.getId(), password, true );
+        }
+    }
+
+
+    /**
+     * Stores a connection password.
+     *
+     * @param connectionId the connection id
+     * @param password the password
+     */
+    public void storeConnectionPassword( String connectionId, String password )
+    {
+        storeConnectionPassword( connectionId, password, true );
+    }
+
+
+    /**
+     * Stores a connection password.
+     *
+     * @param connectionId the connection id
+     * @param password the password
+     * @param saveKeystore if the keystore needs to be saved
+     */
+    public void storeConnectionPassword( String connectionId, String password, boolean saveKeystore )
+    {
+        if ( isLoaded() && ( connectionId != null ) )
+        {
+            try
+            {
+                // Checking if the password is null
+                if ( password == null )
+                {
+                    // We need to remove the corresponding entry in the keystore
+                    if ( keystore.containsAlias( connectionId ) )
+                    {
+                        keystore.deleteEntry( connectionId );
+                    }
+                }
+                else
+                {
+                    // Generating a secret key from the password
+                    SecretKeyFactory factory = SecretKeyFactory.getInstance( "PBE" );
+                    SecretKey generatedSecret = factory.generateSecret( new PBEKeySpec( password.toCharArray() ) );
+
+                    // Setting the entry in the keystore
+                    keystore.setEntry( connectionId, new KeyStore.SecretKeyEntry( generatedSecret ),
+                        new KeyStore.PasswordProtection( masterPassword.toCharArray() ) );
+                }
+
+                // Saving
+                if ( saveKeystore )
+                {
+                    save();
+                }
+            }
+            catch ( Exception e )
+            {
+                // Silent
+            }
+        }
+    }
+
+
+    /**
+     * Gets a connection password.
+     *
+     * @param connection the connection
+     * @return the password for the connection or <code>null</code>.
+     */
+    public String getConnectionPassword( Connection connection )
+    {
+        if ( connection != null )
+        {
+            return getConnectionPassword( connection.getId() );
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Gets a connection password.
+     *
+     * @param connectionId the connection id
+     * @return the password for the connection id or <code>null</code>.
+     */
+    public String getConnectionPassword( String connectionId )
+    {
+        if ( isLoaded() && ( connectionId != null ) )
+        {
+            try
+            {
+                SecretKeyFactory factory = SecretKeyFactory.getInstance( "PBE" );
+                SecretKeyEntry ske = ( SecretKeyEntry ) keystore.getEntry( connectionId,
+                    new KeyStore.PasswordProtection( masterPassword.toCharArray() ) );
+
+                if ( ske != null )
+                {
+                    PBEKeySpec keySpec = ( PBEKeySpec ) factory.getKeySpec( ske.getSecretKey(), PBEKeySpec.class );
+
+                    if ( keySpec != null )
+                    {
+                        char[] password = keySpec.getPassword();
+
+                        if ( password != null )
+                        {
+                            return new String( password );
+                        }
+                    }
+                }
+            }
+            catch ( Exception e )
+            {
+                return null;
+            }
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Resets the keystore manager.
+     */
+    public void reset()
+    {
+        // Reseting the fields
+        this.keystore = null;
+        this.masterPassword = null;
+
+        // Getting the keystore file
+        File keystoreFile = getKeyStoreFile();
+
+        // If the keystore file exists, we need to remove it
+        if ( keystoreFile.exists() )
+        {
+            // Deleting the file
+            FileUtils.deleteQuietly( keystoreFile );
+        }
+    }
+
+
+    public void reload( String masterPassword ) throws KeyStoreException
+    {
+        // Reseting the fields
+        this.keystore = null;
+        this.masterPassword = null;
+
+        load( masterPassword );
+    }
+
+
+    /**
+     * Gets the master password.
+     *
+     * @return the master password
+     */
+    public String getMasterPassword()
+    {
+        return masterPassword;
+    }
+}
\ No newline at end of file

Modified: directory/studio/trunk/plugins/connection.ui/plugin.properties
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.ui/plugin.properties?rev=1466945&r1=1466944&r2=1466945&view=diff
==============================================================================
--- directory/studio/trunk/plugins/connection.ui/plugin.properties (original)
+++ directory/studio/trunk/plugins/connection.ui/plugin.properties Thu Apr 11 16:23:23 2013
@@ -48,3 +48,5 @@ PrefPage_ConnectionsPreferencePage_id=or
 PrefPage_ConnectionsPreferencePage_name=Connections
 PrefPage_CertificateValidationPreferencePage_id=org.apache.directory.studio.connection.preferences.CertificateValidationPreferencePage
 PrefPage_CertificateValidationPreferencePage_name=Certificate Validation
+PrefPage_PasswordsKeystorePreferencePage_id=org.apache.directory.studio.connection.ui.preferences.PasswordsKeystorePreferencePage
+PrefPage_PasswordsKeystorePreferencePage_name=Passwords Keystore

Modified: directory/studio/trunk/plugins/connection.ui/plugin.xml
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.ui/plugin.xml?rev=1466945&r1=1466944&r2=1466945&view=diff
==============================================================================
--- directory/studio/trunk/plugins/connection.ui/plugin.xml (original)
+++ directory/studio/trunk/plugins/connection.ui/plugin.xml Thu Apr 11 16:23:23 2013
@@ -42,6 +42,7 @@
             name="%NewWizards_NewConnectionWizard_name"
             project="false"/>
    </extension>
+   
    <extension
          point="org.apache.directory.studio.connectionparameterpages">
       <connectionParameterPage
@@ -57,6 +58,7 @@
             id="%ConnectionParameterPage_AuthenticationParameterPage_id"
             name="%ConnectionParameterPage_AuthenticationParameterPage_name"/>
    </extension>
+   
    <extension
          point="org.eclipse.ui.preferencePages">
       <page
@@ -71,5 +73,11 @@
             id="%PrefPage_CertificateValidationPreferencePage_id"
             name="%PrefPage_CertificateValidationPreferencePage_name">
       </page>
+      <page
+            category="%PrefPage_ConnectionsPreferencePage_id"
+            class="org.apache.directory.studio.connection.ui.preferences.PasswordsKeystorePreferencePage"
+            id="%PrefPage_PasswordsKeystorePreferencePage_id"
+            name="%PrefPage_PasswordsKeystorePreferencePage_name">
+      </page>
    </extension>  
 </plugin>

Modified: directory/studio/trunk/plugins/connection.ui/plugin_fr.properties
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.ui/plugin_fr.properties?rev=1466945&r1=1466944&r2=1466945&view=diff
==============================================================================
--- directory/studio/trunk/plugins/connection.ui/plugin_fr.properties (original)
+++ directory/studio/trunk/plugins/connection.ui/plugin_fr.properties Thu Apr 11 16:23:23 2013
@@ -29,3 +29,4 @@ ConnectionParameterPage_AuthenticationPa
 
 PrefPage_ConnectionsPreferencePage_name=Connexions
 PrefPage_CertificateValidationPreferencePage_name=Validation de certificat
+PrefPage_PasswordsKeystorePreferencePage_name=Coffre-fort de mots de passe

Added: directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/PasswordsKeyStoreManagerUtils.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/PasswordsKeyStoreManagerUtils.java?rev=1466945&view=auto
==============================================================================
--- directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/PasswordsKeyStoreManagerUtils.java (added)
+++ directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/PasswordsKeyStoreManagerUtils.java Thu Apr 11 16:23:23 2013
@@ -0,0 +1,116 @@
+package org.apache.directory.studio.connection.ui;
+
+
+import java.security.KeyStoreException;
+
+import org.apache.directory.studio.connection.core.ConnectionCoreConstants;
+import org.apache.directory.studio.connection.core.ConnectionCorePlugin;
+import org.apache.directory.studio.connection.ui.dialogs.PasswordDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+
+/**
+ * This class contains utility methods for the passwords keystore.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class PasswordsKeyStoreManagerUtils
+{
+    /**
+     * Checks if the passwords keystore is enabled.
+     *
+     * @return <code>true</code> if the passwords keystore is enabled,
+     *         <code>false</code> if not.
+     */
+    public static boolean isPasswordsKeystoreEnabled()
+    {
+        return ConnectionCorePlugin.getDefault().getPluginPreferences()
+            .getInt( ConnectionCoreConstants.PREFERENCE_CONNECTIONS_PASSWORDS_KEYSTORE ) == ConnectionCoreConstants.PREFERENCE_CONNECTIONS_PASSWORDS_KEYSTORE_ON;
+    }
+
+
+    /**
+     * Asks the user to load the keystore.
+     *
+     * @return <code>true</code> if the keystore was loaded,
+     *         <code>false</code> if not.
+     */
+    public static boolean askUserToLoadKeystore()
+    {
+        final boolean keystoreLoaded[] = new boolean[1];
+        keystoreLoaded[0] = false;
+
+        PlatformUI.getWorkbench().getDisplay().syncExec( new Runnable()
+        {
+            public void run()
+            {
+                while ( true )
+                {
+                    // Getting the shell
+                    Shell shell = PlatformUI.getWorkbench().getDisplay().getActiveShell();
+
+                    // We ask the user for the keystore password
+                    PasswordDialog passwordDialog = new PasswordDialog( shell, "Verify Master Password",
+                        "Please enter your master password:", null );
+
+                    if ( passwordDialog.open() == PasswordDialog.CANCEL )
+                    {
+                        // The user cancelled the action
+                        keystoreLoaded[0] = false;
+                        return;
+                    }
+
+                    // Getting the password
+                    String masterPassword = passwordDialog.getPassword();
+
+                    // Checking the password
+                    Exception checkPasswordException = null;
+                    try
+                    {
+                        if ( ConnectionCorePlugin.getDefault().getPasswordsKeyStoreManager()
+                            .checkMasterPassword( masterPassword ) )
+                        {
+                            keystoreLoaded[0] = true;
+                            break;
+                        }
+                    }
+                    catch ( KeyStoreException e )
+                    {
+                        checkPasswordException = e;
+                    }
+
+                    // Creating the message
+                    String message = null;
+
+                    if ( checkPasswordException != null )
+                    {
+                        message = "The master password verification failed.\n\nThe following exception was raised:\n"
+                            + checkPasswordException.getMessage();
+                    }
+                    else
+                    {
+                        message = "The master password verification failed.";
+                    }
+
+                    // We ask the user if he wants to retry to unlock the passwords keystore
+                    MessageDialog errorDialog = new MessageDialog( shell,
+                        "Verify Master Password Failed", null, message, MessageDialog.ERROR, new String[]
+                            { IDialogConstants.RETRY_LABEL,
+                                IDialogConstants.CANCEL_LABEL }, 0 );
+
+                    if ( errorDialog.open() == MessageDialog.CANCEL )
+                    {
+                        // The user cancelled the action
+                        keystoreLoaded[0] = false;
+                        return;
+                    }
+                }
+            }
+        } );
+
+        return keystoreLoaded[0];
+    }
+}

Modified: directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/UIAuthHandler.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/UIAuthHandler.java?rev=1466945&r1=1466944&r2=1466945&view=diff
==============================================================================
--- directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/UIAuthHandler.java (original)
+++ directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/UIAuthHandler.java Thu Apr 11 16:23:23 2013
@@ -21,10 +21,12 @@
 package org.apache.directory.studio.connection.ui;
 
 
+import org.apache.directory.studio.connection.core.ConnectionCorePlugin;
 import org.apache.directory.studio.connection.core.ConnectionParameter;
 import org.apache.directory.studio.connection.core.Credentials;
 import org.apache.directory.studio.connection.core.IAuthHandler;
 import org.apache.directory.studio.connection.core.ICredentials;
+import org.apache.directory.studio.connection.core.PasswordsKeyStoreManager;
 import org.apache.directory.studio.connection.ui.dialogs.PasswordDialog;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.ui.PlatformUI;
@@ -44,47 +46,101 @@ public class UIAuthHandler implements IA
      */
     public ICredentials getCredentials( final ConnectionParameter connectionParameter )
     {
+        // Checking if the bind principal is null or empty (no authentication)
         if ( connectionParameter.getBindPrincipal() == null || "".equals( connectionParameter.getBindPrincipal() ) ) //$NON-NLS-1$
         {
             return new Credentials( "", "", connectionParameter ); //$NON-NLS-1$ //$NON-NLS-2$
         }
-        else if ( connectionParameter.getBindPassword() != null && !"".equals( connectionParameter.getBindPassword() ) ) //$NON-NLS-1$
-        {
-            return new Credentials( connectionParameter.getBindPrincipal(), connectionParameter.getBindPassword(),
-                connectionParameter );
-        }
         else
         {
-            final String[] pw = new String[1];
-            PlatformUI.getWorkbench().getDisplay().syncExec( new Runnable()
+            // Checking of the connection passwords keystore is enabled
+            if ( PasswordsKeyStoreManagerUtils.isPasswordsKeystoreEnabled() )
             {
-                public void run()
+                // Getting the passwords keystore manager
+                PasswordsKeyStoreManager passwordsKeyStoreManager = ConnectionCorePlugin.getDefault()
+                    .getPasswordsKeyStoreManager();
+
+                // Checking if the keystore is not loaded 
+                if ( !passwordsKeyStoreManager.isLoaded() )
                 {
-                    PasswordDialog dialog = new PasswordDialog(
-                        PlatformUI.getWorkbench().getDisplay().getActiveShell(),
-                        NLS.bind(
-                            Messages.getString( "UIAuthHandler.EnterPasswordFor" ), new String[] { connectionParameter.getName() } ), //$NON-NLS-1$
-                        NLS.bind(
-                            Messages.getString( "UIAuthHandler.PleaseEnterPasswordOfUser" ), connectionParameter.getBindPrincipal() ), "" ); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
-                    if ( dialog.open() == PasswordDialog.OK )
+                    // Asking the user to load the keystore
+                    if ( !PasswordsKeyStoreManagerUtils.askUserToLoadKeystore() )
                     {
-                        pw[0] = dialog.getPassword();
-                    }
-                    else
-                    {
-                        pw[0] = null;
+                        // The user failed to load the keystore and cancelled
+                        return null;
                     }
                 }
-            } );
 
-            if ( pw[0] == null )
-            {
-                return null;
+                // Getting the password
+                String password = passwordsKeyStoreManager.getConnectionPassword( connectionParameter.getId() );
+
+                // Checking if the bind password is available (the user chose to store the password)
+                if ( password != null
+                    && !"".equals( password ) ) //$NON-NLS-1$
+                {
+                    return new Credentials( connectionParameter.getBindPrincipal(),
+                        password, connectionParameter );
+                }
+                // The user chose NOT to store the password, we need to ask him
+                else
+                {
+                    return askConnectionPassword( connectionParameter );
+                }
             }
+            // Connection passwords keystore is NOT enabled
             else
             {
-                return new Credentials( connectionParameter.getBindPrincipal(), pw[0], connectionParameter );
+                // Checking if the bind password is available (the user chose to store the password)
+                if ( connectionParameter.getBindPassword() != null
+                    && !"".equals( connectionParameter.getBindPassword() ) ) //$NON-NLS-1$
+                {
+                    return new Credentials( connectionParameter.getBindPrincipal(),
+                        connectionParameter.getBindPassword(), connectionParameter );
+                }
+                // The user chose NOT to store the password, we need to ask him
+                else
+                {
+                    return askConnectionPassword( connectionParameter );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Asks the user for the connection password.
+     *
+     * @param connectionParameter the connection parameter
+     * @return the corresponding credentials
+     */
+    private Credentials askConnectionPassword( final ConnectionParameter connectionParameter )
+    {
+        final String[] password = new String[1];
+
+        PlatformUI.getWorkbench().getDisplay().syncExec( new Runnable()
+        {
+            public void run()
+            {
+                PasswordDialog dialog = new PasswordDialog(
+                    PlatformUI.getWorkbench().getDisplay().getActiveShell(),
+                    NLS.bind(
+                        Messages.getString( "UIAuthHandler.EnterPasswordFor" ), new String[] { connectionParameter.getName() } ), //$NON-NLS-1$
+                    NLS.bind(
+                        Messages.getString( "UIAuthHandler.PleaseEnterPasswordOfUser" ), connectionParameter.getBindPrincipal() ), "" ); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+
+                if ( dialog.open() == PasswordDialog.OK )
+                {
+                    password[0] = dialog.getPassword();
+                }
             }
+        } );
+
+        if ( password[0] != null )
+        {
+            return new Credentials( connectionParameter.getBindPrincipal(), password[0],
+                connectionParameter );
         }
+
+        return null;
     }
 }

Modified: directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/PasswordDialog.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/PasswordDialog.java?rev=1466945&r1=1466944&r2=1466945&view=diff
==============================================================================
--- directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/PasswordDialog.java (original)
+++ directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/PasswordDialog.java Thu Apr 11 16:23:23 2013
@@ -24,9 +24,11 @@ package org.apache.directory.studio.conn
 import org.apache.directory.studio.common.ui.widgets.BaseWidgetUtils;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
@@ -54,7 +56,7 @@ public class PasswordDialog extends Dial
     private String value = "";//$NON-NLS-1$
 
     // UI Widgets
-    private Text text;
+    private Text passwordText;
     private Button showPasswordCheckbox;
 
 
@@ -104,7 +106,7 @@ public class PasswordDialog extends Dial
     {
         if ( buttonId == IDialogConstants.OK_ID )
         {
-            value = text.getText();
+            value = passwordText.getText();
         }
         else
         {
@@ -119,21 +121,30 @@ public class PasswordDialog extends Dial
      */
     protected Control createDialogArea( Composite parent )
     {
-        Composite composite = ( Composite ) super.createDialogArea( parent );
+        // Composite
+        Composite composite = new Composite( parent, SWT.NONE );
+        GridLayout layout = new GridLayout();
+        layout.marginHeight = convertVerticalDLUsToPixels( IDialogConstants.VERTICAL_MARGIN );
+        layout.marginWidth = convertHorizontalDLUsToPixels( IDialogConstants.HORIZONTAL_MARGIN );
+        layout.verticalSpacing = convertVerticalDLUsToPixels( IDialogConstants.VERTICAL_SPACING );
+        layout.horizontalSpacing = convertHorizontalDLUsToPixels( IDialogConstants.HORIZONTAL_SPACING );
+        composite.setLayout( layout );
+        GridData compositeGridData = new GridData( SWT.FILL, SWT.FILL, true, true );
+        compositeGridData.widthHint = convertHorizontalDLUsToPixels( IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH );
+        composite.setLayoutData( compositeGridData );
 
+        // Message
         if ( message != null )
         {
-            Label label = BaseWidgetUtils.createWrappedLabel( composite, message, 1 );
-            GridData data = new GridData( GridData.GRAB_HORIZONTAL
-                | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL
-                | GridData.VERTICAL_ALIGN_CENTER );
-            data.widthHint = convertHorizontalDLUsToPixels( IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH );
-            label.setLayoutData( data );
+            Label messageLabel = BaseWidgetUtils.createWrappedLabel( composite, message, 1 );
+            GridData messageLabelGridData = new GridData( SWT.FILL, SWT.CENTER, true, true );
+            messageLabelGridData.widthHint = convertHorizontalDLUsToPixels( IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH );
+            messageLabel.setLayoutData( messageLabelGridData );
         }
 
         // Password Text
-        text = BaseWidgetUtils.createText( composite, value, 1 );
-        text.setEchoChar( '\u2022' );
+        passwordText = BaseWidgetUtils.createText( composite, value, 1 );
+        passwordText.setEchoChar( '\u2022' );
 
         // Show Password Checkbox
         showPasswordCheckbox = BaseWidgetUtils.createCheckbox( composite, "Show password", 1 );
@@ -143,15 +154,18 @@ public class PasswordDialog extends Dial
             {
                 if ( showPasswordCheckbox.getSelection() )
                 {
-                    text.setEchoChar( '\0' );
+                    passwordText.setEchoChar( '\0' );
                 }
                 else
                 {
-                    text.setEchoChar( '\u2022' );
+                    passwordText.setEchoChar( '\u2022' );
                 }
             }
         } );
 
+        // Setting focus
+        passwordText.setFocus();
+
         applyDialogFont( composite );
         return composite;
     }

Added: directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/ResetPasswordDialog.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/ResetPasswordDialog.java?rev=1466945&view=auto
==============================================================================
--- directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/ResetPasswordDialog.java (added)
+++ directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/ResetPasswordDialog.java Thu Apr 11 16:23:23 2013
@@ -0,0 +1,312 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+
+package org.apache.directory.studio.connection.ui.dialogs;
+
+
+import org.apache.directory.studio.common.ui.widgets.BaseWidgetUtils;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+
+/**
+ * The ResetPasswordDialog is used to ask the user his current password 
+ * (for verification purposes) and a new (verified) password.
+ * <p>
+ * It has a useful checkbox that can show/hide the typed passwords.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class ResetPasswordDialog extends Dialog
+{
+    /** The title of the dialog */
+    private String title;
+
+    /** The message to display, or <code>null</code> if none */
+    private String message;
+
+    /** The current password value; the empty string by default */
+    private String currentPassword = ""; //$NON-NLS-1$
+
+    /** The new password value; the empty string by default */
+    private String newPassword = ""; //$NON-NLS-1$
+
+    // UI Widgets
+    private Button okButton;
+    private Text currentPasswordText;
+    private Button showCurrentPasswordCheckbox;
+    private Text newPasswordText;
+    private Button showNewPasswordCheckbox;
+    private Text verifyNewPasswordText;
+    private Button showVerifyNewPasswordCheckbox;
+
+
+    /**
+     * Creates a new instance of CredentialsDialog.
+     * 
+     * @param parentShell the parent shell
+     * @param title the title
+     * @param message the dialog message
+     * @param initialValue the initial value
+     */
+    public ResetPasswordDialog( Shell parentShell, String title, String message, String initialValue )
+    {
+        super( parentShell );
+        this.title = title;
+        this.message = message;
+
+        if ( initialValue == null )
+        {
+            currentPassword = ""; //$NON-NLS-1$
+        }
+        else
+        {
+            currentPassword = initialValue;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void configureShell( Shell shell )
+    {
+        super.configureShell( shell );
+
+        if ( title != null )
+        {
+            shell.setText( title );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void createButtonsForButtonBar( Composite parent )
+    {
+        okButton = createButton( parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true );
+        createButton( parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false );
+
+        validate();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void buttonPressed( int buttonId )
+    {
+        if ( buttonId == IDialogConstants.OK_ID )
+        {
+            currentPassword = currentPasswordText.getText();
+            newPassword = newPasswordText.getText();
+        }
+        else
+        {
+            currentPassword = null;
+            newPassword = null;
+        }
+
+        super.buttonPressed( buttonId );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected Control createDialogArea( Composite parent )
+    {
+        // Composite
+        Composite composite = new Composite( parent, SWT.NONE );
+        GridLayout layout = new GridLayout();
+        layout.marginHeight = convertVerticalDLUsToPixels( IDialogConstants.VERTICAL_MARGIN );
+        layout.marginWidth = convertHorizontalDLUsToPixels( IDialogConstants.HORIZONTAL_MARGIN );
+        layout.verticalSpacing = convertVerticalDLUsToPixels( IDialogConstants.VERTICAL_SPACING );
+        layout.horizontalSpacing = convertHorizontalDLUsToPixels( IDialogConstants.HORIZONTAL_SPACING );
+        composite.setLayout( layout );
+        GridData compositeGridData = new GridData( SWT.FILL, SWT.FILL, true, true );
+        compositeGridData.widthHint = convertHorizontalDLUsToPixels( IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH );
+        composite.setLayoutData( compositeGridData );
+
+        // Message
+        if ( message != null )
+        {
+            Label messageLabel = BaseWidgetUtils.createWrappedLabel( composite, message, 1 );
+            GridData messageLabelGridData = new GridData( SWT.FILL, SWT.CENTER, true, true, 2, 1 );
+            messageLabelGridData.widthHint = convertHorizontalDLUsToPixels( IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH );
+            messageLabel.setLayoutData( messageLabelGridData );
+        }
+
+        // Current Password Group
+        Group currentPasswordGroup = BaseWidgetUtils.createGroup( composite, "Current password", 1 );
+        currentPasswordGroup.setLayout( new GridLayout( 2, false ) );
+
+        // Current Password Text
+        BaseWidgetUtils.createLabel( currentPasswordGroup, "Current password:", 1 );
+        currentPasswordText = BaseWidgetUtils.createText( currentPasswordGroup, "", 1 );
+        currentPasswordText.setEchoChar( '\u2022' );
+        currentPasswordText.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                validate();
+            }
+        } );
+
+        // Show Current Password Checkbox
+        BaseWidgetUtils.createLabel( currentPasswordGroup, "", 1 );
+        showCurrentPasswordCheckbox = BaseWidgetUtils.createCheckbox( currentPasswordGroup, "Show password", 1 );
+        showCurrentPasswordCheckbox.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                if ( showCurrentPasswordCheckbox.getSelection() )
+                {
+                    currentPasswordText.setEchoChar( '\0' );
+                }
+                else
+                {
+                    currentPasswordText.setEchoChar( '\u2022' );
+                }
+            }
+        } );
+
+        // New Password Group
+        Group newPasswordGroup = BaseWidgetUtils.createGroup( composite, "New password", 1 );
+        newPasswordGroup.setLayout( new GridLayout( 2, false ) );
+
+        // New Password Text
+        BaseWidgetUtils.createLabel( newPasswordGroup, "New password:", 1 );
+        newPasswordText = BaseWidgetUtils.createText( newPasswordGroup, "", 1 );
+        newPasswordText.setEchoChar( '\u2022' );
+        newPasswordText.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                validate();
+            }
+        } );
+
+        // Show New Password Checkbox
+        BaseWidgetUtils.createLabel( newPasswordGroup, "", 1 );
+        showNewPasswordCheckbox = BaseWidgetUtils.createCheckbox( newPasswordGroup, "Show password", 1 );
+        showNewPasswordCheckbox.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                if ( showNewPasswordCheckbox.getSelection() )
+                {
+                    newPasswordText.setEchoChar( '\0' );
+                }
+                else
+                {
+                    newPasswordText.setEchoChar( '\u2022' );
+                }
+            }
+        } );
+
+        // Verify Text
+        BaseWidgetUtils.createLabel( newPasswordGroup, "Verify new password:", 1 );
+        verifyNewPasswordText = BaseWidgetUtils.createText( newPasswordGroup, "", 1 );
+        verifyNewPasswordText.setEchoChar( '\u2022' );
+        verifyNewPasswordText.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                validate();
+            }
+        } );
+
+        // Show Verify New Password Checkbox
+        BaseWidgetUtils.createLabel( newPasswordGroup, "", 1 );
+        showVerifyNewPasswordCheckbox = BaseWidgetUtils.createCheckbox( newPasswordGroup, "Show password", 1 );
+        showVerifyNewPasswordCheckbox.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                if ( showVerifyNewPasswordCheckbox.getSelection() )
+                {
+                    verifyNewPasswordText.setEchoChar( '\0' );
+                }
+                else
+                {
+                    verifyNewPasswordText.setEchoChar( '\u2022' );
+                }
+            }
+        } );
+
+        // Setting focus
+        currentPasswordGroup.setFocus();
+
+        applyDialogFont( composite );
+        return composite;
+    }
+
+
+    /**
+     * Returns current password.
+     * 
+     * @return the current password
+     */
+    public String getCurrentPassword()
+    {
+        return currentPassword;
+    }
+
+
+    /**
+     * Returns new password.
+     * 
+     * @return the new password
+     */
+    public String getNewPassword()
+    {
+        return newPassword;
+    }
+
+
+    /**
+     * Validates the input.
+     */
+    private void validate()
+    {
+        String currentPassword = currentPasswordText.getText();
+        String newPassword = newPasswordText.getText();
+        String verifyNewPassword = verifyNewPasswordText.getText();
+
+        okButton
+            .setEnabled( ( !"".equals( currentPassword ) ) && ( !"".equals( newPassword ) ) && ( newPassword.equals( verifyNewPassword ) ) && ( !currentPassword.equals( newPassword ) ) ); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+}

Added: directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/SetupPasswordDialog.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/SetupPasswordDialog.java?rev=1466945&view=auto
==============================================================================
--- directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/SetupPasswordDialog.java (added)
+++ directory/studio/trunk/plugins/connection.ui/src/main/java/org/apache/directory/studio/connection/ui/dialogs/SetupPasswordDialog.java Thu Apr 11 16:23:23 2013
@@ -0,0 +1,257 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+
+package org.apache.directory.studio.connection.ui.dialogs;
+
+
+import org.apache.directory.studio.common.ui.widgets.BaseWidgetUtils;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+
+/**
+ * The SetupPasswordDialog is used to ask the user for a setup password 
+ * with a second text widget for verification purposes.
+ * <p>
+ * It has a useful checkbox that can show/hide the typed passwords.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class SetupPasswordDialog extends Dialog
+{
+    /** The title of the dialog */
+    private String title;
+
+    /** The message to display, or <code>null</code> if none */
+    private String message;
+
+    /** The input value; the empty string by default */
+    private String value = "";//$NON-NLS-1$
+
+    // UI Widgets
+    private Button okButton;
+    private Text passwordText;
+    private Button showPasswordCheckbox;
+    private Text verifyPasswordText;
+    private Button showVerifyPasswordCheckbox;
+
+
+    /**
+     * Creates a new instance of CredentialsDialog.
+     * 
+     * @param parentShell the parent shell
+     * @param title the title
+     * @param message the dialog message
+     * @param initialValue the initial value
+     */
+    public SetupPasswordDialog( Shell parentShell, String title, String message, String initialValue )
+    {
+        super( parentShell );
+        this.title = title;
+        this.message = message;
+
+        if ( initialValue == null )
+        {
+            value = "";//$NON-NLS-1$
+        }
+        else
+        {
+            value = initialValue;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void configureShell( Shell shell )
+    {
+        super.configureShell( shell );
+
+        if ( title != null )
+        {
+            shell.setText( title );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void createButtonsForButtonBar( Composite parent )
+    {
+        okButton = createButton( parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true );
+        createButton( parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false );
+
+        validate();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void buttonPressed( int buttonId )
+    {
+        if ( buttonId == IDialogConstants.OK_ID )
+        {
+            value = passwordText.getText();
+        }
+        else
+        {
+            value = null;
+        }
+        super.buttonPressed( buttonId );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected Control createDialogArea( Composite parent )
+    {
+        // Composite
+        Composite composite = new Composite( parent, SWT.NONE );
+        GridLayout layout = new GridLayout();
+        layout.marginHeight = convertVerticalDLUsToPixels( IDialogConstants.VERTICAL_MARGIN );
+        layout.marginWidth = convertHorizontalDLUsToPixels( IDialogConstants.HORIZONTAL_MARGIN );
+        layout.verticalSpacing = convertVerticalDLUsToPixels( IDialogConstants.VERTICAL_SPACING );
+        layout.horizontalSpacing = convertHorizontalDLUsToPixels( IDialogConstants.HORIZONTAL_SPACING );
+        composite.setLayout( layout );
+        GridData compositeGridData = new GridData( SWT.FILL, SWT.FILL, true, true );
+        compositeGridData.widthHint = convertHorizontalDLUsToPixels( IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH );
+        composite.setLayoutData( compositeGridData );
+
+        // Message
+        if ( message != null )
+        {
+            Label messageLabel = BaseWidgetUtils.createWrappedLabel( composite, message, 1 );
+            GridData messageLabelGridData = new GridData( SWT.FILL, SWT.CENTER, true, true );
+            messageLabelGridData.widthHint = convertHorizontalDLUsToPixels( IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH );
+            messageLabel.setLayoutData( messageLabelGridData );
+        }
+
+        // Password Group
+        Group passwordGroup = BaseWidgetUtils.createGroup( composite, "Password", 1 );
+        passwordGroup.setLayout( new GridLayout( 2, false ) );
+
+        // Password Text
+        BaseWidgetUtils.createLabel( passwordGroup, "Password:", 1 );
+        passwordText = BaseWidgetUtils.createText( passwordGroup, value, 1 );
+        passwordText.setEchoChar( '\u2022' );
+        passwordText.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                validate();
+            }
+        } );
+
+        // Show Password Checkbox
+        BaseWidgetUtils.createLabel( passwordGroup, "", 1 );
+        showPasswordCheckbox = BaseWidgetUtils.createCheckbox( passwordGroup, "Show password", 1 );
+        showPasswordCheckbox.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                if ( showPasswordCheckbox.getSelection() )
+                {
+                    passwordText.setEchoChar( '\0' );
+                }
+                else
+                {
+                    passwordText.setEchoChar( '\u2022' );
+                }
+            }
+        } );
+
+        // Verify Text
+        BaseWidgetUtils.createLabel( passwordGroup, "Verify password:", 1 );
+        verifyPasswordText = BaseWidgetUtils.createText( passwordGroup, value, 1 );
+        verifyPasswordText.setEchoChar( '\u2022' );
+        verifyPasswordText.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                validate();
+            }
+        } );
+
+        // Show Verify Password Checkbox
+        BaseWidgetUtils.createLabel( passwordGroup, "", 1 );
+        showVerifyPasswordCheckbox = BaseWidgetUtils.createCheckbox( passwordGroup, "Show password", 1 );
+        showVerifyPasswordCheckbox.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                if ( showVerifyPasswordCheckbox.getSelection() )
+                {
+                    verifyPasswordText.setEchoChar( '\0' );
+                }
+                else
+                {
+                    verifyPasswordText.setEchoChar( '\u2022' );
+                }
+            }
+        } );
+
+        // Setting focus
+        passwordText.setFocus();
+
+        applyDialogFont( composite );
+        return composite;
+    }
+
+
+    /**
+     * Returns the string typed into this password dialog.
+     * 
+     * @return the input string
+     */
+    public String getPassword()
+    {
+        return value;
+    }
+
+
+    /**
+     * Validates the input.
+     */
+    private void validate()
+    {
+        String password = passwordText.getText();
+        String verifyPassword = verifyPasswordText.getText();
+
+        okButton.setEnabled( ( !"".equals( password ) ) && ( password.equals( verifyPassword ) ) ); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+}