From c62cfa5ac6f96c10a3efe14ee286755f4d25be54 Mon Sep 17 00:00:00 2001 From: gcalvino Date: Thu, 5 Oct 2017 18:21:25 +0200 Subject: [PATCH] Fix bug 350 - Sensitive information recorded in openmano.log Change-Id: I36c03de50d9f328beedde41d7f7c0698df053b72 Signed-off-by: gcalvino --- openmano | 5 +++-- openmanod | 2 +- osm_ro/db_base.py | 13 ++++++++---- osm_ro/httpserver.py | 48 ++++++++++++++++++++++++++++++++++++++------ osm_ro/nfvo.py | 6 +++--- 5 files changed, 58 insertions(+), 16 deletions(-) diff --git a/openmano b/openmano index 8f5d7cc4..abfdba39 100755 --- a/openmano +++ b/openmano @@ -28,7 +28,7 @@ openmano client used to interact with openmano-server (openmanod) """ __author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes" __date__ = "$09-oct-2014 09:09:48$" -__version__ = "0.4.21-r531" +__version__ = "0.4.22-r532" version_date = "Oct 2017" from argcomplete.completers import FilesCompleter @@ -1017,8 +1017,9 @@ def datacenter_attach(args): datacenter_dict['vim_password'] = args.password if args.config!=None: datacenter_dict["config"] = _load_file_or_yaml(args.config) + payload_req = json.dumps( {"datacenter": datacenter_dict }) - + #print payload_req URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter) diff --git a/openmanod b/openmanod index 6d0b32e9..bb27d166 100755 --- a/openmanod +++ b/openmanod @@ -48,7 +48,7 @@ import osm_ro __author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes" __date__ = "$26-aug-2014 11:09:29$" -__version__ = "0.5.30-r540" +__version__ = "0.5.31-r541" version_date = "Oct 2017" database_version = 27 # expected database schema version diff --git a/osm_ro/db_base.py b/osm_ro/db_base.py index badf5089..c8e5eb16 100644 --- a/osm_ro/db_base.py +++ b/osm_ro/db_base.py @@ -367,7 +367,7 @@ class db_base(): self.cur.execute(cmd) return uuid - def _new_row_internal(self, table, INSERT, add_uuid=False, root_uuid=None, created_time=0): + def _new_row_internal(self, table, INSERT, add_uuid=False, root_uuid=None, created_time=0, confidential_data=False): ''' Add one row into a table. It DOES NOT begin or end the transaction, so self.con.cursor must be created Attribute INSERT: dictionary with the key:value to insert @@ -403,7 +403,12 @@ class db_base(): ",".join(map(self.__tuple2db_format_set, INSERT.iteritems() )) if created_time: cmd += ",created_at=%f" % created_time - self.logger.debug(cmd) + if confidential_data: + index = cmd.find("SET") + subcmd = cmd[:index] + 'SET...' + self.logger.debug(subcmd) + else: + self.logger.debug(cmd) self.cur.execute(cmd) self.cur.rowcount return uuid @@ -415,7 +420,7 @@ class db_base(): rows = self.cur.fetchall() return rows - def new_row(self, table, INSERT, add_uuid=False, created_time=0): + def new_row(self, table, INSERT, add_uuid=False, created_time=0, confidential_data=False): ''' Add one row into a table. Attribute INSERT: dictionary with the key: value to insert @@ -432,7 +437,7 @@ class db_base(): try: with self.con: self.cur = self.con.cursor() - return self._new_row_internal(table, INSERT, add_uuid, None, created_time) + return self._new_row_internal(table, INSERT, add_uuid, None, created_time, confidential_data) except (mdb.Error, AttributeError) as e: self._format_error(e, tries) diff --git a/osm_ro/httpserver.py b/osm_ro/httpserver.py index d77846c8..bb082d5e 100644 --- a/osm_ro/httpserver.py +++ b/osm_ro/httpserver.py @@ -183,7 +183,7 @@ def format_out(data): #return data #json no style return json.dumps(data, indent=4) + "\n" -def format_in(default_schema, version_fields=None, version_dict_schema=None): +def format_in(default_schema, version_fields=None, version_dict_schema=None, confidential_data=False): """ Parse the content of HTTP request against a json_schema :param default_schema: The schema to be parsed by default if no version field is found in the client data. In None @@ -216,8 +216,11 @@ def format_in(default_schema, version_fields=None, version_dict_schema=None): # if client_data == None: # bottle.abort(HTTP_Bad_Request, "Content error, empty") # return - - logger.debug('IN: %s', yaml.safe_dump(client_data, explicit_start=True, indent=4, default_flow_style=False, + if confidential_data: + logger.debug('IN: %s', remove_clear_passwd (yaml.safe_dump(client_data, explicit_start=True, indent=4, default_flow_style=False, + tags=False, encoding='utf-8', allow_unicode=True))) + else: + logger.debug('IN: %s', yaml.safe_dump(client_data, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True) ) # look for the client provider version error_text = "Invalid content " @@ -341,7 +344,11 @@ def http_get_tenant_id(tenant_id): #obtain data logger.debug('FROM %s %s %s', bottle.request.remote_addr, bottle.request.method, bottle.request.url) try: - tenant = mydb.get_table_by_uuid_name('nfvo_tenants', tenant_id, "tenant") + from_ = 'nfvo_tenants' + select_, where_, limit_ = filter_query_string(bottle.request.query, None, + ('uuid', 'name', 'description', 'created_at')) + where_['uuid'] = tenant_id + tenant = mydb.get_rows(FROM=from_, SELECT=select_,WHERE=where_) #change_keys_http2db(content, http2db_tenant, reverse=True) convert_datetime2str(tenant) data={'tenant' : tenant} @@ -492,6 +499,12 @@ def http_get_datacenter_id(tenant_id, datacenter_id): try: config_dict = yaml.load(vim_tenant['config']) vim_tenant['config'] = config_dict + if vim_tenant['config'].get('admin_password'): + vim_tenant['config']['admin_password'] = "******" + if vim_tenant['config'].get('vcenter_password'): + vim_tenant['config']['vcenter_password'] = "******" + if vim_tenant['config'].get('nsx_password'): + vim_tenant['config']['nsx_password'] = "******" except Exception as e: logger.error("Exception '%s' while trying to load config information", str(e)) @@ -499,6 +512,12 @@ def http_get_datacenter_id(tenant_id, datacenter_id): try: config_dict = yaml.load(datacenter['config']) datacenter['config'] = config_dict + if datacenter['config'].get('admin_password'): + datacenter['config']['admin_password'] = "******" + if datacenter['config'].get('vcenter_password'): + datacenter['config']['vcenter_password'] = "******" + if datacenter['config'].get('nsx_password'): + datacenter['config']['nsx_password'] = "******" except Exception as e: logger.error("Exception '%s' while trying to load config information", str(e)) #change_keys_http2db(content, http2db_datacenter, reverse=True) @@ -518,7 +537,7 @@ def http_post_datacenters(): '''insert a datacenter into the catalogue. ''' #parse input data logger.debug('FROM %s %s %s', bottle.request.remote_addr, bottle.request.method, bottle.request.url) - http_content,_ = format_in( datacenter_schema ) + http_content,_ = format_in(datacenter_schema, confidential_data=True) r = utils.remove_extra_items(http_content, datacenter_schema) if r: logger.debug("Remove received extra items %s", str(r)) @@ -860,7 +879,7 @@ def http_associate_datacenters(tenant_id, datacenter_id): '''associate an existing datacenter to a this tenant. ''' logger.debug('FROM %s %s %s', bottle.request.remote_addr, bottle.request.method, bottle.request.url) #parse input data - http_content,_ = format_in( datacenter_associate_schema ) + http_content,_ = format_in(datacenter_associate_schema, confidential_data=True) r = utils.remove_extra_items(http_content, datacenter_associate_schema) if r: logger.debug("Remove received extra items %s", str(r)) @@ -1533,6 +1552,23 @@ def http_get_instance_scenario_action(tenant_id, instance_id, action_id=None): logger.error("Unexpected exception: ", exc_info=True) bottle.abort(HTTP_Internal_Server_Error, type(e).__name__ + ": " + str(e)) +def remove_clear_passwd(data): + """ + Removes clear passwords from the data received + :param data: data with clear password + :return: data without the password information + """ + + passw = ['password: ', 'passwd: '] + + for pattern in passw: + init = data.find(pattern) + while init != -1: + end = data.find('\n', init) + data = data[:init] + '{}******'.format(pattern) + data[end:] + init += 1 + init = data.find(pattern, init) + return data @bottle.error(400) @bottle.error(401) diff --git a/osm_ro/nfvo.py b/osm_ro/nfvo.py index 049cb50c..6ce84d45 100644 --- a/osm_ro/nfvo.py +++ b/osm_ro/nfvo.py @@ -3660,7 +3660,7 @@ def new_tenant(mydb, tenant_dict): pub_key, priv_key = create_RO_keypair(tenant_uuid) tenant_dict['RO_pub_key'] = pub_key tenant_dict['encrypted_RO_priv_key'] = priv_key - mydb.new_row("nfvo_tenants", tenant_dict) + mydb.new_row("nfvo_tenants", tenant_dict, confidential_data=True) except db_base_Exception as e: raise NfvoException("Error creating the new tenant: {} ".format(tenant_dict['name']) + str(e), HTTP_Internal_Server_Error) return tenant_uuid @@ -3689,7 +3689,7 @@ def new_datacenter(mydb, datacenter_descriptor): # file.close(module_info[0]) raise NfvoException("Incorrect datacenter type '{}'. Plugin '{}'.py not installed".format(datacenter_type, module), HTTP_Bad_Request) - datacenter_id = mydb.new_row("datacenters", datacenter_descriptor, add_uuid=True) + datacenter_id = mydb.new_row("datacenters", datacenter_descriptor, add_uuid=True, confidential_data=True) return datacenter_id @@ -3800,7 +3800,7 @@ def associate_datacenter_to_tenant(mydb, nfvo_tenant, datacenter, vim_tenant_id= datacenter_tenants_dict["datacenter_id"] = datacenter_id if config: datacenter_tenants_dict["config"] = yaml.safe_dump(config, default_flow_style=True, width=256) - id_ = mydb.new_row('datacenter_tenants', datacenter_tenants_dict, add_uuid=True) + id_ = mydb.new_row('datacenter_tenants', datacenter_tenants_dict, add_uuid=True, confidential_data=True) datacenter_tenants_dict["uuid"] = id_ #fill tenants_datacenters table -- 2.17.1