Root admin stuff

This commit is contained in:
Adam Ierymenko 2019-09-30 09:32:00 -07:00
commit b0d222768a
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
16 changed files with 217 additions and 46 deletions

View file

@ -356,6 +356,9 @@ func createAPIServer(basePath string, node *Node) (*http.Server, error) {
if queriedID == 0 {
apiSendObj(out, req, http.StatusBadRequest, nil)
} else {
var r Root
if apiReadObj(out, req, &r) == nil {
}
}
} else if req.Method == http.MethodGet || req.Method == http.MethodHead {
roots := node.Roots()

View file

@ -20,6 +20,7 @@ func (e Err) Error() string { return (string)(e) }
// Simple ZeroTier Errors
const (
ErrInternal Err = "internal error"
ErrNodeInitFailed Err = "unable to initialize core Node instance"
ErrInvalidMACAddress Err = "invalid MAC address"
ErrInvalidZeroTierAddress Err = "invalid ZeroTier address"
@ -28,5 +29,6 @@ const (
ErrTapInitFailed Err = "unable to create native Tap instance"
ErrUncrecognizedIdentityType Err = "unrecognized identity type"
ErrInvalidKey Err = "invalid key data"
ErrInvalidSignature Err = "invalid signature"
ErrSecretKeyRequired Err = "secret key required"
)

View file

@ -17,7 +17,10 @@ package zerotier
//#include "../../native/GoGlue.h"
import "C"
import "unsafe"
import (
"encoding/json"
"unsafe"
)
// LocatorDNSSigningKey is the public (as a secure DNS name) and private keys for entering locators into DNS
type LocatorDNSSigningKey struct {
@ -25,6 +28,20 @@ type LocatorDNSSigningKey struct {
PrivateKey []byte
}
// NewLocatorDNSSigningKey creates a new signing key and secure DNS name for storing locators in DNS
func NewLocatorDNSSigningKey() (*LocatorDNSSigningKey, error) {
var nameBuf [256]C.char
var keyBuf [64]byte
keySize := int(C.ZT_GoLocator_makeSecureDNSName(&nameBuf[0], 256, (*C.uint8_t)(unsafe.Pointer(&keyBuf[0])), 128))
if keySize <= 0 {
return nil, ErrInternal
}
var sk LocatorDNSSigningKey
sk.SecureDNSName = C.GoString(&nameBuf[0])
sk.PrivateKey = keyBuf[0:keySize]
return &sk, nil
}
// Locator is a binary serialized record containing information about where a ZeroTier node is located on the network
type Locator struct {
// Identity is the full identity of the node being located
@ -95,5 +112,62 @@ func NewLocator(id *Identity, virtualAddresses []*Identity, physicalAddresses []
}, nil
}
// NewLocatorFromBytes decodes a locator from its serialized byte array form
func NewLocatorFromBytes(b []byte) (*Locator, error) {
if len(b) == 0 {
return nil, ErrInvalidParameter
}
var info C.struct_ZT_GoLocator_Info
res := C.ZT_GoLocator_decodeLocator((*C.uint8_t)(unsafe.Pointer(&b[0])), C.uint(len(b)), &info)
if res == -2 {
return nil, ErrInvalidSignature
} else if res <= 0 {
return nil, ErrInvalidParameter
}
var loc Locator
var err error
loc.Identity, err = NewIdentityFromString(C.GoString(info.id))
if err != nil {
return nil, err
}
for i := 0; i < int(info.phyCount); i++ {
ua := sockaddrStorageToUDPAddr(&info.phy[i])
if ua != nil {
loc.Physical = append(loc.Physical, &InetAddress{IP: ua.IP, Port: ua.Port})
}
}
for i := 0; i < int(info.virtCount); i++ {
id, err := NewIdentityFromString(C.GoString(info.virt[i]))
if err == nil {
loc.Virtual = append(loc.Virtual, id)
}
}
return &loc, nil
}
// Bytes returns this locator in byte serialized format
func (l *Locator) Bytes() []byte { return l.bytes }
// MarshalJSON marshals this Locator as its byte encoding
func (l *Locator) MarshalJSON() ([]byte, error) {
b := l.bytes
return json.Marshal(&b)
}
// UnmarshalJSON unmarshals this Locator from a byte array in JSON.
func (l *Locator) UnmarshalJSON(j []byte) error {
var ba []byte
err := json.Unmarshal(j, &ba)
if err != nil {
return nil
}
tmp, err := NewLocatorFromBytes(ba)
if err != nil {
return err
}
*l = *tmp
return nil
}

View file

@ -558,7 +558,7 @@ func (n *Node) Roots() []*Root {
}
}
roots = append(roots, &Root{
DNSName: C.GoString(root.dnsName),
Name: C.GoString(root.dnsName),
Identity: id,
Addresses: addrs,
Preferred: (root.preferred != 0),
@ -571,6 +571,42 @@ func (n *Node) Roots() []*Root {
return roots
}
// SetRoot sets or updates a root.
// Name can be a DNS name (preferably secure) for DNS fetched locators or can be
// the empty string for static roots. If the name is empty then the locator must
// be non-nil.
func (n *Node) SetRoot(name string, locator *Locator) error {
if len(name) == 0 {
if locator == nil {
return ErrInvalidParameter
}
name = locator.Identity.address.String()
}
var lb []byte
if locator != nil {
lb = locator.Bytes()
}
var lbp unsafe.Pointer
if len(lb) > 0 {
lbp = unsafe.Pointer(&lb[0])
}
cn := C.CString(name)
defer C.free(unsafe.Pointer(cn))
if C.ZT_Node_setRoot(n.zn, cn, lbp, C.uint(len(lb))) != 0 {
return ErrInternal
}
return nil
}
// RemoveRoot removes a root.
// For static roots the name should be the ZeroTier address.
func (n *Node) RemoveRoot(name string) {
cn := C.CString(name)
defer C.free(unsafe.Pointer(cn))
C.ZT_Node_removeRoot(n.zn, cn)
return
}
// Peers retrieves a list of current peers
func (n *Node) Peers() []*Peer {
var peers []*Peer

View file

@ -15,16 +15,10 @@ package zerotier
// Root describes a root server used to find and establish communication with other nodes.
type Root struct {
DNSName string
Name string
Identity *Identity
Addresses []InetAddress
Locator Locator
Locator *Locator
Preferred bool
Online bool
}
// Static returns true if this is a static root
func (r *Root) Static() bool { return len(r.DNSName) == 0 }
// Dynamic returns true if this is a dynamic root
func (r *Root) Dynamic() bool { return len(r.DNSName) > 0 }

View file

@ -57,7 +57,7 @@ func (w *sizeLimitWriter) trim(maxSize int, trimFactor float64, trimAtCR bool) e
if flen > int64(maxSize) {
var buf [131072]byte
trimAt := int64(float64(flen) * trimFactor)
trimAt := int64(float64(maxSize) * trimFactor)
if trimAt >= flen { // sanity check
return nil
}