Bug 1256437 - Protected text fields are not being added to options_hash
Summary: Protected text fields are not being added to options_hash
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat CloudForms Management Engine
Classification: Red Hat
Component: Automate
Version: 5.4.0
Hardware: Unspecified
OS: Unspecified
high
high
Target Milestone: GA
: 5.5.0
Assignee: Greg McCullough
QA Contact: Aziza Karol
URL:
Whiteboard:
Depends On:
Blocks: 1261025
TreeView+ depends on / blocked
 
Reported: 2015-08-24 14:51 UTC by Vagner Farias
Modified: 2015-12-08 13:28 UTC (History)
8 users (show)

Fixed In Version: 5.5.0.1
Doc Type: Bug Fix
Doc Text:
Clone Of:
: 1261025 (view as bug list)
Environment:
Last Closed: 2015-12-08 13:28:19 UTC
Category: ---
Cloudforms Team: ---
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
suggested patch to add protected text to options_hash (1.05 KB, patch)
2015-08-24 14:56 UTC, Vagner Farias
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2015:2551 0 normal SHIPPED_LIVE Moderate: CFME 5.5.0 bug fixes and enhancement update 2015-12-08 17:58:09 UTC

Description Vagner Farias 2015-08-24 14:51:52 UTC
Description of problem:
I'd like to decrypt a password entered in a Service Dialog, in order to use it in a cloud-init script. I'm almost sure that in CloudForms 3.1 I could achieve this using something like the following:

chpasswd:
  list: |
    root:<%=MiqPassword.decrypt(evm[:"password::dialog_root_pw"]) %>
  expire: False

In CF 3.2 this isn't working anymore and it seems this is happening because password dialog entries are not being added to options_hash the way it was done in 3.1.

Version-Release number of selected component (if applicable):
EVM  5.4.1.0.20150717083323_6ed7e1c 

How reproducible:
Always

Steps to Reproduce:
1. Create a service dialog with a protected text element
2. Create a cloudinit customization template with a call to decrypt the protected text (like the example above)
3. Create an openstack catalog item, using the service dialog and customization template 
4. Order the service

Actual results:
<%=MiqPassword.decrypt(evm[:"password::dialog_root_pw"]) %> returns nothing

Expected results:
<%=MiqPassword.decrypt(evm[:"password::dialog_root_pw"]) %> should return decrypted text

Additional info:
If the change was intentional, it should be documented somewhere.

Comment 1 Vagner Farias 2015-08-24 14:56:09 UTC
Created attachment 1066436 [details]
suggested patch to add protected text to options_hash

Using this patch I could achieve the expected result, with a small modification to MiqPassword.decrypt. Instead of:

<%=MiqPassword.decrypt(evm[:"password::dialog_root_pw"]) %>

I'm using the following in the customization template:

<%=MiqPassword.decrypt(evm[:"password::root_pw"]) %>

I believe this happens because dialog_parser removes the "dialog_" string.

Comment 3 Tina Fitzgerald 2015-08-24 16:02:50 UTC
Hi Vagner,

Thanks for including the patch for the dialog_parser. 

We had an issue where we removed the "dialog_" prefix and that caused some problems for custom scripts that relied on the prefix.  We made a code change to add both the prefixed and stripped dialog options to the hash. 

Could you test adding back the "dialog_" prefix in your customization template and comment out your option_password_value method to see if it works?

More information on the dialog prefix change: 
https://bugzilla.redhat.com/show_bug.cgi?id=1235975

Thanks,
Tina

Comment 4 Vagner Farias 2015-08-24 17:14:06 UTC
Hi Tina,

I believe this isn't directly related to bz #1235975. My original customization template was using dialog_ prefix and it was not working - although it was working in CF 3.1.

It seems to me the builtin dialog_parser isn't prepared to handle password protected elements. If you look at the code, it's looking for dialog_key to match one of the following strings:

^dialog_option_(?<sequence>\d*)_(?<option_key>.*)
^array::dialog_option_(?<sequence>\d*)_(?<option_key>.*)
^dialog_tag_(?<sequence>\d*)_(?<option_key>.*)
^array::dialog_tag_(?<sequence>\d*)_(?<option_key>.*)

However, password protected elements will match with:

^password::dialog_option_(?<sequence>\d*)_(?<option_key>.*)

Look at the following example, starting with the service_request_quota_validation method:

[----] I, [2015-08-23T02:34:44.700951 #24594:9b0cea4]  INFO -- : Q-task_id([service_template_provision_request_10000000000075]) <AEMethod service_request_quota_validation> Adding seq_id: 0 key: :"password::dialog_option_1_root_pw" value: "v2:{c7TlWs/zQuObrIcgphFihg==}" to options_hash

Later, when dialog_parser is called, you can't see this option being added:

[----] I, [2015-08-23T02:34:55.029341 #24591:7a6f638]  INFO -- : Q-task_id([service_template_provision_task_10000000000187]) <AEMethod dialog_parser> dialog_options: {"dialog_service_name"=>"remover", "dialog_option_0_flavor"=>"m1.small", "password::dialog_option_1_root_pw"=>"v2:{c7TlWs/zQuObrIcgphFihg==}", "request"=>"clone_to_service"}
[----] I, [2015-08-23T02:34:55.030990 #24591:7a6f638]  INFO -- : Q-task_id([service_template_provision_task_10000000000187]) <AEMethod dialog_parser> Adding seq_id: 0 key: service_name value: remover 
[----] I, [2015-08-23T02:34:55.032009 #24591:7a6f638]  INFO -- : Q-task_id([service_template_provision_task_10000000000187]) <AEMethod dialog_parser> Adding seq_id: 0 key: dialog_service_name value: remover 
[----] I, [2015-08-23T02:34:55.032922 #24591:7a6f638]  INFO -- : Q-task_id([service_template_provision_task_10000000000187]) <AEMethod dialog_parser> Adding seq_id: 0 key: flavor value: m1.small 
[----] I, [2015-08-23T02:34:55.033817 #24591:7a6f638]  INFO -- : Q-task_id([service_template_provision_task_10000000000187]) <AEMethod dialog_parser> Current task has dialog information
[----] I, [2015-08-23T02:34:55.068252 #24591:7a6f638]  INFO -- : Q-task_id([service_template_provision_task_10000000000187]) <AEMethod dialog_parser> parsed_dialog_options: "---\n0:\n  :service_name: remover\n  :dialog_service_name: remover\n  :flavor: m1.small\n"

This service has only one item, so index=1 would be correct.

Now, look to a similar request, after including the option_password_value method:

[----] I, [2015-08-24T11:04:41.684258 #24591:8bf0df8]  INFO -- : Q-task_id([service_template_provision_task_10000000000228]) <AEMethod dialog_parserv2> dialog_options: {"dialog_service_name"=>"teste1100", "dialog_option_0_flavor"=>"m1.small", "password::dialog_option_1_root_pw"=>"v2:{IkhPucxFYU6A2WaEFcNjYg==}", "request"=>"clone_to_service"}
[----] I, [2015-08-24T11:04:41.685765 #24591:8bf0df8]  INFO -- : Q-task_id([service_template_provision_task_10000000000228]) <AEMethod dialog_parserv2> Adding seq_id: 0 key: service_name value: teste1100 
[----] I, [2015-08-24T11:04:41.686670 #24591:8bf0df8]  INFO -- : Q-task_id([service_template_provision_task_10000000000228]) <AEMethod dialog_parserv2> Adding seq_id: 0 key: dialog_service_name value: teste1100 
[----] I, [2015-08-24T11:04:41.687644 #24591:8bf0df8]  INFO -- : Q-task_id([service_template_provision_task_10000000000228]) <AEMethod dialog_parserv2> Adding seq_id: 0 key: flavor value: m1.small 
[----] I, [2015-08-24T11:04:41.688677 #24591:8bf0df8]  INFO -- : Q-task_id([service_template_provision_task_10000000000228]) <AEMethod dialog_parserv2> Adding seq_id: 1 key: root_pw value: v2:{IkhPucxFYU6A2WaEFcNjYg==} 
[----] I, [2015-08-24T11:04:41.689666 #24591:8bf0df8]  INFO -- : Q-task_id([service_template_provision_task_10000000000228]) <AEMethod dialog_parserv2> Current task has dialog information
[----] I, [2015-08-24T11:04:41.725706 #24591:8bf0df8]  INFO -- : Q-task_id([service_template_provision_task_10000000000228]) <AEMethod dialog_parserv2> parsed_dialog_options: "---\n0:\n  :service_name: teste1100\n  :dialog_service_name: teste1100\n  :flavor: m1.small\n1:\n  :root_pw: v2:{IkhPucxFYU6A2WaEFcNjYg==}\n"

I hope this clarifies the issue.

Comment 5 Tina Fitzgerald 2015-08-24 18:36:13 UTC
Hi Vagner,

Thanks so much for the explanation. You are absolutely correct.

I didn't realize protected fields show up in the dialog that way.

Your script change is exactly what is needed.  I make an official fix for it.

Thanks again,
Tina

Comment 6 Vagner Farias 2015-08-24 19:00:58 UTC
Tina,

I was thinking that in order to keep backwards compatibility, the code for  option_password_value should be:

def option_password_value(dialog_key, dialog_value, options_hash)
  return false unless /^password::dialog_option_(?<sequence>\d*)_(?<option_key>.*)/i =~ dialog_key
  option_key='password::dialog_'+option_key
  add_hash_value(sequence.to_i, option_key.to_sym, dialog_value, options_hash)
  true
end

In order to allow using dialog_<option> and <option>, additional changes would be required. A simple but not optimized could be:

def option_password_value(dialog_key, dialog_value, options_hash)
  return false unless /^password::dialog_option_(?<sequence>\d*)_(?<option_key>.*)/i =~ dialog_key
  option_key_dialog='password::dialog_'+option_key
  option_key='password::'+option_key
  add_hash_value(sequence.to_i, option_key_dialog.to_sym, dialog_value, options_hash)
  add_hash_value(sequence.to_i, option_key.to_sym, dialog_value, options_hash)
  true
end

Comment 7 Tina Fitzgerald 2015-08-24 19:53:10 UTC
Hi Vagner,

Right, and we should support password::dialog_ without the _option_(?<sequence>\d*) format as well.

Regards,
Tina

Comment 8 CFME Bot 2015-08-26 19:26:32 UTC
New commit detected on manageiq/master:
https://github.com/ManageIQ/manageiq/commit/fbb5273f6e1166676fb4f6affc9871071ddc2f0a

commit fbb5273f6e1166676fb4f6affc9871071ddc2f0a
Author:     Tina Fitzgerald <tfitzger>
AuthorDate: Tue Aug 25 12:51:48 2015 -0400
Commit:     Tina Fitzgerald <tfitzger>
CommitDate: Tue Aug 25 15:20:53 2015 -0400

    Services, Add protected fields to dialog options hash.
    
    Recent modifications changed the behavior for protected fields.
    Previously, passwords and any other attributes would have been added to
    the options_hash by default. The recent modification change was to add
    only "dialog_" prefixed attributes which prevented the addition of the
    password attributes.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1256437

 .../Methods.class/__methods__/dialog_parser.rb     | 36 ++++++++++++++---
 .../unit/method_validation/dialog_parser_spec.rb   | 46 ++++++++++++++++++----
 2 files changed, 69 insertions(+), 13 deletions(-)

Comment 10 Aziza Karol 2015-11-04 09:31:35 UTC
Verified in version:5.5.0.9-beta2.20151102161742_5530c9a

Comment 12 errata-xmlrpc 2015-12-08 13:28:19 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2015:2551


Note You need to log in before you can comment on or make changes to this bug.