From fda0722242928648e3c62fabbf4b4cb56c430182 Mon Sep 17 00:00:00 2001 From: Melvin Frederiks Date: Tue, 7 Apr 2026 10:32:57 +0200 Subject: [PATCH 1/2] Actually wait on the password workers before finishing --- rulegen.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/rulegen.py b/rulegen.py index 29397f4..e6fa0df 100755 --- a/rulegen.py +++ b/rulegen.py @@ -1006,9 +1006,11 @@ def analyze_passwords_file(self, passwords_file): words_queue = multiprocessing.Queue() # Start workers + pw_procs = [] for i in range(self.threads): - multiprocessing.Process(target=self.password_worker, - args=(i, passwords_queue, rules_queue, words_queue)).start() + pw_procs.append(multiprocessing.Process(target=self.password_worker, + args=(i, passwords_queue, rules_queue, words_queue))) + pw_procs[i].start() multiprocessing.Process(target=self.rule_worker, args=(rules_queue, "%s.rule" % self.basename)).start() multiprocessing.Process(target=self.word_worker, args=(words_queue, "%s.word" % self.basename)).start() @@ -1045,9 +1047,9 @@ def analyze_passwords_file(self, passwords_file): for i in range(self.threads): passwords_queue.put(None) - # Wait for all of the queued passwords to finish. - while not passwords_queue.empty(): - time.sleep(1) + # Wait for all of the queued passwords to finish. + for proc in pw_procs: + proc.join() # Signal writers to stop. rules_queue.put(None) From 50ce9ebe1acdc8b9cbb8324c981e31857c94ac2a Mon Sep 17 00:00:00 2001 From: Melvin Frederiks Date: Wed, 8 Apr 2026 10:04:08 +0200 Subject: [PATCH 2/2] Fixed string formatting using raw strings --- maskgen.py | 18 +++++++++--------- policygen.py | 18 +++++++++--------- rulegen.py | 22 +++++++++++----------- statsgen.py | 18 +++++++++--------- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/maskgen.py b/maskgen.py index 2147a87..ca112bf 100755 --- a/maskgen.py +++ b/maskgen.py @@ -179,15 +179,15 @@ def getmaskscoverage(self, checkmasks): if __name__ == "__main__": - header = " _ \n" - header += " MaskGen %s | |\n" % VERSION - header += " _ __ __ _ ___| | _\n" - header += " | '_ \ / _` |/ __| |/ /\n" - header += " | |_) | (_| | (__| < \n" - header += " | .__/ \__,_|\___|_|\_\\\n" - header += " | | \n" - header += " |_| iphelix@thesprawl.org\n" - header += "\n" + header = " _ \n" + header += " MaskGen %s | |\n" % VERSION + header += " _ __ __ _ ___| | _\n" + header += r" | '_ \ / _` |/ __| |/ /" + "\n" + header += " | |_) | (_| | (__| < \n" + header += r" | .__/ \__,_|\___|_|\_\ " + "\n" + header += " | | \n" + header += " |_| iphelix@thesprawl.org\n" + header += "\n" parser = OptionParser("%prog pass0.masks [pass1.masks ...] [options]", version="%prog "+VERSION) diff --git a/policygen.py b/policygen.py index 108d759..d185875 100755 --- a/policygen.py +++ b/policygen.py @@ -148,15 +148,15 @@ def generate_masks(self, noncompliant): if __name__ == "__main__": - header = " _ \n" - header += " PolicyGen %s | |\n" % VERSION - header += " _ __ __ _ ___| | _\n" - header += " | '_ \ / _` |/ __| |/ /\n" - header += " | |_) | (_| | (__| < \n" - header += " | .__/ \__,_|\___|_|\_\\\n" - header += " | | \n" - header += " |_| iphelix@thesprawl.org\n" - header += "\n" + header = " _ \n" + header += " PolicyGen %s | |\n" % VERSION + header += " _ __ __ _ ___| | _\n" + header += r" | '_ \ / _` |/ __| |/ /" + "\n" + header += " | |_) | (_| | (__| < \n" + header += r" | .__/ \__,_|\___|_|\_\ " + "\n" + header += " | | \n" + header += " |_| iphelix@thesprawl.org\n" + header += "\n" # parse command line arguments parser = OptionParser("%prog [options]\n\nType --help for more options", version="%prog " + VERSION) diff --git a/rulegen.py b/rulegen.py index e6fa0df..a407378 100755 --- a/rulegen.py +++ b/rulegen.py @@ -73,8 +73,8 @@ def __init__(self, language="en", providers="aspell,myspell", basename='analysis # Preanalysis Password Patterns self.password_pattern = dict() self.password_pattern["insertion"] = re.compile('^[^a-z]*(?P.+?)[^a-z]*$', re.IGNORECASE) - self.password_pattern["email"] = re.compile('^(?P.+?)@[A-Z0-9.-]+\.[A-Z]{2,4}', re.IGNORECASE) - self.password_pattern["alldigits"] = re.compile('^(\d+)$', re.IGNORECASE) + self.password_pattern["email"] = re.compile(r'^(?P.+?)@[A-Z0-9.-]+\.[A-Z]{2,4}', re.IGNORECASE) + self.password_pattern["alldigits"] = re.compile(r'^(\d+)$', re.IGNORECASE) self.password_pattern["allspecial"] = re.compile('^([^a-z0-9]+)$', re.IGNORECASE) ######################################################################## @@ -1131,15 +1131,15 @@ def verify_hashcat_rules(self, word, rules, password): if __name__ == "__main__": - header = " _ \n" - header += " RuleGen %s | |\n" % VERSION - header += " _ __ __ _ ___| | _\n" - header += " | '_ \ / _` |/ __| |/ /\n" - header += " | |_) | (_| | (__| < \n" - header += " | .__/ \__,_|\___|_|\_\\\n" - header += " | | \n" - header += " |_| iphelix@thesprawl.org\n" - header += "\n" + header = " _ \n" + header += " RuleGen %s | |\n" % VERSION + header += " _ __ __ _ ___| | _\n" + header += r" | '_ \ / _` |/ __| |/ /" + "\n" + header += " | |_) | (_| | (__| < \n" + header += r" | .__/ \__,_|\___|_|\_\ " + "\n" + header += " | | \n" + header += " |_| iphelix@thesprawl.org\n" + header += "\n" parser = OptionParser("%prog [options] passwords.txt", version="%prog " + VERSION) diff --git a/statsgen.py b/statsgen.py index d6f174a..3dc135f 100755 --- a/statsgen.py +++ b/statsgen.py @@ -241,15 +241,15 @@ def print_stats(self): if __name__ == "__main__": - header = " _ \n" - header += " StatsGen %s | |\n" % VERSION - header += " _ __ __ _ ___| | _\n" - header += " | '_ \ / _` |/ __| |/ /\n" - header += " | |_) | (_| | (__| < \n" - header += " | .__/ \__,_|\___|_|\_\\\n" - header += " | | \n" - header += " |_| iphelix@thesprawl.org\n" - header += "\n" + header = " _ \n" + header += " StatsGen %s | |\n" % VERSION + header += " _ __ __ _ ___| | _\n" + header += r" | '_ \ / _` |/ __| |/ /" + "\n" + header += " | |_) | (_| | (__| < \n" + header += r" | .__/ \__,_|\___|_|\_\ " + "\n" + header += " | | \n" + header += " |_| iphelix@thesprawl.org\n" + header += "\n" parser = OptionParser("%prog [options] passwords.txt\n\nType --help for more options", version="%prog "+VERSION)