diff --git a/build_whl.com b/build_whl.com new file mode 100644 index 0000000000000000000000000000000000000000..a152158c3b479f42ba0afe941983380df9164082_YnVpbGRfd2hsLmNvbQ== --- /dev/null +++ b/build_whl.com @@ -0,0 +1,3 @@ +$ python -m build -w -n -x -o ./ ./ +$ +$ exit diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..a152158c3b479f42ba0afe941983380df9164082_cHlwcm9qZWN0LnRvbWw= --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,39 @@ +[build-system] +requires = [ + "setuptools>=42", + "wheel" +] +build-backend = "setuptools.build_meta" + +[project] +name = "secrules" +version = "0.1.0" +description = "secrules for VSI Python 3" +readme = "README.md" +requires-python = ">= 3.10" +license.file = "LICENSE" +authors = [ + { name = "Jean-François Piéronne", email = "jf.pieronne@laposte.net" }, +] +classifiers = [ + "License :: OSI Approved :: GNU LGPL v3 License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: Implementation :: CPython", +] +urls.homepage = "https://foss.vmsgenerations.org/openvms/tools/secrules/" +urls.changelog = "https://foss.vmsgenerations.org/openvms/tools/secrules/" + +dependencies = [ +] + +[project.optional-dependencies] +docs = [ +] +test = [ +] +typing = [ +] +virtualenv = [ +] diff --git a/secrules/__main__.py b/secrules/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..a152158c3b479f42ba0afe941983380df9164082_c2VjcnVsZXMvX19tYWluX18ucHk= --- /dev/null +++ b/secrules/__main__.py @@ -0,0 +1,164 @@ +# -*- coding: iso-8859-1 -*- + +import sys +import os +import re +import argparse +import importlib + +DEBUG = False +if DEBUG: + import debugpy + + # 5678 is the default attach port in the VS Code debug configurations. + # Unless a host and port are specified, host defaults to 127.0.0.1 + debugpy.configure(subProcess=False) + + debugpy.listen(('0.0.0.0', 5678), in_process_debug_adapter=True) + print('Waiting for debugger attach') + debugpy.wait_for_client() + debugpy.breakpoint() + print('break on this line') + + +all_rules = {} +args = None + + +def rules_exec(seclass, numrule=None, info=False, fo=None, export=None): + global all_rules, args + rules = all_rules[seclass][1] + m = all_rules[seclass][0] + if numrule is None: + for r in rules: + if info: + print(getattr(m, r).__name__) + print(getattr(m, r).__doc__) + print() + else: + getattr(m, r)(fo, export) + else: + for n in numrule: + rname = 'rule%s%02d' % (seclass[-2:], n) + if rname in rules: + if info: + print(getattr(m, rname).__name__) + print(getattr(m, rname).__doc__) + print() + else: + getattr(m, rname)(fo, export) + + +class InflateRange(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): + lst = [] + for string in values: # type: ignore + string = string.replace('(', '') + string = string.replace(')', '') + if '-' in string or ':' in string: + string = string.replace(':', '-') + m = re.match(r'(\d+)(?:-(\d+))?$', string) + # ^ (or use .split('-'). anyway you like.) + if not m: + raise argparse.ArgumentTypeError( + "'" + + string + + "' is not a range of number. Expected forms like '0-5' or '2'." + ) + start = m.group(1) + end = m.group(2) or start + lst.extend(list(range(int(start, 10), int(end, 10) + 1))) + else: + string = string.replace(',', ' ') + for string in string.split(' '): + if string: + lst.append(int(string)) + setattr(namespace, self.dest, lst) + + +def load_rules(levels): + global all_rules + mods = [ + fn[:-3] + for fn in os.listdir('./secrules') + if fn.startswith('rule') and fn[-1:].lower() == 'y' + ] + all_rules = {} + for modn in mods: + m = importlib.import_module('.' + modn, 'secrules') + # m = __import__('secrules.' + modn, globals(), locals(), ['*'], -1) + lst = [m, []] + for r in dir(m): + if r.startswith('rule'): + if ( + levels is None + or not hasattr(getattr(m, r), 'rule_level') + or getattr(m, r).rule_level in levels + ): + lst[1].append(r) + all_rules[modn] = lst + # all_rules[modn] = (m, [r for r in dir(m) if r.startswith('rule')]) + + +def main(): + global args + parser = argparse.ArgumentParser(description='security checker') + parser.add_argument( + '--output', + type=argparse.FileType('w'), + dest='fo', + metavar='out-file', + help='output file', + default=sys.stdout, + ) + parser.add_argument( + '--class', type=int, dest='seclass', help='security class' + ) + parser.add_argument( + '--rule', + action=InflateRange, + nargs='*', + dest='numrule', + help='rule number', + ) + parser.add_argument( + '--export', + action='store_true', + dest='export', + default=False, + help='export format', + ) + parser.add_argument( + '--info', + action='store_true', + dest='info', + default=False, + help='Rules info', + ) + parser.add_argument( + '--level', + action=InflateRange, + nargs='*', + dest='levels', + help='rule levels', + ) + + args = parser.parse_args() + + load_rules(args.levels) + + if args.seclass is None: + if args.numrule is not None: + raise argparse.ArgumentTypeError('missing seclass argument') + lst = list(all_rules.keys()) + lst.sort() + for seclass in lst: + # seclass = 'rules%02d' % args.seclass + rules_exec(seclass, args.numrule, args.info, args.fo, args.export) + else: + seclass = 'rules%02d' % args.seclass + rules_exec(seclass, args.numrule, args.info, args.fo, args.export) + + +if __name__ == '__main__': + main() diff --git a/setup.py b/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..a152158c3b479f42ba0afe941983380df9164082_c2V0dXAucHk= --- /dev/null +++ b/setup.py @@ -0,0 +1,20 @@ +from setuptools import setup, find_packages, Distribution + +class PureDistribution(Distribution): + def is_pure(self): + return True + + def has_ext_modules(self): + return False + +setup( + # this will be the package name you will see + name = 'secrules', + # some version number you may wish to add - increment this after every update + version='0.1', + package_data={'': ['*.exe', '*.pyi']}, + distclass=PureDistribution, + + packages=find_packages(), #include/exclude arguments take * as wildcard, . for any sub-package names +) +