summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIkram Ikramullah <ikram@research.att.com>2020-01-23 11:53:16 -0500
committerdhebeha <dhebeha.mj71@wipro.com>2020-01-24 21:55:18 +0530
commit920b9ff54e4b75973b27438158030c5a4736ffc6 (patch)
treeaf74a97ee1ae568d11164582a3478b7111941d77
parent9f8f7046d3978b6dbd05c7e5ad645b3dd9201249 (diff)
Encryption/Decryption utility
Putting in the encryption/decryption utility. Hit cipher-util inside the virutalenv to see its usage. The work is still in progress. Issue-ID: OPTFRA-683 Signed-off-by: dhebeha <dhebeha.mj71@wipro.com> Change-Id: I7a4845c1318db8d14f1efbb0f98e785adf214e06
-rw-r--r--api_paste.ini26
-rwxr-xr-xconductor.conf3
-rw-r--r--conductor/conductor/api/adapters/aaf/aaf_authentication.py6
-rw-r--r--conductor/conductor/cmd/encryptionUtil.py54
-rw-r--r--conductor/conductor/common/music/api.py14
-rw-r--r--conductor/conductor/common/utils/basic_auth_util.py2
-rw-r--r--conductor/conductor/common/utils/cipherUtils.py77
-rw-r--r--conductor/conductor/data/plugins/inventory_provider/aai.py5
-rw-r--r--conductor/conductor/data/plugins/service_controller/sdnc.py3
-rw-r--r--conductor/conductor/data/plugins/vim_controller/multicloud.py2
-rw-r--r--conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py2
-rw-r--r--conductor/conductor/tests/unit/music/test_api.py2
-rw-r--r--conductor/requirements.txt3
-rw-r--r--conductor/setup.cfg1
-rwxr-xr-xpreload_secrets.yaml10
15 files changed, 187 insertions, 23 deletions
diff --git a/api_paste.ini b/api_paste.ini
new file mode 100644
index 0000000..4299f46
--- /dev/null
+++ b/api_paste.ini
@@ -0,0 +1,26 @@
+# Conductor API WSGI Pipeline
+# Define the filters that make up the pipeline for processing WSGI requests
+# Note: This pipeline is PasteDeploy's term rather than Conductor's pipeline
+# used for processing samples
+
+# Remove authtoken from the pipeline if you don't want to use keystone authentication
+[pipeline:main]
+pipeline = cors http_proxy_to_wsgi api-server
+#pipeline = cors http_proxy_to_wsgi request_id authtoken api-server
+
+[app:api-server]
+paste.app_factory = conductor.api.app:app_factory
+
+#[filter:authtoken]
+#paste.filter_factory = keystonemiddleware.auth_token:filter_factory
+
+#[filter:request_id]
+#paste.filter_factory = oslo_middleware:RequestId.factory
+
+[filter:cors]
+paste.filter_factory = oslo_middleware.cors:filter_factory
+oslo_config_project = conductor
+
+[filter:http_proxy_to_wsgi]
+paste.filter_factory = oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory
+oslo_config_project = conductor
diff --git a/conductor.conf b/conductor.conf
index b4f09b1..79ec774 100755
--- a/conductor.conf
+++ b/conductor.conf
@@ -131,6 +131,9 @@
#fatal_deprecations = false
+[auth]
+aapkey = h@ss3crtky400fdntc#001
+
[aaf_api]
#
diff --git a/conductor/conductor/api/adapters/aaf/aaf_authentication.py b/conductor/conductor/api/adapters/aaf/aaf_authentication.py
index a85ac11..fb0b9ab 100644
--- a/conductor/conductor/api/adapters/aaf/aaf_authentication.py
+++ b/conductor/conductor/api/adapters/aaf/aaf_authentication.py
@@ -24,7 +24,7 @@ import os
from conductor.common import rest
from conductor.i18n import _LE, _LI
-from conductor import __file__ as conductor_root
+from conductor.common.utils import cipherUtils
from oslo_log import log
LOG = log.getLogger(__name__)
@@ -83,7 +83,7 @@ def clear_cache():
def authenticate(uid, passwd):
aafUser = None
username = CONF.conductor_api.username
- password = CONF.conductor_api.password
+ password = cipherUtils.AESCipher.get_instance().decrypt(CONF.conductor_api.password)
if username == uid and password == passwd:
aafUser = CONF.aaf_api.aaf_conductor_user
else:
@@ -159,7 +159,7 @@ def remote_api(aafUser):
"server_url": server_url,
"retries": CONF.aaf_api.aaf_retries,
"username": CONF.aaf_api.username,
- "password": CONF.aaf_api.password,
+ "password": cipherUtils.AESCipher.get_instance().decrypt(CONF.aaf_api.password),
"log_debug": LOG.debug,
"read_timeout": CONF.aaf_api.aaf_timeout,
"cert_file": CONF.aaf_api.aaf_cert_file,
diff --git a/conductor/conductor/cmd/encryptionUtil.py b/conductor/conductor/cmd/encryptionUtil.py
new file mode 100644
index 0000000..179d366
--- /dev/null
+++ b/conductor/conductor/cmd/encryptionUtil.py
@@ -0,0 +1,54 @@
+#
+# -------------------------------------------------------------------------
+# Copyright (c) 2015-2018 AT&T Intellectual Property
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# -------------------------------------------------------------------------
+#
+
+import sys
+from conductor.common.utils import cipherUtils
+
+
+def main():
+
+ if len(sys.argv) != 4:
+ print("Invalid input - usage --> (options(encrypt/decrypt) input-value with-key)")
+ return
+
+ enc_dec = sys.argv[1]
+ valid_option_values = ['encrypt', 'decrypt']
+ if enc_dec not in valid_option_values:
+ print("Invalid input - usage --> (options(encrypt/decrypt) input-value with-key)")
+ print("Option value can only be one of {}".format(valid_option_values))
+ print("You entered '{}'".format(enc_dec))
+ return
+
+ input_string = sys.argv[2]
+ with_key = sys.argv[3]
+
+ print("You've requested '{}' to be '{}ed' using key '{}'".format(input_string, enc_dec, with_key))
+ print("You can always perform the reverse operation (encrypt/decrypt) using the same key"
+ "to be certain you get the same results back'")
+
+ util = cipherUtils.AESCipher.get_instance(with_key)
+ #util = CipherUtil.AESCipher(with_key)
+
+ if enc_dec.lower() == 'encrypt':
+ result = util.encrypt(input_string)
+ else:
+ result = util.decrypt(input_string)
+
+ print("Your result: {}".format(result))
+
diff --git a/conductor/conductor/common/music/api.py b/conductor/conductor/common/music/api.py
index 0ca4301..5929b58 100644
--- a/conductor/conductor/common/music/api.py
+++ b/conductor/conductor/common/music/api.py
@@ -30,6 +30,7 @@ from oslo_log import log
from conductor.common import rest
from conductor.common.utils import basic_auth_util
from conductor.i18n import _LE, _LI # pylint: disable=W0212
+from conductor.common.utils import cipherUtils
LOG = log.getLogger(__name__)
@@ -137,22 +138,23 @@ class MusicAPI(object):
}
self.rest = rest.REST(**kwargs)
+ music_pwd = cipherUtils.AESCipher.get_instance().decrypt(CONF.music_api.aafpass)
# Set one parameter for connection mode
# Currently depend on music version
- if (CONF.music_api.enable_https_mode):
+ if CONF.music_api.enable_https_mode:
self.rest.server_url = 'https://{}:{}/{}'.format(
host, port, version, path.rstrip('/').lstrip('/'))
self.rest.session.verify = CONF.music_api.certificate_authority_bundle_file
- if(CONF.music_api.music_new_version):
- MUSIC_version = CONF.music_api.music_version.split(".")
+ if CONF.music_api.music_new_version:
+ music_version = CONF.music_api.music_version.split(".")
self.rest.session.headers['content-type'] = 'application/json'
- self.rest.session.headers['X-minorVersion'] = MUSIC_version[1]
- self.rest.session.headers['X-patchVersion'] = MUSIC_version[2]
+ self.rest.session.headers['X-minorVersion'] = music_version[1]
+ self.rest.session.headers['X-patchVersion'] = music_version[2]
self.rest.session.headers['ns'] = CONF.music_api.aafns
self.rest.session.headers['userId'] = CONF.music_api.aafuser
- self.rest.session.headers['password'] = CONF.music_api.aafpass
+ self.rest.session.headers['password'] = music_pwd
self.rest.session.headers['Authorization'] = basic_auth_util.encode(CONF.music_api.aafuser,
CONF.music_api.aafpass)
diff --git a/conductor/conductor/common/utils/basic_auth_util.py b/conductor/conductor/common/utils/basic_auth_util.py
index a94418f..d4cdbac 100644
--- a/conductor/conductor/common/utils/basic_auth_util.py
+++ b/conductor/conductor/common/utils/basic_auth_util.py
@@ -28,7 +28,7 @@ LOG = log.getLogger(__name__)
def encode(user_id, password):
""" Provide the basic authencation encoded value in an 'Authorization' Header """
- user_pass = user_id + ':' + password
+ user_pass = str(user_id) + ":" + str(password)
base64_val = base64.b64encode(user_pass)
authorization_val = _LE("Basic {}".format(base64_val))
diff --git a/conductor/conductor/common/utils/cipherUtils.py b/conductor/conductor/common/utils/cipherUtils.py
new file mode 100644
index 0000000..6ee6c58
--- /dev/null
+++ b/conductor/conductor/common/utils/cipherUtils.py
@@ -0,0 +1,77 @@
+#
+# -------------------------------------------------------------------------
+# Copyright (c) 2015-2017 AT&T Intellectual Property
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# -------------------------------------------------------------------------
+#
+
+import base64
+import hashlib
+from Crypto import Random
+from Crypto.Cipher import AES
+from oslo_config import cfg
+
+CONF = cfg.CONF
+
+cipher_opts = [
+ cfg.StrOpt('appkey',
+ default='ch00se@g003ntropy',
+ help='Master key to secure other secrets')
+]
+
+CONF.register_opts(cipher_opts, group='auth')
+
+
+class AESCipher(object):
+ __instance = None
+
+ @staticmethod
+ def get_instance(key = None):
+ if AESCipher.__instance is None:
+ print ('Creating the singleton instance')
+ AESCipher(key)
+ return AESCipher.__instance
+
+ def __init__(self, key=None):
+ if AESCipher.__instance is not None:
+ raise Exception("This class is a singleton!")
+ else:
+ AESCipher.__instance = self
+
+ self.bs = 32
+ if key is None:
+ key = CONF.auth.appkey.encode()
+
+ self.key = hashlib.sha256(key.encode()).digest()
+
+ def encrypt(self, raw):
+ raw = self._pad(raw)
+ iv = Random.new().read(AES.block_size)
+ cipher = AES.new(self.key, AES.MODE_CBC, iv)
+ return base64.b64encode(iv + cipher.encrypt(raw))
+
+ def decrypt(self, enc):
+ enc = base64.b64decode(enc)
+ iv = enc[:AES.block_size]
+ cipher = AES.new(self.key, AES.MODE_CBC, iv)
+ return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')
+
+ def _pad(self, s):
+ return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)
+
+ @staticmethod
+ def _unpad(s):
+ return s[:-ord(s[len(s)-1:])]
+
diff --git a/conductor/conductor/data/plugins/inventory_provider/aai.py b/conductor/conductor/data/plugins/inventory_provider/aai.py
index 26b390a..f49d526 100644
--- a/conductor/conductor/data/plugins/inventory_provider/aai.py
+++ b/conductor/conductor/data/plugins/inventory_provider/aai.py
@@ -23,11 +23,10 @@ import uuid
import copy
import json
-from oslo_config import cfg
-from oslo_log import log
from conductor.common import rest
from conductor.data.plugins import constants
+from conductor.common.utils import cipherUtils
from conductor.data.plugins.inventory_provider import base
from conductor.data.plugins.inventory_provider import hpa_utils
from conductor.data.plugins.triage_translator.triage_translator import TraigeTranslator
@@ -111,7 +110,7 @@ class AAI(base.InventoryProviderBase):
self.timeout = self.conf.aai.aai_rest_timeout
self.retries = self.conf.aai.aai_retries
self.username = self.conf.aai.username
- self.password = self.conf.aai.password
+ self.password = cipherUtils.AESCipher.get_instance().decrypt(self.conf.aai.password)
self.triage_translator=TraigeTranslator()
# Cache is initially empty
diff --git a/conductor/conductor/data/plugins/service_controller/sdnc.py b/conductor/conductor/data/plugins/service_controller/sdnc.py
index 5e4e8a0..1571b41 100644
--- a/conductor/conductor/data/plugins/service_controller/sdnc.py
+++ b/conductor/conductor/data/plugins/service_controller/sdnc.py
@@ -23,6 +23,7 @@ from oslo_config import cfg
from oslo_log import log
from conductor.common import rest
+from conductor.common.utils import cipherUtils
from conductor.data.plugins.service_controller import base
from conductor.i18n import _LE
@@ -66,7 +67,7 @@ class SDNC(base.ServiceControllerBase):
self.conf = CONF
self.base = self.conf.sdnc.server_url.rstrip('/')
- self.password = self.conf.sdnc.password
+ self.password = cipherUtils.AESCipher.get_instance().decrypt(self.conf.sdnc.password)
self.timeout = self.conf.sdnc.sdnc_rest_timeout
self.verify = False
self.retries = self.conf.sdnc.sdnc_retries
diff --git a/conductor/conductor/data/plugins/vim_controller/multicloud.py b/conductor/conductor/data/plugins/vim_controller/multicloud.py
index 5c2b5f7..b5c7a66 100644
--- a/conductor/conductor/data/plugins/vim_controller/multicloud.py
+++ b/conductor/conductor/data/plugins/vim_controller/multicloud.py
@@ -115,7 +115,7 @@ class MULTICLOUD(base.VimControllerBase):
"read_timeout": self.timeout,
}
self.rest = rest.REST(**kwargs)
- if(self.conf.multicloud.enable_https_mode):
+ if self.conf.multicloud.enable_https_mode:
self.rest.server_url = self.base[:4]+'s'+self.base[4:]
self.rest.session.verify =self.conf.multicloud.certificate_authority_bundle_file
diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py b/conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py
index 9d1245d..5b9984a 100644
--- a/conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py
+++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py
@@ -30,7 +30,7 @@ from oslo_config import cfg
class TestAAI(unittest.TestCase):
def setUp(self):
-
+ cfg.CONF.set_override('password', '4HyU6sI+Tw0YMXgSHr5sJ5C0UTkeBaxXoxQqWuSVFugls7sQnaAXp4zMfJ8FKFrH', 'aai')
CONF = cfg.CONF
CONF.register_opts(aai.AAI_OPTS, group='aai')
self.conf = CONF
diff --git a/conductor/conductor/tests/unit/music/test_api.py b/conductor/conductor/tests/unit/music/test_api.py
index 90bd57d..285d0d7 100644
--- a/conductor/conductor/tests/unit/music/test_api.py
+++ b/conductor/conductor/tests/unit/music/test_api.py
@@ -23,12 +23,12 @@ from conductor.common import rest
from conductor.common.music.api import MusicAPI
from oslo_config import cfg
-
class TestMusicApi(unittest.TestCase):
def setUp(self):
cfg.CONF.set_override('debug', True, 'music_api')
cfg.CONF.set_override('certificate_authority_bundle_file', '../AAF_RootCA.cer', 'music_api')
+ cfg.CONF.set_override('aafpass', 'U5AudaTTC/DYQ29Q7qiXx/iwsgwV+dV7v7/Q5TDBh1URPwqAGECnbVmUkOynLjTY', 'music_api')
self.mock_lock_id = mock.patch.object(MusicAPI, '_lock_id_create',
return_value='12345678')
self.mock_lock_acquire = mock.patch.object(MusicAPI,
diff --git a/conductor/requirements.txt b/conductor/requirements.txt
index d6d413d..6ad13e2 100644
--- a/conductor/requirements.txt
+++ b/conductor/requirements.txt
@@ -25,4 +25,5 @@ stevedore>=1.9.0 # Apache-2.0, also required by oslo.config
WebOb>=1.2.3 # MIT
onapsmsclient>=0.0.4
Flask>=0.11.1
-prometheus-client>=0.3.1 \ No newline at end of file
+prometheus-client>=0.3.1
+pycrypto==2.6.1
diff --git a/conductor/setup.cfg b/conductor/setup.cfg
index 5152285..9d2298d 100644
--- a/conductor/setup.cfg
+++ b/conductor/setup.cfg
@@ -63,6 +63,7 @@ console_scripts =
conductor-data = conductor.cmd.data:main
conductor-solver = conductor.cmd.solver:main
conductor-reservation = conductor.cmd.reservation:main
+ cipher-util = conductor.cmd.encryptionUtil:main
conductor.inventory_provider.plugin =
aai = conductor.data.plugins.inventory_provider.aai:AAI
diff --git a/preload_secrets.yaml b/preload_secrets.yaml
index 3ec1b92..62a00f2 100755
--- a/preload_secrets.yaml
+++ b/preload_secrets.yaml
@@ -6,22 +6,22 @@ secrets:
- name: aai
values:
username: oof@oof.onap.org
- password: demo123456!
+ password: 4HyU6sI+Tw0YMXgSHr5sJ5C0UTkeBaxXoxQqWuSVFugls7sQnaAXp4zMfJ8FKFrH
- name: conductor_api
values:
username: admin1
- password: plan.15
+ password: /90ON7wZM2SfItrVXix57TpCyMMR/EUxrhE9Vbo62yJyNfcrpEfsYEZKqTOXHmkn
- name: sdnc
values:
username: admin
- password: Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+ password: jI4D86X3lZIZILHLpHIWVsJeYODWpcEHlkfswE3pHF0UKjwp36euiwILMyV1jmyNjFF37we3n9VKZFc2UYO6Xsrfe2wBfwhod9Ft4rZEqFo
- name: music_api
values:
aafuser: conductor
- aafpass: c0nduct0r
+ aafpass: U5AudaTTC/DYQ29Q7qiXx/iwsgwV+dV7v7/Q5TDBh1URPwqAGECnbVmUkOynLjTY
aafns: conductor
- name: aaf_api
values:
username: aaf_admin@people.osaaf.org
- password: demo123456!
+ password: IE4lBg4NmcIikB7RLjnXbyVeU2jxuKUWqX1ZfEzCcBAe0wDV87xFGTYTNoTzptXn
aaf_conductor_user: oof@oof.onap.org