예제 #1
0
        public object Execute(ExecutorContext context)
        {
            var cmdletContext = context as CmdletContext;
            var request       = new GetPasswordDataRequest();

            if (cmdletContext.InstanceId != null)
            {
                request.InstanceId = cmdletContext.InstanceId;
            }

            var          client = Client ?? CreateClient(_CurrentCredentials, _RegionEndpoint);
            CmdletOutput output;

            try
            {
                var response = CallAWSServiceOperation(client, request);

                if (string.IsNullOrEmpty(response.PasswordData))
                {
                    var msg = string.Format(
                        "Password data is not yet available for instance {0}.\n\nPassword generation and encryption can sometimes take more than 30 minutes. Please wait at least 5 minutes after launching an instance before trying to retrieve the generated password.",
                        cmdletContext.InstanceId);
                    this.WriteWarning(msg);
                    return(new CmdletOutput
                    {
                        ServiceResponse = response
                    });
                }

                if (!cmdletContext.Decrypt)
                {
                    output = new CmdletOutput
                    {
                        PipelineOutput  = response.PasswordData,
                        ServiceResponse = response
                    };
                }
                else
                {
                    output = new CmdletOutput
                    {
                        PipelineOutput = string.IsNullOrEmpty(cmdletContext.PemFile)
                            ? DecryptViaPemDiscovery(cmdletContext.InstanceId, response, ProfileName, ProfileLocation)
                            : DecryptViaPemFile(cmdletContext.PemFile, response)
                    };
                }
            }
            catch (Exception e)
            {
                output = new CmdletOutput {
                    ErrorResponse = e
                };
            }

            return(output);
        }
예제 #2
0
        public Tuple<string, string> WaitForPassword(string instanceId, string key)
        {
            var passwordRequest = new GetPasswordDataRequest { InstanceId = instanceId };

            var response = _client.GetPasswordData(passwordRequest);
            if (string.IsNullOrWhiteSpace(response.PasswordData))
            {
                Logger.Info(string.Format("Password not yet ready for {0}, waiting 30 seconds...", instanceId));
                Thread.Sleep(30000);
                return WaitForPassword(instanceId, key);
            }
            return new Tuple<string, string>(instanceId, response.GetDecryptedPassword(key));
        }
예제 #3
0
        /// <summary>
        /// Gets a particular instance's password (or at least, the original
        /// password assigned to the EC2 instance upon creation).
        /// </summary>
        /// <param name="amazonEC2">
        /// An instance of <see cref="IAmazonEC2" />.
        /// </param>
        /// <param name="passwordEncryptionKey">
        /// The AWS password encryption key, used in decryption.
        /// </param>
        /// <param name="instanceId">
        /// The id of the <see cref="Instance" /> to pull back a password for.
        /// </param>
        /// <returns>
        /// The instance's password, as a <see cref="string" /> .
        /// </returns>
        private string GetInstancePassword(
            IAmazonEC2 amazonEC2,
            string passwordEncryptionKey,
            string instanceId)
        {
            string toReturn = null;

            this.loggingProvider.Debug(
                $"Requesitng encrypted password data from " +
                $"{nameof(Instance)} ID \"{instanceId}\"...");

            GetPasswordDataRequest getPasswordDataRequest =
                new GetPasswordDataRequest(instanceId);

            GetPasswordDataResponse getPasswordDataResponse =
                amazonEC2.GetPasswordData(getPasswordDataRequest);

            this.loggingProvider.Info(
                $"Password data returned for {nameof(Instance)} ID " +
                $"\"{instanceId}\".");

            try
            {
                this.loggingProvider.Debug(
                    $"Using password encryption key to decrypt password " +
                    $"for {nameof(Instance)} ID \"{instanceId}\"...");

                toReturn = getPasswordDataResponse
                           .GetDecryptedPassword(passwordEncryptionKey);

                this.loggingProvider.Info(
                    $"Password for {nameof(Instance)} ID \"{instanceId}\" " +
                    $"decrypted with success.");
            }
            catch (CryptographicException)
            {
                // We still want to carry on if we can't decrypt the password,
                // but...
                this.loggingProvider.Error(
                    $"Could not decrypt password for {nameof(Instance)} " +
                    $"ID \"{instanceId}\"! Are you sure that the password " +
                    $"encryption key is correct? Returning null.");
            }

            return(toReturn);
        }
        /// <summary>
        /// Gets a particular instance's password (or at least, the original
        /// password assigned to the EC2 instance upon creation).
        /// </summary>
        /// <param name="amazonEC2">
        /// An instance of <see cref="IAmazonEC2" />.
        /// </param>
        /// <param name="passwordEncryptionKeys">
        /// Multiple EC2 password encryption keys.
        /// </param>
        /// <param name="instanceId">
        /// The id of the <see cref="Instance" /> to pull back a password for.
        /// </param>
        /// <returns>
        /// The instance's password, as a <see cref="string" /> .
        /// </returns>
        private string GetInstancePassword(
            IAmazonEC2 amazonEC2,
            string[] passwordEncryptionKeys,
            string instanceId)
        {
            string toReturn = null;

            this.loggingProvider.Debug(
                $"Requesitng encrypted password data from " +
                $"{nameof(Instance)} ID \"{instanceId}\"...");

            GetPasswordDataRequest getPasswordDataRequest =
                new GetPasswordDataRequest(instanceId);

            GetPasswordDataResponse getPasswordDataResponse =
                amazonEC2.GetPasswordData(getPasswordDataRequest);

            this.loggingProvider.Info(
                $"Password data returned for {nameof(Instance)} ID " +
                $"\"{instanceId}\". Attempting to decrypt password with " +
                $"all {passwordEncryptionKeys.Length} password encryption " +
                $"key(s) in memory...");

            // Only keep going for as long as we don't have a key decrypted.
            string passwordEncryptionKey = null;

            for (int i = 0; i < passwordEncryptionKeys.Length && string.IsNullOrEmpty(toReturn); i++)
            {
                try
                {
                    passwordEncryptionKey = passwordEncryptionKeys[i];

                    this.loggingProvider.Debug(
                        $"Using password encryption key " +
                        $"{i + 1}/{passwordEncryptionKeys.Length} to " +
                        $"decrypt password for {nameof(Instance)} ID " +
                        $"\"{instanceId}\"...");

                    toReturn = getPasswordDataResponse
                               .GetDecryptedPassword(passwordEncryptionKey);

                    this.loggingProvider.Info(
                        $"Password for {nameof(Instance)} ID " +
                        $"\"{instanceId}\" decrypted with success.");
                }
                catch (CryptographicException)
                {
                    // We still want to carry on if we can't decrypt the
                    // password, but...
                    this.loggingProvider.Warn(
                        $"Could not decrypt password for {nameof(Instance)} " +
                        $"ID \"{instanceId}\" using password encryption key " +
                        $"{i + 1}/{passwordEncryptionKeys.Length}.");
                }
            }

            if (string.IsNullOrEmpty(toReturn))
            {
                this.loggingProvider.Error(
                    $"Could not decrypt password for {nameof(Instance)}: " +
                    $"{passwordEncryptionKeys.Length} password encryption " +
                    $"keys were tried, and none succeeded. Are you sure " +
                    $"that the key file(s) are correct?");
            }

            return(toReturn);
        }