User:Kevin Reid/Offline delegation

From Erights

(Difference between revisions)
Jump to: navigation, search
(link to mailing list message)
(publishing offline delegation attempt #2)
Line 1: Line 1:
-
Mailing list post of this: [http://www.eros-os.org/pipermail/cap-talk/2008-May/011062.html]
 
-
 
<pre>
<pre>
# Copyright 2008 Kevin Reid, under the terms of the MIT X license
# Copyright 2008 Kevin Reid, under the terms of the MIT X license
Line 54: Line 52:
}
}
-
/** Turn an object whose methods take an extra argument for the delegation chain into a scap. */
+
/** Turn an object whose methods take an extra argument for the delegation chain into a certificate. */
def exportOD(handler) {
def exportOD(handler) {
   def rootSigner := makeSigner("export root")
   def rootSigner := makeSigner("export root")

Revision as of 16:59, 30 May 2008

# Copyright 2008 Kevin Reid, under the terms of the MIT X license
# found at http://www.opensource.org/licenses/mit-license.html ................

pragma.syntax("0.9")

# --- Utilities ---

def makeProxy := <elib:ref.makeProxy>
def makeBrand := <elib:sealing.makeBrand>

def everything {
  to contains(_) { return true }
}

# --- Signing ---

interface ::"Signed" guards SignedStamp {}

def makeSigner(label) {
  def who {
    to __printOn(out) {
      out.print("<", label, ">")
    }
  }
  def signer {
    to __printOn(out) {
      out.print("<signing as ", label, ">")
    }
    to who() { return who }
    to run(what) {
      def ::"signed" implements SignedStamp {
        to _who() { return who }
        to _get() { return what }
      }
      return ::"signed"
    }
  }
  return signer
}

def verifyAndGet(::"signed" : ::"Signed") {
  return [::"signed"._get(), ::"signed"._who()]
}

# --- Operations ---

def ::"delegate"(scap, filter, note) {
  def [cert, signer, host] := scap
  def newSigner := makeSigner(note)
  return [signer(["delegate", cert, newSigner.who(), filter]), newSigner, host]
}

/** Turn an object whose methods take an extra argument for the delegation chain into a certificate. */
def exportOD(handler) {
  def rootSigner := makeSigner("export root")

  def handleMessage(delegators, verb :String, args :List, cert) {
    def [[=="delegate", prevCert, whoTo, filter], whoBy] := verifyAndGet(cert)
    if (!filter.contains(verb)) {
      throw(`$verb not permitted by $whoBy`)
    }
    
    def delegators1 := delegators.with(whoTo)
    return if (whoBy != rootSigner.who()) {
      handleMessage(delegators1, verb, args, prevCert)
    } else {
      E.call(handler, verb, [delegators1] + args)
    }
  }
  
  def host(verb, args, cert) {
    handleMessage([], verb, args, cert)
  }
  
  return [rootSigner(["delegate", Ref.broken("n/a"), rootSigner.who(), everything]), rootSigner, host]
}

/** Turn a scap into a normal invokable reference. */
def importOD(scap) {
  def [cert, signer, host] := scap
  return makeProxy(def handler {
    to handleSend(verb, args) {
      return host <- (verb, args, cert)
    }
    to handleSendOnly(verb, args) {
      return host <- (verb, args, cert)
    }
    to handleOptSealedDispatch(_) {}
  }, Ref.whenBroken(host, fn _ {Ref.optProblem(host)}), true)
}

# --- Example ---

def carol(x) {
  def xr := importOD(x)
  xr <- hello("world")
}

def bob(x) {
  def xr := importOD(x)
  when ( carol <- (::"delegate"(x, ["hello"].asSet(), "Carol")) ) -> {
    xr <- goodbye()
  }
}

def alice(x) {
  bob <- (::"delegate"(x, ["hello", "goodbye"].asSet(), "Bob"))
}


def root := exportOD(def root0 {
  to hello(chain, greeted) {
    println(chain, " greeted ", greeted)
  }
  to goodbye(chain) {
    println(chain, " said goodbye")
  }
})
alice(::"delegate"(root, ["hello", "goodbye"].asSet(), "Alice"))
Personal tools
more tools