130 lines
4.5 KiB
Bash
130 lines
4.5 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
if [[ $# -ne 1 ]]; then
|
|
printf 'usage: %s <release-evidence-dir>\n' "$0" >&2
|
|
exit 2
|
|
fi
|
|
|
|
EVIDENCE_DIR="$1"
|
|
failures=()
|
|
|
|
fail() {
|
|
failures+=("$1")
|
|
}
|
|
|
|
require_file() {
|
|
local path="$1"
|
|
if [[ ! -s "$EVIDENCE_DIR/$path" ]]; then
|
|
fail "missing_or_empty:$path"
|
|
fi
|
|
}
|
|
|
|
require_dir() {
|
|
local path="$1"
|
|
if [[ ! -d "$EVIDENCE_DIR/$path" ]]; then
|
|
fail "missing_directory:$path"
|
|
fi
|
|
}
|
|
|
|
if [[ ! -d "$EVIDENCE_DIR" ]]; then
|
|
printf 'release_evidence_check=fail\nmissing_directory:%s\n' "$EVIDENCE_DIR"
|
|
exit 2
|
|
fi
|
|
|
|
require_file "release-evidence-manifest.json"
|
|
require_file "RELEASE_EVIDENCE_REPORT_RU.md"
|
|
require_file "SHA256SUMS"
|
|
require_dir "logs"
|
|
require_dir "artifacts"
|
|
|
|
if [[ -s "$EVIDENCE_DIR/SHA256SUMS" ]]; then
|
|
(cd "$EVIDENCE_DIR" && sha256sum -c SHA256SUMS >/dev/null) || fail "sha256sum_check_failed"
|
|
fi
|
|
|
|
if [[ -s "$EVIDENCE_DIR/release-evidence-manifest.json" ]]; then
|
|
if command -v jq >/dev/null 2>&1; then
|
|
jq -e . "$EVIDENCE_DIR/release-evidence-manifest.json" >/dev/null || fail "invalid_json:release-evidence-manifest.json"
|
|
jq -e '
|
|
.product == "AWatch-rus"
|
|
and (.release_version | type == "string" and length > 0)
|
|
and (.release_commit | type == "string" and length > 0)
|
|
and (.build_runner | type == "string" and length > 0)
|
|
and .primary_source_repository == "https://git.iri1968.dpdns.org/awatch-rus/AWatch-rus"
|
|
and .github_role == "public_mirror_only"
|
|
and (.generated_at | type == "string" and length > 0)
|
|
and (.checks | type == "array")
|
|
and (.artifacts | type == "array")
|
|
' "$EVIDENCE_DIR/release-evidence-manifest.json" >/dev/null || fail "manifest_required_fields"
|
|
elif command -v python3 >/dev/null 2>&1; then
|
|
python3 - "$EVIDENCE_DIR/release-evidence-manifest.json" <<'PY' || fail "manifest_required_fields"
|
|
import json
|
|
import sys
|
|
|
|
with open(sys.argv[1], "r", encoding="utf-8") as fh:
|
|
data = json.load(fh)
|
|
|
|
required = {
|
|
"product": "AWatch-rus",
|
|
"primary_source_repository": "https://git.iri1968.dpdns.org/awatch-rus/AWatch-rus",
|
|
"github_role": "public_mirror_only",
|
|
}
|
|
for key, value in required.items():
|
|
if data.get(key) != value:
|
|
raise SystemExit(f"{key} mismatch")
|
|
for key in ("release_version", "release_commit", "build_runner", "generated_at"):
|
|
if not isinstance(data.get(key), str) or not data[key]:
|
|
raise SystemExit(f"{key} missing")
|
|
if not isinstance(data.get("checks"), list):
|
|
raise SystemExit("checks missing")
|
|
if not isinstance(data.get("artifacts"), list):
|
|
raise SystemExit("artifacts missing")
|
|
PY
|
|
else
|
|
fail "json_validator_missing:jq_or_python3_required"
|
|
fi
|
|
fi
|
|
|
|
if [[ ! -s "$EVIDENCE_DIR/cargo-metadata.json" ]] && ! grep -Eiq 'cargo_metadata.*skipped' "$EVIDENCE_DIR/skipped-checks.txt" 2>/dev/null; then
|
|
fail "missing_cargo_metadata_or_documented_skip"
|
|
fi
|
|
|
|
if [[ ! -s "$EVIDENCE_DIR/cargo-tree.txt" ]] && ! grep -Eiq 'cargo_tree.*skipped' "$EVIDENCE_DIR/skipped-checks.txt" 2>/dev/null; then
|
|
fail "missing_cargo_tree_or_documented_skip"
|
|
fi
|
|
|
|
if ! find "$EVIDENCE_DIR/artifacts" -maxdepth 1 -type f -name '*source*.tar.gz' | grep -q .; then
|
|
fail "missing_source_archive"
|
|
fi
|
|
|
|
if ! find "$EVIDENCE_DIR/artifacts" -maxdepth 1 -type f \( -name '*binaries*.tar.gz' -o -name '*binaries*.tar.gz.skip' \) | grep -q .; then
|
|
fail "missing_binary_archive_or_documented_skip"
|
|
fi
|
|
|
|
scan_files=(
|
|
"$EVIDENCE_DIR/RELEASE_EVIDENCE_REPORT_RU.md"
|
|
"$EVIDENCE_DIR/release-evidence-manifest.json"
|
|
)
|
|
|
|
if grep -RInEi "(ФСТЭК|ФСБ).{0,80}(сертифицирован|сертификация|сертификат).{0,80}(есть|получен|имеется|подтвержден)|сертифицированное[[:space:]]+СЗИ" "${scan_files[@]}" >/tmp/release_evidence_forbidden_cert.$$ 2>/dev/null; then
|
|
fail "forbidden_claim_certification:$(cat /tmp/release_evidence_forbidden_cert.$$)"
|
|
fi
|
|
rm -f /tmp/release_evidence_forbidden_cert.$$
|
|
|
|
if grep -RInEi "(replaces|заменяет).{0,80}(SIEM|DLP)|(SIEM|DLP).{0,80}(replacement|заменяет)" "${scan_files[@]}" \
|
|
| grep -Eiv "(does not|not |not_claimed|не |forbidden|не заявляет)" \
|
|
>/tmp/release_evidence_forbidden_replace.$$ 2>/dev/null; then
|
|
fail "forbidden_claim_siem_dlp_replacement:$(cat /tmp/release_evidence_forbidden_replace.$$)"
|
|
fi
|
|
rm -f /tmp/release_evidence_forbidden_replace.$$
|
|
|
|
if ((${#failures[@]} > 0)); then
|
|
printf 'release_evidence_check=fail\n'
|
|
for failure in "${failures[@]}"; do
|
|
printf '%s\n' "$failure"
|
|
done
|
|
exit 2
|
|
fi
|
|
|
|
printf 'release_evidence_check=ok\n'
|