diff options
author | Juergen Daubert <juergen.daubert@t-online.de> | 2006-09-04 19:02:00 +0000 |
---|---|---|
committer | Juergen Daubert <juergen.daubert@t-online.de> | 2006-09-04 19:02:00 +0000 |
commit | a8d3e111ba64c9b91e8eeb6750de3f30de69a397 (patch) | |
tree | 18f396f2dd3d7cf043e3c35529bc78f5d8adfbf3 /lib | |
parent | c0922fe4735ddb104a0e0b2562eb7e20a0b534ad (diff) | |
download | prt-utils-a8d3e111ba64c9b91e8eeb6750de3f30de69a397.tar.gz prt-utils-a8d3e111ba64c9b91e8eeb6750de3f30de69a397.tar.xz |
prt-utils: added prtverify
Diffstat (limited to 'lib')
-rw-r--r-- | lib/prtverify/00_prtverify_lib.awk | 70 | ||||
-rw-r--r-- | lib/prtverify/05_file_check.awk | 58 | ||||
-rw-r--r-- | lib/prtverify/10_file_check_clean_repo.awk | 32 | ||||
-rw-r--r-- | lib/prtverify/20_evil_cmds.awk | 47 | ||||
-rw-r--r-- | lib/prtverify/20_maintainer_email.awk | 17 | ||||
-rw-r--r-- | lib/prtverify/20_missing_deps.awk | 31 | ||||
-rw-r--r-- | lib/prtverify/20_pkgfile_headers.awk | 38 | ||||
-rw-r--r-- | lib/prtverify/20_pkgfile_vars.awk | 35 | ||||
-rw-r--r-- | lib/prtverify/20_port_name_match.awk | 16 | ||||
-rw-r--r-- | lib/prtverify/20_release_number.awk | 18 | ||||
-rw-r--r-- | lib/prtverify/30_file_conflict.awk | 30 | ||||
-rw-r--r-- | lib/prtverify/30_file_permissions.awk | 16 | ||||
-rw-r--r-- | lib/prtverify/30_invalid_dirs.awk | 25 | ||||
-rw-r--r-- | lib/prtverify/30_junk_files.awk | 25 | ||||
-rw-r--r-- | lib/prtverify/30_suid_sgid.awk | 16 | ||||
-rw-r--r-- | lib/prtverify/30_system_users.awk | 29 | ||||
-rw-r--r-- | lib/prtverify/90_mk_footprint_db.awk | 57 | ||||
-rw-r--r-- | lib/prtverify/prtverify.wl | 8 |
18 files changed, 568 insertions, 0 deletions
diff --git a/lib/prtverify/00_prtverify_lib.awk b/lib/prtverify/00_prtverify_lib.awk new file mode 100644 index 0000000..36faf85 --- /dev/null +++ b/lib/prtverify/00_prtverify_lib.awk @@ -0,0 +1,70 @@ +# +# 00_prtverify_lib.awk +# +# Version 0.1.6 - 2006-08-30 +# Jürgen Daubert <jue at jue dot li> +# +# Utility functions for prtverify + + +function fullpath(dir, cmd) +{ + cmd = "cd " dir " && pwd" + cmd | getline dir + close(cmd) + return dir +} + +function collectionport(path) +{ + sub(/\/$/, "", path) + return substr(path, match(path, /[^/]+\/[^/]+$/)) +} + +function perror(level,message, d,i,l,m,p,w) +{ + l = 25 + w[INFO] = "INFO " + w[WARN] = "WARN " + w[ERROR] = "ERROR " + w[FATAL] = "FATAL " + + p = substr(COLLPORT, 1, l) + for (i=1; i<=l-length(p); i++) + d = d "." + m = sprintf("%s %s %s %s", w[level], p, d, message) + if (! (m in WLIST)) + print m +} + +function loglevel_ok(level) +{ + return and(LOG_LEVEL,level) +} + +function usr_error(message) +{ + print "===== ", message > "/dev/stderr" +} + + +BEGIN { + + if (! LOG_LEVEL) + LOG_LEVEL = 15 + + if (LOG_LEVEL <1 || LOG_LEVEL >15) { + LOG_LEVEL = 15 + usr_error("Invalid loglevel, using " LOG_LEVEL) + } + + INFO = 8 + WARN = 4 + ERROR = 2 + FATAL = 1 + + PKGFILE = ".*\\/Pkgfile" + FOOTPRINT = ".*\\/\\.footprint" + MD5SUM = ".*\\/\\.md5sum" +} + diff --git a/lib/prtverify/05_file_check.awk b/lib/prtverify/05_file_check.awk new file mode 100644 index 0000000..2f5524a --- /dev/null +++ b/lib/prtverify/05_file_check.awk @@ -0,0 +1,58 @@ +# +# 05_file_check.awk +# +# Version 0.1.8 - 2006-08-30 +# Jürgen Daubert <jue at jue dot li> +# +# Tests for the mandatory port files +# +# Sets some global variables +# - PORTDIR the full path of the port +# - PORT the name of the port +# - COLLPORT a shortcut for Collection/Port like core/gcc +# +# PORT_FILES and WHITE_LIST are set by prtverify + + + +function readwhitelist(file, line) +{ + if (system("test -f " file) != 0) + return + while ((getline line < file) > 0) + WLIST[line] +} + + +BEGIN { + + PORTDIR = ARGV[1] + if (system("test -d " PORTDIR) != 0) { + usr_error(PORTDIR " is not a directory, ignoring") + exit + } + + PORTDIR = fullpath(PORTDIR) + PORT = gensub(/^.*\//, "", 1, PORTDIR) + COLLPORT = collectionport(PORTDIR) + + delete ARGV + ARGC = 1 + + split(PORT_FILES, af) + + for (f in af) { + p = PORTDIR "/" af[f] + if (system("test -f " p) == 0) + ARGV[ARGC++] = p + else + if(loglevel_ok(FATAL)) + perror(FATAL, "file not found: " af[f]) + } + + if (ARGC == 1) + exit + + readwhitelist(WHITE_LIST) +} + diff --git a/lib/prtverify/10_file_check_clean_repo.awk b/lib/prtverify/10_file_check_clean_repo.awk new file mode 100644 index 0000000..df6632d --- /dev/null +++ b/lib/prtverify/10_file_check_clean_repo.awk @@ -0,0 +1,32 @@ +# +# 10_file_check_clean_repo.awk +# +# Version 0.1.0 - 2006-08-07 +# Johannes Winkelmann, jw at smts dot ch +# +# Tests for invalid files in a clean repo + + +function list_files(dir,af, cmd,f) +{ + cmd = "ls -1A --color=none " dir + delete af + while (cmd | getline f) + af[f] + close(cmd) +} + + +BEGIN { + + if (loglevel_ok(FATAL)) { + + list_files(PORTDIR, af) + + for (f in af) { + if (f ~ "(.(tar.(bz2|gz)|tgz|zip|rar|svn)|CVS|REPO|index.hml)$") + perror(FATAL, "invalid file/directory: " f) + } + } +} + diff --git a/lib/prtverify/20_evil_cmds.awk b/lib/prtverify/20_evil_cmds.awk new file mode 100644 index 0000000..9c0ff9a --- /dev/null +++ b/lib/prtverify/20_evil_cmds.awk @@ -0,0 +1,47 @@ +# +# 20_evil_cmds.awk +# +# Version 0.1.2 - 2006-07-14 +# Jürgen Daubert <jue at jue dot li> +# +# Two test to find malicious rm and cd commands like 'rm -rf /usr'. +# +# Because there are often cases where we need a rm inside the workdir, +# it's not posssible to expect always a $PKG in front of the rm parameter. +# Best would be to interpret the whole build function to see where we are +# in the filesystem. For now it should be sufficent to have a look at the +# cd command too, to find something like 'cd /usr && rm -rf .' +# +# The test for rm is a bit complicated, because we often have multiline +# commands with rm. + + +loglevel_ok(FATAL) && FILENAME ~ PKGFILE { + + if (match($0, /\<rm\>/)) { + + a = substr($0, RSTART) + + while ($0 ~ /\\$/) { + getline + a = a $0 + gsub(/\\/, "", a) + } + + split(a, ab) + + for (i in ab) { + if (ab[i] ~ /^\//) + perror(FATAL, "Use of rm outside the workdir, Pkgfile line " NR) + } + } + + + if ($0 ~ /\<cd\>/) { + for (c=1; c<=NF; c++) { + if ($c == "cd" && $(c+1) ~ /^\//) + perror(FATAL, "Use of cd to go outside the workdir, Pkgfile line " NR) + } + } +} + diff --git a/lib/prtverify/20_maintainer_email.awk b/lib/prtverify/20_maintainer_email.awk new file mode 100644 index 0000000..5cfa662 --- /dev/null +++ b/lib/prtverify/20_maintainer_email.awk @@ -0,0 +1,17 @@ +# +# 20_maintainer_email.awk +# +# Version 0.1.0 - 2006-09-02 +# Jürgen Daubert <jue at jue dot li> +# +# Checks the Maintainer header for invalid characters + + +loglevel_ok(WARN) && FILENAME ~ PKGFILE { + + if ( $0 ~ ("^# Maintainer:") ) { + if ( p = match($0, /[<>@]+/) ) + perror(WARN, "invalid email address: " substr($0, p)) + } +} + diff --git a/lib/prtverify/20_missing_deps.awk b/lib/prtverify/20_missing_deps.awk new file mode 100644 index 0000000..b6eb821 --- /dev/null +++ b/lib/prtverify/20_missing_deps.awk @@ -0,0 +1,31 @@ +# +# 20_missing_deps.awk +# +# Version 0.1 - 2006-08-26 +# Jürgen Daubert <jue at jue dot li> + + +BEGIN { + + if (DEP_PORTS) { + split(DEP_PORTS, ac) + for (i in ac) + DEP_MAP[ac[i]] + } +} + + +loglevel_ok(ERROR) && FILENAME ~ PKGFILE && DEP_PORTS { + + if ( $0 ~ ("^# Depends on:") ) { + + split($0, ac, /:[[:space:]]*/) + split(ac[2], ad, /[[:space:]]*,[[:space:]]*|[[:space:]]+/) + + for (d in ad) { + if (ad[d] !~ /^ *$/ && ! (ad[d] in DEP_MAP)) + perror(ERROR, "missing dependency: " ad[d]) + } + } +} + diff --git a/lib/prtverify/20_pkgfile_headers.awk b/lib/prtverify/20_pkgfile_headers.awk new file mode 100644 index 0000000..968b152 --- /dev/null +++ b/lib/prtverify/20_pkgfile_headers.awk @@ -0,0 +1,38 @@ +# +# 20_pkgfile_headers.awk +# +# Version 0.1.1 - 2006-08-24 +# Jürgen Daubert <jue at jue dot li> + + +BEGIN { + + pkgfile_headers["Description"] = 0 + pkgfile_headers["URL"] = 0 + pkgfile_headers["Maintainer"] = 0 +} + + +loglevel_ok(ERROR) && FILENAME ~ PKGFILE { + + for (h in pkgfile_headers) { + if ( $0 ~ ("^# " h ":") ) { + pkgfile_headers[h] = 1 + split($0, ac, ":") + if (! ac[2]) + perror(ERROR, "empty header found: " h) + } + } +} + + +END { + + if (loglevel_ok(ERROR)) { + for (h in pkgfile_headers) { + if (! pkgfile_headers[h]) + perror(ERROR, "header not found: " h) + } + } +} + diff --git a/lib/prtverify/20_pkgfile_vars.awk b/lib/prtverify/20_pkgfile_vars.awk new file mode 100644 index 0000000..4cf3d5c --- /dev/null +++ b/lib/prtverify/20_pkgfile_vars.awk @@ -0,0 +1,35 @@ +# +# 20_pkgfile_vars.awk +# +# Version 0.1.2 - 2006-07-14 +# Jürgen Daubert <jue at jue dot li> + + +BEGIN { + + pkgfile_vars["name"] = 0 + pkgfile_vars["version"] = 0 + pkgfile_vars["release"] = 0 + pkgfile_vars["source"] = 0 +} + + +loglevel_ok(ERROR) && FILENAME ~ PKGFILE { + + for (v in pkgfile_vars) { + if ( $1 ~ ("^" v "=") ) + pkgfile_vars[v] = 1 + } +} + + +END { + + if (loglevel_ok(ERROR)) { + for (v in pkgfile_vars) { + if (! pkgfile_vars[v]) + perror(ERROR, "variable not found: " v) + } + } +} + diff --git a/lib/prtverify/20_port_name_match.awk b/lib/prtverify/20_port_name_match.awk new file mode 100644 index 0000000..5cfc83a --- /dev/null +++ b/lib/prtverify/20_port_name_match.awk @@ -0,0 +1,16 @@ +# +# 20_port_name_match.awk +# +# Version 0.1.1 - 2006-07-14 +# Jürgen Daubert <jue at jue dot li> + + +loglevel_ok(ERROR) && FILENAME ~ PKGFILE { + + if ($1 ~ /^name=/) { + split($1, an, "=") + if (an[2] != PORT) + perror(ERROR, "variable name do not match the portname: " an[2]) + } +} + diff --git a/lib/prtverify/20_release_number.awk b/lib/prtverify/20_release_number.awk new file mode 100644 index 0000000..6c63717 --- /dev/null +++ b/lib/prtverify/20_release_number.awk @@ -0,0 +1,18 @@ +# +# 20_release_number.awk +# +# Version 0.1.2 - 2006-07-14 +# Jürgen Daubert <jue at jue dot li> +# +# only integer numbers >= 1 are valid for the release variable + + +loglevel_ok(ERROR) && FILENAME ~ PKGFILE { + + if ($1 ~ /^release=/) { + split($1, an, "=") + if (an[2] !~ /^[1-9][0-9]*$/) + perror(ERROR, "variable release contains invalid characters: " an[2]) + } +} + diff --git a/lib/prtverify/30_file_conflict.awk b/lib/prtverify/30_file_conflict.awk new file mode 100644 index 0000000..ad1c073 --- /dev/null +++ b/lib/prtverify/30_file_conflict.awk @@ -0,0 +1,30 @@ +# +# 30_file_conflict.awk +# +# Version 0.1.0 - 2006-08-31 +# Jürgen Daubert <jue at jue dot li> + + +BEGIN { + + if (FOOTPRINTDB) { + while ((getline l < FOOTPRINTDB) > 0) { + split(l, am, "\t") + file_conflict[am[1]] = am[2] + } + close(file) + } +} + + +loglevel_ok(ERROR) && FILENAME ~ FOOTPRINT { + + if ($3 in file_conflict) { + split(file_conflict[$3], am, ":") + for (i in am) { + if (am[i] != COLLPORT) + perror(ERROR, "file conflict found: " am[i] " -> " $3) + } + } +} + diff --git a/lib/prtverify/30_file_permissions.awk b/lib/prtverify/30_file_permissions.awk new file mode 100644 index 0000000..d20e5a0 --- /dev/null +++ b/lib/prtverify/30_file_permissions.awk @@ -0,0 +1,16 @@ +# +# 30_file_permissions.awk +# +# Version 0.1.1 - 2006-07-14 +# Jürgen Daubert <jue at jue dot li> + + +loglevel_ok(FATAL) && FILENAME ~ FOOTPRINT { + + if ($1 ~ /^d.......w./) + perror(FATAL, "world writable directory found: " $3) + + if ($1 ~ /^-.......w./) + perror(FATAL, "world writable file found: " $3) +} + diff --git a/lib/prtverify/30_invalid_dirs.awk b/lib/prtverify/30_invalid_dirs.awk new file mode 100644 index 0000000..b132ec1 --- /dev/null +++ b/lib/prtverify/30_invalid_dirs.awk @@ -0,0 +1,25 @@ +# +# 30_invalid_dirs.awk +# +# Version 0.1.2 - 2006-07-16 +# Jürgen Daubert <jue at jue dot li> + + +BEGIN { + + invalid_dirs[1] = "^usr/share/man/$" + invalid_dirs[2] = "^usr/local/$" + invalid_dirs[3] = "^usr/share/locale/$" + invalid_dirs[4] = "^usr/info/$" + invalid_dirs[5] = "^usr/libexec/$" +} + + +loglevel_ok(ERROR) && FILENAME ~ FOOTPRINT { + + for (d in invalid_dirs) { + if ($3 ~ invalid_dirs[d]) + perror(ERROR, "directory not allowed: " $3) + } +} + diff --git a/lib/prtverify/30_junk_files.awk b/lib/prtverify/30_junk_files.awk new file mode 100644 index 0000000..8925c5a --- /dev/null +++ b/lib/prtverify/30_junk_files.awk @@ -0,0 +1,25 @@ +# +# 30_junk_files.awk +# +# Version 0.1.2 - 2006-07-14 +# Jürgen Daubert <jue at jue dot li> + + +BEGIN { + + # Perl junk files + junk_files[1] = ".*/perl./.*/(perllocal\\.pod|\\.packlist|[^/]+\\.bs)$" + + # GNU junk files + junk_files[2] = "AUTHORS|BUGS|COPYING|ChangeLog|INSTALL|NEWS|README|THANKS|TODO" +} + + +loglevel_ok(WARN) && FILENAME ~ FOOTPRINT { + + for (f in junk_files) { + if ($3 ~ junk_files[f]) + perror(WARN, "junk file found: " $3) + } +} + diff --git a/lib/prtverify/30_suid_sgid.awk b/lib/prtverify/30_suid_sgid.awk new file mode 100644 index 0000000..161dd2b --- /dev/null +++ b/lib/prtverify/30_suid_sgid.awk @@ -0,0 +1,16 @@ +# +# 30_suid_sgid.awk +# +# Version 0.1 - 2006-07-24 +# Jürgen Daubert <jue at jue dot li> + + +loglevel_ok(INFO) && FILENAME ~ FOOTPRINT { + + if ($1 ~ /^...s....../) + perror(INFO, "suid file found: " $3) + + if ($1 ~ /^......s.../) + perror(INFO, "sgid file found: " $3) +} + diff --git a/lib/prtverify/30_system_users.awk b/lib/prtverify/30_system_users.awk new file mode 100644 index 0000000..5211a87 --- /dev/null +++ b/lib/prtverify/30_system_users.awk @@ -0,0 +1,29 @@ +# +# 30_system_users.awk +# +# Version 0.1.1 2006-07-14 +# Jürgen Daubert <jue at jue dot li> + + +loglevel_ok(ERROR+INFO) && FILENAME ~ FOOTPRINT { + + split($2, au, "/") + warned = 0 + + if (loglevel_ok(ERROR)) { + + if (au[1] ~ /[1-9][0-9]*/) { + perror(ERROR, "invalid user: " $2 " -> " $3) + warned = 1 + } + + if (au[2] ~ /[1-9][0-9]*/) + perror(ERROR, "invalid group: " $2 " -> " $3) + } + + if (! warned && loglevel_ok(INFO) && $3 ~ /^(lib|sbin|usr)\//) { + if (au[1] !~ /root/) + perror(INFO, "file not owned by root: " $2 " -> " $3) + } +} + diff --git a/lib/prtverify/90_mk_footprint_db.awk b/lib/prtverify/90_mk_footprint_db.awk new file mode 100644 index 0000000..ba11917 --- /dev/null +++ b/lib/prtverify/90_mk_footprint_db.awk @@ -0,0 +1,57 @@ +# +# 90_mk_footprint_db.awk +# +# Version 0.1.0 - 2006-08-31 +# Jürgen Daubert <jue at jue dot li> +# +# Creates a temporary file with all footprints and +# the owners of those +# +# File format: +# <file-name> coll1/port1:coll2/port2:... +# +# Needed variables: +# - FOOTPRINTDB the name of the temporary file +# +# Requires: +# - 00_prtverify_lib.awk +# +# Usage example: +# gawk -v FOOTPRINTDB=<file> \ +# -f 00_prtverify_lib.awk \ +# -f 90_mk_footprint_db.awk \ +# /usr/ports/{core,opt,contrib}/*/.footprint + + +function beginfile(name) +{ + sub(/\/\.footprint/, "", name) + name = fullpath(name) + COLLPORT = collectionport(name) +} + + +BEGIN { + FS = "\t" +} + + +FNR == 1 { + beginfile(FILENAME) +} + +FILENAME ~ FOOTPRINT && $3 !~ /\/$/ { + sub(/ -> .*/, "", $3) + if (! ($3 in fc_map)) + fc_map[$3] = COLLPORT + else + fc_map[$3] = fc_map[$3] ":" COLLPORT +} + + +END { + + for (i in fc_map) + print i "\t" fc_map[i] > FOOTPRINTDB +} + diff --git a/lib/prtverify/prtverify.wl b/lib/prtverify/prtverify.wl new file mode 100644 index 0000000..6daf8a3 --- /dev/null +++ b/lib/prtverify/prtverify.wl @@ -0,0 +1,8 @@ +WARN core/autoconf ............ junk file found: usr/share/autoconf/INSTALL +WARN core/automake ............ junk file found: usr/share/automake-1.9/COPYING +WARN core/automake ............ junk file found: usr/share/automake-1.9/INSTALL +FATAL core/filesystem .......... world writable directory found: tmp/ +FATAL core/filesystem .......... world writable directory found: var/lock/ +FATAL core/filesystem .......... world writable directory found: var/spool/mail/ +FATAL core/filesystem .......... world writable directory found: var/tmp/ + |