Exemple #1
0
    def _reap(self, now=False):
        if self.reaped:
            return True

        if now and self.proc.poll() is None:
            # Wait for the first process to stop executing
            self.proc.wait()

        if self.proc.poll() is not None:
            # Stop ___hashcat_writer_thread as soon as possible (takes a bit because of the sleep(1))
            self.stop_in_thread = True  # This stops the ___hashcat_writer_thread

            # The process stopped executing, close it's write pipes
            self.err_w = SingleProcess._close_helper(
                self.err_w)[0]  # Stops err_reader_thread
            self.out_w = SingleProcess._close_helper(
                self.out_w)[0]  # Stops out_reader_thread

            # After we closed the writing end of the pipe _all_reader_thread should stop
            self.err_reader_thread = SingleProcess._join_helper(
                self.err_reader_thread)[0]
            self.out_reader_thread = SingleProcess._join_helper(
                self.out_reader_thread)[0]

            # This process might take a bit to shutdown because it has a sleep(1)
            # Mark stop_in_thread as true ASAP in order to give the thread time to stop
            self.in_writer_thread = SingleProcess._join_helper(
                self.in_writer_thread)[0]

            # Convert error from list to string
            self.err = "".join(self.err)

            # Mark the second process as completely stopped
            self.reaped = True

            if self.critical and self.proc.poll() != 0:
                # Second process could be hashcat which sometimes returns 1 but no error
                if SingleProcess.command_is_hashcat(
                        self.cmd) and self.proc.poll() != 1:
                    Comunicator.debug_logger(
                        "Process %s exited with status %d. Stderr:\n%s" %
                        (self.cmd, self.proc.poll(), self.err))
                    self._force_cleanup()
                    Comunicator.fatal_debug_printer(
                        "Fatal error encountered in critical single process. See logs."
                    )

            return True
        return False
Exemple #2
0
    def _reap_snd(self, now=False):
        if self.snd_reaped:
            return True

        if now and self.snd_proc.poll() is None:
            self.snd_proc.wait()
            # self.snd_out, _ = self.snd_proc.get_output()

        if self.snd_proc.poll() is not None:
            # Process stopped so close the writing end of the pipes
            self.snd_err_w.close()
            self.snd_err_w = None

            self.snd_out_w.close()
            self.snd_out_w = None

            # Cleanup the reading pipe
            self.comm_r.close()
            self.comm_r = None

            # After we closed the writing end of the pipe _all_reader_thread should stop
            self.snd_err_reader_thread.join()
            self.snd_err_reader_thread = None

            self.snd_out_reader_thread.join()
            self.snd_out_reader_thread = None

            # Convert error from list to string
            self.snd_err = "".join(self.snd_err)

            # Mark the second process as completely stopped
            self.snd_reaped = True

            if self.critical and self.snd_proc.poll() != 0:
                # Second process could be hashcat which sometimes returns 1 but no error
                if DoubleProcess.command_is_hashcat(
                        self.snd_cmd) and self.snd_proc.poll() != 1:
                    Comunicator.debug_logger(
                        "Second process %s exited with status %d. Stderr:\n%s"
                        % (self.snd_cmd, self.snd_proc.poll(), self.snd_err))
                    self._force_cleanup()
                    Comunicator.fatal_debug_printer(
                        "Fatal error encountered in critical second process. See logs."
                    )

            return True

        return False
Exemple #3
0
    def __init__(self, fst_cmd, snd_cmd, crit=True):
        super(DoubleProcess, self).__init__()
        if len(fst_cmd) == 0 or len(snd_cmd) == 0:
            Comunicator.fatal_debug_printer(
                "One empty command in chained processes '%s' | '%s'" %
                (fst_cmd, snd_cmd))

        self.critical = crit
        self.ended = False

        # Logging data
        self.command = fst_cmd + ' | ' + snd_cmd
        self.fst_cmd = fst_cmd
        self.snd_cmd = snd_cmd

        disp1 = fst_cmd if type(fst_cmd) is str else " ".join(fst_cmd)
        disp2 = snd_cmd if type(snd_cmd) is str else " ".join(snd_cmd)

        Comunicator.debug_logger("Executing chained commands: '%s | %s'" %
                                 (disp1, disp2))

        # Output variables need to be mutable in order to modify them
        # from generic thread
        self.snd_out = []
        self.snd_err = []
        self.fst_err = []

        self.comm_r, self.comm_w = DoubleProcess.get_pipe_wrapper()
        self.snd_out_r, self.snd_out_w = DoubleProcess.get_pipe_wrapper()
        self.fst_err_r, self.fst_err_w = DoubleProcess.get_pipe_wrapper()
        self.snd_err_r, self.snd_err_w = DoubleProcess.get_pipe_wrapper()

        self.fst_reaped = False
        self.snd_reaped = False

        # Why an entire thread just to read from pipes?
        # Because if a pipe is full the program writing to the pipe will
        # get stuck until data is read from the pipe. If we simply call
        # wait for the process without reading data it will get stuck.
        # If we call readlines before we wait we might get stuck because
        # the writing end of the pipe is never closed... despite the program
        # not running anymore.
        self.fst_err_reader_thread = Thread(target=self._all_reader_thread,
                                            args=(self.fst_err_r,
                                                  self.fst_err))
        self.snd_err_reader_thread = Thread(target=self._all_reader_thread,
                                            args=(self.snd_err_r,
                                                  self.snd_err))

        if DoubleProcess.command_is_hashcat(self.snd_cmd):
            self.snd_out_reader_thread = Thread(
                target=self._hashcat_out_thread,
                args=(self.snd_out_r, self.snd_out, self.hashcat_progress,
                      self))
        else:
            self.snd_out_reader_thread = Thread(target=self._all_reader_thread,
                                                args=(self.snd_out_r,
                                                      self.snd_out))

        if type(snd_cmd) is str:
            snd_cmd = snd_cmd.split(' ')
        try:
            self.snd_proc = Popen(snd_cmd,
                                  stdin=self.comm_r,
                                  stdout=self.snd_out_w,
                                  stderr=self.snd_err_w)
        except Exception as e:
            Comunicator.fatal_debug_printer(
                "Error while trying to run command '%s':\n%s" % (snd_cmd, e))

        if type(fst_cmd) is str:
            fst_cmd = fst_cmd.split(' ')
        try:
            self.fst_proc = Popen(fst_cmd,
                                  stdin=DoubleProcess.get_devnull_r(),
                                  stdout=self.comm_w,
                                  stderr=self.fst_err_w)
        except Exception as e:
            Comunicator.fatal_debug_printer(
                "Error while trying to run command '%s':\n%s" % (fst_cmd, e))

        self.fst_err_reader_thread.start()
        self.snd_err_reader_thread.start()
        self.snd_out_reader_thread.start()