def __on_idle(self, udata): if self.type == FileOperation.TYPE_LOAD: ctx, rctx = udata self.loading_view = True log.debug('Creating a new session after loading for %s' % str(ctx)) if ctx is backend.SequenceContext: from umit.pm.gui.sessions.sequencesession import SequenceSession ServiceBus().call('pm.sessions', 'bind_session', SequenceSession, rctx) elif ctx is backend.SniffContext or \ ctx is backend.StaticContext: from umit.pm.gui.sessions.sniffsession import SniffSession ServiceBus().call('pm.sessions', 'bind_session', SniffSession, rctx) else: from umit.pm.gui.sessions.sniffsession import SniffSession if isinstance(self.session, SniffSession): self.session.sniff_page.statusbar.label = '<b>%s</b>' % \ self.ctx.summary self.loading_view = False self.percentage = 100.0 self.state = self.NOT_RUNNING # Force update. self.notify_parent() return False
def __on_button_press(self, tree, event): self.last_pos = (event.x, event.y) if event.button != 3: return selected = self.get_selected_ips() if not selected: return info_str = len(selected) == 1 and \ selected[0] or _('%d IP') % len(selected) session = ServiceBus().call('pm.sessions', 'get_current_session') if session.session_name == 'AUDIT' and \ session.get_current_page_name() == 'TARGETS': sensitive = True else: sensitive = False menu = gtk.Menu() act = gtk.Action('target1-add', _("Add '%s' to target1") % info_str, None, gtk.STOCK_ADD) act.connect('activate', lambda a, (s, ip): \ s.target_page.target1_tree.append(ip), (session, selected)) item = act.create_menu_item() item.set_sensitive(sensitive) menu.append(item) act = gtk.Action('target2-add', _("Add '%s' to target2") % info_str, None, gtk.STOCK_ADD) act.connect('activate', lambda a, (s, ip): \ s.target_page.target2_tree.append(ip), (session, selected)) item = act.create_menu_item() item.set_sensitive(sensitive) menu.append(item) menu.show_all() menu.popup(None, None, None, event.button, event.time) return True
def bind_perspective(self, ptype, callback): """ Bind the perspective 'type' The callback should be of the type def perspective_cb(perspective, type, already_present, added) @param type the perspective's type (see also PerspectiveType) @param callback the callback to execute when a new perspective of type 'type' is created """ log.debug( "Binding method %s for perspective of type %s" % \ (callback, PerspectiveType.types[ptype]) ) self.perspective_binder[ptype].append(callback) for page in ServiceBus().call('pm.sessions', 'get_sessions'): if not isinstance(page, Session): continue for perspective in page.perspectives: idx = PerspectiveType.types[type(perspective)] callback(perspective, idx, True, True)
def unbind_session(self, ptype, persp_klass): try: for i in range(len(self.session_binder[ptype])): (klass, show, resize) = self.session_binder[ptype][i] if klass is not persp_klass: continue del self.session_binder[ptype][i] klass = SessionType.types[ptype] for page in ServiceBus().call('pm.sessions', 'get_sessions'): if isinstance(page, klass): page.remove_perspective(persp_klass) log.debug( "Binding method %s for perspective of type %s removed" % \ (persp_klass, SessionType.types[ptype]) ) return True except: log.error( "Failed to remove binding method %s for session of type %s" % \ (persp_klass, SessionType.type[ptype]) ) return False
def debind_perspective(self, type, callback): """ Remove the binding callback for perspective of type 'type' @param type the perspective type @param callback the callback to remove @return True if the callback is removed correctly """ try: self.perspective_binder[type].remove(callback) for page in ServiceBus().call('pm.sessions', 'get_sessions'): if not isinstance(page, Session): continue for perspective in page.perspectives: idx = PerspectiveType.types[type(perspective)] callback(perspective, idx, True, False) log.debug( "Binding method %s for perspective of type %s removed" % \ (callback, PerspectiveType.types[type]) ) return True except: log.error( "Failed to remove binding method %s " "for perspective of type %s" % \ (callback, PerspectiveType.types[type]) ) return False
def __on_quit(self, *args): self.hide() # We need to stop the pending sniff threads lst = [] for page in ServiceBus().call('pm.sessions', 'get_sessions'): if isinstance(page, Session) and \ isinstance(page.context, backend.TimedContext): lst.append(page.context) for ctx in lst: ctx.stop() # Avoids joining all threads are daemon #for ctx in lst: # ctx.join() errs = [] try: log.debug('Saving options before exiting') Prefs().write_options() except IOError, err: errs.append(err)
def __on_field_selected(self, tree, packet=None, proto=None, field=None): if not proto or not field: return if packet in self.notify: for cb in self.notify[packet]: cb(packet, proto, field, False) # We should select also the bounds in HexView page = ServiceBus().call('pm.sessions', 'get_current_session') if page: start = backend.get_field_offset(packet, proto, field) length = backend.get_field_size(proto, field) log.debug('Field %s start at %d and finish at %d' % (field, start, length)) if length == 0: # Deselect all page.packet_page.hexview.select_block(0, 0) return page.packet_page.hexview.select_block(start / 8, max(length / 8, 1))
def create_session(self, menu, tup): """ Create a new session using ctxklass and sessklass @param menu gtk.MenuItem @param tuple a tuple containing (sessklass, ctxklass) """ sessklass, ctxklass = tup ServiceBus().call('pm.sessions', 'create_session', sessklass, ctxklass)
def _idle(self): if self.phase == 0: self.splash.text = _("Registering icons ...") from icons import register_icons register_icons() elif self.phase == 1: self.splash.text = _("Loading preferences ...") from umit.pm.manager.preferencemanager import Prefs self.prefs = Prefs() elif self.phase == 2: services_boot() self.splash.text = _("Creating main window ...") from mainwindow import MainWindow self.bus = ServiceBus() self.main_window = MainWindow() self.main_window.connect_tabs_signals() self.plugin_engine = PluginEngine() self.plugin_engine.load_selected_plugins() # Destroy the splash screen self.splash.hide() self.splash.destroy() self.splash.finished = True del self.splash # Now let's parse the args passed in the constructor parser = self._create_parser() options, args = parser.parse_args(self._args) if options.fread: self.main_window.open_generic_file_async(options.fread) if options.audit: dev1, dev2, bpf_filter = options.audit, '', '' try: dev1, dev2 = options.audit.split(',', 1) dev2, bpf_filter = other.split(':', 1) except: pass self.main_window.start_new_audit(dev1, dev2, bpf_filter, False, False) return False self.phase += 1 return True
def __init__(self, dev1, dev2, bpf_filter, skipfwd, unoffensive): capmethod = Prefs()['backend.system.audit.capmethod'].value if capmethod < 0 or capmethod > 2: Prefs()['backend.system.sendreceive.capmethod'].value = 0 capmethod = 0 Operation.__init__(self) backend.AuditContext.__init__(self, dev1, dev2, bpf_filter, capmethod) self.session = ServiceBus().call('pm.sessions', 'create_audit_session', self)
def open_generic_file(self, fname): """ Open a generic file (pcap/sequence and other supported file format) @param fname the path to the file to open @return a umit.pm.session.base.Session object or None on errors """ if not os.path.isfile(fname): return None types = {} sessions = (backend.StaticContext, backend.SequenceContext, backend.SniffContext) for ctx in sessions: for name, pattern in ctx.file_types: types[pattern] = (name, ctx) try: find = fname.split('.')[-1] for pattern in types: if pattern.split('.')[-1] == find: ctx = types[pattern][1] except: pass if ctx is backend.SequenceContext: return ServiceBus().call('pm.sessions', 'load_sequence_session', fname) elif ctx is backend.SniffContext: return ServiceBus().call('pm.sessions', 'load_sniff_session', fname) elif ctx is backend.StaticContext: return ServiceBus().call('pm.sessions', 'load_static_session', fname)
def populate(self): """ Could be called to refresh the store. """ intf = self.intf_combo.get_interface() self.store.clear() populate_cb = ServiceBus().get_function('pm.hostlist', 'populate') if not callable(populate_cb): return for ip, mac, desc in populate_cb(intf): self.store.append([ip, mac, desc])
def __do_append_cur_sequence(self, selection=None, hier=False): sel = self.__get_selected() if sel: sess = ServiceBus().call('pm.sessions', 'get_current_session') if not isinstance(sess, SequenceSession): return False if not hier: sess.sequence_page.append_packet(sel, selection) else: sess.packet_page.proto_hierarchy.append_packet(sel, selection) return True return False
def __init__(self, iface, filter=None, minsize=0, maxsize=0, capfile=None, \ scount=0, stime=0, ssize=0, real=True, scroll=True, \ resmac=True, resname=False, restransport=True, promisc=True, \ background=False, capmethod=0, audits=True): Operation.__init__(self) backend.SniffContext.__init__(self, iface, filter, minsize, maxsize, capfile, scount, stime, ssize, real, scroll, resmac, resname, restransport, promisc, background, capmethod, audits, self.__recv_callback, None) if not self.background: self.session = ServiceBus().call('pm.sessions', 'create_sniff_session', self) else: self.session = None
def __init__(self, seq, count, inter, iface=None, strict=True, \ report_recv=False, report_sent=True): capmethod = Prefs()['backend.system.sequence.capmethod'].value if capmethod < 0 or capmethod > 2: Prefs()['backend.system.sendreceive.capmethod'].value = 0 capmethod = 0 log.debug('Using %d as capmethod for SendReceiveContext' % capmethod) Operation.__init__(self) backend.SequenceContext.__init__(self, seq, count, inter, iface, \ strict, report_recv, report_sent, \ capmethod, \ self.__send_callback, \ self.__receive_callback) self.session = ServiceBus().call('pm.sessions', 'create_sniff_session', self)
def __redraw_hex_view(self, tree, entry_destroyed): # This is called when the user end the edit action on the PropertyGrid # and we could redraw the entire hexview to show changes # The tree argument is the PropertyGridTree object page = ServiceBus().call('pm.sessions', 'get_current_session') # FIXME: check if the packet page object is avaiable # within this session or use isinstance(SessionPage, SequencePage) if page: # No reload to avoid repopulating page.packet_page.redraw_hexview() packet, proto, field = self.grid.tree.get_selected_field() if packet in self.notify: for cb in self.notify[packet]: cb(packet, proto, field, True) # Now reselect the blocks self.__on_field_selected(self.grid.tree, packet, proto, field)
def __on_hierarchy_selection_changed(self, selection): packet, proto = \ self.prev_page.packet_page.proto_hierarchy.get_active_protocol() if not proto: return self.grid.clear() self.grid.populate(packet, proto) # Let's select entire protocol in the hexview page = ServiceBus().call('pm.sessions', 'get_current_session') if page: bounds = packet.get_protocol_bounds(proto) if bounds: page.packet_page.hexview.select_block(bounds[0], bounds[1] - bounds[0]) self._main_widget.set_sensitive(True)
def __on_info(self, button): import umit.pm.gui.core.app ips = [] intf = self.intf_combo.get_interface() info_cb = ServiceBus().get_function('pm.hostlist', 'info') # Doesn't test for null info_cb. If we are here the button is enabled # and the test is already done. def add_to_string(model, path, iter, selected): ips.append((model.get_value(iter, 0), model.get_value(iter, 1))) self.tree.get_selection().selected_foreach(add_to_string, ips) for ip, mac in ips: ret = info_cb(intf, ip, mac) d = gtk.Dialog(_('Informations for %s - PacketManipulator') % \ ret.l3_addr, umit.pm.gui.core.app.PMApp().main_window, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_COPY, gtk.RESPONSE_ACCEPT, gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)) d.set_size_request(460, 300) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) details = HostListDetails() details.populate(ret) sw.add(details) sw.show_all() d.vbox.pack_start(sw) d.connect('response', self.__on_dialog_response) d.show()
def bind_session(self, ptype, persp_klass, show_pers=True, resize=False): """ Bind the perspective 'pers_klass' to Session 'ptype' @param ptype the Session type to customize @param persp_klass the perspective class to add to the selected Session @param show_pers choose to show the perspective @param resize if True child should resize when the paned is resized """ log.debug( "Binding perspective %s to Session %s" % \ (persp_klass, SessionType.types[ptype]) ) self.session_binder[ptype].append((persp_klass, show_pers, resize)) klass = SessionType.types[ptype] for page in ServiceBus().call('pm.sessions', 'get_sessions'): if isinstance(page, klass): self.apply_bindings(page, ptype, persp_klass)
def __on_dialog_response(self, dialog, rid): import gtk import umit.pm.gui.core.app if rid != gtk.RESPONSE_ACCEPT: dialog.hide() dialog.destroy() return table = dialog.vbox.get_children()[0] assert isinstance(table, gtk.Table) inp_dict = {} for widget in table: if isinstance(widget, gtk.Label): continue if isinstance(widget, gtk.SpinButton): if widget.get_digits() == 0: value = widget.get_value_as_int() else: value = widget.get_value() elif isinstance(widget, gtk.ToggleButton): value = widget.get_active() else: value = widget.get_text() inp_dict[widget.get_name()] = value dialog.hide() dialog.destroy() audit_sess = ServiceBus().call('pm.sessions', 'get_current_session') self.__start_audit(audit_sess, inp_dict)
def __create_session(self): self.session = ServiceBus().call('pm.sessions', 'create_sniff_session', self)
def create_ui(self): self._main_widget.set_border_width(4) self._main_widget.set_spacing(2) self.intf_combo = InterfacesCombo() self._main_widget.pack_start(self.intf_combo, False, False) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) self.store = gtk.ListStore(str, str, str) self.tree = gtk.TreeView(self.store) rend = gtk.CellRendererText() self.tree.append_column(gtk.TreeViewColumn(_('IP'), rend, text=0)) self.tree.append_column(gtk.TreeViewColumn(_('MAC'), rend, text=1)) self.tree.append_column( gtk.TreeViewColumn(_('Description'), rend, text=2)) self.tree.get_column(2).set_resizable(True) self.tree.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [('text/plain', 0, 0)], gtk.gdk.ACTION_DEFAULT | \ gtk.gdk.ACTION_COPY) # Enable multiple selection self.tree.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.tree.set_rubber_banding(True) self.last_pos = (0, 0) self.tree.connect("drag-begin", self.__on_drag_begin) self.tree.connect("drag-data-get", self.__on_drag_data_get) self.tree.connect("button-press-event", self.__on_button_press) self.tree.set_rules_hint(True) self.tree.set_search_column(0) self.tree.set_enable_search(True) sw.add(self.tree) self._main_widget.pack_start(sw) bb = gtk.HButtonBox() bb.set_layout(gtk.BUTTONBOX_END) self.btn_refresh = new_button(gtk.STOCK_REFRESH, _('Refresh the list')) self.btn_refresh.connect('clicked', self.__on_refresh) self.btn_info = new_button(gtk.STOCK_INFO, _('Information for selected host')) self.btn_info.connect('clicked', self.__on_info) bb.pack_start(self.btn_refresh, False, False) bb.pack_end(self.btn_info, False, False) self._main_widget.pack_end(bb, False, False) self._main_widget.show_all() self.btn_info.set_sensitive(False) self.btn_refresh.set_sensitive(False) svc = ServiceBus().get_service('pm.hostlist') svc.connect('func-binded', self.__on_func_assigned) svc.connect('func-unbinded', self.__on_func_assigned) self.populate()
def activate(self): if not self.session: self.session = ServiceBus().call('pm.sessions', 'create_sniff_session', self)
def __add_to_new_sequence(self, action): sel = self.__get_selected() if sel: ServiceBus().call('pm.sessions', 'create_edit_session', sel) return True
def on_input_request(self, action): import gtk import umit.pm.gui.core.app if not self.__inputs__: audit_sess = ServiceBus().call('pm.sessions', 'get_current_session') self.__start_audit(audit_sess, {}) return dialog = gtk.Dialog(_('Inputs for %s - PacketManipulator') % \ self.__class__.__name__, umit.pm.gui.core.app.PMApp().main_window, gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) tbl = gtk.Table(2, 1, False) tbl.set_border_width(4) tbl.set_col_spacings(4) tbl.set_row_spacings(4) dialog.vbox.pack_start(tbl) idx = 0 for txt, (opt_val, desc) in self.__inputs__: lbl = gtk.Label('') lbl.set_alignment(.0, .5) lbl.set_markup('<b>%s:</b>' % txt.capitalize()) if isinstance(opt_val, bool): widget = gtk.ToggleButton('') widget.set_active(opt_val) widget.get_child().set_text(widget.get_active() \ and _('Enabled') \ or _('Disabled')) widget.connect('toggled', lambda w: w.get_child().set_text( \ w.get_active() and _('Enabled') or _('Disabled'))) elif isinstance(opt_val, str): widget = gtk.Entry() widget.set_text(opt_val) elif isinstance(opt_val, int): widget = gtk.SpinButton(gtk.Adjustment(opt_val, -sys.maxint, sys.maxint, 1, 10), digits=0) elif isinstance(opt_val, float): widget = gtk.SpinButton(gtk.Adjustment(opt_val, -sys.maxint, sys.maxint, 1, 10), digits=4) lbl.props.has_tooltip = True widget.props.has_tooltip = True lbl.set_tooltip_markup(desc) widget.set_tooltip_markup(desc) widget.set_name(txt) tbl.attach(lbl, 0, 1, idx, idx + 1, gtk.FILL, gtk.FILL) tbl.attach(widget, 1, 2, idx, idx + 1, yoptions=gtk.FILL) idx += 1 tbl.show_all() dialog.connect('response', self.__on_dialog_response) dialog.show()
def create_targets(self): """ Update targets structure appropriately by looking at target{1,2}_tree. @return True if the list is filled right or False """ func = ServiceBus().get_function('pm.hostlist', 'get_target') if not func: dialog = gtk.MessageDialog(self.get_toplevel(), gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, "No class implements `get_target method'" " of pm.hostlist interface. Please load " "an appropriate plugin.") dialog.run() dialog.hide() dialog.destroy() else: netmask = Netmask(self.session.context.get_netmask1(), self.session.context.get_ip1()) def add_host_entry(target, targets_idx): entry = None if is_mac(target): entry = HostEntry(l2_addr=target) elif func: if is_ip(target) and netmask.match_strict(target): profs = filter(lambda p: p.l2_addr is not None, func(l3_addr=target, netmask=netmask) or \ []) if profs: entry = HostEntry(l2_addr=profs[0].l2_addr, l3_addr=target, hostname=profs[0].hostname) else: profs = filter(lambda p: p.l2_addr is not None, func(hostname=target, netmask=netmask) or \ []) if profs: entry = HostEntry(l2_addr=profs[0].l2_addr, l3_addr=profs[0].l3_addr, hostname=target) if entry: log.info('Group %d -> %s' % (targets_idx + 1, entry)) self.targets[targets_idx].append(entry) # Ok. Now let's create the target list if not self.targets[0] and not self.targets[1]: log.info('Creating targets list for the MITM attack') for target in self.target1_tree.get_targets(): add_host_entry(target, 0) for target in self.target2_tree.get_targets(): add_host_entry(target, 1) errs = [] if func: netmask = None if not self.targets[0]: netmask = Netmask(self.session.context.get_netmask1(), self.session.context.get_ip1()) for prof in filter(lambda p: p.l2_addr is not None, func(netmask=netmask) or []): entry = HostEntry(l2_addr=prof.l2_addr, l3_addr=prof.l3_addr, hostname=prof.hostname) self.targets[0].append(entry) log.info('[AUTOADD] Group 1 -> %s' % entry) if not self.targets[1]: if not netmask: netmask = Netmask(self.session.context.get_netmask1(), self.session.context.get_ip1()) for prof in filter(lambda p: p.l2_addr is not None, func(netmask=netmask) or []): entry = HostEntry(l2_addr=prof.l2_addr, l3_addr=prof.l3_addr, hostname=prof.hostname) self.targets[1].append(entry) log.info('[AUTOADD] Group 2 -> %s' % entry) if not self.targets[0]: errs.append( _('Could not set any targets for the first group.')) if not self.targets[1]: errs.append( _('Could not set any targets for the second group.')) if errs and not func: errs.append( _('Neither get_target can be used to autopopulate the targ' 'ets. Please load at least an appropriate plugin (like ' 'Profiler) and make an ARP scan, or add targets MAC by ' 'hand.')) if errs: dialog = gtk.MessageDialog(self.get_toplevel(), gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, "Some errors found:\n\n" + \ '\n'.join(errs)) dialog.run() dialog.hide() dialog.destroy() return False return True
def create_ui(self): self._main_widget.set_border_width(4) self._main_widget.set_spacing(2) self.intf_combo = InterfacesCombo() self._main_widget.pack_start(self.intf_combo, False, False) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) self.store = gtk.ListStore(str, str, str) self.tree = gtk.TreeView(self.store) rend = gtk.CellRendererText() self.tree.append_column(gtk.TreeViewColumn(_('IP'), rend, text=0)) self.tree.append_column(gtk.TreeViewColumn(_('MAC'), rend, text=1)) self.tree.append_column(gtk.TreeViewColumn(_('Description'), rend, text=2)) self.tree.get_column(2).set_resizable(True) self.tree.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [('text/plain', 0, 0)], gtk.gdk.ACTION_DEFAULT | \ gtk.gdk.ACTION_COPY) # Enable multiple selection self.tree.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.tree.set_rubber_banding(True) self.last_pos = (0, 0) self.tree.connect("drag-begin", self.__on_drag_begin) self.tree.connect("drag-data-get", self.__on_drag_data_get) self.tree.connect("button-press-event", self.__on_button_press) self.tree.set_rules_hint(True) self.tree.set_search_column(0) self.tree.set_enable_search(True) sw.add(self.tree) self._main_widget.pack_start(sw) bb = gtk.HButtonBox() bb.set_layout(gtk.BUTTONBOX_END) self.btn_refresh = new_button(gtk.STOCK_REFRESH, _('Refresh the list')) self.btn_refresh.connect('clicked', self.__on_refresh) self.btn_info = new_button(gtk.STOCK_INFO, _('Information for selected host')) self.btn_info.connect('clicked', self.__on_info) bb.pack_start(self.btn_refresh, False, False) bb.pack_end(self.btn_info, False, False) self._main_widget.pack_end(bb, False, False) self._main_widget.show_all() self.btn_info.set_sensitive(False) self.btn_refresh.set_sensitive(False) svc = ServiceBus().get_service('pm.hostlist') svc.connect('func-binded', self.__on_func_assigned) svc.connect('func-unbinded', self.__on_func_assigned) self.populate()
def __on_save_session_as(self, action): session = ServiceBus().call('pm.sessions', 'get_current_session') if session: session.save_as()
def __on_new_sequence(self, action): ServiceBus().call('pm.sessions', 'create_sequence_session', [])
def __on_create_seq(self, action): ServiceBus().call('pm.sessions', 'create_sequence_session', self.get_selected_packets(True))
def __init__(self): gobject.GObject.__init__(self) self.mainwindow = None self.bus = ServiceBus() gtk.about_dialog_set_url_hook(self.__about_dialog_url, None)