示例#1
0
文件: main.py 项目: lnv42/repator
def main(conf=None):
    """Creates the window repator, initializing the databases and the git repository."""
    tab_lst = OrderedDict()
    tab_lst["Mission"] = copy(MISSION)
    tab_lst["Auditors"] = dict(
        lst=copy(PEOPLE), db=DBHandler.auditors(), add_fct=add_people)
    tab_lst["Clients"] = dict(
        lst=copy(PEOPLE), db=DBHandler.clients(), add_fct=add_people)
    tab_lst["Vulns"] = dict(vulns={"class": Vulns, "arg": (
        copy(VULNS), DBHandler.vulns(), add_vuln)})

    copyfile(DB_VULNS, DB_VULNS_INITIAL)

    # as we don't use arguments, I prefer to use python-fire
    app = QApplication([])
    window = Window('Repator', tab_lst)
    Git()

    # this allows us to have a directory for every mission with a file that can
    # be automatically configured
    # then, just use repator.py --conf=path or repator.py path (or nothing to
    # use default)
    if conf is not None:
        if path.exists(conf):
            config = ConfigParser()
            config.optionxform = str
            config.read(conf)
            window.load_dict({s: dict(config.items(s))
                              for s in config.sections()})
        else:
            window.load_dict({})
    window.showMaximized()

    app.exec_()
示例#2
0
    def load(self, values):
        """Loads values into the database and displays it on the screen."""
        if "vulns" in self.fields:
            self.fields["vulns"].load(values)
            return

        if self.database is not None and "db" in values:
            creation_date = QDateTime.currentDateTime().toString(
                "yyyyMMdd-hhmmss")
            db_path = self.database.path + "-tmp-" + creation_date + ".json"
            default_values = self.database.default_values
            self.database.close()
            self.database = DBHandler(db_path, default_values)
            self.database.insert_multiple(values["db"])

            if self.add_fct is not None:
                self.row = 0
                self.lst = self.head_lst
                self.values.clear()
                self.fields.clear()

                items = self.database.get_all()
                for item in items:
                    self.add_fct(self.lst, item.doc_id, item)
                self.parse_lst()

        for name, value in values.items():
            if name.isdigit():
                doc_id = name
                if "check-" + doc_id in self.fields:
                    self.fields["check-" + doc_id].setCheckState(Qt.Checked)
                if "status" in value and "isVuln-" + doc_id in self.fields:
                    self.fields["isVuln-" + doc_id].setCurrentText(
                        value["status"])

            elif name in self.fields:
                field = self.fields[name]
                if "setText" in dir(field):
                    field.setText(value)
                if "setCurrentText" in dir(field):
                    field.setCurrentText(value)
                if "setDate" in dir(field):
                    field.setDate(QDate.fromString(value))
示例#3
0
    def init_tab(self):
        self.tabw = QTabWidget()
        tab_lst = copy(VULNS_INITIAL), DBHandler.vulns(), DBHandler.vulns_git(
        ), add_vuln_initial
        obj = ObjectsGit("vulns", tab_lst, self)
        self.tabw.addTab(obj, "Vulns")

        tab_lst = copy(AUDITORS_INITIAL), DBHandler.auditors(
        ), DBHandler.auditors_git(), add_auditor_initial
        obj = ObjectsGit("auditors", tab_lst, self)
        self.tabw.addTab(obj, "Auditors")

        tab_lst = copy(AUDITORS_INITIAL), DBHandler.clients(
        ), DBHandler.clients_git(), add_auditor_initial
        obj = ObjectsGit("clients", tab_lst, self)
        self.tabw.addTab(obj, "Clients")
示例#4
0
    def refresh_repator(self, repator, index=None):
        """Rebuilds the vulns widget repator with the tabs currently open (without index)"""
        vulns = repator.layout().itemAt(0).widget().widget(3).fields["vulns"]
        tabs = []
        for i in range(vulns.tabw.tabBar().count() - 1, 0, -1):
            tabs.append(vulns.tabw.tabBar().tabText(i))
            self.tabw.tabBar().removeTab(i)
        if index:
            for i in index:
                if i in tabs:
                    tabs.remove(i)

        del vulns.database
        vulns.tabw.deleteLater()
        vulns.lst = copy(VULNS)
        vulns.database = DBHandler.vulns()
        vulns.tabs = {}
        vulns.init_tab()
        vulns.grid.replaceWidget(vulns.layout().itemAt(0).widget(), vulns.tabw)

        for doc_id in reversed(tabs):
            vulns.tabs["All"].fields["edit-" + doc_id].animateClick()
        vulns.tabw.setCurrentWidget(vulns.tabs["All"])
示例#5
0
def main(args):
    """Main process."""
    clean_db(DBHandler.auditors(), DB_AUDITORS_DEFAULT)
    clean_db(DBHandler.clients(), DB_CLIENTS_DEFAULT)
    clean_db(DBHandler.vulns(), DB_VULNS_DEFAULT, LANGUAGES)
示例#6
0
def main(args):
    """Main process."""
    if len(args) < 2:
        _help(args)
        return
    if args[1] == '-h' or args[1] == "--help":
        _help(args)
        return

    input_file = args[1]

    print("/!\\ Your current database will be erased ! /!\\")
    print("Please make sure you have a copy of it ;)")
    print(
        "You may also consider closing repator because the tabs won't refresh automaticaly."
    )

    input_value = input("Enter y if you want to continue : ")
    print()

    if not (input_value in {'y', 'Y'}):
        print("exit")
        exit(1)

    field_names_lang = list(DB_VULNS_DEFAULT.keys())
    for field in MONOLANGFIELDS:
        field_names_lang.remove(field)

    field_names = ["id", "LANGUAGES"] + list(DB_VULNS_DEFAULT.keys())
    if len(LANGUAGES) > 1:
        for lang in LANGUAGES:
            field_names += [field + lang for field in field_names_lang]

    list_fields = ["LANGUAGES"]
    for key, value in DB_VULNS_DEFAULT.items():
        if isinstance(value, list):
            list_fields += [key]

    res_dict = OrderedDict()

    with open(input_file, newline='') as csvfile:
        data = DictReader(csvfile)

        for row in data:
            for field in field_names:
                try:
                    row[field] = JSONDecoder(
                        object_pairs_hook=OrderedDict).decode(row[field])
                except:
                    pass

            if LANGUAGES != row["LANGUAGES"]:
                print(
                    "IMPORT FAILED : Please make sure your LANGUAGES in conf/report.py are"
                    +
                    "the same as the LANGUAGES used when your CSV file was created"
                )
                exit(1)
            ident = row["id"]

            del row["LANGUAGES"]
            del row["id"]
            for field in dict(row):
                if not field in field_names and not row[field]:
                    del row[field]
            res_dict[ident] = row
    jsondb = "{\"_default\":" + dumps(
        res_dict, ensure_ascii=False, sort_keys=True) + "}"
    with open(DB_LOCAL_FILES["vulns"], 'w') as output:
        output.write(jsondb)

    print("New database successfuly imported.")
    clean_db(DBHandler.vulns(), DB_VULNS_DEFAULT, LANGUAGES)
    print("New database successfuly cleaned.")
示例#7
0
class Tab(QScrollArea):
    """Class that contains the attributes of a tab for repator, diffs and repator->Vulns."""
    def __init__(self, parent, lst, database=None, add_fct=None):
        super().__init__(parent)
        self.head_lst = lst
        self.database = database
        self.add_fct = add_fct
        self._parent = parent
        self.row = 0
        self.lst = self.head_lst
        self.values = OrderedDict()
        self.init_tab()

    def init_tab(self):
        """Initializes features and widgets of a tab."""
        self.fields = {}
        if self.database is not None and self.add_fct is not None:
            items = self.database.get_all()
            for item in items:
                self.add_fct(self.lst, item.doc_id, item)

        self.grid = QGridLayout()
        self.grid.setSpacing(5)
        self.grid.setContentsMargins(5, 5, 5, 5)
        self.grid.setAlignment(Qt.AlignTop)

        self.parse_lst()

        self.widget = QWidget()
        self.widget.setLayout(self.grid)
        self.setWidget(self.widget)
        self.setWidgetResizable(True)

    def change_value(self, string=None):
        """Changes the value of a field with the provided encoding."""
        sender = self.sender()
        field = sender.accessibleName()

        if string is None:
            string = sender
        if "toString" in dir(string):
            string = string.toString()
        if "toHtml" in dir(string):
            string = string.toHtml()

        self.values[field] = string

    def update_vuln(self, string=None):
        """Updates the database value of the sender and updates the fields values accordingly."""
        sender = self.sender()
        while True:
            field_name = sender.accessibleName()
            if field_name:
                break
            if sender.parent() is None:
                return
            sender = sender.parent()

        field_tab = field_name.split('-')

        if string is None:
            string = sender
        if "toString" in dir(string):
            string = string.toString()
        if "to_plain_text" in dir(string):
            string = string.to_plain_text()
        history_field_name = field_tab[0] + "History-" + field_tab[1]

        doc = self.database.search_by_id(int(field_tab[1]))

        diff_name = "diff-" + field_tab[1]
        if diff_name in self._parent.tabs["All"].fields:
            self._parent.tabs["All"].fields[diff_name].edited()

        if history_field_name in self.fields:
            index = self.fields[history_field_name].currentIndex()
            if self.fields[field_name].to_plain_text() != doc[
                    field_tab[0] + "History"][index]:
                self.fields[history_field_name].setCurrentIndex(0)
        self.database.update(int(field_tab[1]), field_tab[0], string)

        self.update_cvss(field_tab[1])

    def load_history(self, index):
        """Writes the string into the non-History field of the sender."""
        sender = self.sender()
        history_field_name = sender.accessibleName()
        doc = self.database.search_by_id(int(
            history_field_name.split('-')[-1]))
        field = sub(r'History.*', 'History', history_field_name)
        if sender.currentIndex() != 0:
            field_name = history_field_name.replace("History", "")

            if field_name in self.fields:
                self.fields[field_name].set_plain_text(doc[field][index])

    def save_history(self, history_field_name):
        """Writes the history into the database."""
        if self.fields[history_field_name].currentIndex() == 0:
            field_tab = history_field_name.split('-')
            field_name = history_field_name.replace("History", "")

            value = self.fields[field_name].to_plain_text()

            history = self.database.search_by_id(int(
                field_tab[1]))[field_tab[0]]

            if value not in history:
                history.append(value)
            self.database.update(int(field_tab[1]), field_tab[0], history)

    def save_histories(self):
        """Writes all histories into the database."""
        for name in self.fields:
            if name.find("History-") > 0:
                self.save_history(name)

    def update_history(self, index):
        """Calls the parent function that updates the History field."""
        self._parent.update_history(self.sender().accessibleName(), self,
                                    index)

    def update_cvss(self, doc_id):
        """Computes the CVSS scores from the field values and writes it into the corresponding
        fields.
        """
        if "CVSS-" + str(doc_id) in self.fields:
            attack_vector = self.fields["AV-" + str(doc_id)].currentText()
            attack_complexity = self.fields["AC-" + str(doc_id)].currentText()
            privileges_required = self.fields["PR-" +
                                              str(doc_id)].currentText()
            user_interaction = self.fields["UI-" + str(doc_id)].currentText()
            scope = self.fields["S-" + str(doc_id)].currentText()
            confidentiality = self.fields["C-" + str(doc_id)].currentText()
            integrity = self.fields["I-" + str(doc_id)].currentText()
            availability = self.fields["A-" + str(doc_id)].currentText()

            cvss_values = list(
                cvssv3(attack_vector, attack_complexity, privileges_required,
                       user_interaction, scope, confidentiality, integrity,
                       availability))
            risk_level_values = list(
                risk_level(attack_vector, attack_complexity,
                           privileges_required, user_interaction, scope,
                           confidentiality, integrity, availability))

            self.fields["CVSS-" + str(doc_id)].setText(str(cvss_values[0]))
            self.fields["CVSSimp-" + str(doc_id)].setText(str(cvss_values[1]))
            self.fields["CVSSexp-" + str(doc_id)].setText(str(cvss_values[2]))

            self.fields["riskLvl-" + str(doc_id)].setText(risk_level_values[0])
            self.fields["impLvl-" + str(doc_id)].setText(risk_level_values[1])
            self.fields["expLvl-" + str(doc_id)].setText(risk_level_values[2])

    def enable_row(self):
        """Shows the row if all conditions are matched."""
        sender = self.sender()
        doc_id = sender.accessibleName().split('-')[1]

        enable = False
        if "isSelected" in dir(sender):
            if sender.isSelected():
                enable = True

        if "isChecked" in dir(sender):
            if sender.isChecked():
                enable = True

        if "currentIndex" in dir(sender):
            if sender.currentIndex() >= 2:
                enable = True

        if enable:
            self.values[doc_id] = self.database.search_by_id(int(doc_id))
            if "currentText" in dir(sender):
                self.values[doc_id]["status"] = sender.currentText()
        else:
            if doc_id in self.values:
                del self.values[doc_id]

    def update_auditor(self, string=None):
        """Gets the value of an auditor and copies it into the database."""
        sender = self.sender()
        field_name = sender.accessibleName()

        field_tab = field_name.split('-')

        if string is None:
            string = sender
        if "toString" in dir(string):
            string = string.toString()
        if "toHtml" in dir(string):
            string = string.toHtml()

        self.database.update(int(field_tab[1]), field_tab[0], string)

    def load(self, values):
        """Loads values into the database and displays it on the screen."""
        if "vulns" in self.fields:
            self.fields["vulns"].load(values)
            return

        if self.database is not None and "db" in values:
            creation_date = QDateTime.currentDateTime().toString(
                "yyyyMMdd-hhmmss")
            db_path = self.database.path + "-tmp-" + creation_date + ".json"
            default_values = self.database.default_values
            self.database.close()
            self.database = DBHandler(db_path, default_values)
            self.database.insert_multiple(values["db"])

            if self.add_fct is not None:
                self.row = 0
                self.lst = self.head_lst
                self.values.clear()
                self.fields.clear()

                items = self.database.get_all()
                for item in items:
                    self.add_fct(self.lst, item.doc_id, item)
                self.parse_lst()

        for name, value in values.items():
            if name.isdigit():
                doc_id = name
                if "check-" + doc_id in self.fields:
                    self.fields["check-" + doc_id].setCheckState(Qt.Checked)
                if "status" in value and "isVuln-" + doc_id in self.fields:
                    self.fields["isVuln-" + doc_id].setCurrentText(
                        value["status"])

            elif name in self.fields:
                field = self.fields[name]
                if "setText" in dir(field):
                    field.setText(value)
                if "setCurrentText" in dir(field):
                    field.setCurrentText(value)
                if "setDate" in dir(field):
                    field.setDate(QDate.fromString(value))

    def save(self, database=False):
        """Saves the values of lst into self.values and takes the values from the database to save
        them into self.values.
        """
        if "list" in self.fields:
            lst = self.fields["list"]
            cpt = 0
            out_lst = {}
            while cpt < lst.count():
                item = lst.item(cpt)

                if ((item.flags()
                     & Qt.ItemIsUserCheckable) == Qt.ItemIsUserCheckable):
                    out_lst[item.text()] = item.checkState()
                else:
                    out_lst[item.text()] = True

                cpt += 1
            self.values["list"] = out_lst

        if "vulns" in self.fields:
            self.values = self.fields["vulns"].save()
            self.values = OrderedDict(
                sorted(self.fields["vulns"].save().items()))

        if database and self.database is not None:
            self.values["db"] = self.database.get_all()
        return self.values

    def edit_vuln(self):
        """Adds the tab edition for the vuln corresponding to the sender and goes to it."""
        sender = self.sender()
        doc_id = sender.accessibleName().split("-")[1]
        vuln = self.database.search_by_id(int(doc_id))
        if len(LANGUAGES) > 1:
            first_lang = True
            lst = dict()
            for lang in LANGUAGES:
                if first_lang:
                    lst[lang] = vuln_editing(doc_id, vuln)
                    first_lang = False
                else:
                    lst[lang] = vuln_editing(doc_id, vuln, lang)
        else:
            lst = vuln_editing(doc_id, vuln)
        self._parent.add_tab(str(doc_id), lst, self.database)
        if len(LANGUAGES) > 1:
            for lang in LANGUAGES:
                self._parent.tabs[str(doc_id)][lang].update_cvss(doc_id)
        else:
            self._parent.tabs[str(doc_id)].update_cvss(doc_id)

    def see_changes_vuln(self):
        """Calls the "Vulns git" function see_changes_vuln."""
        self._parent.see_changes_vuln(
            self.sender().accessibleName().split("-")[1])

    def del_vuln(self):
        """Shows a vuln as deleted on first pressure on the button "delete" and removes the vuln
        on the second pressure.
        """
        sender = self.sender()
        doc_id = sender.accessibleName().split("-")[1]
        diff = self.fields["diff-" + doc_id]
        if diff.status() != DiffStatus.DELETED and diff.status(
        ) != DiffStatus.ADDED:
            diff.deleted()
            return

        name_lst = list()

        for name in self.fields:
            split = name.split("-")
            if len(split) > 1:
                if name.split("-")[1] == doc_id:
                    name_lst.append(name)

        for name in name_lst:
            self.grid.removeWidget(self.fields[name])
            self.fields[name].deleteLater()
            del self.fields[name]
            del self.lst[name]

        if doc_id in self.values:
            del self.values[doc_id]
        self.database.delete(int(doc_id))
        self.fields["categorySort"].update_values()

    def add_vuln(self):
        """Adds a vuln to the database and displays it as a newly added vuln."""
        doc_id = self.database.insert_record()
        lst = OrderedDict()
        add_vuln(lst, doc_id, self.database.search_by_id(doc_id))
        self.parse_lst(lst)
        for ident, field in lst.items():
            self.lst[ident] = field
        self.fields["categorySort"].connect_buttons(doc_id)
        self.fields["diff-" + str(doc_id)].added()

    def add_auditor(self):
        """Adds an auditor to the database and displays it."""
        doc_id = self.database.insert_record()
        lst = OrderedDict()
        add_people(lst, doc_id, self.database.search_by_id(doc_id))
        self.parse_lst(lst)
        for ident, field in lst.items():
            self.lst[ident] = field

    def del_auditor(self):
        """Checks for all selected auditors and remove them from the display and the database."""
        for ident, field in self.fields.items():
            selected = False
            if "isSelected" in dir(field):
                if field.isSelected():
                    selected = True

            if "isChecked" in dir(field):
                if field.isChecked():
                    selected = True

            if selected:
                for row in range(1, self.row + 1):
                    if self.grid.itemAtPosition(row, 0) is not None:
                        if self.grid.itemAtPosition(
                                row, 0).widget().accessibleName() == ident:
                            col = 0
                            while self.grid.itemAtPosition(row,
                                                           col) is not None:
                                name = self.grid.itemAtPosition(
                                    row, col).widget().accessibleName()
                                self.grid.removeWidget(self.fields[name])
                                self.fields[name].deleteLater()

                                del self.fields[name]
                                del self.lst[name]
                                col += 1

                            doc_id = ident[ident.find('-') + 1:]
                            self.database.delete(int(doc_id))

                            del self.values[doc_id]

                            self.del_auditor()

                            return

    def parse_lst(self, lst=None):
        """Parses the lst to create the objects correponding to the UI of the tab."""
        if lst is None:
            lst = self.lst

        for ident, field in lst.items():
            if "args" in field:
                widget = field["class"](*(field["args"] + [self]))
            elif "arg" in field:
                widget = field["class"](field["arg"], self)
                try:
                    getattr(widget, field["class"]).emit(field["arg"])
                except (TypeError, AttributeError):
                    pass
            else:
                widget = field["class"](self)

            widget.setAccessibleName(ident)
            self.fields[ident] = widget

            if "signal" in field:
                if "signalFct" in field:
                    getattr(widget, field["signal"]).connect(
                        getattr(self, field["signalFct"]))
                else:
                    getattr(widget, field["signal"]).connect(self.change_value)

            if "help" in field:
                widget.setToolTip(field["help"])

            if "list" in field:
                for line in field["list"]["lines"]:
                    line_list = field["list"]["class"](line, widget)
                    if "flags" in field["list"]:
                        line_list.setFlags(field["list"]["flags"])
                    if "setData" in field["list"]:
                        for arg1, arg2 in field["list"]["setData"].items():
                            line_list.setData(arg1, arg2)

            if "items" in field:
                for item in field["items"]:
                    widget.addItem(item)

            if "flags" in field:
                widget.setFlags(field["flags"])

            if "setLength" in field:
                char_width = widget.fontMetrics().averageCharWidth() * 1.1
                widget.setFixedWidth(int(char_width * field["setLength"]))

            if "setData" in field:
                for arg1, arg2 in field["setData"].items():
                    widget.setData(arg1, arg2)

            if "setCurrentText" in field:
                widget.setCurrentText(field["setCurrentText"])

            if "setText" in field:
                widget.setText(field["setText"])

            if "selectionMode" in field:
                widget.setSelectionMode(field["selectionMode"])

            if "clicked" in field:
                widget.clicked.connect(getattr(self, field["clicked"]))

            if "setStyleSheet" in field:
                widget.setStyleSheet(field["setStyleSheet"])

            if "setReadOnly" in field:
                widget.setReadOnly(field["setReadOnly"])

            if "selectionMode" in field:
                widget.setSelectionMode(field["selectionMode"])

            if "clicked" in field:
                widget.clicked.connect(getattr(self, field["clicked"]))

            if "setStyleSheet" in field:
                widget.setStyleSheet(field["setStyleSheet"])

            if "setReadOnly" in field:
                widget.setReadOnly(field["setReadOnly"])

            if "label" in field:
                label = QLabel(field["label"])
                self.grid.addWidget(label, self.row, 0)
                self.grid.addWidget(widget, self.row, 1, 1, -1)
            elif "col" in field:
                if field["col"] > 0:
                    self.row -= 1
                if "colspan" in field:
                    self.grid.addWidget(widget, self.row + 1, field["col"], 1,
                                        field["colspan"])
                else:
                    self.grid.addWidget(widget, self.row + 1, field["col"])
            else:
                self.grid.addWidget(widget, self.row, 0, 1, 2)

            self.row += 1
示例#8
0
    def refresh_repator(self, repator, index=[]):
        """Rebuilds the objs widget repator with the tabs currently open (without index)"""
        if self.obj == "vulns":
            objs = repator.layout().itemAt(0).widget().widget(
                3).fields["vulns"]
        elif self.obj == "auditors":
            objs = repator.layout().itemAt(0).widget().widget(1)
        elif self.obj == "clients":
            objs = repator.layout().itemAt(0).widget().widget(2)
        else:
            return

        # save the status
        if self.obj == "vulns":
            saved_status = {}
            for name, obj_class in objs.tabs["All"].fields.items():
                name = name.split("-")
                if len(name) > 1 and name[0] == "isVuln":
                    saved_status[name[1]] = obj_class.currentText()
            tabs = []

            #save the current opened tabs (only vulns, without index)
            for i in range(objs.tabw.tabBar().count() - 1, 0, -1):
                if i not in index:
                    tabs.append(objs.tabw.tabBar().tabText(i))
                self.tabw.tabBar().removeTab(i)

            if index:
                for i in index:
                    if i in tabs:
                        tabs.remove(i)

        else:
            saved_checked = {}
            for name, obj_class in objs.fields.items():
                name = name.split("-")
                if len(name) > 1 and name[0] == "check":
                    saved_checked[name[1]] = obj_class.checkState()
        # rebuild the objs
        if self.obj == "vulns":
            objs.tabw.deleteLater()
            del objs.database
            objs.database = DBHandler.vulns()  # TODO adapt for each self.obj
            objs.tabs = {}
        objs.lst = copy(VULNS) if self.obj == "vulns" else copy(PEOPLE)
        objs.init_tab()
        if self.obj == "vulns":
            objs.grid.replaceWidget(objs.layout().itemAt(0).widget(),
                                    objs.tabw)

            # re-open the tabs edit (vulns only)
            for doc_id in reversed(tabs):
                objs.tabs["All"].fields["edit-" + doc_id].animateClick()
            objs.tabw.setCurrentWidget(objs.tabs["All"])

            # redo the status
            for number, status in saved_status.items():
                if "isVuln-" + number in objs.tabs["All"].fields:
                    objs.tabs["All"].fields["isVuln-" +
                                            number].setCurrentText(status)
        else:  # redo the status
            for number, checked in saved_checked.items():
                if "check-" + number in objs.fields:
                    objs.fields["check-" + number].setCheckState(checked)