mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
pkgbase splits programs and their tests into separate packages (e.g. unifdef/yacc/indent/file2c -> toolchain, jail -> jail, etc), while their tests always land in the generic tests package. Installing just the tests package therefore leaves these suites unable to find the binary they exercise, and they fail confusingly instead of skipping. Rather than force all packages to be installed for the tests package, make the tests cope with the missing packages. Add require.progs (or, for TAP/PLAIN-style suites with no atf_set hook: TEST_METADATA required_programs) for the binary under test in: bectl, certctl, ctfconvert, dhclient, file2c, indent, ipfw, jail, lastcomm, mixer, newsyslog, nvmecontrol, pfctl, praudit, sa, syslogd, tunefs, unifdef, yacc, ztest. I skipped adding data for all the binaries in the base runtime package for simplicity. Assisted-by: Claude Code (Sonnet 5) Sponsored by: Netflix Reviewed by: ngie Differential Revision: https://reviews.freebsd.org/D58262
340 lines
8.2 KiB
Bash
340 lines
8.2 KiB
Bash
#
|
|
# Copyright (c) 2025 Dag-Erling Smørgrav <[email protected]>
|
|
#
|
|
# SPDX-License-Identifier: BSD-2-Clause
|
|
#
|
|
|
|
. $(atf_get_srcdir)/certctl.subr
|
|
|
|
# Random sets of eight non-colliding names
|
|
set1()
|
|
{
|
|
cat <<EOF
|
|
AVOYKJHSLFHWPVQMKBHENUAHJTEGMCCB 0ca83bbe
|
|
UYSYXKDNNJTYOQPBGIKQDHRJYZHTDPKK 0d9a6512
|
|
LODHGFXMZYKGOKAYGWTMMYQJYHDATDDM 4e6219f5
|
|
NBBTQHJLHKBFFFWJTHHSNKOQYMGLHLPW 5dd76abc
|
|
BJFAQZXZHYQLIDDPCAQFPDMNXICUXBXW ad68573d
|
|
IOKNTHVEVVIJMNMYAVILMEMQQWLVRESN b577803d
|
|
BHGMAJJGNJPIVMHMFCUTJLGFROJICEKN c98a6338
|
|
HCRFQMGDQJALMLUQNXMPGLXFLLJRODJW f50c6379
|
|
EOF
|
|
}
|
|
|
|
set2()
|
|
{
|
|
cat <<EOF
|
|
GOHKZTSKIPDSYNLMGYXGLROPTATELXIU 30789c88
|
|
YOOTYHEGHZIYFXOBLNKENPSJUDGOPJJU 7fadbc13
|
|
ETRINNYBGKIENAVGOKVJYFSSHFZIJZRH 8ed664af
|
|
DBFGMFFMRNLPQLQPOLXOEUVLCRXLRSWT 8f34355e
|
|
WFOPBQPLQFHDHZOUQFEIDGSYDUOTSNDQ ac0471df
|
|
HMNETZMGNIWRGXQCVZXVZGWSGFBRRDQC b32f1472
|
|
SHFYBXDVAUACBFPPAIGDAQIAGYOYGMQE baca75fa
|
|
PCBGDNVPYCDGNRQSGRSLXFHYKXLAVLHW ddeeae01
|
|
EOF
|
|
}
|
|
|
|
set3()
|
|
{
|
|
cat <<EOF
|
|
NJWIRLPWAIICVJBKXXHFHLCPAERZATRL 000aa2e5
|
|
RJAENDPOCZQEVCPFUWOWDXPCSMYJPVYC 021b95a3
|
|
PQUQDSWHBNVLBTNBGONYRLGZZVEFXVLO 071e8c50
|
|
VZEXRKJUPZSFBDWBOLUZXOGLNTEAPCZM 3af7bb9b
|
|
ZXOWOXQTXNZMAMZIWVFDZDJEWOOAGAOH 48d5c7cc
|
|
KQSFQYVJMFTMADIHJIWGSQISWKSHRYQO 509f5ba1
|
|
AIECYSLWZOIEPJWWUTWSQXCNCIHHZHYI 8cb0c503
|
|
RFHWDJZEPOFLMPGXAHVEJFHCDODAPVEV 9ae4e049
|
|
EOF
|
|
}
|
|
|
|
# Random set of three colliding names
|
|
collhash=f2888ce3
|
|
coll()
|
|
{
|
|
cat <<EOF
|
|
EJFTZEOANQLOYPEHWWXBWEWEFVKHMSNA $collhash
|
|
LEMRWZAZLKZLPPSFLNLQZVGKKBEOFYWG $collhash
|
|
ZWUPHYWKKTVEFBJOLLPDAIKGRDFVXZID $collhash
|
|
EOF
|
|
}
|
|
|
|
sortfile() {
|
|
for filename; do
|
|
sort "${filename}" >"${filename}"-
|
|
mv "${filename}"- "${filename}"
|
|
done
|
|
}
|
|
|
|
certctl_setup()
|
|
{
|
|
export DESTDIR="$PWD"
|
|
|
|
# Create input directories
|
|
mkdir -p ${DESTDIR}${DISTBASE}/usr/share/certs/trusted
|
|
mkdir -p ${DESTDIR}${DISTBASE}/usr/share/certs/untrusted
|
|
mkdir -p ${DESTDIR}/usr/local/share/certs
|
|
|
|
# Do not create output directories; certctl will take care of it
|
|
#mkdir -p ${DESTDIR}${DISTBASE}/etc/ssl/certs
|
|
#mkdir -p ${DESTDIR}${DISTBASE}/etc/ssl/untrusted
|
|
|
|
# Generate a random key
|
|
keyname="testkey"
|
|
gen_key ${keyname}
|
|
|
|
# Generate certificates
|
|
:>metalog.expect
|
|
:>trusted.expect
|
|
:>untrusted.expect
|
|
metalog() {
|
|
echo ".${DISTBASE}$@ type=file" >>metalog.expect
|
|
}
|
|
trusted() {
|
|
local crtname=$1
|
|
local filename=$2
|
|
printf "%s\t%s\n" "${filename}" "${crtname}" >>trusted.expect
|
|
metalog "/etc/ssl/certs/${filename}"
|
|
}
|
|
untrusted() {
|
|
local crtname=$1
|
|
local filename=$2
|
|
printf "%s\t%s\n" "${filename}" "${crtname}" >>untrusted.expect
|
|
metalog "/etc/ssl/untrusted/${filename}"
|
|
}
|
|
set1 | while read crtname hash ; do
|
|
gen_crt ${crtname} ${keyname}
|
|
mv ${crtname}.crt ${DESTDIR}${DISTBASE}/usr/share/certs/trusted
|
|
trusted "${crtname}" "${hash}.0"
|
|
done
|
|
local c=0
|
|
coll | while read crtname hash ; do
|
|
gen_crt ${crtname} ${keyname}
|
|
mv ${crtname}.crt ${DESTDIR}${DISTBASE}/usr/share/certs/trusted
|
|
trusted "${crtname}" "${hash}.${c}"
|
|
c=$((c+1))
|
|
done
|
|
set2 | while read crtname hash ; do
|
|
gen_crt ${crtname} ${keyname}
|
|
openssl x509 -in ${crtname}.crt
|
|
rm ${crtname}.crt
|
|
trusted "${crtname}" "${hash}.0"
|
|
done >usr/local/share/certs/bundle.crt
|
|
set3 | while read crtname hash ; do
|
|
gen_crt ${crtname} ${keyname}
|
|
mv ${crtname}.crt ${DESTDIR}${DISTBASE}/usr/share/certs/untrusted
|
|
untrusted "${crtname}" "${hash}.0"
|
|
done
|
|
metalog "/etc/ssl/cert.pem"
|
|
unset -f untrusted
|
|
unset -f trusted
|
|
unset -f metalog
|
|
sortfile *.expect
|
|
}
|
|
|
|
check_trusted() {
|
|
local crtname=$1
|
|
local subject="$(subject ${crtname})"
|
|
local c=${2:-1}
|
|
|
|
atf_check -e ignore -o match:"found: ${c}\$" \
|
|
openssl storeutl -noout -subject "${subject}" \
|
|
${DESTDIR}${DISTBASE}/etc/ssl/certs
|
|
atf_check -e ignore -o not-match:"found: [1-9]" \
|
|
openssl storeutl -noout -subject "${subject}" \
|
|
${DESTDIR}${DISTBASE}/etc/ssl/untrusted
|
|
}
|
|
|
|
check_untrusted() {
|
|
local crtname=$1
|
|
local subject="$(subject ${crtname})"
|
|
local c=${2:-1}
|
|
|
|
atf_check -e ignore -o not-match:"found: [1-9]" \
|
|
openssl storeutl -noout -subject "${subject}" \
|
|
${DESTDIR}/${DISTBASE}/etc/ssl/certs
|
|
atf_check -e ignore -o match:"found: ${c}\$" \
|
|
openssl storeutl -noout -subject "${subject}" \
|
|
${DESTDIR}/${DISTBASE}/etc/ssl/untrusted
|
|
}
|
|
|
|
check_in_bundle() {
|
|
local b=${DISTBASE}${DISTBASE+/}
|
|
local crtfile=$1
|
|
local line
|
|
|
|
line=$(tail +5 "${crtfile}" | head -1)
|
|
atf_check grep -q "${line}" ${DESTDIR}${DISTBASE}/etc/ssl/cert.pem
|
|
}
|
|
|
|
check_not_in_bundle() {
|
|
local b=${DISTBASE}${DISTBASE+/}
|
|
local crtfile=$1
|
|
local line
|
|
|
|
line=$(tail +5 "${crtfile}" | head -1)
|
|
atf_check -s exit:1 grep -q "${line}" etc/ssl/cert.pem
|
|
}
|
|
|
|
atf_test_case rehash
|
|
rehash_head()
|
|
{
|
|
atf_set "descr" "Test the rehash command"
|
|
atf_set "require.progs" certctl
|
|
}
|
|
rehash_body()
|
|
{
|
|
certctl_setup
|
|
atf_check certctl rehash
|
|
|
|
# Verify non-colliding trusted certificates
|
|
(set1; set2) >trusted
|
|
while read crtname hash ; do
|
|
check_trusted "${crtname}"
|
|
done <trusted
|
|
|
|
# Verify colliding trusted certificates
|
|
coll >coll
|
|
while read crtname hash ; do
|
|
check_trusted "${crtname}" $(wc -l <coll)
|
|
done <coll
|
|
|
|
# Verify untrusted certificates
|
|
set3 >untrusted
|
|
while read crtname hash ; do
|
|
check_untrusted "${crtname}"
|
|
done <untrusted
|
|
|
|
# Verify bundle
|
|
for f in etc/ssl/certs/*.? ; do
|
|
check_in_bundle "${f}"
|
|
done
|
|
for f in etc/ssl/untrusted/*.? ; do
|
|
check_not_in_bundle "${f}"
|
|
done
|
|
}
|
|
|
|
atf_test_case list
|
|
list_head()
|
|
{
|
|
atf_set "descr" "Test the list and untrusted commands"
|
|
atf_set "require.progs" certctl
|
|
}
|
|
list_body()
|
|
{
|
|
certctl_setup
|
|
atf_check certctl rehash
|
|
|
|
atf_check -o save:trusted.out certctl list
|
|
sortfile trusted.out
|
|
# the ordering of the colliding certificates is partly
|
|
# determined by fields that change every time we regenerate
|
|
# them, so ignore them in the diff
|
|
atf_check diff -u \
|
|
--ignore-matching-lines $collhash \
|
|
trusted.expect trusted.out
|
|
|
|
atf_check -o save:untrusted.out certctl untrusted
|
|
sortfile untrusted.out
|
|
atf_check diff -u \
|
|
untrusted.expect untrusted.out
|
|
}
|
|
|
|
atf_test_case trust
|
|
trust_head()
|
|
{
|
|
atf_set "descr" "Test the trust command"
|
|
atf_set "require.progs" certctl
|
|
}
|
|
trust_body()
|
|
{
|
|
certctl_setup
|
|
atf_check certctl rehash
|
|
crtname=$(set3 | (read crtname hash ; echo ${crtname}))
|
|
crtfile=usr/share/certs/untrusted/${crtname}.crt
|
|
check_untrusted ${crtname}
|
|
check_not_in_bundle ${crtfile}
|
|
atf_check -e match:"was previously untrusted" \
|
|
certctl trust ${crtfile}
|
|
check_trusted ${crtname}
|
|
check_in_bundle ${crtfile}
|
|
}
|
|
|
|
atf_test_case untrust
|
|
untrust_head()
|
|
{
|
|
atf_set "descr" "Test the untrust command"
|
|
atf_set "require.progs" certctl
|
|
}
|
|
untrust_body()
|
|
{
|
|
certctl_setup
|
|
atf_check certctl rehash
|
|
crtname=$(set1 | (read crtname hash ; echo ${crtname}))
|
|
crtfile=usr/share/certs/trusted/${crtname}.crt
|
|
check_trusted "${crtname}"
|
|
check_in_bundle ${crtfile}
|
|
atf_check -e match:"1 new untrusted" \
|
|
certctl untrust "${crtfile}"
|
|
check_untrusted "${crtname}"
|
|
check_not_in_bundle ${crtfile}
|
|
}
|
|
|
|
atf_test_case metalog
|
|
metalog_head()
|
|
{
|
|
atf_set "descr" "Verify the metalog"
|
|
atf_set "require.progs" certctl
|
|
}
|
|
metalog_body()
|
|
{
|
|
export DISTBASE=/base
|
|
certctl_setup
|
|
|
|
# certctl gets DESTDIR and DISTBASE from environment
|
|
rm -f metalog.orig
|
|
atf_check certctl -U -M metalog.orig rehash
|
|
sed -E 's/(type=file) .*/\1/' metalog.orig | sort >metalog.short
|
|
atf_check diff -u metalog.expect metalog.short
|
|
|
|
# certctl gets DESTDIR and DISTBASE from command line
|
|
rm -f metalog.orig
|
|
atf_check env -uDESTDIR -uDISTBASE \
|
|
certctl -D ${DESTDIR} -d ${DISTBASE} -U -M metalog.orig rehash
|
|
sed -E 's/(type=file) .*/\1/' metalog.orig | sort >metalog.short
|
|
atf_check diff -u metalog.expect metalog.short
|
|
|
|
# as above, but intentionally add trailing slashes
|
|
rm -f metalog.orig
|
|
atf_check env -uDESTDIR -uDISTBASE \
|
|
certctl -D ${DESTDIR}// -d ${DISTBASE}/ -U -M metalog.orig rehash
|
|
sed -E 's/(type=file) .*/\1/' metalog.orig | sort >metalog.short
|
|
atf_check diff -u metalog.expect metalog.short
|
|
}
|
|
|
|
atf_test_case misc
|
|
misc_head()
|
|
{
|
|
atf_set "descr" "Test miscellaneous edge cases"
|
|
atf_set "require.progs" certctl
|
|
}
|
|
misc_body()
|
|
{
|
|
# certctl rejects DISTBASE that does not begin with a slash
|
|
atf_check -s exit:1 -e match:"begin with a slash" \
|
|
certctl -d base -n rehash
|
|
atf_check -s exit:1 -e match:"begin with a slash" \
|
|
env DISTBASE=base certctl -n rehash
|
|
}
|
|
|
|
atf_init_test_cases()
|
|
{
|
|
atf_add_test_case rehash
|
|
atf_add_test_case list
|
|
atf_add_test_case trust
|
|
atf_add_test_case untrust
|
|
atf_add_test_case metalog
|
|
atf_add_test_case misc
|
|
}
|