all ads now properly validated before storing
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/indra-labs/indra/pkg/ad"
|
||||
"github.com/indra-labs/indra/pkg/onions/adload"
|
||||
"github.com/indra-labs/indra/pkg/util/slice"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
@@ -67,61 +68,67 @@ func (ng *Engine) HandleAd(p *pubsub.Message, ctx context.Context) (e error) {
|
||||
if e = c.Decode(s); fails(e) {
|
||||
return
|
||||
}
|
||||
var ok bool
|
||||
switch c.(type) {
|
||||
case *adaddress.Ad:
|
||||
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
|
||||
if addr, ok := c.(*adaddress.Ad); !ok {
|
||||
var addr *adaddress.Ad
|
||||
if addr, ok = c.(*adaddress.Ad); !ok {
|
||||
return fmt.Errorf(ErrWrongTypeDecode,
|
||||
adaddress.Magic, reflect.TypeOf(c).String())
|
||||
} else {
|
||||
// If we got to here now we can add to the PeerStore.
|
||||
log.D.S("new ad for address:", c)
|
||||
var id peer.ID
|
||||
if id, e = peer.IDFromPublicKey(addr.Key); fails(e) {
|
||||
return
|
||||
}
|
||||
if e = ng.Listener.Host.
|
||||
Peerstore().Put(id, "services", s.GetAll().ToBytes()); fails(e) {
|
||||
return
|
||||
}
|
||||
} else if !addr.Validate() {
|
||||
return errors.New("addr ad failed validation")
|
||||
}
|
||||
// If we got to here now we can add to the PeerStore.
|
||||
log.D.S("new ad for address:", c)
|
||||
var id peer.ID
|
||||
if id, e = peer.IDFromPublicKey(addr.Key); fails(e) {
|
||||
return
|
||||
}
|
||||
if e = ng.Listener.Host.
|
||||
Peerstore().Put(id, "services", s.GetAll().ToBytes()); fails(e) {
|
||||
return
|
||||
}
|
||||
case *adintro.Ad:
|
||||
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
|
||||
if intr, ok := c.(*adintro.Ad); !ok {
|
||||
var intr *adintro.Ad
|
||||
if intr, ok = c.(*adintro.Ad); !ok {
|
||||
return fmt.Errorf(ErrWrongTypeDecode,
|
||||
adintro.Magic, reflect.TypeOf(c).String())
|
||||
} else {
|
||||
// If we got to here now we can add to the PeerStore.
|
||||
log.D.S("new ad for intro:", c)
|
||||
var id peer.ID
|
||||
if id, e = peer.IDFromPublicKey(intr.Key); fails(e) {
|
||||
return
|
||||
}
|
||||
if e = ng.Listener.Host.
|
||||
Peerstore().Put(id, "services", s.GetAll().ToBytes()); fails(e) {
|
||||
return
|
||||
}
|
||||
} else if !intr.Validate() {
|
||||
return errors.New("intro ad failed validation")
|
||||
}
|
||||
// If we got to here now we can add to the PeerStore.
|
||||
log.D.S("new ad for intro:", c)
|
||||
var id peer.ID
|
||||
if id, e = peer.IDFromPublicKey(intr.Key); fails(e) {
|
||||
return
|
||||
}
|
||||
if e = ng.Listener.Host.
|
||||
Peerstore().Put(id, "services", s.GetAll().ToBytes()); fails(e) {
|
||||
return
|
||||
}
|
||||
case *adload.Ad:
|
||||
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
|
||||
if lod, ok := c.(*adload.Ad); !ok {
|
||||
var lod *adload.Ad
|
||||
if lod, ok = c.(*adload.Ad); !ok {
|
||||
return fmt.Errorf(ErrWrongTypeDecode,
|
||||
adaddress.Magic, reflect.TypeOf(c).String())
|
||||
} else {
|
||||
// If we got to here now we can add to the PeerStore.
|
||||
log.D.S("new ad for load:", c)
|
||||
var id peer.ID
|
||||
if id, e = peer.IDFromPublicKey(lod.Key); fails(e) {
|
||||
return
|
||||
}
|
||||
if e = ng.Listener.Host.
|
||||
Peerstore().Put(id, "services", s.GetAll().ToBytes()); fails(e) {
|
||||
return
|
||||
}
|
||||
} else if !lod.Validate() {
|
||||
return errors.New("load ad failed validation")
|
||||
}
|
||||
// If we got to here now we can add to the PeerStore.
|
||||
log.D.S("new ad for load:", c)
|
||||
var id peer.ID
|
||||
if id, e = peer.IDFromPublicKey(lod.Key); fails(e) {
|
||||
return
|
||||
}
|
||||
if e = ng.Listener.Host.
|
||||
Peerstore().Put(id, "services", s.GetAll().ToBytes()); fails(e) {
|
||||
return
|
||||
}
|
||||
case *adpeer.Ad:
|
||||
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
|
||||
var ok bool
|
||||
var pa *adpeer.Ad
|
||||
if pa, ok = c.(*adpeer.Ad); !ok {
|
||||
return fmt.Errorf(ErrWrongTypeDecode,
|
||||
@@ -141,21 +148,61 @@ func (ng *Engine) HandleAd(p *pubsub.Message, ctx context.Context) (e error) {
|
||||
}
|
||||
case *adservices.Ad:
|
||||
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
|
||||
if serv, ok := c.(*adservices.Ad); !ok {
|
||||
var sa *adservices.Ad
|
||||
if sa, ok = c.(*adservices.Ad); !ok {
|
||||
return fmt.Errorf(ErrWrongTypeDecode,
|
||||
adservices.Magic, reflect.TypeOf(c).String())
|
||||
} else {
|
||||
// If we got to here now we can add to the PeerStore.
|
||||
log.D.S("new ad for services:", c)
|
||||
var id peer.ID
|
||||
if id, e = peer.IDFromPublicKey(serv.Key); fails(e) {
|
||||
return
|
||||
}
|
||||
if e = ng.Listener.Host.
|
||||
Peerstore().Put(id, "services", s.GetAll().ToBytes()); fails(e) {
|
||||
return
|
||||
}
|
||||
} else if !sa.Validate() {
|
||||
return errors.New("services ad failed validation")
|
||||
}
|
||||
// If we got to here now we can add to the PeerStore.
|
||||
log.D.S("new ad for services:", c)
|
||||
var id peer.ID
|
||||
if id, e = peer.IDFromPublicKey(sa.Key); fails(e) {
|
||||
return
|
||||
}
|
||||
if e = ng.Listener.Host.
|
||||
Peerstore().Put(id, "services", s.GetAll().ToBytes()); fails(e) {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ng *Engine) GetPeerRecord(id peer.ID, key string) (add ad.Ad, e error) {
|
||||
var a interface{}
|
||||
if a, e = ng.Listener.Host.Peerstore().Get(id, key); fails(e) {
|
||||
return
|
||||
}
|
||||
|
||||
var ok bool
|
||||
var adb slice.Bytes
|
||||
if adb, ok = a.(slice.Bytes); !ok {
|
||||
e = errors.New("peer record did not decode slice.Bytes")
|
||||
return
|
||||
}
|
||||
s := splice.NewFrom(adb)
|
||||
c := reg.Recognise(s)
|
||||
if c == nil {
|
||||
e = errors.New("message not recognised")
|
||||
return
|
||||
}
|
||||
if e = c.Decode(s); fails(e) {
|
||||
return
|
||||
}
|
||||
if add, ok = c.(ad.Ad); !ok {
|
||||
e = errors.New("peer record did not decode as Ad")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ng *Engine) ClearPeerRecord(id peer.ID, key string) (add ad.Ad, e error) {
|
||||
if _, e = ng.Listener.Host.Peerstore().Get(id, key); fails(e) {
|
||||
return
|
||||
}
|
||||
if e = ng.Listener.Host.
|
||||
Peerstore().Put(id, key, []byte{}); fails(e) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -87,11 +87,11 @@ func (x *Ad) Len() int { return Len }
|
||||
func (x *Ad) Magic() string { return Magic }
|
||||
|
||||
func (x *Ad) Splice(s *splice.Splice) {
|
||||
x.SpliceWithoutSig(s)
|
||||
x.SpliceNoSig(s)
|
||||
s.Signature(x.Sig)
|
||||
}
|
||||
|
||||
func (x *Ad) SpliceWithoutSig(s *splice.Splice) {
|
||||
func (x *Ad) SpliceNoSig(s *splice.Splice) {
|
||||
var e error
|
||||
var ap netip.AddrPort
|
||||
if ap, e = multi.AddrToAddrPort(x.Addr); fails(e) {
|
||||
@@ -107,13 +107,13 @@ func (x *Ad) SpliceWithoutSig(s *splice.Splice) {
|
||||
|
||||
func (x *Ad) Validate() bool {
|
||||
s := splice.New(Len - magic.Len)
|
||||
x.SpliceWithoutSig(s)
|
||||
x.SpliceNoSig(s)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
key, e := x.Sig.Recover(hash)
|
||||
if fails(e) {
|
||||
return false
|
||||
}
|
||||
if key.Equals(x.Key) {
|
||||
if key.Equals(x.Key) && x.Expiry.After(time.Now()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -133,7 +133,7 @@ func New(id nonce.ID, key *crypto.Prv,
|
||||
Addr: ma,
|
||||
}
|
||||
s := splice.New(Len)
|
||||
peerAd.SpliceWithoutSig(s)
|
||||
peerAd.SpliceNoSig(s)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
var e error
|
||||
if peerAd.Sig, e = crypto.Sign(key, hash); fails(e) {
|
||||
|
||||
@@ -125,25 +125,24 @@ func New(
|
||||
) (in *Ad) {
|
||||
|
||||
pk := crypto.DerivePub(key)
|
||||
s := splice.New(Len)
|
||||
IntroSplice(s, id, pk, ap, relayRate, port, expires)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
var e error
|
||||
var sign crypto.SigBytes
|
||||
if sign, e = crypto.Sign(key, hash); fails(e) {
|
||||
return nil
|
||||
}
|
||||
|
||||
in = &Ad{
|
||||
Ad: adproto.Ad{
|
||||
ID: id,
|
||||
Key: pk,
|
||||
Expiry: time.Now().Add(adproto.TTL),
|
||||
Sig: sign,
|
||||
Expiry: expires,
|
||||
},
|
||||
AddrPort: ap,
|
||||
RelayRate: relayRate,
|
||||
Port: port,
|
||||
}
|
||||
s := splice.New(in.Len())
|
||||
in.SpliceNoSig(s)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
var e error
|
||||
if in.Sig, e = crypto.Sign(key, hash); fails(e) {
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/indra-labs/indra/pkg/engine/coding"
|
||||
"github.com/indra-labs/indra/pkg/engine/magic"
|
||||
"github.com/indra-labs/indra/pkg/engine/sess"
|
||||
"github.com/indra-labs/indra/pkg/onions/adintro"
|
||||
"github.com/indra-labs/indra/pkg/onions/adproto"
|
||||
"github.com/indra-labs/indra/pkg/onions/reg"
|
||||
log2 "github.com/indra-labs/indra/pkg/proc/log"
|
||||
@@ -24,7 +23,7 @@ var (
|
||||
|
||||
const (
|
||||
Magic = "load"
|
||||
Len = adproto.Len +1
|
||||
Len = adproto.Len + 1
|
||||
)
|
||||
|
||||
// Ad stores a specification for the fee rate and existence of a peer.
|
||||
@@ -39,24 +38,22 @@ var _ coding.Codec = &Ad{}
|
||||
func New(id nonce.ID, key *crypto.Prv, load byte,
|
||||
expiry time.Time) (sv *Ad) {
|
||||
|
||||
s := splice.New(adintro.Len)
|
||||
k := crypto.DerivePub(key)
|
||||
Splice(s, id, k, load, expiry)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
var e error
|
||||
var sign crypto.SigBytes
|
||||
if sign, e = crypto.Sign(key, hash); fails(e) {
|
||||
return nil
|
||||
}
|
||||
sv = &Ad{
|
||||
Ad: adproto.Ad{
|
||||
ID: id,
|
||||
Key: k,
|
||||
Expiry: time.Now().Add(adproto.TTL),
|
||||
Sig: sign,
|
||||
Expiry: expiry,
|
||||
},
|
||||
Load: load,
|
||||
}
|
||||
s := splice.New(sv.Len())
|
||||
sv.SpliceNoSig(s)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
var e error
|
||||
if sv.Sig, e = crypto.Sign(key, hash); fails(e) {
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -83,17 +80,6 @@ func (x *Ad) Len() int { return Len }
|
||||
|
||||
func (x *Ad) Magic() string { return "" }
|
||||
|
||||
func (x *Ad) Sign(prv *crypto.Prv) (e error) {
|
||||
s := splice.New(x.Len())
|
||||
x.SpliceNoSig(s)
|
||||
var b crypto.SigBytes
|
||||
if b, e = crypto.Sign(prv, sha256.Single(s.GetUntil(s.GetCursor()))); fails(e) {
|
||||
return
|
||||
}
|
||||
copy(x.Sig[:], b[:])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Ad) Splice(s *splice.Splice) {
|
||||
x.SpliceNoSig(s)
|
||||
s.Signature(x.Sig)
|
||||
@@ -104,14 +90,14 @@ func (x *Ad) SpliceNoSig(s *splice.Splice) {
|
||||
}
|
||||
|
||||
func (x *Ad) Validate() (valid bool) {
|
||||
s := splice.New(adintro.Len - magic.Len)
|
||||
s := splice.New(x.Len() - magic.Len)
|
||||
x.SpliceNoSig(s)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
key, e := x.Sig.Recover(hash)
|
||||
if fails(e) {
|
||||
return false
|
||||
}
|
||||
if key.Equals(x.Key) {
|
||||
if key.Equals(x.Key) && x.Expiry.After(time.Now()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -76,11 +76,11 @@ func (x *Ad) Len() int { return Len }
|
||||
func (x *Ad) Magic() string { return Magic }
|
||||
|
||||
func (x *Ad) Splice(s *splice.Splice) {
|
||||
x.SpliceWithoutSig(s)
|
||||
x.SpliceNoSig(s)
|
||||
s.Signature(x.Sig)
|
||||
}
|
||||
|
||||
func (x *Ad) SpliceWithoutSig(s *splice.Splice) {
|
||||
func (x *Ad) SpliceNoSig(s *splice.Splice) {
|
||||
s.Magic(Magic).
|
||||
ID(x.ID).
|
||||
Pubkey(x.Key).
|
||||
@@ -89,7 +89,7 @@ func (x *Ad) SpliceWithoutSig(s *splice.Splice) {
|
||||
|
||||
func (x *Ad) Validate() bool {
|
||||
s := splice.New(Len)
|
||||
x.SpliceWithoutSig(s)
|
||||
x.SpliceNoSig(s)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
key, e := x.Sig.Recover(hash)
|
||||
if fails(e) {
|
||||
@@ -111,7 +111,7 @@ func New(id nonce.ID, key *crypto.Prv,
|
||||
Expiry: expiry,
|
||||
}
|
||||
s := splice.New(Len - magic.Len)
|
||||
protoAd.SpliceWithoutSig(s)
|
||||
protoAd.SpliceNoSig(s)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
var e error
|
||||
if protoAd.Sig, e = crypto.Sign(key, hash); fails(e) {
|
||||
|
||||
@@ -49,24 +49,22 @@ var _ coding.Codec = &Ad{}
|
||||
func New(id nonce.ID, key *crypto.Prv, services []Service,
|
||||
expiry time.Time) (sv *Ad) {
|
||||
|
||||
s := splice.New(adintro.Len)
|
||||
k := crypto.DerivePub(key)
|
||||
ServiceSplice(s, id, k, services, expiry)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
var e error
|
||||
var sign crypto.SigBytes
|
||||
if sign, e = crypto.Sign(key, hash); fails(e) {
|
||||
return nil
|
||||
}
|
||||
sv = &Ad{
|
||||
Ad: adproto.Ad{
|
||||
ID: id,
|
||||
Key: k,
|
||||
Expiry: time.Now().Add(adproto.TTL),
|
||||
Sig: sign,
|
||||
},
|
||||
Services: services,
|
||||
}
|
||||
s := splice.New(adintro.Len)
|
||||
sv.SpliceNoSig(s)
|
||||
hash := sha256.Single(s.GetUntil(s.GetCursor()))
|
||||
var e error
|
||||
if sv.Sig, e = crypto.Sign(key, hash); fails(e) {
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user