diff previous-work/more_control_helpers/bin/list_package @ 1:d6bef198ae71

add work by Matthias S. Benkmann which is the inspiration for this project.
author Robert McIntyre <rlm@mit.edu>
date Tue, 08 Jan 2013 11:45:01 +0000
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/previous-work/more_control_helpers/bin/list_package	Tue Jan 08 11:45:01 2013 +0000
     1.3 @@ -0,0 +1,291 @@
     1.4 +#!/bin/bash
     1.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
     1.6 +# You may do everything with this code except misrepresent its origin.
     1.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
     1.8 +
     1.9 +if [ $# -lt 1 -o \( $# -gt 1 -a "z$1" != "z:man" -a "z$1" != "z:mani" -a "z$1" != "z:lib" \) -o "$1" = "--help" ]; then
    1.10 +  echo 1>&2
    1.11 +  echo 1>&2 'USAGE: '"${0##*/}"' <user_or_group_name>'
    1.12 +  echo 1>&2
    1.13 +  echo 1>&2 '  Entries will be matched if group and/or user equals <user_or_group_name>'
    1.14 +  echo 1>&2 '    (numeric UID/GID allowed).'
    1.15 +  echo 1>&2 '  This script uses `forall_direntries_from'"'"' and `list_suspicious_files_from'"'."
    1.16 +  echo 1>&2
    1.17 +  echo 1>&2 '  NOTE: Several minutes may pass before you see the first output.'
    1.18 +  echo 1>&2 '  You should probably redirect output to a file for later reference.'
    1.19 +  echo 1>&2
    1.20 +  echo 1>&2 '  WARNING! This program is for listing files from package users only!'
    1.21 +  echo 1>&2 '           Do NOT use it to list files from untrusted users!'
    1.22 +  echo 1>&2 '           An untrusted user could set up a manipulated manpage to exploit'
    1.23 +  echo 1>&2 '           a bug in man when it is used to extract the summary!'
    1.24 +  exit 1
    1.25 +fi
    1.26 +
    1.27 +# KNOWN BUGS:
    1.28 +#  - when extracting summaries from manpages, candidate manpages are considered
    1.29 +#    in alphabetic order rather than the order used by the man command.
    1.30 +#    The problem with this is that section 8, which contains manpages for
    1.31 +#    admin commands, will be considered after lower-numbered sections.
    1.32 +#    In the rare case that an admin command has the same name as a topic from
    1.33 +#    a lower-numbered manpage installed by the same package, the summary will
    1.34 +#    be taken from the wrong manpage.
    1.35 +#    An example for such a clash are the faillog.5 and faillog.8 manpages from
    1.36 +#    the shadow package.
    1.37 +#    Because this problem is difficult to fix, rare and easily spotted (since
    1.38 +#    the manpage that should have provided the summary will be listed under
    1.39 +#    EXTRA MANPAGES) I won't fix it.
    1.40 +
    1.41 +ugname="$1"
    1.42 +
    1.43 +#suppress ugly debug output from shell
    1.44 +trap ':' SIGPIPE
    1.45 +
    1.46 +if [ $# -gt 1 ]; then
    1.47 +  name="${2##*/}"
    1.48 +  case "$1" in
    1.49 +    :man) 
    1.50 +      name=${name%.gz}
    1.51 +      name=${name%.bz2}
    1.52 +      name=${name%.*}
    1.53 +      echo $'command\2'"$name"$'\2man\2'"$2" ;;
    1.54 +    :mani) 
    1.55 +      name=${name%.gz}
    1.56 +      name=${name%.bz2}
    1.57 +      name=${name%.*}
    1.58 +      echo $'command\2'"$name"$'\2mani\2'"$2" ;;
    1.59 +    :lib) 
    1.60 +      name=${name%.a}
    1.61 +      name=${name%%.so*}
    1.62 +      echo "lib $name" 
    1.63 +      ;;
    1.64 +  esac
    1.65 +  exit 0
    1.66 +fi
    1.67 +
    1.68 +sanitize() { tr -c '[:print:]' '?' ; }
    1.69 +
    1.70 +# $1: <commandname>
    1.71 +# $2: command\2<commandname>\2cmd\2(-><linktarget>)
    1.72 +# $3: command\2<commandname>\2man[i]\2<manpage_path>  or  <empty>
    1.73 +expand_command()
    1.74 +{
    1.75 +  sep=$'\2'
    1.76 +  cmdname="$1"
    1.77 +  cmdline="$2"
    1.78 +  manline="$3"
    1.79 +  linktarget="${cmdline##*${sep}}"
    1.80 +  
    1.81 +  if [ -z "$manline" ]; then
    1.82 +    description='No manpage'
    1.83 +    #the "l" at the beginning is just to make it sort after "lib"
    1.84 +    echo -n "lmanlessbin $cmdname" | sanitize
    1.85 +    echo 
    1.86 +    
    1.87 +  else # if [ ! -z "$manline" ]; then
    1.88 +    manpage=${manline##*${sep}}
    1.89 +    manpagedir=${manpage%/*}
    1.90 +    wsc='[[:space:],]\+'
    1.91 +    # The cd $manpagedir is a workaround for a bug in man-db that causes it
    1.92 +    # to attempt to resolve paths relative to cwd.
    1.93 +    # The `t l;d;:l;n;b l' in the sed command is voodoo magic to make sed
    1.94 +    # output only the first match but to keep eating up all input. I use this
    1.95 +    # instead of  `| head -n 1', because head breaks the pipe after doing
    1.96 +    # its 1 line output, which (if it happens before sed has processed the
    1.97 +    # complete input) freaks out man and causes it to emit a totally
    1.98 +    # silly error message including "No such file or directory", which is
    1.99 +    # annoying when you do testing without suppressing man's errors.
   1.100 +    # The $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' removes the backspace-based 
   1.101 +    # as well as ESC-based formatting from man's output. 
   1.102 +    description="$( { cd "$manpagedir/.." 2>/dev/null ;
   1.103 +                      COLUMNS=300 man "$manpage" 2>/dev/null || 
   1.104 +                                      echo " $name - Broken manpage" ; } | 
   1.105 +       sed $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' |
   1.106 +       sed -n "/^NAME/,/^[A-Z]/s/^.*${wsc}${cmdname}${wsc}.*-\+${wsc}\(.*\)/\1/p;t l;d;:l;n;b l" )"
   1.107 +    if [ -z "$description" ]; then
   1.108 +      description="$( cd "$manpagedir/.." 2>/dev/null ;
   1.109 +                      COLUMNS=300 man "$manpage" 2>/dev/null |
   1.110 +        sed $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' |
   1.111 +        sed -n "s/^.*${wsc}..*${wsc}.*-\+${wsc}\(.*\)/\1/p;t l;d;:l;n;b l" )"
   1.112 +    fi
   1.113 +    test -z "$description" && description="Weird manpage"
   1.114 +  fi
   1.115 +
   1.116 +  echo -n "binexe $cmdname" | sanitize
   1.117 +  test "$linktarget" != '(->)' && echo -n "$linktarget" | sanitize
   1.118 +  echo 
   1.119 +  #the "lx" in "lxdescription" is just to make sure it sorts after "lmanlessbin"
   1.120 +  echo -n "lxdescription $cmdname: $description" | sanitize  
   1.121 +  echo 
   1.122 +}
   1.123 +
   1.124 +# NOTE: The -path and -lname stuff at the beginning of the following is
   1.125 +# there to make sure that none of the lines output by find contains
   1.126 +# a) \n or \r, because that would mess up post-processing the output 
   1.127 +#    line-by-line.
   1.128 +# b) \x7f, because this character triggers one of the nastier bash-bugs
   1.129 +#    wrt string handling
   1.130 +# c) \2, because I use this as separator within the lines
   1.131 +#    (Why \2 and not \0 or \1 ? Because bash can't cope with \0 at all and has
   1.132 +#    bugs related to \1.)
   1.133 +#
   1.134 +# Because of this, having the final section called "ALL FILES" is technically
   1.135 +# a lie, because files with a path containing one of the abovementioned
   1.136 +# characters will not appear in output.
   1.137 +# However, a) no sane package contains such files
   1.138 +#          b) they will be listed in the output from list_suspicious_files
   1.139 +cmd=(\( -path $'*\n*' -or -path $'*\r*' -or -path $'*\x7f*' 
   1.140 +        -or -path $'*\2*'
   1.141 +        -or -lname $'*\n*' -or -lname $'*\r*' -or -lname $'*\x7f*' 
   1.142 +        -or -lname $'*\2*' 
   1.143 +     \) 
   1.144 +     -or
   1.145 +     \(
   1.146 +       \( -printf "zall %p\n" \) ,
   1.147 +       \(
   1.148 +         \( -type f -or -xtype f \) -and
   1.149 +         \(
   1.150 +           \( -perm -u+x \( -path "*/bin/*" -or -path "*/sbin/*" \) -printf 'command\2%f\2cmd\2(->%l)\n' \)
   1.151 +       -or \( -path "*/man/man*/*" -exec "$0" ":man" {} \; \)
   1.152 +       -or \( -path "*/man/*/man*/*" -exec "$0" ":mani" {} \; \)
   1.153 +       -or \( \( -name "lib*.so" -or -name "lib*.a" -or -name "lib*.so.*" \) -path "*/lib/*" -exec "$0" ":lib" {} \; \)
   1.154 +       -or \( -type f -perm -u+x -not \( \( -name "lib*.so" -or -name "lib*.a" -or -name "lib*.so.*" \) -path "*/lib/*" \)  -printf "nobinexe %p\n" \)
   1.155 +         \)
   1.156 +       \)  
   1.157 +     \)
   1.158 +    )
   1.159 +
   1.160 +forall_direntries_from "$ugname" "${cmd[@]}" | sort -u |
   1.161 +{
   1.162 +  sep=$'\2'
   1.163 +  hold=''
   1.164 +  for((;;)) 
   1.165 +  do
   1.166 +    if [ -z "$hold" ]; then
   1.167 +      read -r line || break
   1.168 +    else
   1.169 +      line="$hold"
   1.170 +      hold=''
   1.171 +    fi
   1.172 +    
   1.173 +    case "z$line" in
   1.174 +      zcommand${sep}*${sep}cmd${sep}*) 
   1.175 +        cmdname=${line#command${sep}}
   1.176 +        cmdname=${cmdname%%${sep}*}
   1.177 +        read -r hold
   1.178 +        case "z$hold" in
   1.179 +          zcommand${sep}${cmdname}${sep}man${sep}*|zcommand${sep}${cmdname}${sep}mani${sep}*) 
   1.180 +            expand_command "$cmdname" "$line" "$hold"
   1.181 +            hold=''
   1.182 +          ;;
   1.183 +          
   1.184 +          z*) 
   1.185 +            expand_command "$cmdname" "$line" ""
   1.186 +          ;;
   1.187 +        esac
   1.188 +        ;;
   1.189 +
   1.190 +      zcommand${sep}*${sep}man${sep}*|command${sep}*${sep}mani${sep}*) 
   1.191 +         
   1.192 +        echo -n "manextra ${line##*${sep}}" | sanitize
   1.193 +        echo
   1.194 +        ;;
   1.195 +
   1.196 +      z*) 
   1.197 +        echo -n "$line" | sanitize
   1.198 +        echo
   1.199 +        ;;
   1.200 +    esac
   1.201 +    
   1.202 +  done
   1.203 +} | sort |  #no -u here, bc. the above processing may equalize different files
   1.204 +{
   1.205 +# (1) binexe: Executables (in *bin/)
   1.206 +# (2) lib: Libraries (in *lib/*)
   1.207 +# (3) lmanlessbin: Executables (in *bin/) without manpages
   1.208 +# (4) lxdescription: Summaries for executables (in *bin/)
   1.209 +# (5) manextra: Extra manpages
   1.210 +#     full paths, no perms
   1.211 +# (6) nobinexe: Executables not in *bin/ (excluding *lib/*.so and *lib/*.so.*)
   1.212 +#     full paths, no perms
   1.213 +# (7) zall: All files
   1.214 +#     full paths, no perms
   1.215 +
   1.216 +  curstate=''
   1.217 +  while read -r line
   1.218 +  do
   1.219 +    newstate="${line%% *}"
   1.220 +    if [ "$newstate" != "$curstate" ]; then
   1.221 +      curstate="$newstate"
   1.222 +      case "$curstate" in
   1.223 +        binexe)
   1.224 +          echo 'EXECUTABLES (in */bin or */sbin)'
   1.225 +          echo -n "  ${line#binexe }"
   1.226 +          ;;
   1.227 +        lib)
   1.228 +          echo
   1.229 +          echo
   1.230 +          echo 'LIBRARIES (lib*.a or lib*.so)'
   1.231 +          echo -n "  ${line#lib }"
   1.232 +          ;;
   1.233 +        lmanlessbin)
   1.234 +          echo
   1.235 +          echo
   1.236 +          echo 'EXECUTABLES WITH NO MANPAGE (in */bin or */sbin)'
   1.237 +          echo -n "  ${line#lmanlessbin }"
   1.238 +          ;;
   1.239 +        lxdescription)
   1.240 +          echo
   1.241 +          echo
   1.242 +          echo 'MANPAGE SUMMARIES OF EXECUTABLES (in */bin or */sbin)'
   1.243 +          echo "  ${line#lxdescription }"
   1.244 +          ;;
   1.245 +        manextra)
   1.246 +          echo
   1.247 +          echo 'EXTRA MANPAGES'
   1.248 +          echo "  ${line#manextra }"
   1.249 +          ;;
   1.250 +        nobinexe)
   1.251 +          echo
   1.252 +          echo 'EXTRA EXECUTABLES (not in */bin or */sbin)'
   1.253 +          echo "  ${line#nobinexe }"
   1.254 +          ;;
   1.255 +        zall)
   1.256 +          echo
   1.257 +          echo 'ALL FILES'
   1.258 +          echo "  ${line#zall }"
   1.259 +          ;;
   1.260 +        *) 
   1.261 +          echo
   1.262 +          echo
   1.263 +          echo 'UNEXPECTED LINE'
   1.264 +          echo "  $line"
   1.265 +          ;;
   1.266 +        
   1.267 +      esac
   1.268 +    else
   1.269 +      case "$curstate" in
   1.270 +        binexe) echo -n ", ${line#binexe }" 
   1.271 +          ;;
   1.272 +        lib) echo -n ", ${line#lib }" 
   1.273 +          ;;
   1.274 +        lmanlessbin) echo -n ", ${line#lmanlessbin }" 
   1.275 +          ;;
   1.276 +        lxdescription) echo "  ${line#lxdescription }" 
   1.277 +          ;;
   1.278 +        manextra) echo "  ${line#manextra }" 
   1.279 +          ;;
   1.280 +        nobinexe) echo "  ${line#nobinexe }" 
   1.281 +          ;;
   1.282 +        zall) echo "  ${line#zall }" 
   1.283 +          ;;
   1.284 +        *) 
   1.285 +          echo
   1.286 +          echo 'UNEXPECTED LINE'
   1.287 +          echo "  $line"
   1.288 +          ;;
   1.289 +      esac
   1.290 +    fi
   1.291 +  done
   1.292 +} 
   1.293 +
   1.294 +list_suspicious_files_from "$ugname"