Layered architecture organizes large systems such that various system
components are divided into groups, called layers, labeled with succesive
integers, starting with zero; and which are subject to the following
global constraint:
setLevel(k)
it sends to x.
setLevel
messages, mentioned above).
The example following the layered policy introduces a increased number of novel concepts that are not encountered in the previous example. The reader is urged to perform and understand the previous examples thoroughly. Furthermore, knowledge of certificates and public key cryptosystems are necessary. Since the trust relationship in this example is built using certificates and digital signatures, this example uses programmed agents rather than human (browser) interface (as used in the previous examples). Furthermore, a certified controller will be used in this case, and the laws will be expressed as direct text and not as URL -- as before. Due to this increased level of complexity, it is important that the steps outlined in this example are followed very closely.
The following components are required for this example:
The Prolog version of this law follows:
law(la,authority(cAdmin),language(prolog)).
authority(cAdmin,keyHash(YOUR-KEY-HASH-IN-HERE)).
authority(sysAdmin,keyHash(YOUR-KEY-HASH-IN-HERE)).
adopted(Par,cert([certificate(issuer(sysAdmin),subject(Self),attributes(A))])) :-
do(add(level(0))), (A=role(mgr) -> do(add(role(mgr)));true).
adopted(par(Args)) :- do(add(level(0))).
certified(Name,certificate(issuer(sysAdmin),subject(Self),attributes(role(mgr)))) :-
do(add(role(mgr))).
sent(X,getCS,Y) :- do(discloseCS(all)).
sent(X,setLevel(K),Y) :- role(mgr)@CS, do(forward).
arrived(X,setLevel(K),Y) :- level(K1)@CS,do(replace(level(K1),level(K))), do(deliver).
sent(X,M,Y) :- level(K)@CS, do(forward(X,[K,M],Y)).
arrived(X,[K,M],Y) :- level(K1)@CS, (K = K1; K1 is K-1), do(deliver(X,M,Y)).
disconnected :- do(quit).
This is the Java version of the law:
law(la,authority(cAdmin),language(java))
authority(cAdmin,keyHash(YOUR-KEY-HASH-IN-HERE)).
authority(sysAdmin,keyHash(YOUR-KEY-HASH-IN-HERE)).
public class la extends Law{
public void adopted(String arg, String[] issuer, String[] subject, String[] attributes) {
if (issuer.length != 0) {
if (issuer[0].equals("sysAdmin") && subject[0].equals(Self) && attributes[0].equals("role(mgr)")) {
doAdd("role(mgr)");
}
}
doAdd("level(0)");
}
public void certified(String source, String issuer, String subject, String attributes) {
if (issuer.equals("sysAdmin") && subject.equals(Self) && attributes.equals("role(mgr)")) {
doAdd("role(mgr)");
}
}
public void sent(String source, String message, String dest) {
if (message.equals("getCS"))
doDiscloseAllCS();
if (message.startsWith("setLevel") && CS.has("role(mgr)") ) {
doForward();
return;
}
int levelK = CS.fetchInt("level");
doForward(source, "extendedMessage(" + levelK + "," + message + ")", dest);
}
public void arrived(String source, String message, String dest) {
String content = getContentFromMessage(message);
Term levelTerm = CS.findT("level(%A)");
if (message.startsWith("setLevel")) {
doReplace(levelTerm.toString(),"level(" + content + ")");
doDeliver();
return;
}
if (message.startsWith("extendedMessage")) {
String trueMessage = content.substring(content.indexOf(',') + 1);
int levelK = Integer.parseInt(content.substring(0, content.indexOf(',')));
int levelK1 = CS.fetchInt("level");
if ((levelK >= levelK1) && (levelK <= levelK1 + 1)) {
doDeliver(source, trueMessage, Self);
return;
}
}
}
public void disconnected() {
doQuit();
}
/**
Helper method to parse the argument out of a regular expression
*/
public String getContentFromMessage(String anyMessage) {
int index = anyMessage.indexOf("(");
if (index == -1) return "";
else return anyMessage.substring(index+1, anyMessage.length()-1);
}
}
The code of the programmed agent follows. This code differs from the code presented in the Quick Start in two aspects: it provides the agent to verify that a controller is well certified; and it allows an agent to submit certificates to the controller in order to gain privileges within the community.
import java.net.*;
import java.util.*;
import java.io.*;
import java.security.*;
import moses.member.*;
import moses.security.*;
import moses.controlState.*;
import moses.util.*;
public class SomeAgent implements Agent{
public void run (String[] args) throws Exception {
System.out.println("> Usage:");
System.out.println("> java SomeAgent contrname contrport lawfile agname");
System.out.println("> java SomeAgent contrname contrport lawfile agname CApub");
System.out.println("> java SomeAgent contrname contrport lawfile agname CApub Mycert Myprivkey");
//variables to read from the command line
String contrname, contrport, lawfile, agname, ca = null, certf = null, priv = null;
if(args.length < 4) {
System.out.println("> java SomeAgent contrname contrport lawfile agname");
System.out.println("> java SomeAgent contrname contrport lawfile agname CApub");
System.out.println("> java SomeAgent contrname contrport lawfile agname CApub Mycert Myprivkey");
return;
}
contrname = args[0];
contrport = args[1];
lawfile = args[2];
agname = args[3];
if(args.length ==5)
ca = args[4];
if(args.length ==7) {
ca = args[4];
certf = args[5];
priv = args[6];
}
//retrieve the public key of the CA - required to verify that
//the controller is properly certified
Member m;
PublicKey pubca = null;
if(ca != null) {
pubca = certCreation.getPublicKey(ca);
}
//retrieve the law from a local file
FileInputStream fis = new FileInputStream(lawfile);
byte[] blaw = new byte[fis.available()];
fis.read(blaw);
String slaw = new String(blaw);
//create the member of the community
//if no public key is fed at the agent, the controller is not verified
if(pubca == null)
m = new Member(slaw,Const.IMM_LAW,contrname, Integer.parseInt(contrport), agname);
else
m = new Member(slaw,Const.IMM_LAW,contrname, Integer.parseInt(contrport), agname, pubca);
//if this agent is started as a manager, then
//provide with the manager's certificate and signature
if (certf!=null) {
LGICert cert = certCreation.getCert(certf);
PrivateKey privk = certCreation.getPrivateKey(priv);
byte[] sign = null;
sign = Secu.signSelfCertificate(cert, privk);
m.addCertificate(cert, sign);
}
//become a member of the community
System.out.println(m.adopt("mypassword","someargument"));
//create a receiver object that receives messages
//assynchronously from the controller
new Receiver(this,m).start();
//read messages from the console;
//these messages are sent to the controller as soon as they are typed in
System.out.println("Type exit to quit");
for(;;) {
try{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String command = in.readLine();
if (command.equals("exit")) {
m.close();
System.out.println("The Agent is shutting down...");
System.exit(0);
}
if (command.startsWith("send")) {
Term ct = Term.parse(command);
if(ct == null) {
System.out.println("send(msg,dest) -- not understood. Try again!");
continue;
}
Term tt = Term.parse("send(%M,%D)");
UnifyResult ur = ct.unify(tt);
if(ur == null) {
System.out.println("send(msg,dest) -- not understood. Try again!");
continue;
}
String msg = ur.getSVar("M");
String dest = ur.getSVar("D");
m.send_lg(msg,dest);
}
} catch(Exception e) {
;
}
}
}
public void processRequest(Member member, String message, String destination) {
;
}
public void processReply(Member member, String reply) {
System.out.println("Received: " + reply);
}
public void processReply(Member member, byte[] breply) {
System.out.println("Received: " + breply);
}
public void processReply(Member member, Object oreply) {
System.out.println("Received: " + oreply);
}
public static void main (String[] args) throws Exception {
SomeAgent somea = new SomeAgent();
somea.run(args);
}
}
The code of the agent is available for download at:
http://www.moses.rutgers.edu/examples/layered/SomeAgent.java
Instructions on running the example -- how to start the agents and how to observe the effects of the law.
> java moses.security.keyPairCreation CApub.key CApriv.key
> java moses.security.keyPairCreation Contrpub.key Contrpriv.key
> java moses.security.keyPairCreation Syspub.key Syspriv.key
> java moses.security.keyPairCreation MGRpub.key MGRpriv.key
> java moses.security.certCreation CApub.key CApriv.key Contrpub.key Contrcertfile certifiedController
role(mgr),
role\(mgr\), "role\(mgr\)", etc.) :> java moses.security.certCreation Syspub.key Syspriv.key MGRpub.key MGRcertfile role(mgr)
> java moses.security.certCreation Syspub.key Syspriv.key MGRpub.key MGRcertfile role(mgr)
> java moses.controller.AuthorityTable -fCApub.key
> java moses.controller.AuthorityTable -fSyspub.key
authority(cAdmin,keyHash(1FF4A9E377A649866C9CA89144334406)) authority(sysAdmin,keyHash(3B50B143ADFC9A735C4D21EF52952A59))
> java moses.Controller -cFileContrcertfile -kFileContrpriv.key
Controller starts (use -help option for help)
Reading certificate and private key from the current directory
in signing message...
ramses.rutgers.edu:9000 is sandboxed
Location of the configuration files is:
> javac SomeAgent.java > java SomeAgent controller-host 9000 layered.java1 mgr CApub.key MGRcertfile MGRpriv.key
> java SomeAgent contrname contrport lawfile agname > java SomeAgent contrname contrport lawfile agname CApub > java SomeAgent contrname contrport lawfile agname CApub Mycert Myprivkey in signing message... -1 Type exit to quit
x and y, as follows:
> java SomeAgent research.rutgers.edu 9000 layered.java1 x CApub.key
> java SomeAgent research.rutgers.edu 9000 layered.java1 y CApub.key
send(somemessage,x@hostname) and observe y's
console displaying Received: somemessage. Try the same
message from y to x. The mesages are permitted because initially x and y
have both the same level: 0 .
send(setLevel(3),x@hostname). X's window should
display Received: setLevel(3). When trying to exchange
messages between x and y, no message is propagated anymore. Reset y's
level by typing in the manager's window the following:
send(setLevel(2),y@hostname). Observe now that all
the messages from x to y are propagated but not the other way.
send(setLevel(2),x@hostname). Observe that x does
not receive any message (its level is greater that y's level). When
the manager attempts that, however, x receives the message and changes
its level accordingly.