diff --git a/etc/heat-engine.conf b/etc/heat-engine.conf index f41b712999..0998d2e9cf 100644 --- a/etc/heat-engine.conf +++ b/etc/heat-engine.conf @@ -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% diff --git a/heat/db/sqlalchemy/api.py b/heat/db/sqlalchemy/api.py index 7365dfd51a..09ab1cf516 100644 --- a/heat/db/sqlalchemy/api.py +++ b/heat/db/sqlalchemy/api.py @@ -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 diff --git a/heat/engine/auth.py b/heat/engine/auth.py index bd547b0c56..a4be7ef0a4 100644 --- a/heat/engine/auth.py +++ b/heat/engine/auth.py @@ -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. diff --git a/install.sh b/install.sh index b58f7153ac..946198b2bb 100755 --- a/install.sh +++ b/install.sh @@ -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