mobile_nebula/nebula/site.go

131 lines
3.5 KiB
Go

package mobileNebula
import (
"time"
"github.com/DefinedNet/dnapi"
"github.com/slackhq/nebula/cert"
"gopkg.in/yaml.v2"
)
// Site represents an IncomingSite in Kotlin/Swift.
type site struct {
Name string `json:"name"`
ID string `json:"id"`
StaticHostmap map[string]staticHost `json:"staticHostmap"`
UnsafeRoutes *[]unsafeRoute `json:"unsafeRoutes"`
Cert string `json:"cert"`
CA string `json:"ca"`
LHDuration int `json:"lhDuration"`
Port int `json:"port"`
MTU *int `json:"mtu"`
Cipher string `json:"cipher"`
SortKey *int `json:"sortKey"`
LogVerbosity *string `json:"logVerbosity"`
Key *string `json:"key"`
Managed jsonTrue `json:"managed"`
LastManagedUpdate *time.Time `json:"lastManagedUpdate"`
RawConfig *string `json:"rawConfig"`
DNCredentials *dnCredentials `json:"dnCredentials"`
}
type staticHost struct {
Lighthouse bool `json:"lighthouse"`
Destinations []string `json:"destinations"`
}
type unsafeRoute struct {
Route string `json:"route"`
Via string `json:"via"`
MTU *int `json:"mtu"`
}
type dnCredentials struct {
HostID string `json:"hostID"`
PrivateKey string `json:"privateKey"`
Counter int `json:"counter"`
TrustedKeys string `json:"trustedKeys"`
}
// jsonTrue always marshals to true.
type jsonTrue bool
func (f jsonTrue) MarshalJSON() ([]byte, error) {
return []byte(`true`), nil
}
func newDNSite(name string, rawCfg []byte, key string, creds dnapi.Credentials) (*site, error) {
// Convert YAML Nebula config to a JSON Site
var cfg config
if err := yaml.Unmarshal(rawCfg, &cfg); err != nil {
return nil, err
}
strCfg := string(rawCfg)
// build static hostmap
shm := map[string]staticHost{}
for vpnIP, remoteIPs := range cfg.StaticHostmap {
sh := staticHost{Destinations: remoteIPs}
shm[vpnIP] = sh
}
for _, vpnIP := range cfg.Lighthouse.Hosts {
if sh, ok := shm[vpnIP]; ok {
sh.Lighthouse = true
shm[vpnIP] = sh
} else {
shm[vpnIP] = staticHost{Lighthouse: true}
}
}
// build unsafe routes
ur := []unsafeRoute{}
for _, canon := range cfg.Tun.UnsafeRoutes {
ur = append(ur, unsafeRoute{
Route: canon.Route,
Via: canon.Via,
MTU: canon.MTU,
})
}
// log verbosity is nullable
var logVerb *string
if cfg.Logging.Level != "" {
v := cfg.Logging.Level
logVerb = &v
}
// TODO the mobile app requires an explicit cipher or it will display an error
cipher := cfg.Cipher
if cipher == "" {
cipher = "aes"
}
now := time.Now()
return &site{
Name: name,
ID: creds.HostID,
StaticHostmap: shm,
UnsafeRoutes: &ur,
Cert: cfg.PKI.Cert,
CA: cfg.PKI.CA,
LHDuration: cfg.Lighthouse.Interval,
Port: cfg.Listen.Port,
MTU: cfg.Tun.MTU,
Cipher: cipher,
SortKey: nil,
LogVerbosity: logVerb,
Key: &key,
Managed: true,
LastManagedUpdate: &now,
RawConfig: &strCfg,
DNCredentials: &dnCredentials{
HostID: creds.HostID,
PrivateKey: string(cert.MarshalEd25519PrivateKey(creds.PrivateKey)),
Counter: int(creds.Counter),
TrustedKeys: string(dnapi.Ed25519PublicKeysToPEM(creds.TrustedKeys)),
},
}, nil
}