Fix bug 350 - Sensitive information recorded in openmano.log 29/5529/6
authorgcalvino <guillermo.calvinosanchez@altran.com>
Thu, 5 Oct 2017 16:21:25 +0000 (18:21 +0200)
committergcalvino <guillermo.calvinosanchez@altran.com>
Mon, 9 Oct 2017 14:01:25 +0000 (16:01 +0200)
Change-Id: I36c03de50d9f328beedde41d7f7c0698df053b72
Signed-off-by: gcalvino <guillermo.calvinosanchez@altran.com>
openmano
openmanod
osm_ro/db_base.py
osm_ro/httpserver.py
osm_ro/nfvo.py

index 8f5d7cc..abfdba3 100755 (executable)
--- 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)
index 6d0b32e..bb27d16 100755 (executable)
--- 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
 
index badf508..c8e5eb1 100644 (file)
@@ -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)
index d77846c..bb082d5 100644 (file)
@@ -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) 
index 049cb50..6ce84d4 100644 (file)
@@ -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