Merge "veyron/services/security/simpledischarged/"
diff --git a/services/security/simpledischarged/main.go b/services/security/simpledischarged/main.go
new file mode 100644
index 0000000..8f6429a
--- /dev/null
+++ b/services/security/simpledischarged/main.go
@@ -0,0 +1,85 @@
+package main
+
+import (
+ "errors"
+ "log"
+ "fmt"
+ "time"
+ "flag"
+
+ "veyron/lib/signals"
+ isecurity "veyron/services/security"
+ "veyron2/ipc"
+ "veyron2/rt"
+ "veyron2/security"
+ "veyron2/vdl"
+)
+
+// TODO(ataly, andreser): ideally, the expiration time (and other caveats) of
+// the discharge would be determined by a function much like ThirdPartyCaveat.Validate
+var expiration = flag.String("expiration", "10s", "time interval after which a discharge will expire")
+var protocol = flag.String("protocol", "bluetooth", "protocol to listen on")
+var address = flag.String("address", "", "address to listen on")
+var port = flag.Int("port", 0, "port to listen on")
+var publish = flag.String("publish", "", "the namespace where to publish this service")
+
+type dischargeAuthorizer struct{}
+func (dischargeAuthorizer) Authorize(c security.Context) error {
+ if c.Method() == "Discharge" {
+ return nil
+ }
+ return fmt.Errorf("Only authorized for method \"Discharge\"")
+}
+
+// discharged implements ipc.Dispatcher. It issues discharges for all caveats
+// present in the current namespace with no additional caveats iff the caveat
+// is valid.
+type discharged struct {
+ id security.PrivateID
+ expiration time.Duration
+}
+
+func (d *discharged) Discharge(ctx ipc.ServerContext, Caveat vdl.Any) (
+ Discharge vdl.Any, err error) {
+ caveat, ok := Caveat.(security.ThirdPartyCaveat)
+ if !ok {
+ err = errors.New("unknown caveat")
+ return
+ }
+ return d.id.MintDischarge(caveat, ctx, d.expiration, nil)
+}
+
+func main() {
+ flag.Parse()
+ expiration, err := time.ParseDuration(*expiration)
+ if err != nil {
+ log.Fatalf("--expiration: ", err)
+ }
+
+ r := rt.Init()
+ server, err := r.NewServer()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ discharger := isecurity.NewServerDischarger(&discharged{
+ id: r.Identity(), expiration: expiration})
+ err = server.Register("discharged", ipc.SoloDispatcher(discharger, dischargeAuthorizer{}))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ endpoint, err := server.Listen(*protocol, *address+":"+fmt.Sprint(*port))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ if *publish != "" {
+ if err := server.Publish(*publish); err != nil {
+ log.Fatal(err)
+ }
+ }
+
+ fmt.Println(endpoint)
+ <-signals.ShutdownOnSignals()
+}