org.cloudifysource.esc.driver.provisioning.jclouds.EC2WindowsPasswordHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.cloudifysource.esc.driver.provisioning.jclouds.EC2WindowsPasswordHandler.java

Source

/*******************************************************************************
 * Copyright (c) 2012 GigaSpaces Technologies Ltd. All rights reserved
 *
 * Licensed 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.cloudifysource.esc.driver.provisioning.jclouds;

import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.concurrent.TimeoutException;

import org.apache.commons.io.FileUtils;
import org.cloudifysource.esc.driver.provisioning.CloudProvisioningException;
import org.jclouds.cloudstack.domain.EncryptedPasswordAndPrivateKey;
import org.jclouds.cloudstack.functions.WindowsLoginCredentialsFromEncryptedData;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.crypto.Crypto;
import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.ec2.EC2Client;
import org.jclouds.ec2.domain.PasswordData;
import org.jclouds.encryption.internal.JCECrypto;

/************
 * Handles decryption of encrypted Administrator passwords for Amazon EC2 windows instances.
 *
 * @author barakme
 * @since 2.1.0
 *
 */
public class EC2WindowsPasswordHandler {

    private static final int PASSWORD_POLLING_INTERVAL_MILLIS = 5000;

    private static final java.util.logging.Logger logger = java.util.logging.Logger
            .getLogger(EC2WindowsPasswordHandler.class.getName());

    /************
     * Returns the decrypted password.
     *
     * @param node
     *            the compute node.
     * @param context
     *            the compute context.
     * @param end
     *            the operation end time.
     * @param pemFile
     *            the private key file used to decrypt the password.
     * @return the decrypted password.
     * @throws InterruptedException .
     * @throws TimeoutException .
     * @throws CloudProvisioningException .
     */
    public LoginCredentials getPassword(final NodeMetadata node, final ComputeServiceContext context,
            final long end, final File pemFile)
            throws InterruptedException, TimeoutException, CloudProvisioningException {
        final EC2Client api = (EC2Client) context.getProviderSpecificContext().getApi();
        final Location zone = node.getLocation();
        final Location region = zone.getParent();
        final String id = node.getId();

        String key;
        try {
            key = FileUtils.readFileToString(pemFile);
        } catch (final IOException e) {
            throw new CloudProvisioningException("Failed to read key file: " + pemFile, e);
        }

        final String amiId = id.split("/")[1];
        while (System.currentTimeMillis() < end) {
            logger.fine("Reading Windows password");

            final PasswordData passwordData = api.getWindowsServices().getPasswordDataInRegion(region.getId(),
                    amiId);

            if (passwordData == null || passwordData.getPasswordData() == null
                    || passwordData.getPasswordData().isEmpty()) {
                Thread.sleep(PASSWORD_POLLING_INTERVAL_MILLIS);
            } else {
                final String encryptedPassword = passwordData.getPasswordData();

                LoginCredentials credentials;
                try {
                    credentials = decryptPasswordData(encryptedPassword, key);
                } catch (final NoSuchAlgorithmException e) {
                    throw new CloudProvisioningException("Failed to decrypt windows password: " + e.getMessage(),
                            e);
                } catch (final CertificateException e) {
                    throw new CloudProvisioningException("Failed to decrypt windows password: " + e.getMessage(),
                            e);
                } catch (final IOException e) {
                    throw new CloudProvisioningException("Failed to decrypt windows password: " + e.getMessage(),
                            e);
                }
                return credentials;

            }
        }

        throw new TimeoutException("Failed to retrieve EC2 Windows password in the allocated time");

    }

    private LoginCredentials decryptPasswordData(final String encryptedPassword, final String key)
            throws NoSuchAlgorithmException, CertificateException, IOException {

        final Crypto crypto = new JCECrypto();

        final WindowsLoginCredentialsFromEncryptedData f = new WindowsLoginCredentialsFromEncryptedData(crypto);

        final LoginCredentials credentials = f.apply(EncryptedPasswordAndPrivateKey.builder()
                .encryptedPassword(encryptedPassword).privateKey(key).build());

        return credentials;

    }
}