On Thu, Mar 15, 2012 at 2:35 PM, Aaron Coburn (Updated) (JIRA)
> Aaron Coburn updated VCL-560:
> Attachment: vmprofile.alter.sql
>> cleartext password stored in VMProfile table
>> Key: VCL-560
>> URL: https://issues.apache.org/jira/browse/VCL-560
>> Project: VCL
>> Issue Type: Bug
>> Components: database, vcld (backend), web gui (frontend)
>> Affects Versions: 2.2.1
>> Reporter: Aaron Coburn
>> Labels: security
>> Attachments: managementnode.patch, vmprofile.alter.sql, web.patch
>> To provide some background, we are setting up a VCL system for several
>> institutions, using multiple, physically distributed management nodes (each
>> located at different institutions). Each management node will control its
>> own VMware infrastructure of one or more hosts while all accessing the
>> central vcl database.
>> As you know, each VMhost draws its configuration information from the
>> `vmprofile` table, including information for accessing that VMhost
>> infrastructure. For vSphere-based systems, the management node extracts
>> login credentials from the `username` and `password` fields. The other API
>> modules do not require the password field. The problem, however, is that the
>> passwords are stored in cleartext.
>> Yes, cleartext.
>> This means that if the VCL is using the vSphere API, anyone from institution
>> X who has access to the VCL database could easily access the login
>> credentials for the VM Host(s) at institution Y. The other issue is that
>> these passwords are being transferred in cleartext between database and
>> management nodes, so anyone listening in on the wire could also,
>> potentially, gain access to the VMware infrastructure. Furthermore, while
>> the passwords are masked in the web UI behind 'password' fields, the ajax
>> call that populates those fields can easily be inspected in order to get the
>> actual text. I can see how this isn't such an issue if a VCL system is
>> running within a single institution inside a single network, but in our
>> case, that is not the situation.
>> A compounding issue is that the web UI allows admins to enter the passwords
>> for VMhost profiles, which means that there would need to be a mechanism for
>> making sure that the password for the VMprofile at institution X isn't
>> encrypted using the same key as the password for the corresponding profile
>> at institution Y.
>> To solve this, I have written some code that performs asymmetric key
>> encryption so that the passwords are stored in a more secure format.
>> Attached are the relevant patch files.
>> Effectively, what I have done is add three fields to the `vmprofile` table:
>> rsa_pub: a string containing a public key
>> rsa_key: the location of the corresponding private key (i.e.
>> encrypted_passwd: the RSA-encrypted password. (There isn't a strong reason
>> to have this be a separate field from the existing password field, but
>> separating the two made it easier to test.)
>> Next, I added additional input fields in the VMProfile UI for accepting
>> this. If an RSA public key is supplied, the vm.php file will encrypt the
>> incoming password using the openssl_* functions that come with most
>> distributions of PHP. The encrypted password is stored in the
>> `encrypted_passwd` field and the `password` field is set to NULL. This
>> causes the web UI not to show the masked passwords, which is a behavior that
>> I preferred to have, though others may prefer something different. The
>> encryption function was put in utils.php and called
>> encryptDataAsymmetric($data, $public_key) -- it more or less follows the
>> style of the existing encryptData($data) function.
>> Finally, vcld needs to be able to decrypt the data, so I added some code to
>> VCL::utils. First, I expanded the vmhost/vmprofile SQL statement to include
>> the new rsa_key and encrypted_passwd fields. Then, vcld will check whether a
>> key exists in the location specified, and if so, it will use that key to
>> decrypt the password. The decrypted password is then put into the data
>> structure in the expected location: vmprofile.password
>> The perl code relies on one additional library: Crypt::OpenSSL::RSA, which
>> has its own set of dependencies, but these are all available on the EPEL
>> repository or CPAN. I would add that the Crypt::OpenSSL::RSA library is
>> quite mature and well maintained.
>> I wrote this code so that it is entirely optional to encrypt passwords. If
>> an RSA public key is not attached, then no encryption is performed: the
>> password is stored, as before, in cleartext in vmprofile.password. If the
>> private keyfile does not exist on a management node, then no decryption is
>> performed, and the existing value of vmprofile.password is used. I should
>> also add that the encrypted passwords are stored in hexadecimal format,
>> since that is easier to deal with when it comes to storing them in a
>> In order to use this code, one will need to generate RSA keys ahead of time
>> like so:
>> $ openssl genrsa -out vmhost.key 1024
>> $ openssl rsa -in vmhost.key -pubout > vmhost.key.pub
>> (One can generate a larger key, if desired, by specifying a larger bit size
>> in the first command.)
>> It is a good idea to control access to the private key:
>> $ chown root.root vmhost.key
>> $ chmod 600 vmhost.key
>> An admin will also need the contents of the public key to enter into the web
>> $ cat vmhost.key.pub
> This message is automatically generated by JIRA.
> If you think it was sent incorrectly, please contact your JIRA
> For more information on JIRA, see: http://www.atlassian.com/software/jira
Virtual Computing Lab
NC State University
All electronic mail messages in connection with State business which
are sent to or received by this account are subject to the NC Public
Records Law and may be disclosed to third parties.