From b44728bf9f0a0599f727bede4823a6ca34958917 Mon Sep 17 00:00:00 2001
From: SanAndreyas <74550995+SanAndreyas@users.noreply.github.com>
Date: Thu, 2 Jul 2026 17:51:35 +0300
Subject: [PATCH 1/3] Update mintSources.py
replace apt-key with a script replacing add, del and list commands for Debian 13 or later.
---
usr/lib/linuxmint/mintSources/mintSources.py | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/usr/lib/linuxmint/mintSources/mintSources.py b/usr/lib/linuxmint/mintSources/mintSources.py
index 02a3d31..a2831b2 100755
--- a/usr/lib/linuxmint/mintSources/mintSources.py
+++ b/usr/lib/linuxmint/mintSources/mintSources.py
@@ -29,6 +29,7 @@
from io import BytesIO
from CountryInformation import CountryInformation
+from pathlib import Path
import apt_pkg
@@ -41,6 +42,7 @@
disable_refresh = False
sources_changed = False
+script_dir = Path(__file__).parent
FLAG_PATH = "/usr/share/iso-flag-png/%s.png"
FLAG_SIZE = 16
@@ -340,7 +342,7 @@ def __init__(self, pub):
self.uid = ""
def delete(self):
- subprocess.call(["apt-key", "del", self.pub])
+ subprocess.call(["./apt-key.sh", "del", self.pub], cwd=script_dir, capture_output=True, text=True)
def get_name(self):
return "%s\n %s" % (GLib.markup_escape_text(self.uid), GLib.markup_escape_text(self.pub))
@@ -1293,9 +1295,9 @@ def __init__(self, path, uri):
def load_keys(self):
self.keys = []
key = None
- output = subprocess.getoutput("apt-key list")
+ output = subprocess.run(["./apt-key.sh", "list"], cwd=script_dir, capture_output=True, text=True)
lines = []
- for line in output.split("\n"):
+ for line in output.stdout.split("\n"):
line = line.strip()
if line.startswith("/etc/apt"):
continue
@@ -1332,7 +1334,7 @@ def add_key(self, widget):
dialog.set_default_response(Gtk.ResponseType.OK)
response = dialog.run()
if response == Gtk.ResponseType.OK:
- subprocess.call(["apt-key", "add", dialog.get_filename()])
+ subprocess.call(["./apt-key.sh", "add", dialog.get_filename()], cwd=script_dir, capture_output=True, text=True)
self.load_keys()
self.enable_reload_button()
dialog.destroy()
From fe4d5142fe3a13abc8b22fd4386809df5fea6079 Mon Sep 17 00:00:00 2001
From: SanAndreyas <74550995+SanAndreyas@users.noreply.github.com>
Date: Thu, 2 Jul 2026 18:10:53 +0300
Subject: [PATCH 2/3] Update mintSources.py
---
usr/lib/linuxmint/mintSources/mintSources.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/usr/lib/linuxmint/mintSources/mintSources.py b/usr/lib/linuxmint/mintSources/mintSources.py
index a2831b2..19248a1 100755
--- a/usr/lib/linuxmint/mintSources/mintSources.py
+++ b/usr/lib/linuxmint/mintSources/mintSources.py
@@ -342,7 +342,7 @@ def __init__(self, pub):
self.uid = ""
def delete(self):
- subprocess.call(["./apt-key.sh", "del", self.pub], cwd=script_dir, capture_output=True, text=True)
+ subprocess.run(["./apt-key.sh", "del", self.pub], cwd=script_dir, capture_output=True, text=True)
def get_name(self):
return "%s\n %s" % (GLib.markup_escape_text(self.uid), GLib.markup_escape_text(self.pub))
@@ -1334,7 +1334,7 @@ def add_key(self, widget):
dialog.set_default_response(Gtk.ResponseType.OK)
response = dialog.run()
if response == Gtk.ResponseType.OK:
- subprocess.call(["./apt-key.sh", "add", dialog.get_filename()], cwd=script_dir, capture_output=True, text=True)
+ subprocess.run(["./apt-key.sh", "add", dialog.get_filename()], cwd=script_dir, capture_output=True, text=True)
self.load_keys()
self.enable_reload_button()
dialog.destroy()
From 697ac92c19ea5da959daa8f87f31f8b5e84e35a2 Mon Sep 17 00:00:00 2001
From: SanAndreyas <74550995+SanAndreyas@users.noreply.github.com>
Date: Thu, 2 Jul 2026 21:56:54 +0300
Subject: [PATCH 3/3] Add files via upload
apt key functionality for Debian 13+
---
usr/lib/linuxmint/mintSources/apt-key.sh | 106 +++++++++++++++++++++++
1 file changed, 106 insertions(+)
create mode 100644 usr/lib/linuxmint/mintSources/apt-key.sh
diff --git a/usr/lib/linuxmint/mintSources/apt-key.sh b/usr/lib/linuxmint/mintSources/apt-key.sh
new file mode 100644
index 0000000..bd5c169
--- /dev/null
+++ b/usr/lib/linuxmint/mintSources/apt-key.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+# apt-key-clone: A drop-in replacement for apt-key on Debian 13
+# Maps legacy commands to all modern and legacy keyring directories.
+
+# Strip up to two dashes to normalize (e.g., --list becomes list)
+COMMAND="${1#-}"
+COMMAND="${COMMAND#-}"
+
+# Define all possible key locations to scan
+SCAN_PATHS=(
+ "/etc/apt/trusted.gpg"
+ "/etc/apt/trusted.gpg.d"/*
+ "/etc/apt/keyrings"/*
+# "/usr/share/keyrings"/*
+)
+
+case "$COMMAND" in
+ list)
+ for keyfile in "${SCAN_PATHS[@]}"; do
+ # The [ -f ] check safely skips missing directories like /etc/apt/trusted.gpg
+ [ -f "$keyfile" ] || continue
+ if file "$keyfile" | grep -qi -E 'PGP|GPG'; then
+ echo "--------------------------------------------------------"
+ echo "Keyring: $keyfile"
+ echo "--------------------------------------------------------"
+ gpg --show-keys --with-fingerprint "$keyfile" 2>/dev/null
+ echo ""
+ fi
+ done
+ ;;
+
+ add)
+ if [ "$EUID" -ne 0 ]; then echo "ERROR: Root privileges required."; exit 1; fi
+ FILE="$2"
+ if [ -z "$FILE" ]; then echo "Usage: apt-key add "; exit 1; fi
+
+ # Capture file or STDIN
+ TMP_INPUT=$(mktemp)
+ if [ "$FILE" = "-" ]; then
+ cat > "$TMP_INPUT"
+ else
+ cat "$FILE" > "$TMP_INPUT"
+ fi
+
+ # Extract the fingerprint to name the file safely
+ FPR=$(gpg --show-keys --with-colons "$TMP_INPUT" 2>/dev/null | grep "^fpr:" | head -n 1 | cut -d: -f10)
+ if [ -z "$FPR" ]; then
+ echo "ERROR: Could not extract a valid GPG key."
+ rm -f "$TMP_INPUT"
+ exit 1
+ fi
+
+ # We save to trusted.gpg.d so the key is globally trusted, mimicking legacy apt-key behavior
+ DEST="/etc/apt/trusted.gpg.d/imported-${FPR}.gpg"
+
+ # Import to a temporary keyring, then export cleanly as a dearmored binary
+ # This handles both ASCII (.asc) and binary (.gpg) files perfectly.
+ TMP_RING=$(mktemp)
+ gpg --no-default-keyring --keyring "$TMP_RING" --import "$TMP_INPUT" >/dev/null 2>&1
+ gpg --no-default-keyring --keyring "$TMP_RING" --export > "$DEST"
+
+ chmod 644 "$DEST"
+ rm -f "$TMP_INPUT" "$TMP_RING" "${TMP_RING}~"
+ echo "OK"
+ ;;
+
+ del)
+ if [ "$EUID" -ne 0 ]; then echo "ERROR: Root privileges required."; exit 1; fi
+ KEYID="$2"
+ if [ -z "$KEYID" ]; then echo "Usage: apt-key del "; exit 1; fi
+
+ # Remove spaces in case the user passed a full fingerprint
+ KEYID=$(echo "$KEYID" | tr -d ' ')
+ FOUND=0
+
+ for keyfile in "${SCAN_PATHS[@]}"; do
+ [ -f "$keyfile" ] || continue
+
+ # Check if the keyid exists in this specific keyring file
+ if gpg --show-keys --with-colons "$keyfile" 2>/dev/null | grep -qF "${KEYID}"; then
+ KEY_COUNT=$(gpg --show-keys --with-colons "$keyfile" 2>/dev/null | grep -c "^pub:")
+
+ if [ "$KEY_COUNT" -le 1 ]; then
+ # If it's the only key in the file, delete the file entirely
+ rm -f "$keyfile"
+ else
+ # If it's a multi-key file, delete just the specific key
+ gpg --no-default-keyring --keyring "$keyfile" --batch --yes --delete-keys "$KEYID" >/dev/null 2>&1
+ rm -f "${keyfile}~" # Clean up GPG backup file
+ fi
+ FOUND=1
+ fi
+ done
+
+ if [ $FOUND -eq 1 ]; then
+ echo "OK"
+ else
+ echo "Warning: Key not found."
+ fi
+ ;;
+
+ *)
+ echo "Usage: apt-key {add | del | list}"
+ exit 1
+ ;;
+esac