NEW: added hashing to fingerprint, added time/date
This commit is contained in:
parent
f2e622d36a
commit
5aae277ec2
5
dbfp.py
5
dbfp.py
|
@ -3,8 +3,8 @@
|
||||||
#
|
#
|
||||||
import argparse
|
import argparse
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from libs import fingerprint
|
from libs import fingerprint
|
||||||
|
from libs import toolbox
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -46,7 +46,8 @@ def parseArgs():
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
if (args.file):
|
if (args.file):
|
||||||
fileout = args.file + "_" + timestr + '.json'
|
filename = toolbox.ToolBox.parseFilename(args.file)
|
||||||
|
fileout = filename + "_" + timestr + '.json'
|
||||||
|
|
||||||
return (args.file, fileout, args.json, args.verbose)
|
return (args.file, fileout, args.json, args.verbose)
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,12 @@
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
import hashlib
|
||||||
|
import time
|
||||||
|
from libs import toolbox
|
||||||
|
|
||||||
delimeter = "|"
|
delimeter = "|"
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Database Schema
|
# Database Schema
|
||||||
# The SQLite database schema is stored in page 1 of the database (root page).
|
# The SQLite database schema is stored in page 1 of the database (root page).
|
||||||
|
@ -51,8 +53,11 @@ class DBSchema:
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print e
|
print e
|
||||||
return -2
|
return -2
|
||||||
|
# extract file name from path+filename
|
||||||
self.dbName = filein
|
try:
|
||||||
|
self.dbName = toolbox.ToolBox.parseFilenameIncExt(filein)
|
||||||
|
except:
|
||||||
|
self.dbName = filein
|
||||||
# read database schema
|
# read database schema
|
||||||
try:
|
try:
|
||||||
self.__readDatabase()
|
self.__readDatabase()
|
||||||
|
@ -110,7 +115,6 @@ class DBSchema:
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Compare the Table Definitions.
|
# Compare the Table Definitions.
|
||||||
# Compare Table 1 (Json table) to Table 2
|
# Compare Table 1 (Json table) to Table 2
|
||||||
|
@ -183,27 +187,31 @@ class DBSchema:
|
||||||
def writeFingerprint(self, filehandle):
|
def writeFingerprint(self, filehandle):
|
||||||
ahash = {}
|
ahash = {}
|
||||||
thash = {}
|
thash = {}
|
||||||
mhash = {}
|
|
||||||
dhash = {}
|
|
||||||
dmhash = {}
|
dmhash = {}
|
||||||
ahash['tables'] = thash
|
shash = {}
|
||||||
ahash['file-metadata'] = mhash
|
mhash = {}
|
||||||
ahash['db-config'] = dhash
|
ahash['tables'] = thash
|
||||||
|
ahash['sql-hashes'] = shash
|
||||||
ahash['db-metadata'] = dmhash
|
ahash['db-metadata'] = dmhash
|
||||||
|
ahash['file-metadata'] = mhash
|
||||||
|
|
||||||
# metadata
|
try:
|
||||||
mhash['scanner-name'] = 'dbfp'
|
timestr = time.strftime('%Y-%m-%d_%H%M%S', time.localtime(time.time()))
|
||||||
mhash['scanner-ver'] = self.scanner_ver
|
except:
|
||||||
|
timestr = ""
|
||||||
|
|
||||||
|
mhash['scan-date'] = timestr
|
||||||
mhash['format-ver'] = self.format_ver
|
mhash['format-ver'] = self.format_ver
|
||||||
|
mhash['scanner-ver'] = self.scanner_ver
|
||||||
# database configuration information
|
mhash['scanner-name'] = 'dbfp'
|
||||||
dhash['dn-name'] = self.dbName
|
mhash['dn-name'] = self.dbName
|
||||||
|
|
||||||
# tables
|
# tables
|
||||||
keys = self.tables.keys()
|
tables = self.tables.keys()
|
||||||
for key in keys:
|
for table in tables:
|
||||||
thash[key] = self.tables[key].fields
|
thash[table] = self.tables[table].fields
|
||||||
dmhash[key] = self.tables[key].SQLstr()
|
dmhash[table] = self.tables[table].SQLstr()
|
||||||
|
shash[table] = self.tables[table].sqlStrHash
|
||||||
|
|
||||||
json.dump(ahash, filehandle, sort_keys=True, indent=4)
|
json.dump(ahash, filehandle, sort_keys=True, indent=4)
|
||||||
|
|
||||||
|
@ -215,8 +223,6 @@ class DBSchema:
|
||||||
elif (errorCode == -3):
|
elif (errorCode == -3):
|
||||||
retval = "ERROR: problem reading database"
|
retval = "ERROR: problem reading database"
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -227,29 +233,41 @@ class TableDefinition:
|
||||||
|
|
||||||
tableschemaregex = r'\((.*)\)'
|
tableschemaregex = r'\((.*)\)'
|
||||||
|
|
||||||
|
#
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.tableName = ""
|
self.tableName = ""
|
||||||
self.sqlStr = ""
|
self.sqlStr = ""
|
||||||
self.fields = {}
|
self.sqlStrHash = ""
|
||||||
|
self.fields = {}
|
||||||
self.primarykeyFlag = False
|
self.primarykeyFlag = False
|
||||||
self.uniqueFlag = False
|
self.uniqueFlag = False
|
||||||
|
|
||||||
|
#
|
||||||
def loadTable(self, tableName, sqlStr):
|
def loadTable(self, tableName, sqlStr):
|
||||||
self.tableName = tableName
|
self.tableName = tableName
|
||||||
self.sqlStr = sqlStr
|
self.sqlStr = sqlStr
|
||||||
|
|
||||||
|
# hash the sql create string for quicker fingerprint matching
|
||||||
|
try:
|
||||||
|
m = hashlib.md5()
|
||||||
|
m.update(self.sqlStr)
|
||||||
|
self.sqlStrHash = m.hexdigest()
|
||||||
|
except:
|
||||||
|
print 'WARN: problem hashing sql string: "{}"'.format(self.sqlStr)
|
||||||
|
# parse the create string into a structured hash table
|
||||||
results = re.search(self.tableschemaregex, sqlStr)
|
results = re.search(self.tableschemaregex, sqlStr)
|
||||||
if results:
|
if results:
|
||||||
colstr = results.group(1)
|
colstr = results.group(1)
|
||||||
print "[[ TABLE: <" + tableName + "> ]]"
|
|
||||||
columns = colstr.split(',')
|
columns = colstr.split(',')
|
||||||
for col in columns:
|
for col in columns:
|
||||||
newField = self.__parseCreateStr(col.strip())
|
newField = self.__parseCreateStr(col.strip())
|
||||||
if newField:
|
if newField:
|
||||||
|
print "[[ TABLE: <{}> ] imported]".format(tableName)
|
||||||
self.fields[newField['name']] = newField
|
self.fields[newField['name']] = newField
|
||||||
|
else:
|
||||||
|
print "[[ TABLE: <{}> ] failed]".format(tableName)
|
||||||
|
|
||||||
|
#
|
||||||
def importTable(self, tbName, sqlStr, fields):
|
def importTable(self, tbName, sqlStr, fields):
|
||||||
self.tableName = tbName
|
self.tableName = tbName
|
||||||
self.sqlStr = sqlStr
|
self.sqlStr = sqlStr
|
||||||
|
@ -355,25 +373,26 @@ class TableDefinition:
|
||||||
self.uniqueFlag = False
|
self.uniqueFlag = False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
print 'WARN: field definition not recognized: "' + sqltext + '"'
|
print 'WARN: field definition not recognized: "{}"'.format(sqltext)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
print 'WARN: problem parsing sql create text: "{}"'.format(sqltext)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
#
|
||||||
def fields(self):
|
def fields(self):
|
||||||
return self.fields
|
return self.fields
|
||||||
|
|
||||||
|
#
|
||||||
def toJSON(self):
|
def toJSON(self):
|
||||||
print json.dumps(self.fields)
|
print json.dumps(self.fields)
|
||||||
|
|
||||||
|
#
|
||||||
def toFile(self, filehandle):
|
def toFile(self, filehandle):
|
||||||
json.dump(self.fields, filehandle, sort_keys=True, indent=4)
|
json.dump(self.fields, filehandle, sort_keys=True, indent=4)
|
||||||
|
|
||||||
|
#
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
global delimeter
|
global delimeter
|
||||||
retstr = ""
|
retstr = ""
|
||||||
|
@ -381,15 +400,15 @@ class TableDefinition:
|
||||||
|
|
||||||
return retstr
|
return retstr
|
||||||
|
|
||||||
|
#
|
||||||
def name(self):
|
def name(self):
|
||||||
return self.tableName
|
return self.tableName
|
||||||
|
|
||||||
|
#
|
||||||
def setSQLstr(self, str):
|
def setSQLstr(self, str):
|
||||||
return self.sqlStr
|
return self.sqlStr
|
||||||
|
|
||||||
|
#
|
||||||
def SQLstr(self):
|
def SQLstr(self):
|
||||||
return self.sqlStr
|
return self.sqlStr
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue