Exemple #1
0
    def get_general_property(self, element, prop_key, prop_value):
        """Answers the query property(element, prop_key, prop_value).
        element, prop_key and prop_value are all prolog data types.
        If the property is not defined, it gets recorded in the
        list of requested but undefined properties, but only if
        prop_key is not a variable.
        """
        prop_key_value = get_value(prop_key)
        if isinstance(prop_key_value, Atom):
            # property key is a constant value, which means it is
            # specifically requested.
            v_prop_value = self.query_engine.variable()
            q = list(
                self.query_engine.query(
                    'prop', [element, prop_key_value, v_prop_value]))
            if q == []:
                # property is not defined
                self.add_undefined_property(to_python(element),
                                            to_python(prop_key_value))

            else:
                self.validate_defined_property(element, prop_key_value)

        for l2 in self.query_engine.query('prop',
                                          [element, prop_key, prop_value]):
            yield False
Exemple #2
0
 def get_property_help(elt, prop):
     a_element = a.query_engine.atom(elt)
     a_property = a.query_engine.atom(prop)
     v_value = a.query_engine.variable()
     v_text = a.query_engine.variable()
     q = a.query_engine.query('prop_text', [a_element, a_property, v_value, v_text])
     return [ (to_python(v_value), to_python(v_text)) for r in q ]
Exemple #3
0
def test_functor_arities():
    s = compile_prolog_from_string(
        '''
    likes(A,B) :- person(A), person(B), friend(A,B).
    likes(A,B,C) :- person(A),person(B), person(C), friend(A,B), friend(A,C).
    likes(A,B) :- person(A), person(B), person(C), foe(A,C), foe(B,C).
    person(mike).
    person(joe).
    person(pete).
    person(zack).
    friend(mike,pete).
    friend(mike,joe).
    foe(joe,zack).
    foe(pete,zack).
    ''', TestContext)

    yp = YP()
    yp.load_script_from_string(s, overwrite=False)
    X = yp.variable()
    Y = yp.variable()
    q = yp.query('likes', [X, Y])
    r = [(to_python(X.get_value()), to_python(Y.get_value())) for x in q]
    assert set(r) == set([
        ('mike', 'pete'),
        ('mike', 'joe'),
        ('joe', 'pete'),
        ('joe', 'joe'),
        ('pete', 'pete'),
        ('pete', 'joe'),
    ])
Exemple #4
0
def test_model_types_defined():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_with_flows)
    name = a.variable()
    tmtype = a.variable()
    q = a.query('type', [name, tmtype])
    r = [[to_python(name), to_python(tmtype)] for _ in q]
    assert r == [[t.name, t] for t in dfd_with_flows.types.values()]
Exemple #5
0
 def optional_attr(self, element, key, value, default):
     # key and default need to be instantiated
     elt = to_python(element)
     self._debug("DEBUG: element", repr(elt))
     v = elt.get(to_python(key), to_python(default))
     for y in unify(value, self.query_engine.atom(v)):
         self._debug("DEBUG: optional_attr: %s=%s" % (to_python(key), v))
         yield False
Exemple #6
0
def test_model_subtypes_defined():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_with_flows)
    tmtype = a.variable()
    parent_type = a.variable()
    q = a.query('subtype', [tmtype, parent_type])
    r = [[to_python(tmtype), to_python(parent_type)] for _ in q]
    tmtype = dfd_with_flows.get_flows()[0].types[0]
    assert r == [[tmtype, t] for t in tmtype.types]
Exemple #7
0
 def validate_property_value(self, element, prop_key, prop_value):
     c_valid = self.query_engine.atom('prop_valid')
     l = list(
         self.query_engine.query('prop_valid',
                                 [element, prop_key, prop_value]))
     if l == []:
         self.invalid_properties.add(
             (to_python(element), to_python(prop_key),
              to_python(prop_value)))
Exemple #8
0
def test_model_query_flow_clause():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_with_flows)
    v_from = a.variable()
    v_to = a.variable()
    v_elt = a.variable()
    q = a.query('flow', [v_elt, v_from, v_to])
    r = [[to_python(v_elt), to_python(v_from), to_python(v_to)] for _ in q]
    flows = dfd_with_flows.get_flows()
    assert r == [[flows[0], flows[0].source, flows[0].target]]
Exemple #9
0
def test_model_query_element_type():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_with_flows)
    zone = dfd_with_flows.get_zones()[0]
    components = dfd_with_flows.get_zone_components(zone)
    elt = a.atom(components[0])
    value = a.variable()
    q = a.query('element', [elt, value])
    r = [[to_python(elt), to_python(value) ] for _ in q]
    assert r == [[components[0], components[0].types[0]]]
Exemple #10
0
 def get_xpath_value(self, query, variable):
     try:
         self._debug("DEBUG: query: %s" % (to_python(query)))
         r = self.xml_tree.xpath(to_python(query))
         for y in r:
             self._debug("DEBUG: %s = %s" % (to_python(query), repr(y)))
             for _ in unify(variable, self.query_engine.atom(y)):
                 yield False
     except lxml.etree.XPathEvalError as e:
         print("ERROR (xpath):", e, to_python(query))
Exemple #11
0
def test_model_query_element_type_inherited():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_with_flows)
    zone = dfd_with_flows.get_zones()[0]
    flows = dfd_with_flows.get_flows()
    elt = a.atom(flows[0])
    value = a.variable()
    q = a.query('element', [elt, value])
    r = [[to_python(elt), to_python(value)] for _ in q]
    assert r == [[flows[0], flows[0].types[0]]]
Exemple #12
0
def test_model_query_component_zone():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_with_flows)
    elt = a.variable()
    value = a.variable()
    const_zone = a.atom('zone')
    q = a.query('property', [elt, const_zone, value])
    r = [[to_python(elt), to_python(value)] for _ in q]
    zone = dfd_with_flows.get_zones()[0]
    components = dfd_with_flows.get_zone_components(zone)
    assert r == [[components[0], zone], [components[1], zone]]
Exemple #13
0
def test_model_query_zone_zone():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_nested_zones)
    elt = a.variable()
    value = a.variable()
    const_zone = a.atom('zone')
    q = a.query('property', [elt, const_zone, value])
    r = [[to_python(elt), to_python(value)] for _ in q]
    office_zone = dfd_nested_zones.zones['office']
    company_zone = dfd_nested_zones.zones['company']
    components = dfd_nested_zones.get_zone_components(office_zone)
    assert r == [[office_zone, company_zone], [components[0], office_zone]]
Exemple #14
0
def test_model_query_undefined_property():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_with_flows)
    flows = dfd_with_flows.get_flows()
    # elt = a.variable()
    elt = a.atom(flows[0])
    value = a.variable()
    const_key = a.atom('define_me')
    q = a.query('property', [elt, const_key, value])
    r = [[to_python(elt), to_python(value)] for _ in q]
    assert r == []
    assert len(a.undefined_properties) == 1
    assert len(a.invalid_properties) == 0
Exemple #15
0
 def attr(self, element, key, value):
     elt = to_python(element)
     self._debug("DEBUG: element", repr(elt))
     for k, v in elt.items():
         for x in unify(key, self.query_engine.atom(k)):
             for y in unify(value, self.query_engine.atom(v)):
                 self._debug("DEBUG: attr: %s=%s" % (k, v))
                 yield False
Exemple #16
0
def get_xpath_value(xml_tree, query, variable):
    '''xpath(Tree, Query, Variable).
    runs the xpath query Query against the XML tree Tree, and
    stores its result in Variable.'''
    # check if tree and query are bound to a value
    tree_a = get_value(xml_tree)
    if not isinstance(tree_a, Atom):
        return
    query_a = get_value(query)
    if not isinstance(query, Atom):
        return
    # do the XPath query
    root = to_python(tree_a).getroot()
    q = to_python(query_a)
    for v in root.findall(q):
        for r in unify(variable, Atom(v)):
            yield False
Exemple #17
0
def test_model_query_dataflow_has_property():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_with_flows)

    add_threat_library_from_source(a, '''
    prop_valid(X,https,yes).
    prop_valid(X,https,no).
    ''')

    elt = a.variable()
    value = a.variable()
    const_key = a.atom('https')
    q = a.query('property', [elt, const_key, value])
    r = [[to_python(elt), to_python(value)] for _ in q]
    flows = dfd_with_flows.get_flows()
    assert r == [[flows[0], 'yes']]
    assert len(a.invalid_properties) == 0
Exemple #18
0
def test_analyzer_loads_script():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_with_flows)
    tl = ThreatLibrary.from_string('animal(monkey).')
    a.add_prolog_rules_from_threat_library(tl)
    v = a.variable()
    q = a.query('animal', [v])
    r = [to_python(v) for _ in q]
    assert r[0] == 'monkey'
Exemple #19
0
def test_model_query_invalid_dataflow_property():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_with_flows_and_invalid_property)

    tl = ThreatLibrary.from_string('''
    prop_valid(X,https,yes).
    prop_valid(X,https,no).
    ''')
    a.add_prolog_rules_from_threat_library(tl)

    flows = dfd_with_flows_and_invalid_property.get_flows()
    elt = a.atom(flows[0])
    value = a.variable()
    const_key = a.atom('https')
    q = a.query('property', [elt, const_key, value])
    r = [[to_python(elt), to_python(value)] for _ in q]
    assert len(r) == 1
    assert len(a.undefined_properties) == 0
    assert len(a.invalid_properties) == 1
Exemple #20
0
def load_xml_tree(xml_tree, filename):
    # first, filename must be bound to an Atom.
    fn_a = get_value(filename)
    if not isinstance(fn_a, Atom):
        # we could raise an exception, but we will just return and not
        # yield any results
        return
    with open(to_python(fn_a), 'r') as f:
        tree = dxml.parse(f)
        a = Atom(tree)
        for r in unify(xml_tree, a):
            yield False
Exemple #21
0
def convert_specfile_to_prolog(infile, outf):
    model = parse_file(infile)
    a = ThreatAnalyzer()
    a.set_model(model)
    outf.write("%% DFD prolog code, generated from:\n")
    outf.write(f"%% {infile}\n\n")
    for predicate, answers in a.query_engine._predicates_store.items():
        outf.write("%% %s/%d:\n" % predicate)
        for answer in answers:
            values = ",".join(obj_to_prolog(to_python(x)) for x in answer.values)
            outf.write("%s(%s).\n" % (predicate[0], values))
        outf.write("\n")
Exemple #22
0
def test_model_zone_valid_values():
    a = FTOThreatAnalyzer()
    a.set_model(dfd_nested_zones)

    add_threat_library_from_source(a, '''
    prop_valid(X,https,yes).
    prop_valid(X,https,no).
    ''')

    z = dfd_nested_zones.get_zones()[1]
    elt = dfd_nested_zones.get_zone_components(z)[0]
    elt = a.variable()
    value = a.variable()
    const_zone = a.atom('zone')
    q = a.query('prop_valid', [elt, const_zone, value])
    r = [ to_python(value) for _ in q ]
    assert r == dfd_nested_zones.get_zones()
Exemple #23
0
 def ask(self, query):
     v = self.query_engine.variable()
     q = self.query_engine.query(query, [v])
     return [to_python(v) for r in q]
Exemple #24
0
 def lowercase(self, val1, val2):
     self._debug("DEBUG: lowercase: %s=%s" % (val1, val2))
     # val1 must be instantiated
     v = self.query_engine.atom(to_python(val1).lower())
     for x in unify(val2, v):
         yield False
Exemple #25
0
 def version_at_least(self, version1, version2):
     # version1 and version2 must be instantiated
     v1 = to_python(version1).split('.')
     v2 = to_python(version2).split('.')
     if v2 >= v1:
         yield False
Exemple #26
0
    stores its result in Variable.'''
    # check if tree and query are bound to a value
    tree_a = get_value(xml_tree)
    if not isinstance(tree_a, Atom):
        return
    query_a = get_value(query)
    if not isinstance(query, Atom):
        return
    # do the XPath query
    root = to_python(tree_a).getroot()
    q = to_python(query_a)
    for v in root.findall(q):
        for r in unify(variable, Atom(v)):
            yield False


qe = yldprolog.engine.YP()
qe.register_function('xml_tree', load_xml_tree)
qe.register_function('xpath', get_xpath_value)

# Execute xml_tree(Tree, 'books.xml').
fn_a = qe.atom('books.xml')
v = qe.variable()
tree_a = [get_value(v) for r in qe.query('xml_tree', [v, fn_a])][0]

# Execute xpath(Tree, 'book/author', V).
q_a = qe.atom('book/author')
authors = [to_python(v) for r in qe.query('xpath', [tree_a, q_a, v])]
for a in authors:
    print(a.text)