Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 56 additions & 15 deletions src/AptSourceActions.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,26 +127,67 @@ def is_safe_sources(sources_text):
if not sources_text or not str(sources_text).strip():
return False

blacklisted_terms = [
"trusted=yes", "trusted=true",
"allow-insecure",
"signed-by=",
"file://", "copy://", "cdrom://"
]

for line in str(sources_text).splitlines():

line = line.strip()
allowed_signed_by_prefixes = (
"/usr/share/keyrings/",
"/etc/apt/keyrings/",
)
allowed_option_keys = {
"arch",
"lang",
"target",
"pdiffs",
"by-hash",
"signed-by",
"check-valid-until",
"check-date",
}

for raw_line in str(sources_text).splitlines():
line = raw_line.strip()
if not line or line.startswith("#"):
continue

if not re.match(r"^deb(-src)?\s+", line):
m = re.match(r"^deb(-src)?\s+(?:\[(.*?)\]\s+)?([^\s]+)", line)
if not m:
return False

options = m.group(2)
uri = m.group(3).lower()

if not (uri.startswith("http://") or uri.startswith("https://")):
return False

compact_line = line.lower().replace(" ", "")
for term in blacklisted_terms:
if term.replace(" ", "") in compact_line:
return False
if options:
chunks = re.split(r"[,\s]+(?=[A-Za-z0-9-]+=)", options.strip())
for chunk in chunks:
chunk = chunk.strip()
if not chunk:
continue
if "=" in chunk:
key, value = chunk.split("=", 1)
else:
key, value = chunk, ""
key = key.lower().strip()
value_l = value.lower().strip()

if key not in allowed_option_keys:
return False
if key in ("check-valid-until", "check-date"):
if value_l in ("false", "no", "0", "off", "disable", "disabled"):
return False
continue
if key == "signed-by":
for part in value.split(","):
part = part.strip()
if not part:
return False
path = os.path.normpath(part)
if not os.path.isabs(path):
return False
if ".." in path.split(os.sep):
return False
if not any(path.startswith(prefix) for prefix in allowed_signed_by_prefixes):
return False

return True

Expand Down
56 changes: 46 additions & 10 deletions src/Group.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,60 @@
@author: fatih
"""

import os
import pwd
import re
import shutil
import subprocess
import sys

USERNAME_REGEX = re.compile(r"^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*\$?$")


def validate_username(username):
if not username or not USERNAME_REGEX.match(username):
sys.stderr.write(f"Error: Invalid username format: '{username}'.\n")
return False
try:
pwd.getpwnam(username)
return True
except KeyError:
sys.stderr.write(f"Error: User '{username}' does not exist.\n")
return False


def main():
def addtogroup(user):
subprocess.call(["adduser", user, "pardus-update"])
if len(sys.argv) < 3:
sys.stderr.write("Usage: Group.py <add|del> <username>\n")
sys.exit(1)

action = sys.argv[1]
user = sys.argv[2]

if not validate_username(user):
sys.exit(1)

def delfromgroup(user):
subprocess.call(["deluser", user, "pardus-update"])
target_group = "pardus-update"

if len(sys.argv) > 1:
if sys.argv[1] == "add":
addtogroup(sys.argv[2])
elif sys.argv[1] == "del":
delfromgroup(sys.argv[2])
if action == "add":
cmd_name = "adduser"
cmd_path = shutil.which(cmd_name) or (f"/usr/sbin/{cmd_name}" if os.path.exists(f"/usr/sbin/{cmd_name}") else None)
if not cmd_path:
sys.stderr.write(f"Error: Command '{cmd_name}' not found on system.\n")
sys.exit(1)
rc = subprocess.call([cmd_path, user, target_group])
sys.exit(rc)
elif action == "del":
cmd_name = "deluser"
cmd_path = shutil.which(cmd_name) or (f"/usr/sbin/{cmd_name}" if os.path.exists(f"/usr/sbin/{cmd_name}") else None)
if not cmd_path:
sys.stderr.write(f"Error: Command '{cmd_name}' not found on system.\n")
sys.exit(1)
rc = subprocess.call([cmd_path, user, target_group])
sys.exit(rc)
else:
print("no argument passed")
sys.stderr.write(f"Error: Unknown action '{action}'. Use 'add' or 'del'.\n")
sys.exit(1)


if __name__ == "__main__":
Expand Down
Loading