class Core: def __init__(self): user_dir = "%s%s.kismon%s" % (os.path.expanduser("~"), os.sep, os.sep) if not os.path.isdir(user_dir): print("Creating Kismon user directory %s" % user_dir) os.mkdir(user_dir) config_file = "%skismon.conf" % user_dir self.config_handler = Config(config_file) self.config_handler.read() self.config = self.config_handler.config self.sources = {} self.crypt_cache = {} self.networks = Networks(self.config) self.client_threads = {} self.init_client_threads() self.tracks = Tracks("%stracks.json" % user_dir) self.tracks.load() if "--disable-map" in sys.argv: self.map_error = "--disable-map used" else: self.map_error = check_osmgpsmap() if self.map_error is not None: self.map_error = "%s\nMap disabled" % self.map_error print(self.map_error, "\n") self.init_map() self.main_window = MainWindow(self.config, self.client_start, self.client_stop, self.map, self.networks, self.sources, self.tracks, self.client_threads) self.main_window.log_list.add("Kismon", "started") if self.map_error is not None: self.main_window.log_list.add("Kismon", self.map_error) self.networks_file = "%snetworks.json" % user_dir if os.path.isfile(self.networks_file): try: self.networks.load(self.networks_file) except: error = sys.exc_info()[1] print(error) dialog_message = "Could not read the networks file '%s':\n%s\n\nDo you want to continue?" % ( self.networks_file, error) dialog = Gtk.MessageDialog(self.main_window.gtkwin, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR, Gtk.ButtonsType.YES_NO, dialog_message) def dialog_response(dialog, response_id): self.dialog_response = response_id dialog.connect("response", dialog_response) dialog.run() dialog.destroy() if self.dialog_response == -9: print("exit") self.clients_stop() self.main_window.gtkwin = None return self.networks.set_autosave(self.config["networks"]["autosave"], self.networks_file, self.main_window.log_list.add) if self.map is not None: self.networks.notify_add_list["map"] = self.add_network_to_map self.networks.notify_remove_list["map"] = self.map.remove_marker GLib.timeout_add(100, self.map.set_last_from_config) self.main_window.network_list.crypt_cache = self.crypt_cache GLib.timeout_add(500, self.queues_handler) GLib.timeout_add(300, self.queues_handler_networks) GLib.idle_add(self.networks.apply_filters) def init_map(self): if self.map_error is not None: self.map = None else: from kismon.map import Map user_agent = 'kismon/%s' % utils.get_version() self.map = Map(self.config["map"], user_agent=user_agent) self.map.set_last_from_config() def init_client_thread(self, server_id): server = self.config["servers"][server_id] server['id'] = server_id self.client_threads[server_id] = RestClientThread(server['uri']) if server['username'] != '' and server['password'] != '': self.client_threads[server_id].client.credentials = ( server['username'], server['password']) def init_client_threads(self): server_id = 0 for server in self.config["servers"]: self.init_client_thread(server_id) server_id += 1 def client_start(self, server_id): if server_id in self.client_threads and self.client_threads[ server_id].is_running: self.client_stop(server_id) self.sources[server_id] = {} self.init_client_thread(server_id) self.client_threads[server_id].start() def client_stop(self, server_id): self.client_threads[server_id].stop() def clients_stop(self): for server_id in self.client_threads: self.client_stop(server_id) return True def queue_handler(self, server_id): server = self.config['servers'][server_id] if self.main_window.gtkwin is None: return False thread = self.client_threads[server_id] if len(thread.client.error) > 0: for error in thread.client.error: self.main_window.log_list.add(server['uri'], error) thread.client.error = [] self.main_window.server_tabs[server_id].server_switch.set_active( False) page_num = self.main_window.notebook.page_num( self.main_window.log_list.widget) self.main_window.notebook.set_current_page(page_num) # info status = thread.get_queue('status') if status: self.main_window.server_tabs[server_id].update_info_table( devices=status['kismet.system.devices.count']) #gps gps = None gps_queue = thread.get_queue("location") while len(gps_queue) > 0: data = gps_queue.pop(0) if not data: continue if data['kismet.common.location.valid'] == 0: continue gps = { 'lat': data['kismet.common.location.lat'], 'lon': data['kismet.common.location.lon'], 'alt': data['kismet.common.location.alt'], 'fix': data['kismet.common.location.fix'], } if data['kismet.common.location.fix'] > 1: if self.config['tracks']['store']: self.tracks.add_point_to_track(server['uri'], gps['lat'], gps['lon'], gps['alt']) if self.map: self.map.add_track(gps['lat'], gps['lon'], server_id) if gps: self.main_window.server_tabs[server_id].update_gps_table( lat=gps['lat'], lon=gps['lon'], fix=gps['fix']) if gps['fix'] > 1 and self.map: server_key = "server%s" % (server_id + 1) if server_id == 0: self.map.set_position(gps['lat'], gps['lon']) else: self.map.add_marker(server_key, server_key, gps['lat'], gps['lon']) message_queue = thread.get_queue("messages") while len(message_queue) > 0: message = message_queue.pop(0) self.main_window.log_list.add( origin=server['uri'], message=message['kismet.messagebus.message_string'], timestamp=message['kismet.messagebus.message_time']) datasources = thread.get_queue('datasources') if len(datasources) == 0: #print("no active datasources") if type(self.main_window.server_tabs[server_id]. datasources_dialog_answer) == bool: # question was already asked pass elif not thread.client.connected: # not connected pass elif self.datasources_dialog(server_id): self.main_window.server_tabs[server_id].on_manage_datasources() sources_updated = False for ds in datasources: uuid = ds['kismet.datasource.uuid'] source = { 'type': ds['kismet.datasource.hardware'], 'packets': ds['kismet.datasource.num_packets'], 'channel': ds['kismet.datasource.channel'], 'hop': ds['kismet.datasource.hopping'], 'hop_rate': ds['kismet.datasource.hop_rate'], 'running': ds['kismet.datasource.running'], 'name': ds['kismet.datasource.name'], 'uuid': uuid, } #print(source) if uuid in self.sources[server_id] and source[ 'packets'] != self.sources[server_id][uuid]['packets']: sources_updated = True self.sources[server_id][uuid] = source if sources_updated is True: self.main_window.server_tabs[server_id].update_sources_table( self.sources[server_id]) def datasources_dialog(self, server_id): dialog_message = "The Kismet instance %s seems to have no active interfaces.\nDo you want to activate them now? *\n\n* Requires authentification" % ( self.config["servers"][server_id]['uri']) dialog = Gtk.MessageDialog(self.main_window.gtkwin, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, dialog_message) def dialog_response(dialog, response_id): answer = False if response_id == -8: answer = True print("yes") else: print("no", response_id) self.main_window.server_tabs[ server_id].datasources_dialog_answer = answer dialog.connect("response", dialog_response) dialog.run() dialog.destroy() return self.main_window.server_tabs[ server_id].datasources_dialog_answer def queues_handler(self): for server_id in self.client_threads: self.queue_handler(server_id) return True def queue_handler_networks(self, server_id): thread = self.client_threads[server_id] queue = thread.get_queue("dot11") for x in range(0, len(queue)): device = queue.pop(0) self.networks.add_device_data(device, server_id) mac = device['kismet.device.base.macaddr'] for sid in device['kismet.device.base.seenby']: source = device['kismet.device.base.seenby'][sid] source_uuid = source['kismet.common.seenby.uuid'] if source_uuid not in self.sources[server_id]: continue if mac not in self.main_window.signal_graphs: continue if source['kismet.common.seenby.signal'][ 'kismet.common.signal.type'] != 'dbm': continue self.main_window.signal_graphs[mac].add_value( source_data=self.sources[server_id][source_uuid], packets=source['kismet.common.seenby.num_packets'], signal=source['kismet.common.seenby.signal'] ['kismet.common.signal.last_signal'], timestamp=source['kismet.common.seenby.last_time'], server_id=server_id) if len(self.networks.notify_add_queue) > 0: self.networks.start_queue() if len(self.networks.notify_add_queue) > 500: self.networks.disable_refresh() self.main_window.networks_queue_progress() self.main_window.update_statusbar() def queues_handler_networks(self): for server_id in self.client_threads: self.queue_handler_networks(server_id) return True def quit(self): self.clients_stop() if self.map is not None: lat = self.map.osm.get_property("latitude") lon = self.map.osm.get_property("longitude") self.config["map"]["last_position"] = "%.6f/%.6f" % (lat, lon) while None in self.config['servers']: self.config['servers'].remove(None) self.config_handler.write() self.networks.save(self.networks_file, force=True) if self.config['tracks']['store']: self.tracks.save() def add_network_to_map(self, mac): network = self.networks.get_network(mac) try: crypt = self.crypt_cache[network["cryptset"]] except KeyError: crypt = decode_cryptset(network["cryptset"], True) self.crypt_cache[network["cryptset"]] = crypt if "AES_CCM" in crypt or "AES_OCB" in crypt: color = "red" elif "WPA" in crypt: color = "orange" elif "WEP" in crypt: color = "yellow" else: color = "green" self.map.add_marker(mac, color, network["lat"], network["lon"])
def test_map(self): from gi.repository import Gtk from kismon.config import Config from kismon.map import Map test_config = Config(None).default_config["map"] test_map = Map(test_config) test_map.set_zoom(16) test_map.set_position(52.513, 13.323) test_map.add_marker("111", "green", 52.513, 13.322) test_map.add_marker("222", "red", 52.512, 13.322) test_map.add_marker("333", "orange", 52.512, 13.322) test_map.locate_marker("111") test_map.add_marker("222", "red", 52.510, 13.321) test_map.add_marker("333", "orange", 52.511, 13.322) test_map.add_marker("444", "green", 52.511, 13.322) test_map.add_marker("server1", "server1", 52.511, 13.321) test_map.set_position(52.513, 13.323) test_map.zoom_out() test_map.zoom_in() test_map.on_map_pressed(None, None) test_map.change_source("openstreetmap") test_map.change_source("opencyclemap") test_map.remove_marker("333") test_map.add_track(52.513, 13.323, 'server1', color=(0, 16621, 19455)) test_map.add_track(52.510, 13.321, 'server1') test_map.add_track(52.511, 13.321, 'server1') test_map.set_track_color('server1', (65535, 1, 65535)) test_window = Gtk.Window() test_window.set_title("Kismon Test Map") test_window.connect("destroy", Gtk.main_quit) test_window.show() test_window.set_size_request(640, 480) test_window.add(test_map.widget) test_window.show_all()