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


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. 
"/etc/vcl/vmhost01.key")
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 rsa_pub 
and rsa_key. I have also updated the javascript code to support 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 database.

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 UI:
$ cat vmhost.key.pub



--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira


Reply via email to