Bug 1422903

Summary: Automate instances with passwords return nil if generated using a different key
Product: Red Hat CloudForms Management Engine Reporter: Josh Carter <jocarter>
Component: AutomateAssignee: mkanoor
Status: CLOSED DUPLICATE QA Contact: Milan Falešník <mfalesni>
Severity: high Docs Contact:
Priority: high    
Version: 5.7.0CC: gmccullo, jhardy, jocarter, kbrock, mkanoor, obarenbo, tfitzger
Target Milestone: GAKeywords: Reopened
Target Release: cfme-future   
Hardware: All   
OS: All   
Whiteboard: automate:security
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-01-03 21:22:37 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Josh Carter 2017-02-16 14:15:33 UTC
Description of problem:

When working in automate in CloudForms we sometimes instantiate instances of classes and utilize the properties of these instances.

test = $evm.instantiate('/Configuration/Test/test')
username = test['username']
password = test.decrypt('password')

If an instance has a field of type Password that is generated by encryption key X and is then imported into a CloudForms server with encryption key Y, the $evm.instantiate() method with return a nil object.

In previous versions of CloudForms in this scenario the $evm.instantiate() call would return a valid object and simply the Password field would be blank/nil.

If we re-enter the password into the instance then export the instance then import the instance the $evm.instnatiate() call returns a valid object once more.

Expected behavior:
$evm.instantiate() should return a valid object for instances with password fields, no matter what encryption key was used to create the password. $evm.instantiate() should return a blank/nil password for passwords encrypted with a different key.



Steps to recreate:
- Create a class with a Password field in its schema: /PasswordNamespace/PasswordClass
- Create an instances of this class: /PasswordNamespace/PasswordClass/PassworInstance
- Assign a value to the password field in the instance.
- Create an automate method that performs the following:

begin
  instance =  $evm.instantiate('/PasswordNamespace/PasswordClass/PasswordInstance')
  $evm.log(:info, "Password = #{instance.decrypt('password')}")
  exit MIQ_OK
rescue => err
  $evm.log(:error, "[#{err}]\n#{err.backtrace.join("\n")}")
  exit MIQ_ABORT
end


- Execute the automate method
- Inspect automation.log to ensure the expected password is logged
- Export the domain with the PasswordNamespace
- Change the appliances encryption key (or import into an appliance with a different encryption key)
- Execute the automate method
- Inspect automation.log and notice that an exception was raised due to instance being nil


Version-Release number of selected component (if applicable): 5.6.2


How reproducible:


Steps to Reproduce:
1.
2.
3.

Actual results:


Expected results:


Additional info:

Comment 3 Keenan Brock 2017-02-27 17:58:59 UTC
if you want to fix the database and you have the old password you can try:

    fix_auth --db --legacy old_key

Comment 4 mkanoor 2017-02-27 21:47:10 UTC
During evm.instantiate we fetch attribute values from the database and try to set it in the I'm memory object. If we get an error creating the password we end up throwing an exception which returns a nil object leading to the decrypt error.

Fixed code to catch the exception. and set the password value to nil.

Comment 6 mkanoor 2017-03-02 20:31:27 UTC
I tried this with different versions of the product, they all seem to fail the same way as reported by the customer.

[----] E, [2017-03-02T20:23:51.259187 #7329:5cc8fe4] ERROR -- : <AEMethod bztest> The following error occurred during method evaluation:
[----] E, [2017-03-02T20:23:51.259627 #7329:5cc8fe4] ERROR -- : <AEMethod bztest>   NoMethodError: undefined method `decrypt' for nil:NilClass
[----] E, [2017-03-02T20:23:51.260401 #7329:5cc8fe4] ERROR -- : <AEMethod bztest>   
[----] E, [2017-03-02T20:23:51.267769 #7329:11fa88c] ERROR -- : Method STDERR: <code: password = test.decrypt('var2')>:7:in `<main>': undefined method `decrypt' for nil:NilClass (NoMethodError)

When the key is different during the initial decrypt for $evm.instantiate we get 
OpenSSL::Cipher::CipherError Exception: bad decrypt
Which we translate into our own exception  MiqPassword::MiqPasswordError and the instantiate process is aborted and we return a nil.


Can we get the build string where the customer has seen this behavior?

Comment 8 mkanoor 2017-03-13 21:07:10 UTC
Josh,

The customer states that
"In previous versions of CloudForms in this scenario the $evm.instantiate() call would return a valid object and simply the Password field would be blank/nil."

I tested in different versions and we consistently throw an exception when we encounter encryption errors.

Ignoring the encryption error and replacing it with a nil value is not an ideal solution here.

Can we ask the customer if they can manually change these after the data has been imported to newer encrypted value.

Another future enhancement would be to optionally allow the importer to ignore encrypted fields.

Thanks,
Madhu

Comment 9 mkanoor 2017-04-17 16:02:04 UTC
From my testing this behavior has not changed from previous versions.

If the password was not updated after the import from an external appliance, the password code is going to going to throw an error and stop the $evm.instantiate object resolution.

We cannot just ignore the error and continue on with the instantiation.

Comment 10 mkanoor 2017-12-06 01:48:00 UTC
Not logging the decryption error hurts the debugging process.
We should revive this PR
Another customer reported a similar issue
https://bugzilla.redhat.com/show_bug.cgi?id=1518058

The core problem there was they exported/imported passwords between different environments and the encryption key was different between the 2 environments.

We didn't log any errors when the decrypt failed and stopped that leg of the resolution.

Comment 11 mkanoor 2018-01-03 21:22:37 UTC
https://github.com/ManageIQ/manageiq-automation_engine/pull/127

Now we log decryption errors from $evm.instantiate
Duplicate of https://bugzilla.redhat.com/show_bug.cgi?id=1518058

*** This bug has been marked as a duplicate of bug 1518058 ***