예제 #1
0
    def test_member(self):
        x = V.make_variable("x")
        y = V.make_variable("y")
        z = V.make_variable("z")

        p = Prolog()
        p.fact(x.pair(y.pair(x)).make_const("member"))
        p.head_body(
            x.pair(y.pair(z)).make_const("member"),
            x.pair(y).make_const("member"))

        w = []
        p.go(
            x.pair(L.make_const(1).make_const(2).make_const(3)).make_const(
                "member"), lambda: w.append(x.value()))
        self.assertEqual(w, [3, 2, 1])
예제 #2
0
 def test(self):
     x = V.make_variable('x')
     t = [1, 2, 3]
     p = Prolog()
     for e in t:
         p.fact(C.make_const(e))
     w = []
     p.go(x, lambda: w.append(x.value()))
     self.assertEqual(w, t)
예제 #3
0
    def test_member_hard(self):
        x = V.make_variable("x")
        y = V.make_variable("y")
        z = V.make_variable("z")

        p = Prolog()
        p.fact(x.pair(y.pair(x)).make_const("member"))
        p.head_body(
            x.pair(y.pair(z)).make_const("member"),
            x.pair(y).make_const("member"))

        w = []
        m = L.make_const(1).make_const(2).make_const(3).make_const(4)
        n = L.make_const(0).make_const(2).make_const(4).make_const(6)
        p.go(
            x.pair(m).make_const("member") & x.pair(n).make_const("member"),
            lambda: w.append(x.value()))
        self.assertEqual(w, [4, 2])
예제 #4
0
    def test_conjunction(self):
        x = V.make_variable('x')
        p = Prolog()
        p.fact(C.make_const(1).make_const("single"))
        p.fact(C.make_const(2).make_const("single"))
        p.head_body(x.pair(x).make_const("double"), x.make_const("single"))

        w = []

        def check():
            w.append(x.value())
            if check.counter >= 10:
                assert False
            check.counter += 1

        check.counter = 0

        p.go(x.pair(x).make_const("double"), check)
        self.assertEqual(w, [1, 2])
예제 #5
0
    def test_head_body_conjunction(self):
        x = V.make_variable("x")
        y = V.make_variable("y")
        p = Prolog()
        p.fact(C.make_const(1).make_const('a'))
        p.fact(C.make_const(2).make_const('b'))
        p.head_body(
            x.pair(y).make_const('c'),
            x.make_const('a') & y.make_const('b'))
        w = 0

        def check():
            nonlocal w
            w += 1
            self.assertEqual(x.value(), 1)
            self.assertEqual(y.value(), 2)

        p.go(x.pair(y).make_const('c'), check)
        self.assertEqual(w, 1)
예제 #6
0
    def test_and_nested(self):
        w = 0
        p = Prolog()
        for e in [1, 2, 3]:
            p.fact(C.make_const(e))

        def go():
            nonlocal w
            w += 1

        p.go(C.make_const(1) & (C.make_const(2) & C.make_const(3)), go)
        self.assertEqual(w, 1)
예제 #7
0
    def test_two_answers(self):
        x = V.make_variable("x")
        y = V.make_variable("y")

        p = Prolog()
        p.fact(x)
        p.fact(y)

        w = []

        p.go(C.make_const(1), lambda: w.append(None))

        self.assertEqual(w, [None, None])
예제 #8
0
    def test_instantiation(self):
        x = V.make_variable("x")

        p = Prolog()
        p.fact(x)
        w = 0

        def do():
            nonlocal w
            w += 1

        p.go(C.make_const(1) & C.make_const(2), do)
        self.assertEqual(w, 1)
예제 #9
0
    def test_head_body_conjunction_warmup_warmup_y_unassigned(self):
        x = V.make_variable("x")
        y = V.make_variable("y")
        p = Prolog()
        p.fact(C.make_const(1).make_const('a'))
        p.fact(C.make_const(2).make_const('b'))
        w = 0

        def check():
            nonlocal w
            w += 1
            self.assertEqual(x.value(), 1)
            with self.assertRaises(Exception):
                y.value()

        p.go(x.make_const('a'), check)
        self.assertEqual(w, 1)
예제 #10
0
    def test_last(self):
        a = V.make_variable('a')
        b = V.make_variable('b')
        c = V.make_variable('c')

        x = V.make_variable('x')
        y = V.make_variable('y')
        z = V.make_variable('z')

        p = Prolog()
        p.fact(x.pair(y.pair(x)).make_const("member"))
        p.head_body(
            x.pair(y.pair(z)).make_const("member"),
            x.pair(y).make_const("member"))

        p.fact(L.pair(x).pair(x).make_const("append"))
        p.head_body(
            a.pair(x).pair(b).pair(c.pair(x)).make_const("append"),
            a.pair(b).pair(c).make_const("append"))

        def do():
            for q in [x, y]:
                s = []
                p.go(
                    a.pair(q).make_const("member"),
                    lambda: s.append(a.value()))
                w.append(s)

        w = []
        p.go(
            x.pair(y).pair(L.make_const('c').make_const('b').make_const(
                'a')).make_const('append'), do)

        self.assertEqual(w,
                         [[], ['a', 'b', 'c'], ['a'], ['b', 'c'], ['a', 'b'],
                          ['c'], ['a', 'b', 'c'], []])
예제 #11
0
from prolog import Prolog, QuerySet
import os

prolog = Prolog(path_to_swipl=os.environ["path_to_swipl"])


@prolog.predicate
def person(name: str, age: int):
    yield name, age


@prolog.predicate
def old(name: str):
    x = prolog.query_var("Y")
    y = prolog.query_var("Y")
    return person(name, x) and y > 60


prolog << person("andrew", 12)
prolog << person("arseny", 15)
prolog << person("vitalii", 73)

prolog.load_predicates()

X = prolog.query_var("X")
Y = prolog.query_var("Y")

q = prolog >> person(X, Y)

print(q.fetch())  # generator object
print(q.fetchone())  # {"x": "andrew", "y": 12}
예제 #12
0
from prolog import Prolog, ANONYMOUS_QV as _, Predicate
from dataclasses import dataclass
from typing import List
import os

prolog = Prolog(path_to_swipl=os.environ["path_to_swipl"])


@dataclass
class Person(Predicate):
    name: str
    sex: int
    age: int
    children: List[str]


prolog << Person("Gomez", 0, 52, ["Wednesday", "Pugsley"])
prolog << Person("Morticia", 1, 48, ["Wednesday", "Pugsley"])
prolog << Person("Pugsley", 0, 13, [])
prolog << Person("Wednesday", 1, 13, [])
prolog << Person("Grandmama", 1, 100, ["Gomez"])

prolog.load_predicates()

q = Person.filter(children=[_ | _])

for person in q.fetch(prolog):
    print(person.name, "has children")
예제 #13
0
def main():
    print("BigMAC Android Policy Processor")
    print(" by Grant Hernandez (https://hernan.de/z)")
    print("")

    parser = argparse.ArgumentParser()
    parser.add_argument('--vendor', required=True)
    parser.add_argument("policy_name")

    parser.add_argument('--debug',
                        action='store_true',
                        help="Enable debug logging.")

    parser.add_argument(
        '--debug-init',
        action='store_true',
        help="Drop into an IPython shell after simulating the boot process.")
    parser.add_argument('--skip-boot',
                        action='store_true',
                        help="Don't simulate the boot process.")

    parser.add_argument('--draw-graph', action='store_true')
    parser.add_argument('--focus-set')

    parser.add_argument('--save',
                        action='store_true',
                        help="Save the instantiated policy graph.")
    parser.add_argument('--load',
                        action='store_true',
                        help="Reload the saved instantiated policy graph.")
    parser.add_argument('--save-policy',
                        action='store_true',
                        help="Generate selinux.txt for debugging.")
    parser.add_argument('--list-objects', action='store_true')

    parser.add_argument('--dont-expand-objects', action='store_true')
    parser.add_argument(
        '--prolog',
        action='store_true',
        help="Compile Prolog helpers and start the query engine")

    args = parser.parse_args()

    if args.load and args.save:
        log.info("--load and --save are exclusive options")
        return 1

    if args.debug:
        logging.getLogger().setLevel(logging.DEBUG)

    if args.policy_name[-1] == "/":
        args.policy_name = args.policy_name[:-1]
    args.policy_name = os.path.basename(args.policy_name)

    policy_results_dir = os.path.join(POLICY_RESULTS_DIR, args.vendor.lower(),
                                      args.policy_name)

    if not os.access(policy_results_dir, os.R_OK):
        log.error("Policy directory does not exist or is not readable")
        return 1

    log.info("Loading android security policy %s (%s)", args.policy_name,
             args.vendor)

    asp = AndroidSecurityPolicy(args.vendor, args.policy_name)
    aspc = ASPCodec(asp)

    try:
        asp = aspc.load()
    except ValueError as e:
        log.error("Saved policy is corrupt: %s", e)
        return 1

    android_version = asp.get_android_version()
    major, minor, revision = android_version
    log.info("Image summary: %s", asp.get_properties()["summary"])

    # Treble handling
    if major == 8:
        file_contexts = read_file_contexts(
            asp.get_saved_file_path("plat_file_contexts"))
        file_contexts += read_file_contexts(
            asp.get_saved_file_path("nonplat_file_contexts"))
    elif major >= 9:
        file_contexts = read_file_contexts(
            asp.get_saved_file_path("plat_file_contexts"))
        file_contexts += read_file_contexts(
            asp.get_saved_file_path("vendor_file_contexts"))
    else:
        file_contexts = read_file_contexts(
            asp.get_saved_file_path("file_contexts"))

    log.info("Loaded %d file contexts", len(file_contexts))
    primary_filesystem = asp.fs_policies[0]

    if args.load:
        try:
            inst = aspc._load_db("inst")
        except ValueError as e:
            log.error("Unable to load saved instantiation: %s", e)
            return 1
    else:
        inst = main_process(args, asp, aspc, file_contexts, primary_filesystem,
                            android_version)

    if inst is None:
        return

    if args.debug:
        from IPython import embed
        oldlevel = logging.getLogger().getEffectiveLevel()
        logging.getLogger().setLevel(logging.INFO)
        embed()
        logging.getLogger().setLevel(oldlevel)

    if args.list_objects:
        output_filename = '%s-files.txt' % (args.policy_name.replace(
            "..", "_").replace(os.sep, ""))
        log.info("Saving file list to %s", output_filename)

        with open(output_filename, 'w') as fp:
            fp.write(primary_filesystem.list_path("*"))

        output_filename = '%s-processes.txt' % (args.policy_name.replace(
            "..", "_").replace(os.sep, ""))
        log.info("Saving process list to %s", output_filename)

        with open(output_filename, 'w') as fp:
            fp.write(inst.list_processes())

    if args.prolog:
        G = inst.fully_instantiate()

        pl = Prolog(G, aspc.db_dir, inst, asp)

        if pl.compile_all():
            pl.interact()

    if args.draw_graph:
        GDF = graph["graphs"]["dataflow"]
        GP = graph["graphs"]["process"]
        GSUB = graph["graphs"]["subject"]

        focus_set = set()
        if args.focus_set:
            focus_names = args.focus_set.split(",")
            focus_set = set(focus_names)

        plot(GDF, "dataflow.svg", prune=True, debug=False, focus_set=focus_set)
        plot(GP, "process.svg", debug=False)
        plot(GSUB, "subject.svg", debug=False)

    return 0