diff options
author | Zhipeng (Howard) Huang <huangzhipeng@huawei.com> | 2017-02-27 13:08:54 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@opnfv.org> | 2017-02-27 13:08:54 +0000 |
commit | 69e33063b3703ae4529b556b63b3c4cc239c3d9a (patch) | |
tree | b30d14715b34f2e4e06928c555c940ddb3365534 /verigraph/service/src/mcnet | |
parent | 280310852bb5e1c7639dedf7ce268e1e66157a51 (diff) | |
parent | 53d83244c1bf36af86e90ce5fe758a369f73563e (diff) |
Merge "Add verigraph code base"
Diffstat (limited to 'verigraph/service/src/mcnet')
27 files changed, 3329 insertions, 0 deletions
diff --git a/verigraph/service/src/mcnet/components/Checker.java b/verigraph/service/src/mcnet/components/Checker.java new file mode 100644 index 0000000..3c13d28 --- /dev/null +++ b/verigraph/service/src/mcnet/components/Checker.java @@ -0,0 +1,363 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.components; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.Expr; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Model; +import com.microsoft.z3.Solver; +import com.microsoft.z3.Status; + +/**Various checks for specific properties in the network. + * + */ +public class Checker { + + Context ctx; + Network net; + NetContext nctx; + Solver solver; + ArrayList<BoolExpr> constraints; + public BoolExpr [] assertions; + public Status result; + public Model model; + + + public Checker(Context context,NetContext nctx,Network network){ + this.ctx = context; + this.net = network; + this.nctx = nctx; + this.solver = ctx.mkSolver(); + this.constraints = new ArrayList<BoolExpr>(); + } + + /**Resets the constraints + * + */ + public void clearState (){ + this.solver.reset(); + this.constraints = new ArrayList<BoolExpr>(); + } + + /**Checks whether the source provided can reach the destination + * + * @param src + * @param dest + * @return + */ + public IsolationResult checkIsolationProperty (NetworkObject src, NetworkObject dest){ + assert(net.elements.contains(src)); + assert(net.elements.contains(dest)); + solver.push (); + addConstraints(); + + Expr p0 = ctx.mkConst("check_isolation_p0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet); + Expr p1 = ctx.mkConst("check_isolation_p1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet); + Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node()); + IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node()); + + // Constraint1 recv(n_0,destNode,p0,t_0) + this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p0, t_0)); + + // Constraint2 send(srcNode,n_1,p1,t_1) + this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p1, t_1)); + + // Constraint3 nodeHasAddr(srcNode,p1.srcAddr) + this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p1))); + + // Constraint4 p1.origin == srcNode + this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p1), src.getZ3Node())); + + // Constraint5 nodeHasAddr(destNode,p1.destAddr) + this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(dest.getZ3Node(), nctx.pf.get("dest").apply(p1))); + + //NON sembrano necessari + // this.solver.add(z3.Or(this.ctx.nodeHasAddr(src.getZ3Node(), this.ctx.packet.src(p0)),\ + // this.ctx.nodeHasAddr(n_0, this.ctx.packet.src(p0)),\ + // this.ctx.nodeHasAddr(n_1, this.ctx.packet.src(p0)))) + //this.solver.add(this.ctx.packet.dest(p1) == this.ctx.packet.dest(p0)) + + // Constraint6 p1.origin == p0.origin + this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p1),nctx.pf.get("origin").apply(p0))); + + // Constraint7 nodeHasAddr(destNode, p0.destAddr) + this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(dest.getZ3Node(), nctx.pf.get("dest").apply(p0))); + + result = this.solver.check(); + model = null; + assertions = this.solver.getAssertions(); + if (result == Status.SATISFIABLE){ + model = this.solver.getModel(); + } + this.solver.pop(); + return new IsolationResult(ctx,result, p0, n_0, t_1, t_0, nctx, assertions, model); + } + + + + public IsolationResult CheckIsolationFlowProperty (NetworkObject src, NetworkObject dest){ + assert(net.elements.contains(src)); + assert(net.elements.contains(dest)); + solver.push (); + addConstraints(); + + Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet); + Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + Expr n_2 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + + IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node()); + IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node()); + IntExpr t_2 = ctx.mkIntConst("check_isolation_t2_"+src.getZ3Node()+"_"+dest.getZ3Node()); + + // Constraint1 recv(n_0,destNode,p,t_0) + this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t_0)); + + // Constraint2 send(srcNode,n_1,p1,t_1) + this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p, t_1)); + + // Constraint3 nodeHasAddr(srcNode,p.srcAddr) + this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p))); + + // Constraint4 p.origin == srcNode + this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node())); + + + Expr p_2 = ctx.mkConst("check_isolation_p_flow_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet); + + // Constraint5 there does not exist p_2, n_2, t_2 : + // send(destNode,n_2,p_2,t_2) && + // p_2.srcAddr == p. destAddr && + // p_2.srcPort == p.destPort && + // p_2.destPort == p.srcPort && + // p_2.destt == p.src && + // t_2 < t_0 + this.solver.add(ctx.mkNot(ctx.mkExists(new Expr[]{p_2,n_2,t_2}, + ctx.mkAnd( + (BoolExpr)nctx.send.apply(dest.getZ3Node(), n_2, p_2, t_2), + ctx.mkEq(nctx.pf.get("src").apply(p_2), nctx.pf.get("dest").apply(p)), + ctx.mkEq(nctx.pf.get("src_port").apply(p_2), nctx.pf.get("dest_port").apply(p)), + ctx.mkEq(nctx.pf.get("dest_port").apply(p_2), nctx.pf.get("src_port").apply(p)), + ctx.mkEq(nctx.pf.get("dest").apply(p_2), nctx.pf.get("src").apply(p)), + ctx.mkLt(t_2,t_0)),1,null,null,null,null))); + + + result = this.solver.check(); + model = null; + assertions = this.solver.getAssertions(); + if (result == Status.SATISFIABLE){ + model = this.solver.getModel(); + } + this.solver.pop(); + return new IsolationResult(ctx,result, p, n_0, t_1, t_0, nctx, assertions, model); + } + + + + public IsolationResult CheckNodeTraversalProperty (NetworkObject src, NetworkObject dest, NetworkObject node){ + assert(net.elements.contains(src)); + assert(net.elements.contains(dest)); + solver.push (); + addConstraints(); + + Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet); + + Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + Expr n_2 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + + IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node()); + IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node()); + IntExpr t_2 = ctx.mkIntConst("check_isolation_t2_"+src.getZ3Node()+"_"+dest.getZ3Node()); + + // Constraint1 recv(n_0,destNode,p,t_0) + this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t_0)); + + // Constraint2 send(srcNode,n_1,p1,t_1) + this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p, t_1)); + + // Constraint3 nodeHasAddr(srcNode,p.srcAddr) + this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p))); + + // Constraint4 p.origin == srcNode + this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node())); + + + // Constraint5 there does not exist n_2, t_2 : recv(n_2,node,p,t_2) && t_2 < t_0 + this.solver.add(ctx.mkNot(ctx.mkExists(new Expr[]{n_2,t_2}, + ctx.mkAnd( + (BoolExpr)nctx.recv.apply(n_2, node.getZ3Node(), p, t_2), + ctx.mkLt(t_2,t_0)),1,null,null,null,null))); + + // Constraint 6 there does not exist n_2, t_2 : send(node,n_2,p,t_2) && t_2 < t_0 + this.solver.add(ctx.mkNot(ctx.mkExists(new Expr[]{n_2,t_2}, + ctx.mkAnd( + (BoolExpr)nctx.send.apply(node.getZ3Node(), n_2, p, t_2), + ctx.mkLt(t_2,t_0)),1,null,null,null,null))); + + + result = this.solver.check(); + model = null; + assertions = this.solver.getAssertions(); + if (result == Status.SATISFIABLE){ + model = this.solver.getModel(); + } + this.solver.pop(); + return new IsolationResult(ctx,result, p, n_0, t_1, t_0, nctx, assertions, model); + + } + + public IsolationResult CheckLinkTraversalProperty (NetworkObject src, NetworkObject dest, NetworkObject le0, NetworkObject le1){ + assert(net.elements.contains(src)); + assert(net.elements.contains(dest)); + solver.push (); + addConstraints(); + + Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet); + + Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + Expr n_1 =ctx.mkConst("check_isolation_n_1_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + + IntExpr t_0 = ctx.mkIntConst("check_isolation_t0_"+src.getZ3Node()+"_"+dest.getZ3Node()); + IntExpr t_1 = ctx.mkIntConst("check_isolation_t1_"+src.getZ3Node()+"_"+dest.getZ3Node()); + IntExpr t_2 = ctx.mkIntConst("check_isolation_t2_"+src.getZ3Node()+"_"+dest.getZ3Node()); + + // Constraint1 recv(n_0,destNode,p,t_0) + this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t_0)); + + // Constraint2 send(srcNode,n_1,p1,t_1) + this.solver.add((BoolExpr)nctx.send.apply(src.getZ3Node(), n_1, p, t_1)); + + // Constraint3 nodeHasAddr(srcNode,p.srcAddr) + this.solver.add((BoolExpr)nctx.nodeHasAddr.apply(src.getZ3Node(), nctx.pf.get("src").apply(p))); + + // Constraint4 p.origin == srcNode + this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node())); + + // Constraint5 ∃ t_1, t_2 : + // send(linkNode0,linkNode1,p,t_1) && + // recv(linkNode0,linkNode1,p,t_2) && + // t_1 < t_0 && + // t_2 < t_0 + this.solver.add(ctx.mkExists(new Expr[]{t_1,t_2}, + ctx.mkAnd( + (BoolExpr)nctx.send.apply(le0.getZ3Node(), le1.getZ3Node(), p, t_1), + (BoolExpr)nctx.recv.apply(le0.getZ3Node(), le1.getZ3Node(), p, t_2), + ctx.mkLt(t_1,t_0), + ctx.mkLt(t_2,t_0)),1,null,null,null,null)); + + + result = this.solver.check(); + model = null; + assertions = this.solver.getAssertions(); + if (result == Status.SATISFIABLE){ + model = this.solver.getModel(); + } + this.solver.pop(); + return new IsolationResult(ctx,result, p, n_0, t_1, t_0, nctx, assertions, model); + + } + + public Result CheckDataIsolationPropertyCore (NetworkObject src, NetworkObject dest){ + assert(net.elements.contains(src)); + assert(net.elements.contains(dest)); + List<BoolExpr> constr = this.getConstraints(); + Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet); + + Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + IntExpr t = ctx.mkIntConst("check_isolation_t_"+src.getZ3Node()+"_"+dest.getZ3Node()); + + // Constraint1 recv(n_0,destNode,p,t) + constr.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t)); + + // Constraint2 p.origin == srcNode + this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node())); + + this.solver.push(); + + // Constraint3 for each constraint( n -> constraint) + ArrayList<BoolExpr> names =new ArrayList<BoolExpr>(); + for(BoolExpr con : constr){ + BoolExpr n = ctx.mkBoolConst(""+con); + names.add(n); + this.solver.add(ctx.mkImplies(n, con)); + } + + BoolExpr[] nam = new BoolExpr[names.size()]; + result = this.solver.check(names.toArray(nam)); + Result ret =null; + + if (result == Status.SATISFIABLE){ + System.out.println("SAT"); + ret = new Result(ctx,this.solver.getModel()); + }else if(result == Status.UNSATISFIABLE){ + System.out.println("unsat"); + ret = new Result(ctx,this.solver.getUnsatCore()); + } + this.solver.pop(); + return ret; + } + + public DataIsolationResult CheckDataIsolationProperty(NetworkObject src, NetworkObject dest){ + assert(net.elements.contains(src)); + assert(net.elements.contains(dest)); + solver.push (); + addConstraints(); + + Expr p = ctx.mkConst("check_isolation_p_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.packet); + + Expr n_0 =ctx.mkConst("check_isolation_n_0_"+src.getZ3Node()+"_"+dest.getZ3Node(), nctx.node); + IntExpr t = ctx.mkIntConst("check_isolation_t_"+src.getZ3Node()+"_"+dest.getZ3Node()); + + // Constraint1 recv(n_0,destNode,p,t) + this.solver.add((BoolExpr)nctx.recv.apply(n_0, dest.getZ3Node(), p, t)); + + // Constraint2 p.origin == srcNode + this.solver.add(ctx.mkEq(nctx.pf.get("origin").apply(p), src.getZ3Node())); + + result = this.solver.check(); + model = null; + assertions = this.solver.getAssertions(); + if (result == Status.SATISFIABLE){ + model = this.solver.getModel(); + } + this.solver.pop(); + return new DataIsolationResult(ctx,result, p, n_0, t, nctx, assertions, model); + } + + + + + public void addConstraints(){ + nctx.addConstraints(solver); + net.addConstraints(solver); + for (NetworkObject el : net.elements) + el.addConstraints(solver); + } + + + public List<BoolExpr> getConstraints(){ + Solver l = ctx.mkSolver(); + nctx.addConstraints(l); + net.addConstraints(l); + for (NetworkObject el : net.elements) + el.addConstraints(l); + return Arrays.asList(l.getAssertions()); + } +} diff --git a/verigraph/service/src/mcnet/components/Core.java b/verigraph/service/src/mcnet/components/Core.java new file mode 100644 index 0000000..c72b9e3 --- /dev/null +++ b/verigraph/service/src/mcnet/components/Core.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.components; +import com.microsoft.z3.Context; +import com.microsoft.z3.Solver; + +/**Core component for everything that matters + * + */ +public abstract class Core{ + + final int MAX_PORT = 512; + + /** + * Base class for all objects in the modeling framework + * @param ctx + * @param args + */ + public Core(Context ctx, Object[]... args){ // Object[]... -> The nearest way to implement variable length argument lists + //in Java, in the most generic way. + init(ctx,args); + } + /** + * Override _init for any constructor initialization. Avoids having to explicitly call super.__init__ every Time.class + * @param ctx + * @param args + */ + abstract protected void init(Context ctx,Object[]... args); + + /** + * Add constraints to solver + * @param solver + */ + abstract protected void addConstraints(Solver solver); +} + + diff --git a/verigraph/service/src/mcnet/components/DataIsolationResult.java b/verigraph/service/src/mcnet/components/DataIsolationResult.java new file mode 100644 index 0000000..b90a47f --- /dev/null +++ b/verigraph/service/src/mcnet/components/DataIsolationResult.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.components; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.Expr; +import com.microsoft.z3.Model; +import com.microsoft.z3.Status; + + +/**Data structure for the response to a check request for data isolation property + * + */ +public class DataIsolationResult { + + Context ctx; + public NetContext nctx; + public Status result; + public Model model; + public Expr violating_packet,last_hop,last_time,t_1; + public BoolExpr [] assertions; + + public DataIsolationResult(Context ctx,Status result, Expr violating_packet, Expr last_hop, Expr last_time, NetContext nctx, BoolExpr[] assertions, Model model){ + this.ctx = ctx; + this.result = result; + this.violating_packet = violating_packet; + this.last_hop = last_hop; + this.model = model; + this.last_time = last_time; + this.assertions = assertions; + } +} + diff --git a/verigraph/service/src/mcnet/components/IsolationResult.java b/verigraph/service/src/mcnet/components/IsolationResult.java new file mode 100644 index 0000000..1ecaccc --- /dev/null +++ b/verigraph/service/src/mcnet/components/IsolationResult.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.components; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.Expr; +import com.microsoft.z3.Model; +import com.microsoft.z3.Status; + +/** + * Data structure for the response to check requests for isolation properties + * + */ +public class IsolationResult { + + Context ctx; + public NetContext nctx; + public Status result; + public Model model; + public Expr violating_packet,last_hop,last_send_time,last_recv_time,t_1; + public BoolExpr [] assertions; + + public IsolationResult(Context ctx,Status result, Expr violating_packet, Expr last_hop, Expr last_send_time, Expr last_recv_time,NetContext nctx, BoolExpr[] assertions, Model model){ + this.ctx = ctx; + this.result = result; + this.violating_packet = violating_packet; + this.last_hop = last_hop; + this.model = model; + this.last_send_time = last_send_time; + this.last_recv_time = last_recv_time; + this.assertions = assertions; + } +} + diff --git a/verigraph/service/src/mcnet/components/NetContext.java b/verigraph/service/src/mcnet/components/NetContext.java new file mode 100644 index 0000000..ece31c5 --- /dev/null +++ b/verigraph/service/src/mcnet/components/NetContext.java @@ -0,0 +1,340 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.components; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Constructor; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.DatatypeSort; +import com.microsoft.z3.EnumSort; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; +import com.microsoft.z3.Sort; + +import mcnet.netobjs.DumbNode; + +/** + * Basic fields and other things required for model checking. + * + */ +public class NetContext extends Core{ + + + List<BoolExpr> constraints; + List<Core> policies; + + public HashMap<String,NetworkObject> nm; //list of nodes, callable by node name + public HashMap<String,DatatypeExpr> am; // list of addresses, callable by address name + public HashMap<String,FuncDecl> pf; + Context ctx; + public EnumSort node,address; + public FuncDecl src_port,dest_port,nodeHasAddr,addrToNode,send,recv; + public DatatypeSort packet; + + /* Constants definition + - used in the packet proto field */ + public final int HTTP_REQUEST = 1; + public final int HTTP_RESPONSE = 2; + public final int POP3_REQUEST = 3; + public final int POP3_RESPONSE = 4; + + /** + * Context for all of the rest that follows. Every network needs one of these + * @param ctx + * @param args + */ + public NetContext(Context ctx,Object[]... args ){ + super(ctx,args); + + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + nm = new HashMap<String,NetworkObject>(); //list of nodes, callable by node name + am = new HashMap<String,DatatypeExpr>(); // list of addresses, callable by address name + pf= new HashMap<String,FuncDecl>() ; + + mkTypes((String[])args[0],(String[])args[1]); + + constraints = new ArrayList<BoolExpr>(); + policies = new ArrayList<Core>(); + + baseCondition(); + } + + /** + * A policy is a collection of shared algorithms or functions used by multiple components + * (for instance compression or DPI policies etc). + * @param policy + */ + public void AddPolicy (NetworkObject policy){ + policies.add(policy); + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + for (Core policy : policies){ + policy.addConstraints(solver); + } + } + + private void mkTypes (String[] nodes, String[] addresses){ + //Nodes in a network + node = ctx.mkEnumSort("Node", nodes); + for(int i=0;i<node.getConsts().length;i++){ + DatatypeExpr fd = (DatatypeExpr)node.getConst(i); + DumbNode dn =new DumbNode(ctx,new Object[]{fd}); + nm.put(fd.toString(),dn); + } + + //Addresses for this network + String[] new_addr = new String[addresses.length+1]; + for(int k=0;k<addresses.length;k++) + new_addr[k] = addresses[k]; + + new_addr[new_addr.length-1] = "null"; + address = ctx.mkEnumSort("Address", new_addr); + for(int i=0;i<address.getConsts().length;i++){ + DatatypeExpr fd = (DatatypeExpr)address.getConst(i); + am.put(fd.toString(),fd); + } + + // Type for packets, contains (some of these are currently represented as relations): + // - src: Source address + // - dest: Destination address + // - origin: Node where the data originated. (Node) + // - body: Packet contents. (Integer) + // - seq: Sequence number for packets. (Integer) + // - options: A representation for IP options. (Integer) + + String[] fieldNames = new String[]{ + "src","dest","inner_src","inner_dest","origin","orig_body","body","seq","proto","emailFrom","url","options","encrypted"}; + Sort[] srt = new Sort[]{ + address,address,address,address,node,ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkIntSort(), + ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkIntSort(),ctx.mkBoolSort()}; + Constructor packetcon = ctx.mkConstructor("packet", "is_packet", fieldNames, srt, null); + packet = ctx.mkDatatypeSort("packet", new Constructor[] {packetcon}); + + for(int i=0;i<fieldNames.length;i++){ + pf.put(fieldNames[i], packet.getAccessors()[0][i]); // pf to get packet's function declarations by name + } + + src_port = ctx.mkFuncDecl("sport", packet, ctx.mkIntSort()); + dest_port = ctx.mkFuncDecl("dport", packet, ctx.mkIntSort()); + + // Some commonly used relations + + // nodeHasAddr: node -> address -> boolean + nodeHasAddr = ctx.mkFuncDecl("nodeHasAddr", new Sort[]{node, address},ctx.mkBoolSort()); + + // addrToNode: address -> node + addrToNode = ctx.mkFuncDecl("addrToNode", address, node); + + // Send and receive both have the form: + // source-> destination -> packet-> int-> bool + + // send: node -> node -> packet-> int-> bool + send = ctx.mkFuncDecl("send", new Sort[]{ node, node, packet, ctx.mkIntSort()},ctx.mkBoolSort()); + + // recv: node -> node -> packet-> int-> bool + recv = ctx.mkFuncDecl("recv", new Sort[]{ node, node, packet, ctx.mkIntSort()},ctx.mkBoolSort()); + + } + + /** + * Set up base conditions for the network + */ + private void baseCondition(){ + // Basic constraints for the overall model + Expr n_0 = ctx.mkConst("ctx_base_n_0", node); + Expr n_1 = ctx.mkConst("ctx_base_n_1", node); + Expr n_2 = ctx.mkConst("ctx_base_n_2", node); + Expr p_0 = ctx.mkConst("ctx_base_p_0", packet); + Expr p_1 = ctx.mkConst("ctx_base_p_1", packet); + IntExpr t_0 = ctx.mkIntConst("ctx_base_t_0"); + IntExpr t_1 = ctx.mkIntConst("ctx_base_t_1"); + + // Constraint1 send(n_0, n_1, p_0, t_0) -> n_0 != n_1 + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0),ctx.mkNot(ctx.mkEq( n_0, n_1))),1,null,null,null,null)); + + // Constraint2 recv(n_0, n_1, p_0, t_0) -> n_0 != n_1 + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0),ctx.mkNot(ctx.mkEq( n_0, n_1))),1,null,null,null,null)); + + // Constraint3 send(n_0, n_1, p_0, t_0) -> p_0.src != p_0.dest + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0), + ctx.mkNot(ctx.mkEq( pf.get("src").apply(p_0), pf.get("dest").apply(p_0)))),1,null,null,null,null)); + + // Constraint4 recv(n_0, n_1, p_0, t_0) -> p_0.src != p_0.dest + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0), + ctx.mkNot(ctx.mkEq(pf.get("src").apply(p_0),pf.get("dest").apply(p_0)))),1,null,null,null,null)); + + // Constraint5 recv(n_0, n_1, p, t_0) -> send(n_0, n_1, p, t_1) && t_1 < t_0 + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0), + ctx.mkExists(new Expr[]{t_1}, + ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_1), + ctx.mkLt(t_1, t_0)),1,null,null,null,null)),1,null,null,null,null)); + + // Constraint6 send(n_0, n_1, p, t_0) -> p.src_port > 0 && p.dest_port < MAX_PORT + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0), + ctx.mkAnd( ctx.mkGe((IntExpr)src_port.apply(p_0),(IntExpr)ctx.mkInt(0)), + ctx.mkLt((IntExpr)src_port.apply(p_0),(IntExpr) ctx.mkInt(MAX_PORT)))),1,null,null,null,null)); + + // Constraint7 recv(n_0, n_1, p, t_0) -> p.src_port > 0 && p.dest_port < MAX_PORT + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0), + ctx.mkAnd( ctx.mkGe((IntExpr)dest_port.apply(p_0),(IntExpr)ctx.mkInt(0)), + ctx.mkLt((IntExpr)dest_port.apply(p_0),(IntExpr) ctx.mkInt(MAX_PORT)))),1,null,null,null,null)); + + // Constraint8 recv(n_0, n_1, p_0, t_0) -> t_0 > 0 + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies((BoolExpr)recv.apply(n_0, n_1, p_0, t_0), + ctx.mkGt(t_0,ctx.mkInt(0))),1,null,null,null,null)); + + // Constraint9 send(n_0, n_1, p_0, t_0) -> t_0 > 0 + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies((BoolExpr)send.apply(n_0, n_1, p_0, t_0), + ctx.mkGt(t_0,ctx.mkInt(0))),1,null,null,null,null)); + + // Extra constriants for supporting the VPN gateway + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies( + ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_0), + ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null")))), + ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0)))),1,null,null,null,null)); + + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies( + ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_0), + ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null"))), + ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null)); + + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies( + ctx.mkAnd((BoolExpr)send.apply(n_0, n_1, p_0, t_0), + ctx.mkEq(this.pf.get("inner_dest").apply(p_0), this.am.get("null"))), + ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null)); + + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies( + ctx.mkAnd((BoolExpr)recv.apply(n_0, n_1, p_0, t_0), + ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null")))), + ctx.mkNot(ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0)))),1,null,null,null,null)); + + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies( + ctx.mkAnd((BoolExpr)recv.apply(n_0, n_1, p_0, t_0), + ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.am.get("null"))), + ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null)); + + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0}, + ctx.mkImplies( + ctx.mkAnd((BoolExpr)recv.apply(n_0, n_1, p_0, t_0), + ctx.mkEq(this.pf.get("inner_dest").apply(p_0), this.am.get("null"))), + ctx.mkEq(this.pf.get("inner_src").apply(p_0), this.pf.get("inner_dest").apply(p_0))),1,null,null,null,null)); + + constraints.add( + ctx.mkForall(new Expr[]{n_0, n_1, p_0, t_0, n_2, p_1, t_1}, + ctx.mkImplies( + ctx.mkAnd( + ctx.mkLt(t_1, t_0), + (BoolExpr)send.apply(n_0, n_1, p_0, t_0), + (BoolExpr)this.pf.get("encrypted").apply(p_1), + (BoolExpr)recv.apply(n_2, n_0, p_1, t_1), + (BoolExpr)this.pf.get("encrypted").apply(p_0)), + ctx.mkAnd( + ctx.mkEq(this.pf.get("inner_src").apply(p_1), this.pf.get("inner_src").apply(p_0)), + ctx.mkEq(this.pf.get("inner_dest").apply(p_1), this.pf.get("inner_dest").apply(p_0)), + ctx.mkEq(this.pf.get("origin").apply(p_1), this.pf.get("origin").apply(p_0)), + ctx.mkEq(this.pf.get("orig_body").apply(p_1), this.pf.get("orig_body").apply(p_0)), + ctx.mkEq(this.pf.get("body").apply(p_1), this.pf.get("body").apply(p_0)), + ctx.mkEq(this.pf.get("seq").apply(p_1), this.pf.get("seq").apply(p_0)), + ctx.mkEq(this.pf.get("proto").apply(p_1), this.pf.get("proto").apply(p_0)), + ctx.mkEq(this.pf.get("emailFrom").apply(p_1), this.pf.get("emailFrom").apply(p_0)), + ctx.mkEq(this.pf.get("url").apply(p_1), this.pf.get("url").apply(p_0)), + ctx.mkEq(this.pf.get("options").apply(p_1), this.pf.get("options").apply(p_0)))),1,null,null,null,null) + ); + } + + /** + * Two packets have equal headers + * @param p1 + * @param p2 + * @return + */ + public BoolExpr PacketsHeadersEqual(Expr p1, Expr p2){ + return ctx.mkAnd(new BoolExpr[]{ + ctx.mkEq(pf.get("src").apply(p1), pf.get("src").apply(p2)), + ctx.mkEq(pf.get("dest").apply(p1), pf.get("dest").apply(p2)), + ctx.mkEq(pf.get("origin").apply(p1), pf.get("origin").apply(p2)), + ctx.mkEq(pf.get("seq").apply(p1), pf.get("seq").apply(p2)), + ctx.mkEq(src_port.apply(p1), src_port.apply(p2)), + ctx.mkEq(dest_port.apply(p1), dest_port.apply(p2)), + ctx.mkEq(pf.get("options").apply(p1), pf.get("options").apply(p2))}); + } + + /** + * Two packets have equal bodies + * @param p1 + * @param p2 + * @return + */ + public BoolExpr PacketContentEqual(Expr p1, Expr p2){ + return ctx.mkEq(pf.get("body").apply(p1), pf.get("body").apply(p2)); + } + + + /* seems to be useless + * + public Function failurePredicate (NetContext context) + { + return (NetworkObject node) -> ctx.mkNot(context.failed (node.z3Node)); + + }*/ + + public BoolExpr destAddrPredicate (Expr p, DatatypeExpr address){ + return ctx.mkEq(pf.get("dest").apply(p),address); + } + + public BoolExpr srcAddrPredicate (Expr p, DatatypeExpr address){ + return ctx.mkEq(pf.get("src").apply(p),address); + } + +}
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/components/Network.java b/verigraph/service/src/mcnet/components/Network.java new file mode 100644 index 0000000..c04f771 --- /dev/null +++ b/verigraph/service/src/mcnet/components/Network.java @@ -0,0 +1,296 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.components; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; +import com.microsoft.z3.Z3Exception; + +/**Model for a network, encompasses routing and wiring + * + */ +public class Network extends Core{ + + Context ctx; + NetContext nctx; + List<BoolExpr> constraints; + List<NetworkObject> elements; + + + + public Network(Context ctx,Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + this.nctx = (NetContext) args[0][0]; + constraints = new ArrayList<BoolExpr>(); + elements = new ArrayList<NetworkObject>(); + + } + + /**Composes the network linking the configured network objects + * + * @param elements + */ + public void attach (NetworkObject ... elements){ + for(NetworkObject el : elements) + this.elements.add(el); + } + + @Override + protected void addConstraints(Solver solver) { + try { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } catch (Z3Exception e) { + e.printStackTrace(); + } + } + + /** + * Specify host to address mapping. + * Handles the case in which we have more than one address for a node + * @param addrmap + */ + public void setAddressMappings(ArrayList<Tuple<NetworkObject,ArrayList<DatatypeExpr>>> addrmap){ + // Set address mapping for nodes. + for (Tuple<NetworkObject,ArrayList<DatatypeExpr>> entry : addrmap) { + NetworkObject node=entry._1; + List<DatatypeExpr> addr=entry._2; + Expr a_0 = ctx.mkConst(node+"_address_mapping_a_0",nctx.address); + ArrayList<BoolExpr> or_clause = new ArrayList<BoolExpr>(); + + // Constraint 1 addrToNode(foreach ad in addr) = node + for (DatatypeExpr ad : addr){ + constraints.add(ctx.mkEq(nctx.addrToNode.apply(ad), node.getZ3Node())); + or_clause.add(ctx.mkEq(a_0,ad)); + } + BoolExpr[] orClause = new BoolExpr[or_clause.size()]; + + // Constraint 2 nodeHasAddr(node, a_0) == Or(foreach ad in addr (a_0 == ad)) + // Note we need the iff here to make sure that we set nodeHasAddr to false + // for other addresses. + constraints.add(ctx.mkForall(new Expr[]{a_0}, + ctx.mkEq(ctx.mkOr(or_clause.toArray(orClause)), nctx.nodeHasAddr.apply(node.getZ3Node(), a_0)),1,null,null,null,null)); + } + } + + + + /** + * Don't forward packets addressed to node + * @param node + */ + public void saneSend(NetworkObject node){ + Expr n_0 = ctx.mkConst(node+"_saneSend_n_0", nctx.node); + Expr p_0 = ctx.mkConst(node+"_saneSend_p_0", nctx.packet); + IntExpr t_0 = ctx.mkIntConst(node+"_saneSend_t_0"); + // Constant: node + //Constraint send(node, n_0, p, t_0) -> !nodeHasAddr(node, p.dest) + constraints.add( + ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(node.getZ3Node(),n_0, p_0, t_0), + ctx.mkNot((BoolExpr)nctx.nodeHasAddr.apply( node.getZ3Node(), + nctx.pf.get("dest").apply(p_0)))),1,null,null,null,null)); + } + + /** + * Node sends all traffic through gateway + * @param node + * @param gateway + */ + public void setGateway (NetworkObject node, NetworkObject gateway){ + // SetGateway(self, node, gateway): All packets from node are sent through gateway + Expr n_0 = ctx.mkConst(node+"_gateway_n_0", nctx.node); + Expr p_0 = ctx.mkConst(node+"_gateway_p_0", nctx.packet); + IntExpr t_0 = ctx.mkIntConst(node+"_gateway_t_0"); + + //Constraint send(node, n_0, p_0, t_0) -> n_0 = gateway + constraints.add( + ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies( + (BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0), + ctx.mkEq(n_0,gateway.getZ3Node())),1,null,null,null,null)); + +// constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0}, +// ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0, node.getZ3Node(), p_0, t_0), +// ctx.mkEq(n_0,gateway.getZ3Node())),1,null,null,null,null)); + } + + /** + * Assigns a specific routing table to a network object. Routing entries in the form: address -> node + * @param node + * @param routing_table + */ + public void routingTable (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> routing_table){ + compositionPolicy(node,routing_table); + } + + /** + * Composition policies steer packets between middleboxes. + * @param node + * @param policy + */ + public void compositionPolicy (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> policy){ + //Policy is of the form predicate -> node + Expr p_0 = ctx.mkConst(node+"_composition_p_0", nctx.packet); + Expr n_0 = ctx.mkConst(node+"_composition_n_0", nctx.node); + Expr t_0 = ctx.mkIntConst(node+"_composition_t_0"); + + HashMap<String,ArrayList<BoolExpr>> collected = new HashMap<String,ArrayList<BoolExpr>>(); + HashMap<String,NetworkObject> node_dict = new HashMap<String,NetworkObject>(); + BoolExpr predicates; + for(int y=0;y<policy.size();y++){ + Tuple<DatatypeExpr,NetworkObject> tp = policy.get(y); + if(collected.containsKey(""+tp._2)) collected.get(""+tp._2).add(nctx.destAddrPredicate(p_0,tp._1)); + else{ + ArrayList<BoolExpr> alb = new ArrayList<BoolExpr>(); + alb.add(nctx.destAddrPredicate(p_0,tp._1)); + collected.put(""+tp._2,alb); + } + node_dict.put(""+tp._2, tp._2); + } + + //Constraint foreach rtAddr,rtNode in rt( send(node, n_0, p_0, t_0) && + // Or(foreach rtAddr in rt destAddrPredicate(p_0,rtAddr)) -> n_0 == rtNode ) + for (Map.Entry<String,ArrayList<BoolExpr>> entry : collected.entrySet()) { + BoolExpr[] pred = new BoolExpr[entry.getValue().size()]; + predicates = ctx.mkOr(entry.getValue().toArray(pred)); + + constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0), predicates), + ctx.mkEq(n_0, node_dict.get(entry.getKey()).getZ3Node())),1,null,null,null,null)); + } + } + + /** + * Routing entries are in the form: address -> node. Also allows packet to be sent to another box for further processing + * @param node + * @param routing_table + * @param shunt_node + */ + public void routingTableShunt (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> routing_table,NetworkObject shunt_node){ + compositionPolicyShunt(node,routing_table,shunt_node); + } + + /** + * Composition policies steer packets between middleboxes.Policy is in the form: predicate -> node + * @param node + * @param routing_table + * @param shunt_node + */ + public void compositionPolicyShunt (NetworkObject node,ArrayList<Tuple<DatatypeExpr,NetworkObject>> routing_table,NetworkObject shunt_node){ + Expr p_0 = ctx.mkConst(node+"_composition_p_0", nctx.packet); + Expr n_0 = ctx.mkConst(node+"_composition_n_0", nctx.node); + Expr t_0 = ctx.mkIntConst(node+"_composition_t_0"); + + HashMap<String,ArrayList<BoolExpr>> collected = new HashMap<String,ArrayList<BoolExpr>>(); + HashMap<String,NetworkObject> node_dict = new HashMap<String,NetworkObject>(); + BoolExpr predicates; + for(int y=0;y<routing_table.size();y++){ + Tuple<DatatypeExpr,NetworkObject> tp = routing_table.get(y); + if(collected.containsKey(""+tp._2)) collected.get(""+tp._2).add(nctx.destAddrPredicate(p_0,tp._1)); + else{ + ArrayList<BoolExpr> alb = new ArrayList<BoolExpr>(); + alb.add(nctx.destAddrPredicate(p_0,tp._1)); + collected.put(""+tp._2,alb); + } + node_dict.put(""+tp._2, tp._2); + } + + //Constraint foreach rtAddr,rtNode in rt( send(node, n_0, p_0, t_0) && + // Or(foreach rtAddr in rt destAddrPredicate(p_0,rtAddr)) -> n_0 == rtNode ) + for (Map.Entry<String,ArrayList<BoolExpr>> entry : collected.entrySet()) { + BoolExpr[] pred = new BoolExpr[entry.getValue().size()]; + predicates = ctx.mkOr(entry.getValue().toArray(pred)); + + constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0), predicates), + ctx.mkOr(ctx.mkEq(n_0, node_dict.get(entry.getKey()).getZ3Node()),ctx.mkEq(n_0, shunt_node.getZ3Node()))),1,null,null,null,null)); + } + + } + +// public void SimpleIsolation (NetworkObject node, ArrayList<DatatypeExpr> addresses){ +// Expr p = ctx.mkConst(node+"_s_p", nctx.packet); +// Expr n = ctx.mkConst(node+"_s_n", nctx.node); +// IntExpr t = ctx.mkInt(node+"_s_t"); +// +// BoolExpr[] a_pred= new BoolExpr[addresses.size()]; +// for(int y=0;y<addresses.size();y++){ +// DatatypeExpr de = addresses.get(y); +// a_pred[y] = ctx.mkOr(ctx.mkEq(nctx.pf.get("src").apply(p), de),ctx.mkEq(nctx.pf.get("dest").apply(p), de)); +// } +// +// constraints.add( +// ctx.mkForall(new Expr[]{p, n, t}, +// ctx.mkImplies((BoolExpr)nctx.recv.apply(n, node.getZ3Node(), p, t), +// ctx.mkOr(a_pred)),1,null,null,null,null)); +// constraints.add( +// ctx.mkForall(new Expr[]{p, n, t}, +// ctx.mkImplies((BoolExpr)nctx.send.apply(node.getZ3Node(), n, p, t), +// ctx.mkOr(a_pred)),1,null,null,null,null)); +// } + + + /** + * Set isolation constraints on a node. + * Doesn't need to be set but useful when interfering policies are in play. + * @param node + * @param adjacencies + * + */ + public void SetIsolationConstraint ( NetworkObject node, ArrayList<NetworkObject> adjacencies){ + + Expr n_0 = ctx.mkConst(node+"_isolation_n_0", nctx.node); + Expr p_0 = ctx.mkConst(node+"_isolation_p_0", nctx.packet); + IntExpr t_0 = ctx.mkInt(node+"_isolation_t_0"); + + BoolExpr[] adj = new BoolExpr[adjacencies.size()]; + for(int y=0;y<adjacencies.size();y++){ + NetworkObject no = adjacencies.get(y); + adj[y] = ctx.mkEq(n_0,no.getZ3Node()); + } + BoolExpr clause = ctx.mkOr(adj); + + constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(node.getZ3Node(), n_0, p_0, t_0), + clause),1,null,null,null,null)); + constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0, node.getZ3Node(), p_0, t_0), + clause),1,null,null,null,null)); + } + + /** + * Return all currently attached endhosts + * @return NetworkObject + */ + public List<String> EndHosts(){ + List<String> att_nos = new ArrayList<String>(); + for(NetworkObject el :elements){ + if(el.isEndHost){ + System.out.println("el: "+el); + att_nos.add(el.getZ3Node().toString()); + } + } + return att_nos; + } +} diff --git a/verigraph/service/src/mcnet/components/NetworkObject.java b/verigraph/service/src/mcnet/components/NetworkObject.java new file mode 100644 index 0000000..0de3937 --- /dev/null +++ b/verigraph/service/src/mcnet/components/NetworkObject.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.components; + +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; + +/** Represents a generic network object. + * + */ +public abstract class NetworkObject extends Core{ + + public NetworkObject(Context ctx,Object[]... args) { + super(ctx,args); + } + + protected DatatypeExpr z3Node; + protected boolean isEndHost; + /** + * Get a reference to the z3 node this class wraps around + * @return + */ + abstract public DatatypeExpr getZ3Node(); + + public String toString(){ + return z3Node.toString(); + } + + //There is probably an error: z3Node.hashCode = 0 because AST.hashCode() has always hash=0 + /*public int hashCode(){ + return z3Node.hashCode(); + }*/ + + /** + * A simple way to determine the set of endhosts + * @return + */ + public boolean isEndHost(){ + return isEndHost; + } + + /** + * Wrap methods to set policy + * @param policy + * @throws UnsupportedOperationException + */ + void setPolicy (Object policy) throws UnsupportedOperationException{ + throw new UnsupportedOperationException(); + } +} diff --git a/verigraph/service/src/mcnet/components/Result.java b/verigraph/service/src/mcnet/components/Result.java new file mode 100644 index 0000000..acb23f1 --- /dev/null +++ b/verigraph/service/src/mcnet/components/Result.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.components; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.Model; + +/**Data structure for the core of the response to a check request for data isolation property + * + */ +public class Result { + Context ctx; + public Model model; + public BoolExpr[] unsat_core; + +/** + * + * @param ctx + * @param model + */ + public Result(Context ctx, Model model){ + this.ctx = ctx; + this.model = model; + } + +/** + * + * @param ctx + * @param unsat_core + */ + public Result(Context ctx, BoolExpr[] unsat_core){ + this.ctx = ctx; + this.unsat_core = unsat_core; +} +} diff --git a/verigraph/service/src/mcnet/components/Tuple.java b/verigraph/service/src/mcnet/components/Tuple.java new file mode 100644 index 0000000..849d607 --- /dev/null +++ b/verigraph/service/src/mcnet/components/Tuple.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.components; + +/** A data structure which is an utility to make a generic couple of objects with different types in Java + * + */ +public class Tuple<T, U> { + public final T _1; + public final U _2; + + + public Tuple(T arg1,U arg2) { + super(); + this._1 = arg1; + this._2 = arg2; + } + + public Tuple(){ + this._1 = null; + this._2 = null; + } + + @Override + public String toString() { + return String.format("(%s, %s)", _1, _2); + } + }
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/AclFirewall.java b/verigraph/service/src/mcnet/netobjs/AclFirewall.java new file mode 100644 index 0000000..4ae3421 --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/AclFirewall.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; +import com.microsoft.z3.Sort; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; +import mcnet.components.Tuple; + +/** Represents a Firewall with the associated Access Control List + * + */ +public class AclFirewall extends NetworkObject{ + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr fw; + ArrayList<Tuple<DatatypeExpr,DatatypeExpr>> acls; + Network net; + NetContext nctx; + FuncDecl acl_func; + + public AclFirewall(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=false; + constraints = new ArrayList<BoolExpr>(); + acls = new ArrayList<Tuple<DatatypeExpr,DatatypeExpr>>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + fw = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + net.saneSend(this); + firewallSendRules(); + } + + /** + * Wrap add acls + * @param policy + */ + public void setPolicy(ArrayList<Tuple<DatatypeExpr, DatatypeExpr>> policy){ + addAcls(policy); + } + + public void addAcls(ArrayList<Tuple<DatatypeExpr,DatatypeExpr>> acls){ + this.acls.addAll(acls); + } + + @Override + public DatatypeExpr getZ3Node() { + return fw; + } + + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + aclConstraints(solver); + } + + private void firewallSendRules (){ + Expr p_0 = ctx.mkConst(fw+"_firewall_send_p_0", nctx.packet); + Expr n_0 = ctx.mkConst(fw+"_firewall_send_n_0", nctx.node); + Expr n_1 = ctx.mkConst(fw+"_firewall_send_n_1", nctx.node); + IntExpr t_0 = ctx.mkIntConst(fw+"_firewall_send_t_0"); + IntExpr t_1 = ctx.mkIntConst(fw+"_firewall_send_t_1"); + acl_func = ctx.mkFuncDecl(fw+"_acl_func", new Sort[]{nctx.address, nctx.address},ctx.mkBoolSort()); + + //Constraint1 send(fw, n_0, p, t_0) -> (exist n_1,t_1 : (recv(n_1, fw, p, t_1) && + // t_1 < t_0 && !acl_func(p.src,p.dest)) + constraints.add( + ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies( + (BoolExpr)nctx.send.apply(new Expr[]{ fw, n_0, p_0, t_0}), + ctx.mkExists(new Expr[]{t_1}, + ctx.mkAnd(ctx.mkLt(t_1,t_0), + ctx.mkExists(new Expr[]{n_1}, + nctx.recv.apply(n_1, fw, p_0, t_1),1,null,null,null,null), + ctx.mkNot((BoolExpr)acl_func.apply(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_0)))),1,null,null,null,null)),1,null,null,null,null)); + + } + + private void aclConstraints(Solver solver){ + if (acls.size() == 0) + return; + Expr a_0 = ctx.mkConst(fw+"_firewall_acl_a_0", nctx.address); + Expr a_1 = ctx.mkConst(fw+"_firewall_acl_a_1", nctx.address); + BoolExpr[] acl_map = new BoolExpr[acls.size()]; + for(int y=0;y<acls.size();y++){ + Tuple<DatatypeExpr,DatatypeExpr> tp = acls.get(y); + acl_map[y] = ctx.mkOr(ctx.mkAnd(ctx.mkEq(a_0,tp._1),ctx.mkEq(a_1,tp._2)), ctx.mkAnd(ctx.mkEq(a_0,tp._2),ctx.mkEq(a_1,tp._1))); + } + //Constraint2 acl_func(a_0,a_1) == or(foreach ip1,ip2 in acl_map ((a_0 == ip1 && a_1 == ip2)||(a_0 == ip2 && a_1 == ip1))) + solver.add(ctx.mkForall(new Expr[]{a_0, a_1}, + ctx.mkEq( + acl_func.apply(a_0, a_1), + ctx.mkOr(acl_map)),1,null,null,null,null)); + } +}
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/DumbNode.java b/verigraph/service/src/mcnet/netobjs/DumbNode.java new file mode 100644 index 0000000..012ff40 --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/DumbNode.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetworkObject; + +/** + * This is just a wrapper around z3 instances. The idea is that by using this we perhaps need to have + * fewer (or no) ifs to deal with the case where we don't instantiate an object for a node + * + */ +public class DumbNode extends NetworkObject { + public DumbNode(Context ctx, Object[]... args){ + super(ctx,args); + } + + @Override + protected void addConstraints(Solver solver) { + return; + } + + @Override + protected void init(Context ctx, Object[]... args) { + isEndHost=true; + this.z3Node = (DatatypeExpr)args[0][0]; + } + @Override + public DatatypeExpr getZ3Node() { + return z3Node; + } +} diff --git a/verigraph/service/src/mcnet/netobjs/EndHost.java b/verigraph/service/src/mcnet/netobjs/EndHost.java new file mode 100644 index 0000000..99cf732 --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/EndHost.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; +/** + * End host network objects + * + */ +public class EndHost extends NetworkObject{ + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr node; + Network net; + NetContext nctx; + + public EndHost(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=true; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + node = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + endHostRules(); + } + + @Override + public DatatypeExpr getZ3Node() { + return node; + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + public void endHostRules (){ + Expr n_0 = ctx.mkConst("eh_"+node+"_n_0", nctx.node); + IntExpr t_0 = ctx.mkIntConst("eh_"+node+"_t_0"); + Expr p_0 = ctx.mkConst("eh_"+node+"_p_0", nctx.packet); + + //Constraint1 send(node, n_0, p, t_0) -> nodeHasAddr(node,p.src) + constraints.add( + ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies( + (BoolExpr)nctx.send.apply( new Expr[]{ node, n_0, p_0, t_0}), + (BoolExpr)nctx.nodeHasAddr.apply(new Expr[]{node, nctx.pf.get("src").apply(p_0)})),1,null,null,null,null)); + //Constraint2 send(node, n_0, p, t_0) -> p.origin == node + constraints.add( + ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies( + (BoolExpr)nctx.send.apply( new Expr[]{ node, n_0, p_0, t_0}), + ctx.mkEq(nctx.pf.get("origin").apply(p_0),node)),1,null,null,null,null)); + //Constraint3 send(node, n_0, p, t_0) -> p.orig_body == p.body + constraints.add( + ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies( + (BoolExpr)nctx.send.apply(new Expr[]{ node, n_0, p_0, t_0}), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null)); + //Constraint4 recv(n_0, node, p, t_0) -> nodeHasAddr(node,p.dest) + constraints.add( + ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies( + (BoolExpr)nctx.recv.apply( new Expr[]{ n_0, node, p_0, t_0}), + (BoolExpr)nctx.nodeHasAddr.apply(new Expr[]{node, nctx.pf.get("dest").apply(p_0)})),1,null,null,null,null)); + +// Just a try: here we state that an endhost is not able to issue a HTTP response traffic +// See PolitoCache.py model for constants definition (2 means HTTP_RESPONSE, 1 means HTTP_REQUEST) +// constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0}, +// ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0), +// ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(1))),1,null,null,null,null)); + } +}
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/PacketModel.java b/verigraph/service/src/mcnet/netobjs/PacketModel.java new file mode 100644 index 0000000..5761861 --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PacketModel.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + +import com.microsoft.z3.DatatypeExpr; + +/* + * Fields that can be configured -> "dest","body","seq","proto","emailFrom","url","options" + */ +public class PacketModel { + + private DatatypeExpr ip_dest; + private Integer body; + private Integer seq; + private Integer proto; + private Integer emailFrom; + private Integer url; + private Integer options; + + public DatatypeExpr getIp_dest() { + return ip_dest; + } + public void setIp_dest(DatatypeExpr ip_dest) { + this.ip_dest = ip_dest; + } + public Integer getBody() { + return body; + } + public void setBody(Integer body) { + this.body = body; + } + public Integer getSeq() { + return seq; + } + public void setSeq(Integer seq) { + this.seq = seq; + } + public Integer getProto() { + return proto; + } + public void setProto(Integer proto) { + this.proto = proto; + } + public Integer getEmailFrom() { + return emailFrom; + } + public void setEmailFrom(Integer emailFrom) { + this.emailFrom = emailFrom; + } + public Integer getUrl() { + return url; + } + public void setUrl(Integer url) { + this.url = url; + } + public Integer getOptions() { + return options; + } + public void setOptions(Integer options) { + this.options = options; + } + +} diff --git a/verigraph/service/src/mcnet/netobjs/PolitoAntispam.java b/verigraph/service/src/mcnet/netobjs/PolitoAntispam.java new file mode 100644 index 0000000..abb4615 --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoAntispam.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; + +/** + * Model of an anti-spam node + * + */ +public class PolitoAntispam extends NetworkObject{ + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr politoAntispam; + Network net; + NetContext nctx; + FuncDecl isInBlacklist; + + public PolitoAntispam(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=false; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + politoAntispam = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + //net.saneSend(this); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoAntispam; + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + public void installAntispam (int[] blackList){ + Expr n_0 = ctx.mkConst(politoAntispam+"_n_0", nctx.node); + Expr n_1 = ctx.mkConst(politoAntispam+"_n_1", nctx.node); + Expr p_0 = ctx.mkConst(politoAntispam+"_p_0", nctx.packet); + IntExpr t_0 = ctx.mkIntConst(politoAntispam+"_t_0"); + IntExpr t_1 = ctx.mkIntConst(politoAntispam+"_t_1"); + IntExpr ef_0 = ctx.mkIntConst(politoAntispam+"_ef_0"); + + isInBlacklist = ctx.mkFuncDecl(politoAntispam+"_isInBlacklist", ctx.mkIntSort(), ctx.mkBoolSort()); + BoolExpr[] blConstraint = new BoolExpr[blackList.length]; + if(blackList.length != 0){ + for (int i=0;i<blackList.length;i++) + blConstraint[i]=(ctx.mkEq(ef_0,ctx.mkInt(blackList[i]))); + //Constraint1a if(isInBlackList(ef_0) == or(for bl in blacklist (ef_0==bl)) ? true : false + constraints.add(ctx.mkForall(new Expr[]{ef_0}, ctx.mkIff((BoolExpr)isInBlacklist.apply(ef_0),ctx.mkOr(blConstraint)),1,null,null,null,null)); + }else{ + //Constraint1b isInblackList(ef_0) == false + constraints.add(ctx.mkForall(new Expr[]{ef_0}, ctx.mkEq((BoolExpr)isInBlacklist.apply(ef_0), ctx.mkBool(false)),1,null,null,null,null)); + } + + //Constraint2 send(politoAntispam, n_0, p, t_0) && p.proto(POP3_RESP) -> + // (exist n_1,t_1 : (recv(n_1, politoAntispam, p, t_1) && t_1 < t_0)) && !isInBlackList(p.emailFrom) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE))), + ctx.mkAnd( ctx.mkExists(new Expr[]{n_1, t_1}, + ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoAntispam, p_0, t_1), ctx.mkLt(t_1 , t_0)),1,null,null,null,null), + ctx.mkNot((BoolExpr)isInBlacklist.apply(nctx.pf.get("emailFrom").apply(p_0))))),1,null,null,null,null)); + + //Constraint3 send(politoAntispam, n_0, p, t_0) && p.proto(POP3_REQ) -> + // (exist n_1,t_1 : (recv(n_1, politoAntispam, p, t_1) && t_1 < t_0)) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_REQUEST))), + ctx.mkAnd(ctx.mkExists(new Expr[]{n_1, t_1}, + ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoAntispam, p_0, t_1), + ctx.mkLt(t_1 , t_0)),1,null,null,null,null))),1,null,null,null,null)); + + //Constraint4 send(politoAntispam, politoErrFunction, p, t_0) -> + // (exist n_1,t_1 : (recv(n_1, politoAntispam, p, t_1) && t_1 < t_0 && p.emailFrom ==1)) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoAntispam, nctx.nm.get("politoErrFunction").getZ3Node(), p_0, t_0), + ctx.mkAnd(ctx.mkExists(new Expr[]{n_1, t_1}, + ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoAntispam, p_0, t_1), + ctx.mkLt(t_1 , t_0), + ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0),ctx.mkInt(1))),1,null,null,null,null))),1,null,null,null,null)); + + //Constraint5 send(politoAntispam, n_0, p, t_0) -> p.proto == POP_REQ || p.protpo == POP_RESP + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0), + ctx.mkOr( ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_REQUEST)), + ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE)))),1,null,null,null,null)); + + //Constraint6 send(politoAntispam, n_0, p, t_0) -> nodeHasAddr(politoAntispam,p.src) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoAntispam, n_0, p_0, t_0), + ctx.mkNot((BoolExpr)nctx.nodeHasAddr.apply(politoAntispam,nctx.pf.get("src").apply(p_0)))),1,null,null,null,null)); + } + }
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/PolitoCache.java b/verigraph/service/src/mcnet/netobjs/PolitoCache.java new file mode 100644 index 0000000..948915c --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoCache.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; +import com.microsoft.z3.Sort; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; +/**Cache Model + * + */ +public class PolitoCache extends NetworkObject{ + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr politoCache; + Network net; + NetContext nctx; + FuncDecl isInBlacklist; + + public PolitoCache(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=false; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + politoCache = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + //net.saneSend(this); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoCache; + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + public void installCache (NetworkObject[] internalNodes){ + Expr n_0 = ctx.mkConst("politoCache_"+politoCache+"_n_0", nctx.node); + Expr n_1 = ctx.mkConst("politoCache_"+politoCache+"_n_1", nctx.node); + Expr n_2 = ctx.mkConst("politoCache_"+politoCache+"_n_2", nctx.node); + Expr p_0 = ctx.mkConst("politoCache_"+politoCache+"_p_0", nctx.packet); + Expr p_1 = ctx.mkConst("politoCache_"+politoCache+"_p_1", nctx.packet); + Expr p_2 = ctx.mkConst("politoCache_"+politoCache+"_p_2", nctx.packet); + + IntExpr t_0 = ctx.mkIntConst("politoCache_"+politoCache+"_t_0"); + IntExpr t_1 = ctx.mkIntConst("politoCache_"+politoCache+"_t_1"); + IntExpr t_2 = ctx.mkIntConst("politoCache_"+politoCache+"_t_2"); + + Expr a_0 = ctx.mkConst(politoCache+"politoCache_a_0", nctx.node); + IntExpr u_0 = ctx.mkIntConst("politoCache_"+politoCache+"_u_0"); + + FuncDecl isInternalNode = ctx.mkFuncDecl(politoCache+"_isInternalNode", nctx.node, ctx.mkBoolSort()); + FuncDecl isInCache = ctx.mkFuncDecl(politoCache+"_isInCache", new Sort[]{ctx.mkIntSort(),ctx.mkIntSort()}, ctx.mkBoolSort()); + + assert(internalNodes.length!=0); //No internal nodes => Should never happen + + //Modeling the behavior of the isInternalNode() and isInCache() functions + BoolExpr[] internalNodesConstraint = new BoolExpr[internalNodes.length]; + for(int w=0;w<internalNodesConstraint.length;w++) + internalNodesConstraint[w]= (ctx.mkEq(a_0,internalNodes[w].getZ3Node())); + + //Constraint1 if(isInternalNode(a_0) == or(listadeinodiinterni) ? True : false + constraints.add( + ctx.mkForall(new Expr[]{a_0}, + ctx.mkIff((BoolExpr)isInternalNode.apply(a_0), ctx.mkOr(internalNodesConstraint)),1,null,null,null,null)); + +// constraints.add(ctx.mkForall(new Expr[]{a_0}, ctx.mkEq(isInternalNode.apply(a_0),ctx.mkOr(internalNodesConstraint)),1,null,null,null,null)); + +// constraints.add(ctx.mkForall(new Expr[]{u_0, t_0}, +// ctx.mkITE(ctx.mkExists(new Expr[]{t_1, t_2, p_1, p_2, n_1, n_2}, +// ctx.mkAnd(ctx.mkLt(t_1, t_2), +// ctx.mkLt(t_1, t_0), +// ctx.mkLt(t_2, t_0), +// (BoolExpr)nctx.recv.apply(n_1, politoCache, p_1, t_1), +// (BoolExpr)nctx.recv.apply(n_2, politoCache, p_2, t_2), +// ctx.mkEq(nctx.pf.get("proto").apply(p_1),ctx.mkInt(nctx.HTTP_REQUEST)), +// ctx.mkEq(nctx.pf.get("proto").apply(p_2),ctx.mkInt(nctx.HTTP_RESPONSE)), +// (BoolExpr)isInternalNode.apply(n_1), +// ctx.mkNot((BoolExpr)isInternalNode.apply(n_2)), +// ctx.mkEq(nctx.pf.get("url").apply(p_1),u_0), +// ctx.mkEq(nctx.pf.get("url").apply(p_2),u_0)),1,null,null,null,null), +// ctx.mkEq(isInCache.apply(u_0,t_0),ctx.mkBool(true)),ctx.mkEq(isInCache.apply(u_0,t_0),ctx.mkBool(false))),1,null,null,null,null)); +// + + //Constraint2 isInCache(u_0,t_0), exist t_1, t_2, p_1, p_2, n_1, n_2 : + // ( t_1< t_2 < t_0 && recv(n_1, politoCache, p_1, t_1) && recv(n_2, politoCache, p_2, t_2))) && + // p_1.proto == HTTP_REQ && p_2.proto == HTTP_RESP && + // isInternalNode(n_1) && !isInternalNode(n_2) && + // p_1.url == u_0 && p_2.url == u_0 ) + constraints.add( + ctx.mkForall(new Expr[]{u_0, t_0}, + ctx.mkImplies((BoolExpr)isInCache.apply(u_0, t_0), + ctx.mkExists(new Expr[]{t_1,t_2,p_1,p_2,n_1, n_2}, + ctx.mkAnd( + ctx.mkLt(t_1, t_2), + ctx.mkLt(t_1, t_0), + ctx.mkLt(t_2, t_0), + (BoolExpr)nctx.recv.apply(n_1, politoCache, p_1, t_1), + (BoolExpr)nctx.recv.apply(n_2, politoCache, p_2, t_2), + ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.HTTP_REQUEST)), + ctx.mkEq(nctx.pf.get("proto").apply(p_2), ctx.mkInt(nctx.HTTP_RESPONSE)), + (BoolExpr)isInternalNode.apply(n_1), + ctx.mkNot((BoolExpr)isInternalNode.apply(n_2)), + ctx.mkEq(nctx.pf.get("url").apply(p_1), u_0), + ctx.mkEq(nctx.pf.get("url").apply(p_2), u_0)),1,null,null,null,null)),1,null,null,null,null)); +// //Always in cache +// constraints.add(ctx.mkForall(new Expr[]{u_0, t_0},ctx.mkEq(isInCache.apply(u_0,t_0),ctx.mkBool(true)),1,null,null,null,null)); + + //Constraint3 Modeling the behavior of the cache + // send(politoCache, n_0, p, t_0) && !isInternalNode(n_0) -> + // (exist t_1,n_1 : + // (t_1 < t_0 && recv(n_1, politoCache, p, t_1) && + // p.proto == HTTP_REQ && !isInCache(p.url,t_0)) + constraints.add( + ctx.mkForall(new Expr[]{n_0,p_0, t_0}, + ctx.mkImplies( + ctx.mkAnd((BoolExpr)nctx.send.apply(politoCache,n_0,p_0,t_0),ctx.mkNot((BoolExpr)isInternalNode.apply(n_0))), + ctx.mkAnd(ctx.mkExists(new Expr[]{t_1, n_1}, + ctx.mkAnd( + ctx.mkLt(t_1, t_0), + (BoolExpr)isInternalNode.apply(n_1), + (BoolExpr)nctx.recv.apply(n_1, politoCache, p_0, t_1)),1,null,null,null,null), + ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST)), + ctx.mkNot((BoolExpr)isInCache.apply(nctx.pf.get("url").apply(p_0), t_0)))),1,null,null,null,null)); + + //Constraint4 send(politoCache, n_0, p, t_0) && isInternalNode(n_0) -> + // (exist p_1,t_1 : + // (t_1 < t_0 && recv(n_0, politoCache, p_1, t_1) && + // p_1.proto == HTTP_REQ && p.proto == HTTP_RESP && + // p_1.url == p.url && p.src == p_1.dest && p.dest==p_1.src + // && isInCache(p.url,t_0)) + constraints.add( + ctx.mkForall(new Expr[]{n_0,p_0, t_0}, + ctx.mkImplies( + ctx.mkAnd((BoolExpr)nctx.send.apply(politoCache,n_0,p_0,t_0),(BoolExpr)isInternalNode.apply(n_0)), + ctx.mkAnd(ctx.mkExists(new Expr[]{p_1, t_1}, + ctx.mkAnd( + ctx.mkLt(t_1, t_0), + (BoolExpr)nctx.recv.apply(n_0, politoCache, p_1, t_1), + ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.HTTP_REQUEST)), + ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0))),1,null,null,null,null), + ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)), + ctx.mkEq(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_1)), + ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("src").apply(p_1)), + (BoolExpr)isInCache.apply(nctx.pf.get("url").apply(p_0), t_0))),1,null,null,null,null)); + } +}
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/PolitoEndHost.java b/verigraph/service/src/mcnet/netobjs/PolitoEndHost.java new file mode 100644 index 0000000..e12579f --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoEndHost.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; + +public class PolitoEndHost extends NetworkObject { + + List<BoolExpr> constraints = new ArrayList<BoolExpr>(); + Context ctx; + DatatypeExpr politoEndHost; + Network net; + NetContext nctx; + + public PolitoEndHost(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoEndHost; + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + this.isEndHost = true; + this.politoEndHost = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + this.net = (Network)args[0][1]; + this.nctx = (NetContext)args[0][2]; + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + /* + * Fields that can be configured -> "dest","body","seq","proto","emailFrom","url","options" + */ + public void installEndHost (PacketModel packet){ + System.out.println("Installing PolitoEndHost..."); + Expr n_0 = ctx.mkConst("PolitoEndHost_"+politoEndHost+"_n_0", nctx.node); + Expr p_0 = ctx.mkConst("PolitoEndHost_"+politoEndHost+"_p_0", nctx.packet); + IntExpr t_0 = ctx.mkIntConst("PolitoEndHost_"+politoEndHost+"_t_0"); + BoolExpr predicatesOnPktFields = ctx.mkTrue(); + + if(packet.getIp_dest() != null) + predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("dest").apply(p_0), packet.getIp_dest())); + if(packet.getBody() != null) + predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("body").apply(p_0), ctx.mkInt(packet.getBody()))); + if(packet.getEmailFrom() != null) + predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0), ctx.mkInt(packet.getEmailFrom()))); + if(packet.getOptions() != null) + predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("options").apply(p_0), ctx.mkInt(packet.getOptions()))); + if(packet.getProto() != null) + predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(packet.getProto()))); + if(packet.getSeq() != null) + predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("seq").apply(p_0), ctx.mkInt(packet.getSeq()))); + if(packet.getUrl() != null) + predicatesOnPktFields = ctx.mkAnd(predicatesOnPktFields, ctx.mkEq(nctx.pf.get("url").apply(p_0), ctx.mkInt(packet.getUrl()))); + + //Constraint1 send(politoWebClient, n_0, p, t_0) -> p.origin == politoWebClient && p.orig_body == p.body && nodeHasAddr(politoWebClient,p.src) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoEndHost, n_0, p_0, t_0), + ctx.mkAnd(predicatesOnPktFields, + ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0)), + ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoEndHost), + (BoolExpr)nctx.nodeHasAddr.apply(politoEndHost,nctx.pf.get("src").apply(p_0)))),1,null,null,null,null)); + + //Constraint2 recv(n_0, politoWebClient, p, t_0) -> nodeHasAddr(politoWebClient,p.dest) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoEndHost, p_0, t_0), + (BoolExpr)nctx.nodeHasAddr.apply(politoEndHost,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)); + + System.out.println("Done."); + return; + } + +} diff --git a/verigraph/service/src/mcnet/netobjs/PolitoErrFunction.java b/verigraph/service/src/mcnet/netobjs/PolitoErrFunction.java new file mode 100644 index 0000000..5f84b9f --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoErrFunction.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; +/**Error Function objects + * + */ +public class PolitoErrFunction extends NetworkObject{ + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr politoErrFunction; + Network net; + NetContext nctx; + FuncDecl isInBlacklist; + + public PolitoErrFunction(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=true; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + politoErrFunction = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + errFunctionRules(); + //net.saneSend(this); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoErrFunction; + } + + @Override + protected void addConstraints(Solver solver) { +// System.out.println("[ERR FUNC] Installing rules."); + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + private void errFunctionRules (){ + Expr n_0 = ctx.mkConst("PolitoErrFunction_"+politoErrFunction+"_n_0", nctx.node); + Expr p_0 = ctx.mkConst("PolitoErrFunction_"+politoErrFunction+"_p_0", nctx.packet); + IntExpr t_0 = ctx.mkIntConst("PolitoErrFunction_"+politoErrFunction+"_t_0"); + +// constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, +// ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0), +// (BoolExpr)nctx.nodeHasAddr.apply(politoErrFunction, nctx.pf.get("src").apply(p_0))),1,null,null,null,null)); +// constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, +// ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0), +// ctx.mkEq(nctx.pf.get("origin").apply(p_0), politoErrFunction)),1,null,null,null,null)); +// +// constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, +// ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0), +// ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null)); + + +// Constraint1 We want the ErrFunction not to send out any packet +// send(politoErrFunction, n_0, p, t_0) -> 1 == 2 + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoErrFunction, n_0, p_0, t_0), + ctx.mkEq(ctx.mkInt(1),ctx.mkInt(2))),1,null,null,null,null)); + +// constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, +// ctx.mkImplies( (BoolExpr)nctx.send.apply(n_0, politoErrFunction, p_0, t_0), +// (BoolExpr)nctx.nodeHasAddr.apply(politoErrFunction, nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)); + + } + }
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/PolitoFieldModifier.java b/verigraph/service/src/mcnet/netobjs/PolitoFieldModifier.java new file mode 100644 index 0000000..6d8d8fe --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoFieldModifier.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; + +public class PolitoFieldModifier extends NetworkObject { + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr politoFieldModifier; + Network net; + NetContext nctx; + + public PolitoFieldModifier(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoFieldModifier; + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=false; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + politoFieldModifier = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + public void installFieldModifier (){ + Expr x = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_x", nctx.node); + Expr y = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_y", nctx.node); + Expr p_0 = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_p_0", nctx.packet); + Expr p_1 = ctx.mkConst("politoFieldModifier_"+politoFieldModifier+"_p_1", nctx.packet); + + IntExpr t_0 = ctx.mkIntConst("politoFieldModifier_"+politoFieldModifier+"_t_0"); + IntExpr t_1 = ctx.mkIntConst("politoFieldModifier_"+politoFieldModifier+"_t_1"); + + constraints.add( + ctx.mkForall(new Expr[]{t_0, p_0, x}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoFieldModifier,x,p_0,t_0), + ctx.mkExists(new Expr[]{y, p_1, t_1}, + ctx.mkAnd(ctx.mkLt(t_1, t_0), + (BoolExpr)nctx.recv.apply(y, politoFieldModifier, p_1, t_1), + ctx.mkEq(nctx.pf.get("encrypted").apply(p_0), nctx.pf.get("encrypted").apply(p_1)), + ctx.mkEq(nctx.pf.get("src").apply(p_0), nctx.pf.get("src").apply(p_1)), + ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("dest").apply(p_1)), + ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.pf.get("inner_src").apply(p_1)), + ctx.mkEq(nctx.pf.get("inner_dest").apply(p_0), nctx.pf.get("inner_dest").apply(p_1)), + ctx.mkEq(nctx.pf.get("origin").apply(p_0), nctx.pf.get("origin").apply(p_1)), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_0), nctx.pf.get("orig_body").apply(p_1)), + ctx.mkEq(nctx.pf.get("body").apply(p_0), nctx.pf.get("body").apply(p_1)), + ctx.mkEq(nctx.pf.get("seq").apply(p_0), nctx.pf.get("seq").apply(p_1)), + ctx.mkEq(nctx.pf.get("proto").apply(p_0), nctx.pf.get("proto").apply(p_1)), + ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0), nctx.pf.get("emailFrom").apply(p_1)), + ctx.mkNot(ctx.mkEq(nctx.pf.get("url").apply(p_0), nctx.pf.get("url").apply(p_1))), + ctx.mkEq(nctx.pf.get("options").apply(p_0), nctx.pf.get("options").apply(p_1))),1,null,null,null,null)), + 1,null,null,null,null)); + } + +}
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/PolitoIDS.java b/verigraph/service/src/mcnet/netobjs/PolitoIDS.java new file mode 100644 index 0000000..6f2cddf --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoIDS.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; + +public class PolitoIDS extends NetworkObject { + + public static final int DROGA = 1; //no go + public static final int GATTINI = 2; //go + + Context ctx; + List<BoolExpr> constraints = new ArrayList<BoolExpr>(); + DatatypeExpr politoIDS; + Network net; + NetContext nctx; + FuncDecl isInBlacklist; + + + public PolitoIDS(Context ctx, Object[]...args){ + super(ctx, args); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoIDS; + } + + @Override + protected void init(Context ctx, Object[]... args) { + + this.ctx = ctx; + this.isEndHost = false; + this.politoIDS = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + this.net = (Network)args[0][1]; + this.nctx = (NetContext)args[0][2]; + + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + + } + + public void installIDS(int[] blackList){ + Expr n_0 = ctx.mkConst(politoIDS + "_n_0", nctx.node); + Expr n_1 = ctx.mkConst(politoIDS + "_n_1", nctx.node); + Expr p_0 = ctx.mkConst(politoIDS + "_p_0", nctx.packet); + IntExpr t_0 = ctx.mkIntConst(politoIDS + "_t_0"); + IntExpr t_1 = ctx.mkIntConst(politoIDS + "_t_1"); + Expr b_0 = ctx.mkIntConst(politoIDS + "_b_0"); + + isInBlacklist = ctx.mkFuncDecl(politoIDS + "_isInBlacklist", ctx.mkIntSort(), ctx.mkBoolSort()); + + + BoolExpr[] blConstraints = new BoolExpr[blackList.length]; + if(blackList.length != 0){ + + for(int i = 0; i<blackList.length; i++) + blConstraints[i] = ctx.mkEq(b_0, ctx.mkInt(blackList[i])); + + this.constraints.add(ctx.mkForall(new Expr[]{b_0}, + ctx.mkIff((BoolExpr)isInBlacklist.apply(b_0), ctx.mkOr(blConstraints)), + 1, + null, null, null, null)); + }else{ + this.constraints.add(ctx.mkForall(new Expr[]{b_0}, + ctx.mkEq(isInBlacklist.apply(b_0), ctx.mkBool(false)), + 1, + null, null, null, null)); + } + + //Constraint2 send(politoIDS, n_0, p, t_0) && (p.proto(HTTP_RESPONSE) || p.proto(HTTP_REQUEST)) -> + // (exist n_1,t_1 : (recv(n_1, politoIDS, p, t_1) && t_1 < t_0)) && !isInBlackList(p.body) + + this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0), ctx.mkOr(ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST)))), + ctx.mkAnd(ctx.mkExists(new Expr[]{n_1,t_1}, + ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1,politoIDS,p_0,t_1),ctx.mkLt(t_1, t_0)), + 1, + null, null, null, null), + ctx.mkNot((BoolExpr)isInBlacklist.apply(nctx.pf.get("body").apply(p_0))))), + 1, + null, null, null, null)); + + //Constraint3 send(politoIDS, n_0, p, t_0) && p.proto(HTTP_REQUEST) -> + // (exist n_1,t_1 : (recv(n_1, politoIDS, p, t_1) && t_1 < t_0)) Constraint not needed anymore (included in contr. 2) + /* + this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies(ctx.mkAnd((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0), ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST))), + ctx.mkAnd(ctx.mkExists(new Expr[]{n_1,t_1}, + ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1,politoIDS,p_0,t_1),ctx.mkLt(t_1, t_0)), + 1, + null, null, null, null))), + 1, + null, null, null, null)); + */ + + //Constraint5 send(politoIDS, n_0, p, t_0) -> p.proto == HTTP_REQ || p.protpo == HTTP_RESP + + this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0), + ctx.mkOr(ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST)), + ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)))), + 1, + null,null,null,null)); + + //Constraint6 send(politoIDS, n_0, p, t_0) -> nodeHasAddr(politoIDS,p.src) + + this.constraints.add(ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoIDS, n_0, p_0, t_0), + ctx.mkNot((BoolExpr)nctx.nodeHasAddr.apply(politoIDS,nctx.pf.get("src").apply(p_0)))), + 1, + null,null,null,null)); + + } + +} diff --git a/verigraph/service/src/mcnet/netobjs/PolitoMailClient.java b/verigraph/service/src/mcnet/netobjs/PolitoMailClient.java new file mode 100644 index 0000000..6925258 --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoMailClient.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; +/** + * MailClient objects + * + */ +public class PolitoMailClient extends NetworkObject{ + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr politoMailClient; + Network net; + NetContext nctx; + FuncDecl isInBlacklist; + + public PolitoMailClient(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=true; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + politoMailClient = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + DatatypeExpr ipServer = (DatatypeExpr) args[0][3]; + mailClientRules(ipServer); + //net.saneSend(this); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoMailClient; + } + + @Override + protected void addConstraints(Solver solver) { +// System.out.println("[MailClient] Installing rules."); + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + private void mailClientRules (DatatypeExpr ipServer){ + Expr n_0 = ctx.mkConst("PolitoMailClient_"+politoMailClient+"_n_0", nctx.node); + Expr p_0 = ctx.mkConst("PolitoMailClient_"+politoMailClient+"_p_0", nctx.packet); + IntExpr t_0 = ctx.mkIntConst("PolitoMailClient_"+politoMailClient+"_t_0"); + +// Constraint1 send(politoMailClient, n_0, p, t_0) -> nodeHasAddr(politoMailClient,p.src) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0), + (BoolExpr)nctx.nodeHasAddr.apply(politoMailClient,nctx.pf.get("src").apply(p_0))),1,null,null,null,null)); + +// Constraint2 send(politoMailClient, n_0, p, t_0) -> p.origin == politoMailClient + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoMailClient)),1,null,null,null,null)); + +// Constraint3 send(politoMailClient, n_0, p, t_0) -> p.orig_body == p.body + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null)); + +// Constraint4 recv(n_0, politoMailClient, p, t_0) -> nodeHasAddr(politoMailClient,p.dest) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoMailClient, p_0, t_0), + (BoolExpr)nctx.nodeHasAddr.apply(politoMailClient,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)); + +// Constraint5 This client is only able to produce POP3 requests +// send(politoMailClient, n_0, p, t_0) -> p.proto == POP3_REQ + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_REQUEST))),1,null,null,null,null)); + +// Constraint6 send(politoMailClient, n_0, p, t_0) -> p.dest == ip_mailServer + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailClient, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("dest").apply(p_0), ipServer)),1,null,null,null,null)); + } +} diff --git a/verigraph/service/src/mcnet/netobjs/PolitoMailServer.java b/verigraph/service/src/mcnet/netobjs/PolitoMailServer.java new file mode 100644 index 0000000..c464195 --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoMailServer.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; +/** Mail server objects + * + */ +public class PolitoMailServer extends NetworkObject{ + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr politoMailServer; + Network net; + NetContext nctx; + FuncDecl isInBlacklist; + + public PolitoMailServer(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=false; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + politoMailServer = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + mailServerRules(); + net.saneSend(this); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoMailServer; + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + private void mailServerRules (){ + Expr n_0 = ctx.mkConst(politoMailServer+"_n_0", nctx.node); + Expr p_0 = ctx.mkConst(politoMailServer+"_p_0", nctx.packet); + Expr p_1 = ctx.mkConst(politoMailServer+"_p_1", nctx.packet); + IntExpr t_0 = ctx.mkIntConst(politoMailServer+"_t_0"); + IntExpr t_1 = ctx.mkIntConst(politoMailServer+"_t_1"); + +// Constraint1 send(politoMailServer, n_0, p, t_0) -> nodeHasAddr(politoMailServer,p.src) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0), + (BoolExpr)nctx.nodeHasAddr.apply(politoMailServer,nctx.pf.get("src").apply(p_0))),1,null,null,null,null)); + +// Constraint2 send(politoMailServer, n_0, p, t_0) -> p.origin == politoMailServer + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoMailServer)),1,null,null,null,null)); + +// Constraint3 send(politoMailServer, n_0, p, t_0) -> p.orig_body == p.body + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null)); + +// Constraint4 recv(n_0, politoMailServer, p, t_0) -> nodeHasAddr(politoMailServer,p.dest) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoMailServer, p_0, t_0), + (BoolExpr)nctx.nodeHasAddr.apply(politoMailServer,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)); + +// Constraint5 send(politoMailServer, n_0, p, t_0) -> p.proto == POP3_RESP && p.emailFrom == 1 + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0), + ctx.mkAnd( ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE)), + ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0), ctx.mkInt(1)))),1,null,null,null,null)); + +// Constraint6 send(politoMailServer, n_0, p, t_0) -> +// (exist p_1, t_1 : (t_1 < t_0 && recv(n_0, politoMailServer, p_1, t_1) && +// p_0.proto == POP3_RESP && p_1.proto == POP3_REQ && p_0.dest == p_1.src ) + + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0), + ctx.mkExists(new Expr[]{p_1, t_1}, + ctx.mkAnd(ctx.mkLt(t_1, t_0), + (BoolExpr)nctx.recv.apply(n_0, politoMailServer, p_1, t_1), + ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.POP3_RESPONSE)), + ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.POP3_REQUEST)), + ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("src").apply(p_1))),1,null,null,null,null)),1,null,null,null,null)); + +// constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, +// ctx.mkImplies((BoolExpr)nctx.send.apply(politoMailServer, n_0, p_0, t_0), +// ctx.mkEq(nctx.pf.get("emailFrom").apply(p_0),ctx.mkInt(2))),1,null,null,null,null)); + } +}
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/PolitoNF.java b/verigraph/service/src/mcnet/netobjs/PolitoNF.java new file mode 100644 index 0000000..53cae28 --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoNF.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; +import com.microsoft.z3.Sort; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; + +/** First example of custom network function: a simple filter + * + */ +public class PolitoNF extends NetworkObject{ + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr politoNF; + Network net; + NetContext nctx; + FuncDecl isInBlacklist; + + + public PolitoNF(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=false; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + politoNF = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + //net.saneSend(this); + } + + public void politoNFRules (DatatypeExpr ipA,DatatypeExpr ipB){ +// System.out.println("[PolitoNf] Installing rules"); + Expr n_0 = ctx.mkConst("politoNF_"+politoNF+"_n_0", nctx.node); + Expr n_1 = ctx.mkConst("politoNF_"+politoNF+"_n_1", nctx.node); + Expr p_0 = ctx.mkConst("politoNF_"+politoNF+"_p_0", nctx.packet); + IntExpr t_0 = ctx.mkIntConst("politoNF_"+politoNF+"_t_0"); + IntExpr t_1 = ctx.mkIntConst("politoNF_"+politoNF+"_t_1"); + Expr a_0 = ctx.mkConst(politoNF+"_politoNF_a_0", nctx.address); + Expr a_1 = ctx.mkConst(politoNF+"_politoNF_a_1", nctx.address); + + FuncDecl myFunction = ctx.mkFuncDecl(politoNF+"_myFunction", new Sort[]{nctx.address,nctx.address}, ctx.mkBoolSort()); + + BoolExpr myConstraint = ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoNF, n_0, p_0, t_0), + ctx.mkExists(new Expr[]{n_1, t_1}, + ctx.mkAnd((BoolExpr)nctx.recv.apply(n_1, politoNF, p_0, t_1), + ctx.mkLt(t_1 , t_0), + (BoolExpr)myFunction.apply(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)),1,null,null,null,null); + + BoolExpr funcConstraint = ctx.mkOr(ctx.mkAnd(ctx.mkEq(a_0, ipA), ctx.mkEq(a_1, ipB)), ctx.mkAnd(ctx.mkEq(a_0,ipB), ctx.mkEq(a_1,ipA))); + + // Constraint1 myFunction(a_0,a_1) == ((a_0 == ipA && a_1 == ipB) || (a_0 == ipB && a_1 == ipA)) + constraints.add( + ctx.mkForall(new Expr[]{a_0,a_1}, + ctx.mkEq(myFunction.apply(a_0, a_1), funcConstraint),1,null,null,null,null)); + + //Constraint2 send(politoNF, n_0, p, t_0) -> + // (exist n_1,t_1 : (t_1 < t_0 && recv(n_1, politoNF, p, t_1) && myFunction(p.src,p.dest)) + constraints.add(myConstraint); + + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoNF; + } + + }
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/PolitoNat.java b/verigraph/service/src/mcnet/netobjs/PolitoNat.java new file mode 100644 index 0000000..6d8a36d --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoNat.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; +/** + * NAT Model object + * + */ +public class PolitoNat extends NetworkObject{ + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr nat; + List<DatatypeExpr> private_addresses; + List<NetworkObject> private_node; + Network net; + NetContext nctx; + FuncDecl private_addr_func ; + + public PolitoNat(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=false; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + nat = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + private_addresses = new ArrayList<DatatypeExpr>(); + private_node = new ArrayList<NetworkObject>(); + net.saneSend(this); + } + + @Override + public DatatypeExpr getZ3Node() { + return nat; + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + /* + private void addPrivateAdd(List<DatatypeExpr> address){ + private_addresses.addAll(address); + } + */ + + public List<DatatypeExpr> getPrivateAddress(){ + return private_addresses; + } + + public void natModel(DatatypeExpr natIp){ + Expr x = ctx.mkConst("x", nctx.node); + Expr y = ctx.mkConst("y", nctx.node); + Expr z = ctx.mkConst("z", nctx.node); + + Expr p_0 = ctx.mkConst("p_0", nctx.packet); + Expr p_1 = ctx.mkConst("p_1", nctx.packet); + Expr p_2 = ctx.mkConst("p_2", nctx.packet); + + IntExpr t_0 = ctx.mkIntConst("t_0"); + IntExpr t_1 = ctx.mkIntConst("t_1"); + IntExpr t_2 = ctx.mkIntConst("t_2"); + +// private_addr_func = ctx.mkFuncDecl("private_addr_func", nctx.address, ctx.mkBoolSort()); + private_addr_func = ctx.mkFuncDecl(nat + "_nat_func", nctx.address, ctx.mkBoolSort()); + + //Constraint1 +// "send(nat, x, p_0, t_0) && !private_addr_func(p_0.dest) -> +// p_0.src == ip_politoNat && +// (exist y, p_1,t_1 : +// (recv(y, nat, p_1, t_1) && t_1 < t_0 && +// private_addr_func(p1.src) && +// p_1.origin == p_0.origin && +// same for p_1.<dest,orig_body,body,seq,proto,emailFrom,url,options> == p_0.<...>) " + constraints.add( ctx.mkForall(new Expr[]{t_0, p_0, x}, + ctx.mkImplies( + ctx.mkAnd((BoolExpr)nctx.send.apply(nat, x, p_0, t_0), + ctx.mkNot((BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0)))), + ctx.mkAnd( + ctx.mkEq(nctx.pf.get("src").apply(p_0),natIp), + ctx.mkExists(new Expr[]{y, p_1, t_1}, + ctx.mkAnd( + (BoolExpr)nctx.recv.apply(y, nat, p_1, t_1), + ctx.mkLt(t_1 , t_0), + (BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_1)), + ctx.mkEq(nctx.pf.get("origin").apply(p_1),nctx.pf.get("origin").apply(p_0)), + ctx.mkEq(nctx.pf.get("dest").apply(p_1),nctx.pf.get("dest").apply(p_0)), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_1),nctx.pf.get("orig_body").apply(p_0)), + ctx.mkEq(nctx.pf.get("body").apply(p_1),nctx.pf.get("body").apply(p_0)), + ctx.mkEq(nctx.pf.get("seq").apply(p_1),nctx.pf.get("seq").apply(p_0)), + ctx.mkEq(nctx.pf.get("proto").apply(p_1),nctx.pf.get("proto").apply(p_0)), + ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1),nctx.pf.get("emailFrom").apply(p_0)), + ctx.mkEq(nctx.pf.get("url").apply(p_1),nctx.pf.get("url").apply(p_0)), + ctx.mkEq(nctx.pf.get("options").apply(p_1),nctx.pf.get("options").apply(p_0))),1,null,null,null,null))),1,null,null,null,null)); + + //Constraint2 +// send(nat, x, p_0, t_0) && private_addr_func(p_0.dest) -> +// !private_addr_func(p_0.src) && +// (exist y, p_1,t_1 : +// (recv(y, nat, p_1, t_1) && t_1 < t_0 && +// !private_addr_func(p1.src) && +// p_1.dest == ip_politoNat && +// p_1.origin == p_0.origin && +// same for p_1.<src,orig_body,body,seq,proto,emailFrom,url,options> == p_0.<...>) + constraints.add( ctx.mkForall(new Expr[]{x, p_0, t_0}, + ctx.mkImplies( + ctx.mkAnd((BoolExpr)nctx.send.apply(nat, x, p_0, t_0), + (BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0))), + ctx.mkAnd( + ctx.mkNot((BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_0))), + ctx.mkExists(new Expr[]{y, p_1, t_1}, + ctx.mkAnd( + ctx.mkLt(t_1 , t_0), + (BoolExpr)nctx.recv.apply(y, nat, p_1, t_1), + ctx.mkNot((BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_1))), + ctx.mkEq(nctx.pf.get("dest").apply(p_1),natIp), + ctx.mkEq(nctx.pf.get("src").apply(p_1),nctx.pf.get("src").apply(p_0)), + ctx.mkEq(nctx.pf.get("origin").apply(p_0),nctx.pf.get("origin").apply(p_1)), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_1),nctx.pf.get("orig_body").apply(p_0)), + ctx.mkEq(nctx.pf.get("body").apply(p_1),nctx.pf.get("body").apply(p_0)), + ctx.mkEq(nctx.pf.get("seq").apply(p_1),nctx.pf.get("seq").apply(p_0)), + ctx.mkEq(nctx.pf.get("proto").apply(p_1),nctx.pf.get("proto").apply(p_0)), + ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1),nctx.pf.get("emailFrom").apply(p_0)), + ctx.mkEq(nctx.pf.get("url").apply(p_1),nctx.pf.get("url").apply(p_0)), + ctx.mkEq(nctx.pf.get("options").apply(p_1),nctx.pf.get("options").apply(p_0)), + ctx.mkExists(new Expr[]{z, p_2, t_2}, + ctx.mkAnd( + ctx.mkLt(t_2 , t_1), + (BoolExpr)nctx.recv.apply(z, nat, p_2, t_2), + (BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_2)), + ctx.mkEq(nctx.pf.get("src").apply(p_1),nctx.pf.get("dest").apply(p_2)), + ctx.mkEq(nctx.pf.get("src").apply(p_0),nctx.pf.get("dest").apply(p_2)), + ctx.mkEq(nctx.pf.get("src").apply(p_2),nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)),1,null,null,null,null))),1,null,null,null,null)); + } + + public void setInternalAddress(ArrayList<DatatypeExpr> internalAddress){ + List<BoolExpr> constr = new ArrayList<BoolExpr>(); + Expr n_0 = ctx.mkConst("nat_node", nctx.address); + + for(DatatypeExpr n : internalAddress){ + constr.add(ctx.mkEq(n_0,n)); + } + BoolExpr[] constrs = new BoolExpr[constr.size()]; + //Constraint private_addr_func(n_0) == or(n_0==n foreach internal address) + constraints.add(ctx.mkForall(new Expr[]{n_0}, ctx.mkEq(private_addr_func.apply(n_0),ctx.mkOr(constr.toArray(constrs))),1,null,null,null,null)); + } +}
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/PolitoVpnAccess.java b/verigraph/service/src/mcnet/netobjs/PolitoVpnAccess.java new file mode 100644 index 0000000..e6fc5fe --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoVpnAccess.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; + +public class PolitoVpnAccess extends NetworkObject { + + List<BoolExpr> constraints = new ArrayList<BoolExpr>(); + DatatypeExpr politoVpnAccess; + FuncDecl private_addr_func; + NetContext nctx; + Context ctx; + Network net; + + public PolitoVpnAccess(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoVpnAccess; + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + this.isEndHost = false; + this.politoVpnAccess = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + this.net = (Network)args[0][1]; + this.nctx = (NetContext)args[0][2]; + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + public void vpnAccessModel(DatatypeExpr vpnAccessIp, DatatypeExpr vpnExitIp) { + Expr x = ctx.mkConst("vpn_x", nctx.node); + Expr y = ctx.mkConst("vpn_y", nctx.node); + + Expr p_0 = ctx.mkConst("vpn_p_0", nctx.packet); + Expr p_1 = ctx.mkConst("vpn_p_1", nctx.packet); + + IntExpr t_0 = ctx.mkIntConst("vpn_t_0"); + IntExpr t_1 = ctx.mkIntConst("vpn_t_1"); + + private_addr_func = ctx.mkFuncDecl("vpn_private_addr_func", nctx.address, ctx.mkBoolSort()); + + BoolExpr constraint1 = ctx.mkForall(new Expr[]{t_0, p_0, x}, + ctx.mkImplies(ctx.mkAnd( + (BoolExpr)nctx.send.apply(politoVpnAccess, x, p_0, t_0), + ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null"))), + ctx.mkAnd( + (BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0)), + ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_0)), + ctx.mkExists(new Expr[]{y, p_1, t_1}, + ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnAccess, p_1, t_1), + ctx.mkLt(t_1, t_0), + (BoolExpr)nctx.pf.get("encrypted").apply(p_1), + ctx.mkEq(nctx.pf.get("src").apply(p_1), vpnExitIp), + ctx.mkEq(nctx.pf.get("dest").apply(p_1), vpnAccessIp), + ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.pf.get("src").apply(p_0)), + ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.pf.get("dest").apply(p_0)), + ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)), + ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)), + ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)), + ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)), + ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)), + ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)), + ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))), + 1,null,null,null,null); + + constraints.add(constraint1); + + BoolExpr constraint2 = ctx.mkForall(new Expr[]{t_0, p_0, x}, + ctx.mkImplies(ctx.mkAnd( + (BoolExpr)nctx.send.apply(politoVpnAccess, x, p_0, t_0), + ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null")))), + ctx.mkAnd( + ctx.mkEq(nctx.pf.get("src").apply(p_0), vpnAccessIp), + ctx.mkEq(nctx.pf.get("dest").apply(p_0), vpnExitIp), + (BoolExpr)private_addr_func.apply(nctx.pf.get("inner_src").apply(p_0)), + ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_dest").apply(p_0), vpnAccessIp)), + (BoolExpr)nctx.pf.get("encrypted").apply(p_0), + ctx.mkExists(new Expr[]{y, p_1, t_1}, + ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnAccess, p_1, t_1), + ctx.mkLt(t_1, t_0), + ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_1)), + ctx.mkEq(nctx.pf.get("src").apply(p_1), nctx.pf.get("inner_src").apply(p_0)), + ctx.mkEq(nctx.pf.get("dest").apply(p_1), nctx.pf.get("inner_dest").apply(p_0)), + ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.am.get("null")), + ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.am.get("null")), + ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)), + ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)), + ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)), + ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)), + ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)), + ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)), + ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))), + 1,null,null,null,null); + + constraints.add(constraint2); + } + + public void setInternalAddress(ArrayList<DatatypeExpr> internalAddress){ + List<BoolExpr> constr = new ArrayList<BoolExpr>(); + Expr n_0 = ctx.mkConst("vpn_node", nctx.address); + + for(DatatypeExpr n : internalAddress){ + constr.add(ctx.mkEq(n_0,n)); + } + BoolExpr[] constrs = new BoolExpr[constr.size()]; + //Constraint private_addr_func(n_0) == or(n_0==n foreach internal address) + constraints.add(ctx.mkForall(new Expr[]{n_0}, ctx.mkEq(private_addr_func.apply(n_0),ctx.mkOr(constr.toArray(constrs))),1,null,null,null,null)); + } + +}
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/PolitoVpnExit.java b/verigraph/service/src/mcnet/netobjs/PolitoVpnExit.java new file mode 100644 index 0000000..fb2341f --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoVpnExit.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; + +public class PolitoVpnExit extends NetworkObject { + + List<BoolExpr> constraints = new ArrayList<BoolExpr>(); + DatatypeExpr politoVpnExit; + FuncDecl private_addr_func; + NetContext nctx; + Context ctx; + Network net; + + public PolitoVpnExit(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoVpnExit; + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + this.isEndHost = false; + this.politoVpnExit = this.z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + this.net = (Network)args[0][1]; + this.nctx = (NetContext)args[0][2]; + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + public void vpnAccessModel(DatatypeExpr vpnAccessIp, DatatypeExpr vpnExitIp) { + Expr x = ctx.mkConst("vpn_x", nctx.node); + Expr y = ctx.mkConst("vpn_y", nctx.node); + + Expr p_0 = ctx.mkConst("vpn_p_0", nctx.packet); + Expr p_1 = ctx.mkConst("vpn_p_1", nctx.packet); + + IntExpr t_0 = ctx.mkIntConst("vpn_t_0"); + IntExpr t_1 = ctx.mkIntConst("vpn_t_1"); + + private_addr_func = ctx.mkFuncDecl("vpn_private_addr_func", nctx.address, ctx.mkBoolSort()); + + BoolExpr constraint1 = ctx.mkForall(new Expr[]{t_0, p_0, x}, + ctx.mkImplies(ctx.mkAnd( + (BoolExpr)nctx.send.apply(politoVpnExit, x, p_0, t_0), + ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null"))), + ctx.mkAnd( + (BoolExpr)private_addr_func.apply(nctx.pf.get("src").apply(p_0)), + ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_0)), + ctx.mkExists(new Expr[]{y, p_1, t_1}, + ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnExit, p_1, t_1), + ctx.mkLt(t_1, t_0), + (BoolExpr)nctx.pf.get("encrypted").apply(p_1), + ctx.mkEq(nctx.pf.get("src").apply(p_1), vpnAccessIp), + ctx.mkEq(nctx.pf.get("dest").apply(p_1), vpnExitIp), + ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.pf.get("src").apply(p_0)), + ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.pf.get("dest").apply(p_0)), + ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)), + ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)), + ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)), + ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)), + ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)), + ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)), + ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))), + 1,null,null,null,null); + + constraints.add(constraint1); + + BoolExpr constraint2 = ctx.mkForall(new Expr[]{t_0, p_0, x}, + ctx.mkImplies(ctx.mkAnd( + (BoolExpr)nctx.send.apply(politoVpnExit, x, p_0, t_0), + ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_src").apply(p_0), nctx.am.get("null")))), + ctx.mkAnd( + ctx.mkEq(nctx.pf.get("src").apply(p_0), vpnExitIp), + ctx.mkEq(nctx.pf.get("dest").apply(p_0), vpnAccessIp), + (BoolExpr)private_addr_func.apply(nctx.pf.get("dest").apply(p_0)), + ctx.mkNot(ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), vpnExitIp)), + (BoolExpr)nctx.pf.get("encrypted").apply(p_0), + ctx.mkExists(new Expr[]{y, p_1, t_1}, + ctx.mkAnd((BoolExpr)nctx.recv.apply(y, politoVpnExit, p_1, t_1), + ctx.mkLt(t_1, t_0), + ctx.mkNot((BoolExpr)nctx.pf.get("encrypted").apply(p_1)), + ctx.mkEq(nctx.pf.get("src").apply(p_1), nctx.pf.get("inner_src").apply(p_0)), + ctx.mkEq(nctx.pf.get("dest").apply(p_1), nctx.pf.get("inner_dest").apply(p_0)), + ctx.mkEq(nctx.pf.get("inner_src").apply(p_1), nctx.am.get("null")), + ctx.mkEq(nctx.pf.get("inner_dest").apply(p_1), nctx.am.get("null")), + ctx.mkEq(nctx.pf.get("origin").apply(p_1), nctx.pf.get("origin").apply(p_0)), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_1), nctx.pf.get("orig_body").apply(p_0)), + ctx.mkEq(nctx.pf.get("body").apply(p_1), nctx.pf.get("body").apply(p_0)), + ctx.mkEq(nctx.pf.get("seq").apply(p_1), nctx.pf.get("seq").apply(p_0)), + ctx.mkEq(nctx.pf.get("proto").apply(p_1), nctx.pf.get("proto").apply(p_0)), + ctx.mkEq(nctx.pf.get("emailFrom").apply(p_1), nctx.pf.get("emailFrom").apply(p_0)), + ctx.mkEq(nctx.pf.get("url").apply(p_1), nctx.pf.get("url").apply(p_0)), + ctx.mkEq(nctx.pf.get("options").apply(p_1), nctx.pf.get("options").apply(p_0))), 1, null, null, null, null))), + 1,null,null,null,null); + + constraints.add(constraint2); + } + + public void setInternalAddress(ArrayList<DatatypeExpr> internalAddress){ + List<BoolExpr> constr = new ArrayList<BoolExpr>(); + Expr n_0 = ctx.mkConst("vpn_node", nctx.address); + + for(DatatypeExpr n : internalAddress){ + constr.add(ctx.mkEq(n_0,n)); + } + BoolExpr[] constrs = new BoolExpr[constr.size()]; + //Constraint private_addr_func(n_0) == or(n_0==n foreach internal address) + constraints.add(ctx.mkForall(new Expr[]{n_0}, ctx.mkEq(private_addr_func.apply(n_0),ctx.mkOr(constr.toArray(constrs))),1,null,null,null,null)); + } + +}
\ No newline at end of file diff --git a/verigraph/service/src/mcnet/netobjs/PolitoWebClient.java b/verigraph/service/src/mcnet/netobjs/PolitoWebClient.java new file mode 100644 index 0000000..28e2cf2 --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoWebClient.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; + +/** + * WebClient + */ +public class PolitoWebClient extends NetworkObject{ + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr politoWebClient; + Network net; + NetContext nctx; + FuncDecl isInBlacklist; + + public PolitoWebClient(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=true; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + politoWebClient = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + DatatypeExpr ipServer = (DatatypeExpr) args[0][3]; + webClientRules(ipServer); + //net.saneSend(this); + } + + @Override + public DatatypeExpr getZ3Node() { + return politoWebClient; + } + + @Override + protected void addConstraints(Solver solver) { +// System.out.println("[MailClient] Installing rules."); + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + private void webClientRules (DatatypeExpr ipServer){ + Expr n_0 = ctx.mkConst("PolitoWebClient_"+politoWebClient+"_n_0", nctx.node); + Expr p_0 = ctx.mkConst("PolitoWebClient_"+politoWebClient+"_p_0", nctx.packet); + IntExpr t_0 = ctx.mkIntConst("PolitoWebClient_"+politoWebClient+"_t_0"); + + //Constraint1 send(politoWebClient, n_0, p, t_0) -> nodeHasAddr(politoWebClient,p.src) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0), + (BoolExpr)nctx.nodeHasAddr.apply(politoWebClient,nctx.pf.get("src").apply(p_0))),1,null,null,null,null)); + + //Constraint2 send(politoWebClient, n_0, p, t_0) -> p.origin == politoWebClient + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("origin").apply(p_0),politoWebClient)),1,null,null,null,null)); + + //Constraint3 send(politoWebClient, n_0, p, t_0) -> p.orig_body == p.body + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))),1,null,null,null,null)); + + //Constraint4 recv(n_0, politoWebClient, p, t_0) -> nodeHasAddr(politoWebClient,p.dest) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,politoWebClient, p_0, t_0), + (BoolExpr)nctx.nodeHasAddr.apply(politoWebClient,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)); + + + //Constraint5 This client is only able to produce HTTP requests + // send(politoWebClient, n_0, p, t_0) -> p.proto == HTTP_REQ + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_REQUEST))),1,null,null,null,null)); + + //Constraint6 send(politoWebClient, n_0, p, t_0) -> p.dest == ipServer + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(politoWebClient, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("dest").apply(p_0), ipServer)),1,null,null,null,null)); + } + } diff --git a/verigraph/service/src/mcnet/netobjs/PolitoWebServer.java b/verigraph/service/src/mcnet/netobjs/PolitoWebServer.java new file mode 100644 index 0000000..54710d9 --- /dev/null +++ b/verigraph/service/src/mcnet/netobjs/PolitoWebServer.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2017 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package mcnet.netobjs; + + +import java.util.ArrayList; +import java.util.List; + +import com.microsoft.z3.BoolExpr; +import com.microsoft.z3.Context; +import com.microsoft.z3.DatatypeExpr; +import com.microsoft.z3.Expr; +import com.microsoft.z3.FuncDecl; +import com.microsoft.z3.IntExpr; +import com.microsoft.z3.Solver; + +import mcnet.components.NetContext; +import mcnet.components.Network; +import mcnet.components.NetworkObject; +/** + * WebServer object + * + */ +public class PolitoWebServer extends NetworkObject{ + + List<BoolExpr> constraints; + Context ctx; + DatatypeExpr node; + Network net; + NetContext nctx; + FuncDecl isInBlacklist; + + public PolitoWebServer(Context ctx, Object[]... args) { + super(ctx, args); + } + + @Override + protected void init(Context ctx, Object[]... args) { + this.ctx = ctx; + isEndHost=true; + constraints = new ArrayList<BoolExpr>(); + z3Node = ((NetworkObject)args[0][0]).getZ3Node(); + node = z3Node; + net = (Network)args[0][1]; + nctx = (NetContext)args[0][2]; + webServerRules(); + } + + @Override + public DatatypeExpr getZ3Node() { + return node; + } + + @Override + protected void addConstraints(Solver solver) { + BoolExpr[] constr = new BoolExpr[constraints.size()]; + solver.add(constraints.toArray(constr)); + } + + private void webServerRules (){ + Expr n_0 = ctx.mkConst("webserver_"+node+"_n_0", nctx.node); + Expr p_0 = ctx.mkConst("webserver_"+node+"_p_0", nctx.packet); + Expr p_1 = ctx.mkConst("webserver_"+node+"_p_1", nctx.packet); + IntExpr t_0 = ctx.mkIntConst("webserver_"+node+"_t_0"); + IntExpr t_1 = ctx.mkIntConst("webserver_"+node+"_t_1"); + + //Constraint1 send(politoWebServer, n_0, p, t_0) -> nodeHasAddr(politoWebServer,p.src) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0), + (BoolExpr)nctx.nodeHasAddr.apply(node,nctx.pf.get("src").apply(p_0))),1,null,null,null,null)); + + //Constraint2 send(politoWebServer, n_0, p, t_0) -> p.origin == politoWebServer + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("origin").apply(p_0),node)),1,null,null,null,null)); + + //Constraint3 send(politoWebServer, n_0, p, t_0) -> p.orig_body == p.body + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0), + ctx.mkEq(nctx.pf.get("orig_body").apply(p_0),nctx.pf.get("body").apply(p_0))), + 1,null,null,null,null)); + + //Constraint4 recv(n_0, politoWebServer, p, t_0) -> nodeHasAddr(politoWebServer,p.dest) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.recv.apply(n_0,node, p_0, t_0), + (BoolExpr)nctx.nodeHasAddr.apply(node,nctx.pf.get("dest").apply(p_0))),1,null,null,null,null)); + + //Constraint5 + // send(politoWebServer, n_0, p, t_0) -> + // (exist p_1,t_1 : + // (t_1 < t_0 && recv(n_0, politoWebServer, p_1, t_1) && + // p_0.proto == HTTP_RESP && p_1.proto == HTTP_REQ && + // p_0.dest == p_1.src && p_0.src == p_1.dest && p_0.url == p_1.url) + constraints.add( ctx.mkForall(new Expr[]{n_0, p_0, t_0}, + ctx.mkImplies((BoolExpr)nctx.send.apply(node, n_0, p_0, t_0), + ctx.mkExists(new Expr[]{p_1, t_1}, + ctx.mkAnd( + ctx.mkLt(t_1, t_0), + ctx.mkEq(nctx.pf.get("url").apply(p_0), nctx.pf.get("url").apply(p_1)), + (BoolExpr)nctx.recv.apply(n_0, node, p_1, t_1), + ctx.mkEq(nctx.pf.get("proto").apply(p_0), ctx.mkInt(nctx.HTTP_RESPONSE)), + ctx.mkEq(nctx.pf.get("proto").apply(p_1), ctx.mkInt(nctx.HTTP_REQUEST)), + ctx.mkEq(nctx.pf.get("dest").apply(p_0), nctx.pf.get("src").apply(p_1)), + ctx.mkEq(nctx.pf.get("src").apply(p_0), nctx.pf.get("dest").apply(p_1))), + 1,null,null,null,null)),1,null,null,null,null)); + } +} |