5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-12-01 19:41:35 +00:00

Merge branch 'develop' into nodeconfig

This commit is contained in:
Neil Alexander 2019-01-15 08:37:10 +00:00
commit 3bf53796a7
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944
4 changed files with 128 additions and 5 deletions

123
contrib/ansible/genkeys.go Normal file
View File

@ -0,0 +1,123 @@
/*
This file generates crypto keys for [ansible-yggdrasil](https://github.com/jcgruenhage/ansible-yggdrasil/)
*/
package main
import (
"encoding/hex"
"flag"
"fmt"
"net"
"os"
"github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
)
var numHosts = flag.Int("hosts", 1, "number of host vars to generate")
var keyTries = flag.Int("tries", 1000, "number of tries before taking the best keys")
type keySet struct {
priv []byte
pub []byte
id []byte
ip string
}
func main() {
flag.Parse()
if *numHosts > *keyTries {
println("Can't generate less keys than hosts.")
return
}
var encryptionKeys []keySet
for i := 0; i < *numHosts + 1; i++ {
encryptionKeys = append(encryptionKeys, newBoxKey())
}
encryptionKeys = sortKeySetArray(encryptionKeys)
for i := 0; i < *keyTries - *numHosts - 1; i++ {
encryptionKeys[0] = newBoxKey();
encryptionKeys = bubbleUpTo(encryptionKeys, 0)
}
var signatureKeys []keySet
for i := 0; i < *numHosts + 1; i++ {
signatureKeys = append(signatureKeys, newSigKey())
}
signatureKeys = sortKeySetArray(signatureKeys)
for i := 0; i < *keyTries - *numHosts - 1; i++ {
signatureKeys[0] = newSigKey();
signatureKeys = bubbleUpTo(signatureKeys, 0)
}
os.MkdirAll("ansible/host_vars", 0755)
for i := 1; i <= *numHosts; i++ {
os.MkdirAll(fmt.Sprintf("ansible/host_vars/%x", i), 0755)
file, err := os.Create(fmt.Sprintf("ansible/host_vars/%x/vars", i))
if err != nil {
return
}
defer file.Close()
file.WriteString(fmt.Sprintf("yggdrasil_encryption_public_key: %v\n", hex.EncodeToString(encryptionKeys[i].pub)))
file.WriteString("yggdrasil_encryption_private_key: \"{{ vault_yggdrasil_encryption_private_key }}\"\n")
file.WriteString(fmt.Sprintf("yggdrasil_signing_public_key: %v\n", hex.EncodeToString(signatureKeys[i].pub)))
file.WriteString("yggdrasil_signing_public_key: \"{{ vault_yggdrasil_signing_private_key }}\"\n")
file.WriteString(fmt.Sprintf("ansible_host: %v\n", encryptionKeys[i].ip))
file, err = os.Create(fmt.Sprintf("ansible/host_vars/%x/vault", i))
if err != nil {
return
}
defer file.Close()
file.WriteString(fmt.Sprintf("vault_yggdrasil_encryption_private_key: %v\n", hex.EncodeToString(encryptionKeys[i].priv)))
file.WriteString(fmt.Sprintf("vault_yggdrasil_signing_private_key: %v\n", hex.EncodeToString(signatureKeys[i].priv)))
}
}
func newBoxKey() keySet {
pub, priv := crypto.NewBoxKeys()
id := crypto.GetNodeID(pub)
ip := net.IP(address.AddrForNodeID(id)[:]).String()
return keySet{priv[:], pub[:], id[:], ip}
}
func newSigKey() keySet {
pub, priv := crypto.NewSigKeys()
id := crypto.GetTreeID(pub)
return keySet{priv[:], pub[:], id[:], ""}
}
func isBetter(oldID, newID []byte) bool {
for idx := range oldID {
if newID[idx] > oldID[idx] {
return true
}
if newID[idx] < oldID[idx] {
return false
}
}
return false
}
func sortKeySetArray(sets []keySet) []keySet {
for i := 0; i < len(sets); i++ {
sets = bubbleUpTo(sets, i)
}
return sets
}
func bubbleUpTo(sets []keySet, num int) []keySet {
for i := 0; i < len(sets) - num - 1; i++ {
if isBetter(sets[i + 1].id, sets[i].id) {
var tmp = sets[i]
sets[i] = sets[i + 1]
sets[i + 1] = tmp
}
}
return sets
}

View File

@ -14,7 +14,7 @@ import (
) )
// The peers struct represents peers with an active connection. // The peers struct represents peers with an active connection.
// Incomping packets are passed to the corresponding peer, which handles them somehow. // Incoming packets are passed to the corresponding peer, which handles them somehow.
// In most cases, this involves passing the packet to the handler for outgoing traffic to another peer. // In most cases, this involves passing the packet to the handler for outgoing traffic to another peer.
// In other cases, it's link protocol traffic used to build the spanning tree, in which case this checks signatures and passes the message along to the switch. // In other cases, it's link protocol traffic used to build the spanning tree, in which case this checks signatures and passes the message along to the switch.
type peers struct { type peers struct {
@ -107,7 +107,7 @@ type peer struct {
close func() // Called when a peer is removed, to close the underlying connection, or via admin api close func() // Called when a peer is removed, to close the underlying connection, or via admin api
} }
// Creates a new peer with the specified box, sig, and linkShared keys, using the lowest unocupied port number. // Creates a new peer with the specified box, sig, and linkShared keys, using the lowest unoccupied port number.
func (ps *peers) newPeer(box *crypto.BoxPubKey, sig *crypto.SigPubKey, linkShared *crypto.BoxSharedKey, endpoint string) *peer { func (ps *peers) newPeer(box *crypto.BoxPubKey, sig *crypto.SigPubKey, linkShared *crypto.BoxSharedKey, endpoint string) *peer {
now := time.Now() now := time.Now()
p := peer{box: *box, p := peer{box: *box,
@ -352,7 +352,7 @@ func (p *peer) handleSwitchMsg(packet []byte) {
} }
// This generates the bytes that we sign or check the signature of for a switchMsg. // This generates the bytes that we sign or check the signature of for a switchMsg.
// It begins with the next node's key, followed by the root and the timetsamp, followed by coords being advertised to the next node. // It begins with the next node's key, followed by the root and the timestamp, followed by coords being advertised to the next node.
func getBytesForSig(next *crypto.SigPubKey, msg *switchMsg) []byte { func getBytesForSig(next *crypto.SigPubKey, msg *switchMsg) []byte {
var loc switchLocator var loc switchLocator
for _, hop := range msg.Hops { for _, hop := range msg.Hops {

View File

@ -30,7 +30,7 @@ const search_MAX_SEARCH_SIZE = 16
const search_RETRY_TIME = time.Second const search_RETRY_TIME = time.Second
// Information about an ongoing search. // Information about an ongoing search.
// Includes the targed NodeID, the bitmask to match it to an IP, and the list of nodes to visit / already visited. // Includes the target NodeID, the bitmask to match it to an IP, and the list of nodes to visit / already visited.
type searchInfo struct { type searchInfo struct {
dest crypto.NodeID dest crypto.NodeID
mask crypto.NodeID mask crypto.NodeID

View File

@ -4,7 +4,7 @@ package yggdrasil
// It routes packets based on distance on the spanning tree // It routes packets based on distance on the spanning tree
// In general, this is *not* equivalent to routing on the tree // In general, this is *not* equivalent to routing on the tree
// It falls back to the tree in the worst case, but it can take shortcuts too // It falls back to the tree in the worst case, but it can take shortcuts too
// This is the part that makse routing reasonably efficient on scale-free graphs // This is the part that makes routing reasonably efficient on scale-free graphs
// TODO document/comment everything in a lot more detail // TODO document/comment everything in a lot more detail