core: Load identity from config

Also, slightly refactor Ricochet to be an interface to get the various
top-level components, and let the implementation define it (such as
backend's RicochetCore RPC type)
This commit is contained in:
John Brooks 2016-08-29 19:49:30 -06:00
parent ca3c672975
commit b74073fd09
5 changed files with 84 additions and 49 deletions

View File

@ -23,12 +23,16 @@ func main() {
log.Fatalf("config error: %v", err) log.Fatalf("config error: %v", err)
} }
ricochet := &RicochetCore{ core := &RicochetCore{
Network: ricochet.CreateNetwork(), config: config,
Config: config, }
core.network = ricochet.CreateNetwork()
core.identity, err = ricochet.CreateIdentity(core)
if err != nil {
log.Fatalf("identity error: %v", err)
} }
rpcServer := grpc.NewServer() rpcServer := grpc.NewServer()
rpc.RegisterRicochetCoreServer(rpcServer, ricochet) rpc.RegisterRicochetCoreServer(rpcServer, core)
rpcServer.Serve(listener) rpcServer.Serve(listener)
} }

View File

@ -8,12 +8,25 @@ import (
"log" "log"
) )
var NotImplementedError error = errors.New("Not implemented")
type RicochetCore struct { type RicochetCore struct {
Network *ricochet.Network config *ricochet.Config
Config *ricochet.Config network *ricochet.Network
identity *ricochet.Identity
} }
var NotImplementedError error = errors.New("Not implemented") func (core *RicochetCore) Config() *ricochet.Config {
return core.config
}
func (core *RicochetCore) Network() *ricochet.Network {
return core.network
}
func (core *RicochetCore) Identity() *ricochet.Identity {
return core.identity
}
func (core *RicochetCore) GetServerStatus(ctx context.Context, req *rpc.ServerStatusRequest) (*rpc.ServerStatusReply, error) { func (core *RicochetCore) GetServerStatus(ctx context.Context, req *rpc.ServerStatusRequest) (*rpc.ServerStatusReply, error) {
if req.RpcVersion != 1 { if req.RpcVersion != 1 {
@ -27,12 +40,12 @@ func (core *RicochetCore) GetServerStatus(ctx context.Context, req *rpc.ServerSt
} }
func (core *RicochetCore) MonitorNetwork(req *rpc.MonitorNetworkRequest, stream rpc.RicochetCore_MonitorNetworkServer) error { func (core *RicochetCore) MonitorNetwork(req *rpc.MonitorNetworkRequest, stream rpc.RicochetCore_MonitorNetworkServer) error {
events := core.Network.EventMonitor().Subscribe(20) events := core.Network().EventMonitor().Subscribe(20)
defer core.Network.EventMonitor().Unsubscribe(events) defer core.Network().EventMonitor().Unsubscribe(events)
// Send initial status event // Send initial status event
{ {
event := core.Network.GetStatus() event := core.Network().GetStatus()
if err := stream.Send(&event); err != nil { if err := stream.Send(&event); err != nil {
return err return err
} }
@ -56,23 +69,26 @@ func (core *RicochetCore) MonitorNetwork(req *rpc.MonitorNetworkRequest, stream
func (core *RicochetCore) StartNetwork(ctx context.Context, req *rpc.StartNetworkRequest) (*rpc.NetworkStatus, error) { func (core *RicochetCore) StartNetwork(ctx context.Context, req *rpc.StartNetworkRequest) (*rpc.NetworkStatus, error) {
// err represents the result of the first connection attempt, but as long // err represents the result of the first connection attempt, but as long
// as 'ok' is true, the network has started and this call was successful. // as 'ok' is true, the network has started and this call was successful.
ok, err := core.Network.Start("tcp://127.0.0.1:9051", "") ok, err := core.Network().Start("tcp://127.0.0.1:9051", "")
if !ok { if !ok {
return nil, err return nil, err
} }
status := core.Network.GetStatus() status := core.Network().GetStatus()
return &status, nil return &status, nil
} }
func (core *RicochetCore) StopNetwork(ctx context.Context, req *rpc.StopNetworkRequest) (*rpc.NetworkStatus, error) { func (core *RicochetCore) StopNetwork(ctx context.Context, req *rpc.StopNetworkRequest) (*rpc.NetworkStatus, error) {
core.Network.Stop() core.Network().Stop()
status := core.Network.GetStatus() status := core.Network().GetStatus()
return &status, nil return &status, nil
} }
func (core *RicochetCore) GetIdentity(ctx context.Context, req *rpc.IdentityRequest) (*rpc.Identity, error) { func (core *RicochetCore) GetIdentity(ctx context.Context, req *rpc.IdentityRequest) (*rpc.Identity, error) {
return nil, NotImplementedError reply := rpc.Identity{
Address: core.Identity().Address(),
}
return &reply, nil
} }
func (core *RicochetCore) MonitorContacts(req *rpc.MonitorContactsRequest, stream rpc.RicochetCore_MonitorContactsServer) error { func (core *RicochetCore) MonitorContacts(req *rpc.MonitorContactsRequest, stream rpc.RicochetCore_MonitorContactsServer) error {

View File

@ -88,6 +88,13 @@ func main() {
log.Fatalf("could not get status: %v", err) log.Fatalf("could not get status: %v", err)
} }
log.Printf("get status result: %v", r) log.Printf("get status result: %v", r)
identity, err := c.Backend.GetIdentity(context.Background(), &rpc.IdentityRequest{})
if err != nil {
log.Fatalf("could not get identity: %v", err)
}
log.Printf("identity: %v", identity)
case "connect": case "connect":
status, err := c.Backend.StartNetwork(context.Background(), &rpc.StartNetworkRequest{}) status, err := c.Backend.StartNetwork(context.Background(), &rpc.StartNetworkRequest{})
if err != nil { if err != nil {

View File

@ -1,29 +1,50 @@
package core package core
type Identity struct { import (
internalId int "crypto/rsa"
"encoding/base64"
"errors"
"github.com/yawning/bulb/utils/pkcs1"
"log"
)
name string type Identity struct {
address string address string
privateKey *rsa.PrivateKey
contactList *ContactList contactList *ContactList
} }
func CreateIdentity(id int, name string) *Identity { func CreateIdentity(core Ricochet) (*Identity, error) {
me := &Identity{ me := &Identity{}
internalId: id,
name: name, config := core.Config().OpenRead()
contactList: &ContactList{}, defer config.Close()
if config.Identity.ServiceKey != "" {
keyData, err := base64.StdEncoding.DecodeString(config.Identity.ServiceKey)
if err != nil {
log.Printf("Decoding identity key failed: %v", err)
return nil, err
}
me.privateKey, _, err = pkcs1.DecodePrivateKeyDER(keyData)
if err != nil {
log.Printf("Decoding identity key failed: %v", err)
return nil, err
}
me.address, err = pkcs1.OnionAddr(&me.privateKey.PublicKey)
if err != nil && me.address == "" {
err = errors.New("Cannot calculate onion address")
}
if err != nil {
log.Printf("Decoding identify key failed: %v", err)
return nil, err
}
me.address = "ricochet:" + me.address
} }
return me
}
func (me *Identity) InternalId() int { return me, nil
return me.internalId
}
func (me *Identity) Name() string {
return me.name
} }
func (me *Identity) Address() string { func (me *Identity) Address() string {

View File

@ -1,20 +1,7 @@
package core package core
type Ricochet struct { type Ricochet interface {
Network *Network Config() *Config
Identity *Identity Network() *Network
Config *Config Identity() *Identity
}
func Initialize(configPath string) (*Ricochet, error) {
cfg, err := LoadConfig(configPath)
if err != nil {
return nil, err
}
ricochet := &Ricochet{
Config: cfg,
}
return ricochet, nil
} }