mirror of
https://github.com/trustedsec/hate_crack.git
synced 2026-04-28 03:53:10 -07:00
style: ruff format pass for Notifications submenu
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -401,7 +401,9 @@ if hcatOptimizedWordlists:
|
||||
if not os.path.isdir(hcatOptimizedWordlists):
|
||||
fallback_optimized = os.path.join(hate_path, "optimized_wordlists")
|
||||
if os.path.isdir(fallback_optimized):
|
||||
print(f"[!] hcatOptimizedWordlists directory not found: {hcatOptimizedWordlists}")
|
||||
print(
|
||||
f"[!] hcatOptimizedWordlists directory not found: {hcatOptimizedWordlists}"
|
||||
)
|
||||
print(f"[!] Falling back to {fallback_optimized}")
|
||||
hcatOptimizedWordlists = fallback_optimized
|
||||
else:
|
||||
@@ -417,8 +419,12 @@ pipalPath = config_parser["pipalPath"]
|
||||
hcatDictionaryWordlist = config_parser["hcatDictionaryWordlist"]
|
||||
hcatHybridlist = config_parser["hcatHybridlist"]
|
||||
hcatCombinationWordlist = config_parser["hcatCombinationWordlist"]
|
||||
hcatCombinator3Wordlist = config_parser.get("hcatCombinator3Wordlist", ["rockyou.txt", "rockyou.txt", "rockyou.txt"])
|
||||
hcatCombinatorXWordlist = config_parser.get("hcatCombinatorXWordlist", ["rockyou.txt", "rockyou.txt"])
|
||||
hcatCombinator3Wordlist = config_parser.get(
|
||||
"hcatCombinator3Wordlist", ["rockyou.txt", "rockyou.txt", "rockyou.txt"]
|
||||
)
|
||||
hcatCombinatorXWordlist = config_parser.get(
|
||||
"hcatCombinatorXWordlist", ["rockyou.txt", "rockyou.txt"]
|
||||
)
|
||||
hcatMiddleCombinatorMasks = config_parser["hcatMiddleCombinatorMasks"]
|
||||
hcatMiddleBaseList = config_parser["hcatMiddleBaseList"]
|
||||
hcatThoroughCombinatorMasks = config_parser["hcatThoroughCombinatorMasks"]
|
||||
@@ -584,8 +590,12 @@ hcatDictionaryWordlist = _normalize_wordlist_setting(
|
||||
hcatCombinationWordlist = _normalize_wordlist_setting(
|
||||
hcatCombinationWordlist, wordlists_dir
|
||||
)
|
||||
hcatCombinator3Wordlist = _normalize_wordlist_setting(hcatCombinator3Wordlist, wordlists_dir)
|
||||
hcatCombinatorXWordlist = _normalize_wordlist_setting(hcatCombinatorXWordlist, wordlists_dir)
|
||||
hcatCombinator3Wordlist = _normalize_wordlist_setting(
|
||||
hcatCombinator3Wordlist, wordlists_dir
|
||||
)
|
||||
hcatCombinatorXWordlist = _normalize_wordlist_setting(
|
||||
hcatCombinatorXWordlist, wordlists_dir
|
||||
)
|
||||
hcatHybridlist = _normalize_wordlist_setting(hcatHybridlist, wordlists_dir)
|
||||
hcatMiddleBaseList = _normalize_wordlist_setting(hcatMiddleBaseList, wordlists_dir)
|
||||
hcatThoroughBaseList = _normalize_wordlist_setting(hcatThoroughBaseList, wordlists_dir)
|
||||
@@ -2397,8 +2407,14 @@ def hcatMarkovTrain(source_file, hcatHashFile):
|
||||
hcatProcess.wait(timeout=300)
|
||||
if hcatProcess.returncode != 0:
|
||||
_, stderr_data = hcatProcess.communicate()
|
||||
err_msg = stderr_data.decode("utf-8", errors="replace") if stderr_data else "Unknown error"
|
||||
print(f"[!] hcstat2gen.bin failed with code {hcatProcess.returncode}: {err_msg}")
|
||||
err_msg = (
|
||||
stderr_data.decode("utf-8", errors="replace")
|
||||
if stderr_data
|
||||
else "Unknown error"
|
||||
)
|
||||
print(
|
||||
f"[!] hcstat2gen.bin failed with code {hcatProcess.returncode}: {err_msg}"
|
||||
)
|
||||
return False
|
||||
except subprocess.TimeoutExpired:
|
||||
print("[!] hcstat2gen.bin timed out after 300 seconds")
|
||||
@@ -3011,7 +3027,9 @@ def cleanup():
|
||||
if os.path.isfile(out_path):
|
||||
print(f"\nCracked passwords combined with original hashes in {out_path}")
|
||||
else:
|
||||
print(f"\nNo cracked hashes to combine. Raw output (if any): {hcatHashFile}.out")
|
||||
print(
|
||||
f"\nNo cracked hashes to combine. Raw output (if any): {hcatHashFile}.out"
|
||||
)
|
||||
print("\nCleaning up temporary files...")
|
||||
if os.path.exists(hcatHashFile + ".masks"):
|
||||
os.remove(hcatHashFile + ".masks")
|
||||
@@ -3813,9 +3831,7 @@ def wordlist_filter_req_exclude(infile: str, outfile: str, mask: int) -> bool:
|
||||
return result.returncode == 0
|
||||
|
||||
|
||||
def wordlist_cutb(
|
||||
infile: str, outfile: str, offset: int, length: int | None
|
||||
) -> bool:
|
||||
def wordlist_cutb(infile: str, outfile: str, offset: int, length: int | None) -> bool:
|
||||
"""Extract a substring from each word starting at offset, optionally limited to length bytes."""
|
||||
cutb_bin = os.path.join(hate_path, "hashcat-utils/bin/cutb.bin")
|
||||
cmd = [cutb_bin, str(offset)]
|
||||
@@ -3853,7 +3869,9 @@ def wordlist_gate(infile: str, outfile: str, mod: int, offset: int) -> bool:
|
||||
"""Shard wordlist: keep every mod-th line starting at offset."""
|
||||
gate_bin = os.path.join(hate_path, "hashcat-utils/bin/gate.bin")
|
||||
with open(infile, "rb") as fin, open(outfile, "wb") as fout:
|
||||
result = subprocess.run([gate_bin, str(mod), str(offset)], stdin=fin, stdout=fout)
|
||||
result = subprocess.run(
|
||||
[gate_bin, str(mod), str(offset)], stdin=fin, stdout=fout
|
||||
)
|
||||
return result.returncode == 0
|
||||
|
||||
|
||||
@@ -3871,7 +3889,9 @@ def rules_cleanup(infile: str, outfile: str) -> bool:
|
||||
|
||||
def rules_optimize(infile: str, outfile: str) -> bool:
|
||||
"""Optimize a rule file using rules_optimize.bin. Returns True on success."""
|
||||
optimize_path = os.path.join(hate_path, "hashcat-utils", "bin", "rules_optimize.bin")
|
||||
optimize_path = os.path.join(
|
||||
hate_path, "hashcat-utils", "bin", "rules_optimize.bin"
|
||||
)
|
||||
with open(infile, "rb") as fin, open(outfile, "wb") as fout:
|
||||
result = subprocess.run([optimize_path], stdin=fin, stdout=fout)
|
||||
return result.returncode == 0
|
||||
|
||||
@@ -84,8 +84,12 @@ def load_settings(config_parser: dict | None) -> NotifySettings:
|
||||
defaults = NotifySettings()
|
||||
return NotifySettings(
|
||||
enabled=_coerce_bool(cfg.get("notify_enabled"), defaults.enabled),
|
||||
pushover_token=_coerce_str(cfg.get("notify_pushover_token"), defaults.pushover_token),
|
||||
pushover_user=_coerce_str(cfg.get("notify_pushover_user"), defaults.pushover_user),
|
||||
pushover_token=_coerce_str(
|
||||
cfg.get("notify_pushover_token"), defaults.pushover_token
|
||||
),
|
||||
pushover_user=_coerce_str(
|
||||
cfg.get("notify_pushover_user"), defaults.pushover_user
|
||||
),
|
||||
per_crack_enabled=_coerce_bool(
|
||||
cfg.get("notify_per_crack_enabled"), defaults.per_crack_enabled
|
||||
),
|
||||
|
||||
@@ -6,6 +6,7 @@ and resolves ``toggle_notifications`` / ``toggle_per_crack_notifications`` /
|
||||
We therefore patch that module directly — patching the ``hate_crack.py``
|
||||
proxy would have no effect on the submenu's internal dispatch.
|
||||
"""
|
||||
|
||||
import hate_crack.main as _main_mod
|
||||
import hate_crack.menu as _menu_mod
|
||||
from hate_crack.notify.settings import NotifySettings
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Unit tests for the toggle_per_crack_enabled runtime toggle."""
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
@@ -80,9 +81,7 @@ class TestTogglePerCrackNotificationsUI:
|
||||
from hate_crack.notify.settings import NotifySettings
|
||||
|
||||
settings = NotifySettings(enabled=enabled, per_crack_enabled=per_crack)
|
||||
monkeypatch.setattr(
|
||||
CLI_MODULE._notify, "get_settings", lambda: settings
|
||||
)
|
||||
monkeypatch.setattr(CLI_MODULE._notify, "get_settings", lambda: settings)
|
||||
return settings
|
||||
|
||||
def test_guard_refuses_on_when_global_off(self, monkeypatch, capsys):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Unit tests for hate_crack.notify.settings."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
@@ -40,16 +41,18 @@ class TestLoadSettings:
|
||||
assert load_settings(None) == NotifySettings()
|
||||
|
||||
def test_load_full_dict(self) -> None:
|
||||
s = load_settings({
|
||||
"notify_enabled": True,
|
||||
"notify_pushover_token": "tok",
|
||||
"notify_pushover_user": "usr",
|
||||
"notify_per_crack_enabled": True,
|
||||
"notify_attack_allowlist": ["Brute Force", "Dictionary"],
|
||||
"notify_suppress_in_orchestrators": False,
|
||||
"notify_max_cracks_per_burst": 20,
|
||||
"notify_poll_interval_seconds": 2.5,
|
||||
})
|
||||
s = load_settings(
|
||||
{
|
||||
"notify_enabled": True,
|
||||
"notify_pushover_token": "tok",
|
||||
"notify_pushover_user": "usr",
|
||||
"notify_per_crack_enabled": True,
|
||||
"notify_attack_allowlist": ["Brute Force", "Dictionary"],
|
||||
"notify_suppress_in_orchestrators": False,
|
||||
"notify_max_cracks_per_burst": 20,
|
||||
"notify_poll_interval_seconds": 2.5,
|
||||
}
|
||||
)
|
||||
assert s.enabled is True
|
||||
assert s.pushover_token == "tok"
|
||||
assert s.pushover_user == "usr"
|
||||
@@ -60,12 +63,14 @@ class TestLoadSettings:
|
||||
assert s.poll_interval_seconds == 2.5
|
||||
|
||||
def test_load_tolerates_bad_types(self) -> None:
|
||||
s = load_settings({
|
||||
"notify_enabled": "true",
|
||||
"notify_max_cracks_per_burst": "not-a-number",
|
||||
"notify_poll_interval_seconds": "also-bad",
|
||||
"notify_attack_allowlist": "not-a-list",
|
||||
})
|
||||
s = load_settings(
|
||||
{
|
||||
"notify_enabled": "true",
|
||||
"notify_max_cracks_per_burst": "not-a-number",
|
||||
"notify_poll_interval_seconds": "also-bad",
|
||||
"notify_attack_allowlist": "not-a-list",
|
||||
}
|
||||
)
|
||||
# string "true" -> True
|
||||
assert s.enabled is True
|
||||
# bad ints fall back to defaults (5, 5.0)
|
||||
@@ -136,10 +141,14 @@ class TestAddToAllowlist:
|
||||
|
||||
def test_preserves_other_entries(self, tmp_path: Path) -> None:
|
||||
config_path = tmp_path / "config.json"
|
||||
config_path.write_text(json.dumps({
|
||||
"hcatBin": "hashcat",
|
||||
"notify_attack_allowlist": ["Existing"],
|
||||
}))
|
||||
config_path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"hcatBin": "hashcat",
|
||||
"notify_attack_allowlist": ["Existing"],
|
||||
}
|
||||
)
|
||||
)
|
||||
add_to_allowlist(str(config_path), "Brute Force")
|
||||
data = json.loads(config_path.read_text())
|
||||
assert data["hcatBin"] == "hashcat"
|
||||
|
||||
Reference in New Issue
Block a user