change(git): allow keys/pgp subdir with .asc files

This allows migration of git history for packages dropped from a repo to AUR
in case they contain PGP key material

Signed-off-by: moson-mo <mo-son@mailbox.org>
This commit is contained in:
moson-mo 2023-06-11 12:20:02 +02:00
parent 1c11c901a2
commit ed17486da6
No known key found for this signature in database
GPG key ID: 4A4760AB4EE15296
2 changed files with 141 additions and 15 deletions

View file

@ -315,6 +315,14 @@ def validate_metadata(metadata, commit): # noqa: C901
die_commit("missing source file: {:s}".format(fname), str(commit.id))
def validate_blob_size(blob: pygit2.Object, commit: pygit2.Commit):
if isinstance(blob, pygit2.Blob) and blob.size > max_blob_size:
die_commit(
"maximum blob size ({:s}) exceeded".format(size_humanize(max_blob_size)),
str(commit.id),
)
def main(): # noqa: C901
repo = pygit2.Repository(repo_path)
@ -376,25 +384,42 @@ def main(): # noqa: C901
for commit in walker:
if "PKGBUILD" not in commit.tree:
die_commit("missing PKGBUILD", str(commit.id))
# Iterate over files in root dir
for treeobj in commit.tree:
blob = repo[treeobj.id]
if isinstance(blob, pygit2.Tree):
# Don't allow any subdirs besides "keys/"
if isinstance(treeobj, pygit2.Tree) and treeobj.name != "keys":
die_commit(
"the repository must not contain subdirectories", str(commit.id)
)
if not isinstance(blob, pygit2.Blob):
die_commit("not a blob object: {:s}".format(treeobj), str(commit.id))
if blob.size > max_blob_size:
die_commit(
"maximum blob size ({:s}) exceeded".format(
size_humanize(max_blob_size)
),
"the repository must not contain subdirectories",
str(commit.id),
)
# Check size of files in root dir
validate_blob_size(treeobj, commit)
# If we got a subdir keys/,
# make sure it only contains a pgp/ subdir with key files
if "keys" in commit.tree:
# Check for forbidden files/dirs in keys/
for keyobj in commit.tree["keys"]:
if not isinstance(keyobj, pygit2.Tree) or keyobj.name != "pgp":
die_commit(
"the keys/ subdir may only contain a pgp/ directory",
str(commit.id),
)
# Check for forbidden files in keys/pgp/
if "keys/pgp" in commit.tree:
for pgpobj in commit.tree["keys/pgp"]:
if not isinstance(pgpobj, pygit2.Blob) or not pgpobj.name.endswith(
".asc"
):
die_commit(
"the subdir may only contain .asc (PGP pub key) files",
str(commit.id),
)
# Check file size for pgp key files
validate_blob_size(pgpobj, commit)
# Display a warning if .SRCINFO is unchanged.
if sha1_old not in ("0000000000000000000000000000000000000000", sha1_new):
srcinfo_id_old = repo[sha1_old].tree[".SRCINFO"].id

View file

@ -191,7 +191,7 @@ test_expect_success 'Removing PKGBUILD.' '
grep -q "^error: missing PKGBUILD$" actual
'
test_expect_success 'Pushing a tree with a subdirectory.' '
test_expect_success 'Pushing a tree with a forbidden subdirectory.' '
old=$(git -C aur.git rev-parse HEAD) &&
test_when_finished "git -C aur.git reset --hard $old" &&
mkdir aur.git/subdir &&
@ -205,6 +205,107 @@ test_expect_success 'Pushing a tree with a subdirectory.' '
grep -q "^error: the repository must not contain subdirectories$" actual
'
test_expect_success 'Pushing a tree with an allowed subdirectory for pgp keys; wrong files.' '
old=$(git -C aur.git rev-parse HEAD) &&
test_when_finished "git -C aur.git reset --hard $old" &&
mkdir -p aur.git/keys/pgp/ &&
touch aur.git/keys/pgp/nonsense &&
git -C aur.git add keys/pgp/nonsense &&
git -C aur.git commit -q -m "Add some nonsense" &&
new=$(git -C aur.git rev-parse HEAD) &&
test_must_fail \
env AUR_USER=user AUR_PKGBASE=foobar AUR_PRIVILEGED=0 \
cover "$GIT_UPDATE" refs/heads/master "$old" "$new" >actual 2>&1 &&
grep -q "^error: the subdir may only contain .asc (PGP pub key) files$" actual
'
test_expect_success 'Pushing a tree with an allowed subdirectory for pgp keys; another subdir.' '
old=$(git -C aur.git rev-parse HEAD) &&
test_when_finished "git -C aur.git reset --hard $old" &&
mkdir -p aur.git/keys/pgp/bla/ &&
touch aur.git/keys/pgp/bla/x.asc &&
git -C aur.git add keys/pgp/bla/x.asc &&
git -C aur.git commit -q -m "Add some nonsense" &&
new=$(git -C aur.git rev-parse HEAD) &&
test_must_fail \
env AUR_USER=user AUR_PKGBASE=foobar AUR_PRIVILEGED=0 \
cover "$GIT_UPDATE" refs/heads/master "$old" "$new" >actual 2>&1 &&
grep -q "^error: the subdir may only contain .asc (PGP pub key) files$" actual
'
test_expect_success 'Pushing a tree with an allowed subdirectory for pgp keys; wrong subdir.' '
old=$(git -C aur.git rev-parse HEAD) &&
test_when_finished "git -C aur.git reset --hard $old" &&
mkdir -p aur.git/keys/xyz/ &&
touch aur.git/keys/xyz/x.asc &&
git -C aur.git add keys/xyz/x.asc &&
git -C aur.git commit -q -m "Add some nonsense" &&
new=$(git -C aur.git rev-parse HEAD) &&
test_must_fail \
env AUR_USER=user AUR_PKGBASE=foobar AUR_PRIVILEGED=0 \
cover "$GIT_UPDATE" refs/heads/master "$old" "$new" >actual 2>&1 &&
grep -q "^error: the keys/ subdir may only contain a pgp/ directory$" actual
'
test_expect_success 'Pushing a tree with an allowed subdirectory with pgp keys; additional files' '
old=$(git -C aur.git rev-parse HEAD) &&
test_when_finished "git -C aur.git reset --hard $old" &&
mkdir -p aur.git/keys/pgp/ &&
touch aur.git/keys/pgp/x.asc &&
touch aur.git/keys/nonsense &&
git -C aur.git add keys/pgp/x.asc &&
git -C aur.git add keys/nonsense &&
git -C aur.git commit -q -m "Add pgp key" &&
new=$(git -C aur.git rev-parse HEAD) &&
test_must_fail \
env AUR_USER=user AUR_PKGBASE=foobar AUR_PRIVILEGED=0 \
cover "$GIT_UPDATE" refs/heads/master "$old" "$new" >actual 2>&1 &&
grep -q "^error: the keys/ subdir may only contain a pgp/ directory$" actual
'
test_expect_success 'Pushing a tree with an allowed subdirectory with pgp keys; additional subdir' '
old=$(git -C aur.git rev-parse HEAD) &&
test_when_finished "git -C aur.git reset --hard $old" &&
mkdir -p aur.git/keys/pgp/ &&
mkdir -p aur.git/somedir/ &&
touch aur.git/keys/pgp/x.asc &&
touch aur.git/somedir/nonsense &&
git -C aur.git add keys/pgp/x.asc &&
git -C aur.git add somedir/nonsense &&
git -C aur.git commit -q -m "Add pgp key" &&
new=$(git -C aur.git rev-parse HEAD) &&
test_must_fail \
env AUR_USER=user AUR_PKGBASE=foobar AUR_PRIVILEGED=0 \
cover "$GIT_UPDATE" refs/heads/master "$old" "$new" >actual 2>&1 &&
grep -q "^error: the repository must not contain subdirectories$" actual
'
test_expect_success 'Pushing a tree with an allowed subdirectory with pgp keys; keys to large' '
old=$(git -C aur.git rev-parse HEAD) &&
test_when_finished "git -C aur.git reset --hard $old" &&
mkdir -p aur.git/keys/pgp/ &&
printf "%256001s" x > aur.git/keys/pgp/x.asc &&
git -C aur.git add keys/pgp/x.asc &&
git -C aur.git commit -q -m "Add pgp key" &&
new=$(git -C aur.git rev-parse HEAD) &&
test_must_fail \
env AUR_USER=user AUR_PKGBASE=foobar AUR_PRIVILEGED=0 \
cover "$GIT_UPDATE" refs/heads/master "$old" "$new" >actual 2>&1 &&
grep -q "^error: maximum blob size (250.00KiB) exceeded$" actual
'
test_expect_success 'Pushing a tree with an allowed subdirectory with pgp keys.' '
old=$(git -C aur.git rev-parse HEAD) &&
test_when_finished "git -C aur.git reset --hard $old" &&
mkdir -p aur.git/keys/pgp/ &&
touch aur.git/keys/pgp/x.asc &&
git -C aur.git add keys/pgp/x.asc &&
git -C aur.git commit -q -m "Add pgp key" &&
new=$(git -C aur.git rev-parse HEAD) &&
env AUR_USER=user AUR_PKGBASE=foobar AUR_PRIVILEGED=0 \
cover "$GIT_UPDATE" refs/heads/master "$old" "$new" 2>&1
'
test_expect_success 'Pushing a tree with a large blob.' '
old=$(git -C aur.git rev-parse HEAD) &&
test_when_finished "git -C aur.git reset --hard $old" &&