blob: 36534989b169ee32037d20ed91a3faac358ae634 [file] [log] [blame]
package main
import (
"bytes"
"crypto/ecdsa"
"fmt"
"runtime/ppapi"
"syscall"
"veyron.io/veyron/veyron2/ipc"
"veyron.io/veyron/veyron2/options"
"veyron.io/veyron/veyron2/rt"
"veyron.io/veyron/veyron2/security"
"veyron.io/wspr/veyron/services/wsprd/wspr"
vsecurity "veyron.io/veyron/veyron/security"
// TODO(cnicolaou): shouldn't be depending on the runtime here.
_ "veyron.io/veyron/veyron/profiles"
_ "veyron.io/veyron/veyron/runtimes/google/security"
)
func main() {
ppapi.Init(newWsprInstance)
}
// WSPR instance represents an instance on a PPAPI client and receives callbacks from PPAPI to handle events.
type wsprInstance struct {
ppapi.Instance
}
var _ ppapi.InstanceHandlers = wsprInstance{}
func (inst wsprInstance) DidCreate(args map[string]string) bool {
fmt.Printf("Got to DidCreate")
return true
}
func (wsprInstance) DidDestroy() {
fmt.Printf("Got to DidDestroy()")
}
func (wsprInstance) DidChangeView(view ppapi.View) {
fmt.Printf("Got to DidChangeView(%v)", view)
}
func (wsprInstance) DidChangeFocus(has_focus bool) {
fmt.Printf("Got to DidChangeFocus(%v)", has_focus)
}
func (wsprInstance) HandleDocumentLoad(url_loader ppapi.Resource) bool {
fmt.Printf("Got to HandleDocumentLoad(%v)", url_loader)
return true
}
func (wsprInstance) HandleInputEvent(event ppapi.InputEvent) bool {
fmt.Printf("Got to HandleInputEvent(%v)", event)
return true
}
func (wsprInstance) Graphics3DContextLost() {
fmt.Printf("Got to Graphics3DContextLost()")
}
// StartWSPR handles starting WSPR.
func (wsprInstance) StartWSPR(message ppapi.Var) {
// HACK!!
// TODO(ataly, ashankar, bprosnitz): The private key should be
// generated/retrieved by directly talking to some secure storage
// in Chrome, e.g. LocalStorage (and not from the config as below).
pemKey, err := message.LookupStringValuedKey("pemPrivateKey")
if err != nil {
panic(err.Error())
}
// TODO(ataly, ashankr, bprosnitz): Figure out whether we need
// passphrase protection here (most likely we do but how do we
// request the passphrase from the user?)
key, err := vsecurity.LoadPEMKey(bytes.NewBufferString(pemKey), nil)
if err != nil {
panic(err.Error())
}
ecdsaKey, ok := key.(*ecdsa.PrivateKey)
if !ok {
panic(fmt.Errorf("got key of type %T, want *ecdsa.PrivateKey", key))
}
principal, err := vsecurity.NewPrincipalFromSigner(security.NewInMemoryECDSASigner(ecdsaKey))
if err != nil {
panic(err.Error())
}
defaultBlessingName, err := message.LookupStringValuedKey("defaultBlessingName")
if err != nil {
panic(err.Error())
}
if err := vsecurity.InitDefaultBlessings(principal, defaultBlessingName); err != nil {
panic(err.Error())
}
rt.Init(options.RuntimePrincipal{principal})
veyronProxy, err := message.LookupStringValuedKey("proxyName")
if err != nil {
panic(err.Error())
}
if veyronProxy == "" {
panic("Empty proxy")
}
mounttable, err := message.LookupStringValuedKey("namespaceRoot")
if err != nil {
panic(err.Error())
}
syscall.Setenv("MOUNTTABLE_ROOT", mounttable)
syscall.Setenv("NAMESPACE_ROOT", mounttable)
identd, err := message.LookupStringValuedKey("identityd")
if err != nil {
panic(err.Error())
}
wsprHttpPort, err := message.LookupIntValuedKey("wsprHttpPort")
if err != nil {
panic(err.Error())
}
// TODO(cnicolaou,bprosnitz) Should we use the roaming profile?
// It uses flags. We should change that.
listenSpec := ipc.ListenSpec{
Proxy: veyronProxy,
Protocol: "tcp",
Address: ":0",
}
fmt.Printf("Starting WSPR with config: proxy=%q mounttable=%q identityd=%q port=%d", veyronProxy, mounttable, identd, wsprHttpPort)
proxy := wspr.NewWSPR(wsprHttpPort, listenSpec, identd, options.RuntimePrincipal{principal})
proxy.Listen()
go func() {
proxy.Serve()
}()
}
// HandleMessage receives messages from Javascript and uses them to perform actions.
// A message is of the form {"type": "typeName", "body": { stuff here }},
// where the body is passed to the message handler.
func (inst wsprInstance) HandleMessage(message ppapi.Var) {
fmt.Printf("Entered HandleMessage")
type handlerType func(ppapi.Var)
handlerMap := map[string]handlerType{
"start": inst.StartWSPR,
}
ty, err := message.LookupStringValuedKey("type")
if err != nil {
panic(err.Error())
}
h, ok := handlerMap[ty]
if !ok {
panic(fmt.Sprintf("No handler found for message type: %q", ty))
}
body, err := message.LookupKey("body")
if err != nil {
body = ppapi.VarFromString("INVALID")
}
h(body)
body.Release()
}
func (wsprInstance) MouseLockLost() {
fmt.Printf("Got to MouseLockLost()")
}
func newWsprInstance(inst ppapi.Instance) ppapi.InstanceHandlers {
return wsprInstance{Instance: inst}
}