mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-09 15:58:48 +00:00
Fix Windows TOTP and PGP issues
This commit is contained in:
@@ -18,9 +18,9 @@ import hashlib
|
||||
from typing import Optional
|
||||
import shutil
|
||||
import time
|
||||
import select
|
||||
import builtins
|
||||
from termcolor import colored
|
||||
from utils.input_utils import timed_input
|
||||
|
||||
from password_manager.encryption import EncryptionManager
|
||||
from password_manager.entry_management import EntryManager
|
||||
@@ -1285,14 +1285,12 @@ class PasswordManager:
|
||||
sys.stdout.write(f"\r{bar} {remaining:2d}s")
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
if (
|
||||
sys.stdin
|
||||
in select.select([sys.stdin], [], [], 1)[0]
|
||||
):
|
||||
user_input = sys.stdin.readline().strip().lower()
|
||||
if user_input == "b":
|
||||
exit_loop = True
|
||||
break
|
||||
user_input = timed_input("", 1)
|
||||
if user_input.strip().lower() == "b":
|
||||
exit_loop = True
|
||||
break
|
||||
except TimeoutError:
|
||||
pass
|
||||
except KeyboardInterrupt:
|
||||
exit_loop = True
|
||||
print()
|
||||
@@ -2009,10 +2007,11 @@ class PasswordManager:
|
||||
print(f"[{idx}] {label}: {code} {bar} {remaining:2d}s")
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
if sys.stdin in select.select([sys.stdin], [], [], 1)[0]:
|
||||
user_input = sys.stdin.readline().strip().lower()
|
||||
if user_input == "b":
|
||||
break
|
||||
user_input = timed_input("", 1)
|
||||
if user_input.strip().lower() == "b":
|
||||
break
|
||||
except TimeoutError:
|
||||
pass
|
||||
except KeyboardInterrupt:
|
||||
print()
|
||||
break
|
||||
|
@@ -30,6 +30,15 @@ from cryptography.hazmat.primitives.asymmetric import ed25519
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from bip_utils import Bip39SeedGenerator
|
||||
|
||||
# Ensure the ``imghdr`` module is available for ``pgpy`` on Python 3.13+
|
||||
try: # pragma: no cover - only executed on Python >= 3.13
|
||||
import imghdr # type: ignore
|
||||
except ModuleNotFoundError: # pragma: no cover - fallback for removed module
|
||||
from utils import imghdr_stub as imghdr # type: ignore
|
||||
import sys
|
||||
|
||||
sys.modules.setdefault("imghdr", imghdr)
|
||||
|
||||
from local_bip85.bip85 import BIP85
|
||||
|
||||
from constants import DEFAULT_PASSWORD_LENGTH, MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH
|
||||
|
@@ -50,7 +50,7 @@ def test_handle_display_totp_codes(monkeypatch, capsys):
|
||||
|
||||
# interrupt the loop after first iteration
|
||||
monkeypatch.setattr(
|
||||
"password_manager.manager.select.select",
|
||||
"password_manager.manager.timed_input",
|
||||
lambda *a, **k: (_ for _ in ()).throw(KeyboardInterrupt()),
|
||||
)
|
||||
|
||||
@@ -91,7 +91,7 @@ def test_display_totp_codes_excludes_blacklisted(monkeypatch, capsys):
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
"password_manager.manager.select.select",
|
||||
"password_manager.manager.timed_input",
|
||||
lambda *a, **k: (_ for _ in ()).throw(KeyboardInterrupt()),
|
||||
)
|
||||
|
||||
|
@@ -69,10 +69,9 @@ def test_list_entries_show_details(monkeypatch, capsys):
|
||||
pm.entry_manager, "get_totp_time_remaining", lambda *a, **k: 1
|
||||
)
|
||||
monkeypatch.setattr("password_manager.manager.time.sleep", lambda *a, **k: None)
|
||||
monkeypatch.setattr(sys.stdin, "readline", lambda *a, **k: "b\n")
|
||||
monkeypatch.setattr(
|
||||
"password_manager.manager.select.select",
|
||||
lambda *a, **k: ([sys.stdin], [], []),
|
||||
"password_manager.manager.timed_input",
|
||||
lambda *a, **k: "b",
|
||||
)
|
||||
|
||||
inputs = iter(["1", "0"])
|
||||
|
@@ -49,10 +49,9 @@ def test_handle_retrieve_totp_entry(monkeypatch, capsys):
|
||||
pm.entry_manager, "get_totp_time_remaining", lambda *a, **k: 1
|
||||
)
|
||||
monkeypatch.setattr("password_manager.manager.time.sleep", lambda *a, **k: None)
|
||||
monkeypatch.setattr(sys.stdin, "readline", lambda *a, **k: "b\n")
|
||||
monkeypatch.setattr(
|
||||
"password_manager.manager.select.select",
|
||||
lambda *a, **k: ([sys.stdin], [], []),
|
||||
"password_manager.manager.timed_input",
|
||||
lambda *a, **k: "b",
|
||||
)
|
||||
|
||||
pm.handle_retrieve_entry()
|
||||
|
@@ -66,7 +66,7 @@ def test_totp_display_secret_mode(monkeypatch, capsys):
|
||||
pm.entry_manager, "get_totp_time_remaining", lambda *a, **k: 30
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"password_manager.manager.select.select",
|
||||
"password_manager.manager.timed_input",
|
||||
lambda *a, **k: (_ for _ in ()).throw(KeyboardInterrupt()),
|
||||
)
|
||||
called = []
|
||||
@@ -115,7 +115,7 @@ def test_totp_display_no_secret_mode(monkeypatch, capsys):
|
||||
pm.entry_manager, "get_totp_time_remaining", lambda *a, **k: 30
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"password_manager.manager.select.select",
|
||||
"password_manager.manager.timed_input",
|
||||
lambda *a, **k: (_ for _ in ()).throw(KeyboardInterrupt()),
|
||||
)
|
||||
called = []
|
||||
|
216
src/utils/imghdr_stub.py
Normal file
216
src/utils/imghdr_stub.py
Normal file
@@ -0,0 +1,216 @@
|
||||
"""Compat module providing :mod:`imghdr` for Python 3.13+.
|
||||
|
||||
This is a copy of Python 3.12's :mod:`imghdr` module which was removed in
|
||||
Python 3.13. It is used by the ``pgpy`` dependency when deriving PGP keys.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from os import PathLike
|
||||
import warnings
|
||||
|
||||
__all__ = ["what"]
|
||||
|
||||
warnings._deprecated(__name__, remove=(3, 13))
|
||||
|
||||
# -------------------------
|
||||
# Recognize image headers
|
||||
# -------------------------
|
||||
|
||||
|
||||
def what(file, h=None):
|
||||
"""Return the type of image contained in a file or byte stream."""
|
||||
f = None
|
||||
try:
|
||||
if h is None:
|
||||
if isinstance(file, (str, PathLike)):
|
||||
f = open(file, "rb")
|
||||
h = f.read(32)
|
||||
else:
|
||||
location = file.tell()
|
||||
h = file.read(32)
|
||||
file.seek(location)
|
||||
for tf in tests:
|
||||
res = tf(h, f)
|
||||
if res:
|
||||
return res
|
||||
finally:
|
||||
if f:
|
||||
f.close()
|
||||
return None
|
||||
|
||||
|
||||
# ---------------------------------
|
||||
# Subroutines per image file type
|
||||
# ---------------------------------
|
||||
|
||||
tests: list = []
|
||||
|
||||
|
||||
def test_jpeg(h, f):
|
||||
"""Test for JPEG data with JFIF or Exif markers; and raw JPEG."""
|
||||
if h[6:10] in (b"JFIF", b"Exif"):
|
||||
return "jpeg"
|
||||
elif h[:4] == b"\xff\xd8\xff\xdb":
|
||||
return "jpeg"
|
||||
|
||||
|
||||
tests.append(test_jpeg)
|
||||
|
||||
|
||||
def test_png(h, f):
|
||||
"""Verify if the image is a PNG."""
|
||||
if h.startswith(b"\211PNG\r\n\032\n"):
|
||||
return "png"
|
||||
|
||||
|
||||
tests.append(test_png)
|
||||
|
||||
|
||||
def test_gif(h, f):
|
||||
"""Verify if the image is a GIF ('87 or '89 variants)."""
|
||||
if h[:6] in (b"GIF87a", b"GIF89a"):
|
||||
return "gif"
|
||||
|
||||
|
||||
tests.append(test_gif)
|
||||
|
||||
|
||||
def test_tiff(h, f):
|
||||
"""Verify if the image is a TIFF (Motorola or Intel)."""
|
||||
if h[:2] in (b"MM", b"II"):
|
||||
return "tiff"
|
||||
|
||||
|
||||
tests.append(test_tiff)
|
||||
|
||||
|
||||
def test_rgb(h, f):
|
||||
"""Test for the SGI image library."""
|
||||
if h.startswith(b"\001\332"):
|
||||
return "rgb"
|
||||
|
||||
|
||||
tests.append(test_rgb)
|
||||
|
||||
|
||||
def test_pbm(h, f):
|
||||
"""Verify if the image is a PBM."""
|
||||
if len(h) >= 3 and h[0] == ord(b"P") and h[1] in b"14" and h[2] in b" \t\n\r":
|
||||
return "pbm"
|
||||
|
||||
|
||||
tests.append(test_pbm)
|
||||
|
||||
|
||||
def test_pgm(h, f):
|
||||
"""Verify if the image is a PGM."""
|
||||
if len(h) >= 3 and h[0] == ord(b"P") and h[1] in b"25" and h[2] in b" \t\n\r":
|
||||
return "pgm"
|
||||
|
||||
|
||||
tests.append(test_pgm)
|
||||
|
||||
|
||||
def test_ppm(h, f):
|
||||
"""Verify if the image is a PPM."""
|
||||
if len(h) >= 3 and h[0] == ord(b"P") and h[1] in b"36" and h[2] in b" \t\n\r":
|
||||
return "ppm"
|
||||
|
||||
|
||||
tests.append(test_ppm)
|
||||
|
||||
|
||||
def test_rast(h, f):
|
||||
"""Test for the Sun raster file."""
|
||||
if h.startswith(b"\x59\xa6\x6a\x95"):
|
||||
return "rast"
|
||||
|
||||
|
||||
tests.append(test_rast)
|
||||
|
||||
|
||||
def test_xbm(h, f):
|
||||
"""Verify if the image is a X bitmap."""
|
||||
if h.startswith(b"#define "):
|
||||
return "xbm"
|
||||
|
||||
|
||||
tests.append(test_xbm)
|
||||
|
||||
|
||||
def test_bmp(h, f):
|
||||
"""Verify if the image is a BMP file."""
|
||||
if h.startswith(b"BM"):
|
||||
return "bmp"
|
||||
|
||||
|
||||
tests.append(test_bmp)
|
||||
|
||||
|
||||
def test_webp(h, f):
|
||||
"""Verify if the image is a WebP."""
|
||||
if h.startswith(b"RIFF") and h[8:12] == b"WEBP":
|
||||
return "webp"
|
||||
|
||||
|
||||
tests.append(test_webp)
|
||||
|
||||
|
||||
def test_exr(h, f):
|
||||
"""Verify if the image is an OpenEXR file."""
|
||||
if h.startswith(b"\x76\x2f\x31\x01"):
|
||||
return "exr"
|
||||
|
||||
|
||||
tests.append(test_exr)
|
||||
|
||||
|
||||
# --------------------
|
||||
# Small test program
|
||||
# --------------------
|
||||
|
||||
|
||||
def test(): # pragma: no cover - only used for manual testing
|
||||
import sys
|
||||
|
||||
recursive = 0
|
||||
if sys.argv[1:] and sys.argv[1] == "-r":
|
||||
del sys.argv[1:2]
|
||||
recursive = 1
|
||||
try:
|
||||
if sys.argv[1:]:
|
||||
testall(sys.argv[1:], recursive, 1)
|
||||
else:
|
||||
testall(["."], recursive, 1)
|
||||
except KeyboardInterrupt:
|
||||
sys.stderr.write("\n[Interrupted]\n")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def testall(list, recursive, toplevel): # pragma: no cover - only for manual use
|
||||
import sys
|
||||
import os
|
||||
|
||||
for filename in list:
|
||||
if os.path.isdir(filename):
|
||||
print(filename + "/:", end=" ")
|
||||
if recursive or toplevel:
|
||||
print("recursing down:")
|
||||
import glob
|
||||
|
||||
names = glob.glob(os.path.join(glob.escape(filename), "*"))
|
||||
testall(names, recursive, 0)
|
||||
else:
|
||||
print("*** directory (use -r) ***")
|
||||
else:
|
||||
print(filename + ":", end=" ")
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
print(what(filename))
|
||||
except OSError:
|
||||
print("*** not found ***")
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover - manual run
|
||||
test()
|
Reference in New Issue
Block a user