Added the argparse module to be able to use command line arguments.
authorPhilipp Spitzer <philipp@spitzer.priv.at>
Thu, 28 Jun 2012 19:30:01 +0000 (21:30 +0200)
committerPhilipp Spitzer <philipp@spitzer.priv.at>
Thu, 28 Jun 2012 19:30:01 +0000 (21:30 +0200)
findwwwritable.py

index 6ef15c1..efd77ad 100755 (executable)
@@ -1,21 +1,22 @@
 #!/usr/bin/python
-# python 2.x is used
+# python 2.7+ is used
 
 import os
 import stat
 from os.path import join
+import argparse
 
 
-def collect_writable_dirs(rootdir, uids, gids):
-    """Returns a list of directories below rootdir (including rootdir) that are writable 
+def collect_writable_dirs(basedir, uids, gids):
+    """Returns a list of directories below basedir (including basedir) that are writable
     by the users with the given uids or gids or that are world writable.
     Normally, uid(s) is the user id of the apache user (e.g. www-data) and gids is a list
     of group ids this user is member of.
     
-    :param rootdir: string. directory where the search should start at
+    :param basedir: string. directory where the search should start at
     :param uids: list of integer user ids
     :param gids: list of integer group ids"""
-    assert isinstance(rootdir, str)
+    assert isinstance(basedir, str)
     assert isinstance(uids, list)
     for uid in uids: assert isinstance(uid, int)
     assert isinstance(gids, list)
@@ -23,7 +24,7 @@ def collect_writable_dirs(rootdir, uids, gids):
 
     writable_dirs = [] # dirs with write permissions - this list is filled by this function
 
-    for root, dirs, files in os.walk(rootdir):
+    for root, dirs, files in os.walk(basedir):
         for d in dirs:
             dp = join(root, d) # dp is the dir with path
             s = os.lstat(dp)
@@ -84,20 +85,39 @@ def apply_whitelist(writable_dirs, whitelist):
 
 
 if __name__ == '__main__':
+    # constants
+    PROGNAME = 'findwwwritable'
+    VERSION = '0.0.2'
 
     # variables
     uids = [33]                # user ids of the user whos write permissions should be found
     gids = [33, 42, 121, 127]  # group ids of the user whos write permissions should be found
-    rootdir = '/home'          # directory where the seach is started
+    basedir = '/home'          # directory where the seach is started
+    config_filename = '/etc/findwwwritable/config'
     whitelist_filename = '/etc/findwwwritable/whitelist' # list of directories that are known to be writable
                                                          # and that should not be reported.
 
+    # parse command line arguments
+    parser = argparse.ArgumentParser(description='find directories that are writeable by www-data (or an other user)')
+    parser.add_argument('-v', '--version', action='version', version='{} {}'.format(PROGNAME, VERSION))
+    parser.add_argument('-c', '--config', help='configuration file (default: {})'.format(config_filename), default=config_filename)
+    parser.add_argument('-w', '--whitelist', help='filename of whitelist (default: {})'.format(whitelist_filename), default=whitelist_filename)
+    parser.add_argument('-f', '--full', help='do not omit subdirs', action='store_true')
+    parser.add_argument('-u', '--uid', dest='uids', help='system uid of the user. may be specified more than once. (default: {})'.format(uids), action='append', type=int)
+    parser.add_argument('-g', '--gid', dest='gids', help='system gid of the user. may be specified more than once. (default: {})'.format(gids), action='append', type=int)
+    parser.add_argument('basedir', nargs='*', default=basedir, help='directories are searched below basedir (default: {})'.format(basedir))
+    args = parser.parse_args()
+    if args.uids is None: args.uids = uids
+    if args.gids is None: args.gids = gids
+
     # read whitelist
-    whitelist = read_whitelist(whitelist_filename)
+    whitelist = read_whitelist(args.whitelist)
 
     # collect and summarize writable directories
-    writable_dirs = collect_writable_dirs(rootdir, uids, gids)
-    writable_dirs = summarize_dirs(writable_dirs)
+    writable_dirs = []
+    for basedir in args.basedir:
+        writable_dirs.extend(collect_writable_dirs(basedir, args.uids, args.gids))
+    if not args.full: writable_dirs = summarize_dirs(writable_dirs)
     writable_dirs = apply_whitelist(writable_dirs, whitelist)
 
     # print writable directories