Add encryption support for authentication information in db.

This patch uses an encryption key generated in install.sh to perform
symmetrical encryption on sensitive authentication information stored
in the database for HA operations.

Change-Id: Ifd09f3f566ba3ebd941a6f453953576011b518b9
Signed-off-by: Ian Main <imain@redhat.com>
This commit is contained in:
Ian Main 2012-07-26 12:57:57 -07:00
parent e646e66728
commit 58cd52624b
4 changed files with 46 additions and 0 deletions

View File

@ -29,3 +29,5 @@ sql_connection = mysql://heat:heat@localhost/heat
db_backend=heat.db.sqlalchemy.api
rpc_backend=heat.openstack.common.rpc.impl_qpid
auth_encryption_key=%ENCRYPTION_KEY%

View File

@ -19,6 +19,7 @@ from sqlalchemy.orm.session import Session
from heat.common.exception import NotFound
from heat.db.sqlalchemy import models
from heat.db.sqlalchemy.session import get_session
from heat.engine import auth
def model_query(context, *args, **kwargs):
@ -202,12 +203,18 @@ def stack_delete(context, stack_id):
def user_creds_create(values):
user_creds_ref = models.UserCreds()
user_creds_ref.update(values)
user_creds_ref.password = auth.encrypt(values['password'])
user_creds_ref.service_password = auth.encrypt(values['service_password'])
user_creds_ref.aws_creds = auth.encrypt(values['aws_creds'])
user_creds_ref.save()
return user_creds_ref
def user_creds_get(user_creds_id):
result = model_query(None, models.UserCreds).get(user_creds_id)
result.password = auth.decrypt(result.password)
result.service_password = auth.decrypt(result.service_password)
result.aws_creds = auth.decrypt(result.aws_creds)
return result

View File

@ -16,6 +16,7 @@
import json
import httplib
import urlparse
import base64
from novaclient.v1_1 import client
from novaclient.exceptions import BadRequest
from novaclient.exceptions import NotFound
@ -23,9 +24,43 @@ from novaclient.exceptions import AuthorizationFailure
from heat.common import context
from heat.openstack.common import log as logging
from Crypto.Cipher import AES
from Crypto import Random
from heat.openstack.common import cfg
from heat.openstack.common import importutils
auth_opts = [
cfg.StrOpt('auth_encryption_key',
default='notgood',
help="Encryption key used for authentication info in database")
]
cfg.CONF.register_opts(auth_opts)
logger = logging.getLogger('heat.engine.auth')
def encrypt(auth_info):
if auth_info is None:
return None
iv = Random.new().read(AES.block_size)
cipher = AES.new(cfg.CONF.auth_encryption_key[:32], AES.MODE_CFB, iv)
res = base64.b64encode(iv + cipher.encrypt(auth_info))
return res
def decrypt(auth_info):
if auth_info is None:
return None
auth = base64.b64decode(auth_info)
iv = auth[:AES.block_size]
cipher = AES.new(cfg.CONF.auth_encryption_key[:32], AES.MODE_CFB, iv)
res = cipher.decrypt(auth[AES.block_size:])
return res
def authenticate(con, service_type='heat', service_name='heat'):
""" Authenticate a user context. This authenticates either an
EC2 style key context or a keystone user/pass context.

View File

@ -20,6 +20,8 @@ do
elif [ -f $CONF_DIR/$f ]; then
echo "not copying over $CONF_DIR/$f"
diff -u $CONF_DIR/$f $f
elif [ $f = 'heat-engine.conf' ]; then
cat $f | sed s/%ENCRYPTION_KEY%/`/bin/uuidgen`/ > $CONF_DIR/$f
else
cp $f $CONF_DIR
fi