public override AmazonWebServiceResponse Unmarshall(XmlUnmarshallerContext context)
        {
            GetPasswordDataResponse response = new GetPasswordDataResponse();

            int targetDepth = 2;

            while (context.Read())
            {
                if (context.IsStartElement || context.IsAttribute)
                {
                    if (context.TestExpression("instanceId", targetDepth))
                    {
                        response.InstanceId = StringUnmarshaller.GetInstance().Unmarshall(context);

                        continue;
                    }
                    if (context.TestExpression("timestamp", targetDepth))
                    {
                        response.Timestamp = DateTimeUnmarshaller.GetInstance().Unmarshall(context);

                        continue;
                    }
                    if (context.TestExpression("passwordData", targetDepth))
                    {
                        response.PasswordData = StringUnmarshaller.GetInstance().Unmarshall(context);

                        continue;
                    }
                }
            }


            return(response);
        }
示例#2
0
        /// <summary>
        /// Loads the specified .pem file and uses it to decrypt the password data returned
        /// from the instance.
        /// </summary>
        /// <param name="pemFile">The full path to the .pem file to use</param>
        /// <param name="passwordDataResponse">Encrypted password data retrieved from the instance</param>
        /// <returns>The decrypted password</returns>
        string DecryptViaPemFile(string pemFile, GetPasswordDataResponse passwordDataResponse)
        {
            string decryptedPassword = null;

            try
            {
                if (!File.Exists(pemFile))
                {
                    throw new ArgumentException("Specified .pem file does not exist");
                }

                string privateKey = null;
                using (var fs = File.OpenRead(pemFile))
                    using (var reader = new StreamReader(fs))
                    {
                        privateKey = reader.ReadToEnd();
                    }

                decryptedPassword = passwordDataResponse.GetDecryptedPassword(privateKey);
            }
            catch (Exception e)
            {
                this.ThrowTerminatingError(new ErrorRecord(e, "InvalidOperationException", ErrorCategory.InvalidOperation, this));
            }

            return(decryptedPassword);
        }
示例#3
0
        /// <summary>
        /// Retrieves the name of the keypair used on launch from the instance, then inspects
        /// the local AWS Toolkit store for matching account & keypair data before decrypting
        /// the password data.
        /// </summary>
        /// <param name="instanceId">The instance the user wants the password for</param>
        /// <param name="passwordDataResponse">Encrypted password data retrieved from the instance</param>
        /// <param name="profileLocation">The location of the ini-format credential file.</param>
        /// <returns>The decrypted password</returns>
        string DecryptViaPemDiscovery(string instanceId, GetPasswordDataResponse passwordDataResponse, string profileName, string profileLocation)
        {
            string decryptedPassword = null;

            try
            {
                WriteVerbose(string.Format("Retrieving keyname from running instance {0}", instanceId));
                var request = new DescribeInstancesRequest();
                request.InstanceIds.Add(instanceId);
                var    response = CallAWSServiceOperation(Client, request);
                string keyName  = response.Reservations[0].Instances[0].KeyName;

                WriteVerbose(string.Format("Retrieved keyname {0}, decrypting password data", keyName));
                string accountSettingsKey = LookupAccountSettingsKey(this._CurrentCredentials.GetCredentials().AccessKey, profileName, profileLocation);
                if (string.IsNullOrEmpty(accountSettingsKey))
                {
                    throw new InvalidOperationException("Unable to determine stored account settings from access key");
                }

                if (ToolkitKeyPairHelper.DoesPrivateKeyExist(accountSettingsKey, this._RegionEndpoint.SystemName, keyName))
                {
                    string privateKey = ToolkitKeyPairHelper.GetPrivateKey(accountSettingsKey, this._RegionEndpoint.SystemName, keyName);
                    decryptedPassword = passwordDataResponse.GetDecryptedPassword(privateKey);
                }
            }
            catch (Exception e)
            {
                this.ThrowTerminatingError(new ErrorRecord(e, "InvalidOperationException", ErrorCategory.InvalidOperation, this));
            }

            return(decryptedPassword);
        }
示例#4
0
        public void TestMissingLeadingZeroIssue()
        {
            string encryptedPassword = "******";
            string privateKey        = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAmOMJ9AIxkXBhPK+0dU0CfgqP+uMUnwPa8TwnY9+pl49s2+BGrGVIl+qccYl+\nZ0mu7MDd0MZsQBH2ZNDl+7464sqpA5PlWkl4a3/Mgc/OC00kU2o4aslLGoHUgFfIRtiA40bXEif8\nnHWQR4AWJCGS3w1oLlW4qvUwDzvLZ5dJ6n/erThZAFJa1XEPZgh3vjdLQEkxb1pkgo831niNPC5B\nZYVpr+MfBFgdVt4LdY3B7o6jkA1h7QxeZp9Au84Ag7nE3RELU7ll4U3Z9WK+8NZ+5/mJQ5LrSN47\n2KRR3Z+KBM2GYLo4U1LutL/ajUbZe1IJeTgdZMb1DMvyLu2283uiOwIDAQABAoIBAQCFzn9RjfHw\nBlk0Edtwplu+EGR/Aet0WJ1wcGNRJ9l4ClEOBzYTf/mO7AjL3bhBkd2E3C/Gn0LyuEXbanE+aPmE\nsDZIKVKcOJ0qCInmOwdsILHgR6Dk5RPUOTjQswNX7fiv8bod691M2h/SVCoMqU2v5j39/4xGI51S\nV9Tn7yMEFk5/Lmu9NNAtIrFF5ywsVbT5so6MbGqBRI8KNX71/T9KTJjXxGR9RnrKRv9zrygDw1yB\nNaJW2/HiOfbcACvehqlwBEyRRMNKZ8t+GnwnSbq30V4ojj7DlJ1piM2+11NUpIbXI1chR2iFRvyp\nP2QMp2YDlqvw5pKo8v53YYRJ5CCxAoGBAPg6lN8C39aBPJHgKgH7VtkV1QQudjHWFPRkXeixuKYi\nOZrdqrEKHt69T2aXcazqaJNNMfT3QxLtg8afe3c4Kz7TuIZI5EtKi0Ny6Wx2QhKa/Lq0YAjoAdQO\nlONf3p0eW4367fezegvZeNazKl0M4RAcW1qje5iqU42bSrPrGgq3AoGBAJ2sV/bM7g+ZRgmsbdOS\nJeoKf9n0+iA9/arhnn0/ygkYYOegQP9vOfefafLmKuImRu3mo1D7iuVhk/p7Mkkse0mQ68aZg88H\n3JBuZgf2WokN/lw0JdP40VUPobGZ9xS/a233+cRUn0Idrtslh7aIeR7yhzHIjuQYP7aAX6nnxXCd\nAoGBAOpSGoAebYBGxQ+LRPxT71rDgi8NUOOgjG1bZU6onX6uZiRrxZqTzCpFGHPm2Bb7vDX4tATj\neHygmzlfCSS0cBZBtDmHC4KLXsUP74tEYwC/L31rkhA2OqucDC5LLJCyvIhdbE/cK4SOCMTbokzu\nQHJ94jrAgobNmkvdYPpQH2gnAoGAR5MSo1BHyQD1EDMb7+zqFSILA6/3U2eQnV+qCIVKe3J7mune\nV5XwJH5TJBZj5SEnFZubC4oEdTgkapI+M4VjufN1dEP/151j/JSA8KBeXNTjYIuzmFPdAtYDupF/\n3gU/CT6GPR+E5AiBda3Fu5CcGvZRdMHsS5LOaVRBGOnDcOkCgYAA06F5y5/pdOFGrCGEoF4KOn43\nXbOG4I4WvjYP5u+CHhu4ipKvLT1TzbugO7fV8ilVU1R7R9Ur7MTCiSc7tO8QMkZbBGvUu3LAe3Hb\nAWdLBliOrgOyAjFWervBecbP9h4gn8fOALcQJqnqg2BRRhbN/lTGPsZpaLwRkS4MuQLGnw==\n-----END RSA PRIVATE KEY-----";

            GetPasswordDataResponse response = new GetPasswordDataResponse {
                PasswordData = encryptedPassword
            };
            string decryptedPassword = response.GetDecryptedPassword(privateKey);

            Assert.IsNotNull(decryptedPassword);
        }
示例#5
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>
        /// Unmarshaller the response from the service to the response class.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override AmazonWebServiceResponse Unmarshall(XmlUnmarshallerContext context)
        {
            GetPasswordDataResponse response = new GetPasswordDataResponse();

            int originalDepth = context.CurrentDepth;
            int targetDepth   = originalDepth + 1;

            if (context.IsStartOfDocument)
            {
                targetDepth = 2;
            }

            while (context.ReadAtDepth(originalDepth))
            {
                if (context.IsStartElement || context.IsAttribute)
                {
                    if (context.TestExpression("instanceId", targetDepth))
                    {
                        var unmarshaller = StringUnmarshaller.Instance;
                        response.InstanceId = unmarshaller.Unmarshall(context);
                        continue;
                    }
                    if (context.TestExpression("passwordData", targetDepth))
                    {
                        var unmarshaller = StringUnmarshaller.Instance;
                        response.PasswordData = unmarshaller.Unmarshall(context);
                        continue;
                    }
                    if (context.TestExpression("timestamp", targetDepth))
                    {
                        var unmarshaller = DateTimeUnmarshaller.Instance;
                        response.Timestamp = unmarshaller.Unmarshall(context);
                        continue;
                    }
                }
            }

            return(response);
        }
        /// <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);
        }