The unified diff between revisions [cbb4788e..] and [29881737..] is displayed below. It can also be downloaded as a raw diff.

This diff has been restricted to the following files: 'scan.py'

#
#
# patch "scan.py"
#  from [4eb1704670d1258628116573a32af771b9d58278]
#    to [1d78a0f945e08738983363d8d23348a6250c316e]
#
============================================================
--- scan.py	4eb1704670d1258628116573a32af771b9d58278
+++ scan.py	1d78a0f945e08738983363d8d23348a6250c316e
@@ -2,6 +2,7 @@ from goatpy.gen2consume import gen2consu

 from goatpy.nmapwrapper import nmap
 from goatpy.gen2consume import gen2consume
+import getopt

 import ConfigParser
 import threading
@@ -15,6 +16,28 @@ import config

 import config

+class TextNotify:
+	def start_scan(self):
+		print "Starting scan."
+	def complete_scan(self):
+		print "Scan complete."
+	def start_host(self, thread_id, host):
+		print "[%2d] starting to scan: %-15s (T:%s U:%s)" % (thread_id, host.addresses[0][0], str(host.tcp_ports), str(host.udp_ports))
+	def complete_host(self, thread_id, host):
+		print "[%2d] %-15s: done with this host" % (thread_id, host.addresses[0][0])
+	def start_plugin(self, thread_id, plugin, host):
+		print "[%2d] %-15s: run plugin %s" % (thread_id, host.addresses[0][0], plugin.export['name'])
+	def complete_plugin(self, thread_id, host):
+		pass
+	def start_writing_results(self, thread_id, host):
+		pass
+	def complete_writing_results(self, thread_id, host):
+		pass
+	def notice(self, str):
+		print "%s" % (str)
+
+notification = None
+
 # urgency
 urgency_info = 0
 urgency_notice = 1
@@ -44,17 +67,18 @@ def scan_host(mythread, host, library):
 	if config.magic_udp_port in host.udp_ports:
 		host.udp_ports = []
 	plugins = library.plugins_for_ports(host.tcp_ports, host.udp_ports)
-	library.notify("[%2d] %-15s: has been assigned (T:%s U:%s)" % (mythread.id, host.addresses[0][0], str(host.tcp_ports), str(host.udp_ports)))
+	notification.start_host(mythread.id, host)
 	errors = []
 	results = []
 	for plugin in plugins:
 		tcp_ports = filter(lambda x: x in plugins[plugin][0], host.tcp_ports)
 		udp_ports = filter(lambda x: x in plugins[plugin][1], host.udp_ports)
 		try:
-			library.notify("[%2d] %-15s: run plugin %s" % (mythread.id, host.addresses[0][0], plugin.export['name']))
+			notification.start_plugin(mythread.id, plugin, host)
 			mythread.status_string = "in plugin %s" % (plugin.export['name'])
 			result = plugin.host_callback(library, host, tcp_ports, udp_ports)
 			mythread.status_string = "completed plugin %s" % (plugin.export['name'])
+			notification.complete_plugin(mythread.id, host)
 			results += result
 		except:
 			import traceback
@@ -62,11 +86,13 @@ def scan_host(mythread, host, library):
 			err_data = '\n'.join(traceback.format_exception(t, v, tr))
 			errors.append((plugin.export['name'], err_data))
 	mythread.status_string = "writing results"
+	notification.start_writing_results(mythread.id, host)
 	for plugin in library.output_plugins:
 		plugin.write_results(library, host, library.scanner_names, results)
 		plugin.write_errors(library, host, errors)
+	notification.complete_writing_results(mythread.id, host)
 	mythread.status_string = None
-	library.notify("[%2d] %-15s: done with this host" % (mythread.id, host.addresses[0][0]))
+	notification.complete_host(mythread.id, host)
 	# clean up memory explicitly, as otherwise Python might not garbage collect
 	# quickly enough for us.
 	del results
@@ -88,7 +114,7 @@ class WaitThread(threading.Thread):
 		while 1:
 			try:
 				procs = os.wait()
-				print "Processes have terminated:", procs
+				notification.notice("Processes have terminated: %s" % (str(procs)))
 			except: pass
 			# for some reason, sometimes this fails unless
 			# this check is here. A bit mysterious.
@@ -117,8 +143,6 @@ class PluginLibrary:
 		if orig_path: sys.path = orig_path
 	def finalise_plugins(self):
 		map(lambda x: x.finalise(self), self.output_plugins)
-	def notify(self, str):
-		print "%s" % (str)
 	def link_ports(self, mod, port_list, hash):
 		if not port_list: return
 		for port in port_list:
@@ -128,7 +152,6 @@ class PluginLibrary:
 		return self.tcp_to_plugin.keys(), self.udp_to_plugin.keys()
 	def do_load_plugin(self, plugin_name):
 		mod = __import__('%s' % plugin_name, globals(), locals(), [''])
-#		self.notify("Plugin loaded: " + mod.export['name'] + " version " + mod.export['version'] + " (" + mod.export['type'] + ")")
 		return mod
 	def plugins_for_ports(self, tcp_ports, udp_ports):
 		rv = {}
@@ -166,8 +189,6 @@ class Scanner:
 		self._config_path = config_path
 		self.config = config
 		self.library = PluginLibrary(self.config)
-	def notify(self, str):
-		print "%s" % (str)
 	def scan(self):
 		nmap_command = self.config.nmap_command + ' ' + self.config.nmap_options
 		ports = []
@@ -177,13 +198,14 @@ class Scanner:
 			udp_ports.append(config.magic_udp_port)
 			ports.append("U:" + ','.join([str(t) for t in udp_ports]))
 		if not len(ports):
-			self.notify("Nothing to do; no ports requested by plugins.")
+			notification.notice("Nothing to do; no ports requested by plugins.")
 			return
 		nmap_command += ' -p ' + ','.join(ports)
 		nmap_command += ' -oX -'
 		range = ' '.join(self.config.scan_networks)
 		nmap_command += ' ' + range
-		self.notify("Starting scan: %s" % (nmap_command))
+		notification.start_scan()
+		notification.notice("Scanner command is: %s" % (nmap_command))
 		gt = gen2consume(nmap(nmap_command), self.config.max_threads, lambda thread, host: scan_host(thread, host, self.library))
 		gt.join()
 		countdown = self.config.thread_wait_time
@@ -192,18 +214,29 @@ class Scanner:
 			has_status = filter(lambda x: "status_string" in dir(x) and x.status_string != None, running)
 			cnt = len(running)
 			reasons = map(lambda x: x.status_string, has_status)
-			print "[%2d secs] Waiting for %d threads (%s)" % (countdown, cnt, ','.join(reasons))
+			notification.notice("[%2d secs] Waiting for %d threads (%s)" % (countdown, cnt, ','.join(reasons)))
 			if cnt == 2: break
 			countdown -= 1
 			time.sleep(1)
-		print "Finalising output plugins."
+		notification.notice("Finalising output plugins.")
 		self.library.finalise_plugins()
-		print "Done!"
+		notification.notice("Done!")
+		notification.complete_scan()

 if __name__ == '__main__':
 	wt = WaitThread()
 	wt.start()
-	scanner = Scanner('scanner.cfg')
+	matched, remain = getopt.getopt(sys.argv[1:], "c:x")
+	output_mode = "text"
+	config_file = 'scanner.cfg'
+	for opt, value in matched:
+		if opt == '-c': config_file = value
+		elif opt == '-g': output_mode = "graphical"
+	if output_mode == "graphical":
+		notification = GraphicalNotify()
+	else:
+		notification = TextNotify()
+	scanner = Scanner(config_file)
 	scanner.scan()
 	sys.exit(0)