1717
1818from lib .core .common import unArrayizeValue
1919from lib .core .convert import base64pickle
20- from lib .core .convert import base64unpickle
2120from lib .core .convert import hexencode
2221from lib .core .convert import dejsonize
2322from lib .core .convert import jsonize
2423from lib .core .data import conf
24+ from lib .core .data import kb
2525from lib .core .data import paths
2626from lib .core .data import logger
2727from lib .core .datatype import AttribDict
2828from lib .core .defaults import _defaults
29+ from lib .core .enums import CONTENT_STATUS
2930from lib .core .log import LOGGER_HANDLER
3031from lib .core .optiondict import optDict
3132from lib .core .subprocessng import Popen
4748# Local global variables
4849adminid = ""
4950db = None
51+ db_filepath = tempfile .mkstemp (prefix = "sqlmapipc-" , text = False )[1 ]
5052tasks = dict ()
5153
5254# API objects
5355class Database (object ):
56+ global db_filepath
57+
5458 LOGS_TABLE = "CREATE TABLE logs(id INTEGER PRIMARY KEY AUTOINCREMENT, taskid INTEGER, time TEXT, level TEXT, message TEXT)"
5559 DATA_TABLE = "CREATE TABLE data(id INTEGER PRIMARY KEY AUTOINCREMENT, taskid INTEGER, status INTEGER, content_type INTEGER, value TEXT)"
5660 ERRORS_TABLE = "CREATE TABLE errors(id INTEGER PRIMARY KEY AUTOINCREMENT, taskid INTEGER, error TEXT)"
5761
58- def __init__ (self ):
59- pass
60-
61- def create (self ):
62- _ , self .database = tempfile .mkstemp (prefix = "sqlmapipc-" , text = False )
63- logger .debug ("IPC database: %s" % self .database )
62+ def __init__ (self , database = None ):
63+ if database :
64+ self .database = database
65+ else :
66+ self .database = db_filepath
6467
65- def connect (self ):
68+ def connect (self , who = "server" ):
6669 self .connection = sqlite3 .connect (self .database , timeout = 3 , isolation_level = None )
6770 self .cursor = self .connection .cursor ()
71+ logger .debug ("REST-JSON API %s connected to IPC database" % who )
6872
6973 def disconnect (self ):
7074 self .cursor .close ()
@@ -79,18 +83,13 @@ def execute(self, statement, arguments=None):
7983 if statement .lstrip ().upper ().startswith ("SELECT" ):
8084 return self .cursor .fetchall ()
8185
82- def initialize (self ):
83- self .create ()
84- self .connect ()
86+ def init (self ):
8587 self .execute (self .LOGS_TABLE )
8688 self .execute (self .DATA_TABLE )
8789 self .execute (self .ERRORS_TABLE )
8890
89- def get_filepath (self ):
90- return self .database
91-
9291class Task (object ):
93- global db
92+ global db_filepath
9493
9594 def __init__ (self , taskid ):
9695 self .process = None
@@ -109,7 +108,7 @@ def initialize_options(self, taskid):
109108 # Let sqlmap engine knows it is getting called by the API, the task ID and the file path of the IPC database
110109 self .options .api = True
111110 self .options .taskid = taskid
112- self .options .database = db . get_filepath ()
111+ self .options .database = db_filepath
113112
114113 # Enforce batch mode and disable coloring
115114 self .options .batch = True
@@ -174,12 +173,25 @@ def __init__(self, taskid, messagetype="stdout"):
174173 else :
175174 sys .stderr = self
176175
177- def write (self , value , status = None , content_type = None ):
176+ def write (self , value , status = CONTENT_STATUS . IN_PROGRESS , content_type = None ):
178177 if self .messagetype == "stdout" :
179- #conf.database_cursor.execute("INSERT INTO data VALUES(NULL, ?, ?, ?, ?)",
180- # (self.taskid, status, content_type, base64pickle(value)))
181- conf .database_cursor .execute ("INSERT INTO data VALUES(NULL, ?, ?, ?, ?)" ,
182- (self .taskid , status , content_type , jsonize (value )))
178+ if content_type is None :
179+ content_type = 99
180+
181+ if status == CONTENT_STATUS .IN_PROGRESS :
182+ output = conf .database_cursor .execute ("SELECT id, value FROM data WHERE taskid = ? AND status = ? AND content_type = ? LIMIT 0,1" ,
183+ (self .taskid , status , content_type ))
184+
185+ if len (output ) == 0 :
186+ conf .database_cursor .execute ("INSERT INTO data VALUES(NULL, ?, ?, ?, ?)" ,
187+ (self .taskid , status , content_type , jsonize (value )))
188+ else :
189+ new_value = "%s%s" % (output [0 ][1 ], value )
190+ conf .database_cursor .execute ("UPDATE data SET value = ? WHERE id = ?" ,
191+ (jsonize (new_value ), output [0 ][0 ]))
192+ else :
193+ conf .database_cursor .execute ("INSERT INTO data VALUES(NULL, ?, ?, ?, ?)" ,
194+ (self .taskid , status , content_type , jsonize (value )))
183195 else :
184196 conf .database_cursor .execute ("INSERT INTO errors VALUES(NULL, ?, ?)" ,
185197 (self .taskid , str (value ) if value else "" ))
@@ -205,8 +217,11 @@ def emit(self, record):
205217
206218def setRestAPILog ():
207219 if hasattr (conf , "api" ):
208- conf .database_connection = sqlite3 .connect (conf .database , timeout = 1 , isolation_level = None )
209- conf .database_cursor = conf .database_connection .cursor ()
220+ #conf.database_connection = sqlite3.connect(conf.database, timeout=1, isolation_level=None)
221+ #conf.database_cursor = conf.database_connection.cursor()
222+
223+ conf .database_cursor = Database (conf .database )
224+ conf .database_cursor .connect ("client" )
210225
211226 # Set a logging handler that writes log messages to a IPC database
212227 logger .removeHandler (LOGGER_HANDLER )
@@ -455,7 +470,6 @@ def scan_data(taskid):
455470
456471 # Read all data from the IPC database for the taskid
457472 for status , content_type , value in db .execute ("SELECT status, content_type, value FROM data WHERE taskid = ? ORDER BY id ASC" , (taskid ,)):
458- #json_data_message.append({"status": status, "type": content_type, "value": base64unpickle(value)})
459473 json_data_message .append ({"status" : status , "type" : content_type , "value" : dejsonize (value )})
460474
461475 # Read all error messages from the IPC database
@@ -536,15 +550,18 @@ def server(host="0.0.0.0", port=RESTAPI_SERVER_PORT):
536550 """
537551 global adminid
538552 global db
553+ global db_filepath
539554
540555 adminid = hexencode (os .urandom (16 ))
541556
542557 logger .info ("Running REST-JSON API server at '%s:%d'.." % (host , port ))
543558 logger .info ("Admin ID: %s" % adminid )
559+ logger .debug ("IPC database: %s" % db_filepath )
544560
545561 # Initialize IPC database
546562 db = Database ()
547- db .initialize ()
563+ db .connect ()
564+ db .init ()
548565
549566 # Run RESTful API
550567 run (host = host , port = port , quiet = True , debug = False )
0 commit comments